1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/hrtimer.h>
25#include <linux/delay.h>
26#include <mach/hardware.h>
27#include <linux/io.h>
28
29#include <asm/system.h>
30#include <asm/mach-types.h>
31#include <linux/semaphore.h>
32#include <linux/spinlock.h>
33
34#include <linux/fb.h>
35
36#include "mdp.h"
37#include "msm_fb.h"
38#include "mdp4.h"
39
40static struct mdp4_overlay_pipe *mddi_pipe;
41static struct mdp4_overlay_pipe *pending_pipe;
42static struct msm_fb_data_type *mddi_mfd;
43
44#define WHOLESCREEN
45
46void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd)
47{
48 MDPIBUF *iBuf = &mfd->ibuf;
49 uint8 *src;
50 int bpp, ptype;
51 uint32 format;
52 uint32 mddi_ld_param;
53 uint16 mddi_vdo_packet_reg;
54 struct mdp4_overlay_pipe *pipe;
55
56 if (mfd->key != MFD_KEY)
57 return;
58
59 mddi_mfd = mfd;
60
61 bpp = iBuf->bpp;
62
63 if (bpp == 2)
64 format = MDP_RGB_565;
65 else if (bpp == 3)
66 format = MDP_RGB_888;
67 else
68 format = MDP_ARGB_8888;
69
70
71 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
72
73 if (mddi_pipe == NULL) {
74 ptype = mdp4_overlay_format2type(format);
75 pipe = mdp4_overlay_pipe_alloc();
76 pipe->pipe_type = ptype;
77
78 pipe->pipe_num = OVERLAY_PIPE_RGB1;
79 pipe->mixer_num = MDP4_MIXER0;
80 pipe->src_format = format;
81 mdp4_overlay_format2pipe(pipe);
82
83 mddi_pipe = pipe;
84
85 mddi_ld_param = 0;
86 mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt;
87
88 if (mfd->panel_info.type == MDDI_PANEL) {
89 if (mfd->panel_info.pdest == DISPLAY_1)
90 mddi_ld_param = 0;
91 else
92 mddi_ld_param = 1;
93 } else {
94 mddi_ld_param = 2;
95 }
96
97 MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param);
98 MDP_OUTP(MDP_BASE + 0x00094,
99 (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg);
100 } else {
101 pipe = mddi_pipe;
102 }
103
104
105 src = (uint8 *) iBuf->buf;
106
107#ifdef WHOLESCREEN
108 {
109 struct fb_info *fbi;
110
111 fbi = mfd->fbi;
112 pipe->src_height = fbi->var.yres;
113 pipe->src_width = fbi->var.xres;
114 pipe->src_h = fbi->var.yres;
115 pipe->src_w = fbi->var.xres;
116 pipe->src_y = 0;
117 pipe->src_x = 0;
118 pipe->dst_h = fbi->var.yres;
119 pipe->dst_w = fbi->var.xres;
120 pipe->dst_y = 0;
121 pipe->dst_x = 0;
122 pipe->srcp0_addr = (uint32)src;
123 pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
124 }
125
126#else
127 if (mdp4_overlay_active(MDP4_MIXER0)) {
128 struct fb_info *fbi;
129
130 fbi = mfd->fbi;
131 pipe->src_height = fbi->var.yres;
132 pipe->src_width = fbi->var.xres;
133 pipe->src_h = fbi->var.yres;
134 pipe->src_w = fbi->var.xres;
135 pipe->src_y = 0;
136 pipe->src_x = 0;
137 pipe->dst_h = fbi->var.yres;
138 pipe->dst_w = fbi->var.xres;
139 pipe->dst_y = 0;
140 pipe->dst_x = 0;
141 pipe->srcp0_addr = (uint32) src;
142 pipe->srcp0_ystride = fbi->var.xres_virtual * bpp;
143 } else {
144
145 src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * bpp;
146
147 pipe->src_height = iBuf->dma_h;
148 pipe->src_width = iBuf->dma_w;
149 pipe->src_h = iBuf->dma_h;
150 pipe->src_w = iBuf->dma_w;
151 pipe->src_y = 0;
152 pipe->src_x = 0;
153 pipe->dst_h = iBuf->dma_h;
154 pipe->dst_w = iBuf->dma_w;
155 pipe->dst_y = iBuf->dma_y;
156 pipe->dst_x = iBuf->dma_x;
157 pipe->srcp0_addr = (uint32) src;
158 pipe->srcp0_ystride = iBuf->ibuf_width * bpp;
159 }
160#endif
161
162 pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
163
164 mdp4_overlay_rgb_setup(pipe);
165
166 mdp4_mixer_stage_up(pipe);
167
168 mdp4_overlayproc_cfg(pipe);
169
170 mdp4_overlay_dmap_xy(pipe);
171
172 mdp4_overlay_dmap_cfg(mfd, 0);
173
174
175 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
176
177}
178
179
180
181
182void mdp4_overlay0_done_mddi()
183{
184 if (pending_pipe)
185 complete(&pending_pipe->comp);
186}
187
188void mdp4_mddi_overlay_restore(void)
189{
190
191 mdp4_overlay_update_lcd(mddi_mfd);
192 mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe);
193}
194
195void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
196 struct mdp4_overlay_pipe *pipe)
197{
198#ifdef MDP4_NONBLOCKING
199 unsigned long flag;
200
201 spin_lock_irqsave(&mdp_spin_lock, flag);
202 if (mfd->dma->busy == TRUE) {
203 INIT_COMPLETION(pipe->comp);
204 pending_pipe = pipe;
205 }
206 spin_unlock_irqrestore(&mdp_spin_lock, flag);
207
208 if (pending_pipe != NULL) {
209
210 wait_for_completion_killable(&pipe->comp);
211 pending_pipe = NULL;
212 }
213 down(&mfd->sem);
214 mdp_enable_irq(MDP_OVERLAY0_TERM);
215 mfd->dma->busy = TRUE;
216
217 mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
218 up(&mfd->sem);
219#else
220 down(&mfd->sem);
221 mdp_enable_irq(MDP_OVERLAY0_TERM);
222 mfd->dma->busy = TRUE;
223 INIT_COMPLETION(pipe->comp);
224 pending_pipe = pipe;
225
226
227 mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd);
228 up(&mfd->sem);
229
230
231 wait_for_completion_killable(&pipe->comp);
232 mdp_disable_irq(MDP_OVERLAY0_TERM);
233#endif
234
235}
236
237void mdp4_mddi_overlay(struct msm_fb_data_type *mfd)
238{
239 mutex_lock(&mfd->dma->ov_mutex);
240
241 if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
242 mdp4_overlay_update_lcd(mfd);
243
244 mdp4_mddi_overlay_kickoff(mfd, mddi_pipe);
245
246
247 if (mfd->pan_waiting) {
248 mfd->pan_waiting = FALSE;
249 complete(&mfd->pan_comp);
250 }
251 }
252
253 mutex_unlock(&mfd->dma->ov_mutex);
254}
255