Skip to content

Commit 7131c52

Browse files
committed
Merge branch 'linux-6.1-trunk/at91/drm' into linux-6.1-mchp
2 parents 25414dd + 2962ef8 commit 7131c52

8 files changed

Lines changed: 406 additions & 33 deletions

File tree

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13636,6 +13636,14 @@ M: Claudiu Beznea <claudiu.beznea@microchip.com>
1363613636
S: Supported
1363713637
F: drivers/power/reset/at91-sama5d2_shdwc.c
1363813638

13639+
MICROCHIP SAM9x7-COMPATIBLE LVDS CONTROLLER
13640+
M: Manikandan Muralidharan <manikandan.m@microchip.com>
13641+
M: Dharma Balasubiramani <dharma.b@microchip.com>
13642+
L: dri-devel@lists.freedesktop.org
13643+
S: Supported
13644+
F: Documentation/devicetree/bindings/display/bridge/microchip,sam9x7-lvds.yaml
13645+
F: drivers/gpu/drm/bridge/microchip-lvds.c
13646+
1363913647
MICROCHIP SPI DRIVER
1364013648
M: Tudor Ambarus <tudor.ambarus@microchip.com>
1364113649
S: Supported

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

Lines changed: 103 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,15 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
7979
int div, ret;
8080
bool is_xlcdc = crtc->dc->desc->is_xlcdc;
8181

82-
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
83-
if (ret)
84-
return;
82+
if (crtc->dc->hlcdc->lvds_pll_clk) {
83+
ret = clk_prepare_enable(crtc->dc->hlcdc->lvds_pll_clk);
84+
if (ret)
85+
return;
86+
} else {
87+
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
88+
if (ret)
89+
return;
90+
}
8591

8692
vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay;
8793
vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end;
@@ -103,39 +109,44 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
103109
(adj->crtc_hdisplay - 1) |
104110
((adj->crtc_vdisplay - 1) << 16));
105111

106-
prate = clk_get_rate(crtc->dc->hlcdc->sys_clk);
107-
mode_rate = adj->crtc_clock * 1000;
108-
if (!crtc->dc->desc->fixed_clksrc) {
109-
prate *= 2;
110-
cfg |= ATMEL_HLCDC_CLKSEL;
111-
mask |= ATMEL_HLCDC_CLKSEL;
112-
}
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+
}
113123

114-
div = DIV_ROUND_UP(prate, mode_rate);
115-
if (div < 2) {
116-
div = 2;
117-
} else if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK) {
118-
/* The divider ended up too big, try a lower base rate. */
119-
cfg &= ~ATMEL_HLCDC_CLKSEL;
120-
prate /= 2;
121124
div = DIV_ROUND_UP(prate, mode_rate);
122-
if (ATMEL_HLCDC_CLKDIV(div) & ~ATMEL_HLCDC_CLKDIV_MASK)
123-
div = ATMEL_HLCDC_CLKDIV_MASK;
124-
} else {
125-
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;
126136

127-
if (div_low >= 2 &&
128-
(10 * (prate / div_low - mode_rate) <
129-
(mode_rate - prate / div)))
130137
/*
131-
* At least 10 times better when using a higher
138+
* Its better to use a higher Pixel clock
132139
* frequency than requested, instead of a lower.
133140
* So, go with that.
134141
*/
135-
div = div_low;
136-
}
137142

138-
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+
}
139150

140151
regmap_update_bits(regmap, ATMEL_HLCDC_CFG(0), mask, cfg);
141152

@@ -160,7 +171,10 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
160171
ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
161172
cfg);
162173

163-
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
174+
if (crtc->dc->hlcdc->lvds_pll_clk)
175+
clk_disable_unprepare(crtc->dc->hlcdc->lvds_pll_clk);
176+
else
177+
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
164178
}
165179

166180
static enum drm_mode_status
@@ -213,7 +227,11 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
213227
(status & ATMEL_HLCDC_PIXEL_CLK))
214228
cpu_relax();
215229

