Loading drivers/video/pxafb.c +23 −13 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ #include <linux/cpufreq.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/clk.h> #include <linux/err.h> #include <asm/hardware.h> #include <asm/io.h> Loading Loading @@ -506,15 +508,15 @@ static struct fb_ops pxafb_ops = { * * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below. */ static inline unsigned int get_pcd(unsigned int pixclock) static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock) { unsigned long long pcd; /* FIXME: Need to take into account Double Pixel Clock mode * (DPC) bit? or perhaps set it based on the various clock * speeds */ pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock; pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000); pcd *= pixclock; do_div(pcd, 100000000 * 2); /* no need for this, since we should subtract 1 anyway. they cancel */ /* pcd += 1; */ /* make up for integer math truncations */ Loading @@ -523,19 +525,21 @@ static inline unsigned int get_pcd(unsigned int pixclock) /* * Some touchscreens need hsync information from the video driver to * function correctly. We export it here. * function correctly. We export it here. Note that 'hsync_time' and * the value returned from pxafb_get_hsync_time() is the *reciprocal* * of the hsync period in seconds. */ static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd) { unsigned long long htime; unsigned long htime; if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { fbi->hsync_time=0; return; } htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000; do_div(htime, pcd * fbi->fb.var.hsync_len); htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len); fbi->hsync_time = htime; } Loading @@ -560,7 +564,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * { struct pxafb_lcd_reg new_regs; u_long flags; u_int lines_per_panel, pcd = get_pcd(var->pixclock); u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); pr_debug("pxafb: Configuring PXA LCD\n"); Loading Loading @@ -803,7 +807,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); /* enable LCD controller clock */ pxa_set_cken(CKEN_LCD, 1); clk_enable(fbi->clk); /* Sequence from 11.7.10 */ LCCR3 = fbi->reg_lccr3; Loading Loading @@ -840,7 +844,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ pxa_set_cken(CKEN_LCD, 0); clk_disable(fbi->clk); } /* Loading Loading @@ -994,7 +998,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) break; case CPUFREQ_POSTCHANGE: pcd = get_pcd(fbi->fb.var.pixclock); pcd = get_pcd(fbi, fbi->fb.var.pixclock); set_hsync_time(fbi, pcd); fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); Loading Loading @@ -1119,6 +1123,12 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) memset(fbi, 0, sizeof(struct pxafb_info)); fbi->dev = dev; fbi->clk = clk_get(dev, "LCDCLK"); if (IS_ERR(fbi->clk)) { kfree(fbi); return NULL; } strcpy(fbi->fb.fix.id, PXA_NAME); fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; Loading drivers/video/pxafb.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ struct pxafb_dma_descriptor { struct pxafb_info { struct fb_info fb; struct device *dev; struct clk *clk; /* * These are the addresses we mapped Loading Loading
drivers/video/pxafb.c +23 −13 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ #include <linux/cpufreq.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/clk.h> #include <linux/err.h> #include <asm/hardware.h> #include <asm/io.h> Loading Loading @@ -506,15 +508,15 @@ static struct fb_ops pxafb_ops = { * * Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below. */ static inline unsigned int get_pcd(unsigned int pixclock) static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock) { unsigned long long pcd; /* FIXME: Need to take into account Double Pixel Clock mode * (DPC) bit? or perhaps set it based on the various clock * speeds */ pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock; pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000); pcd *= pixclock; do_div(pcd, 100000000 * 2); /* no need for this, since we should subtract 1 anyway. they cancel */ /* pcd += 1; */ /* make up for integer math truncations */ Loading @@ -523,19 +525,21 @@ static inline unsigned int get_pcd(unsigned int pixclock) /* * Some touchscreens need hsync information from the video driver to * function correctly. We export it here. * function correctly. We export it here. Note that 'hsync_time' and * the value returned from pxafb_get_hsync_time() is the *reciprocal* * of the hsync period in seconds. */ static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd) { unsigned long long htime; unsigned long htime; if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) { fbi->hsync_time=0; return; } htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000; do_div(htime, pcd * fbi->fb.var.hsync_len); htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len); fbi->hsync_time = htime; } Loading @@ -560,7 +564,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info * { struct pxafb_lcd_reg new_regs; u_long flags; u_int lines_per_panel, pcd = get_pcd(var->pixclock); u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock); pr_debug("pxafb: Configuring PXA LCD\n"); Loading Loading @@ -803,7 +807,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); /* enable LCD controller clock */ pxa_set_cken(CKEN_LCD, 1); clk_enable(fbi->clk); /* Sequence from 11.7.10 */ LCCR3 = fbi->reg_lccr3; Loading Loading @@ -840,7 +844,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ pxa_set_cken(CKEN_LCD, 0); clk_disable(fbi->clk); } /* Loading Loading @@ -994,7 +998,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) break; case CPUFREQ_POSTCHANGE: pcd = get_pcd(fbi->fb.var.pixclock); pcd = get_pcd(fbi, fbi->fb.var.pixclock); set_hsync_time(fbi, pcd); fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); Loading Loading @@ -1119,6 +1123,12 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) memset(fbi, 0, sizeof(struct pxafb_info)); fbi->dev = dev; fbi->clk = clk_get(dev, "LCDCLK"); if (IS_ERR(fbi->clk)) { kfree(fbi); return NULL; } strcpy(fbi->fb.fix.id, PXA_NAME); fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; Loading
drivers/video/pxafb.h +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ struct pxafb_dma_descriptor { struct pxafb_info { struct fb_info fb; struct device *dev; struct clk *clk; /* * These are the addresses we mapped Loading