diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_tcon.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_tcon.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 523a6d787921..b263de7a8237 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -31,12 +31,12 @@ #include <uapi/drm/drm_mode.h> #include "sun4i_crtc.h" -#include "sun4i_dotclock.h" #include "sun4i_drv.h" #include "sun4i_lvds.h" #include "sun4i_rgb.h" #include "sun4i_tcon.h" #include "sun6i_mipi_dsi.h" +#include "sun4i_tcon_dclk.h" #include "sun8i_tcon_top.h" #include "sunxi_engine.h" @@ -291,18 +291,6 @@ static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode, return delay; } -static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, - const struct drm_display_mode *mode) -{ - /* Configure the dot clock */ - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); - - /* Set the resolution */ - regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, - SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | - SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); -} - static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon, const struct drm_connector *connector) { @@ -367,10 +355,18 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, u32 block_space, start_delay; u32 tcon_div; + /* + * dclk is required to run at 1/4 the DSI per-lane bit rate. + */ tcon->dclk_min_div = SUN6I_DSI_TCON_DIV; tcon->dclk_max_div = SUN6I_DSI_TCON_DIV; + clk_set_rate(tcon->dclk, mode->crtc_clock * 1000 * (bpp / lanes) + / SUN6I_DSI_TCON_DIV); - sun4i_tcon0_mode_set_common(tcon, mode); + /* Set the resolution */ + regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, + SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | + SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); /* Set dithering if needed */ sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); @@ -438,7 +434,12 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon, tcon->dclk_min_div = 7; tcon->dclk_max_div = 7; - sun4i_tcon0_mode_set_common(tcon, mode); + clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); + + /* Set the resolution */ + regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, + SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | + SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); /* Set dithering if needed */ sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); @@ -515,7 +516,12 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, tcon->dclk_min_div = tcon->quirks->dclk_min_div; tcon->dclk_max_div = 127; - sun4i_tcon0_mode_set_common(tcon, mode); + clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); + + /* Set the resolution */ + regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, + SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | + SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); /* Set dithering if needed */ sun4i_tcon0_mode_set_dithering(tcon, connector); @@ -1237,14 +1243,14 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, ret = sun4i_tcon_init_irq(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON interrupts\n"); - goto err_free_dotclock; + goto err_free_dclk; } tcon->crtc = sun4i_crtc_init(drm, engine, tcon); if (IS_ERR(tcon->crtc)) { dev_err(dev, "Couldn't create our CRTC\n"); ret = PTR_ERR(tcon->crtc); - goto err_free_dotclock; + goto err_free_dclk; } if (tcon->quirks->has_channel_0) { @@ -1264,7 +1270,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, of_node_put(remote); if (ret < 0) - goto err_free_dotclock; + goto err_free_dclk; } if (tcon->quirks->needs_de_be_mux) { @@ -1290,7 +1296,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, return 0; -err_free_dotclock: +err_free_dclk: if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); err_free_clocks: |