blob: dff03c811401efa0daa87000f3ebd87cb0b1d268 [file] [log] [blame]
Ajay Dudani232ce812009-12-02 00:14:11 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
Duy Truongf3ac7b32013-02-13 01:07:28 -08005 * Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
Shashank Mittal37040832010-08-24 15:57:57 -07006 *
Ajay Dudani232ce812009-12-02 00:14:11 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
Channagoud Kadabi43000a62012-06-28 18:23:24 +053014 * the documentation and/or other materials provided with the
Ajay Dudani232ce812009-12-02 00:14:11 -080015 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
Channagoud Kadabi43000a62012-06-28 18:23:24 +053024 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
Ajay Dudani232ce812009-12-02 00:14:11 -080025 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <debug.h>
32#include <stdlib.h>
33#include <reg.h>
34#include <platform/iomap.h>
35#include <dev/fbcon.h>
Chandan Uddaraju07644852010-07-14 12:07:11 -070036#include <target/display.h>
Wentao Xu97df7fd2011-01-19 15:01:17 -050037#include <dev/lcdc.h>
Ajay Dudani232ce812009-12-02 00:14:11 -080038
Shashank Mittal402d0972010-09-29 10:09:52 -070039#if PLATFORM_MSM7X30
Shashank Mittal37040832010-08-24 15:57:57 -070040#define MSM_MDP_BASE1 0xA3F00000
41#define LCDC_BASE 0xC0000
Shashank Mittal402d0972010-09-29 10:09:52 -070042#elif PLATFORM_MSM8X60
43#define MSM_MDP_BASE1 0x05100000
44#define LCDC_BASE 0xC0000
45#define LCDC_FB_ADDR 0x43E00000
Shashank Mittal37040832010-08-24 15:57:57 -070046#else
Ajay Dudani232ce812009-12-02 00:14:11 -080047#define MSM_MDP_BASE1 0xAA200000
Shashank Mittal37040832010-08-24 15:57:57 -070048#define LCDC_BASE 0xE0000
49#endif
Ajay Dudani232ce812009-12-02 00:14:11 -080050
51#define LCDC_PIXCLK_IN_PS 26
52#define LCDC_FB_PHYS 0x16600000
53#define LCDC_FB_BPP 16
54
Ajay Dudani232ce812009-12-02 00:14:11 -080055#define BIT(x) (1<<(x))
56#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0))
57#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2))
58#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4))
59#define CLR_G 0x0
60#define CLR_B 0x1
61#define CLR_R 0x2
62#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
63#define DMA_PACK_ALIGN_LSB 0
64#define DMA_PACK_PATTERN_RGB \
65 (MDP_GET_PACK_PATTERN(0,CLR_R,CLR_G,CLR_B,2)<<8)
66#define DMA_DITHER_EN BIT(24)
67#define DMA_OUT_SEL_LCDC BIT(20)
68#define DMA_IBUF_FORMAT_RGB565 BIT(25)
69
Ajay Dudani5b1d0452010-11-11 19:07:30 -080070#define MDP_RGB_565_FORMAT (BIT(14) | (1<<9) | (0<<8) | (0<<6) | (1<<4) | (1<<2) | (2<<0))
71
Ajay Dudani232ce812009-12-02 00:14:11 -080072static struct fbcon_config fb_cfg = {
Ajay Dudanib01e5062011-12-03 23:23:42 -080073 .height = LCDC_FB_HEIGHT,
74 .width = LCDC_FB_WIDTH,
75 .stride = LCDC_FB_WIDTH,
76 .format = FB_FORMAT_RGB565,
77 .bpp = LCDC_FB_BPP,
78 .update_start = NULL,
79 .update_done = NULL,
Ajay Dudani232ce812009-12-02 00:14:11 -080080};
81
82void lcdc_clock_init(unsigned rate);
83
Ajay Dudanib01e5062011-12-03 23:23:42 -080084struct fbcon_config *lcdc_init_set(struct lcdc_timing_parameters
85 *custom_timing_param)
Ajay Dudani232ce812009-12-02 00:14:11 -080086{
Wentao Xu97df7fd2011-01-19 15:01:17 -050087 struct lcdc_timing_parameters timing_param;
88 unsigned mdp_rgb_size;
89
Ajay Dudanib01e5062011-12-03 23:23:42 -080090 if (custom_timing_param == DEFAULT_LCD_TIMING) {
91 timing_param.lcdc_hsync_pulse_width_dclk =
92 LCDC_HSYNC_PULSE_WIDTH_DCLK;
93 timing_param.lcdc_hsync_back_porch_dclk =
94 LCDC_HSYNC_BACK_PORCH_DCLK;
95 timing_param.lcdc_hsync_front_porch_dclk =
96 LCDC_HSYNC_FRONT_PORCH_DCLK;
97 timing_param.lcdc_hsync_skew_dclk = LCDC_HSYNC_SKEW_DCLK;
Wentao Xu97df7fd2011-01-19 15:01:17 -050098
Ajay Dudanib01e5062011-12-03 23:23:42 -080099 timing_param.lcdc_vsync_pulse_width_lines =
100 LCDC_VSYNC_PULSE_WIDTH_LINES;
101 timing_param.lcdc_vsync_back_porch_lines =
102 LCDC_VSYNC_BACK_PORCH_LINES;
103 timing_param.lcdc_vsync_front_porch_lines =
104 LCDC_VSYNC_FRONT_PORCH_LINES;
105 } else {
106 /*use custom timing parameters */
107 timing_param.lcdc_hsync_pulse_width_dclk =
108 custom_timing_param->lcdc_hsync_pulse_width_dclk;
109 timing_param.lcdc_hsync_back_porch_dclk =
110 custom_timing_param->lcdc_hsync_back_porch_dclk;
111 timing_param.lcdc_hsync_front_porch_dclk =
112 custom_timing_param->lcdc_hsync_front_porch_dclk;
113 timing_param.lcdc_hsync_skew_dclk =
114 custom_timing_param->lcdc_hsync_skew_dclk;
Wentao Xu97df7fd2011-01-19 15:01:17 -0500115
Ajay Dudanib01e5062011-12-03 23:23:42 -0800116 timing_param.lcdc_vsync_pulse_width_lines =
117 custom_timing_param->lcdc_vsync_pulse_width_lines;
118 timing_param.lcdc_vsync_back_porch_lines =
119 custom_timing_param->lcdc_vsync_back_porch_lines;
120 timing_param.lcdc_vsync_front_porch_lines =
121 custom_timing_param->lcdc_vsync_front_porch_lines;
Wentao Xu97df7fd2011-01-19 15:01:17 -0500122
123 /* only set when using custom timing since initialized with defaults */
124 fb_cfg.height = custom_timing_param->lcdc_fb_height;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800125 fb_cfg.width = custom_timing_param->lcdc_fb_width;
Wentao Xu97df7fd2011-01-19 15:01:17 -0500126 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800127 mdp_rgb_size = (fb_cfg.height << 16) + fb_cfg.width;
Wentao Xu97df7fd2011-01-19 15:01:17 -0500128
Ajay Dudanib01e5062011-12-03 23:23:42 -0800129 dprintf(INFO, "lcdc_init(): panel is %d x %d\n", fb_cfg.width,
130 fb_cfg.height);
Shashank Mittal402d0972010-09-29 10:09:52 -0700131 fb_cfg.base = LCDC_FB_ADDR;
Ajay Dudani232ce812009-12-02 00:14:11 -0800132
Ajay Dudanib01e5062011-12-03 23:23:42 -0800133 writel((unsigned)fb_cfg.base, MSM_MDP_BASE1 + 0x90008);
Ajay Dudani232ce812009-12-02 00:14:11 -0800134
135 writel((fb_cfg.height << 16) | fb_cfg.width, MSM_MDP_BASE1 + 0x90004);
136 writel(fb_cfg.width * fb_cfg.bpp / 8, MSM_MDP_BASE1 + 0x9000c);
137 writel(0, MSM_MDP_BASE1 + 0x90010);
138
Ajay Dudanib01e5062011-12-03 23:23:42 -0800139 writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB | DMA_DITHER_EN |
140 DMA_OUT_SEL_LCDC | DMA_IBUF_FORMAT_RGB565 | DMA_DSTC0G_8BITS |
141 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS, MSM_MDP_BASE1 + 0x90000);
Ajay Dudani232ce812009-12-02 00:14:11 -0800142
Ajay Dudanib01e5062011-12-03 23:23:42 -0800143 int hsync_period = timing_param.lcdc_hsync_pulse_width_dclk +
144 timing_param.lcdc_hsync_back_porch_dclk +
145 fb_cfg.width + timing_param.lcdc_hsync_front_porch_dclk;
146 int vsync_period = (timing_param.lcdc_vsync_pulse_width_lines +
147 timing_param.lcdc_vsync_back_porch_lines +
148 fb_cfg.height +
149 timing_param.lcdc_vsync_front_porch_lines) *
150 hsync_period;
151 int hsync_start_x =
152 timing_param.lcdc_hsync_pulse_width_dclk +
153 timing_param.lcdc_hsync_back_porch_dclk;
154 int hsync_end_x =
155 hsync_period - timing_param.lcdc_hsync_front_porch_dclk - 1;
156 int display_hctl = (hsync_end_x << 16) | hsync_start_x;
157 int display_vstart = (timing_param.lcdc_vsync_pulse_width_lines +
158 timing_param.lcdc_vsync_back_porch_lines)
159 * hsync_period + timing_param.lcdc_hsync_skew_dclk;
160 int display_vend = vsync_period -
161 (timing_param.lcdc_vsync_front_porch_lines * hsync_period)
162 + timing_param.lcdc_hsync_skew_dclk - 1;
Ajay Dudani232ce812009-12-02 00:14:11 -0800163
Ajay Dudanib01e5062011-12-03 23:23:42 -0800164 writel((hsync_period << 16) | timing_param.lcdc_hsync_pulse_width_dclk,
165 MSM_MDP_BASE1 + LCDC_BASE + 0x4);
Shashank Mittal37040832010-08-24 15:57:57 -0700166 writel(vsync_period, MSM_MDP_BASE1 + LCDC_BASE + 0x8);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800167 writel(timing_param.lcdc_vsync_pulse_width_lines * hsync_period,
168 MSM_MDP_BASE1 + LCDC_BASE + 0xc);
Shashank Mittal37040832010-08-24 15:57:57 -0700169 writel(display_hctl, MSM_MDP_BASE1 + LCDC_BASE + 0x10);
170 writel(display_vstart, MSM_MDP_BASE1 + LCDC_BASE + 0x14);
171 writel(display_vend, MSM_MDP_BASE1 + LCDC_BASE + 0x18);
Ajay Dudani5b1d0452010-11-11 19:07:30 -0800172
Shashank Mittal37040832010-08-24 15:57:57 -0700173#if MDP4
174 writel(0xf, MSM_MDP_BASE1 + LCDC_BASE + 0x28);
Shashank Mittal37040832010-08-24 15:57:57 -0700175 writel(0xff, MSM_MDP_BASE1 + LCDC_BASE + 0x2c);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800176 writel(timing_param.lcdc_hsync_skew_dclk,
177 MSM_MDP_BASE1 + LCDC_BASE + 0x30);
Shashank Mittal37040832010-08-24 15:57:57 -0700178 writel(0x3, MSM_MDP_BASE1 + LCDC_BASE + 0x38);
Shashank Mittal37040832010-08-24 15:57:57 -0700179 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x1c);
180 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x20);
181 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x24);
Ajay Dudani5b1d0452010-11-11 19:07:30 -0800182
183 /* setting for single layer direct out mode for rgb565 source */
184 writel(0x100, MSM_MDP_BASE1 + 0x10100);
Wentao Xu97df7fd2011-01-19 15:01:17 -0500185 writel(mdp_rgb_size, MSM_MDP_BASE1 + 0x40000);
186 writel(mdp_rgb_size, MSM_MDP_BASE1 + 0x40008);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800187 writel((int)fb_cfg.base, MSM_MDP_BASE1 + 0x40010);
Ajay Dudani5b1d0452010-11-11 19:07:30 -0800188 writel(fb_cfg.width * fb_cfg.bpp / 8, MSM_MDP_BASE1 + 0x40040);
189 writel(0x00, MSM_MDP_BASE1 + 0x41008);
190 writel(MDP_RGB_565_FORMAT, MSM_MDP_BASE1 + 0x40050);
191 writel(0x1, MSM_MDP_BASE1 + 0x10004);
192 writel(0x1, MSM_MDP_BASE1 + 0x10014);
193
194 /* register flush and enable LCDC */
195 writel(0x11, MSM_MDP_BASE1 + 0x18000);
196 writel(0x1, MSM_MDP_BASE1 + LCDC_BASE + 0x0);
197
198#else
199 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x28);
200 writel(0xff, MSM_MDP_BASE1 + LCDC_BASE + 0x2c);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800201 writel(timing_param.lcdc_hsync_skew_dclk,
202 MSM_MDP_BASE1 + LCDC_BASE + 0x30);
Ajay Dudani5b1d0452010-11-11 19:07:30 -0800203 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x38);
204 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x1c);
205 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x20);
206 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x24);
Shashank Mittal37040832010-08-24 15:57:57 -0700207 writel(1, MSM_MDP_BASE1 + LCDC_BASE + 0x0);
Ajay Dudani5b1d0452010-11-11 19:07:30 -0800208#endif
Ajay Dudani232ce812009-12-02 00:14:11 -0800209
210 return &fb_cfg;
211}
Shashank Mittal4f99a882010-02-01 13:58:50 -0800212
Wentao Xu97df7fd2011-01-19 15:01:17 -0500213struct fbcon_config *lcdc_init(void)
214{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800215 return lcdc_init_set(DEFAULT_LCD_TIMING);
Wentao Xu97df7fd2011-01-19 15:01:17 -0500216}
217
Shashank Mittalc648e712010-10-06 18:37:42 -0700218void lcdc_shutdown(void)
219{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800220 writel(0, MSM_MDP_BASE1 + LCDC_BASE + 0x0);
Shashank Mittalc648e712010-10-06 18:37:42 -0700221}