Hi Heiko,

CEC is not working when CEC 5V is enabled

On 2018-09-10 11:22, Heiko Stuebner wrote:

> The rk3328 uses a dw-hdmi controller with an external hdmi phy from
> Innosilicon which uses the generic phy framework for access.
> Add the necessary data and the compatible for the rk3328 to the
> rockchip dw-hdmi driver.
>
> Signed-off-by: Heiko Stuebner <he...@sntech.de>
> Tested-by: Robin Murphy <robin.mur...@arm.com>
> Acked-by: Rob Herring <r...@kernel.org>
>
> changes in v3:
> - reword as suggested by Rob to show that it's a dw-hdmi + Inno phy
> ---
>  .../display/rockchip/dw_hdmi-rockchip.txt     |   1 +
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   | 106 ++++++++++++++++++
>  2 files changed, 107 insertions(+)
>
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt 
> b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
> index 937bfb472e1d..39143424a474 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
> +++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
> @@ -13,6 +13,7 @@ Required properties:
>  
>  - compatible: should be one of the following:
>               "rockchip,rk3288-dw-hdmi"
> +             "rockchip,rk3328-dw-hdmi"
>               "rockchip,rk3399-dw-hdmi"
>  - reg: See dw_hdmi.txt.
>  - reg-io-width: See dw_hdmi.txt. Shall be 4.
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
> b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 19f002fa0a09..237f31fd8403 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -25,6 +25,24 @@
>  
>  #define RK3288_GRF_SOC_CON6          0x025C
>  #define RK3288_HDMI_LCDC_SEL         BIT(4)
> +#define RK3328_GRF_SOC_CON2          0x0408
> +
> +#define RK3328_HDMI_SDAIN_MSK                BIT(11)
> +#define RK3328_HDMI_SCLIN_MSK                BIT(10)
> +#define RK3328_HDMI_HPD_IOE          BIT(2)
> +#define RK3328_GRF_SOC_CON3          0x040c
> +/* need to be unset if hdmi or i2c should control voltage */
> +#define RK3328_HDMI_SDA5V_GRF                BIT(15)
> +#define RK3328_HDMI_SCL5V_GRF                BIT(14)
> +#define RK3328_HDMI_HPD5V_GRF                BIT(13)
> +#define RK3328_HDMI_CEC5V_GRF                BIT(12)
> +#define RK3328_GRF_SOC_CON4          0x0410
> +#define RK3328_HDMI_HPD_SARADC               BIT(13)
> +#define RK3328_HDMI_CEC_5V           BIT(11)
> +#define RK3328_HDMI_SDA_5V           BIT(10)
> +#define RK3328_HDMI_SCL_5V           BIT(9)
> +#define RK3328_HDMI_HPD_5V           BIT(8)
> +
>  #define RK3399_GRF_SOC_CON20         0x6250
>  #define RK3399_HDMI_LCDC_SEL         BIT(6)
>  
> @@ -292,6 +310,68 @@ static const struct drm_encoder_helper_funcs 
> dw_hdmi_rockchip_encoder_helper_fun
>       .atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
>  };
>  
> +static int dw_hdmi_rockchip_genphy_init(struct dw_hdmi *dw_hdmi, void *data,
> +                          struct drm_display_mode *mode)
> +{
> +     struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
> +
> +     return phy_power_on(hdmi->phy);
> +}
> +
> +static void dw_hdmi_rockchip_genphy_disable(struct dw_hdmi *dw_hdmi, void 
> *data)
> +{
> +     struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
> +
> +     phy_power_off(hdmi->phy);
> +}
> +
> +static enum drm_connector_status
> +dw_hdmi_rk3328_read_hpd(struct dw_hdmi *dw_hdmi, void *data)
> +{
> +     struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
> +     enum drm_connector_status status;
> +
> +     status = dw_hdmi_phy_read_hpd(dw_hdmi, data);
> +
> +     if (status == connector_status_connected)
> +             regmap_write(hdmi->regmap,
> +                     RK3328_GRF_SOC_CON4,
> +                     HIWORD_UPDATE(RK3328_HDMI_CEC_5V | RK3328_HDMI_SDA_5V |
> +                                   RK3328_HDMI_SCL_5V,
> +                                   RK3328_HDMI_CEC_5V | RK3328_HDMI_SDA_5V |
> +                                   RK3328_HDMI_SCL_5V));

This differs from BSP kernel and enable of CEC 5V stops CEC from working.
BSP kernel do not set write enable bit for CEC 5V:

RK3328_IO_5V_DOMAIN ((7 << 9) | (3 << (9 + 16)))

https://github.com/Kwiboo/linux-rockchip/commit/e74ac6a3a581bcb7b2ac9f4d70cf7298df01e417
 makes CEC work on v3 of this patch.

> +     else
> +             regmap_write(hdmi->regmap,
> +                     RK3328_GRF_SOC_CON4,
> +                     HIWORD_UPDATE(0,
> +                                   RK3328_HDMI_CEC_5V | RK3328_HDMI_SDA_5V |
> +                                   RK3328_HDMI_SCL_5V));
> +     return status;
> +}
> +
> +static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
> +{
> +     struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
> +
> +     dw_hdmi_phy_setup_hpd(dw_hdmi, data);
> +
> +     /* Enable and map pins to 3V grf-controlled io-voltage */
> +     regmap_write(hdmi->regmap,
> +             RK3328_GRF_SOC_CON4,
> +             HIWORD_UPDATE(0, RK3328_HDMI_HPD_SARADC | RK3328_HDMI_CEC_5V |
> +                              RK3328_HDMI_SDA_5V | RK3328_HDMI_SCL_5V |
> +                              RK3328_HDMI_HPD_5V));
> +     regmap_write(hdmi->regmap,
> +             RK3328_GRF_SOC_CON3,
> +             HIWORD_UPDATE(0, RK3328_HDMI_SDA5V_GRF | RK3328_HDMI_SCL5V_GRF |
> +                              RK3328_HDMI_HPD5V_GRF | 
> RK3328_HDMI_CEC5V_GRF));
> +     regmap_write(hdmi->regmap,
> +             RK3328_GRF_SOC_CON2,
> +             HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
> +                           RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
> +                           RK3328_HDMI_HPD_IOE));
> +}
> +
>  static struct rockchip_hdmi_chip_data rk3288_chip_data = {
>       .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
>       .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
> @@ -306,6 +386,29 @@ static const struct dw_hdmi_plat_data 
> rk3288_hdmi_drv_data = {
>       .phy_data = &rk3288_chip_data,
>  };
>  
> +static const struct dw_hdmi_phy_ops rk3328_hdmi_phy_ops = {
> +     .init           = dw_hdmi_rockchip_genphy_init,
> +     .disable        = dw_hdmi_rockchip_genphy_disable,
> +     .read_hpd       = dw_hdmi_rk3328_read_hpd,
> +     .update_hpd     = dw_hdmi_phy_update_hpd,
> +     .setup_hpd      = dw_hdmi_rk3328_setup_hpd,
> +};
> +
> +static struct rockchip_hdmi_chip_data rk3328_chip_data = {
> +     .lcdsel_grf_reg = -1,
> +};
> +
> +static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
> +     .mode_valid = dw_hdmi_rockchip_mode_valid,
> +     .mpll_cfg = rockchip_mpll_cfg,
> +     .cur_ctr = rockchip_cur_ctr,
> +     .phy_config = rockchip_phy_config,
> +     .phy_data = &rk3328_chip_data,
> +     .phy_ops = &rk3328_hdmi_phy_ops,
> +     .phy_name = "inno_dw_hdmi_phy2",
> +     .phy_force_vendor = true,
> +};
> +
>  static struct rockchip_hdmi_chip_data rk3399_chip_data = {
>       .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
>       .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
> @@ -324,6 +427,9 @@ static const struct of_device_id 
> dw_hdmi_rockchip_dt_ids[] = {
>       { .compatible = "rockchip,rk3288-dw-hdmi",
>         .data = &rk3288_hdmi_drv_data
>       },
> +     { .compatible = "rockchip,rk3328-dw-hdmi",
> +       .data = &rk3328_hdmi_drv_data
> +     },
>       { .compatible = "rockchip,rk3399-dw-hdmi",
>         .data = &rk3399_hdmi_drv_data
>       },
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to