On 2019-04-29 at 09:38:32 +0200, Daniel Vetter wrote: > On Thu, Apr 18, 2019 at 02:28:04PM +0530, Ramalingam C wrote: > > This patch adds a optional CP downstream info blob property to the > > connectors. This enables the Userspace to read the information of HDCP > > authenticated downstream topology. > > > > Driver will update this blob with all downstream information at the > > end of the authentication. > > > > In case userspace configures this platform as repeater, then this > > information is needed for the authentication with upstream HDCP > > transmitter. > > > > v2: > > s/cp_downstream/content_protection_downstream [daniel] > > v3: > > s/content_protection_downstream/hdcp_topology [daniel] > > v4: > > hdcp_topology_info struct is added with explicit padding [Daniel] > > v5: > > Rebased. > > > > Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> > > --- > > drivers/gpu/drm/drm_atomic_uapi.c | 3 ++ > > drivers/gpu/drm/drm_connector.c | 20 ++++++++++ > > drivers/gpu/drm/drm_hdcp.c | 65 +++++++++++++++++++++++++++++++ > > include/drm/drm_connector.h | 6 +++ > > include/drm/drm_hdcp.h | 6 +++ > > include/drm/drm_mode_config.h | 6 +++ > > include/uapi/drm/drm_mode.h | 37 ++++++++++++++++++ > > 7 files changed, 143 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c > > index 0b0747869963..1c9e1ab0d536 100644 > > --- a/drivers/gpu/drm/drm_atomic_uapi.c > > +++ b/drivers/gpu/drm/drm_atomic_uapi.c > > @@ -813,6 +813,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector, > > *val = state->content_protection; > > } else if (property == config->hdcp_content_type_property) { > > *val = state->hdcp_content_type; > > + } else if (property == config->hdcp_topology_property) { > > + *val = connector->hdcp_topology_blob_ptr ? > > + connector->hdcp_topology_blob_ptr->base.id : 0; > > } else if (property == config->writeback_fb_id_property) { > > /* Writeback framebuffer is one-shot, write and forget */ > > *val = 0; > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c > > index 436cf8e764cc..033ced774d37 100644 > > --- a/drivers/gpu/drm/drm_connector.c > > +++ b/drivers/gpu/drm/drm_connector.c > > @@ -246,6 +246,7 @@ int drm_connector_init(struct drm_device *dev, > > mutex_init(&connector->mutex); > > connector->edid_blob_ptr = NULL; > > connector->tile_blob_ptr = NULL; > > + connector->hdcp_topology_blob_ptr = NULL; > > connector->status = connector_status_unknown; > > connector->display_info.panel_orientation = > > DRM_MODE_PANEL_ORIENTATION_UNKNOWN; > > @@ -972,6 +973,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = { > > * authentication process. If content type is changed when > > * content_protection is not UNDESIRED, then kernel will disable the HDCP > > * and re-enable with new type in the same atomic commit > > + * HDCP Topology: > > + * This blob property is used to pass the HDCP downstream topology details > > + * of a HDCP encrypted connector, from kernel to userspace. > > + * This provides all required information to userspace, so that userspace > > + * can implement the HDCP repeater using the kernel as downstream ports of > > + * the repeater. as illustrated below: > > + * > > + * HDCP Repeaters > > + * +--------------------------------------------------------------+ > > + * | | > > + * | | | > > + * | Userspace HDCP Receiver +-----> KMD HDCP transmitters | > > + * | (Upstream Port) <------+ (Downstream Ports) | > > + * | | | > > + * | | > > + * +--------------------------------------------------------------+ > > Hm I think this misrenders, since the table isn't indented or marked as > fixed with. Did you check the output of $make htmldocs? Yes checked on doc output. corrupted. I will fix it. > > > + * > > + * Kernel will populate this blob only when the HDCP authentication is > > + * successful. > > * > > * max bpc: > > * This range property is used by userspace to limit the bit depth. When > > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c > > index 5640c4e744fe..c0d3fc93fc50 100644 > > --- a/drivers/gpu/drm/drm_hdcp.c > > +++ b/drivers/gpu/drm/drm_hdcp.c > > @@ -431,3 +431,68 @@ void drm_hdcp_update_content_protection(struct drm_connector *connector, > > dev->mode_config.content_protection_property); > > } > > EXPORT_SYMBOL(drm_hdcp_update_content_protection); > > + > > +/** > > + * drm_connector_attach_hdcp_topology_property - attach hdcp topology property > > + * > > + * @connector: connector to attach hdcp topology property with. > > + * > > + * This is used to add support for hdcp topology support on select connectors. > > + * When Intel platform is configured as repeater, this downstream info is used > > + * by userspace, to complete the repeater authentication of HDCP specification > > + * with upstream HDCP transmitter. > > + * > > + * The blob_id of the hdcp topology info will be set to > > + * &drm_connector_state.hdcp_topology > > + * > > + * Returns: > > + * Zero on success, negative errno on failure. > > + */ > > +int drm_connector_attach_hdcp_topology_property(struct drm_connector *connector) > > +{ > > + struct drm_device *dev = connector->dev; > > + struct drm_property *prop = dev->mode_config.hdcp_topology_property; > > + > > + if (!prop) > > + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | > > + DRM_MODE_PROP_IMMUTABLE, > > + "HDCP Topology", 0); > > + if (!prop) > > + return -ENOMEM; > > + > > + drm_object_attach_property(&connector->base, prop, 0); > > + dev->mode_config.hdcp_topology_property = prop; > > + return 0; > > +} > > +EXPORT_SYMBOL(drm_connector_attach_hdcp_topology_property); > > + > > +/** > > + * drm_connector_update_hdcp_topology_property - update the hdcp topology > > + * property of a connector > > + * @connector: drm connector, the topology is associated to > > + * @hdcp_topology_info: new content for the blob of hdcp_topology_property > > + * > > + * This function creates a new blob modeset object and assigns its id to the > > + * connector's hdcp_topology_property. > > + * > > + * Returns: > > + * Zero on success, negative errno on failure. > > + */ > > +int > > +drm_connector_update_hdcp_topology_property(struct drm_connector *connector, > > + const struct hdcp_topology_info *info) > > +{ > > + struct drm_device *dev = connector->dev; > > + int ret; > > + > > + if (!info) > > + return -EINVAL; > > + > > + ret = drm_property_replace_global_blob(dev, > > + &connector->hdcp_topology_blob_ptr, > > + sizeof(struct hdcp_topology_info), > > + info, &connector->base, > > + dev->mode_config.hdcp_topology_property); > > + return ret; > > +} > > Hm, I'd put this into the previous function that also sends out the > uevent. That way we can guarantee that we update everyting _before_ we > send out the uevent to signal to userspace that it should take some > action. That will not work as above fucntion wont be called for the disable request. Where as this blob needs to be removed on disable. So I prefer to keep this as separate. > > > +EXPORT_SYMBOL(drm_connector_update_hdcp_topology_property); > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > > index 9e2f1a9de2a0..180f8f4d4526 100644 > > --- a/include/drm/drm_connector.h > > +++ b/include/drm/drm_connector.h > > @@ -1050,6 +1050,12 @@ struct drm_connector { > > /** @properties: property tracking for this connector */ > > struct drm_object_properties properties; > > > > + /** > > + * @hdcp_topology_blob_ptr: DRM BLOB pointer for hdcp downstream > > + * topology information. > > + */ > > + struct drm_property_blob *hdcp_topology_blob_ptr; > > + > > /** > > * @scaling_mode_property: Optional atomic property to control the > > * upscaling. See drm_connector_attach_content_protection_property(). > > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h > > index 9457c7ec0d37..011f35e121a5 100644 > > --- a/include/drm/drm_hdcp.h > > +++ b/include/drm/drm_hdcp.h > > @@ -300,10 +300,16 @@ struct hdcp2_srm_header { > > > > struct drm_device; > > struct drm_connector; > > +struct hdcp_topology_info; > > > > bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count); > > int drm_connector_attach_content_protection_property( > > struct drm_connector *connector, bool hdcp_content_type); > > void drm_hdcp_update_content_protection(struct drm_connector *connector, > > u64 val); > > +int drm_connector_attach_hdcp_topology_property( > > + struct drm_connector *connector); > > +int drm_connector_update_hdcp_topology_property( > > + struct drm_connector *connector, > > + const struct hdcp_topology_info *info); > > #endif > > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h > > index b359b5b71eb9..4349b614fa15 100644 > > --- a/include/drm/drm_mode_config.h > > +++ b/include/drm/drm_mode_config.h > > @@ -848,6 +848,12 @@ struct drm_mode_config { > > */ > > struct drm_property *hdcp_content_type_property; > > > > + /** > > + * @hdcp_topology_property: DRM BLOB property for hdcp downstream > > + * topology information. > > + */ > > + struct drm_property *hdcp_topology_property; > > + > > /* dumb ioctl parameters */ > > uint32_t preferred_depth, prefer_shadow; > > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > > index 8ac03351fdee..9d7cdfab4962 100644 > > --- a/include/uapi/drm/drm_mode.h > > +++ b/include/uapi/drm/drm_mode.h > > @@ -213,6 +213,43 @@ extern "C" { > > #define DRM_MODE_HDCP_CONTENT_TYPE0 0 > > #define DRM_MODE_HDCP_CONTENT_TYPE1 1 > > > > +#define DRM_MODE_HDCP_KSV_LEN 5 > > +#define DRM_MODE_HDCP_MAX_DEVICE_CNT 127 > > +#define DRM_MODE_HDCP14_IN_FORCE (1 << 0) > > +#define DRM_MODE_HDCP22_IN_FORCE (1 << 1) > > + > > +struct hdcp_topology_info { > > + /* Version of HDCP authenticated (1.4/2.2) */ > > + __u32 ver_in_force; > > + > > + /* Applicable only for HDCP2.2 */ > > + __u32 content_type; > > + > > + /* KSV of immediate HDCP Sink. In Little-Endian Format. */ > > + __u8 bksv[DRM_MODE_HDCP_KSV_LEN]; > > + > > + /* Whether Immediate HDCP sink is a repeater? */ > > + __u8 is_repeater; > > + > > + /* Depth received from immediate downstream repeater */ > > + __u8 depth; > > + __u8 pad1; > > + > > + /* Device count received from immediate downstream repeater */ > > + __u32 device_count; > > + > > + /* > > + * Max buffer required to hold ksv list received from immediate > > + * repeater. In this array first device_count * DRM_MODE_HDCP_KSV_LEN > > + * will hold the valid ksv bytes. > > + * If authentication specification is > > + * HDCP1.4 - each KSV's Bytes will be in Little-Endian format. > > + * HDCP2.2 - each KSV's Bytes will be in Big-Endian format. > > + */ > > + __u8 ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT]; > > + __u8 pad2[5]; > > +} __packed; > > So I think we need userspace for this, but not sure where the discussions > on that are right now. Is this feasible, or this and follow-up i915 patch > more fyi and not for upstream? This is not for upstream, as i couldn't comeup with userspace. I will mention that in the commit msg. Otherwise share your view on the patch. -Ram > -Daniel > > > + > > struct drm_mode_modeinfo { > > __u32 clock; > > __u16 hdisplay; > > -- > > 2.19.1 > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx