130be4c96STimur Tabi /* 230be4c96STimur Tabi * P1022DS board specific routines 330be4c96STimur Tabi * 430be4c96STimur Tabi * Authors: Travis Wheatley <travis.wheatley@freescale.com> 530be4c96STimur Tabi * Dave Liu <daveliu@freescale.com> 630be4c96STimur Tabi * Timur Tabi <timur@freescale.com> 730be4c96STimur Tabi * 830be4c96STimur Tabi * Copyright 2010 Freescale Semiconductor, Inc. 930be4c96STimur Tabi * 1030be4c96STimur Tabi * This file is taken from the Freescale P1022DS BSP, with modifications: 1130be4c96STimur Tabi * 2) No AMP support 1230be4c96STimur Tabi * 3) No PCI endpoint support 1330be4c96STimur Tabi * 1430be4c96STimur Tabi * This file is licensed under the terms of the GNU General Public License 1530be4c96STimur Tabi * version 2. This program is licensed "as is" without any warranty of any 1630be4c96STimur Tabi * kind, whether express or implied. 1730be4c96STimur Tabi */ 1830be4c96STimur Tabi 1930be4c96STimur Tabi #include <linux/pci.h> 2030be4c96STimur Tabi #include <linux/of_platform.h> 21dc1c41f4SKumar Gala #include <linux/memblock.h> 222c184cd3STimur Tabi #include <asm/div64.h> 2330be4c96STimur Tabi #include <asm/mpic.h> 2430be4c96STimur Tabi #include <asm/swiotlb.h> 2530be4c96STimur Tabi 2630be4c96STimur Tabi #include <sysdev/fsl_soc.h> 2730be4c96STimur Tabi #include <sysdev/fsl_pci.h> 28ba8438fbSMichael Neuling #include <asm/udbg.h> 292c184cd3STimur Tabi #include <asm/fsl_guts.h> 30582d3e09SKyle Moffett #include "smp.h" 312c184cd3STimur Tabi 32543a07b1SDmitry Eremin-Solenikov #include "mpc85xx.h" 33543a07b1SDmitry Eremin-Solenikov 342c184cd3STimur Tabi #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 352c184cd3STimur Tabi 366597c713STimur Tabi #define PMUXCR_ELBCDIU_MASK 0xc0000000 376597c713STimur Tabi #define PMUXCR_ELBCDIU_NOR16 0x80000000 386597c713STimur Tabi #define PMUXCR_ELBCDIU_DIU 0x40000000 396597c713STimur Tabi 402c184cd3STimur Tabi /* 412c184cd3STimur Tabi * Board-specific initialization of the DIU. This code should probably be 422c184cd3STimur Tabi * executed when the DIU is opened, rather than in arch code, but the DIU 432c184cd3STimur Tabi * driver does not have a mechanism for this (yet). 442c184cd3STimur Tabi * 452c184cd3STimur Tabi * This is especially problematic on the P1022DS because the local bus (eLBC) 462c184cd3STimur Tabi * and the DIU video signals share the same pins, which means that enabling the 472c184cd3STimur Tabi * DIU will disable access to NOR flash. 482c184cd3STimur Tabi */ 492c184cd3STimur Tabi 502c184cd3STimur Tabi /* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */ 512c184cd3STimur Tabi #define CLKDVDR_PXCKEN 0x80000000 522c184cd3STimur Tabi #define CLKDVDR_PXCKINV 0x10000000 532c184cd3STimur Tabi #define CLKDVDR_PXCKDLY 0x06000000 542c184cd3STimur Tabi #define CLKDVDR_PXCLK_MASK 0x00FF0000 552c184cd3STimur Tabi 562c184cd3STimur Tabi /* Some ngPIXIS register definitions */ 576597c713STimur Tabi #define PX_CTL 3 586597c713STimur Tabi #define PX_BRDCFG0 8 596597c713STimur Tabi #define PX_BRDCFG1 9 606597c713STimur Tabi 616597c713STimur Tabi #define PX_BRDCFG0_ELBC_SPI_MASK 0xc0 626597c713STimur Tabi #define PX_BRDCFG0_ELBC_SPI_ELBC 0x00 636597c713STimur Tabi #define PX_BRDCFG0_ELBC_SPI_NULL 0xc0 646597c713STimur Tabi #define PX_BRDCFG0_ELBC_DIU 0x02 656597c713STimur Tabi 662c184cd3STimur Tabi #define PX_BRDCFG1_DVIEN 0x80 672c184cd3STimur Tabi #define PX_BRDCFG1_DFPEN 0x40 682c184cd3STimur Tabi #define PX_BRDCFG1_BACKLIGHT 0x20 692c184cd3STimur Tabi #define PX_BRDCFG1_DDCEN 0x10 702c184cd3STimur Tabi 716597c713STimur Tabi #define PX_CTL_ALTACC 0x80 726597c713STimur Tabi 732c184cd3STimur Tabi /* 742c184cd3STimur Tabi * DIU Area Descriptor 752c184cd3STimur Tabi * 762c184cd3STimur Tabi * Note that we need to byte-swap the value before it's written to the AD 772c184cd3STimur Tabi * register. So even though the registers don't look like they're in the same 782c184cd3STimur Tabi * bit positions as they are on the MPC8610, the same value is written to the 792c184cd3STimur Tabi * AD register on the MPC8610 and on the P1022. 802c184cd3STimur Tabi */ 812c184cd3STimur Tabi #define AD_BYTE_F 0x10000000 822c184cd3STimur Tabi #define AD_ALPHA_C_MASK 0x0E000000 832c184cd3STimur Tabi #define AD_ALPHA_C_SHIFT 25 842c184cd3STimur Tabi #define AD_BLUE_C_MASK 0x01800000 852c184cd3STimur Tabi #define AD_BLUE_C_SHIFT 23 862c184cd3STimur Tabi #define AD_GREEN_C_MASK 0x00600000 872c184cd3STimur Tabi #define AD_GREEN_C_SHIFT 21 882c184cd3STimur Tabi #define AD_RED_C_MASK 0x00180000 892c184cd3STimur Tabi #define AD_RED_C_SHIFT 19 902c184cd3STimur Tabi #define AD_PALETTE 0x00040000 912c184cd3STimur Tabi #define AD_PIXEL_S_MASK 0x00030000 922c184cd3STimur Tabi #define AD_PIXEL_S_SHIFT 16 932c184cd3STimur Tabi #define AD_COMP_3_MASK 0x0000F000 942c184cd3STimur Tabi #define AD_COMP_3_SHIFT 12 952c184cd3STimur Tabi #define AD_COMP_2_MASK 0x00000F00 962c184cd3STimur Tabi #define AD_COMP_2_SHIFT 8 972c184cd3STimur Tabi #define AD_COMP_1_MASK 0x000000F0 982c184cd3STimur Tabi #define AD_COMP_1_SHIFT 4 992c184cd3STimur Tabi #define AD_COMP_0_MASK 0x0000000F 1002c184cd3STimur Tabi #define AD_COMP_0_SHIFT 0 1012c184cd3STimur Tabi 1022c184cd3STimur Tabi #define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \ 1032c184cd3STimur Tabi cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \ 1042c184cd3STimur Tabi (blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \ 1052c184cd3STimur Tabi (red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \ 1062c184cd3STimur Tabi (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \ 1072c184cd3STimur Tabi (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT)) 1082c184cd3STimur Tabi 1092c184cd3STimur Tabi /** 1102c184cd3STimur Tabi * p1022ds_get_pixel_format: return the Area Descriptor for a given pixel depth 1112c184cd3STimur Tabi * 1122c184cd3STimur Tabi * The Area Descriptor is a 32-bit value that determine which bits in each 1132c184cd3STimur Tabi * pixel are to be used for each color. 1142c184cd3STimur Tabi */ 1157653aaabSTimur Tabi static u32 p1022ds_get_pixel_format(enum fsl_diu_monitor_port port, 1167653aaabSTimur Tabi unsigned int bits_per_pixel) 1172c184cd3STimur Tabi { 1182c184cd3STimur Tabi switch (bits_per_pixel) { 1192c184cd3STimur Tabi case 32: 1202c184cd3STimur Tabi /* 0x88883316 */ 1212c184cd3STimur Tabi return MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8); 1222c184cd3STimur Tabi case 24: 1232c184cd3STimur Tabi /* 0x88082219 */ 1242c184cd3STimur Tabi return MAKE_AD(4, 0, 1, 2, 2, 0, 8, 8, 8); 1252c184cd3STimur Tabi case 16: 1262c184cd3STimur Tabi /* 0x65053118 */ 1272c184cd3STimur Tabi return MAKE_AD(4, 2, 1, 0, 1, 5, 6, 5, 0); 1282c184cd3STimur Tabi default: 1292c184cd3STimur Tabi pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel); 1302c184cd3STimur Tabi return 0; 1312c184cd3STimur Tabi } 1322c184cd3STimur Tabi } 1332c184cd3STimur Tabi 1342c184cd3STimur Tabi /** 1352c184cd3STimur Tabi * p1022ds_set_gamma_table: update the gamma table, if necessary 1362c184cd3STimur Tabi * 1372c184cd3STimur Tabi * On some boards, the gamma table for some ports may need to be modified. 1382c184cd3STimur Tabi * This is not the case on the P1022DS, so we do nothing. 1392c184cd3STimur Tabi */ 1407653aaabSTimur Tabi static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port, 1417653aaabSTimur Tabi char *gamma_table_base) 1422c184cd3STimur Tabi { 1432c184cd3STimur Tabi } 1442c184cd3STimur Tabi 1452c184cd3STimur Tabi /** 1462c184cd3STimur Tabi * p1022ds_set_monitor_port: switch the output to a different monitor port 1472c184cd3STimur Tabi * 1482c184cd3STimur Tabi */ 1497653aaabSTimur Tabi static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) 1502c184cd3STimur Tabi { 1516597c713STimur Tabi struct device_node *guts_node; 1526597c713STimur Tabi struct device_node *indirect_node = NULL; 1539cb6abcbSTimur Tabi struct ccsr_guts __iomem *guts; 1546597c713STimur Tabi u8 __iomem *lbc_lcs0_ba = NULL; 1556597c713STimur Tabi u8 __iomem *lbc_lcs1_ba = NULL; 1566597c713STimur Tabi u8 b; 1576597c713STimur Tabi 1586597c713STimur Tabi /* Map the global utilities registers. */ 1596597c713STimur Tabi guts_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); 1606597c713STimur Tabi if (!guts_node) { 1616597c713STimur Tabi pr_err("p1022ds: missing global utilties device node\n"); 1626597c713STimur Tabi return; 1636597c713STimur Tabi } 1646597c713STimur Tabi 1656597c713STimur Tabi guts = of_iomap(guts_node, 0); 1666597c713STimur Tabi if (!guts) { 1676597c713STimur Tabi pr_err("p1022ds: could not map global utilties device\n"); 1686597c713STimur Tabi goto exit; 1696597c713STimur Tabi } 1706597c713STimur Tabi 1716597c713STimur Tabi indirect_node = of_find_compatible_node(NULL, NULL, 1726597c713STimur Tabi "fsl,p1022ds-indirect-pixis"); 1736597c713STimur Tabi if (!indirect_node) { 1746597c713STimur Tabi pr_err("p1022ds: missing pixis indirect mode node\n"); 1756597c713STimur Tabi goto exit; 1766597c713STimur Tabi } 1776597c713STimur Tabi 1786597c713STimur Tabi lbc_lcs0_ba = of_iomap(indirect_node, 0); 1796597c713STimur Tabi if (!lbc_lcs0_ba) { 1806597c713STimur Tabi pr_err("p1022ds: could not map localbus chip select 0\n"); 1816597c713STimur Tabi goto exit; 1826597c713STimur Tabi } 1836597c713STimur Tabi 1846597c713STimur Tabi lbc_lcs1_ba = of_iomap(indirect_node, 1); 1856597c713STimur Tabi if (!lbc_lcs1_ba) { 1866597c713STimur Tabi pr_err("p1022ds: could not map localbus chip select 1\n"); 1876597c713STimur Tabi goto exit; 1886597c713STimur Tabi } 1896597c713STimur Tabi 1906597c713STimur Tabi /* Make sure we're in indirect mode first. */ 1916597c713STimur Tabi if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != 1926597c713STimur Tabi PMUXCR_ELBCDIU_DIU) { 1936597c713STimur Tabi struct device_node *pixis_node; 19431655958STimur Tabi void __iomem *pixis; 1952c184cd3STimur Tabi 1966597c713STimur Tabi pixis_node = 1976597c713STimur Tabi of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga"); 1986597c713STimur Tabi if (!pixis_node) { 1996597c713STimur Tabi pr_err("p1022ds: missing pixis node\n"); 2006597c713STimur Tabi goto exit; 2012c184cd3STimur Tabi } 2022c184cd3STimur Tabi 2036597c713STimur Tabi pixis = of_iomap(pixis_node, 0); 2046597c713STimur Tabi of_node_put(pixis_node); 20531655958STimur Tabi if (!pixis) { 2066597c713STimur Tabi pr_err("p1022ds: could not map pixis registers\n"); 2076597c713STimur Tabi goto exit; 2082c184cd3STimur Tabi } 2096597c713STimur Tabi 2106597c713STimur Tabi /* Enable indirect PIXIS mode. */ 2116597c713STimur Tabi setbits8(pixis + PX_CTL, PX_CTL_ALTACC); 2126597c713STimur Tabi iounmap(pixis); 2136597c713STimur Tabi 2146597c713STimur Tabi /* Switch the board mux to the DIU */ 2156597c713STimur Tabi out_8(lbc_lcs0_ba, PX_BRDCFG0); /* BRDCFG0 */ 2166597c713STimur Tabi b = in_8(lbc_lcs1_ba); 2176597c713STimur Tabi b |= PX_BRDCFG0_ELBC_DIU; 2186597c713STimur Tabi out_8(lbc_lcs1_ba, b); 2196597c713STimur Tabi 2206597c713STimur Tabi /* Set the chip mux to DIU mode. */ 2216597c713STimur Tabi clrsetbits_be32(&guts->pmuxcr, PMUXCR_ELBCDIU_MASK, 2226597c713STimur Tabi PMUXCR_ELBCDIU_DIU); 2236597c713STimur Tabi in_be32(&guts->pmuxcr); 2246597c713STimur Tabi } 2256597c713STimur Tabi 2262c184cd3STimur Tabi 2277653aaabSTimur Tabi switch (port) { 2287653aaabSTimur Tabi case FSL_DIU_PORT_DVI: 2292c184cd3STimur Tabi /* Enable the DVI port, disable the DFP and the backlight */ 2306597c713STimur Tabi out_8(lbc_lcs0_ba, PX_BRDCFG1); 2316597c713STimur Tabi b = in_8(lbc_lcs1_ba); 2326597c713STimur Tabi b &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT); 2336597c713STimur Tabi b |= PX_BRDCFG1_DVIEN; 2346597c713STimur Tabi out_8(lbc_lcs1_ba, b); 2352c184cd3STimur Tabi break; 2367653aaabSTimur Tabi case FSL_DIU_PORT_LVDS: 2376597c713STimur Tabi /* 2386597c713STimur Tabi * LVDS also needs backlight enabled, otherwise the display 2396597c713STimur Tabi * will be blank. 2406597c713STimur Tabi */ 2412c184cd3STimur Tabi /* Enable the DFP port, disable the DVI and the backlight */ 2426597c713STimur Tabi out_8(lbc_lcs0_ba, PX_BRDCFG1); 2436597c713STimur Tabi b = in_8(lbc_lcs1_ba); 2446597c713STimur Tabi b &= ~PX_BRDCFG1_DVIEN; 2456597c713STimur Tabi b |= PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT; 2466597c713STimur Tabi out_8(lbc_lcs1_ba, b); 2472c184cd3STimur Tabi break; 2482c184cd3STimur Tabi default: 2497653aaabSTimur Tabi pr_err("p1022ds: unsupported monitor port %i\n", port); 2502c184cd3STimur Tabi } 25131655958STimur Tabi 2526597c713STimur Tabi exit: 2536597c713STimur Tabi if (lbc_lcs1_ba) 2546597c713STimur Tabi iounmap(lbc_lcs1_ba); 2556597c713STimur Tabi if (lbc_lcs0_ba) 2566597c713STimur Tabi iounmap(lbc_lcs0_ba); 2576597c713STimur Tabi if (guts) 2586597c713STimur Tabi iounmap(guts); 2596597c713STimur Tabi 2606597c713STimur Tabi of_node_put(indirect_node); 2616597c713STimur Tabi of_node_put(guts_node); 2622c184cd3STimur Tabi } 2632c184cd3STimur Tabi 2642c184cd3STimur Tabi /** 2652c184cd3STimur Tabi * p1022ds_set_pixel_clock: program the DIU's clock 2662c184cd3STimur Tabi * 2672c184cd3STimur Tabi * @pixclock: the wavelength, in picoseconds, of the clock 2682c184cd3STimur Tabi */ 2692c184cd3STimur Tabi void p1022ds_set_pixel_clock(unsigned int pixclock) 2702c184cd3STimur Tabi { 2712c184cd3STimur Tabi struct device_node *guts_np = NULL; 2729cb6abcbSTimur Tabi struct ccsr_guts __iomem *guts; 2732c184cd3STimur Tabi unsigned long freq; 2742c184cd3STimur Tabi u64 temp; 2752c184cd3STimur Tabi u32 pxclk; 2762c184cd3STimur Tabi 2772c184cd3STimur Tabi /* Map the global utilities registers. */ 2782c184cd3STimur Tabi guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); 2792c184cd3STimur Tabi if (!guts_np) { 2802c184cd3STimur Tabi pr_err("p1022ds: missing global utilties device node\n"); 2812c184cd3STimur Tabi return; 2822c184cd3STimur Tabi } 2832c184cd3STimur Tabi 2842c184cd3STimur Tabi guts = of_iomap(guts_np, 0); 2852c184cd3STimur Tabi of_node_put(guts_np); 2862c184cd3STimur Tabi if (!guts) { 2872c184cd3STimur Tabi pr_err("p1022ds: could not map global utilties device\n"); 2882c184cd3STimur Tabi return; 2892c184cd3STimur Tabi } 2902c184cd3STimur Tabi 2912c184cd3STimur Tabi /* Convert pixclock from a wavelength to a frequency */ 2922c184cd3STimur Tabi temp = 1000000000000ULL; 2932c184cd3STimur Tabi do_div(temp, pixclock); 2942c184cd3STimur Tabi freq = temp; 2952c184cd3STimur Tabi 2967b93eccfSTimur Tabi /* 2977b93eccfSTimur Tabi * 'pxclk' is the ratio of the platform clock to the pixel clock. 2987b93eccfSTimur Tabi * This number is programmed into the CLKDVDR register, and the valid 2997b93eccfSTimur Tabi * range of values is 2-255. 3007b93eccfSTimur Tabi */ 3012c184cd3STimur Tabi pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq); 3027b93eccfSTimur Tabi pxclk = clamp_t(u32, pxclk, 2, 255); 3032c184cd3STimur Tabi 3042c184cd3STimur Tabi /* Disable the pixel clock, and set it to non-inverted and no delay */ 3052c184cd3STimur Tabi clrbits32(&guts->clkdvdr, 3062c184cd3STimur Tabi CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK); 3072c184cd3STimur Tabi 3082c184cd3STimur Tabi /* Enable the clock and set the pxclk */ 3092c184cd3STimur Tabi setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16)); 31031655958STimur Tabi 31131655958STimur Tabi iounmap(guts); 3122c184cd3STimur Tabi } 3132c184cd3STimur Tabi 3142c184cd3STimur Tabi /** 3157653aaabSTimur Tabi * p1022ds_valid_monitor_port: set the monitor port for sysfs 3162c184cd3STimur Tabi */ 3177653aaabSTimur Tabi enum fsl_diu_monitor_port 3187653aaabSTimur Tabi p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) 3192c184cd3STimur Tabi { 3207653aaabSTimur Tabi switch (port) { 3217653aaabSTimur Tabi case FSL_DIU_PORT_DVI: 3227653aaabSTimur Tabi case FSL_DIU_PORT_LVDS: 3237653aaabSTimur Tabi return port; 3247653aaabSTimur Tabi default: 3257653aaabSTimur Tabi return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */ 3262c184cd3STimur Tabi } 3272c184cd3STimur Tabi } 3282c184cd3STimur Tabi 3292c184cd3STimur Tabi #endif 33030be4c96STimur Tabi 33130be4c96STimur Tabi void __init p1022_ds_pic_init(void) 33230be4c96STimur Tabi { 333e55d7f73SKyle Moffett struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | 33430be4c96STimur Tabi MPIC_SINGLE_DEST_CPU, 33530be4c96STimur Tabi 0, 256, " OpenPIC "); 33630be4c96STimur Tabi BUG_ON(mpic == NULL); 33730be4c96STimur Tabi mpic_init(mpic); 33830be4c96STimur Tabi } 33930be4c96STimur Tabi 3404951896aSTimur Tabi #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 3414951896aSTimur Tabi 3424951896aSTimur Tabi /* 3434951896aSTimur Tabi * Disables a node in the device tree. 3444951896aSTimur Tabi * 3454951896aSTimur Tabi * This function is called before kmalloc() is available, so the 'new' object 3464951896aSTimur Tabi * should be allocated in the global area. The easiest way is to do that is 3474951896aSTimur Tabi * to allocate one static local variable for each call to this function. 3484951896aSTimur Tabi */ 3494951896aSTimur Tabi static void __init disable_one_node(struct device_node *np, struct property *new) 3504951896aSTimur Tabi { 3514951896aSTimur Tabi struct property *old; 3524951896aSTimur Tabi 3534951896aSTimur Tabi old = of_find_property(np, new->name, NULL); 3544951896aSTimur Tabi if (old) 3554951896aSTimur Tabi prom_update_property(np, new, old); 3564951896aSTimur Tabi else 3574951896aSTimur Tabi prom_add_property(np, new); 3584951896aSTimur Tabi } 3594951896aSTimur Tabi 3604951896aSTimur Tabi /* TRUE if there is a "video=fslfb" command-line parameter. */ 3614951896aSTimur Tabi static bool fslfb; 3624951896aSTimur Tabi 3634951896aSTimur Tabi /* 3644951896aSTimur Tabi * Search for a "video=fslfb" command-line parameter, and set 'fslfb' to 3654951896aSTimur Tabi * true if we find it. 3664951896aSTimur Tabi * 3674951896aSTimur Tabi * We need to use early_param() instead of __setup() because the normal 3684951896aSTimur Tabi * __setup() gets called to late. However, early_param() gets called very 3694951896aSTimur Tabi * early, before the device tree is unflattened, so all we can do now is set a 3704951896aSTimur Tabi * global variable. Later on, p1022_ds_setup_arch() will use that variable 3714951896aSTimur Tabi * to determine if we need to update the device tree. 3724951896aSTimur Tabi */ 3734951896aSTimur Tabi static int __init early_video_setup(char *options) 3744951896aSTimur Tabi { 3754951896aSTimur Tabi fslfb = (strncmp(options, "fslfb:", 6) == 0); 3764951896aSTimur Tabi 3774951896aSTimur Tabi return 0; 3784951896aSTimur Tabi } 3794951896aSTimur Tabi early_param("video", early_video_setup); 3804951896aSTimur Tabi 3814951896aSTimur Tabi #endif 3824951896aSTimur Tabi 38330be4c96STimur Tabi /* 38430be4c96STimur Tabi * Setup the architecture 38530be4c96STimur Tabi */ 38630be4c96STimur Tabi static void __init p1022_ds_setup_arch(void) 38730be4c96STimur Tabi { 38830be4c96STimur Tabi #ifdef CONFIG_PCI 38930be4c96STimur Tabi struct device_node *np; 39030be4c96STimur Tabi #endif 39130be4c96STimur Tabi dma_addr_t max = 0xffffffff; 39230be4c96STimur Tabi 39330be4c96STimur Tabi if (ppc_md.progress) 39430be4c96STimur Tabi ppc_md.progress("p1022_ds_setup_arch()", 0); 39530be4c96STimur Tabi 39630be4c96STimur Tabi #ifdef CONFIG_PCI 39730be4c96STimur Tabi for_each_compatible_node(np, "pci", "fsl,p1022-pcie") { 39830be4c96STimur Tabi struct resource rsrc; 39930be4c96STimur Tabi struct pci_controller *hose; 40030be4c96STimur Tabi 40130be4c96STimur Tabi of_address_to_resource(np, 0, &rsrc); 40230be4c96STimur Tabi 40330be4c96STimur Tabi if ((rsrc.start & 0xfffff) == 0x8000) 40430be4c96STimur Tabi fsl_add_bridge(np, 1); 40530be4c96STimur Tabi else 40630be4c96STimur Tabi fsl_add_bridge(np, 0); 40730be4c96STimur Tabi 40830be4c96STimur Tabi hose = pci_find_hose_for_OF_device(np); 40930be4c96STimur Tabi max = min(max, hose->dma_window_base_cur + 41030be4c96STimur Tabi hose->dma_window_size); 41130be4c96STimur Tabi } 41230be4c96STimur Tabi #endif 41330be4c96STimur Tabi 4142c184cd3STimur Tabi #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 4152c184cd3STimur Tabi diu_ops.get_pixel_format = p1022ds_get_pixel_format; 4162c184cd3STimur Tabi diu_ops.set_gamma_table = p1022ds_set_gamma_table; 4172c184cd3STimur Tabi diu_ops.set_monitor_port = p1022ds_set_monitor_port; 4182c184cd3STimur Tabi diu_ops.set_pixel_clock = p1022ds_set_pixel_clock; 4197653aaabSTimur Tabi diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; 4204951896aSTimur Tabi 4214951896aSTimur Tabi /* 4224951896aSTimur Tabi * Disable the NOR flash node if there is video=fslfb... command-line 4234951896aSTimur Tabi * parameter. When the DIU is active, NOR flash is unavailable, so we 4244951896aSTimur Tabi * have to disable the node before the MTD driver loads. 4254951896aSTimur Tabi */ 4264951896aSTimur Tabi if (fslfb) { 4274951896aSTimur Tabi struct device_node *np = 4284951896aSTimur Tabi of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); 4294951896aSTimur Tabi 4304951896aSTimur Tabi if (np) { 4314951896aSTimur Tabi np = of_find_compatible_node(np, NULL, "cfi-flash"); 4324951896aSTimur Tabi if (np) { 4334951896aSTimur Tabi static struct property nor_status = { 4344951896aSTimur Tabi .name = "status", 4354951896aSTimur Tabi .value = "disabled", 4364951896aSTimur Tabi .length = sizeof("disabled"), 4374951896aSTimur Tabi }; 4384951896aSTimur Tabi 4394951896aSTimur Tabi pr_info("p1022ds: disabling %s node", 4404951896aSTimur Tabi np->full_name); 4414951896aSTimur Tabi disable_one_node(np, &nor_status); 4424951896aSTimur Tabi of_node_put(np); 4434951896aSTimur Tabi } 4444951896aSTimur Tabi } 4454951896aSTimur Tabi 4464951896aSTimur Tabi } 4474951896aSTimur Tabi 4482c184cd3STimur Tabi #endif 4492c184cd3STimur Tabi 45030be4c96STimur Tabi mpc85xx_smp_init(); 45130be4c96STimur Tabi 45230be4c96STimur Tabi #ifdef CONFIG_SWIOTLB 453dc1c41f4SKumar Gala if (memblock_end_of_DRAM() > max) { 45430be4c96STimur Tabi ppc_swiotlb_enable = 1; 45530be4c96STimur Tabi set_pci_dma_ops(&swiotlb_dma_ops); 45630be4c96STimur Tabi ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; 45730be4c96STimur Tabi } 45830be4c96STimur Tabi #endif 45930be4c96STimur Tabi 46030be4c96STimur Tabi pr_info("Freescale P1022 DS reference board\n"); 46130be4c96STimur Tabi } 46230be4c96STimur Tabi 4638a95bc8dSTimur Tabi machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices); 46430be4c96STimur Tabi 46530be4c96STimur Tabi machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); 46630be4c96STimur Tabi 46730be4c96STimur Tabi /* 46830be4c96STimur Tabi * Called very early, device-tree isn't unflattened 46930be4c96STimur Tabi */ 47030be4c96STimur Tabi static int __init p1022_ds_probe(void) 47130be4c96STimur Tabi { 47230be4c96STimur Tabi unsigned long root = of_get_flat_dt_root(); 47330be4c96STimur Tabi 47430be4c96STimur Tabi return of_flat_dt_is_compatible(root, "fsl,p1022ds"); 47530be4c96STimur Tabi } 47630be4c96STimur Tabi 47730be4c96STimur Tabi define_machine(p1022_ds) { 47830be4c96STimur Tabi .name = "P1022 DS", 47930be4c96STimur Tabi .probe = p1022_ds_probe, 48030be4c96STimur Tabi .setup_arch = p1022_ds_setup_arch, 48130be4c96STimur Tabi .init_IRQ = p1022_ds_pic_init, 48230be4c96STimur Tabi #ifdef CONFIG_PCI 48330be4c96STimur Tabi .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 48430be4c96STimur Tabi #endif 48530be4c96STimur Tabi .get_irq = mpic_get_irq, 48630be4c96STimur Tabi .restart = fsl_rstcr_restart, 48730be4c96STimur Tabi .calibrate_decr = generic_calibrate_decr, 48830be4c96STimur Tabi .progress = udbg_progress, 48930be4c96STimur Tabi }; 490