diff options
Diffstat (limited to 'arch/powerpc/platforms/85xx/corenet_diu.c')
-rw-r--r-- | arch/powerpc/platforms/85xx/corenet_diu.c | 105 |
1 files changed, 99 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/85xx/corenet_diu.c b/arch/powerpc/platforms/85xx/corenet_diu.c index c8c322b..cb5a512 100644 --- a/arch/powerpc/platforms/85xx/corenet_diu.c +++ b/arch/powerpc/platforms/85xx/corenet_diu.c @@ -77,11 +77,93 @@ exit: } /** + * t102xqds_set_monitor_port: switch the output to a different monitor port + */ + +#define BRDCFG5 0x55 +#define BRDCFG15 0x5F +/* BRDCFG5[0:1] controls routing and use of I2C3 & I2C4 ports*/ +#define BRDCFG5_IMX_DIU_HIGH 0x80 +#define BRDCFG5_IMX_DIU_LOW 0x40 + +/* BRDCFG15[3] controls LCD Panel Powerdown*/ +#define BRDCFG15_LCD_PD 0x10 +#define BRDCFG15_LCD_ENABLED 0x80 + +/* BRDCFG15[6:7] controls DIU MUX selction*/ +#define BRDCFG15_DIUSEL_HDMI 0x03 +#define BRDCFG15_DIUSEL_LVDS 0x01 + +static void t102xqds_set_monitor_port(enum fsl_diu_monitor_port port) +{ + struct device_node *pixis_node; + void __iomem *pixis; + + pixis_node = of_find_compatible_node(NULL, NULL, "fsl,tetra-fpga"); + if (!pixis_node) { + pr_err("t102xqds: missing pixis node\n"); + goto exit; + } + + pixis = of_iomap(pixis_node, 0); + of_node_put(pixis_node); + if (!pixis) { + pr_err("t102xqds: could not map pixis registers\n"); + goto exit; + } + + /* Route I2C4 to DIU system as HSYNC/VSYNC */ + clrbits8(pixis + BRDCFG5, BRDCFG5_IMX_DIU_LOW); + setbits8(pixis + BRDCFG5, BRDCFG5_IMX_DIU_HIGH); + + switch (port) { + case FSL_DIU_PORT_DVI: + /* Enable the DVI(HDMI) port, disable the DFP and + * the backlight + */ + clrbits8(pixis + BRDCFG15, BRDCFG15_LCD_ENABLED); + setbits8(pixis + BRDCFG15, BRDCFG15_LCD_PD); + + clrbits8(pixis + BRDCFG15, BRDCFG15_DIUSEL_HDMI); + break; + case FSL_DIU_PORT_LVDS: + /* + * LVDS also needs backlight enabled, otherwise the display + * will be blank. + */ + /* Enable the DFP port, disable the DVI*/ + setbits8(pixis + BRDCFG15, BRDCFG15_DIUSEL_LVDS); + + clrbits8(pixis + BRDCFG15, BRDCFG15_LCD_PD); + setbits8(pixis + BRDCFG15, BRDCFG15_LCD_ENABLED); + break; + default: + pr_err("%s: Unsupported monitor port %i\n", __func__, port); + } + + iounmap(pixis); + +exit: + return; +} + +static const struct of_device_id scfg_matches[] = { + { + .compatible = "fsl,t1040-scfg", + }, + { + .compatible = "fsl,t1024-scfg", + }, + {}, +}; + + +/** * t1042rdb_set_pixel_clock: program the DIU's clock * * @pixclock: the wavelength, in picoseconds, of the clock */ -static void t1042rdb_set_pixel_clock(unsigned int pixclock) +static void corenet_set_pixel_clock(unsigned int pixclock) { struct device_node *scfg_np = NULL; void __iomem *scfg; @@ -90,7 +172,7 @@ static void t1042rdb_set_pixel_clock(unsigned int pixclock) u32 pxclk; /* Map the global utilities registers. */ - scfg_np = of_find_compatible_node(NULL, NULL, "fsl,t1040-scfg"); + scfg_np = of_find_matching_node_and_match(NULL, scfg_matches, NULL); if (!scfg_np) { freq = temp; pr_err("%s: Missing scfg node. Can not display video.\n", @@ -130,10 +212,10 @@ static void t1042rdb_set_pixel_clock(unsigned int pixclock) } /** - * t1042rdb_valid_monitor_port: set the monitor port for sysfs + * corenet_valid_monitor_port: set the monitor port for sysfs */ static enum fsl_diu_monitor_port -t1042rdb_valid_monitor_port(enum fsl_diu_monitor_port port) +corenet_valid_monitor_port(enum fsl_diu_monitor_port port) { switch (port) { case FSL_DIU_PORT_DVI: @@ -147,8 +229,15 @@ t1042rdb_valid_monitor_port(enum fsl_diu_monitor_port port) static void t1042rdb_diu_init(void) { diu_ops.set_monitor_port = t1042rdb_set_monitor_port; - diu_ops.set_pixel_clock = t1042rdb_set_pixel_clock; - diu_ops.valid_monitor_port = t1042rdb_valid_monitor_port; + diu_ops.set_pixel_clock = corenet_set_pixel_clock; + diu_ops.valid_monitor_port = corenet_valid_monitor_port; +} + +static void t1024qds_diu_init(void) +{ + diu_ops.set_monitor_port = t102xqds_set_monitor_port; + diu_ops.set_pixel_clock = corenet_set_pixel_clock; + diu_ops.valid_monitor_port = corenet_valid_monitor_port; } static int __init corenet_diu_init(void) @@ -163,6 +252,10 @@ static int __init corenet_diu_init(void) if (of_find_compatible_node(NULL, NULL, "fsl,T1042RDB_PI")) t1042rdb_diu_init(); + /* T1024QDS board */ + if (of_find_compatible_node(NULL, NULL, "fsl,T1024QDS")) + t1024qds_diu_init(); + return 0; } early_initcall(corenet_diu_init); |