diff --git a/rust/kernel/drm/kms/encoder.rs b/rust/kernel/drm/kms/encoder.rs
index f37945ea93f0c3cf1c2a3b820260e715e1656a0f..0c4577fde7f5d5a566782e391241725a9697c171 100644
--- a/rust/kernel/drm/kms/encoder.rs
+++ b/rust/kernel/drm/kms/encoder.rs
@@ -105,8 +105,13 @@ pub struct DriverEncoderOps {
 ///
 /// This is implemented internally by DRM.
 ///
+/// # Safety
+///
+/// [`as_raw()`] must always return a valid pointer to a [`struct drm_encoder`].
+///
 /// [`struct drm_encoder`]: srctree/include/drm/drm_encoder.h
-pub trait AsRawEncoder: StaticModeObject {
+/// [`as_raw()`]: AsRawEncoder::as_raw()
+pub unsafe trait AsRawEncoder: StaticModeObject {
     /// Return the raw `bindings::drm_encoder` for this DRM encoder.
     ///
     /// Drivers should never use this directly
@@ -181,7 +186,11 @@ impl<T: DriverEncoder> Deref for Encoder<T> {
     }
 }
 
-impl<T: DriverEncoder> AsRawEncoder for Encoder<T> {
+// SAFETY:
+// * Via our type invariants our data layout starts with `drm_encoder`.
+// * Since we don't expose `Encoder` to users befre it has been initialized, this and our data
+//   layout ensure that `as_raw()` always returns a valid pointer to a `drm_encoder`.
+unsafe impl<T: DriverEncoder> AsRawEncoder for Encoder<T> {
     fn as_raw(&self) -> *mut bindings::drm_encoder {
         self.encoder.get()
     }