[PATCH v4 6/6] drm/rockchip: dw_hdmi: add dw-hdmi support for the rk3328
Jonas Karlman
jonas at kwiboo.se
Mon Sep 10 15:15:46 UTC 2018
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 <heiko at sntech.de>
> Tested-by: Robin Murphy <robin.murphy at arm.com>
> Acked-by: Rob Herring <robh at 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
> },
>
More information about the dri-devel
mailing list