[ARM] pxa: update pxafb to use clk support
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Mon, 20 Aug 2007 09:18:42 +0000 (10:18 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 12 Oct 2007 20:14:56 +0000 (21:14 +0100)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/video/pxafb.c
drivers/video/pxafb.h

index a280a52f8efec27d49a440d604bd0cf9311440ba..f9b12ab59642d62a66ea1e8bc479e8863af5e9f2 100644 (file)
@@ -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>
@@ -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;
+        * (DPC) bit? or perhaps set it based on the various clock
+        * speeds */
+       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 */
@@ -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;
 }
 
@@ -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");
 
@@ -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;
@@ -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);
 }
 
 /*
@@ -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);
@@ -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;
index 7499a1c4bf790c9ecf51ba7093878080284facb6..f8605b807b0acbf5c018cc5ce407cc85b3f014ce 100644 (file)
@@ -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