From: Wang Dongsheng <dongsheng.w...@freescale.com> T104x Platforms based on corenet_generic. The platforms DIU-block that need a special initialization to solve some callback functions, those functions depend on platform handle.
Signed-off-by: Wang Dongsheng <dongsheng.w...@freescale.com> --- This patch is *depends on* Prabhakar Kushwaha support T104x patchset. v2: No change. diff --git a/arch/powerpc/platforms/85xx/fix/Makefile b/arch/powerpc/platforms/85xx/fix/Makefile index a8e8154..0530acd 100644 --- a/arch/powerpc/platforms/85xx/fix/Makefile +++ b/arch/powerpc/platforms/85xx/fix/Makefile @@ -1 +1,3 @@ obj-y += fix.o + +obj-y += t104x_diu.o diff --git a/arch/powerpc/platforms/85xx/fix/fix.c b/arch/powerpc/platforms/85xx/fix/fix.c index 7b59a52..c278eb1 100644 --- a/arch/powerpc/platforms/85xx/fix/fix.c +++ b/arch/powerpc/platforms/85xx/fix/fix.c @@ -21,6 +21,19 @@ static int fix_platform_init(void) { + u32 svr; + + svr = SVR_SOC_VER(mfspr(SPRN_SVR)); + + switch (svr) { + case SVR_T1040: + case SVR_T1042: + fix_t104x_diu_init(); + break; + default: + pr_info("Platform is not need to fix anything\n"); + } + return 0; } early_initcall(fix_platform_init); diff --git a/arch/powerpc/platforms/85xx/fix/fix.h b/arch/powerpc/platforms/85xx/fix/fix.h index 5a8c80e3..d27635f 100644 --- a/arch/powerpc/platforms/85xx/fix/fix.h +++ b/arch/powerpc/platforms/85xx/fix/fix.h @@ -1,4 +1,6 @@ #ifndef __CORENET_GENERIC_FIX_H__ #define __CORENET_GENERIC_FIX_H__ +extern void fix_t104x_diu_init(void); + #endif diff --git a/arch/powerpc/platforms/85xx/fix/t104x_diu.c b/arch/powerpc/platforms/85xx/fix/t104x_diu.c new file mode 100644 index 0000000..39c7242 --- /dev/null +++ b/arch/powerpc/platforms/85xx/fix/t104x_diu.c @@ -0,0 +1,155 @@ +/* + * T104x RDB Particular Setup + * Should apply for RDB platform of T1040 and it's personalities. + * viz T1040/T1042 + * + * Copyright 2014 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/io.h> +#include <sysdev/fsl_soc.h> + +#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) +/*DIU Pixel ClockCR offset in scfg*/ +#define CCSR_SCFG_PIXCLKCR 0x28 + +/* DIU Pixel Clock bits of the PIXCLKCR */ +#define PIXCLKCR_PXCKEN 0x80000000 +#define PIXCLKCR_PXCKINV 0x40000000 +#define PIXCLKCR_PXCKDLY 0x0000FF00 +#define PIXCLKCR_PXCLK_MASK 0x00FF0000 + +/* Some CPLD register definitions */ +#define CPLD_DIUCSR 0x16 +#define CPLD_DIUCSR_DVIEN 0x80 +#define CPLD_DIUCSR_BACKLIGHT 0x0f + +/** + * t104xrdb_set_monitor_port: switch the output to a different monitor port + */ +static void t104xrdb_set_monitor_port(enum fsl_diu_monitor_port port) +{ + struct device_node *cpld_node; + static void __iomem *cpld_base; + + cpld_node = of_find_compatible_node(NULL, NULL, "fsl,t104xrdb-cpld"); + if (!cpld_node) { + pr_err("T104xRDB: missing CPLD node\n"); + return; + } + + cpld_base = of_iomap(cpld_node, 0); + if (!cpld_base) { + pr_err("T104xRDB: could not map cpld registers\n"); + goto exit; + } + + switch (port) { + case FSL_DIU_PORT_DVI: + /* Enable the DVI(HDMI) port, disable the DFP and + * the backlight + */ + clrbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_DVIEN); + 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(cpld_base + CPLD_DIUCSR, 0x01 << 8); + setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 4); + setbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_BACKLIGHT); + break; + default: + pr_err("T104xRDB: unsupported monitor port %i\n", port); + } + +exit: + of_node_put(cpld_node); +} + +/** + * t104xrdb_set_pixel_clock: program the DIU's clock + * + * @pixclock: the wavelength, in picoseconds, of the clock + */ +static void t104xrdb_set_pixel_clock(unsigned int pixclock) +{ + struct device_node *scfg_np = NULL; + void __iomem *scfg; + unsigned long freq; + u64 temp; + u32 pxclk; + + /* Map the global utilities registers. */ + scfg_np = of_find_compatible_node(NULL, NULL, "fsl,t1040-scfg"); + if (!scfg_np) { + freq = temp; + pr_err("T104xRDB: missing supplemental configuration unit device node\n"); + return; + } + + scfg = of_iomap(scfg_np, 0); + of_node_put(scfg_np); + if (!scfg) { + pr_err("T104xRDB: could not map device\n"); + return; + } + + /* Convert pixclock from a wavelength to a frequency */ + temp = 1000000000000ULL; + do_div(temp, pixclock); + freq = temp; + + /* + * 'pxclk' is the ratio of the platform clock to the pixel clock. + * This number is programmed into the PIXCLKCR register, and the valid + * range of values is 2-255. + */ + pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq); + pxclk = clamp_t(u32, pxclk, 2, 255); + + /* Disable the pixel clock, and set it to non-inverted and no delay */ + clrbits32(scfg + CCSR_SCFG_PIXCLKCR, + PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK); + + /* Enable the clock and set the pxclk */ + setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16)); + + iounmap(scfg); +} + +/** + * t104xrdb_valid_monitor_port: set the monitor port for sysfs + */ +static enum fsl_diu_monitor_port +t104xrdb_valid_monitor_port(enum fsl_diu_monitor_port port) +{ + switch (port) { + case FSL_DIU_PORT_DVI: + case FSL_DIU_PORT_LVDS: + return port; + default: + return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */ + } +} +#endif + +void fix_t104x_diu_init(void) +{ +#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) + diu_ops.set_monitor_port = t104xrdb_set_monitor_port; + diu_ops.set_pixel_clock = t104xrdb_set_pixel_clock; + diu_ops.valid_monitor_port = t104xrdb_valid_monitor_port; +#endif +} -- 1.8.5 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev