Skip to content

Commit 9bdc953

Browse files
author
Dharma Balasubiramani
committed
drm: atmel-hlcdc: disable clock divider to match LCDC_PCK with the src clk
When utilizing the LVDS interface, enable the ATMEL_XLCDC_CLKBYP bit in LCDC_CFG0 for XLCDC. This configuration ensures that the LCDC pixel clock aligns with the source clock (LVDS PLL). Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com>
1 parent ab9801b commit 9bdc953

2 files changed

Lines changed: 31 additions & 25 deletions

File tree

drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -109,39 +109,44 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
109109
(adj->crtc_hdisplay - 1) |
110110
((adj->crtc_vdisplay - 1) << 16));
111111

112-
prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
113-
mode_rate = adj->crtc_clock * 1000;
114-
if (!crtc->dc->desc->fixed_clksrc) {
115-
prate *= 2;
116-
cfg |= ATMEL_HLCDC_CLKSEL;
117-
mask |= ATMEL_HLCDC_CLKSEL;
118-
}
112+
if (crtc->dc->hlcdc->lvds_pll_clk) {
113+
cfg |= ATMEL_XLCDC_CLKBYP;
114+
mask |= ATMEL_XLCDC_CLKBYP;
115+
} else {
116+
prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
117+
mode_rate = adj->crtc_clock * 1000;
118+
if (!crtc->dc->desc->fixed_clksrc) {
119+
prate *= 2;
120+
cfg |= ATMEL_HLCDC_CLKSEL;
121+
mask |= ATMEL_HLCDC_CLKSEL;
122+
}
119123

120-
div = DIV_ROUND_UP(prate, mode_rate);
121-
if (div < 2) {
122-
div = 2;
123-
} else if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK) {
124-
/* The divider ended up too big, try a lower base rate. */
125-
cfg &= ~ATMEL_HLCDC_CLKSEL;
126-
prate /= 2;
127124
div = DIV_ROUND_UP(prate, mode_rate);
128-
if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK)
129-
div = ATMEL_HLCDC_CLKDIV_MASK;
130-
} else {
131-
int div_low = prate / mode_rate;
125+
if (div < 2) {
126+
div = 2;
127+
} else if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK) {
128+
/* The divider ended up too big, try a lower base rate. */
129+
cfg &= ~ATMEL_HLCDC_CLKSEL;
130+
prate /= 2;
131+
div = DIV_ROUND_UP(prate, mode_rate);
132+
if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK)
133+
div = ATMEL_HLCDC_CLKDIV_MASK;
134+
} else {
135+
int div_low = prate / mode_rate;
132136

133-
if (div_low >= 2 &&
134-
(10 * (prate / div_low - mode_rate) <
135-
(mode_rate - prate / div)))
136137
/*
137-
* At least 10 times better when using a higher
138+
* Its better to use a higher Pixel clock
138139
* frequency than requested, instead of a lower.
139140
* So, go with that.
140141
*/
141-
div = div_low;
142-
}
143142

144-
cfg |= ATMEL_HLCDC_CLKDIV(div);
143+
if (div_low >= 2 &&
144+
((prate / div_low >= mode_rate) &&
145+
(prate / div < mode_rate)))
146+
div = div_low;
147+
}
148+
cfg |= ATMEL_HLCDC_CLKDIV(div);
149+
}
145150

146151
regmap_update_bits(regmap, ATMEL_HLCDC_CFG(0), mask, cfg);
147152

include/linux/mfd/atmel-hlcdc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define ATMEL_XLCDC_HEO_UPDATE BIT(3)
4545

4646
#define ATMEL_HLCDC_CLKPOL BIT(0)
47+
#define ATMEL_XLCDC_CLKBYP BIT(1)
4748
#define ATMEL_HLCDC_CLKSEL BIT(2)
4849
#define ATMEL_HLCDC_CLKPWMSEL BIT(3)
4950
#define ATMEL_HLCDC_CGDIS(i) BIT(8 + (i))

0 commit comments

Comments
 (0)