216-
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
230+
if (crtc->dc->hlcdc->lvds_pll_clk)
231+
clk_disable_unprepare(crtc->dc->hlcdc->lvds_pll_clk);
232+
else
233+
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
234+
217235
pinctrl_pm_select_sleep_state(dev->dev);
218236

219237
pm_runtime_allow(dev->dev);
@@ -226,15 +244,37 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
226244
{
227245
struct drm_device *dev = c->dev;
228246
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
247+
struct drm_display_mode *adj = &c->state->adjusted_mode;
229248
struct regmap *regmap = crtc->dc->hlcdc->regmap;
230249
unsigned int status;
250+
int ret;
231251

232252
pm_runtime_get_sync(dev->dev);
233253

234254
pm_runtime_forbid(dev->dev);
235255

236256
pinctrl_pm_select_default_state(dev->dev);
237-
clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
257+
258+
if (crtc->dc->hlcdc->lvds_pll_clk) {
259+
/* If the LVDS interface is used, fetch the pixel clock
260+
* from the panel and set the clock rate.
261+
* Here LVDS PLL clock is 7 times the pixel clock.
262+
*/
263+
ret = clk_set_rate(crtc->dc->hlcdc->lvds_pll_clk,
264+
(adj->clock * 7 * 1000));
265+
if (ret) {
266+
dev_err(c->dev->dev, "failed to set clk rate for lvds pll: %d\n", ret);
267+
return;
268+
}
269+
270+
ret = clk_prepare_enable(crtc->dc->hlcdc->lvds_pll_clk);
271+
if (ret)
272+
return;
273+
} else {
274+
ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
275+
if (ret)
276+
return;
277+
}
238278

239279
regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
240280
while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
@@ -295,7 +335,8 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
295335
if (!encoder)
296336
encoder = connector->encoder;
297337

298-
if (encoder->encoder_type == DRM_MODE_ENCODER_DSI) {
338+
switch (encoder->encoder_type) {
339+
case DRM_MODE_ENCODER_DSI:
299340
/*
300341
* atmel-hlcdc to support DSI formats with DSI video pipeline
301342
* when DRM_MODE_ENCODER_DSI type is set by
@@ -338,7 +379,35 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
338379
break;
339380
}
340381
}
341-
} else {
382+
break;
383+
case DRM_MODE_ENCODER_LVDS:
384+
switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
385+
case 0:
386+
break;
387+
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
388+
case MEDIA_BUS_FMT_RGB666_1X18:
389+
return ATMEL_HLCDC_RGB666_OUTPUT;
390+
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
391+
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
392+
default:
393+
return ATMEL_HLCDC_RGB888_OUTPUT;
394+
}
395+
396+
for (j = 0; j < info->num_bus_formats; j++) {
397+
switch (info->bus_formats[j]) {
398+
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
399+
case MEDIA_BUS_FMT_RGB666_1X18:
400+
supported_fmts |= ATMEL_HLCDC_RGB666_OUTPUT;
401+
break;
402+
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
403+
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
404+
default:
405+
supported_fmts |= ATMEL_HLCDC_RGB888_OUTPUT;
406+
break;
407+
}
408+
}
409+
break;
410+
default:
342411
switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
343412
case 0:
344413
break;
@@ -372,6 +441,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
372441
break;
373442
}
374443
}
444+
break;
375445
}
376446
return supported_fmts;
377447
}

drivers/gpu/drm/bridge/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ config DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW
184184
to DP++. This is used with the i.MX6 imx-ldb
185185
driver. You are likely to say N here.
186186

187+
config DRM_MICROCHIP_LVDS_SERIALIZER
188+
tristate "Microchip LVDS serailzer support"
189+
depends on OF
190+
depends on DRM_ATMEL_HLCDC
191+
help
192+
Support for Microchip's LVDS serializer.
193+
187194
config DRM_NWL_MIPI_DSI
188195
tristate "Northwest Logic MIPI DSI Host controller"
189196
depends on DRM

drivers/gpu/drm/bridge/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
1212
obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
1313
obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
1414
obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
15+
obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) += microchip-lvds.o
1516
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
1617
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
1718
obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o

0 commit comments

Comments
 (0)