blob: 4fc6ee33dc9270fcbb891d639df9f967f5b672d3 [file] [log] [blame]
Channagoud Kadabi43000a62012-06-28 18:23:24 +05301/*
Padmanabhan Komandurufa4be752012-10-08 16:51:56 +05302 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Channagoud Kadabi43000a62012-06-28 18:23:24 +05303 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in
11 * the documentation and/or other materials provided with the
12 * distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
21 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <debug.h>
29#include <stdlib.h>
30#include <reg.h>
31#include <platform/iomap.h>
32#include <dev/fbcon.h>
33#include <target/display.h>
34#include <dev/lcdc.h>
35#include <msm_panel.h>
36#include <err.h>
37#include <mdp4.h>
38#include <bits.h>
39
40int mdp_lcdc_config(struct msm_panel_info *pinfo,
41 struct fbcon_config *fb)
42{
43 unsigned mdp_rgb_size;
44 unsigned mdp_rgb_size_src;
45 int hsync_period, vsync_period;
46 int hsync_start_x, hsync_end_x;
47 int display_hctl, display_vstart, display_vend;
48 unsigned mdp_rgb_format = 0;
49
50 int active_x, active_y;
51 int active_hstart_x, active_hend_x;
52 int active_vstart, active_vend;
53 int mdp_rev;
54
55 struct lcdc_panel_info *lcdc = NULL;
56
57 if (pinfo == NULL)
58 return;
59
60 lcdc = &(pinfo->lcdc);
61 if (lcdc == NULL)
62 return;
63
64 mdp_rev = mdp_get_revision();
65
66 mdp_rgb_size = (pinfo->yres << 16) + pinfo->xres;
67 mdp_rgb_size_src = (fb->height << 16) + fb->width;
68
69 dprintf(INFO, "Panel is %d x %d\n",
70 pinfo->xres + lcdc->xres_pad,
71 pinfo->yres + lcdc->yres_pad);
72
73 /* write fb addr in MDP_DMA_P_BUF_ADDR */
74 writel(fb->base, MDP_DMA_P_BUF_ADDR);
75
76 /* write active region size*/
77 writel(mdp_rgb_size, MDP_DMA_P_SIZE);
78
79 /* set Y-stride value in bytes */
80 /* Y-stride is defined as the number of bytes
81 in a line.
82 */
83 writel((pinfo->xres * pinfo->bpp/8), MDP_DMA_P_BUF_Y_STRIDE);
84
85 /* Start XY coordinates */
86 writel(0, MDP_DMA_P_OUT_XY);
87
88 if (fb->bpp == 16) {
89 writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
90 DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
91 DMA_IBUF_FORMAT_RGB565 | DMA_DSTC0G_6BITS |
92 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS,
93 MDP_DMA_P_CONFIG);
94 mdp_rgb_format = MDP_RGB_565_FORMAT;
95 } else if (fb->bpp == 24) {
96 writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
97 DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
98 DMA_IBUF_FORMAT_RGB888 | DMA_DSTC0G_8BITS |
99 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS,
100 MDP_DMA_P_CONFIG);
101 mdp_rgb_format = MDP_RGB_888_FORMAT;
102 } else {
103 dprintf(CRITICAL, "Unsupported bpp detected!\n");
104 return ERR_INVALID_ARGS;
105 }
106
107 hsync_period = lcdc->h_pulse_width +
108 lcdc->h_back_porch +
109 pinfo->xres + lcdc->h_front_porch;
110 vsync_period = (lcdc->v_pulse_width +
111 lcdc->v_back_porch +
112 pinfo->yres +
113 lcdc->v_front_porch) *
114 hsync_period;
115 hsync_start_x =
116 lcdc->h_pulse_width +
117 lcdc->h_back_porch;
118 hsync_end_x =
119 hsync_period - lcdc->h_front_porch - 1;
120 display_hctl = (hsync_end_x << 16) | hsync_start_x;
121 display_vstart = (lcdc->v_pulse_width +
122 lcdc->v_back_porch)
123 * hsync_period + lcdc->hsync_skew;
124 display_vend = vsync_period -
125 (lcdc->v_front_porch * hsync_period)
126 +lcdc->hsync_skew - 1;
127
128 active_x = (pinfo->xres - fb->width)/2;
129 active_y = (pinfo->yres - fb->height)/2;
130
131 active_hstart_x = lcdc->h_pulse_width + lcdc->h_back_porch
132 + active_x;
133 active_hend_x = active_hstart_x + fb->width - 1;
134
135 active_vstart = (lcdc->v_pulse_width + lcdc->v_back_porch
136 + active_y) * hsync_period
137 + lcdc->hsync_skew;
138 active_vend = active_vstart + (fb->height * hsync_period) - 1;
139
140
141 /* LCDC specific initalizations */
142 writel((hsync_period << 16) | lcdc->h_pulse_width,
143 MDP_LCDC_HSYNC_CTL);
144 writel(vsync_period, MDP_LCDC_VSYNC_PERIOD);
145 writel(lcdc->v_pulse_width * hsync_period,
146 MDP_LCDC_VSYNC_PULSE_WIDTH);
147 writel(display_hctl, MDP_LCDC_DISPLAY_HCTL);
148 writel(display_vstart, MDP_LCDC_DISPLAY_V_START);
149 writel(display_vend, MDP_LCDC_DISPLAY_V_END);
150
151 if (mdp_rev >= MDP_REV_40) {
152 writel(BIT(31) | (active_hend_x << 16) | active_hstart_x,
153 MDP_LCDC_ACTIVE_HCTL);
154
155 writel(BIT(31) | active_vstart, MDP_LCDC_ACTIVE_V_START);
156 writel(active_vend, MDP_LCDC_ACTIVE_V_END);
157
158 writel(0xf, MDP_LCDC_BORDER_CLR);
159 writel(0xff, MDP_LCDC_UNDERFLOW_CTL);
160 writel(lcdc->hsync_skew,
161 MDP_LCDC_HSYNC_SKEW);
162 writel(0x3, MDP_LCDC_CTL_POLARITY);
163 writel(0, MDP_LCDC_ACTIVE_HCTL);
164 writel(0, MDP_LCDC_ACTIVE_V_START);
165 writel(0, MDP_LCDC_ACTIVE_V_END);
166
167 /* setting for single layer direct out mode for rgb565 source */
168 writel(0x100, MDP_LAYERMIXER_IN_CFG);
169 writel(mdp_rgb_size_src, MDP_RGB1_SRC_SIZE);
170 writel(mdp_rgb_size, MDP_RGB1_OUT_SIZE);
171 writel((int)fb->base, MDP_RGB1_SRCP0_ADDR);
172 writel((fb->stride * fb->bpp / 8), MDP_RGB1_SRC_YSTRIDE1);
173 writel(0x00, MDP_RGB1_CONSTANT_COLOR);
174 writel(mdp_rgb_format, MDP_RGB1_SRC_FORMAT);
175 writel(0x1, MDP_OVERLAYPROC0_CFG);
176 if (fb->bpp == 16)
177 writel(0x1, MDP_OVERLAYPROC0_OPMODE);
178 else if (fb->bpp == 24)
179 writel(0x0, MDP_OVERLAYPROC0_OPMODE);
180 /* register flush and enable LCDC */
181 writel(0x11, MDP_OVERLAY_REG_FLUSH);
182 } else if (MDP_REV_303 == mdp_rev) {
183 writel(0x0, MDP_BASE + LCDC_BASE + 0x28);
184 writel(0xff, MDP_BASE + LCDC_BASE + 0x2c);
185 writel(lcdc->hsync_skew, MDP_BASE + LCDC_BASE + 0x30);
186 writel(0x0, MDP_BASE + LCDC_BASE + 0x38);
187 writel(0x0, MDP_BASE + LCDC_BASE + 0x1c);
188 writel(0x0, MDP_BASE + LCDC_BASE + 0x20);
189 writel(0x0, MDP_BASE + LCDC_BASE + 0x24);
190 }
191 return NO_ERROR;
192}
193
194int mdp_lcdc_on()
195{
196 writel(0x1, MDP_LCDC_EN);
197 return NO_ERROR;
198}
199
200int mdp_lcdc_off()
201{
Padmanabhan Komandurufa4be752012-10-08 16:51:56 +0530202 if(!target_cont_splash_screen())
203 writel(0x0, MDP_LCDC_EN);
Channagoud Kadabi43000a62012-06-28 18:23:24 +0530204 return NO_ERROR;
205}