From: Stephen Rothwell Date: Wed, 3 Aug 2011 03:17:44 +0000 (+1000) Subject: Merge remote-tracking branch 'fbdev/master' X-Git-Tag: next-20110803~19 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=a7a1df1954939021d9ab9ba2f467b9e9e5d5f6c1;p=karo-tx-linux.git Merge remote-tracking branch 'fbdev/master' --- a7a1df1954939021d9ab9ba2f467b9e9e5d5f6c1 diff --cc arch/powerpc/platforms/85xx/p1022_ds.c index 266b3aadfe5e,a13d3cce413c..c01c7277888c --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@@ -126,10 -127,9 +127,10 @@@ static void p1022ds_set_gamma_table(enu * p1022ds_set_monitor_port: switch the output to a different monitor port * */ - static void p1022ds_set_monitor_port(int monitor_port) + static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) { struct device_node *pixis_node; + void __iomem *pixis; u8 __iomem *brdcfg1; pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis"); @@@ -143,10 -143,11 +144,11 @@@ pr_err("p1022ds: could not map ngPIXIS registers\n"); return; } - brdcfg1 += 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */ + brdcfg1 = pixis + 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */ - switch (monitor_port) { - case 0: /* DVI */ + switch (port) { + case FSL_DIU_PORT_DVI: + printk(KERN_INFO "%s:%u\n", __func__, __LINE__); /* Enable the DVI port, disable the DFP and the backlight */ clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT, PX_BRDCFG1_DVIEN); @@@ -157,10 -159,8 +160,10 @@@ PX_BRDCFG1_DFPEN); break; default: - pr_err("p1022ds: unsupported monitor port %i\n", monitor_port); + pr_err("p1022ds: unsupported monitor port %i\n", port); } + + iounmap(pixis); } /** diff --cc arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 74e018ef724b,0d80e9614f31..13fa9a6403e6 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@@ -199,83 -194,95 +201,77 @@@ void mpc8610hpcd_set_gamma_table(enum f #define PX_BRDCFG0_DLINK (1 << 4) #define PX_BRDCFG0_DIU_MASK (PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK) - void mpc8610hpcd_set_monitor_port(int monitor_port) + void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port) { - static const u8 bdcfg[] = { - PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK, - PX_BRDCFG0_DLINK, - 0, - }; - - if (monitor_port < 3) + switch (port) { + case FSL_DIU_PORT_DVI: clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK, - bdcfg[monitor_port]); + PX_BRDCFG0_DVISEL | PX_BRDCFG0_DLINK); + break; + case FSL_DIU_PORT_LVDS: + clrsetbits_8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK, + PX_BRDCFG0_DLINK); + break; + case FSL_DIU_PORT_DLVDS: + clrbits8(pixis_bdcfg0, PX_BRDCFG0_DIU_MASK); + break; + } } +/** + * mpc8610hpcd_set_pixel_clock: program the DIU's clock + * + * @pixclock: the wavelength, in picoseconds, of the clock + */ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock) { - u32 __iomem *clkdvdr; - u32 temp; - /* variables for pixel clock calcs */ - ulong bestval, bestfreq, speed_ccb, minpixclock, maxpixclock; - ulong pixval; - long err; - int i; - - clkdvdr = ioremap(get_immrbase() + 0xe0800, sizeof(u32)); - if (!clkdvdr) { - printk(KERN_ERR "Err: can't map clock divider register!\n"); + struct device_node *guts_np = NULL; + struct ccsr_guts_86xx __iomem *guts; + unsigned long freq; + u64 temp; + u32 pxclk; + + /* Map the global utilities registers. */ + guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts"); + if (!guts_np) { + pr_err("mpc8610hpcd: missing global utilties device node\n"); return; } - /* Pixel Clock configuration */ - speed_ccb = fsl_get_sys_freq(); - - /* Calculate the pixel clock with the smallest error */ - /* calculate the following in steps to avoid overflow */ - pr_debug("DIU pixclock in ps - %d\n", pixclock); - temp = 1000000000/pixclock; - temp *= 1000; - pixclock = temp; - pr_debug("DIU pixclock freq - %u\n", pixclock); - - temp = pixclock * 5 / 100; - pr_debug("deviation = %d\n", temp); - minpixclock = pixclock - temp; - maxpixclock = pixclock + temp; - pr_debug("DIU minpixclock - %lu\n", minpixclock); - pr_debug("DIU maxpixclock - %lu\n", maxpixclock); - pixval = speed_ccb/pixclock; - pr_debug("DIU pixval = %lu\n", pixval); - - err = 100000000; - bestval = pixval; - pr_debug("DIU bestval = %lu\n", bestval); - - bestfreq = 0; - for (i = -1; i <= 1; i++) { - temp = speed_ccb / ((pixval+i) + 1); - pr_debug("DIU test pixval i= %d, pixval=%lu, temp freq. = %u\n", - i, pixval, temp); - if ((temp < minpixclock) || (temp > maxpixclock)) - pr_debug("DIU exceeds monitor range (%lu to %lu)\n", - minpixclock, maxpixclock); - else if (abs(temp - pixclock) < err) { - pr_debug("Entered the else if block %d\n", i); - err = abs(temp - pixclock); - bestval = pixval+i; - bestfreq = temp; - } + guts = of_iomap(guts_np, 0); + of_node_put(guts_np); + if (!guts) { + pr_err("mpc8610hpcd: could not map global utilties device\n"); + return; } - pr_debug("DIU chose = %lx\n", bestval); - pr_debug("DIU error = %ld\n NomPixClk ", err); - pr_debug("DIU: Best Freq = %lx\n", bestfreq); - /* Modify PXCLK in GUTS CLKDVDR */ - pr_debug("DIU: Current value of CLKDVDR = 0x%08x\n", (*clkdvdr)); - temp = (*clkdvdr) & 0x2000FFFF; - *clkdvdr = temp; /* turn off clock */ - *clkdvdr = temp | 0x80000000 | (((bestval) & 0x1F) << 16); - pr_debug("DIU: Modified value of CLKDVDR = 0x%08x\n", (*clkdvdr)); - iounmap(clkdvdr); + /* 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. + * On the MPC8610, the value programmed into CLKDVDR is the ratio + * minus one. The valid range of values is 2-31. + */ + pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq) - 1; + pxclk = clamp_t(u32, pxclk, 2, 31); + + /* Disable the pixel clock, and set it to non-inverted and no delay */ + clrbits32(&guts->clkdvdr, + CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK); + + /* Enable the clock and set the pxclk */ + setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16)); + + iounmap(guts); } - ssize_t mpc8610hpcd_show_monitor_port(int monitor_port, char *buf) - { - return snprintf(buf, PAGE_SIZE, - "%c0 - DVI\n" - "%c1 - Single link LVDS\n" - "%c2 - Dual link LVDS\n", - monitor_port == 0 ? '*' : ' ', - monitor_port == 1 ? '*' : ' ', - monitor_port == 2 ? '*' : ' '); - } - - int mpc8610hpcd_set_sysfs_monitor_port(int val) + enum fsl_diu_monitor_port + mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port) { - return val < 3 ? val : 0; + return port; } #endif