LCOV - code coverage report
Current view: top level - include/linux/amba - clcd.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 79 0.0 %
Date: 2014-02-18 Functions: 0 2 0.0 %
Branches: 0 78 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/include/asm-arm/hardware/amba_clcd.h -- Integrator LCD panel.
       3                 :            :  *
       4                 :            :  * David A Rusling
       5                 :            :  *
       6                 :            :  * Copyright (C) 2001 ARM Limited
       7                 :            :  *
       8                 :            :  * This file is subject to the terms and conditions of the GNU General Public
       9                 :            :  * License.  See the file COPYING in the main directory of this archive
      10                 :            :  * for more details.
      11                 :            :  */
      12                 :            : #include <linux/fb.h>
      13                 :            : 
      14                 :            : /*
      15                 :            :  * CLCD Controller Internal Register addresses
      16                 :            :  */
      17                 :            : #define CLCD_TIM0               0x00000000
      18                 :            : #define CLCD_TIM1               0x00000004
      19                 :            : #define CLCD_TIM2               0x00000008
      20                 :            : #define CLCD_TIM3               0x0000000c
      21                 :            : #define CLCD_UBAS               0x00000010
      22                 :            : #define CLCD_LBAS               0x00000014
      23                 :            : 
      24                 :            : #define CLCD_PL110_IENB         0x00000018
      25                 :            : #define CLCD_PL110_CNTL         0x0000001c
      26                 :            : #define CLCD_PL110_STAT         0x00000020
      27                 :            : #define CLCD_PL110_INTR         0x00000024
      28                 :            : #define CLCD_PL110_UCUR         0x00000028
      29                 :            : #define CLCD_PL110_LCUR         0x0000002C
      30                 :            : 
      31                 :            : #define CLCD_PL111_CNTL         0x00000018
      32                 :            : #define CLCD_PL111_IENB         0x0000001c
      33                 :            : #define CLCD_PL111_RIS          0x00000020
      34                 :            : #define CLCD_PL111_MIS          0x00000024
      35                 :            : #define CLCD_PL111_ICR          0x00000028
      36                 :            : #define CLCD_PL111_UCUR         0x0000002c
      37                 :            : #define CLCD_PL111_LCUR         0x00000030
      38                 :            : 
      39                 :            : #define CLCD_PALL               0x00000200
      40                 :            : #define CLCD_PALETTE            0x00000200
      41                 :            : 
      42                 :            : #define TIM2_CLKSEL             (1 << 5)
      43                 :            : #define TIM2_IVS                (1 << 11)
      44                 :            : #define TIM2_IHS                (1 << 12)
      45                 :            : #define TIM2_IPC                (1 << 13)
      46                 :            : #define TIM2_IOE                (1 << 14)
      47                 :            : #define TIM2_BCD                (1 << 26)
      48                 :            : 
      49                 :            : #define CNTL_LCDEN              (1 << 0)
      50                 :            : #define CNTL_LCDBPP1            (0 << 1)
      51                 :            : #define CNTL_LCDBPP2            (1 << 1)
      52                 :            : #define CNTL_LCDBPP4            (2 << 1)
      53                 :            : #define CNTL_LCDBPP8            (3 << 1)
      54                 :            : #define CNTL_LCDBPP16           (4 << 1)
      55                 :            : #define CNTL_LCDBPP16_565       (6 << 1)
      56                 :            : #define CNTL_LCDBPP16_444       (7 << 1)
      57                 :            : #define CNTL_LCDBPP24           (5 << 1)
      58                 :            : #define CNTL_LCDBW              (1 << 4)
      59                 :            : #define CNTL_LCDTFT             (1 << 5)
      60                 :            : #define CNTL_LCDMONO8           (1 << 6)
      61                 :            : #define CNTL_LCDDUAL            (1 << 7)
      62                 :            : #define CNTL_BGR                (1 << 8)
      63                 :            : #define CNTL_BEBO               (1 << 9)
      64                 :            : #define CNTL_BEPO               (1 << 10)
      65                 :            : #define CNTL_LCDPWR             (1 << 11)
      66                 :            : #define CNTL_LCDVCOMP(x)        ((x) << 12)
      67                 :            : #define CNTL_LDMAFIFOTIME       (1 << 15)
      68                 :            : #define CNTL_WATERMARK          (1 << 16)
      69                 :            : 
      70                 :            : enum {
      71                 :            :         /* individual formats */
      72                 :            :         CLCD_CAP_RGB444         = (1 << 0),
      73                 :            :         CLCD_CAP_RGB5551        = (1 << 1),
      74                 :            :         CLCD_CAP_RGB565         = (1 << 2),
      75                 :            :         CLCD_CAP_RGB888         = (1 << 3),
      76                 :            :         CLCD_CAP_BGR444         = (1 << 4),
      77                 :            :         CLCD_CAP_BGR5551        = (1 << 5),
      78                 :            :         CLCD_CAP_BGR565         = (1 << 6),
      79                 :            :         CLCD_CAP_BGR888         = (1 << 7),
      80                 :            : 
      81                 :            :         /* connection layouts */
      82                 :            :         CLCD_CAP_444            = CLCD_CAP_RGB444 | CLCD_CAP_BGR444,
      83                 :            :         CLCD_CAP_5551           = CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551,
      84                 :            :         CLCD_CAP_565            = CLCD_CAP_RGB565 | CLCD_CAP_BGR565,
      85                 :            :         CLCD_CAP_888            = CLCD_CAP_RGB888 | CLCD_CAP_BGR888,
      86                 :            : 
      87                 :            :         /* red/blue ordering */
      88                 :            :         CLCD_CAP_RGB            = CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 |
      89                 :            :                                   CLCD_CAP_RGB565 | CLCD_CAP_RGB888,
      90                 :            :         CLCD_CAP_BGR            = CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 |
      91                 :            :                                   CLCD_CAP_BGR565 | CLCD_CAP_BGR888,
      92                 :            : 
      93                 :            :         CLCD_CAP_ALL            = CLCD_CAP_BGR | CLCD_CAP_RGB,
      94                 :            : };
      95                 :            : 
      96                 :            : struct clcd_panel {
      97                 :            :         struct fb_videomode     mode;
      98                 :            :         signed short            width;  /* width in mm */
      99                 :            :         signed short            height; /* height in mm */
     100                 :            :         u32                     tim2;
     101                 :            :         u32                     tim3;
     102                 :            :         u32                     cntl;
     103                 :            :         u32                     caps;
     104                 :            :         unsigned int            bpp:8,
     105                 :            :                                 fixedtimings:1,
     106                 :            :                                 grayscale:1;
     107                 :            :         unsigned int            connector;
     108                 :            : };
     109                 :            : 
     110                 :            : struct clcd_regs {
     111                 :            :         u32                     tim0;
     112                 :            :         u32                     tim1;
     113                 :            :         u32                     tim2;
     114                 :            :         u32                     tim3;
     115                 :            :         u32                     cntl;
     116                 :            :         unsigned long           pixclock;
     117                 :            : };
     118                 :            : 
     119                 :            : struct clcd_fb;
     120                 :            : 
     121                 :            : /*
     122                 :            :  * the board-type specific routines
     123                 :            :  */
     124                 :            : struct clcd_board {
     125                 :            :         const char *name;
     126                 :            : 
     127                 :            :         /*
     128                 :            :          * Optional.  Hardware capability flags.
     129                 :            :          */
     130                 :            :         u32     caps;
     131                 :            : 
     132                 :            :         /*
     133                 :            :          * Optional.  Check whether the var structure is acceptable
     134                 :            :          * for this display.
     135                 :            :          */
     136                 :            :         int     (*check)(struct clcd_fb *fb, struct fb_var_screeninfo *var);
     137                 :            : 
     138                 :            :         /*
     139                 :            :          * Compulsory.  Decode fb->fb.var into regs->*.  In the case of
     140                 :            :          * fixed timing, set regs->* to the register values required.
     141                 :            :          */
     142                 :            :         void    (*decode)(struct clcd_fb *fb, struct clcd_regs *regs);
     143                 :            : 
     144                 :            :         /*
     145                 :            :          * Optional.  Disable any extra display hardware.
     146                 :            :          */
     147                 :            :         void    (*disable)(struct clcd_fb *);
     148                 :            : 
     149                 :            :         /*
     150                 :            :          * Optional.  Enable any extra display hardware.
     151                 :            :          */
     152                 :            :         void    (*enable)(struct clcd_fb *);
     153                 :            : 
     154                 :            :         /*
     155                 :            :          * Setup platform specific parts of CLCD driver
     156                 :            :          */
     157                 :            :         int     (*setup)(struct clcd_fb *);
     158                 :            : 
     159                 :            :         /*
     160                 :            :          * mmap the framebuffer memory
     161                 :            :          */
     162                 :            :         int     (*mmap)(struct clcd_fb *, struct vm_area_struct *);
     163                 :            : 
     164                 :            :         /*
     165                 :            :          * Remove platform specific parts of CLCD driver
     166                 :            :          */
     167                 :            :         void    (*remove)(struct clcd_fb *);
     168                 :            : };
     169                 :            : 
     170                 :            : struct amba_device;
     171                 :            : struct clk;
     172                 :            : 
     173                 :            : /* this data structure describes each frame buffer device we find */
     174                 :            : struct clcd_fb {
     175                 :            :         struct fb_info          fb;
     176                 :            :         struct amba_device      *dev;
     177                 :            :         struct clk              *clk;
     178                 :            :         struct clcd_panel       *panel;
     179                 :            :         struct clcd_board       *board;
     180                 :            :         void                    *board_data;
     181                 :            :         void __iomem            *regs;
     182                 :            :         u16                     off_ienb;
     183                 :            :         u16                     off_cntl;
     184                 :            :         u32                     clcd_cntl;
     185                 :            :         u32                     cmap[16];
     186                 :            :         bool                    clk_enabled;
     187                 :            : };
     188                 :            : 
     189                 :          0 : static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
     190                 :            : {
     191                 :            :         struct fb_var_screeninfo *var = &fb->fb.var;
     192                 :            :         u32 val, cpl;
     193                 :            : 
     194                 :            :         /*
     195                 :            :          * Program the CLCD controller registers and start the CLCD
     196                 :            :          */
     197                 :          0 :         val = ((var->xres / 16) - 1) << 2;
     198                 :          0 :         val |= (var->hsync_len - 1) << 8;
     199                 :          0 :         val |= (var->right_margin - 1) << 16;
     200                 :          0 :         val |= (var->left_margin - 1) << 24;
     201                 :          0 :         regs->tim0 = val;
     202                 :            : 
     203                 :          0 :         val = var->yres;
     204         [ #  # ]:          0 :         if (fb->panel->cntl & CNTL_LCDDUAL)
     205                 :          0 :                 val /= 2;
     206                 :          0 :         val -= 1;
     207                 :          0 :         val |= (var->vsync_len - 1) << 10;
     208                 :          0 :         val |= var->lower_margin << 16;
     209                 :          0 :         val |= var->upper_margin << 24;
     210                 :          0 :         regs->tim1 = val;
     211                 :            : 
     212                 :          0 :         val = fb->panel->tim2;
     213         [ #  # ]:          0 :         val |= var->sync & FB_SYNC_HOR_HIGH_ACT  ? 0 : TIM2_IHS;
     214         [ #  # ]:          0 :         val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS;
     215                 :            : 
     216                 :          0 :         cpl = var->xres_virtual;
     217         [ #  # ]:          0 :         if (fb->panel->cntl & CNTL_LCDTFT)      /* TFT */
     218                 :            :                 /* / 1 */;
     219         [ #  # ]:          0 :         else if (!var->grayscale)              /* STN color */
     220                 :          0 :                 cpl = cpl * 8 / 3;
     221         [ #  # ]:          0 :         else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
     222                 :          0 :                 cpl /= 8;
     223                 :            :         else                                      /* STN monochrome, 4bit */
     224                 :          0 :                 cpl /= 4;
     225                 :            : 
     226                 :          0 :         regs->tim2 = val | ((cpl - 1) << 16);
     227                 :            : 
     228                 :          0 :         regs->tim3 = fb->panel->tim3;
     229                 :            : 
     230                 :          0 :         val = fb->panel->cntl;
     231         [ #  # ]:          0 :         if (var->grayscale)
     232                 :          0 :                 val |= CNTL_LCDBW;
     233                 :            : 
     234 [ #  # ][ #  # ]:          0 :         if (fb->panel->caps && fb->board->caps &&
                 [ #  # ]
     235                 :          0 :             var->bits_per_pixel >= 16) {
     236                 :            :                 /*
     237                 :            :                  * if board and panel supply capabilities, we can support
     238                 :            :                  * changing BGR/RGB depending on supplied parameters
     239                 :            :                  */
     240         [ #  # ]:          0 :                 if (var->red.offset == 0)
     241                 :          0 :                         val &= ~CNTL_BGR;
     242                 :            :                 else
     243                 :          0 :                         val |= CNTL_BGR;
     244                 :            :         }
     245                 :            : 
     246   [ #  #  #  #  :          0 :         switch (var->bits_per_pixel) {
                   #  # ]
     247                 :            :         case 1:
     248                 :            :                 val |= CNTL_LCDBPP1;
     249                 :            :                 break;
     250                 :            :         case 2:
     251                 :          0 :                 val |= CNTL_LCDBPP2;
     252                 :          0 :                 break;
     253                 :            :         case 4:
     254                 :          0 :                 val |= CNTL_LCDBPP4;
     255                 :          0 :                 break;
     256                 :            :         case 8:
     257                 :          0 :                 val |= CNTL_LCDBPP8;
     258                 :          0 :                 break;
     259                 :            :         case 16:
     260                 :            :                 /*
     261                 :            :                  * PL110 cannot choose between 5551 and 565 modes in its
     262                 :            :                  * control register.  It is possible to use 565 with
     263                 :            :                  * custom external wiring.
     264                 :            :                  */
     265 [ #  # ][ #  # ]:          0 :                 if (amba_part(fb->dev) == 0x110 ||
     266                 :          0 :                     var->green.length == 5)
     267                 :          0 :                         val |= CNTL_LCDBPP16;
     268         [ #  # ]:          0 :                 else if (var->green.length == 6)
     269                 :          0 :                         val |= CNTL_LCDBPP16_565;
     270                 :            :                 else
     271                 :          0 :                         val |= CNTL_LCDBPP16_444;
     272                 :            :                 break;
     273                 :            :         case 32:
     274                 :          0 :                 val |= CNTL_LCDBPP24;
     275                 :          0 :                 break;
     276                 :            :         }
     277                 :            : 
     278                 :          0 :         regs->cntl = val;
     279                 :          0 :         regs->pixclock = var->pixclock;
     280                 :          0 : }
     281                 :            : 
     282                 :          0 : static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
     283                 :            : {
     284                 :          0 :         var->xres_virtual = var->xres = (var->xres + 15) & ~15;
     285                 :          0 :         var->yres_virtual = var->yres = (var->yres + 1) & ~1;
     286                 :            : 
     287                 :            : #define CHECK(e,l,h) (var->e < l || var->e > h)
     288 [ #  # ][ #  # ]:          0 :         if (CHECK(right_margin, (5+1), 256) ||  /* back porch */
     289         [ #  # ]:          0 :             CHECK(left_margin, (5+1), 256) ||   /* front porch */
     290         [ #  # ]:          0 :             CHECK(hsync_len, (5+1), 256) ||
     291         [ #  # ]:          0 :             var->xres > 4096 ||
     292         [ #  # ]:          0 :             var->lower_margin > 255 ||            /* back porch */
     293         [ #  # ]:          0 :             var->upper_margin > 255 ||            /* front porch */
     294         [ #  # ]:          0 :             var->vsync_len > 32 ||
     295                 :            :             var->yres > 1024)
     296                 :            :                 return -EINVAL;
     297                 :            : #undef CHECK
     298                 :            : 
     299                 :            :         /* single panel mode: PCD = max(PCD, 1) */
     300                 :            :         /* dual panel mode: PCD = max(PCD, 5) */
     301                 :            : 
     302                 :            :         /*
     303                 :            :          * You can't change the grayscale setting, and
     304                 :            :          * we can only do non-interlaced video.
     305                 :            :          */
     306 [ #  # ][ #  # ]:          0 :         if (var->grayscale != fb->fb.var.grayscale ||
     307                 :          0 :             (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
     308                 :            :                 return -EINVAL;
     309                 :            : 
     310                 :            : #define CHECK(e) (var->e != fb->fb.var.e)
     311 [ #  # ][ #  # ]:          0 :         if (fb->panel->fixedtimings &&
     312         [ #  # ]:          0 :             (CHECK(xres)                ||
     313         [ #  # ]:          0 :              CHECK(yres)                ||
     314         [ #  # ]:          0 :              CHECK(bits_per_pixel)      ||
     315         [ #  # ]:          0 :              CHECK(pixclock)            ||
     316         [ #  # ]:          0 :              CHECK(left_margin)         ||
     317         [ #  # ]:          0 :              CHECK(right_margin)        ||
     318         [ #  # ]:          0 :              CHECK(upper_margin)        ||
     319         [ #  # ]:          0 :              CHECK(lower_margin)        ||
     320         [ #  # ]:          0 :              CHECK(hsync_len)           ||
     321         [ #  # ]:          0 :              CHECK(vsync_len)           ||
     322                 :          0 :              CHECK(sync)))
     323                 :            :                 return -EINVAL;
     324                 :            : #undef CHECK
     325                 :            : 
     326                 :          0 :         var->nonstd = 0;
     327                 :          0 :         var->accel_flags = 0;
     328                 :            : 
     329                 :          0 :         return 0;
     330                 :            : }

Generated by: LCOV version 1.9