From: Jani Nikula <jani.nikula@intel.com>
To: Shashank Sharma <shashank.sharma@intel.com>,
dri-devel@lists.freedesktop.org, airlied@redhat.com
Cc: daniel.vetter@intel.com
Subject: Re: [PATCH v6] drm: Helper for lspcon in drm_dp_dual_mode
Date: Tue, 18 Oct 2016 15:43:34 +0300 [thread overview]
Message-ID: <87d1ixx1xl.fsf@intel.com> (raw)
In-Reply-To: <1476720277-16298-1-git-send-email-shashank.sharma@intel.com>
On Mon, 17 Oct 2016, Shashank Sharma <shashank.sharma@intel.com> wrote:
> Readme: {
> This patch-series got approved in drm-intel mailing list already.
> Sending this one patch to dri-devel too, as this patch touches the
> drm layer dp_dual_mode_helper implementation. Plese provide an ack
> so that we can merge this in intel-gfx tree.
> The full patch series and review history at:
> https://patchwork.freedesktop.org/patch/115769/
> }
>
> This patch adds lspcon support in dp_dual_mode helper.
> lspcon is essentially a dp->hdmi dongle with dual personality.
>
> LS mode: It works as a passive dongle, by level shifting DP++
> signals to HDMI signals, in LS mode.
> PCON mode: It works as a protocol converter active dongle
> in pcon mode, by converting DP++ outputs to HDMI 2.0 outputs.
>
> This patch adds support for lspcon detection and mode set
> switch operations, as a dp dual mode dongle.
>
> v2: Addressed review comments from Ville
> - add adaptor id for lspcon devices (0x08), use it to identify lspcon
> - change function names
> old: drm_lspcon_get_current_mode/drm_lspcon_change_mode
> new: drm_lspcon_get_mode/drm_lspcon_set_mode
> - change drm_lspcon_get_mode type to int, to match
> drm_dp_dual_mode_get_tmds_output
> - change 'err' to 'ret' to match the rest of the functions
> - remove pointless typecasting during call to dual_mode_read
> - fix the but while setting value of data, while writing lspcon mode
> - fix indentation
> - change mdelay(10) -> msleep(10)
> - return ETIMEDOUT instead of EFAULT, when lspcon mode change times out
> - Add an empty line to separate std regs macros and lspcon regs macros
> Indent bit definition
>
> v3: Addressed review comments from Rodrigo
> - change macro name from DP_DUAL_MODE_TYPE_LSPCON to
> DP_DUAL_MODE_TYPE_HAS_DPCD for better readability
> - change macro name from DP_DUAL_MODE_LSPCON_MODE_PCON to
> DP_DUAL_MODE_LSPCON_MODE_PCON for better readability
> - add comment for MCA specific offsets like 0x40 and 0x41
> - remove DP_DUAL_MODE_REV_TYPE2 check while checking lspcon adapter id
>
> v4: Addressed review comments from Ville
> - Fixed indentation at few places
> - s/current_mode/mode
> - s/reqd_mode/mode
> - remove unnecessary void* cast
> - remove drm_edid.h from includes
> - Add a comment for _HAS_DPCD
> - Fix enum description, for lspcon_mode.
>
> v5: Rebase
> v6: Rebase
>
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Pushed to drm-intel-next-queued with Dave's IRC ack to merge via Intel
trees.
BR,
Jani.
> ---
> drivers/gpu/drm/drm_dp_dual_mode_helper.c | 103 ++++++++++++++++++++++++++++++
> include/drm/drm_dp_dual_mode_helper.h | 26 ++++++++
> 2 files changed, 129 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
> index a7b2a75..a7aeb1e 100644
> --- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c
> +++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
> @@ -148,6 +148,14 @@ static bool is_type2_adaptor(uint8_t adaptor_id)
> DP_DUAL_MODE_REV_TYPE2);
> }
>
> +bool is_lspcon_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN],
> + const uint8_t adaptor_id)
> +{
> + return is_hdmi_adaptor(hdmi_id) &&
> + (adaptor_id == (DP_DUAL_MODE_TYPE_TYPE2 |
> + DP_DUAL_MODE_TYPE_HAS_DPCD));
> +}
> +
> /**
> * drm_dp_dual_mode_detect - Identify the DP dual mode adaptor
> * @adapter: I2C adapter for the DDC bus
> @@ -203,6 +211,8 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
> ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
> &adaptor_id, sizeof(adaptor_id));
> if (ret == 0) {
> + if (is_lspcon_adaptor(hdmi_id, adaptor_id))
> + return DRM_DP_DUAL_MODE_LSPCON;
> if (is_type2_adaptor(adaptor_id)) {
> if (is_hdmi_adaptor(hdmi_id))
> return DRM_DP_DUAL_MODE_TYPE2_HDMI;
> @@ -364,3 +374,96 @@ const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type)
> }
> }
> EXPORT_SYMBOL(drm_dp_get_dual_mode_type_name);
> +
> +/**
> + * drm_lspcon_get_mode: Get LSPCON's current mode of operation by
> + * by reading offset (0x80, 0x41)
> + * @i2c_adapter: I2C-over-aux adapter
> + * @current_mode: out vaiable, current lspcon mode of operation
> + *
> + * Returns:
> + * 0 on success, sets the current_mode value to appropriate mode
> + * -error on failure
> + */
> +int drm_lspcon_get_mode(struct i2c_adapter *adapter,
> + enum drm_lspcon_mode *mode)
> +{
> + u8 data;
> + int ret = 0;
> +
> + if (!mode) {
> + DRM_ERROR("NULL input\n");
> + return -EINVAL;
> + }
> +
> + /* Read Status: i2c over aux */
> + ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_LSPCON_CURRENT_MODE,
> + &data, sizeof(data));
> + if (ret < 0) {
> + DRM_ERROR("LSPCON read(0x80, 0x41) failed\n");
> + return -EFAULT;
> + }
> +
> + if (data & DP_DUAL_MODE_LSPCON_MODE_PCON)
> + *mode = DRM_LSPCON_MODE_PCON;
> + else
> + *mode = DRM_LSPCON_MODE_LS;
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_lspcon_get_mode);
> +
> +/**
> + * drm_lspcon_change_mode: Change LSPCON's mode of operation by
> + * by writing offset (0x80, 0x40)
> + * @i2c_adapter: I2C-over-aux adapter
> + * @reqd_mode: required mode of operation
> + *
> + * Returns:
> + * 0 on success, -error on failure/timeout
> + */
> +int drm_lspcon_set_mode(struct i2c_adapter *adapter,
> + enum drm_lspcon_mode mode)
> +{
> + u8 data = 0;
> + int ret;
> + int time_out = 200;
> + enum drm_lspcon_mode current_mode;
> +
> + if (mode == DRM_LSPCON_MODE_PCON)
> + data = DP_DUAL_MODE_LSPCON_MODE_PCON;
> +
> + /* Change mode */
> + ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_LSPCON_MODE_CHANGE,
> + &data, sizeof(data));
> + if (ret < 0) {
> + DRM_ERROR("LSPCON mode change failed\n");
> + return ret;
> + }
> +
> + /*
> + * Confirm mode change by reading the status bit.
> + * Sometimes, it takes a while to change the mode,
> + * so wait and retry until time out or done.
> + */
> + do {
> + ret = drm_lspcon_get_mode(adapter, ¤t_mode);
> + if (ret) {
> + DRM_ERROR("can't confirm LSPCON mode change\n");
> + return ret;
> + } else {
> + if (current_mode != mode) {
> + msleep(10);
> + time_out -= 10;
> + } else {
> + DRM_DEBUG_KMS("LSPCON mode changed to %s\n",
> + mode == DRM_LSPCON_MODE_LS ?
> + "LS" : "PCON");
> + return 0;
> + }
> + }
> + } while (time_out);
> +
> + DRM_ERROR("LSPCON mode change timed out\n");
> + return -ETIMEDOUT;
> +}
> +EXPORT_SYMBOL(drm_lspcon_set_mode);
> diff --git a/include/drm/drm_dp_dual_mode_helper.h b/include/drm/drm_dp_dual_mode_helper.h
> index e8a9dfd..5567770 100644
> --- a/include/drm/drm_dp_dual_mode_helper.h
> +++ b/include/drm/drm_dp_dual_mode_helper.h
> @@ -40,6 +40,8 @@
> #define DP_DUAL_MODE_REV_TYPE2 0x00
> #define DP_DUAL_MODE_TYPE_MASK 0xf0
> #define DP_DUAL_MODE_TYPE_TYPE2 0xa0
> +/* This field is marked reserved in dual mode spec, used in LSPCON */
> +#define DP_DUAL_MODE_TYPE_HAS_DPCD 0x08
> #define DP_DUAL_MODE_IEEE_OUI 0x11 /* 11-13*/
> #define DP_DUAL_IEEE_OUI_LEN 3
> #define DP_DUAL_DEVICE_ID 0x14 /* 14-19 */
> @@ -55,6 +57,11 @@
> #define DP_DUAL_MODE_CEC_ENABLE 0x01
> #define DP_DUAL_MODE_I2C_SPEED_CTRL 0x22
>
> +/* LSPCON specific registers, defined by MCA */
> +#define DP_DUAL_MODE_LSPCON_MODE_CHANGE 0x40
> +#define DP_DUAL_MODE_LSPCON_CURRENT_MODE 0x41
> +#define DP_DUAL_MODE_LSPCON_MODE_PCON 0x1
> +
> struct i2c_adapter;
>
> ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
> @@ -63,6 +70,19 @@ ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
> u8 offset, const void *buffer, size_t size);
>
> /**
> +* enum drm_lspcon_mode
> +* @lspcon_mode_ls: Level shifter mode of LSPCON
> +* which drives DP++ to HDMI 1.4 conversion.
> +* @lspcon_mode_pcon: Protocol converter mode of LSPCON
> +* which drives DP++ to HDMI 2.0 active conversion.
> +*/
> +enum drm_lspcon_mode {
> + DRM_LSPCON_MODE_INVALID,
> + DRM_LSPCON_MODE_LS,
> + DRM_LSPCON_MODE_PCON,
> +};
> +
> +/**
> * enum drm_dp_dual_mode_type - Type of the DP dual mode adaptor
> * @DRM_DP_DUAL_MODE_NONE: No DP dual mode adaptor
> * @DRM_DP_DUAL_MODE_UNKNOWN: Could be either none or type 1 DVI adaptor
> @@ -70,6 +90,7 @@ ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
> * @DRM_DP_DUAL_MODE_TYPE1_HDMI: Type 1 HDMI adaptor
> * @DRM_DP_DUAL_MODE_TYPE2_DVI: Type 2 DVI adaptor
> * @DRM_DP_DUAL_MODE_TYPE2_HDMI: Type 2 HDMI adaptor
> + * @DRM_DP_DUAL_MODE_TYPE2_LSPCON: Level shifter /protocol converter
> */
> enum drm_dp_dual_mode_type {
> DRM_DP_DUAL_MODE_NONE,
> @@ -78,6 +99,7 @@ enum drm_dp_dual_mode_type {
> DRM_DP_DUAL_MODE_TYPE1_HDMI,
> DRM_DP_DUAL_MODE_TYPE2_DVI,
> DRM_DP_DUAL_MODE_TYPE2_HDMI,
> + DRM_DP_DUAL_MODE_LSPCON,
> };
>
> enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter);
> @@ -89,4 +111,8 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
> struct i2c_adapter *adapter, bool enable);
> const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type);
>
> +int drm_lspcon_get_mode(struct i2c_adapter *adapter,
> + enum drm_lspcon_mode *current_mode);
> +int drm_lspcon_set_mode(struct i2c_adapter *adapter,
> + enum drm_lspcon_mode reqd_mode);
> #endif
--
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
prev parent reply other threads:[~2016-10-18 12:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-17 16:04 [PATCH v6] drm: Helper for lspcon in drm_dp_dual_mode Shashank Sharma
2016-10-18 6:57 ` Jani Nikula
2016-10-18 8:05 ` Sharma, Shashank
2016-10-18 12:43 ` Jani Nikula [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87d1ixx1xl.fsf@intel.com \
--to=jani.nikula@intel.com \
--cc=airlied@redhat.com \
--cc=daniel.vetter@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=shashank.sharma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.