]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/video/imx25lcdc.c
Merge branch 'u-boot-microblaze/zynq' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / video / imx25lcdc.c
1 /*
2  * (C) Copyright 2011
3  * Matthias Weisser <weisserm@arcor.de>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  *
7  * imx25lcdc.c - Graphic interface for i.MX25 lcd controller
8  */
9
10 #include <common.h>
11
12 #include <malloc.h>
13 #include <asm/io.h>
14 #include <asm/arch/imx-regs.h>
15 #include <video_fb.h>
16 #include "videomodes.h"
17
18 /*
19  * 4MB (at the end of system RAM)
20  */
21 #define VIDEO_MEM_SIZE          0x400000
22
23 #define FB_SYNC_CLK_INV         (1<<16) /* pixel clock inverted */
24
25 /*
26  * Graphic Device
27  */
28 static GraphicDevice imx25fb;
29
30 void *video_hw_init(void)
31 {
32         struct lcdc_regs *lcdc = (struct lcdc_regs *)IMX_LCDC_BASE;
33         struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE;
34         GraphicDevice *pGD = &imx25fb;
35         char *s;
36         u32 *videomem;
37
38         memset(pGD, 0, sizeof(GraphicDevice));
39
40         pGD->gdfIndex = GDF_16BIT_565RGB;
41         pGD->gdfBytesPP = 2;
42         pGD->memSize = VIDEO_MEM_SIZE;
43         pGD->frameAdrs = PHYS_SDRAM + PHYS_SDRAM_SIZE - VIDEO_MEM_SIZE;
44
45         videomem = (u32 *)pGD->frameAdrs;
46
47         s = getenv("videomode");
48         if (s != NULL) {
49                 struct ctfb_res_modes var_mode;
50                 u32 lsr, lpcr, lhcr, lvcr;
51                 unsigned long div;
52                 int bpp;
53
54                 /* Disable all clocks of the LCDC */
55                 writel(readl(&ccm->cgr0) & ~((1<<7) | (1<<24)), &ccm->cgr0);
56                 writel(readl(&ccm->cgr1) & ~(1<<29), &ccm->cgr1);
57
58                 bpp = video_get_params(&var_mode, s);
59
60                 if (bpp == 0) {
61                         var_mode.xres = 320;
62                         var_mode.yres = 240;
63                         var_mode.pixclock = 154000;
64                         var_mode.left_margin = 68;
65                         var_mode.right_margin = 20;
66                         var_mode.upper_margin = 4;
67                         var_mode.lower_margin = 18;
68                         var_mode.hsync_len = 40;
69                         var_mode.vsync_len = 6;
70                         var_mode.sync = 0;
71                         var_mode.vmode = 0;
72                 }
73
74                 /* Fill memory with white */
75                 memset(videomem, 0xFF, var_mode.xres * var_mode.yres * 2);
76
77                 imx25fb.winSizeX = var_mode.xres;
78                 imx25fb.winSizeY = var_mode.yres;
79
80                 /* LCD base clock is 66.6MHZ. We do calculations in kHz */
81                 div = 66000 / (1000000000L / var_mode.pixclock);
82                 if (div > 63)
83                         div = 63;
84                 if (0 == div)
85                         div = 1;
86
87                 lsr = ((var_mode.xres / 16) << 20) |
88                         var_mode.yres;
89                 lpcr =  (1 << 31) |
90                         (1 << 30) |
91                         (5 << 25) |
92                         (1 << 23) |
93                         (1 << 22) |
94                         (1 << 19) |
95                         (1 <<  7) |
96                         div;
97                 lhcr =  (var_mode.right_margin << 0) |
98                         (var_mode.left_margin << 8) |
99                         (var_mode.hsync_len << 26);
100
101                 lvcr =  (var_mode.lower_margin << 0) |
102                         (var_mode.upper_margin << 8) |
103                         (var_mode.vsync_len << 26);
104
105                 writel((uint32_t)videomem, &lcdc->lssar);
106                 writel(lsr, &lcdc->lsr);
107                 writel(var_mode.xres * 2 / 4, &lcdc->lvpwr);
108                 writel(lpcr, &lcdc->lpcr);
109                 writel(lhcr, &lcdc->lhcr);
110                 writel(lvcr, &lcdc->lvcr);
111                 writel(0x00040060, &lcdc->ldcr);
112
113                 writel(0xA90300, &lcdc->lpccr);
114
115                 /* Ensable all clocks of the LCDC */
116                 writel(readl(&ccm->cgr0) | ((1<<7) | (1<<24)), &ccm->cgr0);
117                 writel(readl(&ccm->cgr1) | (1<<29), &ccm->cgr1);
118         }
119
120         return pGD;
121 }