summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2015-03-13 14:09:45 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-06-18 02:57:43 -0400
commita9bd32a8b4c4c2670f9ed8cae63f9378b6df3ded (patch)
tree0aa034e63000fca0fceccf3b4cacc563f3dea0ae /drivers/video
parenta8998202c1d80274c44a520f3d2eb6fc641733c1 (diff)
msm: msm_fb: Remove dead code
This code is no longer used now that mach-msm has been removed. Delete it. Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: David Brown <davidb@codeaurora.org> Cc: Bryan Huntsman <bryanh@codeaurora.org> Cc: Daniel Walker <dwalker@fifo99.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/Kconfig7
-rw-r--r--drivers/video/fbdev/Makefile1
-rw-r--r--drivers/video/fbdev/msm/Makefile19
-rw-r--r--drivers/video/fbdev/msm/mddi.c821
-rw-r--r--drivers/video/fbdev/msm/mddi_client_dummy.c85
-rw-r--r--drivers/video/fbdev/msm/mddi_client_nt35399.c252
-rw-r--r--drivers/video/fbdev/msm/mddi_client_toshiba.c280
-rw-r--r--drivers/video/fbdev/msm/mddi_hw.h305
-rw-r--r--drivers/video/fbdev/msm/mdp.c520
-rw-r--r--drivers/video/fbdev/msm/mdp_csc_table.h582
-rw-r--r--drivers/video/fbdev/msm/mdp_hw.h627
-rw-r--r--drivers/video/fbdev/msm/mdp_ppp.c731
-rw-r--r--drivers/video/fbdev/msm/mdp_scale_tables.c766
-rw-r--r--drivers/video/fbdev/msm/mdp_scale_tables.h38
-rw-r--r--drivers/video/fbdev/msm/msm_fb.c659
15 files changed, 0 insertions, 5693 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 54fb8f86b68d..2d98de535e0f 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2326,13 +2326,6 @@ config FB_PRE_INIT_FB
2326 Select this option if display contents should be inherited as set by 2326 Select this option if display contents should be inherited as set by
2327 the bootloader. 2327 the bootloader.
2328 2328
2329config FB_MSM
2330 tristate "MSM Framebuffer support"
2331 depends on FB && ARCH_MSM
2332 select FB_CFB_FILLRECT
2333 select FB_CFB_COPYAREA
2334 select FB_CFB_IMAGEBLIT
2335
2336config FB_MX3 2329config FB_MX3
2337 tristate "MX3 Framebuffer support" 2330 tristate "MX3 Framebuffer support"
2338 depends on FB && MX3_IPU 2331 depends on FB && MX3_IPU
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 1979afffccfe..cecea5063a80 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -126,7 +126,6 @@ obj-y += omap2/
126obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o 126obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
127obj-$(CONFIG_FB_CARMINE) += carminefb.o 127obj-$(CONFIG_FB_CARMINE) += carminefb.o
128obj-$(CONFIG_FB_MB862XX) += mb862xx/ 128obj-$(CONFIG_FB_MB862XX) += mb862xx/
129obj-$(CONFIG_FB_MSM) += msm/
130obj-$(CONFIG_FB_NUC900) += nuc900fb.o 129obj-$(CONFIG_FB_NUC900) += nuc900fb.o
131obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o 130obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
132obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o 131obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
diff --git a/drivers/video/fbdev/msm/Makefile b/drivers/video/fbdev/msm/Makefile
deleted file mode 100644
index 802d6ae523fb..000000000000
--- a/drivers/video/fbdev/msm/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
1
2# core framebuffer
3#
4obj-y := msm_fb.o
5
6# MDP DMA/PPP engine
7#
8obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
9
10# MDDI interface
11#
12obj-y += mddi.o
13
14# MDDI client/panel drivers
15#
16obj-y += mddi_client_dummy.o
17obj-y += mddi_client_toshiba.o
18obj-y += mddi_client_nt35399.o
19
diff --git a/drivers/video/fbdev/msm/mddi.c b/drivers/video/fbdev/msm/mddi.c
deleted file mode 100644
index e0f8011a3c4b..000000000000
--- a/drivers/video/fbdev/msm/mddi.c
+++ /dev/null
@@ -1,821 +0,0 @@
1/*
2 * MSM MDDI Transport
3 *
4 * Copyright (C) 2007 Google Incorporated
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/dma-mapping.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/gfp.h>
25#include <linux/spinlock.h>
26#include <linux/clk.h>
27#include <linux/io.h>
28#include <linux/sched.h>
29#include <linux/platform_data/video-msm_fb.h>
30#include "mddi_hw.h"
31
32#define FLAG_DISABLE_HIBERNATION 0x0001
33#define FLAG_HAVE_CAPS 0x0002
34#define FLAG_HAS_VSYNC_IRQ 0x0004
35#define FLAG_HAVE_STATUS 0x0008
36
37#define CMD_GET_CLIENT_CAP 0x0601
38#define CMD_GET_CLIENT_STATUS 0x0602
39
40union mddi_rev {
41 unsigned char raw[MDDI_REV_BUFFER_SIZE];
42 struct mddi_rev_packet hdr;
43 struct mddi_client_status status;
44 struct mddi_client_caps caps;
45 struct mddi_register_access reg;
46};
47
48struct reg_read_info {
49 struct completion done;
50 uint32_t reg;
51 uint32_t status;
52 uint32_t result;
53};
54
55struct mddi_info {
56 uint16_t flags;
57 uint16_t version;
58 char __iomem *base;
59 int irq;
60 struct clk *clk;
61 struct msm_mddi_client_data client_data;
62
63 /* buffer for rev encap packets */
64 void *rev_data;
65 dma_addr_t rev_addr;
66 struct mddi_llentry *reg_write_data;
67 dma_addr_t reg_write_addr;
68 struct mddi_llentry *reg_read_data;
69 dma_addr_t reg_read_addr;
70 size_t rev_data_curr;
71
72 spinlock_t int_lock;
73 uint32_t int_enable;
74 uint32_t got_int;
75 wait_queue_head_t int_wait;
76
77 struct mutex reg_write_lock;
78 struct mutex reg_read_lock;
79 struct reg_read_info *reg_read;
80
81 struct mddi_client_caps caps;
82 struct mddi_client_status status;
83
84 void (*power_client)(struct msm_mddi_client_data *, int);
85
86 /* client device published to bind us to the
87 * appropriate mddi_client driver
88 */
89 char client_name[20];
90
91 struct platform_device client_pdev;
92};
93
94static void mddi_init_rev_encap(struct mddi_info *mddi);
95
96#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
97#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
98
99void mddi_activate_link(struct msm_mddi_client_data *cdata)
100{
101 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
102 client_data);
103
104 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
105}
106
107static void mddi_handle_link_list_done(struct mddi_info *mddi)
108{
109}
110
111static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
112{
113 printk(KERN_INFO "mddi: resetting rev ptr\n");
114 mddi->rev_data_curr = 0;
115 mddi_writel(mddi->rev_addr, REV_PTR);
116 mddi_writel(mddi->rev_addr, REV_PTR);
117 mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
118}
119
120static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
121{
122 int i;
123 struct reg_read_info *ri;
124
125 if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
126 (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
127
128 switch (rev->hdr.type) {
129 case TYPE_CLIENT_CAPS:
130 memcpy(&mddi->caps, &rev->caps,
131 sizeof(struct mddi_client_caps));
132 mddi->flags |= FLAG_HAVE_CAPS;
133 wake_up(&mddi->int_wait);
134 break;
135 case TYPE_CLIENT_STATUS:
136 memcpy(&mddi->status, &rev->status,
137 sizeof(struct mddi_client_status));
138 mddi->flags |= FLAG_HAVE_STATUS;
139 wake_up(&mddi->int_wait);
140 break;
141 case TYPE_REGISTER_ACCESS:
142 ri = mddi->reg_read;
143 if (ri == 0) {
144 printk(KERN_INFO "rev: got reg %x = %x without "
145 " pending read\n",
146 rev->reg.register_address,
147 rev->reg.register_data_list);
148 break;
149 }
150 if (ri->reg != rev->reg.register_address) {
151 printk(KERN_INFO "rev: got reg %x = %x for "
152 "wrong register, expected "
153 "%x\n",
154 rev->reg.register_address,
155 rev->reg.register_data_list, ri->reg);
156 break;
157 }
158 mddi->reg_read = NULL;
159 ri->status = 0;
160 ri->result = rev->reg.register_data_list;
161 complete(&ri->done);
162 break;
163 default:
164 printk(KERN_INFO "rev: unknown reverse packet: "
165 "len=%04x type=%04x CURR_REV_PTR=%x\n",
166 rev->hdr.length, rev->hdr.type,
167 mddi_readl(CURR_REV_PTR));
168 for (i = 0; i < rev->hdr.length + 2; i++) {
169 if ((i % 16) == 0)
170 printk(KERN_INFO "\n");
171 printk(KERN_INFO " %02x", rev->raw[i]);
172 }
173 printk(KERN_INFO "\n");
174 mddi_reset_rev_encap_ptr(mddi);
175 }
176 } else {
177 printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
178 rev->hdr.length, mddi_readl(CURR_REV_PTR));
179 mddi_reset_rev_encap_ptr(mddi);
180 }
181}
182
183static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
184
185static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
186{
187 uint32_t rev_data_count;
188 uint32_t rev_crc_err_count;
189 struct reg_read_info *ri;
190 size_t prev_offset;
191 uint16_t length;
192
193 union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
194
195 /* clear the interrupt */
196 mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
197 rev_data_count = mddi_readl(REV_PKT_CNT);
198 rev_crc_err_count = mddi_readl(REV_CRC_ERR);
199 if (rev_data_count > 1)
200 printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
201
202 if (rev_crc_err_count) {
203 printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
204 rev_crc_err_count, mddi_readl(INT));
205 ri = mddi->reg_read;
206 if (ri == 0) {
207 printk(KERN_INFO "rev: got crc error without pending "
208 "read\n");
209 } else {
210 mddi->reg_read = NULL;
211 ri->status = -EIO;
212 ri->result = -1;
213 complete(&ri->done);
214 }
215 }
216
217 if (rev_data_count == 0)
218 return;
219
220 prev_offset = mddi->rev_data_curr;
221
222 length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
223 mddi->rev_data_curr++;
224 if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
225 mddi->rev_data_curr = 0;
226 length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
227 mddi->rev_data_curr += 1 + length;
228 if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
229 mddi->rev_data_curr =
230 mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
231
232 if (length > MDDI_REV_BUFFER_SIZE - 2) {
233 printk(KERN_INFO "mddi: rev data length greater than buffer"
234 "size\n");
235 mddi_reset_rev_encap_ptr(mddi);
236 return;
237 }
238
239 if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
240 union mddi_rev tmprev;
241 size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
242 memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
243 memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
244 mddi_handle_rev_data(mddi, &tmprev);
245 } else {
246 mddi_handle_rev_data(mddi, crev);
247 }
248
249 if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
250 mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
251 mddi_writel(mddi->rev_addr, REV_PTR);
252 }
253}
254
255static irqreturn_t mddi_isr(int irq, void *data)
256{
257 struct msm_mddi_client_data *cdata = data;
258 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
259 client_data);
260 uint32_t active, status;
261
262 spin_lock(&mddi->int_lock);
263
264 active = mddi_readl(INT);
265 status = mddi_readl(STAT);
266
267 mddi_writel(active, INT);
268
269 /* ignore any interrupts we have disabled */
270 active &= mddi->int_enable;
271
272 mddi->got_int |= active;
273 wake_up(&mddi->int_wait);
274
275 if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
276 mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
277 mddi_handle_link_list_done(mddi);
278 }
279 if (active & MDDI_INT_REV_DATA_AVAIL)
280 mddi_handle_rev_data_avail(mddi);
281
282 if (active & ~MDDI_INT_NEED_CLEAR)
283 mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
284
285 if (active & MDDI_INT_LINK_ACTIVE) {
286 mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
287 mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
288 }
289
290 if (active & MDDI_INT_IN_HIBERNATION) {
291 mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
292 mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
293 }
294
295 mddi_writel(mddi->int_enable, INTEN);
296 spin_unlock(&mddi->int_lock);
297
298 return IRQ_HANDLED;
299}
300
301static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
302 uint32_t intmask, int timeout)
303{
304 unsigned long irq_flags;
305
306 spin_lock_irqsave(&mddi->int_lock, irq_flags);
307 mddi->got_int &= ~intmask;
308 mddi->int_enable |= intmask;
309 mddi_writel(mddi->int_enable, INTEN);
310 spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
311 return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
312 timeout);
313}
314
315static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
316{
317 if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
318 printk(KERN_INFO "mddi_wait_interrupt %d, timeout "
319 "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
320 current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
321 mddi->got_int);
322}
323
324static void mddi_init_rev_encap(struct mddi_info *mddi)
325{
326 memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
327 mddi_writel(mddi->rev_addr, REV_PTR);
328 mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
329 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
330}
331
332void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
333{
334 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
335 client_data);
336 mddi_writel(MDDI_CMD_POWERDOWN, CMD);
337 mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
338 mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
339 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
340}
341
342
343static uint16_t mddi_init_registers(struct mddi_info *mddi)
344{
345 mddi_writel(0x0001, VERSION);
346 mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
347 mddi_writel(0x0003, SPM); /* subframes per media */
348 mddi_writel(0x0005, TA1_LEN);
349 mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
350 mddi_writel(0x0096, DRIVE_HI);
351 /* 0x32 normal, 0x50 for Toshiba display */
352 mddi_writel(0x0050, DRIVE_LO);
353 mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
354 mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
355
356 mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
357 mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
358
359 /* disable periodic rev encap */
360 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
361 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
362
363 if (mddi_readl(PAD_CTL) == 0) {
364 /* If we are turning on band gap, need to wait 5us before
365 * turning on the rest of the PAD */
366 mddi_writel(0x08000, PAD_CTL);
367 udelay(5);
368 }
369
370 /* Recommendation from PAD hw team */
371 mddi_writel(0xa850f, PAD_CTL);
372
373
374 /* Need an even number for counts */
375 mddi_writel(0x60006, DRIVER_START_CNT);
376
377 mddi_set_auto_hibernate(&mddi->client_data, 0);
378
379 mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
380 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
381
382 mddi_init_rev_encap(mddi);
383 return mddi_readl(CORE_VER) & 0xffff;
384}
385
386static void mddi_suspend(struct msm_mddi_client_data *cdata)
387{
388 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
389 client_data);
390 /* turn off the client */
391 if (mddi->power_client)
392 mddi->power_client(&mddi->client_data, 0);
393 /* turn off the link */
394 mddi_writel(MDDI_CMD_RESET, CMD);
395 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
396 /* turn off the clock */
397 clk_disable(mddi->clk);
398}
399
400static void mddi_resume(struct msm_mddi_client_data *cdata)
401{
402 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
403 client_data);
404 mddi_set_auto_hibernate(&mddi->client_data, 0);
405 /* turn on the client */
406 if (mddi->power_client)
407 mddi->power_client(&mddi->client_data, 1);
408 /* turn on the clock */
409 clk_enable(mddi->clk);
410 /* set up the local registers */
411 mddi->rev_data_curr = 0;
412 mddi_init_registers(mddi);
413 mddi_writel(mddi->int_enable, INTEN);
414 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
415 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
416 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
417 mddi_set_auto_hibernate(&mddi->client_data, 1);
418}
419
420static int mddi_get_client_caps(struct mddi_info *mddi)
421{
422 int i, j;
423
424 /* clear any stale interrupts */
425 mddi_writel(0xffffffff, INT);
426
427 mddi->int_enable = MDDI_INT_LINK_ACTIVE |
428 MDDI_INT_IN_HIBERNATION |
429 MDDI_INT_PRI_LINK_LIST_DONE |
430 MDDI_INT_REV_DATA_AVAIL |
431 MDDI_INT_REV_OVERFLOW |
432 MDDI_INT_REV_OVERWRITE |
433 MDDI_INT_RTD_FAILURE;
434 mddi_writel(mddi->int_enable, INTEN);
435
436 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
437 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
438
439 for (j = 0; j < 3; j++) {
440 /* the toshiba vga panel does not respond to get
441 * caps unless you SEND_RTD, but the first SEND_RTD
442 * will fail...
443 */
444 for (i = 0; i < 4; i++) {
445 uint32_t stat;
446
447 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
448 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
449 stat = mddi_readl(STAT);
450 printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
451 "rtd val %x\n", mddi_readl(INT), stat,
452 mddi_readl(RTD_VAL));
453 if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
454 break;
455 msleep(1);
456 }
457
458 mddi_writel(CMD_GET_CLIENT_CAP, CMD);
459 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
460 wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
461 HZ / 100);
462
463 if (mddi->flags & FLAG_HAVE_CAPS)
464 break;
465 printk(KERN_INFO "mddi_init, timeout waiting for caps\n");
466 }
467 return mddi->flags & FLAG_HAVE_CAPS;
468}
469
470/* link must be active when this is called */
471int mddi_check_status(struct mddi_info *mddi)
472{
473 int ret = -1, retry = 3;
474 mutex_lock(&mddi->reg_read_lock);
475 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
476 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
477
478 do {
479 mddi->flags &= ~FLAG_HAVE_STATUS;
480 mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
481 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
482 wait_event_timeout(mddi->int_wait,
483 mddi->flags & FLAG_HAVE_STATUS,
484 HZ / 100);
485
486 if (mddi->flags & FLAG_HAVE_STATUS) {
487 if (mddi->status.crc_error_count)
488 printk(KERN_INFO "mddi status: crc_error "
489 "count: %d\n",
490 mddi->status.crc_error_count);
491 else
492 ret = 0;
493 break;
494 } else
495 printk(KERN_INFO "mddi status: failed to get client "
496 "status\n");
497 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
498 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
499 } while (--retry);
500
501 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
502 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
503 mutex_unlock(&mddi->reg_read_lock);
504 return ret;
505}
506
507
508void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
509 uint32_t reg)
510{
511 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
512 client_data);
513 struct mddi_llentry *ll;
514 struct mddi_register_access *ra;
515
516 mutex_lock(&mddi->reg_write_lock);
517
518 ll = mddi->reg_write_data;
519
520 ra = &(ll->u.r);
521 ra->length = 14 + 4;
522 ra->type = TYPE_REGISTER_ACCESS;
523 ra->client_id = 0;
524 ra->read_write_info = MDDI_WRITE | 1;
525 ra->crc16 = 0;
526
527 ra->register_address = reg;
528 ra->register_data_list = val;
529
530 ll->flags = 1;
531 ll->header_count = 14;
532 ll->data_count = 4;
533 ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
534 u.r.register_data_list);
535 ll->next = 0;
536 ll->reserved = 0;
537
538 mddi_writel(mddi->reg_write_addr, PRI_PTR);
539
540 mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
541 mutex_unlock(&mddi->reg_write_lock);
542}
543
544uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
545{
546 struct mddi_info *mddi = container_of(cdata, struct mddi_info,
547 client_data);
548 struct mddi_llentry *ll;
549 struct mddi_register_access *ra;
550 struct reg_read_info ri;
551 unsigned s;
552 int retry_count = 2;
553 unsigned long irq_flags;
554
555 mutex_lock(&mddi->reg_read_lock);
556
557 ll = mddi->reg_read_data;
558
559 ra = &(ll->u.r);
560 ra->length = 14;
561 ra->type = TYPE_REGISTER_ACCESS;
562 ra->client_id = 0;
563 ra->read_write_info = MDDI_READ | 1;
564 ra->crc16 = 0;
565
566 ra->register_address = reg;
567
568 ll->flags = 0x11;
569 ll->header_count = 14;
570 ll->data_count = 0;
571 ll->data = 0;
572 ll->next = 0;
573 ll->reserved = 0;
574
575 s = mddi_readl(STAT);
576
577 ri.reg = reg;
578 ri.status = -1;
579
580 do {
581 init_completion(&ri.done);
582 mddi->reg_read = &ri;
583 mddi_writel(mddi->reg_read_addr, PRI_PTR);
584
585 mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
586
587 /* Enable Periodic Reverse Encapsulation. */
588 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
589 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
590 if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
591 !ri.done.done) {
592 printk(KERN_INFO "mddi_remote_read(%x) timeout "
593 "(%d %d %d)\n",
594 reg, ri.status, ri.result, ri.done.done);
595 spin_lock_irqsave(&mddi->int_lock, irq_flags);
596 mddi->reg_read = NULL;
597 spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
598 ri.status = -1;
599 ri.result = -1;
600 }
601 if (ri.status == 0)
602 break;
603
604 mddi_writel(MDDI_CMD_SEND_RTD, CMD);
605 mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
606 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
607 printk(KERN_INFO "mddi_remote_read: failed, sent "
608 "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
609 "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
610 mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
611 } while (retry_count-- > 0);
612 /* Disable Periodic Reverse Encapsulation. */
613 mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
614 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
615 mddi->reg_read = NULL;
616 mutex_unlock(&mddi->reg_read_lock);
617 return ri.result;
618}
619
620static struct mddi_info mddi_info[2];
621
622static int mddi_clk_setup(struct platform_device *pdev, struct mddi_info *mddi,
623 unsigned long clk_rate)
624{
625 int ret;
626
627 /* set up the clocks */
628 mddi->clk = clk_get(&pdev->dev, "mddi_clk");
629 if (IS_ERR(mddi->clk)) {
630 printk(KERN_INFO "mddi: failed to get clock\n");
631 return PTR_ERR(mddi->clk);
632 }
633 ret = clk_enable(mddi->clk);
634 if (ret)
635 goto fail;
636 ret = clk_set_rate(mddi->clk, clk_rate);
637 if (ret)
638 goto fail;
639 return 0;
640
641fail:
642 clk_put(mddi->clk);
643 return ret;
644}
645
646static int __init mddi_rev_data_setup(struct mddi_info *mddi)
647{
648 void *dma;
649 dma_addr_t dma_addr;
650
651 /* set up dma buffer */
652 dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
653 if (dma == 0)
654 return -ENOMEM;
655 mddi->rev_data = dma;
656 mddi->rev_data_curr = 0;
657 mddi->rev_addr = dma_addr;
658 mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
659 mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
660 mddi->reg_read_data = mddi->reg_write_data + 1;
661 mddi->reg_read_addr = mddi->reg_write_addr +
662 sizeof(*mddi->reg_write_data);
663 return 0;
664}
665
666static int mddi_probe(struct platform_device *pdev)
667{
668 struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
669 struct mddi_info *mddi = &mddi_info[pdev->id];
670 struct resource *resource;
671 int ret, i;
672
673 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
674 if (!resource) {
675 printk(KERN_ERR "mddi: no associated mem resource!\n");
676 return -ENOMEM;
677 }
678 mddi->base = ioremap(resource->start, resource_size(resource));
679 if (!mddi->base) {
680 printk(KERN_ERR "mddi: failed to remap base!\n");
681 ret = -EINVAL;
682 goto error_ioremap;
683 }
684 resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
685 if (!resource) {
686 printk(KERN_ERR "mddi: no associated irq resource!\n");
687 ret = -EINVAL;
688 goto error_get_irq_resource;
689 }
690 mddi->irq = resource->start;
691 printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
692 mddi->irq);
693 mddi->power_client = pdata->power_client;
694
695 mutex_init(&mddi->reg_write_lock);
696 mutex_init(&mddi->reg_read_lock);
697 spin_lock_init(&mddi->int_lock);
698 init_waitqueue_head(&mddi->int_wait);
699
700 ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
701 if (ret) {
702 printk(KERN_ERR "mddi: failed to setup clock!\n");
703 goto error_clk_setup;
704 }
705
706 ret = mddi_rev_data_setup(mddi);
707 if (ret) {
708 printk(KERN_ERR "mddi: failed to setup rev data!\n");
709 goto error_rev_data;
710 }
711
712 mddi->int_enable = 0;
713 mddi_writel(mddi->int_enable, INTEN);
714 ret = request_irq(mddi->irq, mddi_isr, 0, "mddi",
715 &mddi->client_data);
716 if (ret) {
717 printk(KERN_ERR "mddi: failed to request enable irq!\n");
718 goto error_request_irq;
719 }
720
721 /* turn on the mddi client bridge chip */
722 if (mddi->power_client)
723 mddi->power_client(&mddi->client_data, 1);
724
725 /* initialize the mddi registers */
726 mddi_set_auto_hibernate(&mddi->client_data, 0);
727 mddi_writel(MDDI_CMD_RESET, CMD);
728 mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
729 mddi->version = mddi_init_registers(mddi);
730 if (mddi->version < 0x20) {
731 printk(KERN_ERR "mddi: unsupported version 0x%x\n",
732 mddi->version);
733 ret = -ENODEV;
734 goto error_mddi_version;
735 }
736
737 /* read the capabilities off the client */
738 if (!mddi_get_client_caps(mddi)) {
739 printk(KERN_INFO "mddi: no client found\n");
740 /* power down the panel */
741 mddi_writel(MDDI_CMD_POWERDOWN, CMD);
742 printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
743 msleep(100);
744 printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
745 return 0;
746 }
747 mddi_set_auto_hibernate(&mddi->client_data, 1);
748
749 if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
750 pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
751
752 mddi->client_pdev.id = 0;
753 for (i = 0; i < pdata->num_clients; i++) {
754 if (pdata->client_platform_data[i].product_id ==
755 (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
756 mddi->client_data.private_client_data =
757 pdata->client_platform_data[i].client_data;
758 mddi->client_pdev.name =
759 pdata->client_platform_data[i].name;
760 mddi->client_pdev.id =
761 pdata->client_platform_data[i].id;
762 /* XXX: possibly set clock */
763 break;
764 }
765 }
766
767 if (i >= pdata->num_clients)
768 mddi->client_pdev.name = "mddi_c_dummy";
769 printk(KERN_INFO "mddi: registering panel %s\n",
770 mddi->client_pdev.name);
771
772 mddi->client_data.suspend = mddi_suspend;
773 mddi->client_data.resume = mddi_resume;
774 mddi->client_data.activate_link = mddi_activate_link;
775 mddi->client_data.remote_write = mddi_remote_write;
776 mddi->client_data.remote_read = mddi_remote_read;
777 mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
778 mddi->client_data.fb_resource = pdata->fb_resource;
779 if (pdev->id == 0)
780 mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
781 else if (pdev->id == 1)
782 mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
783 else {
784 printk(KERN_ERR "mddi: can not determine interface %d!\n",
785 pdev->id);
786 ret = -EINVAL;
787 goto error_mddi_interface;
788 }
789
790 mddi->client_pdev.dev.platform_data = &mddi->client_data;
791 printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
792 platform_device_register(&mddi->client_pdev);
793 return 0;
794
795error_mddi_interface:
796error_mddi_version:
797 free_irq(mddi->irq, 0);
798error_request_irq:
799 dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
800error_rev_data:
801error_clk_setup:
802error_get_irq_resource:
803 iounmap(mddi->base);
804error_ioremap:
805
806 printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
807 return ret;
808}
809
810
811static struct platform_driver mddi_driver = {
812 .probe = mddi_probe,
813 .driver = { .name = "msm_mddi" },
814};
815
816static int __init _mddi_init(void)
817{
818 return platform_driver_register(&mddi_driver);
819}
820
821module_init(_mddi_init);
diff --git a/drivers/video/fbdev/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c
deleted file mode 100644
index cdb8f69a5d88..000000000000
--- a/drivers/video/fbdev/msm/mddi_client_dummy.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/* drivers/video/msm_fb/mddi_client_dummy.c
2 *
3 * Support for "dummy" mddi client devices which require no
4 * special initialization code.
5 *
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/device.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/platform_device.h>
23
24#include <linux/platform_data/video-msm_fb.h>
25
26struct panel_info {
27 struct platform_device pdev;
28 struct msm_panel_data panel_data;
29};
30
31static int mddi_dummy_suspend(struct msm_panel_data *panel_data)
32{
33 return 0;
34}
35
36static int mddi_dummy_resume(struct msm_panel_data *panel_data)
37{
38 return 0;
39}
40
41static int mddi_dummy_blank(struct msm_panel_data *panel_data)
42{
43 return 0;
44}
45
46static int mddi_dummy_unblank(struct msm_panel_data *panel_data)
47{
48 return 0;
49}
50
51static int mddi_dummy_probe(struct platform_device *pdev)
52{
53 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
54 struct panel_info *panel =
55 devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
56 if (!panel)
57 return -ENOMEM;
58 platform_set_drvdata(pdev, panel);
59 panel->panel_data.suspend = mddi_dummy_suspend;
60 panel->panel_data.resume = mddi_dummy_resume;
61 panel->panel_data.blank = mddi_dummy_blank;
62 panel->panel_data.unblank = mddi_dummy_unblank;
63 panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
64 panel->pdev.name = "msm_panel";
65 panel->pdev.id = pdev->id;
66 platform_device_add_resources(&panel->pdev,
67 client_data->fb_resource, 1);
68 panel->panel_data.fb_data = client_data->private_client_data;
69 panel->pdev.dev.platform_data = &panel->panel_data;
70 return platform_device_register(&panel->pdev);
71}
72
73static struct platform_driver mddi_client_dummy = {
74 .probe = mddi_dummy_probe,
75 .driver = { .name = "mddi_c_dummy" },
76};
77
78static int __init mddi_client_dummy_init(void)
79{
80 platform_driver_register(&mddi_client_dummy);
81 return 0;
82}
83
84module_init(mddi_client_dummy_init);
85
diff --git a/drivers/video/fbdev/msm/mddi_client_nt35399.c b/drivers/video/fbdev/msm/mddi_client_nt35399.c
deleted file mode 100644
index f96df32e5509..000000000000
--- a/drivers/video/fbdev/msm/mddi_client_nt35399.c
+++ /dev/null
@@ -1,252 +0,0 @@
1/* drivers/video/msm_fb/mddi_client_nt35399.c
2 *
3 * Support for Novatek NT35399 MDDI client of Sapphire
4 *
5 * Copyright (C) 2008 HTC Incorporated
6 * Author: Solomon Chiu (solomon_chiu@htc.com)
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/sched.h>
23#include <linux/gpio.h>
24#include <linux/slab.h>
25#include <linux/platform_data/video-msm_fb.h>
26
27static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
28
29struct panel_info {
30 struct msm_mddi_client_data *client_data;
31 struct platform_device pdev;
32 struct msm_panel_data panel_data;
33 struct msmfb_callback *fb_callback;
34 struct work_struct panel_work;
35 struct workqueue_struct *fb_wq;
36 int nt35399_got_int;
37};
38
39static void
40nt35399_request_vsync(struct msm_panel_data *panel_data,
41 struct msmfb_callback *callback)
42{
43 struct panel_info *panel = container_of(panel_data, struct panel_info,
44 panel_data);
45 struct msm_mddi_client_data *client_data = panel->client_data;
46
47 panel->fb_callback = callback;
48 if (panel->nt35399_got_int) {
49 panel->nt35399_got_int = 0;
50 client_data->activate_link(client_data); /* clears interrupt */
51 }
52}
53
54static void nt35399_wait_vsync(struct msm_panel_data *panel_data)
55{
56 struct panel_info *panel = container_of(panel_data, struct panel_info,
57 panel_data);
58 struct msm_mddi_client_data *client_data = panel->client_data;
59
60 if (panel->nt35399_got_int) {
61 panel->nt35399_got_int = 0;
62 client_data->activate_link(client_data); /* clears interrupt */
63 }
64
65 if (wait_event_timeout(nt35399_vsync_wait, panel->nt35399_got_int,
66 HZ/2) == 0)
67 printk(KERN_ERR "timeout waiting for VSYNC\n");
68
69 panel->nt35399_got_int = 0;
70 /* interrupt clears when screen dma starts */
71}
72
73static int nt35399_suspend(struct msm_panel_data *panel_data)
74{
75 struct panel_info *panel = container_of(panel_data, struct panel_info,
76 panel_data);
77 struct msm_mddi_client_data *client_data = panel->client_data;
78
79 struct msm_mddi_bridge_platform_data *bridge_data =
80 client_data->private_client_data;
81 int ret;
82
83 ret = bridge_data->uninit(bridge_data, client_data);
84 if (ret) {
85 printk(KERN_INFO "mddi nt35399 client: non zero return from "
86 "uninit\n");
87 return ret;
88 }
89 client_data->suspend(client_data);
90 return 0;
91}
92
93static int nt35399_resume(struct msm_panel_data *panel_data)
94{
95 struct panel_info *panel = container_of(panel_data, struct panel_info,
96 panel_data);
97 struct msm_mddi_client_data *client_data = panel->client_data;
98
99 struct msm_mddi_bridge_platform_data *bridge_data =
100 client_data->private_client_data;
101 int ret;
102
103 client_data->resume(client_data);
104 ret = bridge_data->init(bridge_data, client_data);
105 if (ret)
106 return ret;
107 return 0;
108}
109
110static int nt35399_blank(struct msm_panel_data *panel_data)
111{
112 struct panel_info *panel = container_of(panel_data, struct panel_info,
113 panel_data);
114 struct msm_mddi_client_data *client_data = panel->client_data;
115 struct msm_mddi_bridge_platform_data *bridge_data =
116 client_data->private_client_data;
117
118 return bridge_data->blank(bridge_data, client_data);
119}
120
121static int nt35399_unblank(struct msm_panel_data *panel_data)
122{
123 struct panel_info *panel = container_of(panel_data, struct panel_info,
124 panel_data);
125 struct msm_mddi_client_data *client_data = panel->client_data;
126 struct msm_mddi_bridge_platform_data *bridge_data =
127 client_data->private_client_data;
128
129 return bridge_data->unblank(bridge_data, client_data);
130}
131
132irqreturn_t nt35399_vsync_interrupt(int irq, void *data)
133{
134 struct panel_info *panel = data;
135
136 panel->nt35399_got_int = 1;
137
138 if (panel->fb_callback) {
139 panel->fb_callback->func(panel->fb_callback);
140 panel->fb_callback = NULL;
141 }
142
143 wake_up(&nt35399_vsync_wait);
144
145 return IRQ_HANDLED;
146}
147
148static int setup_vsync(struct panel_info *panel, int init)
149{
150 int ret;
151 int gpio = 97;
152 unsigned int irq;
153
154 if (!init) {
155 ret = 0;
156 goto uninit;
157 }
158 ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
159 if (ret)
160 goto err_request_gpio_failed;
161
162 ret = irq = gpio_to_irq(gpio);
163 if (ret < 0)
164 goto err_get_irq_num_failed;
165
166 ret = request_irq(irq, nt35399_vsync_interrupt, IRQF_TRIGGER_RISING,
167 "vsync", panel);
168 if (ret)
169 goto err_request_irq_failed;
170
171 printk(KERN_INFO "vsync on gpio %d now %d\n",
172 gpio, gpio_get_value(gpio));
173 return 0;
174
175uninit:
176 free_irq(gpio_to_irq(gpio), panel->client_data);
177err_request_irq_failed:
178err_get_irq_num_failed:
179 gpio_free(gpio);
180err_request_gpio_failed:
181 return ret;
182}
183
184static int mddi_nt35399_probe(struct platform_device *pdev)
185{
186 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
187 struct msm_mddi_bridge_platform_data *bridge_data =
188 client_data->private_client_data;
189
190 int ret;
191
192 struct panel_info *panel = devm_kzalloc(&pdev->dev,
193 sizeof(struct panel_info),
194 GFP_KERNEL);
195
196 printk(KERN_DEBUG "%s: enter.\n", __func__);
197
198 if (!panel)
199 return -ENOMEM;
200 platform_set_drvdata(pdev, panel);
201
202 ret = setup_vsync(panel, 1);
203 if (ret) {
204 dev_err(&pdev->dev, "mddi_nt35399_setup_vsync failed\n");
205 return ret;
206 }
207
208 panel->client_data = client_data;
209 panel->panel_data.suspend = nt35399_suspend;
210 panel->panel_data.resume = nt35399_resume;
211 panel->panel_data.wait_vsync = nt35399_wait_vsync;
212 panel->panel_data.request_vsync = nt35399_request_vsync;
213 panel->panel_data.blank = nt35399_blank;
214 panel->panel_data.unblank = nt35399_unblank;
215 panel->panel_data.fb_data = &bridge_data->fb_data;
216 panel->panel_data.caps = 0;
217
218 panel->pdev.name = "msm_panel";
219 panel->pdev.id = pdev->id;
220 panel->pdev.resource = client_data->fb_resource;
221 panel->pdev.num_resources = 1;
222 panel->pdev.dev.platform_data = &panel->panel_data;
223
224 if (bridge_data->init)
225 bridge_data->init(bridge_data, client_data);
226
227 platform_device_register(&panel->pdev);
228
229 return 0;
230}
231
232static int mddi_nt35399_remove(struct platform_device *pdev)
233{
234 struct panel_info *panel = platform_get_drvdata(pdev);
235
236 setup_vsync(panel, 0);
237 return 0;
238}
239
240static struct platform_driver mddi_client_0bda_8a47 = {
241 .probe = mddi_nt35399_probe,
242 .remove = mddi_nt35399_remove,
243 .driver = { .name = "mddi_c_0bda_8a47" },
244};
245
246static int __init mddi_client_nt35399_init(void)
247{
248 return platform_driver_register(&mddi_client_0bda_8a47);
249}
250
251module_init(mddi_client_nt35399_init);
252
diff --git a/drivers/video/fbdev/msm/mddi_client_toshiba.c b/drivers/video/fbdev/msm/mddi_client_toshiba.c
deleted file mode 100644
index 061d7dfebbf3..000000000000
--- a/drivers/video/fbdev/msm/mddi_client_toshiba.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/* drivers/video/msm_fb/mddi_client_toshiba.c
2 *
3 * Support for Toshiba TC358720XBG mddi client devices which require no
4 * special initialization code.
5 *
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/gpio.h>
23#include <linux/sched.h>
24#include <linux/slab.h>
25#include <linux/platform_data/video-msm_fb.h>
26
27
28#define LCD_CONTROL_BLOCK_BASE 0x110000
29#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
30#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
31#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
32#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
33#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0)
34#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
35#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
36#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
37#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
38
39#define BASE5 0x150000
40#define BASE6 0x160000
41#define BASE7 0x170000
42
43#define GPIOIEV (BASE5 + 0x10)
44#define GPIOIE (BASE5 + 0x14)
45#define GPIORIS (BASE5 + 0x18)
46#define GPIOMIS (BASE5 + 0x1C)
47#define GPIOIC (BASE5 + 0x20)
48
49#define INTMASK (BASE6 + 0x0C)
50#define INTMASK_VWAKEOUT (1U << 0)
51#define INTMASK_VWAKEOUT_ACTIVE_LOW (1U << 8)
52#define GPIOSEL (BASE7 + 0x00)
53#define GPIOSEL_VWAKEINT (1U << 0)
54
55static DECLARE_WAIT_QUEUE_HEAD(toshiba_vsync_wait);
56
57struct panel_info {
58 struct msm_mddi_client_data *client_data;
59 struct platform_device pdev;
60 struct msm_panel_data panel_data;
61 struct msmfb_callback *toshiba_callback;
62 int toshiba_got_int;
63};
64
65
66static void toshiba_request_vsync(struct msm_panel_data *panel_data,
67 struct msmfb_callback *callback)
68{
69 struct panel_info *panel = container_of(panel_data, struct panel_info,
70 panel_data);
71 struct msm_mddi_client_data *client_data = panel->client_data;
72
73 panel->toshiba_callback = callback;
74 if (panel->toshiba_got_int) {
75 panel->toshiba_got_int = 0;
76 client_data->activate_link(client_data);
77 }
78}
79
80static void toshiba_clear_vsync(struct msm_panel_data *panel_data)
81{
82 struct panel_info *panel = container_of(panel_data, struct panel_info,
83 panel_data);
84 struct msm_mddi_client_data *client_data = panel->client_data;
85
86 client_data->activate_link(client_data);
87}
88
89static void toshiba_wait_vsync(struct msm_panel_data *panel_data)
90{
91 struct panel_info *panel = container_of(panel_data, struct panel_info,
92 panel_data);
93 struct msm_mddi_client_data *client_data = panel->client_data;
94
95 if (panel->toshiba_got_int) {
96 panel->toshiba_got_int = 0;
97 client_data->activate_link(client_data); /* clears interrupt */
98 }
99 if (wait_event_timeout(toshiba_vsync_wait, panel->toshiba_got_int,
100 HZ/2) == 0)
101 printk(KERN_ERR "timeout waiting for VSYNC\n");
102 panel->toshiba_got_int = 0;
103 /* interrupt clears when screen dma starts */
104}
105
106static int toshiba_suspend(struct msm_panel_data *panel_data)
107{
108 struct panel_info *panel = container_of(panel_data, struct panel_info,
109 panel_data);
110 struct msm_mddi_client_data *client_data = panel->client_data;
111
112 struct msm_mddi_bridge_platform_data *bridge_data =
113 client_data->private_client_data;
114 int ret;
115
116 ret = bridge_data->uninit(bridge_data, client_data);
117 if (ret) {
118 printk(KERN_INFO "mddi toshiba client: non zero return from "
119 "uninit\n");
120 return ret;
121 }
122 client_data->suspend(client_data);
123 return 0;
124}
125
126static int toshiba_resume(struct msm_panel_data *panel_data)
127{
128 struct panel_info *panel = container_of(panel_data, struct panel_info,
129 panel_data);
130 struct msm_mddi_client_data *client_data = panel->client_data;
131
132 struct msm_mddi_bridge_platform_data *bridge_data =
133 client_data->private_client_data;
134 int ret;
135
136 client_data->resume(client_data);
137 ret = bridge_data->init(bridge_data, client_data);
138 if (ret)
139 return ret;
140 return 0;
141}
142
143static int toshiba_blank(struct msm_panel_data *panel_data)
144{
145 struct panel_info *panel = container_of(panel_data, struct panel_info,
146 panel_data);
147 struct msm_mddi_client_data *client_data = panel->client_data;
148 struct msm_mddi_bridge_platform_data *bridge_data =
149 client_data->private_client_data;
150
151 return bridge_data->blank(bridge_data, client_data);
152}
153
154static int toshiba_unblank(struct msm_panel_data *panel_data)
155{
156 struct panel_info *panel = container_of(panel_data, struct panel_info,
157 panel_data);
158 struct msm_mddi_client_data *client_data = panel->client_data;
159 struct msm_mddi_bridge_platform_data *bridge_data =
160 client_data->private_client_data;
161
162 return bridge_data->unblank(bridge_data, client_data);
163}
164
165irqreturn_t toshiba_vsync_interrupt(int irq, void *data)
166{
167 struct panel_info *panel = data;
168
169 panel->toshiba_got_int = 1;
170 if (panel->toshiba_callback) {
171 panel->toshiba_callback->func(panel->toshiba_callback);
172 panel->toshiba_callback = 0;
173 }
174 wake_up(&toshiba_vsync_wait);
175 return IRQ_HANDLED;
176}
177
178static int setup_vsync(struct panel_info *panel,
179 int init)
180{
181 int ret;
182 int gpio = 97;
183 unsigned int irq;
184
185 if (!init) {
186 ret = 0;
187 goto uninit;
188 }
189 ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
190 if (ret)
191 goto err_request_gpio_failed;
192
193 ret = irq = gpio_to_irq(gpio);
194 if (ret < 0)
195 goto err_get_irq_num_failed;
196
197 ret = request_irq(irq, toshiba_vsync_interrupt, IRQF_TRIGGER_RISING,
198 "vsync", panel);
199 if (ret)
200 goto err_request_irq_failed;
201 printk(KERN_INFO "vsync on gpio %d now %d\n",
202 gpio, gpio_get_value(gpio));
203 return 0;
204
205uninit:
206 free_irq(gpio_to_irq(gpio), panel);
207err_request_irq_failed:
208err_get_irq_num_failed:
209 gpio_free(gpio);
210err_request_gpio_failed:
211 return ret;
212}
213
214static int mddi_toshiba_probe(struct platform_device *pdev)
215{
216 int ret;
217 struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
218 struct msm_mddi_bridge_platform_data *bridge_data =
219 client_data->private_client_data;
220 struct panel_info *panel =
221 kzalloc(sizeof(struct panel_info), GFP_KERNEL);
222 if (!panel)
223 return -ENOMEM;
224 platform_set_drvdata(pdev, panel);
225
226 /* mddi_remote_write(mddi, 0, WAKEUP); */
227 client_data->remote_write(client_data, GPIOSEL_VWAKEINT, GPIOSEL);
228 client_data->remote_write(client_data, INTMASK_VWAKEOUT, INTMASK);
229
230 ret = setup_vsync(panel, 1);
231 if (ret) {
232 dev_err(&pdev->dev, "mddi_bridge_setup_vsync failed\n");
233 return ret;
234 }
235
236 panel->client_data = client_data;
237 panel->panel_data.suspend = toshiba_suspend;
238 panel->panel_data.resume = toshiba_resume;
239 panel->panel_data.wait_vsync = toshiba_wait_vsync;
240 panel->panel_data.request_vsync = toshiba_request_vsync;
241 panel->panel_data.clear_vsync = toshiba_clear_vsync;
242 panel->panel_data.blank = toshiba_blank;
243 panel->panel_data.unblank = toshiba_unblank;
244 panel->panel_data.fb_data = &bridge_data->fb_data;
245 panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
246
247 panel->pdev.name = "msm_panel";
248 panel->pdev.id = pdev->id;
249 panel->pdev.resource = client_data->fb_resource;
250 panel->pdev.num_resources = 1;
251 panel->pdev.dev.platform_data = &panel->panel_data;
252 bridge_data->init(bridge_data, client_data);
253 platform_device_register(&panel->pdev);
254
255 return 0;
256}
257
258static int mddi_toshiba_remove(struct platform_device *pdev)
259{
260 struct panel_info *panel = platform_get_drvdata(pdev);
261
262 setup_vsync(panel, 0);
263 kfree(panel);
264 return 0;
265}
266
267static struct platform_driver mddi_client_d263_0000 = {
268 .probe = mddi_toshiba_probe,
269 .remove = mddi_toshiba_remove,
270 .driver = { .name = "mddi_c_d263_0000" },
271};
272
273static int __init mddi_client_toshiba_init(void)
274{
275 platform_driver_register(&mddi_client_d263_0000);
276 return 0;
277}
278
279module_init(mddi_client_toshiba_init);
280
diff --git a/drivers/video/fbdev/msm/mddi_hw.h b/drivers/video/fbdev/msm/mddi_hw.h
deleted file mode 100644
index 45cc01fc1e7f..000000000000
--- a/drivers/video/fbdev/msm/mddi_hw.h
+++ /dev/null
@@ -1,305 +0,0 @@
1/* drivers/video/msm_fb/mddi_hw.h
2 *
3 * MSM MDDI Hardware Registers and Structures
4 *
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef _MDDI_HW_H_
19#define _MDDI_HW_H_
20
21#include <linux/types.h>
22
23#define MDDI_CMD 0x0000
24#define MDDI_VERSION 0x0004
25#define MDDI_PRI_PTR 0x0008
26#define MDDI_SEC_PTR 0x000c
27#define MDDI_BPS 0x0010
28#define MDDI_SPM 0x0014
29#define MDDI_INT 0x0018
30#define MDDI_INTEN 0x001c
31#define MDDI_REV_PTR 0x0020
32#define MDDI_REV_SIZE 0x0024
33#define MDDI_STAT 0x0028
34#define MDDI_REV_RATE_DIV 0x002c
35#define MDDI_REV_CRC_ERR 0x0030
36#define MDDI_TA1_LEN 0x0034
37#define MDDI_TA2_LEN 0x0038
38#define MDDI_TEST_BUS 0x003c
39#define MDDI_TEST 0x0040
40#define MDDI_REV_PKT_CNT 0x0044
41#define MDDI_DRIVE_HI 0x0048
42#define MDDI_DRIVE_LO 0x004c
43#define MDDI_DISP_WAKE 0x0050
44#define MDDI_REV_ENCAP_SZ 0x0054
45#define MDDI_RTD_VAL 0x0058
46#define MDDI_PAD_CTL 0x0068
47#define MDDI_DRIVER_START_CNT 0x006c
48#define MDDI_NEXT_PRI_PTR 0x0070
49#define MDDI_NEXT_SEC_PTR 0x0074
50#define MDDI_MISR_CTL 0x0078
51#define MDDI_MISR_DATA 0x007c
52#define MDDI_SF_CNT 0x0080
53#define MDDI_MF_CNT 0x0084
54#define MDDI_CURR_REV_PTR 0x0088
55#define MDDI_CORE_VER 0x008c
56
57#define MDDI_INT_PRI_PTR_READ 0x0001
58#define MDDI_INT_SEC_PTR_READ 0x0002
59#define MDDI_INT_REV_DATA_AVAIL 0x0004
60#define MDDI_INT_DISP_REQ 0x0008
61#define MDDI_INT_PRI_UNDERFLOW 0x0010
62#define MDDI_INT_SEC_UNDERFLOW 0x0020
63#define MDDI_INT_REV_OVERFLOW 0x0040
64#define MDDI_INT_CRC_ERROR 0x0080
65#define MDDI_INT_MDDI_IN 0x0100
66#define MDDI_INT_PRI_OVERWRITE 0x0200
67#define MDDI_INT_SEC_OVERWRITE 0x0400
68#define MDDI_INT_REV_OVERWRITE 0x0800
69#define MDDI_INT_DMA_FAILURE 0x1000
70#define MDDI_INT_LINK_ACTIVE 0x2000
71#define MDDI_INT_IN_HIBERNATION 0x4000
72#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000
73#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000
74#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000
75#define MDDI_INT_RTD_FAILURE 0x40000
76#define MDDI_INT_REV_PKT_RECEIVED 0x80000
77#define MDDI_INT_REV_PKTS_AVAIL 0x100000
78
79#define MDDI_INT_NEED_CLEAR ( \
80 MDDI_INT_REV_DATA_AVAIL | \
81 MDDI_INT_PRI_UNDERFLOW | \
82 MDDI_INT_SEC_UNDERFLOW | \
83 MDDI_INT_REV_OVERFLOW | \
84 MDDI_INT_CRC_ERROR | \
85 MDDI_INT_REV_PKT_RECEIVED)
86
87
88#define MDDI_STAT_LINK_ACTIVE 0x0001
89#define MDDI_STAT_NEW_REV_PTR 0x0002
90#define MDDI_STAT_NEW_PRI_PTR 0x0004
91#define MDDI_STAT_NEW_SEC_PTR 0x0008
92#define MDDI_STAT_IN_HIBERNATION 0x0010
93#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020
94#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040
95#define MDDI_STAT_PENDING_TIMING_PKT 0x0080
96#define MDDI_STAT_PENDING_REV_ENCAP 0x0100
97#define MDDI_STAT_PENDING_POWERDOWN 0x0200
98#define MDDI_STAT_RTD_MEAS_FAIL 0x0800
99#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000
100
101
102#define MDDI_CMD_POWERDOWN 0x0100
103#define MDDI_CMD_POWERUP 0x0200
104#define MDDI_CMD_HIBERNATE 0x0300
105#define MDDI_CMD_RESET 0x0400
106#define MDDI_CMD_DISP_IGNORE 0x0501
107#define MDDI_CMD_DISP_LISTEN 0x0500
108#define MDDI_CMD_SEND_REV_ENCAP 0x0600
109#define MDDI_CMD_GET_CLIENT_CAP 0x0601
110#define MDDI_CMD_GET_CLIENT_STATUS 0x0602
111#define MDDI_CMD_SEND_RTD 0x0700
112#define MDDI_CMD_LINK_ACTIVE 0x0900
113#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00
114#define MDDI_CMD_FORCE_NEW_REV_PTR 0x0C00
115
116
117
118#define MDDI_VIDEO_REV_PKT_SIZE 0x40
119#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60
120#define MDDI_MAX_REV_PKT_SIZE 0x60
121
122/* #define MDDI_REV_BUFFER_SIZE 128 */
123#define MDDI_REV_BUFFER_SIZE (MDDI_MAX_REV_PKT_SIZE * 4)
124
125/* MDP sends 256 pixel packets, so lower value hibernates more without
126 * significantly increasing latency of waiting for next subframe */
127#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00
128#define MDDI_HOST_TA2_LEN 0x000c
129#define MDDI_HOST_REV_RATE_DIV 0x0002
130
131
132struct __attribute__((packed)) mddi_rev_packet {
133 uint16_t length;
134 uint16_t type;
135 uint16_t client_id;
136};
137
138struct __attribute__((packed)) mddi_client_status {
139 uint16_t length;
140 uint16_t type;
141 uint16_t client_id;
142 uint16_t reverse_link_request; /* bytes needed in rev encap message */
143 uint8_t crc_error_count;
144 uint8_t capability_change;
145 uint16_t graphics_busy_flags;
146 uint16_t crc16;
147};
148
149struct __attribute__((packed)) mddi_client_caps {
150 uint16_t length; /* length, exclusive of this field */
151 uint16_t type; /* 66 */
152 uint16_t client_id;
153
154 uint16_t Protocol_Version;
155 uint16_t Minimum_Protocol_Version;
156 uint16_t Data_Rate_Capability;
157 uint8_t Interface_Type_Capability;
158 uint8_t Number_of_Alt_Displays;
159 uint16_t PostCal_Data_Rate;
160 uint16_t Bitmap_Width;
161 uint16_t Bitmap_Height;
162 uint16_t Display_Window_Width;
163 uint16_t Display_Window_Height;
164 uint32_t Color_Map_Size;
165 uint16_t Color_Map_RGB_Width;
166 uint16_t RGB_Capability;
167 uint8_t Monochrome_Capability;
168 uint8_t Reserved_1;
169 uint16_t Y_Cb_Cr_Capability;
170 uint16_t Bayer_Capability;
171 uint16_t Alpha_Cursor_Image_Planes;
172 uint32_t Client_Feature_Capability_Indicators;
173 uint8_t Maximum_Video_Frame_Rate_Capability;
174 uint8_t Minimum_Video_Frame_Rate_Capability;
175 uint16_t Minimum_Sub_frame_Rate;
176 uint16_t Audio_Buffer_Depth;
177 uint16_t Audio_Channel_Capability;
178 uint16_t Audio_Sample_Rate_Capability;
179 uint8_t Audio_Sample_Resolution;
180 uint8_t Mic_Audio_Sample_Resolution;
181 uint16_t Mic_Sample_Rate_Capability;
182 uint8_t Keyboard_Data_Format;
183 uint8_t pointing_device_data_format;
184 uint16_t content_protection_type;
185 uint16_t Mfr_Name;
186 uint16_t Product_Code;
187 uint16_t Reserved_3;
188 uint32_t Serial_Number;
189 uint8_t Week_of_Manufacture;
190 uint8_t Year_of_Manufacture;
191
192 uint16_t crc16;
193} mddi_client_capability_type;
194
195
196struct __attribute__((packed)) mddi_video_stream {
197 uint16_t length;
198 uint16_t type; /* 16 */
199 uint16_t client_id; /* 0 */
200
201 uint16_t video_data_format_descriptor;
202/* format of each pixel in the Pixel Data in the present stream in the
203 * present packet.
204 * If bits [15:13] = 000 monochrome
205 * If bits [15:13] = 001 color pixels (palette).
206 * If bits [15:13] = 010 color pixels in raw RGB
207 * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format
208 * If bits [15:13] = 100 Bayer pixels
209 */
210
211 uint16_t pixel_data_attributes;
212/* interpreted as follows:
213 * Bits [1:0] = 11 pixel data is displayed to both eyes
214 * Bits [1:0] = 10 pixel data is routed to the left eye only.
215 * Bits [1:0] = 01 pixel data is routed to the right eye only.
216 * Bits [1:0] = 00 pixel data is routed to the alternate display.
217 * Bit 2 is 0 Pixel Data is in the standard progressive format.
218 * Bit 2 is 1 Pixel Data is in interlace format.
219 * Bit 3 is 0 Pixel Data is in the standard progressive format.
220 * Bit 3 is 1 Pixel Data is in alternate pixel format.
221 * Bit 4 is 0 Pixel Data is to or from the display frame buffer.
222 * Bit 4 is 1 Pixel Data is to or from the camera.
223 * Bit 5 is 0 pixel data contains the next consecutive row of pixels.
224 * Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge,
225 * X Start, and Y Start parameters are not defined and
226 * shall be ignored by the client.
227 * Bits [7:6] = 01 Pixel data is written to the offline image buffer.
228 * Bits [7:6] = 00 Pixel data is written to the buffer to refresh display.
229 * Bits [7:6] = 11 Pixel data is written to all image buffers.
230 * Bits [7:6] = 10 Invalid. Reserved for future use.
231 * Bits 8 through 11 alternate display number.
232 * Bits 12 through 14 are reserved for future use and shall be set to zero.
233 * Bit 15 is 1 the row of pixels is the last row of pixels in a frame.
234 */
235
236 uint16_t x_left_edge;
237 uint16_t y_top_edge;
238 /* X,Y coordinate of the top left edge of the screen window */
239
240 uint16_t x_right_edge;
241 uint16_t y_bottom_edge;
242 /* X,Y coordinate of the bottom right edge of the window being
243 * updated. */
244
245 uint16_t x_start;
246 uint16_t y_start;
247 /* (X Start, Y Start) is the first pixel in the Pixel Data field
248 * below. */
249
250 uint16_t pixel_count;
251 /* number of pixels in the Pixel Data field below. */
252
253 uint16_t parameter_CRC;
254 /* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */
255
256 uint16_t reserved;
257 /* 16-bit variable to make structure align on 4 byte boundary */
258};
259
260#define TYPE_VIDEO_STREAM 16
261#define TYPE_CLIENT_CAPS 66
262#define TYPE_REGISTER_ACCESS 146
263#define TYPE_CLIENT_STATUS 70
264
265struct __attribute__((packed)) mddi_register_access {
266 uint16_t length;
267 uint16_t type; /* 146 */
268 uint16_t client_id;
269
270 uint16_t read_write_info;
271 /* Bits 13:0 a 14-bit unsigned integer that specifies the number of
272 * 32-bit Register Data List items to be transferred in the
273 * Register Data List field.
274 * Bits[15:14] = 00 Write to register(s);
275 * Bits[15:14] = 10 Read from register(s);
276 * Bits[15:14] = 11 Response to a Read.
277 * Bits[15:14] = 01 this value is reserved for future use. */
278#define MDDI_WRITE (0 << 14)
279#define MDDI_READ (2 << 14)
280#define MDDI_READ_RESP (3 << 14)
281
282 uint32_t register_address;
283 /* the register address that is to be written to or read from. */
284
285 uint16_t crc16;
286
287 uint32_t register_data_list;
288 /* list of 4-byte register data values for/from client registers */
289};
290
291struct __attribute__((packed)) mddi_llentry {
292 uint16_t flags;
293 uint16_t header_count;
294 uint16_t data_count;
295 dma_addr_t data; /* 32 bit */
296 struct mddi_llentry *next;
297 uint16_t reserved;
298 union {
299 struct mddi_video_stream v;
300 struct mddi_register_access r;
301 uint32_t _[12];
302 } u;
303};
304
305#endif
diff --git a/drivers/video/fbdev/msm/mdp.c b/drivers/video/fbdev/msm/mdp.c
deleted file mode 100644
index 113c7876c855..000000000000
--- a/drivers/video/fbdev/msm/mdp.c
+++ /dev/null
@@ -1,520 +0,0 @@
1/* drivers/video/msm_fb/mdp.c
2 *
3 * MSM MDP Interface (used by framebuffer core)
4 *
5 * Copyright (C) 2007 QUALCOMM Incorporated
6 * Copyright (C) 2007 Google Incorporated
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/fb.h>
20#include <linux/msm_mdp.h>
21#include <linux/interrupt.h>
22#include <linux/wait.h>
23#include <linux/clk.h>
24#include <linux/file.h>
25#include <linux/major.h>
26#include <linux/slab.h>
27
28#include <linux/platform_data/video-msm_fb.h>
29#include <linux/platform_device.h>
30#include <linux/export.h>
31
32#include "mdp_hw.h"
33
34struct class *mdp_class;
35
36#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
37
38static uint16_t mdp_default_ccs[] = {
39 0x254, 0x000, 0x331, 0x254, 0xF38, 0xE61, 0x254, 0x409, 0x000,
40 0x010, 0x080, 0x080
41};
42
43static DECLARE_WAIT_QUEUE_HEAD(mdp_dma2_waitqueue);
44static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
45static struct msmfb_callback *dma_callback;
46static struct clk *clk;
47static unsigned int mdp_irq_mask;
48static DEFINE_SPINLOCK(mdp_lock);
49DEFINE_MUTEX(mdp_mutex);
50
51static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
52{
53 unsigned long irq_flags;
54 int ret = 0;
55
56 BUG_ON(!mask);
57
58 spin_lock_irqsave(&mdp_lock, irq_flags);
59 /* if the mask bits are already set return an error, this interrupt
60 * is already enabled */
61 if (mdp_irq_mask & mask) {
62 printk(KERN_ERR "mdp irq already on already on %x %x\n",
63 mdp_irq_mask, mask);
64 ret = -1;
65 }
66 /* if the mdp irq is not already enabled enable it */
67 if (!mdp_irq_mask) {
68 if (clk)
69 clk_enable(clk);
70 enable_irq(mdp->irq);
71 }
72
73 /* update the irq mask to reflect the fact that the interrupt is
74 * enabled */
75 mdp_irq_mask |= mask;
76 spin_unlock_irqrestore(&mdp_lock, irq_flags);
77 return ret;
78}
79
80static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
81{
82 /* this interrupt is already disabled! */
83 if (!(mdp_irq_mask & mask)) {
84 printk(KERN_ERR "mdp irq already off %x %x\n",
85 mdp_irq_mask, mask);
86 return -1;
87 }
88 /* update the irq mask to reflect the fact that the interrupt is
89 * disabled */
90 mdp_irq_mask &= ~(mask);
91 /* if no one is waiting on the interrupt, disable it */
92 if (!mdp_irq_mask) {
93 disable_irq_nosync(mdp->irq);
94 if (clk)
95 clk_disable(clk);
96 }
97 return 0;
98}
99
100static int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
101{
102 unsigned long irq_flags;
103 int ret;
104
105 spin_lock_irqsave(&mdp_lock, irq_flags);
106 ret = locked_disable_mdp_irq(mdp, mask);
107 spin_unlock_irqrestore(&mdp_lock, irq_flags);
108 return ret;
109}
110
111static irqreturn_t mdp_isr(int irq, void *data)
112{
113 uint32_t status;
114 unsigned long irq_flags;
115 struct mdp_info *mdp = data;
116
117 spin_lock_irqsave(&mdp_lock, irq_flags);
118
119 status = mdp_readl(mdp, MDP_INTR_STATUS);
120 mdp_writel(mdp, status, MDP_INTR_CLEAR);
121
122 status &= mdp_irq_mask;
123 if (status & DL0_DMA2_TERM_DONE) {
124 if (dma_callback) {
125 dma_callback->func(dma_callback);
126 dma_callback = NULL;
127 }
128 wake_up(&mdp_dma2_waitqueue);
129 }
130
131 if (status & DL0_ROI_DONE)
132 wake_up(&mdp_ppp_waitqueue);
133
134 if (status)
135 locked_disable_mdp_irq(mdp, status);
136
137 spin_unlock_irqrestore(&mdp_lock, irq_flags);
138 return IRQ_HANDLED;
139}
140
141static uint32_t mdp_check_mask(uint32_t mask)
142{
143 uint32_t ret;
144 unsigned long irq_flags;
145
146 spin_lock_irqsave(&mdp_lock, irq_flags);
147 ret = mdp_irq_mask & mask;
148 spin_unlock_irqrestore(&mdp_lock, irq_flags);
149 return ret;
150}
151
152static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
153{
154 int ret = 0;
155 unsigned long irq_flags;
156
157 wait_event_timeout(*wq, !mdp_check_mask(mask), HZ);
158
159 spin_lock_irqsave(&mdp_lock, irq_flags);
160 if (mdp_irq_mask & mask) {
161 locked_disable_mdp_irq(mdp, mask);
162 printk(KERN_WARNING "timeout waiting for mdp to complete %x\n",
163 mask);
164 ret = -ETIMEDOUT;
165 }
166 spin_unlock_irqrestore(&mdp_lock, irq_flags);
167
168 return ret;
169}
170
171void mdp_dma_wait(struct mdp_device *mdp_dev)
172{
173#define MDP_MAX_TIMEOUTS 20
174 static int timeout_count;
175 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
176
177 if (mdp_wait(mdp, DL0_DMA2_TERM_DONE, &mdp_dma2_waitqueue) == -ETIMEDOUT)
178 timeout_count++;
179 else
180 timeout_count = 0;
181
182 if (timeout_count > MDP_MAX_TIMEOUTS) {
183 printk(KERN_ERR "mdp: dma failed %d times, somethings wrong!\n",
184 MDP_MAX_TIMEOUTS);
185 BUG();
186 }
187}
188
189static int mdp_ppp_wait(struct mdp_info *mdp)
190{
191 return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
192}
193
194void mdp_dma_to_mddi(struct mdp_info *mdp, uint32_t addr, uint32_t stride,
195 uint32_t width, uint32_t height, uint32_t x, uint32_t y,
196 struct msmfb_callback *callback)
197{
198 uint32_t dma2_cfg;
199 uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
200
201 if (enable_mdp_irq(mdp, DL0_DMA2_TERM_DONE)) {
202 printk(KERN_ERR "mdp_dma_to_mddi: busy\n");
203 return;
204 }
205
206 dma_callback = callback;
207
208 dma2_cfg = DMA_PACK_TIGHT |
209 DMA_PACK_ALIGN_LSB |
210 DMA_PACK_PATTERN_RGB |
211 DMA_OUT_SEL_AHB |
212 DMA_IBUF_NONCONTIGUOUS;
213
214 dma2_cfg |= DMA_IBUF_FORMAT_RGB565;
215
216 dma2_cfg |= DMA_OUT_SEL_MDDI;
217
218 dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
219
220 dma2_cfg |= DMA_DITHER_EN;
221
222 /* setup size, address, and stride */
223 mdp_writel(mdp, (height << 16) | (width),
224 MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
225 mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
226 mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);
227
228 /* 666 18BPP */
229 dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
230
231 /* set y & x offset and MDDI transaction parameters */
232 mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
233 mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
234 mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM,
235 MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
236
237 mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);
238
239 /* start DMA2 */
240 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
241}
242
243void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
244 uint32_t width, uint32_t height, uint32_t x, uint32_t y,
245 struct msmfb_callback *callback, int interface)
246{
247 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
248
249 if (interface == MSM_MDDI_PMDH_INTERFACE) {
250 mdp_dma_to_mddi(mdp, addr, stride, width, height, x, y,
251 callback);
252 }
253}
254
255int get_img(struct mdp_img *img, struct fb_info *info,
256 unsigned long *start, unsigned long *len,
257 struct file **filep)
258{
259 int ret = 0;
260 struct fd f = fdget(img->memory_id);
261 if (f.file == NULL)
262 return -1;
263
264 if (MAJOR(file_inode(f.file)->i_rdev) == FB_MAJOR) {
265 *start = info->fix.smem_start;
266 *len = info->fix.smem_len;
267 } else
268 ret = -1;
269 fdput(f);
270
271 return ret;
272}
273
274void put_img(struct file *src_file, struct file *dst_file)
275{
276}
277
278int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
279 struct mdp_blit_req *req)
280{
281 int ret;
282 unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
283 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
284 struct file *src_file = 0, *dst_file = 0;
285
286 /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
287 if (unlikely(req->src_rect.h == 0 ||
288 req->src_rect.w == 0)) {
289 printk(KERN_ERR "mpd_ppp: src img of zero size!\n");
290 return -EINVAL;
291 }
292 if (unlikely(req->dst_rect.h == 0 ||
293 req->dst_rect.w == 0))
294 return -EINVAL;
295
296 /* do this first so that if this fails, the caller can always
297 * safely call put_img */
298 if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
299 printk(KERN_ERR "mpd_ppp: could not retrieve src image from "
300 "memory\n");
301 return -EINVAL;
302 }
303
304 if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
305 printk(KERN_ERR "mpd_ppp: could not retrieve dst image from "
306 "memory\n");
307 return -EINVAL;
308 }
309 mutex_lock(&mdp_mutex);
310
311 /* transp_masking unimplemented */
312 req->transp_mask = MDP_TRANSP_NOP;
313 if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
314 req->alpha != MDP_ALPHA_NOP ||
315 HAS_ALPHA(req->src.format)) &&
316 (req->flags & MDP_ROT_90 &&
317 req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
318 int i;
319 unsigned int tiles = req->dst_rect.h / 16;
320 unsigned int remainder = req->dst_rect.h % 16;
321 req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
322 req->dst_rect.h = 16;
323 for (i = 0; i < tiles; i++) {
324 enable_mdp_irq(mdp, DL0_ROI_DONE);
325 ret = mdp_ppp_blit(mdp, req, src_file, src_start,
326 src_len, dst_file, dst_start,
327 dst_len);
328 if (ret)
329 goto err_bad_blit;
330 ret = mdp_ppp_wait(mdp);
331 if (ret)
332 goto err_wait_failed;
333 req->dst_rect.y += 16;
334 req->src_rect.x += req->src_rect.w;
335 }
336 if (!remainder)
337 goto end;
338 req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
339 req->dst_rect.h = remainder;
340 }
341 enable_mdp_irq(mdp, DL0_ROI_DONE);
342 ret = mdp_ppp_blit(mdp, req, src_file, src_start, src_len, dst_file,
343 dst_start,
344 dst_len);
345 if (ret)
346 goto err_bad_blit;
347 ret = mdp_ppp_wait(mdp);
348 if (ret)
349 goto err_wait_failed;
350end:
351 put_img(src_file, dst_file);
352 mutex_unlock(&mdp_mutex);
353 return 0;
354err_bad_blit:
355 disable_mdp_irq(mdp, DL0_ROI_DONE);
356err_wait_failed:
357 put_img(src_file, dst_file);
358 mutex_unlock(&mdp_mutex);
359 return ret;
360}
361
362void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
363{
364 struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
365
366 disp_id &= 0xf;
367 mdp_writel(mdp, disp_id, MDP_FULL_BYPASS_WORD43);
368}
369
370int register_mdp_client(struct class_interface *cint)
371{
372 if (!mdp_class) {
373 pr_err("mdp: no mdp_class when registering mdp client\n");
374 return -ENODEV;
375 }
376 cint->class = mdp_class;
377 return class_interface_register(cint);
378}
379
380#include "mdp_csc_table.h"
381#include "mdp_scale_tables.h"
382
383int mdp_probe(struct platform_device *pdev)
384{
385 struct resource *resource;
386 int ret;
387 int n;
388 struct mdp_info *mdp;
389
390 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
391 if (!resource) {
392 pr_err("mdp: can not get mdp mem resource!\n");
393 return -ENOMEM;
394 }
395
396 mdp = kzalloc(sizeof(struct mdp_info), GFP_KERNEL);
397 if (!mdp)
398 return -ENOMEM;
399
400 mdp->irq = platform_get_irq(pdev, 0);
401 if (mdp->irq < 0) {
402 pr_err("mdp: can not get mdp irq\n");
403 ret = mdp->irq;
404 goto error_get_irq;
405 }
406
407 mdp->base = ioremap(resource->start, resource_size(resource));
408 if (mdp->base == 0) {
409 printk(KERN_ERR "msmfb: cannot allocate mdp regs!\n");
410 ret = -ENOMEM;
411 goto error_ioremap;
412 }
413
414 mdp->mdp_dev.dma = mdp_dma;
415 mdp->mdp_dev.dma_wait = mdp_dma_wait;
416 mdp->mdp_dev.blit = mdp_blit;
417 mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
418
419 clk = clk_get(&pdev->dev, "mdp_clk");
420 if (IS_ERR(clk)) {
421 printk(KERN_INFO "mdp: failed to get mdp clk");
422 ret = PTR_ERR(clk);
423 goto error_get_clk;
424 }
425
426 ret = request_irq(mdp->irq, mdp_isr, 0, "msm_mdp", mdp);
427 if (ret)
428 goto error_request_irq;
429 disable_irq(mdp->irq);
430 mdp_irq_mask = 0;
431
432 /* debug interface write access */
433 mdp_writel(mdp, 1, 0x60);
434
435 mdp_writel(mdp, MDP_ANY_INTR_MASK, MDP_INTR_ENABLE);
436 mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
437
438 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
439 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
440
441 for (n = 0; n < ARRAY_SIZE(csc_table); n++)
442 mdp_writel(mdp, csc_table[n].val, csc_table[n].reg);
443
444 /* clear up unused fg/main registers */
445 /* comp.plane 2&3 ystride */
446 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
447
448 /* unpacked pattern */
449 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
450 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
451 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
452 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
453 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
454 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
455 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
456 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
457 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
458
459 /* comp.plane 2 & 3 */
460 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
461 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
462
463 /* clear unused bg registers */
464 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
465 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
466 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
467 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
468 mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
469
470 for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++)
471 mdp_writel(mdp, mdp_upscale_table[n].val,
472 mdp_upscale_table[n].reg);
473
474 for (n = 0; n < 9; n++)
475 mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n);
476 mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0);
477 mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0);
478 mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0);
479
480 /* register mdp device */
481 mdp->mdp_dev.dev.parent = &pdev->dev;
482 mdp->mdp_dev.dev.class = mdp_class;
483 dev_set_name(&mdp->mdp_dev.dev, "mdp%d", pdev->id);
484
485 /* if you can remove the platform device you'd have to implement
486 * this:
487 mdp_dev.release = mdp_class; */
488
489 ret = device_register(&mdp->mdp_dev.dev);
490 if (ret)
491 goto error_device_register;
492 return 0;
493
494error_device_register:
495 free_irq(mdp->irq, mdp);
496error_request_irq:
497error_get_clk:
498 iounmap(mdp->base);
499error_get_irq:
500error_ioremap:
501 kfree(mdp);
502 return ret;
503}
504
505static struct platform_driver msm_mdp_driver = {
506 .probe = mdp_probe,
507 .driver = {.name = "msm_mdp"},
508};
509
510static int __init mdp_init(void)
511{
512 mdp_class = class_create(THIS_MODULE, "msm_mdp");
513 if (IS_ERR(mdp_class)) {
514 printk(KERN_ERR "Error creating mdp class\n");
515 return PTR_ERR(mdp_class);
516 }
517 return platform_driver_register(&msm_mdp_driver);
518}
519
520subsys_initcall(mdp_init);
diff --git a/drivers/video/fbdev/msm/mdp_csc_table.h b/drivers/video/fbdev/msm/mdp_csc_table.h
deleted file mode 100644
index d1cde30ead52..000000000000
--- a/drivers/video/fbdev/msm/mdp_csc_table.h
+++ /dev/null
@@ -1,582 +0,0 @@
1/* drivers/video/msm_fb/mdp_csc_table.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16static struct {
17 uint32_t reg;
18 uint32_t val;
19} csc_table[] = {
20 { 0x40400, 0x83 },
21 { 0x40404, 0x102 },
22 { 0x40408, 0x32 },
23 { 0x4040c, 0xffffffb5 },
24 { 0x40410, 0xffffff6c },
25 { 0x40414, 0xe1 },
26 { 0x40418, 0xe1 },
27 { 0x4041c, 0xffffff45 },
28 { 0x40420, 0xffffffdc },
29 { 0x40440, 0x254 },
30 { 0x40444, 0x0 },
31 { 0x40448, 0x331 },
32 { 0x4044c, 0x254 },
33 { 0x40450, 0xffffff38 },
34 { 0x40454, 0xfffffe61 },
35 { 0x40458, 0x254 },
36 { 0x4045c, 0x409 },
37 { 0x40460, 0x0 },
38 { 0x40480, 0x5d },
39 { 0x40484, 0x13a },
40 { 0x40488, 0x20 },
41 { 0x4048c, 0xffffffcd },
42 { 0x40490, 0xffffff54 },
43 { 0x40494, 0xe1 },
44 { 0x40498, 0xe1 },
45 { 0x4049c, 0xffffff35 },
46 { 0x404a0, 0xffffffec },
47 { 0x404c0, 0x254 },
48 { 0x404c4, 0x0 },
49 { 0x404c8, 0x396 },
50 { 0x404cc, 0x254 },
51 { 0x404d0, 0xffffff94 },
52 { 0x404d4, 0xfffffef0 },
53 { 0x404d8, 0x254 },
54 { 0x404dc, 0x43a },
55 { 0x404e0, 0x0 },
56 { 0x40500, 0x10 },
57 { 0x40504, 0x80 },
58 { 0x40508, 0x80 },
59 { 0x40540, 0x10 },
60 { 0x40544, 0x80 },
61 { 0x40548, 0x80 },
62 { 0x40580, 0x10 },
63 { 0x40584, 0xeb },
64 { 0x40588, 0x10 },
65 { 0x4058c, 0xf0 },
66 { 0x405c0, 0x10 },
67 { 0x405c4, 0xeb },
68 { 0x405c8, 0x10 },
69 { 0x405cc, 0xf0 },
70 { 0x40800, 0x0 },
71 { 0x40804, 0x151515 },
72 { 0x40808, 0x1d1d1d },
73 { 0x4080c, 0x232323 },
74 { 0x40810, 0x272727 },
75 { 0x40814, 0x2b2b2b },
76 { 0x40818, 0x2f2f2f },
77 { 0x4081c, 0x333333 },
78 { 0x40820, 0x363636 },
79 { 0x40824, 0x393939 },
80 { 0x40828, 0x3b3b3b },
81 { 0x4082c, 0x3e3e3e },
82 { 0x40830, 0x404040 },
83 { 0x40834, 0x434343 },
84 { 0x40838, 0x454545 },
85 { 0x4083c, 0x474747 },
86 { 0x40840, 0x494949 },
87 { 0x40844, 0x4b4b4b },
88 { 0x40848, 0x4d4d4d },
89 { 0x4084c, 0x4f4f4f },
90 { 0x40850, 0x515151 },
91 { 0x40854, 0x535353 },
92 { 0x40858, 0x555555 },
93 { 0x4085c, 0x565656 },
94 { 0x40860, 0x585858 },
95 { 0x40864, 0x5a5a5a },
96 { 0x40868, 0x5b5b5b },
97 { 0x4086c, 0x5d5d5d },
98 { 0x40870, 0x5e5e5e },
99 { 0x40874, 0x606060 },
100 { 0x40878, 0x616161 },
101 { 0x4087c, 0x636363 },
102 { 0x40880, 0x646464 },
103 { 0x40884, 0x666666 },
104 { 0x40888, 0x676767 },
105 { 0x4088c, 0x686868 },
106 { 0x40890, 0x6a6a6a },
107 { 0x40894, 0x6b6b6b },
108 { 0x40898, 0x6c6c6c },
109 { 0x4089c, 0x6e6e6e },
110 { 0x408a0, 0x6f6f6f },
111 { 0x408a4, 0x707070 },
112 { 0x408a8, 0x717171 },
113 { 0x408ac, 0x727272 },
114 { 0x408b0, 0x747474 },
115 { 0x408b4, 0x757575 },
116 { 0x408b8, 0x767676 },
117 { 0x408bc, 0x777777 },
118 { 0x408c0, 0x787878 },
119 { 0x408c4, 0x797979 },
120 { 0x408c8, 0x7a7a7a },
121 { 0x408cc, 0x7c7c7c },
122 { 0x408d0, 0x7d7d7d },
123 { 0x408d4, 0x7e7e7e },
124 { 0x408d8, 0x7f7f7f },
125 { 0x408dc, 0x808080 },
126 { 0x408e0, 0x818181 },
127 { 0x408e4, 0x828282 },
128 { 0x408e8, 0x838383 },
129 { 0x408ec, 0x848484 },
130 { 0x408f0, 0x858585 },
131 { 0x408f4, 0x868686 },
132 { 0x408f8, 0x878787 },
133 { 0x408fc, 0x888888 },
134 { 0x40900, 0x898989 },
135 { 0x40904, 0x8a8a8a },
136 { 0x40908, 0x8b8b8b },
137 { 0x4090c, 0x8c8c8c },
138 { 0x40910, 0x8d8d8d },
139 { 0x40914, 0x8e8e8e },
140 { 0x40918, 0x8f8f8f },
141 { 0x4091c, 0x8f8f8f },
142 { 0x40920, 0x909090 },
143 { 0x40924, 0x919191 },
144 { 0x40928, 0x929292 },
145 { 0x4092c, 0x939393 },
146 { 0x40930, 0x949494 },
147 { 0x40934, 0x959595 },
148 { 0x40938, 0x969696 },
149 { 0x4093c, 0x969696 },
150 { 0x40940, 0x979797 },
151 { 0x40944, 0x989898 },
152 { 0x40948, 0x999999 },
153 { 0x4094c, 0x9a9a9a },
154 { 0x40950, 0x9b9b9b },
155 { 0x40954, 0x9c9c9c },
156 { 0x40958, 0x9c9c9c },
157 { 0x4095c, 0x9d9d9d },
158 { 0x40960, 0x9e9e9e },
159 { 0x40964, 0x9f9f9f },
160 { 0x40968, 0xa0a0a0 },
161 { 0x4096c, 0xa0a0a0 },
162 { 0x40970, 0xa1a1a1 },
163 { 0x40974, 0xa2a2a2 },
164 { 0x40978, 0xa3a3a3 },
165 { 0x4097c, 0xa4a4a4 },
166 { 0x40980, 0xa4a4a4 },
167 { 0x40984, 0xa5a5a5 },
168 { 0x40988, 0xa6a6a6 },
169 { 0x4098c, 0xa7a7a7 },
170 { 0x40990, 0xa7a7a7 },
171 { 0x40994, 0xa8a8a8 },
172 { 0x40998, 0xa9a9a9 },
173 { 0x4099c, 0xaaaaaa },
174 { 0x409a0, 0xaaaaaa },
175 { 0x409a4, 0xababab },
176 { 0x409a8, 0xacacac },
177 { 0x409ac, 0xadadad },
178 { 0x409b0, 0xadadad },
179 { 0x409b4, 0xaeaeae },
180 { 0x409b8, 0xafafaf },
181 { 0x409bc, 0xafafaf },
182 { 0x409c0, 0xb0b0b0 },
183 { 0x409c4, 0xb1b1b1 },
184 { 0x409c8, 0xb2b2b2 },
185 { 0x409cc, 0xb2b2b2 },
186 { 0x409d0, 0xb3b3b3 },
187 { 0x409d4, 0xb4b4b4 },
188 { 0x409d8, 0xb4b4b4 },
189 { 0x409dc, 0xb5b5b5 },
190 { 0x409e0, 0xb6b6b6 },
191 { 0x409e4, 0xb6b6b6 },
192 { 0x409e8, 0xb7b7b7 },
193 { 0x409ec, 0xb8b8b8 },
194 { 0x409f0, 0xb8b8b8 },
195 { 0x409f4, 0xb9b9b9 },
196 { 0x409f8, 0xbababa },
197 { 0x409fc, 0xbababa },
198 { 0x40a00, 0xbbbbbb },
199 { 0x40a04, 0xbcbcbc },
200 { 0x40a08, 0xbcbcbc },
201 { 0x40a0c, 0xbdbdbd },
202 { 0x40a10, 0xbebebe },
203 { 0x40a14, 0xbebebe },
204 { 0x40a18, 0xbfbfbf },
205 { 0x40a1c, 0xc0c0c0 },
206 { 0x40a20, 0xc0c0c0 },
207 { 0x40a24, 0xc1c1c1 },
208 { 0x40a28, 0xc1c1c1 },
209 { 0x40a2c, 0xc2c2c2 },
210 { 0x40a30, 0xc3c3c3 },
211 { 0x40a34, 0xc3c3c3 },
212 { 0x40a38, 0xc4c4c4 },
213 { 0x40a3c, 0xc5c5c5 },
214 { 0x40a40, 0xc5c5c5 },
215 { 0x40a44, 0xc6c6c6 },
216 { 0x40a48, 0xc6c6c6 },
217 { 0x40a4c, 0xc7c7c7 },
218 { 0x40a50, 0xc8c8c8 },
219 { 0x40a54, 0xc8c8c8 },
220 { 0x40a58, 0xc9c9c9 },
221 { 0x40a5c, 0xc9c9c9 },
222 { 0x40a60, 0xcacaca },
223 { 0x40a64, 0xcbcbcb },
224 { 0x40a68, 0xcbcbcb },
225 { 0x40a6c, 0xcccccc },
226 { 0x40a70, 0xcccccc },
227 { 0x40a74, 0xcdcdcd },
228 { 0x40a78, 0xcecece },
229 { 0x40a7c, 0xcecece },
230 { 0x40a80, 0xcfcfcf },
231 { 0x40a84, 0xcfcfcf },
232 { 0x40a88, 0xd0d0d0 },
233 { 0x40a8c, 0xd0d0d0 },
234 { 0x40a90, 0xd1d1d1 },
235 { 0x40a94, 0xd2d2d2 },
236 { 0x40a98, 0xd2d2d2 },
237 { 0x40a9c, 0xd3d3d3 },
238 { 0x40aa0, 0xd3d3d3 },
239 { 0x40aa4, 0xd4d4d4 },
240 { 0x40aa8, 0xd4d4d4 },
241 { 0x40aac, 0xd5d5d5 },
242 { 0x40ab0, 0xd6d6d6 },
243 { 0x40ab4, 0xd6d6d6 },
244 { 0x40ab8, 0xd7d7d7 },
245 { 0x40abc, 0xd7d7d7 },
246 { 0x40ac0, 0xd8d8d8 },
247 { 0x40ac4, 0xd8d8d8 },
248 { 0x40ac8, 0xd9d9d9 },
249 { 0x40acc, 0xd9d9d9 },
250 { 0x40ad0, 0xdadada },
251 { 0x40ad4, 0xdbdbdb },
252 { 0x40ad8, 0xdbdbdb },
253 { 0x40adc, 0xdcdcdc },
254 { 0x40ae0, 0xdcdcdc },
255 { 0x40ae4, 0xdddddd },
256 { 0x40ae8, 0xdddddd },
257 { 0x40aec, 0xdedede },
258 { 0x40af0, 0xdedede },
259 { 0x40af4, 0xdfdfdf },
260 { 0x40af8, 0xdfdfdf },
261 { 0x40afc, 0xe0e0e0 },
262 { 0x40b00, 0xe0e0e0 },
263 { 0x40b04, 0xe1e1e1 },
264 { 0x40b08, 0xe1e1e1 },
265 { 0x40b0c, 0xe2e2e2 },
266 { 0x40b10, 0xe3e3e3 },
267 { 0x40b14, 0xe3e3e3 },
268 { 0x40b18, 0xe4e4e4 },
269 { 0x40b1c, 0xe4e4e4 },
270 { 0x40b20, 0xe5e5e5 },
271 { 0x40b24, 0xe5e5e5 },
272 { 0x40b28, 0xe6e6e6 },
273 { 0x40b2c, 0xe6e6e6 },
274 { 0x40b30, 0xe7e7e7 },
275 { 0x40b34, 0xe7e7e7 },
276 { 0x40b38, 0xe8e8e8 },
277 { 0x40b3c, 0xe8e8e8 },
278 { 0x40b40, 0xe9e9e9 },
279 { 0x40b44, 0xe9e9e9 },
280 { 0x40b48, 0xeaeaea },
281 { 0x40b4c, 0xeaeaea },
282 { 0x40b50, 0xebebeb },
283 { 0x40b54, 0xebebeb },
284 { 0x40b58, 0xececec },
285 { 0x40b5c, 0xececec },
286 { 0x40b60, 0xededed },
287 { 0x40b64, 0xededed },
288 { 0x40b68, 0xeeeeee },
289 { 0x40b6c, 0xeeeeee },
290 { 0x40b70, 0xefefef },
291 { 0x40b74, 0xefefef },
292 { 0x40b78, 0xf0f0f0 },
293 { 0x40b7c, 0xf0f0f0 },
294 { 0x40b80, 0xf1f1f1 },
295 { 0x40b84, 0xf1f1f1 },
296 { 0x40b88, 0xf2f2f2 },
297 { 0x40b8c, 0xf2f2f2 },
298 { 0x40b90, 0xf2f2f2 },
299 { 0x40b94, 0xf3f3f3 },
300 { 0x40b98, 0xf3f3f3 },
301 { 0x40b9c, 0xf4f4f4 },
302 { 0x40ba0, 0xf4f4f4 },
303 { 0x40ba4, 0xf5f5f5 },
304 { 0x40ba8, 0xf5f5f5 },
305 { 0x40bac, 0xf6f6f6 },
306 { 0x40bb0, 0xf6f6f6 },
307 { 0x40bb4, 0xf7f7f7 },
308 { 0x40bb8, 0xf7f7f7 },
309 { 0x40bbc, 0xf8f8f8 },
310 { 0x40bc0, 0xf8f8f8 },
311 { 0x40bc4, 0xf9f9f9 },
312 { 0x40bc8, 0xf9f9f9 },
313 { 0x40bcc, 0xfafafa },
314 { 0x40bd0, 0xfafafa },
315 { 0x40bd4, 0xfafafa },
316 { 0x40bd8, 0xfbfbfb },
317 { 0x40bdc, 0xfbfbfb },
318 { 0x40be0, 0xfcfcfc },
319 { 0x40be4, 0xfcfcfc },
320 { 0x40be8, 0xfdfdfd },
321 { 0x40bec, 0xfdfdfd },
322 { 0x40bf0, 0xfefefe },
323 { 0x40bf4, 0xfefefe },
324 { 0x40bf8, 0xffffff },
325 { 0x40bfc, 0xffffff },
326 { 0x40c00, 0x0 },
327 { 0x40c04, 0x0 },
328 { 0x40c08, 0x0 },
329 { 0x40c0c, 0x0 },
330 { 0x40c10, 0x0 },
331 { 0x40c14, 0x0 },
332 { 0x40c18, 0x0 },
333 { 0x40c1c, 0x0 },
334 { 0x40c20, 0x0 },
335 { 0x40c24, 0x0 },
336 { 0x40c28, 0x0 },
337 { 0x40c2c, 0x0 },
338 { 0x40c30, 0x0 },
339 { 0x40c34, 0x0 },
340 { 0x40c38, 0x0 },
341 { 0x40c3c, 0x0 },
342 { 0x40c40, 0x10101 },
343 { 0x40c44, 0x10101 },
344 { 0x40c48, 0x10101 },
345 { 0x40c4c, 0x10101 },
346 { 0x40c50, 0x10101 },
347 { 0x40c54, 0x10101 },
348 { 0x40c58, 0x10101 },
349 { 0x40c5c, 0x10101 },
350 { 0x40c60, 0x10101 },
351 { 0x40c64, 0x10101 },
352 { 0x40c68, 0x20202 },
353 { 0x40c6c, 0x20202 },
354 { 0x40c70, 0x20202 },
355 { 0x40c74, 0x20202 },
356 { 0x40c78, 0x20202 },
357 { 0x40c7c, 0x20202 },
358 { 0x40c80, 0x30303 },
359 { 0x40c84, 0x30303 },
360 { 0x40c88, 0x30303 },
361 { 0x40c8c, 0x30303 },
362 { 0x40c90, 0x30303 },
363 { 0x40c94, 0x40404 },
364 { 0x40c98, 0x40404 },
365 { 0x40c9c, 0x40404 },
366 { 0x40ca0, 0x40404 },
367 { 0x40ca4, 0x40404 },
368 { 0x40ca8, 0x50505 },
369 { 0x40cac, 0x50505 },
370 { 0x40cb0, 0x50505 },
371 { 0x40cb4, 0x50505 },
372 { 0x40cb8, 0x60606 },
373 { 0x40cbc, 0x60606 },
374 { 0x40cc0, 0x60606 },
375 { 0x40cc4, 0x70707 },
376 { 0x40cc8, 0x70707 },
377 { 0x40ccc, 0x70707 },
378 { 0x40cd0, 0x70707 },
379 { 0x40cd4, 0x80808 },
380 { 0x40cd8, 0x80808 },
381 { 0x40cdc, 0x80808 },
382 { 0x40ce0, 0x90909 },
383 { 0x40ce4, 0x90909 },
384 { 0x40ce8, 0xa0a0a },
385 { 0x40cec, 0xa0a0a },
386 { 0x40cf0, 0xa0a0a },
387 { 0x40cf4, 0xb0b0b },
388 { 0x40cf8, 0xb0b0b },
389 { 0x40cfc, 0xb0b0b },
390 { 0x40d00, 0xc0c0c },
391 { 0x40d04, 0xc0c0c },
392 { 0x40d08, 0xd0d0d },
393 { 0x40d0c, 0xd0d0d },
394 { 0x40d10, 0xe0e0e },
395 { 0x40d14, 0xe0e0e },
396 { 0x40d18, 0xe0e0e },
397 { 0x40d1c, 0xf0f0f },
398 { 0x40d20, 0xf0f0f },
399 { 0x40d24, 0x101010 },
400 { 0x40d28, 0x101010 },
401 { 0x40d2c, 0x111111 },
402 { 0x40d30, 0x111111 },
403 { 0x40d34, 0x121212 },
404 { 0x40d38, 0x121212 },
405 { 0x40d3c, 0x131313 },
406 { 0x40d40, 0x131313 },
407 { 0x40d44, 0x141414 },
408 { 0x40d48, 0x151515 },
409 { 0x40d4c, 0x151515 },
410 { 0x40d50, 0x161616 },
411 { 0x40d54, 0x161616 },
412 { 0x40d58, 0x171717 },
413 { 0x40d5c, 0x171717 },
414 { 0x40d60, 0x181818 },
415 { 0x40d64, 0x191919 },
416 { 0x40d68, 0x191919 },
417 { 0x40d6c, 0x1a1a1a },
418 { 0x40d70, 0x1b1b1b },
419 { 0x40d74, 0x1b1b1b },
420 { 0x40d78, 0x1c1c1c },
421 { 0x40d7c, 0x1c1c1c },
422 { 0x40d80, 0x1d1d1d },
423 { 0x40d84, 0x1e1e1e },
424 { 0x40d88, 0x1f1f1f },
425 { 0x40d8c, 0x1f1f1f },
426 { 0x40d90, 0x202020 },
427 { 0x40d94, 0x212121 },
428 { 0x40d98, 0x212121 },
429 { 0x40d9c, 0x222222 },
430 { 0x40da0, 0x232323 },
431 { 0x40da4, 0x242424 },
432 { 0x40da8, 0x242424 },
433 { 0x40dac, 0x252525 },
434 { 0x40db0, 0x262626 },
435 { 0x40db4, 0x272727 },
436 { 0x40db8, 0x272727 },
437 { 0x40dbc, 0x282828 },
438 { 0x40dc0, 0x292929 },
439 { 0x40dc4, 0x2a2a2a },
440 { 0x40dc8, 0x2b2b2b },
441 { 0x40dcc, 0x2c2c2c },
442 { 0x40dd0, 0x2c2c2c },
443 { 0x40dd4, 0x2d2d2d },
444 { 0x40dd8, 0x2e2e2e },
445 { 0x40ddc, 0x2f2f2f },
446 { 0x40de0, 0x303030 },
447 { 0x40de4, 0x313131 },
448 { 0x40de8, 0x323232 },
449 { 0x40dec, 0x333333 },
450 { 0x40df0, 0x333333 },
451 { 0x40df4, 0x343434 },
452 { 0x40df8, 0x353535 },
453 { 0x40dfc, 0x363636 },
454 { 0x40e00, 0x373737 },
455 { 0x40e04, 0x383838 },
456 { 0x40e08, 0x393939 },
457 { 0x40e0c, 0x3a3a3a },
458 { 0x40e10, 0x3b3b3b },
459 { 0x40e14, 0x3c3c3c },
460 { 0x40e18, 0x3d3d3d },
461 { 0x40e1c, 0x3e3e3e },
462 { 0x40e20, 0x3f3f3f },
463 { 0x40e24, 0x404040 },
464 { 0x40e28, 0x414141 },
465 { 0x40e2c, 0x424242 },
466 { 0x40e30, 0x434343 },
467 { 0x40e34, 0x444444 },
468 { 0x40e38, 0x464646 },
469 { 0x40e3c, 0x474747 },
470 { 0x40e40, 0x484848 },
471 { 0x40e44, 0x494949 },
472 { 0x40e48, 0x4a4a4a },
473 { 0x40e4c, 0x4b4b4b },
474 { 0x40e50, 0x4c4c4c },
475 { 0x40e54, 0x4d4d4d },
476 { 0x40e58, 0x4f4f4f },
477 { 0x40e5c, 0x505050 },
478 { 0x40e60, 0x515151 },
479 { 0x40e64, 0x525252 },
480 { 0x40e68, 0x535353 },
481 { 0x40e6c, 0x545454 },
482 { 0x40e70, 0x565656 },
483 { 0x40e74, 0x575757 },
484 { 0x40e78, 0x585858 },
485 { 0x40e7c, 0x595959 },
486 { 0x40e80, 0x5b5b5b },
487 { 0x40e84, 0x5c5c5c },
488 { 0x40e88, 0x5d5d5d },
489 { 0x40e8c, 0x5e5e5e },
490 { 0x40e90, 0x606060 },
491 { 0x40e94, 0x616161 },
492 { 0x40e98, 0x626262 },
493 { 0x40e9c, 0x646464 },
494 { 0x40ea0, 0x656565 },
495 { 0x40ea4, 0x666666 },
496 { 0x40ea8, 0x686868 },
497 { 0x40eac, 0x696969 },
498 { 0x40eb0, 0x6a6a6a },
499 { 0x40eb4, 0x6c6c6c },
500 { 0x40eb8, 0x6d6d6d },
501 { 0x40ebc, 0x6f6f6f },
502 { 0x40ec0, 0x707070 },
503 { 0x40ec4, 0x717171 },
504 { 0x40ec8, 0x737373 },
505 { 0x40ecc, 0x747474 },
506 { 0x40ed0, 0x767676 },
507 { 0x40ed4, 0x777777 },
508 { 0x40ed8, 0x797979 },
509 { 0x40edc, 0x7a7a7a },
510 { 0x40ee0, 0x7c7c7c },
511 { 0x40ee4, 0x7d7d7d },
512 { 0x40ee8, 0x7f7f7f },
513 { 0x40eec, 0x808080 },
514 { 0x40ef0, 0x828282 },
515 { 0x40ef4, 0x838383 },
516 { 0x40ef8, 0x858585 },
517 { 0x40efc, 0x868686 },
518 { 0x40f00, 0x888888 },
519 { 0x40f04, 0x898989 },
520 { 0x40f08, 0x8b8b8b },
521 { 0x40f0c, 0x8d8d8d },
522 { 0x40f10, 0x8e8e8e },
523 { 0x40f14, 0x909090 },
524 { 0x40f18, 0x919191 },
525 { 0x40f1c, 0x939393 },
526 { 0x40f20, 0x959595 },
527 { 0x40f24, 0x969696 },
528 { 0x40f28, 0x989898 },
529 { 0x40f2c, 0x9a9a9a },
530 { 0x40f30, 0x9b9b9b },
531 { 0x40f34, 0x9d9d9d },
532 { 0x40f38, 0x9f9f9f },
533 { 0x40f3c, 0xa1a1a1 },
534 { 0x40f40, 0xa2a2a2 },
535 { 0x40f44, 0xa4a4a4 },
536 { 0x40f48, 0xa6a6a6 },
537 { 0x40f4c, 0xa7a7a7 },
538 { 0x40f50, 0xa9a9a9 },
539 { 0x40f54, 0xababab },
540 { 0x40f58, 0xadadad },
541 { 0x40f5c, 0xafafaf },
542 { 0x40f60, 0xb0b0b0 },
543 { 0x40f64, 0xb2b2b2 },
544 { 0x40f68, 0xb4b4b4 },
545 { 0x40f6c, 0xb6b6b6 },
546 { 0x40f70, 0xb8b8b8 },
547 { 0x40f74, 0xbababa },
548 { 0x40f78, 0xbbbbbb },
549 { 0x40f7c, 0xbdbdbd },
550 { 0x40f80, 0xbfbfbf },
551 { 0x40f84, 0xc1c1c1 },
552 { 0x40f88, 0xc3c3c3 },
553 { 0x40f8c, 0xc5c5c5 },
554 { 0x40f90, 0xc7c7c7 },
555 { 0x40f94, 0xc9c9c9 },
556 { 0x40f98, 0xcbcbcb },
557 { 0x40f9c, 0xcdcdcd },
558 { 0x40fa0, 0xcfcfcf },
559 { 0x40fa4, 0xd1d1d1 },
560 { 0x40fa8, 0xd3d3d3 },
561 { 0x40fac, 0xd5d5d5 },
562 { 0x40fb0, 0xd7d7d7 },
563 { 0x40fb4, 0xd9d9d9 },
564 { 0x40fb8, 0xdbdbdb },
565 { 0x40fbc, 0xdddddd },
566 { 0x40fc0, 0xdfdfdf },
567 { 0x40fc4, 0xe1e1e1 },
568 { 0x40fc8, 0xe3e3e3 },
569 { 0x40fcc, 0xe5e5e5 },
570 { 0x40fd0, 0xe7e7e7 },
571 { 0x40fd4, 0xe9e9e9 },
572 { 0x40fd8, 0xebebeb },
573 { 0x40fdc, 0xeeeeee },
574 { 0x40fe0, 0xf0f0f0 },
575 { 0x40fe4, 0xf2f2f2 },
576 { 0x40fe8, 0xf4f4f4 },
577 { 0x40fec, 0xf6f6f6 },
578 { 0x40ff0, 0xf8f8f8 },
579 { 0x40ff4, 0xfbfbfb },
580 { 0x40ff8, 0xfdfdfd },
581 { 0x40ffc, 0xffffff },
582};
diff --git a/drivers/video/fbdev/msm/mdp_hw.h b/drivers/video/fbdev/msm/mdp_hw.h
deleted file mode 100644
index 35848d741001..000000000000
--- a/drivers/video/fbdev/msm/mdp_hw.h
+++ /dev/null
@@ -1,627 +0,0 @@
1/* drivers/video/msm_fb/mdp_hw.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#ifndef _MDP_HW_H_
16#define _MDP_HW_H_
17
18#include <linux/platform_data/video-msm_fb.h>
19
20struct mdp_info {
21 struct mdp_device mdp_dev;
22 char * __iomem base;
23 int irq;
24};
25struct mdp_blit_req;
26struct mdp_device;
27int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
28 struct file *src_file, unsigned long src_start,
29 unsigned long src_len, struct file *dst_file,
30 unsigned long dst_start, unsigned long dst_len);
31#define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
32#define mdp_readl(mdp, offset) readl(mdp->base + offset)
33
34#define MDP_SYNC_CONFIG_0 (0x00000)
35#define MDP_SYNC_CONFIG_1 (0x00004)
36#define MDP_SYNC_CONFIG_2 (0x00008)
37#define MDP_SYNC_STATUS_0 (0x0000c)
38#define MDP_SYNC_STATUS_1 (0x00010)
39#define MDP_SYNC_STATUS_2 (0x00014)
40#define MDP_SYNC_THRESH_0 (0x00018)
41#define MDP_SYNC_THRESH_1 (0x0001c)
42#define MDP_INTR_ENABLE (0x00020)
43#define MDP_INTR_STATUS (0x00024)
44#define MDP_INTR_CLEAR (0x00028)
45#define MDP_DISPLAY0_START (0x00030)
46#define MDP_DISPLAY1_START (0x00034)
47#define MDP_DISPLAY_STATUS (0x00038)
48#define MDP_EBI2_LCD0 (0x0003c)
49#define MDP_EBI2_LCD1 (0x00040)
50#define MDP_DISPLAY0_ADDR (0x00054)
51#define MDP_DISPLAY1_ADDR (0x00058)
52#define MDP_EBI2_PORTMAP_MODE (0x0005c)
53#define MDP_MODE (0x00060)
54#define MDP_TV_OUT_STATUS (0x00064)
55#define MDP_HW_VERSION (0x00070)
56#define MDP_SW_RESET (0x00074)
57#define MDP_AXI_ERROR_MASTER_STOP (0x00078)
58#define MDP_SEL_CLK_OR_HCLK_TEST_BUS (0x0007c)
59#define MDP_PRIMARY_VSYNC_OUT_CTRL (0x00080)
60#define MDP_SECONDARY_VSYNC_OUT_CTRL (0x00084)
61#define MDP_EXTERNAL_VSYNC_OUT_CTRL (0x00088)
62#define MDP_VSYNC_CTRL (0x0008c)
63#define MDP_CGC_EN (0x00100)
64#define MDP_CMD_STATUS (0x10008)
65#define MDP_PROFILE_EN (0x10010)
66#define MDP_PROFILE_COUNT (0x10014)
67#define MDP_DMA_START (0x10044)
68#define MDP_FULL_BYPASS_WORD0 (0x10100)
69#define MDP_FULL_BYPASS_WORD1 (0x10104)
70#define MDP_COMMAND_CONFIG (0x10104)
71#define MDP_FULL_BYPASS_WORD2 (0x10108)
72#define MDP_FULL_BYPASS_WORD3 (0x1010c)
73#define MDP_FULL_BYPASS_WORD4 (0x10110)
74#define MDP_FULL_BYPASS_WORD6 (0x10118)
75#define MDP_FULL_BYPASS_WORD7 (0x1011c)
76#define MDP_FULL_BYPASS_WORD8 (0x10120)
77#define MDP_FULL_BYPASS_WORD9 (0x10124)
78#define MDP_PPP_SOURCE_CONFIG (0x10124)
79#define MDP_FULL_BYPASS_WORD10 (0x10128)
80#define MDP_FULL_BYPASS_WORD11 (0x1012c)
81#define MDP_FULL_BYPASS_WORD12 (0x10130)
82#define MDP_FULL_BYPASS_WORD13 (0x10134)
83#define MDP_FULL_BYPASS_WORD14 (0x10138)
84#define MDP_PPP_OPERATION_CONFIG (0x10138)
85#define MDP_FULL_BYPASS_WORD15 (0x1013c)
86#define MDP_FULL_BYPASS_WORD16 (0x10140)
87#define MDP_FULL_BYPASS_WORD17 (0x10144)
88#define MDP_FULL_BYPASS_WORD18 (0x10148)
89#define MDP_FULL_BYPASS_WORD19 (0x1014c)
90#define MDP_FULL_BYPASS_WORD20 (0x10150)
91#define MDP_PPP_DESTINATION_CONFIG (0x10150)
92#define MDP_FULL_BYPASS_WORD21 (0x10154)
93#define MDP_FULL_BYPASS_WORD22 (0x10158)
94#define MDP_FULL_BYPASS_WORD23 (0x1015c)
95#define MDP_FULL_BYPASS_WORD24 (0x10160)
96#define MDP_FULL_BYPASS_WORD25 (0x10164)
97#define MDP_FULL_BYPASS_WORD26 (0x10168)
98#define MDP_FULL_BYPASS_WORD27 (0x1016c)
99#define MDP_FULL_BYPASS_WORD29 (0x10174)
100#define MDP_FULL_BYPASS_WORD30 (0x10178)
101#define MDP_FULL_BYPASS_WORD31 (0x1017c)
102#define MDP_FULL_BYPASS_WORD32 (0x10180)
103#define MDP_DMA_CONFIG (0x10180)
104#define MDP_FULL_BYPASS_WORD33 (0x10184)
105#define MDP_FULL_BYPASS_WORD34 (0x10188)
106#define MDP_FULL_BYPASS_WORD35 (0x1018c)
107#define MDP_FULL_BYPASS_WORD37 (0x10194)
108#define MDP_FULL_BYPASS_WORD39 (0x1019c)
109#define MDP_FULL_BYPASS_WORD40 (0x101a0)
110#define MDP_FULL_BYPASS_WORD41 (0x101a4)
111#define MDP_FULL_BYPASS_WORD43 (0x101ac)
112#define MDP_FULL_BYPASS_WORD46 (0x101b8)
113#define MDP_FULL_BYPASS_WORD47 (0x101bc)
114#define MDP_FULL_BYPASS_WORD48 (0x101c0)
115#define MDP_FULL_BYPASS_WORD49 (0x101c4)
116#define MDP_FULL_BYPASS_WORD50 (0x101c8)
117#define MDP_FULL_BYPASS_WORD51 (0x101cc)
118#define MDP_FULL_BYPASS_WORD52 (0x101d0)
119#define MDP_FULL_BYPASS_WORD53 (0x101d4)
120#define MDP_FULL_BYPASS_WORD54 (0x101d8)
121#define MDP_FULL_BYPASS_WORD55 (0x101dc)
122#define MDP_FULL_BYPASS_WORD56 (0x101e0)
123#define MDP_FULL_BYPASS_WORD57 (0x101e4)
124#define MDP_FULL_BYPASS_WORD58 (0x101e8)
125#define MDP_FULL_BYPASS_WORD59 (0x101ec)
126#define MDP_FULL_BYPASS_WORD60 (0x101f0)
127#define MDP_VSYNC_THRESHOLD (0x101f0)
128#define MDP_FULL_BYPASS_WORD61 (0x101f4)
129#define MDP_FULL_BYPASS_WORD62 (0x101f8)
130#define MDP_FULL_BYPASS_WORD63 (0x101fc)
131#define MDP_TFETCH_TEST_MODE (0x20004)
132#define MDP_TFETCH_STATUS (0x20008)
133#define MDP_TFETCH_TILE_COUNT (0x20010)
134#define MDP_TFETCH_FETCH_COUNT (0x20014)
135#define MDP_TFETCH_CONSTANT_COLOR (0x20040)
136#define MDP_CSC_BYPASS (0x40004)
137#define MDP_SCALE_COEFF_LSB (0x5fffc)
138#define MDP_TV_OUT_CTL (0xc0000)
139#define MDP_TV_OUT_FIR_COEFF (0xc0004)
140#define MDP_TV_OUT_BUF_ADDR (0xc0008)
141#define MDP_TV_OUT_CC_DATA (0xc000c)
142#define MDP_TV_OUT_SOBEL (0xc0010)
143#define MDP_TV_OUT_Y_CLAMP (0xc0018)
144#define MDP_TV_OUT_CB_CLAMP (0xc001c)
145#define MDP_TV_OUT_CR_CLAMP (0xc0020)
146#define MDP_TEST_MODE_CLK (0xd0000)
147#define MDP_TEST_MISR_RESET_CLK (0xd0004)
148#define MDP_TEST_EXPORT_MISR_CLK (0xd0008)
149#define MDP_TEST_MISR_CURR_VAL_CLK (0xd000c)
150#define MDP_TEST_MODE_HCLK (0xd0100)
151#define MDP_TEST_MISR_RESET_HCLK (0xd0104)
152#define MDP_TEST_EXPORT_MISR_HCLK (0xd0108)
153#define MDP_TEST_MISR_CURR_VAL_HCLK (0xd010c)
154#define MDP_TEST_MODE_DCLK (0xd0200)
155#define MDP_TEST_MISR_RESET_DCLK (0xd0204)
156#define MDP_TEST_EXPORT_MISR_DCLK (0xd0208)
157#define MDP_TEST_MISR_CURR_VAL_DCLK (0xd020c)
158#define MDP_TEST_CAPTURED_DCLK (0xd0210)
159#define MDP_TEST_MISR_CAPT_VAL_DCLK (0xd0214)
160#define MDP_LCDC_CTL (0xe0000)
161#define MDP_LCDC_HSYNC_CTL (0xe0004)
162#define MDP_LCDC_VSYNC_CTL (0xe0008)
163#define MDP_LCDC_ACTIVE_HCTL (0xe000c)
164#define MDP_LCDC_ACTIVE_VCTL (0xe0010)
165#define MDP_LCDC_BORDER_CLR (0xe0014)
166#define MDP_LCDC_H_BLANK (0xe0018)
167#define MDP_LCDC_V_BLANK (0xe001c)
168#define MDP_LCDC_UNDERFLOW_CLR (0xe0020)
169#define MDP_LCDC_HSYNC_SKEW (0xe0024)
170#define MDP_LCDC_TEST_CTL (0xe0028)
171#define MDP_LCDC_LINE_IRQ (0xe002c)
172#define MDP_LCDC_CTL_POLARITY (0xe0030)
173#define MDP_LCDC_DMA_CONFIG (0xe1000)
174#define MDP_LCDC_DMA_SIZE (0xe1004)
175#define MDP_LCDC_DMA_IBUF_ADDR (0xe1008)
176#define MDP_LCDC_DMA_IBUF_Y_STRIDE (0xe100c)
177
178
179#define MDP_DMA2_TERM 0x1
180#define MDP_DMA3_TERM 0x2
181#define MDP_PPP_TERM 0x3
182
183/* MDP_INTR_ENABLE */
184#define DL0_ROI_DONE (1<<0)
185#define DL1_ROI_DONE (1<<1)
186#define DL0_DMA2_TERM_DONE (1<<2)
187#define DL1_DMA2_TERM_DONE (1<<3)
188#define DL0_PPP_TERM_DONE (1<<4)
189#define DL1_PPP_TERM_DONE (1<<5)
190#define TV_OUT_DMA3_DONE (1<<6)
191#define TV_ENC_UNDERRUN (1<<7)
192#define DL0_FETCH_DONE (1<<11)
193#define DL1_FETCH_DONE (1<<12)
194
195#define MDP_PPP_BUSY_STATUS (DL0_ROI_DONE| \
196 DL1_ROI_DONE| \
197 DL0_PPP_TERM_DONE| \
198 DL1_PPP_TERM_DONE)
199
200#define MDP_ANY_INTR_MASK (DL0_ROI_DONE| \
201 DL1_ROI_DONE| \
202 DL0_DMA2_TERM_DONE| \
203 DL1_DMA2_TERM_DONE| \
204 DL0_PPP_TERM_DONE| \
205 DL1_PPP_TERM_DONE| \
206 DL0_FETCH_DONE| \
207 DL1_FETCH_DONE| \
208 TV_ENC_UNDERRUN)
209
210#define MDP_TOP_LUMA 16
211#define MDP_TOP_CHROMA 0
212#define MDP_BOTTOM_LUMA 19
213#define MDP_BOTTOM_CHROMA 3
214#define MDP_LEFT_LUMA 22
215#define MDP_LEFT_CHROMA 6
216#define MDP_RIGHT_LUMA 25
217#define MDP_RIGHT_CHROMA 9
218
219#define CLR_G 0x0
220#define CLR_B 0x1
221#define CLR_R 0x2
222#define CLR_ALPHA 0x3
223
224#define CLR_Y CLR_G
225#define CLR_CB CLR_B
226#define CLR_CR CLR_R
227
228/* from lsb to msb */
229#define MDP_GET_PACK_PATTERN(a, x, y, z, bit) \
230 (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
231
232/* MDP_SYNC_CONFIG_0/1/2 */
233#define MDP_SYNCFG_HGT_LOC 22
234#define MDP_SYNCFG_VSYNC_EXT_EN (1<<21)
235#define MDP_SYNCFG_VSYNC_INT_EN (1<<20)
236
237/* MDP_SYNC_THRESH_0 */
238#define MDP_PRIM_BELOW_LOC 0
239#define MDP_PRIM_ABOVE_LOC 8
240
241/* MDP_{PRIMARY,SECONDARY,EXTERNAL}_VSYNC_OUT_CRL */
242#define VSYNC_PULSE_EN (1<<31)
243#define VSYNC_PULSE_INV (1<<30)
244
245/* MDP_VSYNC_CTRL */
246#define DISP0_VSYNC_MAP_VSYNC0 0
247#define DISP0_VSYNC_MAP_VSYNC1 (1<<0)
248#define DISP0_VSYNC_MAP_VSYNC2 ((1<<0)|(1<<1))
249
250#define DISP1_VSYNC_MAP_VSYNC0 0
251#define DISP1_VSYNC_MAP_VSYNC1 (1<<2)
252#define DISP1_VSYNC_MAP_VSYNC2 ((1<<2)|(1<<3))
253
254#define PRIMARY_LCD_SYNC_EN (1<<4)
255#define PRIMARY_LCD_SYNC_DISABLE 0
256
257#define SECONDARY_LCD_SYNC_EN (1<<5)
258#define SECONDARY_LCD_SYNC_DISABLE 0
259
260#define EXTERNAL_LCD_SYNC_EN (1<<6)
261#define EXTERNAL_LCD_SYNC_DISABLE 0
262
263/* MDP_VSYNC_THRESHOLD / MDP_FULL_BYPASS_WORD60 */
264#define VSYNC_THRESHOLD_ABOVE_LOC 0
265#define VSYNC_THRESHOLD_BELOW_LOC 16
266#define VSYNC_ANTI_TEAR_EN (1<<31)
267
268/* MDP_COMMAND_CONFIG / MDP_FULL_BYPASS_WORD1 */
269#define MDP_CMD_DBGBUS_EN (1<<0)
270
271/* MDP_PPP_SOURCE_CONFIG / MDP_FULL_BYPASS_WORD9&53 */
272#define PPP_SRC_C0G_8BIT ((1<<1)|(1<<0))
273#define PPP_SRC_C1B_8BIT ((1<<3)|(1<<2))
274#define PPP_SRC_C2R_8BIT ((1<<5)|(1<<4))
275#define PPP_SRC_C3A_8BIT ((1<<7)|(1<<6))
276
277#define PPP_SRC_C0G_6BIT (1<<1)
278#define PPP_SRC_C1B_6BIT (1<<3)
279#define PPP_SRC_C2R_6BIT (1<<5)
280
281#define PPP_SRC_C0G_5BIT (1<<0)
282#define PPP_SRC_C1B_5BIT (1<<2)
283#define PPP_SRC_C2R_5BIT (1<<4)
284
285#define PPP_SRC_C3ALPHA_EN (1<<8)
286
287#define PPP_SRC_BPP_1BYTES 0
288#define PPP_SRC_BPP_2BYTES (1<<9)
289#define PPP_SRC_BPP_3BYTES (1<<10)
290#define PPP_SRC_BPP_4BYTES ((1<<10)|(1<<9))
291
292#define PPP_SRC_BPP_ROI_ODD_X (1<<11)
293#define PPP_SRC_BPP_ROI_ODD_Y (1<<12)
294#define PPP_SRC_INTERLVD_2COMPONENTS (1<<13)
295#define PPP_SRC_INTERLVD_3COMPONENTS (1<<14)
296#define PPP_SRC_INTERLVD_4COMPONENTS ((1<<14)|(1<<13))
297
298
299/* RGB666 unpack format
300** TIGHT means R6+G6+B6 together
301** LOOSE means R6+2 +G6+2+ B6+2 (with MSB)
302** or 2+R6 +2+G6 +2+B6 (with LSB)
303*/
304#define PPP_SRC_PACK_TIGHT (1<<17)
305#define PPP_SRC_PACK_LOOSE 0
306#define PPP_SRC_PACK_ALIGN_LSB 0
307#define PPP_SRC_PACK_ALIGN_MSB (1<<18)
308
309#define PPP_SRC_PLANE_INTERLVD 0
310#define PPP_SRC_PLANE_PSEUDOPLNR (1<<20)
311
312#define PPP_SRC_WMV9_MODE (1<<21)
313
314/* MDP_PPP_OPERATION_CONFIG / MDP_FULL_BYPASS_WORD14 */
315#define PPP_OP_SCALE_X_ON (1<<0)
316#define PPP_OP_SCALE_Y_ON (1<<1)
317
318#define PPP_OP_CONVERT_RGB2YCBCR 0
319#define PPP_OP_CONVERT_YCBCR2RGB (1<<2)
320#define PPP_OP_CONVERT_ON (1<<3)
321
322#define PPP_OP_CONVERT_MATRIX_PRIMARY 0
323#define PPP_OP_CONVERT_MATRIX_SECONDARY (1<<4)
324
325#define PPP_OP_LUT_C0_ON (1<<5)
326#define PPP_OP_LUT_C1_ON (1<<6)
327#define PPP_OP_LUT_C2_ON (1<<7)
328
329/* rotate or blend enable */
330#define PPP_OP_ROT_ON (1<<8)
331
332#define PPP_OP_ROT_90 (1<<9)
333#define PPP_OP_FLIP_LR (1<<10)
334#define PPP_OP_FLIP_UD (1<<11)
335
336#define PPP_OP_BLEND_ON (1<<12)
337
338#define PPP_OP_BLEND_SRCPIXEL_ALPHA 0
339#define PPP_OP_BLEND_DSTPIXEL_ALPHA (1<<13)
340#define PPP_OP_BLEND_CONSTANT_ALPHA (1<<14)
341#define PPP_OP_BLEND_SRCPIXEL_TRANSP ((1<<13)|(1<<14))
342
343#define PPP_OP_BLEND_ALPHA_BLEND_NORMAL 0
344#define PPP_OP_BLEND_ALPHA_BLEND_REVERSE (1<<15)
345
346#define PPP_OP_DITHER_EN (1<<16)
347
348#define PPP_OP_COLOR_SPACE_RGB 0
349#define PPP_OP_COLOR_SPACE_YCBCR (1<<17)
350
351#define PPP_OP_SRC_CHROMA_RGB 0
352#define PPP_OP_SRC_CHROMA_H2V1 (1<<18)
353#define PPP_OP_SRC_CHROMA_H1V2 (1<<19)
354#define PPP_OP_SRC_CHROMA_420 ((1<<18)|(1<<19))
355#define PPP_OP_SRC_CHROMA_COSITE 0
356#define PPP_OP_SRC_CHROMA_OFFSITE (1<<20)
357
358#define PPP_OP_DST_CHROMA_RGB 0
359#define PPP_OP_DST_CHROMA_H2V1 (1<<21)
360#define PPP_OP_DST_CHROMA_H1V2 (1<<22)
361#define PPP_OP_DST_CHROMA_420 ((1<<21)|(1<<22))
362#define PPP_OP_DST_CHROMA_COSITE 0
363#define PPP_OP_DST_CHROMA_OFFSITE (1<<23)
364
365#define PPP_BLEND_ALPHA_TRANSP (1<<24)
366
367#define PPP_OP_BG_CHROMA_RGB 0
368#define PPP_OP_BG_CHROMA_H2V1 (1<<25)
369#define PPP_OP_BG_CHROMA_H1V2 (1<<26)
370#define PPP_OP_BG_CHROMA_420 ((1<<25)|(1<<26))
371#define PPP_OP_BG_CHROMA_SITE_COSITE 0
372#define PPP_OP_BG_CHROMA_SITE_OFFSITE (1<<27)
373
374/* MDP_PPP_DESTINATION_CONFIG / MDP_FULL_BYPASS_WORD20 */
375#define PPP_DST_C0G_8BIT ((1<<0)|(1<<1))
376#define PPP_DST_C1B_8BIT ((1<<3)|(1<<2))
377#define PPP_DST_C2R_8BIT ((1<<5)|(1<<4))
378#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
379
380#define PPP_DST_C0G_6BIT (1<<1)
381#define PPP_DST_C1B_6BIT (1<<3)
382#define PPP_DST_C2R_6BIT (1<<5)
383
384#define PPP_DST_C0G_5BIT (1<<0)
385#define PPP_DST_C1B_5BIT (1<<2)
386#define PPP_DST_C2R_5BIT (1<<4)
387
388#define PPP_DST_C3A_8BIT ((1<<7)|(1<<6))
389#define PPP_DST_C3ALPHA_EN (1<<8)
390
391#define PPP_DST_INTERLVD_2COMPONENTS (1<<9)
392#define PPP_DST_INTERLVD_3COMPONENTS (1<<10)
393#define PPP_DST_INTERLVD_4COMPONENTS ((1<<10)|(1<<9))
394#define PPP_DST_INTERLVD_6COMPONENTS ((1<<11)|(1<<9))
395
396#define PPP_DST_PACK_LOOSE 0
397#define PPP_DST_PACK_TIGHT (1<<13)
398#define PPP_DST_PACK_ALIGN_LSB 0
399#define PPP_DST_PACK_ALIGN_MSB (1<<14)
400
401#define PPP_DST_OUT_SEL_AXI 0
402#define PPP_DST_OUT_SEL_MDDI (1<<15)
403
404#define PPP_DST_BPP_2BYTES (1<<16)
405#define PPP_DST_BPP_3BYTES (1<<17)
406#define PPP_DST_BPP_4BYTES ((1<<17)|(1<<16))
407
408#define PPP_DST_PLANE_INTERLVD 0
409#define PPP_DST_PLANE_PLANAR (1<<18)
410#define PPP_DST_PLANE_PSEUDOPLNR (1<<19)
411
412#define PPP_DST_TO_TV (1<<20)
413
414#define PPP_DST_MDDI_PRIMARY 0
415#define PPP_DST_MDDI_SECONDARY (1<<21)
416#define PPP_DST_MDDI_EXTERNAL (1<<22)
417
418/* image configurations by image type */
419#define PPP_CFG_MDP_RGB_565(dir) (PPP_##dir##_C2R_5BIT | \
420 PPP_##dir##_C0G_6BIT | \
421 PPP_##dir##_C1B_5BIT | \
422 PPP_##dir##_BPP_2BYTES | \
423 PPP_##dir##_INTERLVD_3COMPONENTS | \
424 PPP_##dir##_PACK_TIGHT | \
425 PPP_##dir##_PACK_ALIGN_LSB | \
426 PPP_##dir##_PLANE_INTERLVD)
427
428#define PPP_CFG_MDP_RGB_888(dir) (PPP_##dir##_C2R_8BIT | \
429 PPP_##dir##_C0G_8BIT | \
430 PPP_##dir##_C1B_8BIT | \
431 PPP_##dir##_BPP_3BYTES | \
432 PPP_##dir##_INTERLVD_3COMPONENTS | \
433 PPP_##dir##_PACK_TIGHT | \
434 PPP_##dir##_PACK_ALIGN_LSB | \
435 PPP_##dir##_PLANE_INTERLVD)
436
437#define PPP_CFG_MDP_ARGB_8888(dir) (PPP_##dir##_C2R_8BIT | \
438 PPP_##dir##_C0G_8BIT | \
439 PPP_##dir##_C1B_8BIT | \
440 PPP_##dir##_C3A_8BIT | \
441 PPP_##dir##_C3ALPHA_EN | \
442 PPP_##dir##_BPP_4BYTES | \
443 PPP_##dir##_INTERLVD_4COMPONENTS | \
444 PPP_##dir##_PACK_TIGHT | \
445 PPP_##dir##_PACK_ALIGN_LSB | \
446 PPP_##dir##_PLANE_INTERLVD)
447
448#define PPP_CFG_MDP_XRGB_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
449#define PPP_CFG_MDP_RGBA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
450#define PPP_CFG_MDP_BGRA_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
451#define PPP_CFG_MDP_RGBX_8888(dir) PPP_CFG_MDP_ARGB_8888(dir)
452
453#define PPP_CFG_MDP_Y_CBCR_H2V2(dir) (PPP_##dir##_C2R_8BIT | \
454 PPP_##dir##_C0G_8BIT | \
455 PPP_##dir##_C1B_8BIT | \
456 PPP_##dir##_C3A_8BIT | \
457 PPP_##dir##_BPP_2BYTES | \
458 PPP_##dir##_INTERLVD_2COMPONENTS | \
459 PPP_##dir##_PACK_TIGHT | \
460 PPP_##dir##_PACK_ALIGN_LSB | \
461 PPP_##dir##_PLANE_PSEUDOPLNR)
462
463#define PPP_CFG_MDP_Y_CRCB_H2V2(dir) PPP_CFG_MDP_Y_CBCR_H2V2(dir)
464
465#define PPP_CFG_MDP_YCRYCB_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
466 PPP_##dir##_C0G_8BIT | \
467 PPP_##dir##_C1B_8BIT | \
468 PPP_##dir##_C3A_8BIT | \
469 PPP_##dir##_BPP_2BYTES | \
470 PPP_##dir##_INTERLVD_4COMPONENTS | \
471 PPP_##dir##_PACK_TIGHT | \
472 PPP_##dir##_PACK_ALIGN_LSB |\
473 PPP_##dir##_PLANE_INTERLVD)
474
475#define PPP_CFG_MDP_Y_CBCR_H2V1(dir) (PPP_##dir##_C2R_8BIT | \
476 PPP_##dir##_C0G_8BIT | \
477 PPP_##dir##_C1B_8BIT | \
478 PPP_##dir##_C3A_8BIT | \
479 PPP_##dir##_BPP_2BYTES | \
480 PPP_##dir##_INTERLVD_2COMPONENTS | \
481 PPP_##dir##_PACK_TIGHT | \
482 PPP_##dir##_PACK_ALIGN_LSB | \
483 PPP_##dir##_PLANE_PSEUDOPLNR)
484
485#define PPP_CFG_MDP_Y_CRCB_H2V1(dir) PPP_CFG_MDP_Y_CBCR_H2V1(dir)
486
487#define PPP_PACK_PATTERN_MDP_RGB_565 \
488 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8)
489#define PPP_PACK_PATTERN_MDP_RGB_888 PPP_PACK_PATTERN_MDP_RGB_565
490#define PPP_PACK_PATTERN_MDP_XRGB_8888 \
491 MDP_GET_PACK_PATTERN(CLR_B, CLR_G, CLR_R, CLR_ALPHA, 8)
492#define PPP_PACK_PATTERN_MDP_ARGB_8888 PPP_PACK_PATTERN_MDP_XRGB_8888
493#define PPP_PACK_PATTERN_MDP_RGBA_8888 \
494 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
495#define PPP_PACK_PATTERN_MDP_BGRA_8888 \
496 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, 8)
497#define PPP_PACK_PATTERN_MDP_RGBX_8888 \
498 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, 8)
499#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1 \
500 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8)
501#define PPP_PACK_PATTERN_MDP_Y_CBCR_H2V2 PPP_PACK_PATTERN_MDP_Y_CBCR_H2V1
502#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1 \
503 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8)
504#define PPP_PACK_PATTERN_MDP_Y_CRCB_H2V2 PPP_PACK_PATTERN_MDP_Y_CRCB_H2V1
505#define PPP_PACK_PATTERN_MDP_YCRYCB_H2V1 \
506 MDP_GET_PACK_PATTERN(CLR_Y, CLR_R, CLR_Y, CLR_B, 8)
507
508#define PPP_CHROMA_SAMP_MDP_RGB_565(dir) PPP_OP_##dir##_CHROMA_RGB
509#define PPP_CHROMA_SAMP_MDP_RGB_888(dir) PPP_OP_##dir##_CHROMA_RGB
510#define PPP_CHROMA_SAMP_MDP_XRGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
511#define PPP_CHROMA_SAMP_MDP_ARGB_8888(dir) PPP_OP_##dir##_CHROMA_RGB
512#define PPP_CHROMA_SAMP_MDP_RGBA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
513#define PPP_CHROMA_SAMP_MDP_BGRA_8888(dir) PPP_OP_##dir##_CHROMA_RGB
514#define PPP_CHROMA_SAMP_MDP_RGBX_8888(dir) PPP_OP_##dir##_CHROMA_RGB
515#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
516#define PPP_CHROMA_SAMP_MDP_Y_CBCR_H2V2(dir) PPP_OP_##dir##_CHROMA_420
517#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
518#define PPP_CHROMA_SAMP_MDP_Y_CRCB_H2V2(dir) PPP_OP_##dir##_CHROMA_420
519#define PPP_CHROMA_SAMP_MDP_YCRYCB_H2V1(dir) PPP_OP_##dir##_CHROMA_H2V1
520
521/* Helpful array generation macros */
522#define PPP_ARRAY0(name) \
523 [MDP_RGB_565] = PPP_##name##_MDP_RGB_565,\
524 [MDP_RGB_888] = PPP_##name##_MDP_RGB_888,\
525 [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888,\
526 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888,\
527 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888,\
528 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888,\
529 [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888,\
530 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1,\
531 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2,\
532 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1,\
533 [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2,\
534 [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1
535
536#define PPP_ARRAY1(name, dir) \
537 [MDP_RGB_565] = PPP_##name##_MDP_RGB_565(dir),\
538 [MDP_RGB_888] = PPP_##name##_MDP_RGB_888(dir),\
539 [MDP_XRGB_8888] = PPP_##name##_MDP_XRGB_8888(dir),\
540 [MDP_ARGB_8888] = PPP_##name##_MDP_ARGB_8888(dir),\
541 [MDP_RGBA_8888] = PPP_##name##_MDP_RGBA_8888(dir),\
542 [MDP_BGRA_8888] = PPP_##name##_MDP_BGRA_8888(dir),\
543 [MDP_RGBX_8888] = PPP_##name##_MDP_RGBX_8888(dir),\
544 [MDP_Y_CBCR_H2V1] = PPP_##name##_MDP_Y_CBCR_H2V1(dir),\
545 [MDP_Y_CBCR_H2V2] = PPP_##name##_MDP_Y_CBCR_H2V2(dir),\
546 [MDP_Y_CRCB_H2V1] = PPP_##name##_MDP_Y_CRCB_H2V1(dir),\
547 [MDP_Y_CRCB_H2V2] = PPP_##name##_MDP_Y_CRCB_H2V2(dir),\
548 [MDP_YCRYCB_H2V1] = PPP_##name##_MDP_YCRYCB_H2V1(dir)
549
550#define IS_YCRCB(img) ((img == MDP_Y_CRCB_H2V2) | (img == MDP_Y_CBCR_H2V2) | \
551 (img == MDP_Y_CRCB_H2V1) | (img == MDP_Y_CBCR_H2V1) | \
552 (img == MDP_YCRYCB_H2V1))
553#define IS_RGB(img) ((img == MDP_RGB_565) | (img == MDP_RGB_888) | \
554 (img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
555 (img == MDP_XRGB_8888) | (img == MDP_BGRA_8888) | \
556 (img == MDP_RGBX_8888))
557#define HAS_ALPHA(img) ((img == MDP_ARGB_8888) | (img == MDP_RGBA_8888) | \
558 (img == MDP_BGRA_8888))
559
560#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
561 (img == MDP_Y_CBCR_H2V2) | \
562 (img == MDP_Y_CRCB_H2V1) | \
563 (img == MDP_Y_CBCR_H2V1))
564
565/* Mappings from addr to purpose */
566#define PPP_ADDR_SRC_ROI MDP_FULL_BYPASS_WORD2
567#define PPP_ADDR_SRC0 MDP_FULL_BYPASS_WORD3
568#define PPP_ADDR_SRC1 MDP_FULL_BYPASS_WORD4
569#define PPP_ADDR_SRC_YSTRIDE MDP_FULL_BYPASS_WORD7
570#define PPP_ADDR_SRC_CFG MDP_FULL_BYPASS_WORD9
571#define PPP_ADDR_SRC_PACK_PATTERN MDP_FULL_BYPASS_WORD10
572#define PPP_ADDR_OPERATION MDP_FULL_BYPASS_WORD14
573#define PPP_ADDR_PHASEX_INIT MDP_FULL_BYPASS_WORD15
574#define PPP_ADDR_PHASEY_INIT MDP_FULL_BYPASS_WORD16
575#define PPP_ADDR_PHASEX_STEP MDP_FULL_BYPASS_WORD17
576#define PPP_ADDR_PHASEY_STEP MDP_FULL_BYPASS_WORD18
577#define PPP_ADDR_ALPHA_TRANSP MDP_FULL_BYPASS_WORD19
578#define PPP_ADDR_DST_CFG MDP_FULL_BYPASS_WORD20
579#define PPP_ADDR_DST_PACK_PATTERN MDP_FULL_BYPASS_WORD21
580#define PPP_ADDR_DST_ROI MDP_FULL_BYPASS_WORD25
581#define PPP_ADDR_DST0 MDP_FULL_BYPASS_WORD26
582#define PPP_ADDR_DST1 MDP_FULL_BYPASS_WORD27
583#define PPP_ADDR_DST_YSTRIDE MDP_FULL_BYPASS_WORD30
584#define PPP_ADDR_EDGE MDP_FULL_BYPASS_WORD46
585#define PPP_ADDR_BG0 MDP_FULL_BYPASS_WORD48
586#define PPP_ADDR_BG1 MDP_FULL_BYPASS_WORD49
587#define PPP_ADDR_BG_YSTRIDE MDP_FULL_BYPASS_WORD51
588#define PPP_ADDR_BG_CFG MDP_FULL_BYPASS_WORD53
589#define PPP_ADDR_BG_PACK_PATTERN MDP_FULL_BYPASS_WORD54
590
591/* MDP_DMA_CONFIG / MDP_FULL_BYPASS_WORD32 */
592#define DMA_DSTC0G_6BITS (1<<1)
593#define DMA_DSTC1B_6BITS (1<<3)
594#define DMA_DSTC2R_6BITS (1<<5)
595#define DMA_DSTC0G_5BITS (1<<0)
596#define DMA_DSTC1B_5BITS (1<<2)
597#define DMA_DSTC2R_5BITS (1<<4)
598
599#define DMA_PACK_TIGHT (1<<6)
600#define DMA_PACK_LOOSE 0
601#define DMA_PACK_ALIGN_LSB 0
602#define DMA_PACK_ALIGN_MSB (1<<7)
603#define DMA_PACK_PATTERN_RGB \
604 (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
605
606#define DMA_OUT_SEL_AHB 0
607#define DMA_OUT_SEL_MDDI (1<<14)
608#define DMA_AHBM_LCD_SEL_PRIMARY 0
609#define DMA_AHBM_LCD_SEL_SECONDARY (1<<15)
610#define DMA_IBUF_C3ALPHA_EN (1<<16)
611#define DMA_DITHER_EN (1<<17)
612
613#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
614#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (1<<18)
615#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (1<<19)
616
617#define DMA_IBUF_FORMAT_RGB565 (1<<20)
618#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 0
619
620#define DMA_IBUF_NONCONTIGUOUS (1<<21)
621
622/* MDDI REGISTER ? */
623#define MDDI_VDO_PACKET_DESC 0x5666
624#define MDDI_VDO_PACKET_PRIM 0xC3
625#define MDDI_VDO_PACKET_SECD 0xC0
626
627#endif
diff --git a/drivers/video/fbdev/msm/mdp_ppp.c b/drivers/video/fbdev/msm/mdp_ppp.c
deleted file mode 100644
index be6079cdfbb6..000000000000
--- a/drivers/video/fbdev/msm/mdp_ppp.c
+++ /dev/null
@@ -1,731 +0,0 @@
1/* drivers/video/msm/mdp_ppp.c
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#include <linux/fb.h>
16#include <linux/file.h>
17#include <linux/delay.h>
18#include <linux/msm_mdp.h>
19#include <linux/platform_data/video-msm_fb.h>
20
21#include "mdp_hw.h"
22#include "mdp_scale_tables.h"
23
24#define DLOG(x...) do {} while (0)
25
26#define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1)
27static int downscale_y_table = MDP_DOWNSCALE_MAX;
28static int downscale_x_table = MDP_DOWNSCALE_MAX;
29
30struct mdp_regs {
31 uint32_t src0;
32 uint32_t src1;
33 uint32_t dst0;
34 uint32_t dst1;
35 uint32_t src_cfg;
36 uint32_t dst_cfg;
37 uint32_t src_pack;
38 uint32_t dst_pack;
39 uint32_t src_rect;
40 uint32_t dst_rect;
41 uint32_t src_ystride;
42 uint32_t dst_ystride;
43 uint32_t op;
44 uint32_t src_bpp;
45 uint32_t dst_bpp;
46 uint32_t edge;
47 uint32_t phasex_init;
48 uint32_t phasey_init;
49 uint32_t phasex_step;
50 uint32_t phasey_step;
51};
52
53static uint32_t pack_pattern[] = {
54 PPP_ARRAY0(PACK_PATTERN)
55};
56
57static uint32_t src_img_cfg[] = {
58 PPP_ARRAY1(CFG, SRC)
59};
60
61static uint32_t dst_img_cfg[] = {
62 PPP_ARRAY1(CFG, DST)
63};
64
65static uint32_t bytes_per_pixel[] = {
66 [MDP_RGB_565] = 2,
67 [MDP_RGB_888] = 3,
68 [MDP_XRGB_8888] = 4,
69 [MDP_ARGB_8888] = 4,
70 [MDP_RGBA_8888] = 4,
71 [MDP_BGRA_8888] = 4,
72 [MDP_RGBX_8888] = 4,
73 [MDP_Y_CBCR_H2V1] = 1,
74 [MDP_Y_CBCR_H2V2] = 1,
75 [MDP_Y_CRCB_H2V1] = 1,
76 [MDP_Y_CRCB_H2V2] = 1,
77 [MDP_YCRYCB_H2V1] = 2
78};
79
80static uint32_t dst_op_chroma[] = {
81 PPP_ARRAY1(CHROMA_SAMP, DST)
82};
83
84static uint32_t src_op_chroma[] = {
85 PPP_ARRAY1(CHROMA_SAMP, SRC)
86};
87
88static uint32_t bg_op_chroma[] = {
89 PPP_ARRAY1(CHROMA_SAMP, BG)
90};
91
92static void rotate_dst_addr_x(struct mdp_blit_req *req, struct mdp_regs *regs)
93{
94 regs->dst0 += (req->dst_rect.w -
95 min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
96 regs->dst1 += (req->dst_rect.w -
97 min((uint32_t)16, req->dst_rect.w)) * regs->dst_bpp;
98}
99
100static void rotate_dst_addr_y(struct mdp_blit_req *req, struct mdp_regs *regs)
101{
102 regs->dst0 += (req->dst_rect.h -
103 min((uint32_t)16, req->dst_rect.h)) *
104 regs->dst_ystride;
105 regs->dst1 += (req->dst_rect.h -
106 min((uint32_t)16, req->dst_rect.h)) *
107 regs->dst_ystride;
108}
109
110static void blit_rotate(struct mdp_blit_req *req,
111 struct mdp_regs *regs)
112{
113 if (req->flags == MDP_ROT_NOP)
114 return;
115
116 regs->op |= PPP_OP_ROT_ON;
117 if ((req->flags & MDP_ROT_90 || req->flags & MDP_FLIP_LR) &&
118 !(req->flags & MDP_ROT_90 && req->flags & MDP_FLIP_LR))
119 rotate_dst_addr_x(req, regs);
120 if (req->flags & MDP_ROT_90)
121 regs->op |= PPP_OP_ROT_90;
122 if (req->flags & MDP_FLIP_UD) {
123 regs->op |= PPP_OP_FLIP_UD;
124 rotate_dst_addr_y(req, regs);
125 }
126 if (req->flags & MDP_FLIP_LR)
127 regs->op |= PPP_OP_FLIP_LR;
128}
129
130static void blit_convert(struct mdp_blit_req *req, struct mdp_regs *regs)
131{
132 if (req->src.format == req->dst.format)
133 return;
134 if (IS_RGB(req->src.format) && IS_YCRCB(req->dst.format)) {
135 regs->op |= PPP_OP_CONVERT_RGB2YCBCR | PPP_OP_CONVERT_ON;
136 } else if (IS_YCRCB(req->src.format) && IS_RGB(req->dst.format)) {
137 regs->op |= PPP_OP_CONVERT_YCBCR2RGB | PPP_OP_CONVERT_ON;
138 if (req->dst.format == MDP_RGB_565)
139 regs->op |= PPP_OP_CONVERT_MATRIX_SECONDARY;
140 }
141}
142
143#define GET_BIT_RANGE(value, high, low) \
144 (((1 << (high - low + 1)) - 1) & (value >> low))
145static uint32_t transp_convert(struct mdp_blit_req *req)
146{
147 uint32_t transp = 0;
148 if (req->src.format == MDP_RGB_565) {
149 /* pad each value to 8 bits by copying the high bits into the
150 * low end, convert RGB to RBG by switching low 2 components */
151 transp |= ((GET_BIT_RANGE(req->transp_mask, 15, 11) << 3) |
152 (GET_BIT_RANGE(req->transp_mask, 15, 13))) << 16;
153
154 transp |= ((GET_BIT_RANGE(req->transp_mask, 4, 0) << 3) |
155 (GET_BIT_RANGE(req->transp_mask, 4, 2))) << 8;
156
157 transp |= (GET_BIT_RANGE(req->transp_mask, 10, 5) << 2) |
158 (GET_BIT_RANGE(req->transp_mask, 10, 9));
159 } else {
160 /* convert RGB to RBG */
161 transp |= (GET_BIT_RANGE(req->transp_mask, 15, 8)) |
162 (GET_BIT_RANGE(req->transp_mask, 23, 16) << 16) |
163 (GET_BIT_RANGE(req->transp_mask, 7, 0) << 8);
164 }
165 return transp;
166}
167#undef GET_BIT_RANGE
168
169static void blit_blend(struct mdp_blit_req *req, struct mdp_regs *regs)
170{
171 /* TRANSP BLEND */
172 if (req->transp_mask != MDP_TRANSP_NOP) {
173 req->transp_mask = transp_convert(req);
174 if (req->alpha != MDP_ALPHA_NOP) {
175 /* use blended transparancy mode
176 * pixel = (src == transp) ? dst : blend
177 * blend is combo of blend_eq_sel and
178 * blend_alpha_sel */
179 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
180 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
181 PPP_OP_BLEND_CONSTANT_ALPHA |
182 PPP_BLEND_ALPHA_TRANSP;
183 } else {
184 /* simple transparancy mode
185 * pixel = (src == transp) ? dst : src */
186 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
187 PPP_OP_BLEND_SRCPIXEL_TRANSP;
188 }
189 }
190
191 req->alpha &= 0xff;
192 /* ALPHA BLEND */
193 if (HAS_ALPHA(req->src.format)) {
194 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
195 PPP_OP_BLEND_SRCPIXEL_ALPHA;
196 } else if (req->alpha < MDP_ALPHA_NOP) {
197 /* just blend by alpha */
198 regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
199 PPP_OP_BLEND_ALPHA_BLEND_NORMAL |
200 PPP_OP_BLEND_CONSTANT_ALPHA;
201 }
202
203 regs->op |= bg_op_chroma[req->dst.format];
204}
205
206#define ONE_HALF (1LL << 32)
207#define ONE (1LL << 33)
208#define TWO (2LL << 33)
209#define THREE (3LL << 33)
210#define FRAC_MASK (ONE - 1)
211#define INT_MASK (~FRAC_MASK)
212
213static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin,
214 uint32_t *phase_init, uint32_t *phase_step)
215{
216 /* to improve precicsion calculations are done in U31.33 and converted
217 * to U3.29 at the end */
218 int64_t k1, k2, k3, k4, tmp;
219 uint64_t n, d, os, os_p, od, od_p, oreq;
220 unsigned rpa = 0;
221 int64_t ip64, delta;
222
223 if (dim_out % 3 == 0)
224 rpa = !(dim_in % (dim_out / 3));
225
226 n = ((uint64_t)dim_out) << 34;
227 d = dim_in;
228 if (!d)
229 return -1;
230 do_div(n, d);
231 k3 = (n + 1) >> 1;
232 if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31)) {
233 DLOG("crap bad scale\n");
234 return -1;
235 }
236 n = ((uint64_t)dim_in) << 34;
237 d = (uint64_t)dim_out;
238 if (!d)
239 return -1;
240 do_div(n, d);
241 k1 = (n + 1) >> 1;
242 k2 = (k1 - ONE) >> 1;
243
244 *phase_init = (int)(k2 >> 4);
245 k4 = (k3 - ONE) >> 1;
246
247 if (rpa) {
248 os = ((uint64_t)origin << 33) - ONE_HALF;
249 tmp = (dim_out * os) + ONE_HALF;
250 if (!dim_in)
251 return -1;
252 do_div(tmp, dim_in);
253 od = tmp - ONE_HALF;
254 } else {
255 os = ((uint64_t)origin << 1) - 1;
256 od = (((k3 * os) >> 1) + k4);
257 }
258
259 od_p = od & INT_MASK;
260 if (od_p != od)
261 od_p += ONE;
262
263 if (rpa) {
264 tmp = (dim_in * od_p) + ONE_HALF;
265 if (!dim_in)
266 return -1;
267 do_div(tmp, dim_in);
268 os_p = tmp - ONE_HALF;
269 } else {
270 os_p = ((k1 * (od_p >> 33)) + k2);
271 }
272
273 oreq = (os_p & INT_MASK) - ONE;
274
275 ip64 = os_p - oreq;
276 delta = ((int64_t)(origin) << 33) - oreq;
277 ip64 -= delta;
278 /* limit to valid range before the left shift */
279 delta = (ip64 & (1LL << 63)) ? 4 : -4;
280 delta <<= 33;
281 while (abs((int)(ip64 >> 33)) > 4)
282 ip64 += delta;
283 *phase_init = (int)(ip64 >> 4);
284 *phase_step = (uint32_t)(k1 >> 4);
285 return 0;
286}
287
288static void load_scale_table(const struct mdp_info *mdp,
289 struct mdp_table_entry *table, int len)
290{
291 int i;
292 for (i = 0; i < len; i++)
293 mdp_writel(mdp, table[i].val, table[i].reg);
294}
295
296enum {
297IMG_LEFT,
298IMG_RIGHT,
299IMG_TOP,
300IMG_BOTTOM,
301};
302
303static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
304 uint32_t *interp1, uint32_t *interp2,
305 uint32_t *repeat1, uint32_t *repeat2) {
306 if (src > 3 * dst) {
307 *interp1 = 0;
308 *interp2 = src - 1;
309 *repeat1 = 0;
310 *repeat2 = 0;
311 } else if (src == 3 * dst) {
312 *interp1 = 0;
313 *interp2 = src;
314 *repeat1 = 0;
315 *repeat2 = 1;
316 } else if (src > dst && src < 3 * dst) {
317 *interp1 = -1;
318 *interp2 = src;
319 *repeat1 = 1;
320 *repeat2 = 1;
321 } else if (src == dst) {
322 *interp1 = -1;
323 *interp2 = src + 1;
324 *repeat1 = 1;
325 *repeat2 = 2;
326 } else {
327 *interp1 = -2;
328 *interp2 = src + 1;
329 *repeat1 = 2;
330 *repeat2 = 2;
331 }
332 *interp1 += src_coord;
333 *interp2 += src_coord;
334}
335
336static int get_edge_cond(struct mdp_blit_req *req, struct mdp_regs *regs)
337{
338 int32_t luma_interp[4];
339 int32_t luma_repeat[4];
340 int32_t chroma_interp[4];
341 int32_t chroma_bound[4];
342 int32_t chroma_repeat[4];
343 uint32_t dst_w, dst_h;
344
345 memset(&luma_interp, 0, sizeof(int32_t) * 4);
346 memset(&luma_repeat, 0, sizeof(int32_t) * 4);
347 memset(&chroma_interp, 0, sizeof(int32_t) * 4);
348 memset(&chroma_bound, 0, sizeof(int32_t) * 4);
349 memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
350 regs->edge = 0;
351
352 if (req->flags & MDP_ROT_90) {
353 dst_w = req->dst_rect.h;
354 dst_h = req->dst_rect.w;
355 } else {
356 dst_w = req->dst_rect.w;
357 dst_h = req->dst_rect.h;
358 }
359
360 if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
361 get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
362 &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
363 &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
364 get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
365 &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
366 &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
367 } else {
368 luma_interp[IMG_LEFT] = req->src_rect.x;
369 luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
370 luma_interp[IMG_TOP] = req->src_rect.y;
371 luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
372 luma_repeat[IMG_LEFT] = 0;
373 luma_repeat[IMG_TOP] = 0;
374 luma_repeat[IMG_RIGHT] = 0;
375 luma_repeat[IMG_BOTTOM] = 0;
376 }
377
378 chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
379 chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
380 chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
381 chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
382
383 chroma_bound[IMG_LEFT] = req->src_rect.x;
384 chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
385 chroma_bound[IMG_TOP] = req->src_rect.y;
386 chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
387
388 if (IS_YCRCB(req->src.format)) {
389 chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
390 chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >> 1;
391
392 chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
393 chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
394 }
395
396 if (req->src.format == MDP_Y_CBCR_H2V2 ||
397 req->src.format == MDP_Y_CRCB_H2V2) {
398 chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
399 chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
400 >> 1;
401 chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
402 chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
403 }
404
405 chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
406 chroma_interp[IMG_LEFT];
407 chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
408 chroma_bound[IMG_RIGHT];
409 chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
410 chroma_interp[IMG_TOP];
411 chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
412 chroma_bound[IMG_BOTTOM];
413
414 if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
415 chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
416 chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
417 chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3 ||
418 luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
419 luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
420 luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
421 luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
422 return -1;
423
424 regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
425 regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
426 regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
427 regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
428 regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
429 regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
430 regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
431 regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
432 return 0;
433}
434
435static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
436 struct mdp_regs *regs)
437{
438 uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
439 uint32_t scale_factor_x, scale_factor_y;
440 uint32_t downscale;
441 uint32_t dst_w, dst_h;
442
443 if (req->flags & MDP_ROT_90) {
444 dst_w = req->dst_rect.h;
445 dst_h = req->dst_rect.w;
446 } else {
447 dst_w = req->dst_rect.w;
448 dst_h = req->dst_rect.h;
449 }
450 if ((req->src_rect.w == dst_w) && (req->src_rect.h == dst_h) &&
451 !(req->flags & MDP_BLUR)) {
452 regs->phasex_init = 0;
453 regs->phasey_init = 0;
454 regs->phasex_step = 0;
455 regs->phasey_step = 0;
456 return 0;
457 }
458
459 if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x,
460 &phase_step_x) ||
461 scale_params(req->src_rect.h, dst_h, 1, &phase_init_y,
462 &phase_step_y))
463 return -1;
464
465 scale_factor_x = (dst_w * 10) / req->src_rect.w;
466 scale_factor_y = (dst_h * 10) / req->src_rect.h;
467
468 if (scale_factor_x > 8)
469 downscale = MDP_DOWNSCALE_PT8TO1;
470 else if (scale_factor_x > 6)
471 downscale = MDP_DOWNSCALE_PT6TOPT8;
472 else if (scale_factor_x > 4)
473 downscale = MDP_DOWNSCALE_PT4TOPT6;
474 else
475 downscale = MDP_DOWNSCALE_PT2TOPT4;
476 if (downscale != downscale_x_table) {
477 load_scale_table(mdp, mdp_downscale_x_table[downscale], 64);
478 downscale_x_table = downscale;
479 }
480
481 if (scale_factor_y > 8)
482 downscale = MDP_DOWNSCALE_PT8TO1;
483 else if (scale_factor_y > 6)
484 downscale = MDP_DOWNSCALE_PT6TOPT8;
485 else if (scale_factor_y > 4)
486 downscale = MDP_DOWNSCALE_PT4TOPT6;
487 else
488 downscale = MDP_DOWNSCALE_PT2TOPT4;
489 if (downscale != downscale_y_table) {
490 load_scale_table(mdp, mdp_downscale_y_table[downscale], 64);
491 downscale_y_table = downscale;
492 }
493
494 regs->phasex_init = phase_init_x;
495 regs->phasey_init = phase_init_y;
496 regs->phasex_step = phase_step_x;
497 regs->phasey_step = phase_step_y;
498 regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
499 return 0;
500
501}
502
503static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req,
504 struct mdp_regs *regs)
505{
506 if (!(req->flags & MDP_BLUR))
507 return;
508
509 if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
510 downscale_y_table == MDP_DOWNSCALE_BLUR)) {
511 load_scale_table(mdp, mdp_gaussian_blur_table, 128);
512 downscale_x_table = MDP_DOWNSCALE_BLUR;
513 downscale_y_table = MDP_DOWNSCALE_BLUR;
514 }
515
516 regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
517}
518
519
520#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
521
522#define Y_TO_CRCB_RATIO(format) \
523 ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
524 (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
525
526static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
527 uint32_t *len0, uint32_t *len1)
528{
529 *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp);
530 if (IS_PSEUDOPLNR(img->format))
531 *len1 = *len0/Y_TO_CRCB_RATIO(img->format);
532 else
533 *len1 = 0;
534}
535
536static int valid_src_dst(unsigned long src_start, unsigned long src_len,
537 unsigned long dst_start, unsigned long dst_len,
538 struct mdp_blit_req *req, struct mdp_regs *regs)
539{
540 unsigned long src_min_ok = src_start;
541 unsigned long src_max_ok = src_start + src_len;
542 unsigned long dst_min_ok = dst_start;
543 unsigned long dst_max_ok = dst_start + dst_len;
544 uint32_t src0_len, src1_len, dst0_len, dst1_len;
545 get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
546 &src1_len);
547 get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
548 &dst1_len);
549
550 if (regs->src0 < src_min_ok || regs->src0 > src_max_ok ||
551 regs->src0 + src0_len > src_max_ok) {
552 DLOG("invalid_src %x %x %lx %lx\n", regs->src0,
553 src0_len, src_min_ok, src_max_ok);
554 return 0;
555 }
556 if (regs->src_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
557 if (regs->src1 < src_min_ok || regs->src1 > src_max_ok ||
558 regs->src1 + src1_len > src_max_ok) {
559 DLOG("invalid_src1");
560 return 0;
561 }
562 }
563 if (regs->dst0 < dst_min_ok || regs->dst0 > dst_max_ok ||
564 regs->dst0 + dst0_len > dst_max_ok) {
565 DLOG("invalid_dst");
566 return 0;
567 }
568 if (regs->dst_cfg & PPP_SRC_PLANE_PSEUDOPLNR) {
569 if (regs->dst1 < dst_min_ok || regs->dst1 > dst_max_ok ||
570 regs->dst1 + dst1_len > dst_max_ok) {
571 DLOG("invalid_dst1");
572 return 0;
573 }
574 }
575 return 1;
576}
577
578
579static void flush_imgs(struct mdp_blit_req *req, struct mdp_regs *regs,
580 struct file *src_file, struct file *dst_file)
581{
582}
583
584static void get_chroma_addr(struct mdp_img *img, struct mdp_rect *rect,
585 uint32_t base, uint32_t bpp, uint32_t cfg,
586 uint32_t *addr, uint32_t *ystride)
587{
588 uint32_t compress_v = Y_TO_CRCB_RATIO(img->format);
589 uint32_t compress_h = 2;
590 uint32_t offset;
591
592 if (IS_PSEUDOPLNR(img->format)) {
593 offset = (rect->x / compress_h) * compress_h;
594 offset += rect->y == 0 ? 0 :
595 ((rect->y + 1) / compress_v) * img->width;
596 *addr = base + (img->width * img->height * bpp);
597 *addr += offset * bpp;
598 *ystride |= *ystride << 16;
599 } else {
600 *addr = 0;
601 }
602}
603
604static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
605 struct mdp_regs *regs, struct file *src_file,
606 struct file *dst_file)
607{
608 mdp_writel(mdp, 1, 0x060);
609 mdp_writel(mdp, regs->src_rect, PPP_ADDR_SRC_ROI);
610 mdp_writel(mdp, regs->src0, PPP_ADDR_SRC0);
611 mdp_writel(mdp, regs->src1, PPP_ADDR_SRC1);
612 mdp_writel(mdp, regs->src_ystride, PPP_ADDR_SRC_YSTRIDE);
613 mdp_writel(mdp, regs->src_cfg, PPP_ADDR_SRC_CFG);
614 mdp_writel(mdp, regs->src_pack, PPP_ADDR_SRC_PACK_PATTERN);
615
616 mdp_writel(mdp, regs->op, PPP_ADDR_OPERATION);
617 mdp_writel(mdp, regs->phasex_init, PPP_ADDR_PHASEX_INIT);
618 mdp_writel(mdp, regs->phasey_init, PPP_ADDR_PHASEY_INIT);
619 mdp_writel(mdp, regs->phasex_step, PPP_ADDR_PHASEX_STEP);
620 mdp_writel(mdp, regs->phasey_step, PPP_ADDR_PHASEY_STEP);
621
622 mdp_writel(mdp, (req->alpha << 24) | (req->transp_mask & 0xffffff),
623 PPP_ADDR_ALPHA_TRANSP);
624
625 mdp_writel(mdp, regs->dst_cfg, PPP_ADDR_DST_CFG);
626 mdp_writel(mdp, regs->dst_pack, PPP_ADDR_DST_PACK_PATTERN);
627 mdp_writel(mdp, regs->dst_rect, PPP_ADDR_DST_ROI);
628 mdp_writel(mdp, regs->dst0, PPP_ADDR_DST0);
629 mdp_writel(mdp, regs->dst1, PPP_ADDR_DST1);
630 mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_DST_YSTRIDE);
631
632 mdp_writel(mdp, regs->edge, PPP_ADDR_EDGE);
633 if (regs->op & PPP_OP_BLEND_ON) {
634 mdp_writel(mdp, regs->dst0, PPP_ADDR_BG0);
635 mdp_writel(mdp, regs->dst1, PPP_ADDR_BG1);
636 mdp_writel(mdp, regs->dst_ystride, PPP_ADDR_BG_YSTRIDE);
637 mdp_writel(mdp, src_img_cfg[req->dst.format], PPP_ADDR_BG_CFG);
638 mdp_writel(mdp, pack_pattern[req->dst.format],
639 PPP_ADDR_BG_PACK_PATTERN);
640 }
641 flush_imgs(req, regs, src_file, dst_file);
642 mdp_writel(mdp, 0x1000, MDP_DISPLAY0_START);
643 return 0;
644}
645
646int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
647 struct file *src_file, unsigned long src_start, unsigned long src_len,
648 struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
649{
650 struct mdp_regs regs = {0};
651
652 if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT ||
653 req->dst.format >= MDP_IMGTYPE_LIMIT)) {
654 printk(KERN_ERR "mpd_ppp: img is of wrong format\n");
655 return -EINVAL;
656 }
657
658 if (unlikely(req->src_rect.x > req->src.width ||
659 req->src_rect.y > req->src.height ||
660 req->dst_rect.x > req->dst.width ||
661 req->dst_rect.y > req->dst.height)) {
662 printk(KERN_ERR "mpd_ppp: img rect is outside of img!\n");
663 return -EINVAL;
664 }
665
666 /* set the src image configuration */
667 regs.src_cfg = src_img_cfg[req->src.format];
668 regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0;
669 regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
670 regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w;
671 regs.src_pack = pack_pattern[req->src.format];
672
673 /* set the dest image configuration */
674 regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI;
675 regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w;
676 regs.dst_pack = pack_pattern[req->dst.format];
677
678 /* set src, bpp, start pixel and ystride */
679 regs.src_bpp = bytes_per_pixel[req->src.format];
680 regs.src0 = src_start + req->src.offset;
681 regs.src_ystride = req->src.width * regs.src_bpp;
682 get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
683 regs.src_cfg, &regs.src1, &regs.src_ystride);
684 regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width)) *
685 regs.src_bpp;
686
687 /* set dst, bpp, start pixel and ystride */
688 regs.dst_bpp = bytes_per_pixel[req->dst.format];
689 regs.dst0 = dst_start + req->dst.offset;
690 regs.dst_ystride = req->dst.width * regs.dst_bpp;
691 get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
692 regs.dst_cfg, &regs.dst1, &regs.dst_ystride);
693 regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width)) *
694 regs.dst_bpp;
695
696 if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req,
697 &regs)) {
698 printk(KERN_ERR "mpd_ppp: final src or dst location is "
699 "invalid, are you trying to make an image too large "
700 "or to place it outside the screen?\n");
701 return -EINVAL;
702 }
703
704 /* set up operation register */
705 regs.op = 0;
706 blit_rotate(req, &regs);
707 blit_convert(req, &regs);
708 if (req->flags & MDP_DITHER)
709 regs.op |= PPP_OP_DITHER_EN;
710 blit_blend(req, &regs);
711 if (blit_scale(mdp, req, &regs)) {
712 printk(KERN_ERR "mpd_ppp: error computing scale for img.\n");
713 return -EINVAL;
714 }
715 blit_blur(mdp, req, &regs);
716 regs.op |= dst_op_chroma[req->dst.format] |
717 src_op_chroma[req->src.format];
718
719 /* if the image is YCRYCB, the x and w must be even */
720 if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) {
721 req->src_rect.x = req->src_rect.x & (~0x1);
722 req->src_rect.w = req->src_rect.w & (~0x1);
723 req->dst_rect.x = req->dst_rect.x & (~0x1);
724 req->dst_rect.w = req->dst_rect.w & (~0x1);
725 }
726 if (get_edge_cond(req, &regs))
727 return -EINVAL;
728
729 send_blit(mdp, req, &regs, src_file, dst_file);
730 return 0;
731}
diff --git a/drivers/video/fbdev/msm/mdp_scale_tables.c b/drivers/video/fbdev/msm/mdp_scale_tables.c
deleted file mode 100644
index 604783b2e17c..000000000000
--- a/drivers/video/fbdev/msm/mdp_scale_tables.c
+++ /dev/null
@@ -1,766 +0,0 @@
1/* drivers/video/msm_fb/mdp_scale_tables.c
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include "mdp_scale_tables.h"
17#include "mdp_hw.h"
18
19struct mdp_table_entry mdp_upscale_table[] = {
20 { 0x5fffc, 0x0 },
21 { 0x50200, 0x7fc00000 },
22 { 0x5fffc, 0xff80000d },
23 { 0x50204, 0x7ec003f9 },
24 { 0x5fffc, 0xfec0001c },
25 { 0x50208, 0x7d4003f3 },
26 { 0x5fffc, 0xfe40002b },
27 { 0x5020c, 0x7b8003ed },
28 { 0x5fffc, 0xfd80003c },
29 { 0x50210, 0x794003e8 },
30 { 0x5fffc, 0xfcc0004d },
31 { 0x50214, 0x76c003e4 },
32 { 0x5fffc, 0xfc40005f },
33 { 0x50218, 0x73c003e0 },
34 { 0x5fffc, 0xfb800071 },
35 { 0x5021c, 0x708003de },
36 { 0x5fffc, 0xfac00085 },
37 { 0x50220, 0x6d0003db },
38 { 0x5fffc, 0xfa000098 },
39 { 0x50224, 0x698003d9 },
40 { 0x5fffc, 0xf98000ac },
41 { 0x50228, 0x654003d8 },
42 { 0x5fffc, 0xf8c000c1 },
43 { 0x5022c, 0x610003d7 },
44 { 0x5fffc, 0xf84000d5 },
45 { 0x50230, 0x5c8003d7 },
46 { 0x5fffc, 0xf7c000e9 },
47 { 0x50234, 0x580003d7 },
48 { 0x5fffc, 0xf74000fd },
49 { 0x50238, 0x534003d8 },
50 { 0x5fffc, 0xf6c00112 },
51 { 0x5023c, 0x4e8003d8 },
52 { 0x5fffc, 0xf6800126 },
53 { 0x50240, 0x494003da },
54 { 0x5fffc, 0xf600013a },
55 { 0x50244, 0x448003db },
56 { 0x5fffc, 0xf600014d },
57 { 0x50248, 0x3f4003dd },
58 { 0x5fffc, 0xf5c00160 },
59 { 0x5024c, 0x3a4003df },
60 { 0x5fffc, 0xf5c00172 },
61 { 0x50250, 0x354003e1 },
62 { 0x5fffc, 0xf5c00184 },
63 { 0x50254, 0x304003e3 },
64 { 0x5fffc, 0xf6000195 },
65 { 0x50258, 0x2b0003e6 },
66 { 0x5fffc, 0xf64001a6 },
67 { 0x5025c, 0x260003e8 },
68 { 0x5fffc, 0xf6c001b4 },
69 { 0x50260, 0x214003eb },
70 { 0x5fffc, 0xf78001c2 },
71 { 0x50264, 0x1c4003ee },
72 { 0x5fffc, 0xf80001cf },
73 { 0x50268, 0x17c003f1 },
74 { 0x5fffc, 0xf90001db },
75 { 0x5026c, 0x134003f3 },
76 { 0x5fffc, 0xfa0001e5 },
77 { 0x50270, 0xf0003f6 },
78 { 0x5fffc, 0xfb4001ee },
79 { 0x50274, 0xac003f9 },
80 { 0x5fffc, 0xfcc001f5 },
81 { 0x50278, 0x70003fb },
82 { 0x5fffc, 0xfe4001fb },
83 { 0x5027c, 0x34003fe },
84};
85
86static struct mdp_table_entry mdp_downscale_x_table_PT2TOPT4[] = {
87 { 0x5fffc, 0x740008c },
88 { 0x50280, 0x33800088 },
89 { 0x5fffc, 0x800008e },
90 { 0x50284, 0x33400084 },
91 { 0x5fffc, 0x8400092 },
92 { 0x50288, 0x33000080 },
93 { 0x5fffc, 0x9000094 },
94 { 0x5028c, 0x3300007b },
95 { 0x5fffc, 0x9c00098 },
96 { 0x50290, 0x32400077 },
97 { 0x5fffc, 0xa40009b },
98 { 0x50294, 0x32000073 },
99 { 0x5fffc, 0xb00009d },
100 { 0x50298, 0x31c0006f },
101 { 0x5fffc, 0xbc000a0 },
102 { 0x5029c, 0x3140006b },
103 { 0x5fffc, 0xc8000a2 },
104 { 0x502a0, 0x31000067 },
105 { 0x5fffc, 0xd8000a5 },
106 { 0x502a4, 0x30800062 },
107 { 0x5fffc, 0xe4000a8 },
108 { 0x502a8, 0x2fc0005f },
109 { 0x5fffc, 0xec000aa },
110 { 0x502ac, 0x2fc0005b },
111 { 0x5fffc, 0xf8000ad },
112 { 0x502b0, 0x2f400057 },
113 { 0x5fffc, 0x108000b0 },
114 { 0x502b4, 0x2e400054 },
115 { 0x5fffc, 0x114000b2 },
116 { 0x502b8, 0x2e000050 },
117 { 0x5fffc, 0x124000b4 },
118 { 0x502bc, 0x2d80004c },
119 { 0x5fffc, 0x130000b6 },
120 { 0x502c0, 0x2d000049 },
121 { 0x5fffc, 0x140000b8 },
122 { 0x502c4, 0x2c800045 },
123 { 0x5fffc, 0x150000b9 },
124 { 0x502c8, 0x2c000042 },
125 { 0x5fffc, 0x15c000bd },
126 { 0x502cc, 0x2b40003e },
127 { 0x5fffc, 0x16c000bf },
128 { 0x502d0, 0x2a80003b },
129 { 0x5fffc, 0x17c000bf },
130 { 0x502d4, 0x2a000039 },
131 { 0x5fffc, 0x188000c2 },
132 { 0x502d8, 0x29400036 },
133 { 0x5fffc, 0x19c000c4 },
134 { 0x502dc, 0x28800032 },
135 { 0x5fffc, 0x1ac000c5 },
136 { 0x502e0, 0x2800002f },
137 { 0x5fffc, 0x1bc000c7 },
138 { 0x502e4, 0x2740002c },
139 { 0x5fffc, 0x1cc000c8 },
140 { 0x502e8, 0x26c00029 },
141 { 0x5fffc, 0x1dc000c9 },
142 { 0x502ec, 0x26000027 },
143 { 0x5fffc, 0x1ec000cc },
144 { 0x502f0, 0x25000024 },
145 { 0x5fffc, 0x200000cc },
146 { 0x502f4, 0x24800021 },
147 { 0x5fffc, 0x210000cd },
148 { 0x502f8, 0x23800020 },
149 { 0x5fffc, 0x220000ce },
150 { 0x502fc, 0x2300001d },
151};
152
153static struct mdp_table_entry mdp_downscale_x_table_PT4TOPT6[] = {
154 { 0x5fffc, 0x740008c },
155 { 0x50280, 0x33800088 },
156 { 0x5fffc, 0x800008e },
157 { 0x50284, 0x33400084 },
158 { 0x5fffc, 0x8400092 },
159 { 0x50288, 0x33000080 },
160 { 0x5fffc, 0x9000094 },
161 { 0x5028c, 0x3300007b },
162 { 0x5fffc, 0x9c00098 },
163 { 0x50290, 0x32400077 },
164 { 0x5fffc, 0xa40009b },
165 { 0x50294, 0x32000073 },
166 { 0x5fffc, 0xb00009d },
167 { 0x50298, 0x31c0006f },
168 { 0x5fffc, 0xbc000a0 },
169 { 0x5029c, 0x3140006b },
170 { 0x5fffc, 0xc8000a2 },
171 { 0x502a0, 0x31000067 },
172 { 0x5fffc, 0xd8000a5 },
173 { 0x502a4, 0x30800062 },
174 { 0x5fffc, 0xe4000a8 },
175 { 0x502a8, 0x2fc0005f },
176 { 0x5fffc, 0xec000aa },
177 { 0x502ac, 0x2fc0005b },
178 { 0x5fffc, 0xf8000ad },
179 { 0x502b0, 0x2f400057 },
180 { 0x5fffc, 0x108000b0 },
181 { 0x502b4, 0x2e400054 },
182 { 0x5fffc, 0x114000b2 },
183 { 0x502b8, 0x2e000050 },
184 { 0x5fffc, 0x124000b4 },
185 { 0x502bc, 0x2d80004c },
186 { 0x5fffc, 0x130000b6 },
187 { 0x502c0, 0x2d000049 },
188 { 0x5fffc, 0x140000b8 },
189 { 0x502c4, 0x2c800045 },
190 { 0x5fffc, 0x150000b9 },
191 { 0x502c8, 0x2c000042 },
192 { 0x5fffc, 0x15c000bd },
193 { 0x502cc, 0x2b40003e },
194 { 0x5fffc, 0x16c000bf },
195 { 0x502d0, 0x2a80003b },
196 { 0x5fffc, 0x17c000bf },
197 { 0x502d4, 0x2a000039 },
198 { 0x5fffc, 0x188000c2 },
199 { 0x502d8, 0x29400036 },
200 { 0x5fffc, 0x19c000c4 },
201 { 0x502dc, 0x28800032 },
202 { 0x5fffc, 0x1ac000c5 },
203 { 0x502e0, 0x2800002f },
204 { 0x5fffc, 0x1bc000c7 },
205 { 0x502e4, 0x2740002c },
206 { 0x5fffc, 0x1cc000c8 },
207 { 0x502e8, 0x26c00029 },
208 { 0x5fffc, 0x1dc000c9 },
209 { 0x502ec, 0x26000027 },
210 { 0x5fffc, 0x1ec000cc },
211 { 0x502f0, 0x25000024 },
212 { 0x5fffc, 0x200000cc },
213 { 0x502f4, 0x24800021 },
214 { 0x5fffc, 0x210000cd },
215 { 0x502f8, 0x23800020 },
216 { 0x5fffc, 0x220000ce },
217 { 0x502fc, 0x2300001d },
218};
219
220static struct mdp_table_entry mdp_downscale_x_table_PT6TOPT8[] = {
221 { 0x5fffc, 0xfe000070 },
222 { 0x50280, 0x4bc00068 },
223 { 0x5fffc, 0xfe000078 },
224 { 0x50284, 0x4bc00060 },
225 { 0x5fffc, 0xfe000080 },
226 { 0x50288, 0x4b800059 },
227 { 0x5fffc, 0xfe000089 },
228 { 0x5028c, 0x4b000052 },
229 { 0x5fffc, 0xfe400091 },
230 { 0x50290, 0x4a80004b },
231 { 0x5fffc, 0xfe40009a },
232 { 0x50294, 0x4a000044 },
233 { 0x5fffc, 0xfe8000a3 },
234 { 0x50298, 0x4940003d },
235 { 0x5fffc, 0xfec000ac },
236 { 0x5029c, 0x48400037 },
237 { 0x5fffc, 0xff0000b4 },
238 { 0x502a0, 0x47800031 },
239 { 0x5fffc, 0xff8000bd },
240 { 0x502a4, 0x4640002b },
241 { 0x5fffc, 0xc5 },
242 { 0x502a8, 0x45000026 },
243 { 0x5fffc, 0x8000ce },
244 { 0x502ac, 0x43800021 },
245 { 0x5fffc, 0x10000d6 },
246 { 0x502b0, 0x4240001c },
247 { 0x5fffc, 0x18000df },
248 { 0x502b4, 0x40800018 },
249 { 0x5fffc, 0x24000e6 },
250 { 0x502b8, 0x3f000014 },
251 { 0x5fffc, 0x30000ee },
252 { 0x502bc, 0x3d400010 },
253 { 0x5fffc, 0x40000f5 },
254 { 0x502c0, 0x3b80000c },
255 { 0x5fffc, 0x50000fc },
256 { 0x502c4, 0x39800009 },
257 { 0x5fffc, 0x6000102 },
258 { 0x502c8, 0x37c00006 },
259 { 0x5fffc, 0x7000109 },
260 { 0x502cc, 0x35800004 },
261 { 0x5fffc, 0x840010e },
262 { 0x502d0, 0x33800002 },
263 { 0x5fffc, 0x9800114 },
264 { 0x502d4, 0x31400000 },
265 { 0x5fffc, 0xac00119 },
266 { 0x502d8, 0x2f4003fe },
267 { 0x5fffc, 0xc40011e },
268 { 0x502dc, 0x2d0003fc },
269 { 0x5fffc, 0xdc00121 },
270 { 0x502e0, 0x2b0003fb },
271 { 0x5fffc, 0xf400125 },
272 { 0x502e4, 0x28c003fa },
273 { 0x5fffc, 0x11000128 },
274 { 0x502e8, 0x268003f9 },
275 { 0x5fffc, 0x12c0012a },
276 { 0x502ec, 0x244003f9 },
277 { 0x5fffc, 0x1480012c },
278 { 0x502f0, 0x224003f8 },
279 { 0x5fffc, 0x1640012e },
280 { 0x502f4, 0x200003f8 },
281 { 0x5fffc, 0x1800012f },
282 { 0x502f8, 0x1e0003f8 },
283 { 0x5fffc, 0x1a00012f },
284 { 0x502fc, 0x1c0003f8 },
285};
286
287static struct mdp_table_entry mdp_downscale_x_table_PT8TO1[] = {
288 { 0x5fffc, 0x0 },
289 { 0x50280, 0x7fc00000 },
290 { 0x5fffc, 0xff80000d },
291 { 0x50284, 0x7ec003f9 },
292 { 0x5fffc, 0xfec0001c },
293 { 0x50288, 0x7d4003f3 },
294 { 0x5fffc, 0xfe40002b },
295 { 0x5028c, 0x7b8003ed },
296 { 0x5fffc, 0xfd80003c },
297 { 0x50290, 0x794003e8 },
298 { 0x5fffc, 0xfcc0004d },
299 { 0x50294, 0x76c003e4 },
300 { 0x5fffc, 0xfc40005f },
301 { 0x50298, 0x73c003e0 },
302 { 0x5fffc, 0xfb800071 },
303 { 0x5029c, 0x708003de },
304 { 0x5fffc, 0xfac00085 },
305 { 0x502a0, 0x6d0003db },
306 { 0x5fffc, 0xfa000098 },
307 { 0x502a4, 0x698003d9 },
308 { 0x5fffc, 0xf98000ac },
309 { 0x502a8, 0x654003d8 },
310 { 0x5fffc, 0xf8c000c1 },
311 { 0x502ac, 0x610003d7 },
312 { 0x5fffc, 0xf84000d5 },
313 { 0x502b0, 0x5c8003d7 },
314 { 0x5fffc, 0xf7c000e9 },
315 { 0x502b4, 0x580003d7 },
316 { 0x5fffc, 0xf74000fd },
317 { 0x502b8, 0x534003d8 },
318 { 0x5fffc, 0xf6c00112 },
319 { 0x502bc, 0x4e8003d8 },
320 { 0x5fffc, 0xf6800126 },
321 { 0x502c0, 0x494003da },
322 { 0x5fffc, 0xf600013a },
323 { 0x502c4, 0x448003db },
324 { 0x5fffc, 0xf600014d },
325 { 0x502c8, 0x3f4003dd },
326 { 0x5fffc, 0xf5c00160 },
327 { 0x502cc, 0x3a4003df },
328 { 0x5fffc, 0xf5c00172 },
329 { 0x502d0, 0x354003e1 },
330 { 0x5fffc, 0xf5c00184 },
331 { 0x502d4, 0x304003e3 },
332 { 0x5fffc, 0xf6000195 },
333 { 0x502d8, 0x2b0003e6 },
334 { 0x5fffc, 0xf64001a6 },
335 { 0x502dc, 0x260003e8 },
336 { 0x5fffc, 0xf6c001b4 },
337 { 0x502e0, 0x214003eb },
338 { 0x5fffc, 0xf78001c2 },
339 { 0x502e4, 0x1c4003ee },
340 { 0x5fffc, 0xf80001cf },
341 { 0x502e8, 0x17c003f1 },
342 { 0x5fffc, 0xf90001db },
343 { 0x502ec, 0x134003f3 },
344 { 0x5fffc, 0xfa0001e5 },
345 { 0x502f0, 0xf0003f6 },
346 { 0x5fffc, 0xfb4001ee },
347 { 0x502f4, 0xac003f9 },
348 { 0x5fffc, 0xfcc001f5 },
349 { 0x502f8, 0x70003fb },
350 { 0x5fffc, 0xfe4001fb },
351 { 0x502fc, 0x34003fe },
352};
353
354struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX] = {
355 [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_x_table_PT2TOPT4,
356 [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_x_table_PT4TOPT6,
357 [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_x_table_PT6TOPT8,
358 [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_x_table_PT8TO1,
359};
360
361static struct mdp_table_entry mdp_downscale_y_table_PT2TOPT4[] = {
362 { 0x5fffc, 0x740008c },
363 { 0x50300, 0x33800088 },
364 { 0x5fffc, 0x800008e },
365 { 0x50304, 0x33400084 },
366 { 0x5fffc, 0x8400092 },
367 { 0x50308, 0x33000080 },
368 { 0x5fffc, 0x9000094 },
369 { 0x5030c, 0x3300007b },
370 { 0x5fffc, 0x9c00098 },
371 { 0x50310, 0x32400077 },
372 { 0x5fffc, 0xa40009b },
373 { 0x50314, 0x32000073 },
374 { 0x5fffc, 0xb00009d },
375 { 0x50318, 0x31c0006f },
376 { 0x5fffc, 0xbc000a0 },
377 { 0x5031c, 0x3140006b },
378 { 0x5fffc, 0xc8000a2 },
379 { 0x50320, 0x31000067 },
380 { 0x5fffc, 0xd8000a5 },
381 { 0x50324, 0x30800062 },
382 { 0x5fffc, 0xe4000a8 },
383 { 0x50328, 0x2fc0005f },
384 { 0x5fffc, 0xec000aa },
385 { 0x5032c, 0x2fc0005b },
386 { 0x5fffc, 0xf8000ad },
387 { 0x50330, 0x2f400057 },
388 { 0x5fffc, 0x108000b0 },
389 { 0x50334, 0x2e400054 },
390 { 0x5fffc, 0x114000b2 },
391 { 0x50338, 0x2e000050 },
392 { 0x5fffc, 0x124000b4 },
393 { 0x5033c, 0x2d80004c },
394 { 0x5fffc, 0x130000b6 },
395 { 0x50340, 0x2d000049 },
396 { 0x5fffc, 0x140000b8 },
397 { 0x50344, 0x2c800045 },
398 { 0x5fffc, 0x150000b9 },
399 { 0x50348, 0x2c000042 },
400 { 0x5fffc, 0x15c000bd },
401 { 0x5034c, 0x2b40003e },
402 { 0x5fffc, 0x16c000bf },
403 { 0x50350, 0x2a80003b },
404 { 0x5fffc, 0x17c000bf },
405 { 0x50354, 0x2a000039 },
406 { 0x5fffc, 0x188000c2 },
407 { 0x50358, 0x29400036 },
408 { 0x5fffc, 0x19c000c4 },
409 { 0x5035c, 0x28800032 },
410 { 0x5fffc, 0x1ac000c5 },
411 { 0x50360, 0x2800002f },
412 { 0x5fffc, 0x1bc000c7 },
413 { 0x50364, 0x2740002c },
414 { 0x5fffc, 0x1cc000c8 },
415 { 0x50368, 0x26c00029 },
416 { 0x5fffc, 0x1dc000c9 },
417 { 0x5036c, 0x26000027 },
418 { 0x5fffc, 0x1ec000cc },
419 { 0x50370, 0x25000024 },
420 { 0x5fffc, 0x200000cc },
421 { 0x50374, 0x24800021 },
422 { 0x5fffc, 0x210000cd },
423 { 0x50378, 0x23800020 },
424 { 0x5fffc, 0x220000ce },
425 { 0x5037c, 0x2300001d },
426};
427
428static struct mdp_table_entry mdp_downscale_y_table_PT4TOPT6[] = {
429 { 0x5fffc, 0x740008c },
430 { 0x50300, 0x33800088 },
431 { 0x5fffc, 0x800008e },
432 { 0x50304, 0x33400084 },
433 { 0x5fffc, 0x8400092 },
434 { 0x50308, 0x33000080 },
435 { 0x5fffc, 0x9000094 },
436 { 0x5030c, 0x3300007b },
437 { 0x5fffc, 0x9c00098 },
438 { 0x50310, 0x32400077 },
439 { 0x5fffc, 0xa40009b },
440 { 0x50314, 0x32000073 },
441 { 0x5fffc, 0xb00009d },
442 { 0x50318, 0x31c0006f },
443 { 0x5fffc, 0xbc000a0 },
444 { 0x5031c, 0x3140006b },
445 { 0x5fffc, 0xc8000a2 },
446 { 0x50320, 0x31000067 },
447 { 0x5fffc, 0xd8000a5 },
448 { 0x50324, 0x30800062 },
449 { 0x5fffc, 0xe4000a8 },
450 { 0x50328, 0x2fc0005f },
451 { 0x5fffc, 0xec000aa },
452 { 0x5032c, 0x2fc0005b },
453 { 0x5fffc, 0xf8000ad },
454 { 0x50330, 0x2f400057 },
455 { 0x5fffc, 0x108000b0 },
456 { 0x50334, 0x2e400054 },
457 { 0x5fffc, 0x114000b2 },
458 { 0x50338, 0x2e000050 },
459 { 0x5fffc, 0x124000b4 },
460 { 0x5033c, 0x2d80004c },
461 { 0x5fffc, 0x130000b6 },
462 { 0x50340, 0x2d000049 },
463 { 0x5fffc, 0x140000b8 },
464 { 0x50344, 0x2c800045 },
465 { 0x5fffc, 0x150000b9 },
466 { 0x50348, 0x2c000042 },
467 { 0x5fffc, 0x15c000bd },
468 { 0x5034c, 0x2b40003e },
469 { 0x5fffc, 0x16c000bf },
470 { 0x50350, 0x2a80003b },
471 { 0x5fffc, 0x17c000bf },
472 { 0x50354, 0x2a000039 },
473 { 0x5fffc, 0x188000c2 },
474 { 0x50358, 0x29400036 },
475 { 0x5fffc, 0x19c000c4 },
476 { 0x5035c, 0x28800032 },
477 { 0x5fffc, 0x1ac000c5 },
478 { 0x50360, 0x2800002f },
479 { 0x5fffc, 0x1bc000c7 },
480 { 0x50364, 0x2740002c },
481 { 0x5fffc, 0x1cc000c8 },
482 { 0x50368, 0x26c00029 },
483 { 0x5fffc, 0x1dc000c9 },
484 { 0x5036c, 0x26000027 },
485 { 0x5fffc, 0x1ec000cc },
486 { 0x50370, 0x25000024 },
487 { 0x5fffc, 0x200000cc },
488 { 0x50374, 0x24800021 },
489 { 0x5fffc, 0x210000cd },
490 { 0x50378, 0x23800020 },
491 { 0x5fffc, 0x220000ce },
492 { 0x5037c, 0x2300001d },
493};
494
495static struct mdp_table_entry mdp_downscale_y_table_PT6TOPT8[] = {
496 { 0x5fffc, 0xfe000070 },
497 { 0x50300, 0x4bc00068 },
498 { 0x5fffc, 0xfe000078 },
499 { 0x50304, 0x4bc00060 },
500 { 0x5fffc, 0xfe000080 },
501 { 0x50308, 0x4b800059 },
502 { 0x5fffc, 0xfe000089 },
503 { 0x5030c, 0x4b000052 },
504 { 0x5fffc, 0xfe400091 },
505 { 0x50310, 0x4a80004b },
506 { 0x5fffc, 0xfe40009a },
507 { 0x50314, 0x4a000044 },
508 { 0x5fffc, 0xfe8000a3 },
509 { 0x50318, 0x4940003d },
510 { 0x5fffc, 0xfec000ac },
511 { 0x5031c, 0x48400037 },
512 { 0x5fffc, 0xff0000b4 },
513 { 0x50320, 0x47800031 },
514 { 0x5fffc, 0xff8000bd },
515 { 0x50324, 0x4640002b },
516 { 0x5fffc, 0xc5 },
517 { 0x50328, 0x45000026 },
518 { 0x5fffc, 0x8000ce },
519 { 0x5032c, 0x43800021 },
520 { 0x5fffc, 0x10000d6 },
521 { 0x50330, 0x4240001c },
522 { 0x5fffc, 0x18000df },
523 { 0x50334, 0x40800018 },
524 { 0x5fffc, 0x24000e6 },
525 { 0x50338, 0x3f000014 },
526 { 0x5fffc, 0x30000ee },
527 { 0x5033c, 0x3d400010 },
528 { 0x5fffc, 0x40000f5 },
529 { 0x50340, 0x3b80000c },
530 { 0x5fffc, 0x50000fc },
531 { 0x50344, 0x39800009 },
532 { 0x5fffc, 0x6000102 },
533 { 0x50348, 0x37c00006 },
534 { 0x5fffc, 0x7000109 },
535 { 0x5034c, 0x35800004 },
536 { 0x5fffc, 0x840010e },
537 { 0x50350, 0x33800002 },
538 { 0x5fffc, 0x9800114 },
539 { 0x50354, 0x31400000 },
540 { 0x5fffc, 0xac00119 },
541 { 0x50358, 0x2f4003fe },
542 { 0x5fffc, 0xc40011e },
543 { 0x5035c, 0x2d0003fc },
544 { 0x5fffc, 0xdc00121 },
545 { 0x50360, 0x2b0003fb },
546 { 0x5fffc, 0xf400125 },
547 { 0x50364, 0x28c003fa },
548 { 0x5fffc, 0x11000128 },
549 { 0x50368, 0x268003f9 },
550 { 0x5fffc, 0x12c0012a },
551 { 0x5036c, 0x244003f9 },
552 { 0x5fffc, 0x1480012c },
553 { 0x50370, 0x224003f8 },
554 { 0x5fffc, 0x1640012e },
555 { 0x50374, 0x200003f8 },
556 { 0x5fffc, 0x1800012f },
557 { 0x50378, 0x1e0003f8 },
558 { 0x5fffc, 0x1a00012f },
559 { 0x5037c, 0x1c0003f8 },
560};
561
562static struct mdp_table_entry mdp_downscale_y_table_PT8TO1[] = {
563 { 0x5fffc, 0x0 },
564 { 0x50300, 0x7fc00000 },
565 { 0x5fffc, 0xff80000d },
566 { 0x50304, 0x7ec003f9 },
567 { 0x5fffc, 0xfec0001c },
568 { 0x50308, 0x7d4003f3 },
569 { 0x5fffc, 0xfe40002b },
570 { 0x5030c, 0x7b8003ed },
571 { 0x5fffc, 0xfd80003c },
572 { 0x50310, 0x794003e8 },
573 { 0x5fffc, 0xfcc0004d },
574 { 0x50314, 0x76c003e4 },
575 { 0x5fffc, 0xfc40005f },
576 { 0x50318, 0x73c003e0 },
577 { 0x5fffc, 0xfb800071 },
578 { 0x5031c, 0x708003de },
579 { 0x5fffc, 0xfac00085 },
580 { 0x50320, 0x6d0003db },
581 { 0x5fffc, 0xfa000098 },
582 { 0x50324, 0x698003d9 },
583 { 0x5fffc, 0xf98000ac },
584 { 0x50328, 0x654003d8 },
585 { 0x5fffc, 0xf8c000c1 },
586 { 0x5032c, 0x610003d7 },
587 { 0x5fffc, 0xf84000d5 },
588 { 0x50330, 0x5c8003d7 },
589 { 0x5fffc, 0xf7c000e9 },
590 { 0x50334, 0x580003d7 },
591 { 0x5fffc, 0xf74000fd },
592 { 0x50338, 0x534003d8 },
593 { 0x5fffc, 0xf6c00112 },
594 { 0x5033c, 0x4e8003d8 },
595 { 0x5fffc, 0xf6800126 },
596 { 0x50340, 0x494003da },
597 { 0x5fffc, 0xf600013a },
598 { 0x50344, 0x448003db },
599 { 0x5fffc, 0xf600014d },
600 { 0x50348, 0x3f4003dd },
601 { 0x5fffc, 0xf5c00160 },
602 { 0x5034c, 0x3a4003df },
603 { 0x5fffc, 0xf5c00172 },
604 { 0x50350, 0x354003e1 },
605 { 0x5fffc, 0xf5c00184 },
606 { 0x50354, 0x304003e3 },
607 { 0x5fffc, 0xf6000195 },
608 { 0x50358, 0x2b0003e6 },
609 { 0x5fffc, 0xf64001a6 },
610 { 0x5035c, 0x260003e8 },
611 { 0x5fffc, 0xf6c001b4 },
612 { 0x50360, 0x214003eb },
613 { 0x5fffc, 0xf78001c2 },
614 { 0x50364, 0x1c4003ee },
615 { 0x5fffc, 0xf80001cf },
616 { 0x50368, 0x17c003f1 },
617 { 0x5fffc, 0xf90001db },
618 { 0x5036c, 0x134003f3 },
619 { 0x5fffc, 0xfa0001e5 },
620 { 0x50370, 0xf0003f6 },
621 { 0x5fffc, 0xfb4001ee },
622 { 0x50374, 0xac003f9 },
623 { 0x5fffc, 0xfcc001f5 },
624 { 0x50378, 0x70003fb },
625 { 0x5fffc, 0xfe4001fb },
626 { 0x5037c, 0x34003fe },
627};
628
629struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX] = {
630 [MDP_DOWNSCALE_PT2TOPT4] = mdp_downscale_y_table_PT2TOPT4,
631 [MDP_DOWNSCALE_PT4TOPT6] = mdp_downscale_y_table_PT4TOPT6,
632 [MDP_DOWNSCALE_PT6TOPT8] = mdp_downscale_y_table_PT6TOPT8,
633 [MDP_DOWNSCALE_PT8TO1] = mdp_downscale_y_table_PT8TO1,
634};
635
636struct mdp_table_entry mdp_gaussian_blur_table[] = {
637 /* max variance */
638 { 0x5fffc, 0x20000080 },
639 { 0x50280, 0x20000080 },
640 { 0x5fffc, 0x20000080 },
641 { 0x50284, 0x20000080 },
642 { 0x5fffc, 0x20000080 },
643 { 0x50288, 0x20000080 },
644 { 0x5fffc, 0x20000080 },
645 { 0x5028c, 0x20000080 },
646 { 0x5fffc, 0x20000080 },
647 { 0x50290, 0x20000080 },
648 { 0x5fffc, 0x20000080 },
649 { 0x50294, 0x20000080 },
650 { 0x5fffc, 0x20000080 },
651 { 0x50298, 0x20000080 },
652 { 0x5fffc, 0x20000080 },
653 { 0x5029c, 0x20000080 },
654 { 0x5fffc, 0x20000080 },
655 { 0x502a0, 0x20000080 },
656 { 0x5fffc, 0x20000080 },
657 { 0x502a4, 0x20000080 },
658 { 0x5fffc, 0x20000080 },
659 { 0x502a8, 0x20000080 },
660 { 0x5fffc, 0x20000080 },
661 { 0x502ac, 0x20000080 },
662 { 0x5fffc, 0x20000080 },
663 { 0x502b0, 0x20000080 },
664 { 0x5fffc, 0x20000080 },
665 { 0x502b4, 0x20000080 },
666 { 0x5fffc, 0x20000080 },
667 { 0x502b8, 0x20000080 },
668 { 0x5fffc, 0x20000080 },
669 { 0x502bc, 0x20000080 },
670 { 0x5fffc, 0x20000080 },
671 { 0x502c0, 0x20000080 },
672 { 0x5fffc, 0x20000080 },
673 { 0x502c4, 0x20000080 },
674 { 0x5fffc, 0x20000080 },
675 { 0x502c8, 0x20000080 },
676 { 0x5fffc, 0x20000080 },
677 { 0x502cc, 0x20000080 },
678 { 0x5fffc, 0x20000080 },
679 { 0x502d0, 0x20000080 },
680 { 0x5fffc, 0x20000080 },
681 { 0x502d4, 0x20000080 },
682 { 0x5fffc, 0x20000080 },
683 { 0x502d8, 0x20000080 },
684 { 0x5fffc, 0x20000080 },
685 { 0x502dc, 0x20000080 },
686 { 0x5fffc, 0x20000080 },
687 { 0x502e0, 0x20000080 },
688 { 0x5fffc, 0x20000080 },
689 { 0x502e4, 0x20000080 },
690 { 0x5fffc, 0x20000080 },
691 { 0x502e8, 0x20000080 },
692 { 0x5fffc, 0x20000080 },
693 { 0x502ec, 0x20000080 },
694 { 0x5fffc, 0x20000080 },
695 { 0x502f0, 0x20000080 },
696 { 0x5fffc, 0x20000080 },
697 { 0x502f4, 0x20000080 },
698 { 0x5fffc, 0x20000080 },
699 { 0x502f8, 0x20000080 },
700 { 0x5fffc, 0x20000080 },
701 { 0x502fc, 0x20000080 },
702 { 0x5fffc, 0x20000080 },
703 { 0x50300, 0x20000080 },
704 { 0x5fffc, 0x20000080 },
705 { 0x50304, 0x20000080 },
706 { 0x5fffc, 0x20000080 },
707 { 0x50308, 0x20000080 },
708 { 0x5fffc, 0x20000080 },
709 { 0x5030c, 0x20000080 },
710 { 0x5fffc, 0x20000080 },
711 { 0x50310, 0x20000080 },
712 { 0x5fffc, 0x20000080 },
713 { 0x50314, 0x20000080 },
714 { 0x5fffc, 0x20000080 },
715 { 0x50318, 0x20000080 },
716 { 0x5fffc, 0x20000080 },
717 { 0x5031c, 0x20000080 },
718 { 0x5fffc, 0x20000080 },
719 { 0x50320, 0x20000080 },
720 { 0x5fffc, 0x20000080 },
721 { 0x50324, 0x20000080 },
722 { 0x5fffc, 0x20000080 },
723 { 0x50328, 0x20000080 },
724 { 0x5fffc, 0x20000080 },
725 { 0x5032c, 0x20000080 },
726 { 0x5fffc, 0x20000080 },
727 { 0x50330, 0x20000080 },
728 { 0x5fffc, 0x20000080 },
729 { 0x50334, 0x20000080 },
730 { 0x5fffc, 0x20000080 },
731 { 0x50338, 0x20000080 },
732 { 0x5fffc, 0x20000080 },
733 { 0x5033c, 0x20000080 },
734 { 0x5fffc, 0x20000080 },
735 { 0x50340, 0x20000080 },
736 { 0x5fffc, 0x20000080 },
737 { 0x50344, 0x20000080 },
738 { 0x5fffc, 0x20000080 },
739 { 0x50348, 0x20000080 },
740 { 0x5fffc, 0x20000080 },
741 { 0x5034c, 0x20000080 },
742 { 0x5fffc, 0x20000080 },
743 { 0x50350, 0x20000080 },
744 { 0x5fffc, 0x20000080 },
745 { 0x50354, 0x20000080 },
746 { 0x5fffc, 0x20000080 },
747 { 0x50358, 0x20000080 },
748 { 0x5fffc, 0x20000080 },
749 { 0x5035c, 0x20000080 },
750 { 0x5fffc, 0x20000080 },
751 { 0x50360, 0x20000080 },
752 { 0x5fffc, 0x20000080 },
753 { 0x50364, 0x20000080 },
754 { 0x5fffc, 0x20000080 },
755 { 0x50368, 0x20000080 },
756 { 0x5fffc, 0x20000080 },
757 { 0x5036c, 0x20000080 },
758 { 0x5fffc, 0x20000080 },
759 { 0x50370, 0x20000080 },
760 { 0x5fffc, 0x20000080 },
761 { 0x50374, 0x20000080 },
762 { 0x5fffc, 0x20000080 },
763 { 0x50378, 0x20000080 },
764 { 0x5fffc, 0x20000080 },
765 { 0x5037c, 0x20000080 },
766};
diff --git a/drivers/video/fbdev/msm/mdp_scale_tables.h b/drivers/video/fbdev/msm/mdp_scale_tables.h
deleted file mode 100644
index 34077b1af603..000000000000
--- a/drivers/video/fbdev/msm/mdp_scale_tables.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/* drivers/video/msm_fb/mdp_scale_tables.h
2 *
3 * Copyright (C) 2007 QUALCOMM Incorporated
4 * Copyright (C) 2007 Google Incorporated
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#ifndef _MDP_SCALE_TABLES_H_
16#define _MDP_SCALE_TABLES_H_
17
18#include <linux/types.h>
19struct mdp_table_entry {
20 uint32_t reg;
21 uint32_t val;
22};
23
24extern struct mdp_table_entry mdp_upscale_table[64];
25
26enum {
27 MDP_DOWNSCALE_PT2TOPT4,
28 MDP_DOWNSCALE_PT4TOPT6,
29 MDP_DOWNSCALE_PT6TOPT8,
30 MDP_DOWNSCALE_PT8TO1,
31 MDP_DOWNSCALE_MAX,
32};
33
34extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
35extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
36extern struct mdp_table_entry mdp_gaussian_blur_table[];
37
38#endif
diff --git a/drivers/video/fbdev/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c
deleted file mode 100644
index 2979d7e72126..000000000000
--- a/drivers/video/fbdev/msm/msm_fb.c
+++ /dev/null
@@ -1,659 +0,0 @@
1/* drivers/video/msm/msm_fb.c
2 *
3 * Core MSM framebuffer driver.
4 *
5 * Copyright (C) 2007 Google Incorporated
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/fb.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22
23#include <linux/freezer.h>
24#include <linux/wait.h>
25#include <linux/msm_mdp.h>
26#include <linux/io.h>
27#include <linux/uaccess.h>
28#include <linux/platform_data/video-msm_fb.h>
29#include <linux/workqueue.h>
30#include <linux/clk.h>
31#include <linux/debugfs.h>
32#include <linux/dma-mapping.h>
33
34#define PRINT_FPS 0
35#define PRINT_BLIT_TIME 0
36
37#define SLEEPING 0x4
38#define UPDATING 0x3
39#define FULL_UPDATE_DONE 0x2
40#define WAKING 0x1
41#define AWAKE 0x0
42
43#define NONE 0
44#define SUSPEND_RESUME 0x1
45#define FPS 0x2
46#define BLIT_TIME 0x4
47#define SHOW_UPDATES 0x8
48
49#define DLOG(mask, fmt, args...) \
50do { \
51 if (msmfb_debug_mask & mask) \
52 printk(KERN_INFO "msmfb: "fmt, ##args); \
53} while (0)
54
55static int msmfb_debug_mask;
56module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
57 S_IRUGO | S_IWUSR | S_IWGRP);
58
59struct mdp_device *mdp;
60
61struct msmfb_info {
62 struct fb_info *fb;
63 struct msm_panel_data *panel;
64 int xres;
65 int yres;
66 unsigned output_format;
67 unsigned yoffset;
68 unsigned frame_requested;
69 unsigned frame_done;
70 int sleeping;
71 unsigned update_frame;
72 struct {
73 int left;
74 int top;
75 int eright; /* exclusive */
76 int ebottom; /* exclusive */
77 } update_info;
78 char *black;
79
80 spinlock_t update_lock;
81 struct mutex panel_init_lock;
82 wait_queue_head_t frame_wq;
83 struct work_struct resume_work;
84 struct msmfb_callback dma_callback;
85 struct msmfb_callback vsync_callback;
86 struct hrtimer fake_vsync;
87 ktime_t vsync_request_time;
88};
89
90static int msmfb_open(struct fb_info *info, int user)
91{
92 return 0;
93}
94
95static int msmfb_release(struct fb_info *info, int user)
96{
97 return 0;
98}
99
100/* Called from dma interrupt handler, must not sleep */
101static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
102{
103 unsigned long irq_flags;
104 struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
105 dma_callback);
106
107 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
108 msmfb->frame_done = msmfb->frame_requested;
109 if (msmfb->sleeping == UPDATING &&
110 msmfb->frame_done == msmfb->update_frame) {
111 DLOG(SUSPEND_RESUME, "full update completed\n");
112 schedule_work(&msmfb->resume_work);
113 }
114 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
115 wake_up(&msmfb->frame_wq);
116}
117
118static int msmfb_start_dma(struct msmfb_info *msmfb)
119{
120 uint32_t x, y, w, h;
121 unsigned addr;
122 unsigned long irq_flags;
123 uint32_t yoffset;
124 s64 time_since_request;
125 struct msm_panel_data *panel = msmfb->panel;
126
127 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
128 time_since_request = ktime_to_ns(ktime_sub(ktime_get(),
129 msmfb->vsync_request_time));
130 if (time_since_request > 20 * NSEC_PER_MSEC) {
131 uint32_t us;
132 us = do_div(time_since_request, NSEC_PER_MSEC) / NSEC_PER_USEC;
133 printk(KERN_WARNING "msmfb_start_dma %lld.%03u ms after vsync "
134 "request\n", time_since_request, us);
135 }
136 if (msmfb->frame_done == msmfb->frame_requested) {
137 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
138 return -1;
139 }
140 if (msmfb->sleeping == SLEEPING) {
141 DLOG(SUSPEND_RESUME, "tried to start dma while asleep\n");
142 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
143 return -1;
144 }
145 x = msmfb->update_info.left;
146 y = msmfb->update_info.top;
147 w = msmfb->update_info.eright - x;
148 h = msmfb->update_info.ebottom - y;
149 yoffset = msmfb->yoffset;
150 msmfb->update_info.left = msmfb->xres + 1;
151 msmfb->update_info.top = msmfb->yres + 1;
152 msmfb->update_info.eright = 0;
153 msmfb->update_info.ebottom = 0;
154 if (unlikely(w > msmfb->xres || h > msmfb->yres ||
155 w == 0 || h == 0)) {
156 printk(KERN_INFO "invalid update: %d %d %d "
157 "%d\n", x, y, w, h);
158 msmfb->frame_done = msmfb->frame_requested;
159 goto error;
160 }
161 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
162
163 addr = ((msmfb->xres * (yoffset + y) + x) * 2);
164 mdp->dma(mdp, addr + msmfb->fb->fix.smem_start,
165 msmfb->xres * 2, w, h, x, y, &msmfb->dma_callback,
166 panel->interface_type);
167 return 0;
168error:
169 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
170 /* some clients need to clear their vsync interrupt */
171 if (panel->clear_vsync)
172 panel->clear_vsync(panel);
173 wake_up(&msmfb->frame_wq);
174 return 0;
175}
176
177/* Called from esync interrupt handler, must not sleep */
178static void msmfb_handle_vsync_interrupt(struct msmfb_callback *callback)
179{
180 struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
181 vsync_callback);
182 msmfb_start_dma(msmfb);
183}
184
185static enum hrtimer_restart msmfb_fake_vsync(struct hrtimer *timer)
186{
187 struct msmfb_info *msmfb = container_of(timer, struct msmfb_info,
188 fake_vsync);
189 msmfb_start_dma(msmfb);
190 return HRTIMER_NORESTART;
191}
192
193static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
194 uint32_t eright, uint32_t ebottom,
195 uint32_t yoffset, int pan_display)
196{
197 struct msmfb_info *msmfb = info->par;
198 struct msm_panel_data *panel = msmfb->panel;
199 unsigned long irq_flags;
200 int sleeping;
201 int retry = 1;
202
203 DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
204 left, top, eright, ebottom, yoffset, pan_display);
205restart:
206 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
207
208 /* if we are sleeping, on a pan_display wait 10ms (to throttle back
209 * drawing otherwise return */
210 if (msmfb->sleeping == SLEEPING) {
211 DLOG(SUSPEND_RESUME, "drawing while asleep\n");
212 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
213 if (pan_display)
214 wait_event_interruptible_timeout(msmfb->frame_wq,
215 msmfb->sleeping != SLEEPING, HZ/10);
216 return;
217 }
218
219 sleeping = msmfb->sleeping;
220 /* on a full update, if the last frame has not completed, wait for it */
221 if ((pan_display && msmfb->frame_requested != msmfb->frame_done) ||
222 sleeping == UPDATING) {
223 int ret;
224 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
225 ret = wait_event_interruptible_timeout(msmfb->frame_wq,
226 msmfb->frame_done == msmfb->frame_requested &&
227 msmfb->sleeping != UPDATING, 5 * HZ);
228 if (ret <= 0 && (msmfb->frame_requested != msmfb->frame_done ||
229 msmfb->sleeping == UPDATING)) {
230 if (retry && panel->request_vsync &&
231 (sleeping == AWAKE)) {
232 panel->request_vsync(panel,
233 &msmfb->vsync_callback);
234 retry = 0;
235 printk(KERN_WARNING "msmfb_pan_display timeout "
236 "rerequest vsync\n");
237 } else {
238 printk(KERN_WARNING "msmfb_pan_display timeout "
239 "waiting for frame start, %d %d\n",
240 msmfb->frame_requested,
241 msmfb->frame_done);
242 return;
243 }
244 }
245 goto restart;
246 }
247
248
249 msmfb->frame_requested++;
250 /* if necessary, update the y offset, if this is the
251 * first full update on resume, set the sleeping state */
252 if (pan_display) {
253 msmfb->yoffset = yoffset;
254 if (left == 0 && top == 0 && eright == info->var.xres &&
255 ebottom == info->var.yres) {
256 if (sleeping == WAKING) {
257 msmfb->update_frame = msmfb->frame_requested;
258 DLOG(SUSPEND_RESUME, "full update starting\n");
259 msmfb->sleeping = UPDATING;
260 }
261 }
262 }
263
264 /* set the update request */
265 if (left < msmfb->update_info.left)
266 msmfb->update_info.left = left;
267 if (top < msmfb->update_info.top)
268 msmfb->update_info.top = top;
269 if (eright > msmfb->update_info.eright)
270 msmfb->update_info.eright = eright;
271 if (ebottom > msmfb->update_info.ebottom)
272 msmfb->update_info.ebottom = ebottom;
273 DLOG(SHOW_UPDATES, "update queued %d %d %d %d %d\n",
274 msmfb->update_info.left, msmfb->update_info.top,
275 msmfb->update_info.eright, msmfb->update_info.ebottom,
276 msmfb->yoffset);
277 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
278
279 /* if the panel is all the way on wait for vsync, otherwise sleep
280 * for 16 ms (long enough for the dma to panel) and then begin dma */
281 msmfb->vsync_request_time = ktime_get();
282 if (panel->request_vsync && (sleeping == AWAKE)) {
283 panel->request_vsync(panel, &msmfb->vsync_callback);
284 } else {
285 if (!hrtimer_active(&msmfb->fake_vsync)) {
286 hrtimer_start(&msmfb->fake_vsync,
287 ktime_set(0, NSEC_PER_SEC/60),
288 HRTIMER_MODE_REL);
289 }
290 }
291}
292
293static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
294 uint32_t eright, uint32_t ebottom)
295{
296 msmfb_pan_update(info, left, top, eright, ebottom, 0, 0);
297}
298
299static void power_on_panel(struct work_struct *work)
300{
301 struct msmfb_info *msmfb =
302 container_of(work, struct msmfb_info, resume_work);
303 struct msm_panel_data *panel = msmfb->panel;
304 unsigned long irq_flags;
305
306 mutex_lock(&msmfb->panel_init_lock);
307 DLOG(SUSPEND_RESUME, "turning on panel\n");
308 if (msmfb->sleeping == UPDATING) {
309 if (panel->unblank(panel)) {
310 printk(KERN_INFO "msmfb: panel unblank failed,"
311 "not starting drawing\n");
312 goto error;
313 }
314 spin_lock_irqsave(&msmfb->update_lock, irq_flags);
315 msmfb->sleeping = AWAKE;
316 wake_up(&msmfb->frame_wq);
317 spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
318 }
319error:
320 mutex_unlock(&msmfb->panel_init_lock);
321}
322
323
324static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
325{
326 if ((var->xres != info->var.xres) ||
327 (var->yres != info->var.yres) ||
328 (var->xres_virtual != info->var.xres_virtual) ||
329 (var->yres_virtual != info->var.yres_virtual) ||
330 (var->xoffset != info->var.xoffset) ||
331 (var->bits_per_pixel != info->var.bits_per_pixel) ||
332 (var->grayscale != info->var.grayscale))
333 return -EINVAL;
334 return 0;
335}
336
337int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
338{
339 struct msmfb_info *msmfb = info->par;
340 struct msm_panel_data *panel = msmfb->panel;
341
342 /* "UPDT" */
343 if ((panel->caps & MSMFB_CAP_PARTIAL_UPDATES) &&
344 (var->reserved[0] == 0x54445055)) {
345 msmfb_pan_update(info, var->reserved[1] & 0xffff,
346 var->reserved[1] >> 16,
347 var->reserved[2] & 0xffff,
348 var->reserved[2] >> 16, var->yoffset, 1);
349 } else {
350 msmfb_pan_update(info, 0, 0, info->var.xres, info->var.yres,
351 var->yoffset, 1);
352 }
353 return 0;
354}
355
356static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
357{
358 cfb_fillrect(p, rect);
359 msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
360 rect->dy + rect->height);
361}
362
363static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
364{
365 cfb_copyarea(p, area);
366 msmfb_update(p, area->dx, area->dy, area->dx + area->width,
367 area->dy + area->height);
368}
369
370static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
371{
372 cfb_imageblit(p, image);
373 msmfb_update(p, image->dx, image->dy, image->dx + image->width,
374 image->dy + image->height);
375}
376
377
378static int msmfb_blit(struct fb_info *info,
379 void __user *p)
380{
381 struct mdp_blit_req req;
382 struct mdp_blit_req_list req_list;
383 int i;
384 int ret;
385
386 if (copy_from_user(&req_list, p, sizeof(req_list)))
387 return -EFAULT;
388
389 for (i = 0; i < req_list.count; i++) {
390 struct mdp_blit_req_list *list =
391 (struct mdp_blit_req_list *)p;
392 if (copy_from_user(&req, &list->req[i], sizeof(req)))
393 return -EFAULT;
394 ret = mdp->blit(mdp, info, &req);
395 if (ret)
396 return ret;
397 }
398 return 0;
399}
400
401
402DEFINE_MUTEX(mdp_ppp_lock);
403
404static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
405{
406 void __user *argp = (void __user *)arg;
407 int ret;
408
409 switch (cmd) {
410 case MSMFB_GRP_DISP:
411 mdp->set_grp_disp(mdp, arg);
412 break;
413 case MSMFB_BLIT:
414 ret = msmfb_blit(p, argp);
415 if (ret)
416 return ret;
417 break;
418 default:
419 printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd);
420 return -EINVAL;
421 }
422 return 0;
423}
424
425static struct fb_ops msmfb_ops = {
426 .owner = THIS_MODULE,
427 .fb_open = msmfb_open,
428 .fb_release = msmfb_release,
429 .fb_check_var = msmfb_check_var,
430 .fb_pan_display = msmfb_pan_display,
431 .fb_fillrect = msmfb_fillrect,
432 .fb_copyarea = msmfb_copyarea,
433 .fb_imageblit = msmfb_imageblit,
434 .fb_ioctl = msmfb_ioctl,
435};
436
437static unsigned PP[16];
438
439
440
441#define BITS_PER_PIXEL 16
442
443static void setup_fb_info(struct msmfb_info *msmfb)
444{
445 struct fb_info *fb_info = msmfb->fb;
446 int r;
447
448 /* finish setting up the fb_info struct */
449 strncpy(fb_info->fix.id, "msmfb", 16);
450 fb_info->fix.ypanstep = 1;
451
452 fb_info->fbops = &msmfb_ops;
453 fb_info->flags = FBINFO_DEFAULT;
454
455 fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
456 fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
457 fb_info->fix.line_length = msmfb->xres * 2;
458
459 fb_info->var.xres = msmfb->xres;
460 fb_info->var.yres = msmfb->yres;
461 fb_info->var.width = msmfb->panel->fb_data->width;
462 fb_info->var.height = msmfb->panel->fb_data->height;
463 fb_info->var.xres_virtual = msmfb->xres;
464 fb_info->var.yres_virtual = msmfb->yres * 2;
465 fb_info->var.bits_per_pixel = BITS_PER_PIXEL;
466 fb_info->var.accel_flags = 0;
467
468 fb_info->var.yoffset = 0;
469
470 if (msmfb->panel->caps & MSMFB_CAP_PARTIAL_UPDATES) {
471 /*
472 * Set the param in the fixed screen, so userspace can't
473 * change it. This will be used to check for the
474 * capability.
475 */
476 fb_info->fix.reserved[0] = 0x5444;
477 fb_info->fix.reserved[1] = 0x5055;
478
479 /*
480 * This preloads the value so that if userspace doesn't
481 * change it, it will be a full update
482 */
483 fb_info->var.reserved[0] = 0x54445055;
484 fb_info->var.reserved[1] = 0;
485 fb_info->var.reserved[2] = (uint16_t)msmfb->xres |
486 ((uint32_t)msmfb->yres << 16);
487 }
488
489 fb_info->var.red.offset = 11;
490 fb_info->var.red.length = 5;
491 fb_info->var.red.msb_right = 0;
492 fb_info->var.green.offset = 5;
493 fb_info->var.green.length = 6;
494 fb_info->var.green.msb_right = 0;
495 fb_info->var.blue.offset = 0;
496 fb_info->var.blue.length = 5;
497 fb_info->var.blue.msb_right = 0;
498
499 r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
500 fb_info->pseudo_palette = PP;
501
502 PP[0] = 0;
503 for (r = 1; r < 16; r++)
504 PP[r] = 0xffffffff;
505}
506
507static int setup_fbmem(struct msmfb_info *msmfb, struct platform_device *pdev)
508{
509 struct fb_info *fb = msmfb->fb;
510 struct resource *resource;
511 unsigned long size = msmfb->xres * msmfb->yres *
512 (BITS_PER_PIXEL >> 3) * 2;
513 unsigned char *fbram;
514
515 /* board file might have attached a resource describing an fb */
516 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
517 if (!resource)
518 return -EINVAL;
519
520 /* check the resource is large enough to fit the fb */
521 if (resource->end - resource->start < size) {
522 printk(KERN_ERR "allocated resource is too small for "
523 "fb\n");
524 return -ENOMEM;
525 }
526 fb->fix.smem_start = resource->start;
527 fb->fix.smem_len = resource_size(resource);
528 fbram = ioremap(resource->start, resource_size(resource));
529 if (fbram == NULL) {
530 printk(KERN_ERR "msmfb: cannot allocate fbram!\n");
531 return -ENOMEM;
532 }
533 fb->screen_base = fbram;
534 return 0;
535}
536
537static int msmfb_probe(struct platform_device *pdev)
538{
539 struct fb_info *fb;
540 struct msmfb_info *msmfb;
541 struct msm_panel_data *panel = pdev->dev.platform_data;
542 int ret;
543
544 if (!panel) {
545 pr_err("msmfb_probe: no platform data\n");
546 return -EINVAL;
547 }
548 if (!panel->fb_data) {
549 pr_err("msmfb_probe: no fb_data\n");
550 return -EINVAL;
551 }
552
553 fb = framebuffer_alloc(sizeof(struct msmfb_info), &pdev->dev);
554 if (!fb)
555 return -ENOMEM;
556 msmfb = fb->par;
557 msmfb->fb = fb;
558 msmfb->panel = panel;
559 msmfb->xres = panel->fb_data->xres;
560 msmfb->yres = panel->fb_data->yres;
561
562 ret = setup_fbmem(msmfb, pdev);
563 if (ret)
564 goto error_setup_fbmem;
565
566 setup_fb_info(msmfb);
567
568 spin_lock_init(&msmfb->update_lock);
569 mutex_init(&msmfb->panel_init_lock);
570 init_waitqueue_head(&msmfb->frame_wq);
571 INIT_WORK(&msmfb->resume_work, power_on_panel);
572 msmfb->black = devm_kzalloc(&pdev->dev,
573 msmfb->fb->var.bits_per_pixel*msmfb->xres,
574 GFP_KERNEL);
575 if (!msmfb->black) {
576 ret = -ENOMEM;
577 goto error_register_framebuffer;
578 }
579
580 printk(KERN_INFO "msmfb_probe() installing %d x %d panel\n",
581 msmfb->xres, msmfb->yres);
582
583 msmfb->dma_callback.func = msmfb_handle_dma_interrupt;
584 msmfb->vsync_callback.func = msmfb_handle_vsync_interrupt;
585 hrtimer_init(&msmfb->fake_vsync, CLOCK_MONOTONIC,
586 HRTIMER_MODE_REL);
587
588
589 msmfb->fake_vsync.function = msmfb_fake_vsync;
590
591 ret = register_framebuffer(fb);
592 if (ret)
593 goto error_register_framebuffer;
594
595 msmfb->sleeping = WAKING;
596
597 platform_set_drvdata(pdev, msmfb);
598
599 return 0;
600
601error_register_framebuffer:
602 iounmap(fb->screen_base);
603error_setup_fbmem:
604 framebuffer_release(msmfb->fb);
605 return ret;
606}
607
608static int msmfb_remove(struct platform_device *pdev)
609{
610 struct msmfb_info *msmfb;
611
612 msmfb = platform_get_drvdata(pdev);
613
614 unregister_framebuffer(msmfb->fb);
615 iounmap(msmfb->fb->screen_base);
616 framebuffer_release(msmfb->fb);
617
618 return 0;
619}
620
621static struct platform_driver msm_panel_driver = {
622 /* need to write remove */
623 .probe = msmfb_probe,
624 .remove = msmfb_remove,
625 .driver = {.name = "msm_panel"},
626};
627
628
629static int msmfb_add_mdp_device(struct device *dev,
630 struct class_interface *class_intf)
631{
632 /* might need locking if mulitple mdp devices */
633 if (mdp)
634 return 0;
635 mdp = container_of(dev, struct mdp_device, dev);
636 return platform_driver_register(&msm_panel_driver);
637}
638
639static void msmfb_remove_mdp_device(struct device *dev,
640 struct class_interface *class_intf)
641{
642 /* might need locking if mulitple mdp devices */
643 if (dev != &mdp->dev)
644 return;
645 platform_driver_unregister(&msm_panel_driver);
646 mdp = NULL;
647}
648
649static struct class_interface msm_fb_interface = {
650 .add_dev = &msmfb_add_mdp_device,
651 .remove_dev = &msmfb_remove_mdp_device,
652};
653
654static int __init msmfb_init(void)
655{
656 return register_mdp_client(&msm_fb_interface);
657}
658
659module_init(msmfb_init);