diff --git a/drivers/gpu/drm/imx/nwl_dsi-imx.c b/drivers/gpu/drm/imx/nwl_dsi-imx.c index 85ee45a125025f71f59cc3e165337dcc3679edc0..da1239f350bcefe6a3840f54233b148da9e74523 100644 --- a/drivers/gpu/drm/imx/nwl_dsi-imx.c +++ b/drivers/gpu/drm/imx/nwl_dsi-imx.c @@ -117,9 +117,9 @@ static struct devtype imx8qm_dev = { .poweroff = &imx8qm_dsi_poweroff, .clk_config = { { .id = CLK_CORE, .present = false }, - { .id = CLK_PIXEL, .present = true }, - { .id = CLK_BYPASS, .present = true }, { .id = CLK_PHYREF, .present = true }, + { .id = CLK_BYPASS, .present = true }, + { .id = CLK_PIXEL, .present = true }, }, .ext_regs = IMX_REG_CSR, .tx_ulps_reg = 0x00, @@ -134,9 +134,9 @@ static struct devtype imx8qxp_dev = { .poweroff = &imx8qxp_dsi_poweroff, .clk_config = { { .id = CLK_CORE, .present = false }, - { .id = CLK_PIXEL, .present = true }, - { .id = CLK_BYPASS, .present = true }, { .id = CLK_PHYREF, .present = true }, + { .id = CLK_BYPASS, .present = true }, + { .id = CLK_PIXEL, .present = true }, }, .ext_regs = IMX_REG_CSR, .tx_ulps_reg = 0x30, @@ -177,28 +177,10 @@ static void imx_nwl_dsi_set_clocks(struct imx_mipi_dsi *dsi, bool enable) struct device *dev = dsi->dev; const char *id; struct clk *clk; - unsigned long new_rate, cur_rate, phy_rate = 0; + unsigned long new_rate, cur_rate; bool enabled; size_t i; - /* - * PHY_REF rate should be set by the nwl-dsi bridge, depending on the - * current mode used. We need that rate to set the PIXEL clock for - * QM or QXP. - */ - for (i = 0; i < dsi->clk_num; i++) { - if (!dsi->clk_config[i].present) - continue; - id = dsi->clk_config[i].id; - clk = dsi->clk_config[i].clk; - - if (!strcmp(id, CLK_BYPASS) || !strcmp(id, CLK_PHYREF)) { - dsi->clk_config[i].rate = clk_get_rate(clk); - phy_rate = dsi->clk_config[i].rate; - break; - } - } - for (i = 0; i < dsi->clk_num; i++) { if (!dsi->clk_config[i].present) continue; @@ -208,9 +190,6 @@ static void imx_nwl_dsi_set_clocks(struct imx_mipi_dsi *dsi, bool enable) cur_rate = clk_get_rate(clk); enabled = dsi->clk_config[i].enabled; - if (!strcmp(id, CLK_PIXEL) && phy_rate) - new_rate = phy_rate; - if (enable) { if (enabled && new_rate != cur_rate) clk_disable_unprepare(clk); @@ -571,6 +550,25 @@ static bool imx_nwl_dsi_mode_fixup(struct imx_mipi_dsi *dsi, return true; } +static void imx_nwl_dsi_mode_set(struct imx_mipi_dsi *dsi, + struct drm_display_mode *mode) +{ const char *id; + struct clk *clk; + size_t i; + + for (i = 0; i < dsi->clk_num; i++) { + if (!dsi->clk_config[i].present) + continue; + id = dsi->clk_config[i].id; + clk = dsi->clk_config[i].clk; + + /* Set bypass and pixel clocks to mode clock rate */ + if (!strcmp(id, CLK_BYPASS) || !strcmp(id, CLK_PIXEL)) + dsi->clk_config[i].rate = mode->crtc_clock * 1000; + } + +} + static int imx_nwl_dsi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -583,11 +581,21 @@ static int imx_nwl_dsi_encoder_atomic_check(struct drm_encoder *encoder, return !imx_nwl_dsi_mode_fixup(dsi, &crtc_state->adjusted_mode); } +static void imx_nwl_dsi_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder); + + imx_nwl_dsi_mode_set(dsi, adjusted_mode); +} + static const struct drm_encoder_helper_funcs imx_nwl_dsi_encoder_helper_funcs = { .enable = imx_nwl_dsi_encoder_enable, .disable = imx_nwl_dsi_encoder_disable, .atomic_check = imx_nwl_dsi_encoder_atomic_check, + .mode_set = imx_nwl_dsi_encoder_mode_set, }; static void imx_nwl_dsi_encoder_destroy(struct drm_encoder *encoder) @@ -625,6 +633,15 @@ static bool imx_nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, return imx_nwl_dsi_mode_fixup(dsi, adjusted); } +static void imx_nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted) +{ + struct imx_mipi_dsi *dsi = bridge->driver_private; + + imx_nwl_dsi_mode_set(dsi, adjusted); +} + static int imx_nwl_dsi_bridge_attach(struct drm_bridge *bridge) { struct imx_mipi_dsi *dsi = bridge->driver_private; @@ -663,6 +680,7 @@ static const struct drm_bridge_funcs imx_nwl_dsi_bridge_funcs = { .enable = imx_nwl_dsi_bridge_enable, .disable = imx_nwl_dsi_bridge_disable, .mode_fixup = imx_nwl_dsi_bridge_mode_fixup, + .mode_set = imx_nwl_dsi_bridge_mode_set, .attach = imx_nwl_dsi_bridge_attach, .detach = imx_nwl_dsi_bridge_detach, };