Skip to content

Commit 0da5bec

Browse files
authored
Merge pull request #6529 from njhollinghurst/dpi-interlace2
2 parents 574ea34 + 7735dd0 commit 0da5bec

File tree

8 files changed

+465
-71
lines changed

8 files changed

+465
-71
lines changed

arch/arm/boot/dts/overlays/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5099,6 +5099,7 @@ Params: clock-frequency Display clock frequency (Hz)
50995099
vsync-invert Vertical sync active low
51005100
de-invert Data Enable active low
51015101
pixclk-invert Negative edge pixel clock
5102+
interlaced Use an interlaced mode (where supported)
51025103
width-mm Define the screen width in mm
51035104
height-mm Define the screen height in mm
51045105
rgb565 Change to RGB565 output on GPIOs 0-19

arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
vsync-invert = <&timing>, "vsync-active:0=0";
6060
de-invert = <&timing>, "de-active:0=0";
6161
pixclk-invert = <&timing>, "pixelclk-active:0=0";
62+
interlaced = <&timing>, "interlaced?";
6263

6364
width-mm = <&panel_generic>, "width-mm:0";
6465
height-mm = <&panel_generic>, "height-mm:0";

drivers/gpu/drm/bridge/panel.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
8282
return ret;
8383
}
8484

85+
connector->interlace_allowed = true;
86+
8587
drm_panel_bridge_set_orientation(connector, bridge);
8688

8789
drm_connector_attach_encoder(&panel_bridge->connector,

drivers/gpu/drm/rp1/rp1-dpi/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22

3-
drm-rp1-dpi-y := rp1_dpi.o rp1_dpi_hw.o rp1_dpi_cfg.o
3+
drm-rp1-dpi-y := rp1_dpi.o rp1_dpi_hw.o rp1_dpi_cfg.o rp1_dpi_pio.o
44

55
obj-$(CONFIG_DRM_RP1_DPI) += drm-rp1-dpi.o

drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
8080
if (dpi->dpi_running &&
8181
fb->format->format != dpi->cur_fmt) {
8282
rp1dpi_hw_stop(dpi);
83+
rp1dpi_pio_stop(dpi);
8384
dpi->dpi_running = false;
8485
}
8586
if (!dpi->dpi_running) {
@@ -88,6 +89,7 @@ static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
8889
dpi->bus_fmt,
8990
dpi->de_inv,
9091
&pipe->crtc.state->mode);
92+
rp1dpi_pio_start(dpi, &pipe->crtc.state->mode);
9193
dpi->dpi_running = true;
9294
}
9395
dpi->cur_fmt = fb->format->format;
@@ -187,6 +189,7 @@ static void rp1dpi_pipe_disable(struct drm_simple_display_pipe *pipe)
187189
drm_crtc_vblank_off(&pipe->crtc);
188190
if (dpi->dpi_running) {
189191
rp1dpi_hw_stop(dpi);
192+
rp1dpi_pio_stop(dpi);
190193
dpi->dpi_running = false;
191194
}
192195
clk_disable_unprepare(dpi->clocks[RP1DPI_CLK_DPI]);
@@ -236,6 +239,7 @@ static void rp1dpi_stopall(struct drm_device *drm)
236239
if (dpi->dpi_running || rp1dpi_hw_busy(dpi)) {
237240
rp1dpi_hw_stop(dpi);
238241
clk_disable_unprepare(dpi->clocks[RP1DPI_CLK_DPI]);
242+
rp1dpi_pio_stop(dpi);
239243
dpi->dpi_running = false;
240244
}
241245
rp1dpi_vidout_poweroff(dpi);
@@ -273,7 +277,7 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
273277
struct rp1_dpi *dpi;
274278
struct drm_bridge *bridge = NULL;
275279
struct drm_panel *panel;
276-
int i, ret;
280+
int i, j, ret;
277281

278282
dev_info(dev, __func__);
279283
ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 0, 0,
@@ -295,6 +299,7 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
295299
return ret;
296300
}
297301
dpi->pdev = pdev;
302+
spin_lock_init(&dpi->hw_lock);
298303

299304
dpi->bus_fmt = default_bus_fmt;
300305
ret = of_property_read_u32(dev->of_node, "default_bus_fmt", &dpi->bus_fmt);
@@ -332,6 +337,33 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
332337
if (ret)
333338
goto done_err;
334339

340+
/* Check if PIO can snoop on or override DPI's GPIO1 */
341+
dpi->gpio1_used = false;
342+
for (i = 0; !dpi->gpio1_used; i++) {
343+
u32 p = 0;
344+
const char *str = NULL;
345+
struct device_node *np1 = of_parse_phandle(dev->of_node, "pinctrl-0", i);
346+
347+
if (!np1)
348+
break;
349+
350+
if (!of_property_read_string(np1, "function", &str) && !strcmp(str, "dpi")) {
351+
for (j = 0; !dpi->gpio1_used; j++) {
352+
if (of_property_read_string_index(np1, "pins", j, &str))
353+
break;
354+
if (!strcmp(str, "gpio1"))
355+
dpi->gpio1_used = true;
356+
}
357+
for (j = 0; !dpi->gpio1_used; j++) {
358+
if (of_property_read_u32_index(np1, "brcm,pins", j, &p))
359+
break;
360+
if (p == 1)
361+
dpi->gpio1_used = true;
362+
}
363+
}
364+
of_node_put(np1);
365+
}
366+
335367
/* Now we have all our resources, finish driver initialization */
336368
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
337369
init_completion(&dpi->finished);

drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ struct rp1_dpi {
4646
bool de_inv, clk_inv;
4747
bool dpi_running, pipe_enabled;
4848
struct completion finished;
49+
50+
/* Experimental stuff for interlace follows */
51+
struct rp1_pio_client *pio;
52+
bool gpio1_used;
53+
bool pio_stole_gpio2;
54+
55+
spinlock_t hw_lock; /* the following are used in line-match ISR */
56+
dma_addr_t last_dma_addr;
57+
u32 last_stride;
58+
u32 shorter_front_porch;
59+
bool interlaced;
60+
bool lower_field_flag;
4961
};
5062

5163
/* ---------------------------------------------------------------------- */
@@ -67,3 +79,9 @@ void rp1dpi_hw_vblank_ctrl(struct rp1_dpi *dpi, int enable);
6779

6880
void rp1dpi_vidout_setup(struct rp1_dpi *dpi, bool drive_negedge);
6981
void rp1dpi_vidout_poweroff(struct rp1_dpi *dpi);
82+
83+
/* ---------------------------------------------------------------------- */
84+
/* PIO control -- we need PIO to generate VSync (from DE) when interlaced */
85+
86+
int rp1dpi_pio_start(struct rp1_dpi *dpi, const struct drm_display_mode *mode);
87+
void rp1dpi_pio_stop(struct rp1_dpi *dpi);

0 commit comments

Comments
 (0)