Skip to content

Commit 42d2e0b

Browse files
drm/rp1/rp1_dsi: Move Composite Sync generation into the kernel
Move RP1 DPI's PIO-assisted Composite Sync generation code, previously released as a separate utility, into the kernel driver. There are 3 variants for progressive, generic interlaced and TV- style interlaced CSync, alongside the existing VSync fixup. Check that all of GPIOs 1-3 are mapped to DPI, so PIO won't try to snoop on a missing output, or override another device's pins. Add "force-csync" as both an OF property and a module parameter, for convenience of testing, as few tools set DRM_MODE_FLAG_CSYNC. Signed-off-by: Nick Hollinghurst <[email protected]>
1 parent cfe137c commit 42d2e0b

File tree

4 files changed

+405
-31
lines changed

4 files changed

+405
-31
lines changed

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

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@
6161
static unsigned int default_bus_fmt = MEDIA_BUS_FMT_RGB666_1X18;
6262
module_param(default_bus_fmt, uint, 0644);
6363

64+
/*
65+
* Override DRM mode flags and OF flag to force the use of Composite Sync.
66+
* This is mostly for testing, as neither panel-timing nor command-line
67+
* arguments nor utilities such as "kmstest" can set DRM_MODE_FLAG_CSYNC
68+
* (which, like interlace, is not strictly part of the DPI standard).
69+
* Sampled on each enable/mode-switch. Default polarity will be -ve.
70+
*/
71+
static bool force_csync;
72+
module_param(force_csync, bool, 0644);
73+
6474
/* -------------------------------------------------------------- */
6575

6676
static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -89,7 +99,8 @@ static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
8999
dpi->bus_fmt,
90100
dpi->de_inv,
91101
&pipe->crtc.state->mode);
92-
rp1dpi_pio_start(dpi, &pipe->crtc.state->mode);
102+
rp1dpi_pio_start(dpi, &pipe->crtc.state->mode,
103+
dpi->of_csync || force_csync);
93104
dpi->dpi_running = true;
94105
}
95106
dpi->cur_fmt = fb->format->format;
@@ -354,6 +365,8 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
354365
if (ret)
355366
goto done_err;
356367

368+
/* Nonstandard options */
369+
dpi->of_csync = of_property_read_bool(dev->of_node, "force-csync");
357370
dpi->rgb_order_override = RP1DPI_ORDER_UNCHANGED;
358371
if (!of_property_read_string(dev->of_node, "rgb_order", &rgb_order)) {
359372
if (!strcmp(rgb_order, "rgb"))
@@ -368,9 +381,9 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
368381
DRM_ERROR("Invalid dpi order %s - ignored\n", rgb_order);
369382
}
370383

371-
/* Check if PIO can snoop on or override DPI's GPIO1 */
372-
dpi->gpio1_used = false;
373-
for (i = 0; !dpi->gpio1_used; i++) {
384+
/* Check if all of GPIOs 1, 2 and 3 are assigned to DPI */
385+
ret = 0;
386+
for (i = 0; ret < 0xE; i++) {
374387
u32 p = 0;
375388
const char *str = NULL;
376389
struct device_node *np1 = of_parse_phandle(dev->of_node, "pinctrl-0", i);
@@ -379,21 +392,26 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
379392
break;
380393

381394
if (!of_property_read_string(np1, "function", &str) && !strcmp(str, "dpi")) {
382-
for (j = 0; !dpi->gpio1_used; j++) {
395+
for (j = 0; ret < 0xE; j++) {
383396
if (of_property_read_string_index(np1, "pins", j, &str))
384397
break;
385398
if (!strcmp(str, "gpio1"))
386-
dpi->gpio1_used = true;
399+
ret |= BIT(1);
400+
else if (!strcmp(str, "gpio2"))
401+
ret |= BIT(2);
402+
else if (!strcmp(str, "gpio3"))
403+
ret |= BIT(3);
387404
}
388-
for (j = 0; !dpi->gpio1_used; j++) {
405+
for (j = 0; ret < 3; j++) {
389406
if (of_property_read_u32_index(np1, "brcm,pins", j, &p))
390407
break;
391-
if (p == 1)
392-
dpi->gpio1_used = true;
408+
if (p >= 1 && p <= 3)
409+
ret |= (1 << p);
393410
}
394411
}
395412
of_node_put(np1);
396413
}
414+
dpi->sync_gpios_mapped = (ret >= 0xE);
397415

398416
/* Now we have all our resources, finish driver initialization */
399417
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ struct rp1_dpi {
5757

5858
/* Experimental stuff for interlace follows */
5959
struct rp1_pio_client *pio;
60-
bool gpio1_used;
61-
bool pio_stole_gpio2;
60+
bool of_csync, sync_gpios_mapped;
6261

6362
spinlock_t hw_lock; /* the following are used in line-match ISR */
6463
dma_addr_t last_dma_addr;
@@ -91,5 +90,6 @@ void rp1dpi_vidout_poweroff(struct rp1_dpi *dpi);
9190
/* ---------------------------------------------------------------------- */
9291
/* PIO control -- we need PIO to generate VSync (from DE) when interlaced */
9392

94-
int rp1dpi_pio_start(struct rp1_dpi *dpi, const struct drm_display_mode *mode);
93+
int rp1dpi_pio_start(struct rp1_dpi *dpi, const struct drm_display_mode *mode,
94+
bool force_csync);
9595
void rp1dpi_pio_stop(struct rp1_dpi *dpi);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ void rp1dpi_hw_setup(struct rp1_dpi *dpi,
392392
int order, i;
393393

394394
drm_info(&dpi->drm,
395-
"in_fmt=\'%c%c%c%c\' bus_fmt=0x%x mode=%dx%d total=%dx%d%s %dkHz %cH%cV%cD%cC",
395+
"in_fmt=\'%c%c%c%c\' bus_fmt=0x%x mode=%dx%d total=%dx%d%s %dkHz %cH%cV%cDE%cCK",
396396
in_format, in_format >> 8, in_format >> 16, in_format >> 24, bus_format,
397397
mode->hdisplay, mode->vdisplay,
398398
mode->htotal, mode->vtotal,
@@ -497,7 +497,7 @@ void rp1dpi_hw_setup(struct rp1_dpi *dpi,
497497
* This driver includes a PIO program to do that, when DE is enabled.
498498
*
499499
* An alternative fixup is to synthesize CSYNC from HSYNC and modified-VSYNC.
500-
* We don't implement that here, but to facilitate it, DPI's VSYNC is replaced
500+
* We can't do this and make VSYNC at the same time; DPI's VSYNC is replaced
501501
* by a "helper signal" that pulses low for 1 or 2 scan-lines, starting 2.0 or
502502
* 2.5 scan-lines respectively before nominal VSYNC start.
503503
*/

0 commit comments

Comments
 (0)