1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <linux/kernel.h>
#include <mach/mt_clkmgr.h>
#include "cmdq_record.h"
#include "ddp_reg.h"
#include "ddp_path.h"
#include "ddp_dither.h"
#define DITHER_REG(reg_base, index) ((reg_base) + 0x100 + (index) * 4)
void disp_dither_init(disp_dither_id_t id, int width, int height,
unsigned int dither_bpp, void *cmdq)
{
unsigned long reg_base = DISPSYS_DITHER_BASE;
unsigned int enable;
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 5) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 6) , 0x00003004, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 7) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 8) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 9) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 10) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 11) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 12) , 0x00000011, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 13) , 0x00000000, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 14) , 0x00000000, ~0);
enable = 0x1;
if (dither_bpp == 16) { /* 565 */
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 15), 0x50500001, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 16), 0x50504040, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 0), 0x00000001, ~0);
} else if (dither_bpp == 18) { /* 666 */
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 15), 0x40400001, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 16), 0x40404040, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 0), 0x00000001, ~0);
} else if (dither_bpp == 24) { /* 888 */
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 15), 0x20200001, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 16), 0x20202020, ~0);
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 0), 0x00000001, ~0);
} else if (dither_bpp > 24) {
printk("[DITHER] High depth LCM (bpp = %d), no dither\n", dither_bpp);
enable = 1;
} else {
printk("[DITHER] invalid dither bpp = %d\n", dither_bpp);
/* Bypass dither */
DISP_REG_MASK(cmdq, DITHER_REG(reg_base, 0), 0x00000000, ~0);
enable = 0;
}
DISP_REG_MASK(cmdq, DISP_REG_DITHER_EN, enable, 0x1);
DISP_REG_MASK(cmdq, DISP_REG_DITHER_CFG, enable << 1, 1 << 1);
DISP_REG_SET(cmdq, DISP_REG_DITHER_SIZE, (width << 16) | height);
}
static int disp_dither_config(DISP_MODULE_ENUM module, disp_ddp_path_config* pConfig, void* cmdq)
{
if (pConfig->dst_dirty) {
disp_dither_init(DISP_DITHER0, pConfig->dst_w, pConfig->dst_h,
pConfig->lcm_bpp, cmdq);
}
return 0;
}
static int disp_dither_bypass(DISP_MODULE_ENUM module, int bypass)
{
int relay = 0;
if (bypass)
relay = 1;
DISP_REG_MASK(NULL, DISP_REG_DITHER_CFG, relay, 0x1);
printk(KERN_DEBUG "disp_dither_bypass(bypass = %d)", bypass);
return 0;
}
static int disp_dither_power_on(DISP_MODULE_ENUM module, void *handle)
{
if (module == DISP_MODULE_DITHER) {
enable_clock(MT_CG_DISP0_DISP_DITHER, "DITHER");
}
return 0;
}
static int disp_dither_power_off(DISP_MODULE_ENUM module, void *handle)
{
if (module == DISP_MODULE_DITHER) {
disable_clock(MT_CG_DISP0_DISP_DITHER, "DITHER");
}
return 0;
}
DDP_MODULE_DRIVER ddp_driver_dither =
{
.config = disp_dither_config,
.bypass = disp_dither_bypass,
.init = disp_dither_power_on,
.deinit = disp_dither_power_off,
.power_on = disp_dither_power_on,
.power_off = disp_dither_power_off,
};
|