Skip to content

Commit 953f785

Browse files
Dharma Balasubiramanimanikandan-m11
authored andcommitted
mfd: atmel-hlcdc: set prepare and enable LVDS PLL clock for LVDS display
The XLCDC IP in sam9x7 supports DSI, parallel RGB and LVDS Display. sys_clk (Generic clock) of atmel-hlcdc is used with DSI and Parallel RGB and LVDS PLL is used with LVDS display. Set the LVDS PLL clock rate by querying the panel's pixel clock frequency. prepare and enable the lvds_pll_clk, if it is configured in DT. Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com> Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com> [manikandan.m@microchip.com: ported to v6.6.9 by fixing conflicts in clock prepare/enable of lvds_pll_clk] Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
1 parent 2a1754f commit 953f785

3 files changed

Lines changed: 49 additions & 6 deletions

File tree

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

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,15 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
100100
drm_connector_list_iter_end(&iter);
101101
}
102102

103-
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
104-
if (ret)
105-
return;
103+
if (crtc->dc->hlcdc->lvds_pll_clk) {
104+
ret = clk_prepare_enable(crtc->dc->hlcdc->lvds_pll_clk);
105+
if (ret)
106+
return;
107+
} else {
108+
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
109+
if (ret)
110+
return;
111+
}
106112

107113
vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay;
108114
vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end;
@@ -185,7 +191,10 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
185191
ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
186192
cfg);
187193

188-
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
194+
if (crtc->dc->hlcdc->lvds_pll_clk)
195+
clk_disable_unprepare(crtc->dc->hlcdc->lvds_pll_clk);
196+
else
197+
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
189198
}
190199

191200
static enum drm_mode_status
@@ -238,7 +247,11 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
238247
(status & ATMEL_HLCDC_PIXEL_CLK))
239248
cpu_relax();
240249

241-
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
250+
if (crtc->dc->hlcdc->lvds_pll_clk)
251+
clk_disable_unprepare(crtc->dc->hlcdc->lvds_pll_clk);
252+
else
253+
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
254+
242255
pinctrl_pm_select_sleep_state(dev->dev);
243256

244257
pm_runtime_allow(dev->dev);
@@ -251,15 +264,37 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
251264
{
252265
struct drm_device *dev = c->dev;
253266
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
267+
struct drm_display_mode *adj = &c->state->adjusted_mode;
254268
struct regmap *regmap = crtc->dc->hlcdc->regmap;
255269
unsigned int status;
270+
int ret;
256271

257272
pm_runtime_get_sync(dev->dev);
258273

259274
pm_runtime_forbid(dev->dev);
260275

261276
pinctrl_pm_select_default_state(dev->dev);
262-
clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
277+
278+
if (crtc->dc->hlcdc->lvds_pll_clk) {
279+
/* If the LVDS interface is used, fetch the pixel clock
280+
* from the panel and set the clock rate.
281+
* Here LVDS PLL clock is 7 times the pixel clock.
282+
*/
283+
ret = clk_set_rate(crtc->dc->hlcdc->lvds_pll_clk,
284+
(adj->clock * 7 * 1000));
285+
if (ret) {
286+
dev_err(c->dev->dev, "failed to set clk rate for lvds pll: %d\n", ret);
287+
return;
288+
}
289+
290+
ret = clk_prepare_enable(crtc->dc->hlcdc->lvds_pll_clk);
291+
if (ret)
292+
return;
293+
} else {
294+
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
295+
if (ret)
296+
return;
297+
}
263298

264299
regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
265300
while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&

drivers/mfd/atmel-hlcdc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ static int atmel_hlcdc_probe(struct platform_device *pdev)
114114
return PTR_ERR(hlcdc->sys_clk);
115115
}
116116

117+
/* Get the optional clock (LVDS PLL) in case if the LVDS interface is used */
118+
hlcdc->lvds_pll_clk = devm_clk_get_optional(dev, "lvds_pll_clk");
119+
if (IS_ERR(hlcdc->lvds_pll_clk)) {
120+
dev_info(dev, "failed to get lvds PLL clock\n");
121+
hlcdc->lvds_pll_clk = NULL;
122+
}
123+
117124
hlcdc->slow_clk = devm_clk_get(dev, "slow_clk");
118125
if (IS_ERR(hlcdc->slow_clk)) {
119126
dev_err(dev, "failed to get slow clock\n");

include/linux/mfd/atmel-hlcdc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
*/
7676
struct atmel_hlcdc {
7777
struct regmap *regmap;
78+
struct clk *lvds_pll_clk;
7879
struct clk *periph_clk;
7980
struct clk *sys_clk;
8081
struct clk *slow_clk;

0 commit comments

Comments
 (0)