From fe0eed973255923eba4241aa6c57b266253b6315 Mon Sep 17 00:00:00 2001 From: Oliver Brown Date: Mon, 16 Jul 2018 08:57:16 -0500 Subject: [PATCH] MLK-18904-6: imx: hdp: Adding support for i.MX8M (MCU2) DP PHY to imx-hdp.c Adding support for MCU2 DisplayPort to imx-hdp.c. Signed-off-by: Oliver Brown --- drivers/gpu/drm/imx/hdp/imx-hdp.c | 91 +++++++++++++++++++++++++++---- drivers/gpu/drm/imx/hdp/imx-hdp.h | 6 +- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.c b/drivers/gpu/drm/imx/hdp/imx-hdp.c index 553339df69d5..5adac814b53b 100644 --- a/drivers/gpu/drm/imx/hdp/imx-hdp.c +++ b/drivers/gpu/drm/imx/hdp/imx-hdp.c @@ -72,6 +72,7 @@ static void imx_hdp_state_init(struct imx_hdp *hdp) state->mem = &hdp->mem; state->rw = hdp->rw; + state->edp = hdp->is_edp; } #ifdef CONFIG_IMX_HDP_CEC @@ -144,7 +145,7 @@ void imx8qm_pixel_link_deinit(state_struct *state) sc_ipc_close(hdp->mu_id); } -void imx8qm_phy_reset(sc_ipc_t ipcHndl, u8 reset) +void imx8qm_phy_reset(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset) { sc_err_t sciErr; /* set the pixel link mode and pixel type */ @@ -153,6 +154,21 @@ void imx8qm_phy_reset(sc_ipc_t ipcHndl, u8 reset) DRM_ERROR("SC_R_HDMI PHY reset failed %d!\n", sciErr); } +void imx8mq_phy_reset(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset) +{ + void *tmp_addr = mem->rst_base; + + if (reset) + __raw_writel(0x8, + (volatile unsigned int *)(tmp_addr+0x4)); /*set*/ + else + __raw_writel(0x8, + (volatile unsigned int *)(tmp_addr+0x8)); /*clear*/ + + + return; +} + int imx8qm_clock_init(struct hdp_clks *clks) { struct imx_hdp *hdp = clks_to_imx_hdp(clks); @@ -450,15 +466,17 @@ void imx8qm_ipg_clock_set_rate(struct hdp_clks *clks) /* hdmi/dp ipg/core clock */ clk_rate = clk_get_rate(clks->dig_pll); - if (clk_rate == PLL_1188MHZ) { - clk_set_rate(clks->dig_pll, PLL_1188MHZ); - clk_set_rate(clks->clk_core, PLL_1188MHZ/10); - clk_set_rate(clks->clk_ipg, PLL_1188MHZ/14); - } else { - clk_set_rate(clks->dig_pll, PLL_675MHZ); - clk_set_rate(clks->clk_core, PLL_675MHZ/5); - clk_set_rate(clks->clk_ipg, PLL_675MHZ/8); + + if (clk_rate != PLL_1188MHZ) { + pr_warn("%s, dig_pll was %u MHz, changing to 1188 MHz\n", + __func__, clk_rate/1000000); } + + /* Force to 1188 MHz until we know better */ + clk_set_rate(clks->dig_pll, PLL_1188MHZ); + clk_set_rate(clks->clk_core, PLL_1188MHZ/10); + clk_set_rate(clks->clk_ipg, PLL_1188MHZ/14); + /* Set Default av pll clock */ clk_set_rate(clks->av_pll, 24000000); } @@ -972,10 +990,27 @@ static struct hdp_devtype imx8mq_hdmi_devtype = { .rw = &imx8mq_rw, }; +static struct hdp_ops imx8mq_dp_ops = { + .phy_init = dp_phy_init_t28hpc, + .mode_set = dp_mode_set, + .get_edid_block = dp_get_edid_block, + .get_hpd_state = dp_get_hpd_state, + .phy_reset = imx8mq_phy_reset, +}; + +static struct hdp_devtype imx8mq_dp_devtype = { + .is_edid = true, + .is_4kp60 = true, + .audio_type = CDN_DPTX, + .ops = &imx8mq_dp_ops, + .rw = &imx8mq_rw, +}; + static const struct of_device_id imx_hdp_dt_ids[] = { { .compatible = "fsl,imx8qm-hdmi", .data = &imx8qm_hdmi_devtype}, { .compatible = "fsl,imx8qm-dp", .data = &imx8qm_dp_devtype}, { .compatible = "fsl,imx8mq-hdmi", .data = &imx8mq_hdmi_devtype}, + { .compatible = "fsl,imx8mq-dp", .data = &imx8mq_dp_devtype}, { } }; MODULE_DEVICE_TABLE(of, imx_hdp_dt_ids); @@ -1068,7 +1103,43 @@ static int imx_hdp_imx_bind(struct device *dev, struct device *master, return -EINVAL; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + hdp->mem.rst_base = devm_ioremap_resource(dev, res); + if (IS_ERR(hdp->mem.rst_base)) { + dev_warn(dev, "Failed to get HDP RESET base register\n"); + } + hdp->is_cec = of_property_read_bool(pdev->dev.of_node, "fsl,cec"); + + hdp->is_edp = of_property_read_bool(pdev->dev.of_node, "fsl,edp"); + + ret = of_property_read_u32(pdev->dev.of_node, + "lane_mapping", + &hdp->lane_mapping); + if (ret) { + hdp->lane_mapping = 0x1b; + dev_warn(dev, "Failed to get lane_mapping - using default\n"); + } + dev_info(dev, "lane_mapping 0x%02x\n", hdp->lane_mapping); + + ret = of_property_read_u32(pdev->dev.of_node, + "edp_link_rate", + &hdp->edp_link_rate); + if (ret) { + hdp->edp_link_rate = 0; + dev_warn(dev, "Failed to get dp_link_rate - using default\n"); + } + dev_info(dev, "edp_link_rate 0x%02x\n", hdp->edp_link_rate); + + ret = of_property_read_u32(pdev->dev.of_node, + "edp_num_lanes", + &hdp->edp_num_lanes); + if (ret) { + hdp->edp_num_lanes = 4; + dev_warn(dev, "Failed to get dp_num_lanes - using default\n"); + } + dev_info(dev, "dp_num_lanes 0x%02x\n", hdp->edp_num_lanes); + hdp->is_edid = devtype->is_edid; hdp->is_4kp60 = devtype->is_4kp60; hdp->audio_type = devtype->audio_type; @@ -1105,7 +1176,7 @@ static int imx_hdp_imx_bind(struct device *dev, struct device *master, } imx_hdp_call(hdp, pixel_clock_enable, &hdp->clks); - imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, 0); + imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, &hdp->mem, 0); imx_hdp_call(hdp, fw_load, &hdp->state); diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.h b/drivers/gpu/drm/imx/hdp/imx-hdp.h index ffc5f21a9eb9..69de718bbb82 100644 --- a/drivers/gpu/drm/imx/hdp/imx-hdp.h +++ b/drivers/gpu/drm/imx/hdp/imx-hdp.h @@ -94,7 +94,7 @@ struct hdp_ops { int (*write_hdr_metadata)(state_struct *state, union hdmi_infoframe *hdr_infoframe); - void (*phy_reset)(sc_ipc_t ipcHndl, u8 reset); + void (*phy_reset)(sc_ipc_t ipcHndl, struct hdp_mem *mem, u8 reset); int (*pixel_link_init)(state_struct *state); void (*pixel_link_deinit)(state_struct *state); void (*pixel_link_mux)(state_struct *state, struct drm_display_mode *mode); @@ -202,7 +202,11 @@ struct imx_hdp { u8 is_edid; u8 is_4kp60; u8 is_cec; + u8 is_edp; u8 audio_type; + u32 lane_mapping; + u32 edp_link_rate; + u32 edp_num_lanes; struct mutex mutex; /* for state below and previous_mode */ enum drm_connector_force force; /* mutex-protected force state */ -- 2.17.1