Blame view

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