Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@
static unsigned int default_bus_fmt = MEDIA_BUS_FMT_RGB666_1X18;
module_param(default_bus_fmt, uint, 0644);

/*
* Override DRM mode flags to force the use of Composite Sync on GPIO1.
* This is mostly for testing, as neither panel-timing nor command-line
* arguments nor utilities such as "kmstest" can set DRM_MODE_FLAG_CSYNC.
* Sampled on each enable/mode-switch. Default polarity will be -ve.
* (Setting this may break Vertical Sync on GPIO2 for interlaced modes.)
*/
static bool force_csync;
module_param(force_csync, bool, 0644);

/* -------------------------------------------------------------- */

static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
Expand Down Expand Up @@ -89,7 +99,8 @@ static void rp1dpi_pipe_update(struct drm_simple_display_pipe *pipe,
dpi->bus_fmt,
dpi->de_inv,
&pipe->crtc.state->mode);
rp1dpi_pio_start(dpi, &pipe->crtc.state->mode);
rp1dpi_pio_start(dpi, &pipe->crtc.state->mode,
force_csync);
dpi->dpi_running = true;
}
dpi->cur_fmt = fb->format->format;
Expand Down Expand Up @@ -294,6 +305,7 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
struct drm_bridge *bridge = NULL;
const char *rgb_order = NULL;
struct drm_panel *panel;
u32 missing_gpios;
int i, j, ret;

dev_info(dev, __func__);
Expand Down Expand Up @@ -354,6 +366,7 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
if (ret)
goto done_err;

/* RGB order property - to match VC4 */
dpi->rgb_order_override = RP1DPI_ORDER_UNCHANGED;
if (!of_property_read_string(dev->of_node, "rgb_order", &rgb_order)) {
if (!strcmp(rgb_order, "rgb"))
Expand All @@ -368,9 +381,9 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
DRM_ERROR("Invalid dpi order %s - ignored\n", rgb_order);
}

/* Check if PIO can snoop on or override DPI's GPIO1 */
dpi->gpio1_used = false;
for (i = 0; !dpi->gpio1_used; i++) {
/* Check if all of GPIOs 1, 2 and 3 are assigned to DPI */
missing_gpios = BIT(1) | BIT(2) | BIT(3);
for (i = 0; missing_gpios; i++) {
u32 p = 0;
const char *str = NULL;
struct device_node *np1 = of_parse_phandle(dev->of_node, "pinctrl-0", i);
Expand All @@ -379,21 +392,26 @@ static int rp1dpi_platform_probe(struct platform_device *pdev)
break;

if (!of_property_read_string(np1, "function", &str) && !strcmp(str, "dpi")) {
for (j = 0; !dpi->gpio1_used; j++) {
for (j = 0; missing_gpios; j++) {
if (of_property_read_string_index(np1, "pins", j, &str))
break;
if (!strcmp(str, "gpio1"))
dpi->gpio1_used = true;
missing_gpios &= ~BIT(1);
else if (!strcmp(str, "gpio2"))
missing_gpios &= ~BIT(2);
else if (!strcmp(str, "gpio3"))
missing_gpios &= ~BIT(3);
}
for (j = 0; !dpi->gpio1_used; j++) {
for (j = 0; missing_gpios; j++) {
if (of_property_read_u32_index(np1, "brcm,pins", j, &p))
break;
if (p == 1)
dpi->gpio1_used = true;
if (p < 32)
missing_gpios &= ~(1 << p);
}
}
of_node_put(np1);
}
dpi->sync_gpios_mapped = !missing_gpios;

/* Now we have all our resources, finish driver initialization */
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ struct rp1_dpi {
unsigned int rgb_order_override;
struct completion finished;

/* Experimental stuff for interlace follows */
/* The following are for Interlace and CSYNC support using PIO */
struct rp1_pio_client *pio;
bool gpio1_used;
bool pio_stole_gpio2;
bool sync_gpios_mapped;

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

int rp1dpi_pio_start(struct rp1_dpi *dpi, const struct drm_display_mode *mode);
int rp1dpi_pio_start(struct rp1_dpi *dpi, const struct drm_display_mode *mode,
bool force_csync);
void rp1dpi_pio_stop(struct rp1_dpi *dpi);
4 changes: 2 additions & 2 deletions drivers/gpu/drm/rp1/rp1-dpi/rp1_dpi_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ void rp1dpi_hw_setup(struct rp1_dpi *dpi,
int order, i;

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