Commit 2576eb26 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Neil Armstrong

drm/bridge: lt9611: fix clock calculation

Instead of having several fixed values for the pcr register, calculate
it before programming. This allows the bridge to support most of the
display modes.

Fixes: 23278bf5 ("drm/bridge: Introduce LT9611 DSI to HDMI bridge")
Reviewed-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230118081658.2198520-6-dmitry.baryshkov@linaro.org
parent ad188aa4
...@@ -192,8 +192,9 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611, ...@@ -192,8 +192,9 @@ static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256)); regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
} }
static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv)
{ {
unsigned int pcr_m = mode->clock * 5 * postdiv / 27000;
const struct reg_sequence reg_cfg[] = { const struct reg_sequence reg_cfg[] = {
{ 0x830b, 0x01 }, { 0x830b, 0x01 },
{ 0x830c, 0x10 }, { 0x830c, 0x10 },
...@@ -236,24 +237,14 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod ...@@ -236,24 +237,14 @@ static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mod
else else
regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
switch (mode->hdisplay) { regmap_write(lt9611->regmap, 0x8326, pcr_m);
case 640:
regmap_write(lt9611->regmap, 0x8326, 0x14);
break;
case 1920:
regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
case 3840:
regmap_write(lt9611->regmap, 0x8326, 0x37);
break;
}
/* pcr rst */ /* pcr rst */
regmap_write(lt9611->regmap, 0x8011, 0x5a); regmap_write(lt9611->regmap, 0x8011, 0x5a);
regmap_write(lt9611->regmap, 0x8011, 0xfa); regmap_write(lt9611->regmap, 0x8011, 0xfa);
} }
static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode) static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv)
{ {
unsigned int pclk = mode->clock; unsigned int pclk = mode->clock;
const struct reg_sequence reg_cfg[] = { const struct reg_sequence reg_cfg[] = {
...@@ -272,12 +263,16 @@ static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode ...@@ -272,12 +263,16 @@ static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode
regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg)); regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
if (pclk > 150000) if (pclk > 150000) {
regmap_write(lt9611->regmap, 0x812d, 0x88); regmap_write(lt9611->regmap, 0x812d, 0x88);
else if (pclk > 70000) *postdiv = 1;
} else if (pclk > 70000) {
regmap_write(lt9611->regmap, 0x812d, 0x99); regmap_write(lt9611->regmap, 0x812d, 0x99);
else *postdiv = 2;
} else {
regmap_write(lt9611->regmap, 0x812d, 0xaa); regmap_write(lt9611->regmap, 0x812d, 0xaa);
*postdiv = 4;
}
/* /*
* first divide pclk by 2 first * first divide pclk by 2 first
...@@ -896,14 +891,15 @@ static void lt9611_bridge_mode_set(struct drm_bridge *bridge, ...@@ -896,14 +891,15 @@ static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
{ {
struct lt9611 *lt9611 = bridge_to_lt9611(bridge); struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
struct hdmi_avi_infoframe avi_frame; struct hdmi_avi_infoframe avi_frame;
unsigned int postdiv;
int ret; int ret;
lt9611_bridge_pre_enable(bridge); lt9611_bridge_pre_enable(bridge);
lt9611_mipi_input_digital(lt9611, mode); lt9611_mipi_input_digital(lt9611, mode);
lt9611_pll_setup(lt9611, mode); lt9611_pll_setup(lt9611, mode, &postdiv);
lt9611_mipi_video_setup(lt9611, mode); lt9611_mipi_video_setup(lt9611, mode);
lt9611_pcr_setup(lt9611, mode); lt9611_pcr_setup(lt9611, mode, postdiv);
ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
&lt9611->connector, &lt9611->connector,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment