aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric miao <eric.miao@marvell.com>2008-04-30 03:52:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:31 -0400
commit84f43c308b73a6a12128288721a1007ba4f1a8da (patch)
tree650246aced2ea56899f11099846980eeae8885e6
parent2c42dd8ebdd92ad59d9a68f88f0e20ad9f45270a (diff)
pxafb: introduce register independent LCD connection type for pxafb
Reasons: 1. straight forward: the name "LCD_COLOR_DSTN_16BPP" is much better than "LCCR0_Pas | LCCR0_Color | LCCR0_Dual" 2. by defining LCD connection types as constants, it allows only valid possibilities 3. by removing the dependency of register bits definitions, those can be later moved into the body of pxafb.c, instead of having a regs-lcd.h around Currently, only lubbock, mainstone, zylonite and littleton have been modified to support these types (see coming patches after this). Other platforms are encouraged to change their way describing the LCD controller connections. Signed-off-by: eric miao <eric.miao@marvell.com> Cc: "Antonino A. Daplas" <adaplas@pol.net> Cc: Russell King <rmk@arm.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/video/pxafb.c76
-rw-r--r--include/asm-arm/arch-pxa/pxafb.h44
2 files changed, 106 insertions, 14 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 4e8f68b7c5b3..0031a5fefa26 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1065,13 +1065,73 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
1065 return fbi->map_cpu ? 0 : -ENOMEM; 1065 return fbi->map_cpu ? 0 : -ENOMEM;
1066} 1066}
1067 1067
1068static void pxafb_decode_mode_info(struct pxafb_info *fbi,
1069 struct pxafb_mode_info *modes,
1070 unsigned int num_modes)
1071{
1072 unsigned int i, smemlen;
1073
1074 pxafb_setmode(&fbi->fb.var, &modes[0]);
1075
1076 for (i = 0; i < num_modes; i++) {
1077 smemlen = modes[i].xres * modes[i].yres * modes[i].bpp / 8;
1078 if (smemlen > fbi->fb.fix.smem_len)
1079 fbi->fb.fix.smem_len = smemlen;
1080 }
1081}
1082
1083static int pxafb_decode_mach_info(struct pxafb_info *fbi,
1084 struct pxafb_mach_info *inf)
1085{
1086 unsigned int lcd_conn = inf->lcd_conn;
1087
1088 fbi->cmap_inverse = inf->cmap_inverse;
1089 fbi->cmap_static = inf->cmap_static;
1090
1091 switch (lcd_conn & 0xf) {
1092 case LCD_TYPE_MONO_STN:
1093 fbi->lccr0 = LCCR0_CMS;
1094 break;
1095 case LCD_TYPE_MONO_DSTN:
1096 fbi->lccr0 = LCCR0_CMS | LCCR0_SDS;
1097 break;
1098 case LCD_TYPE_COLOR_STN:
1099 fbi->lccr0 = 0;
1100 break;
1101 case LCD_TYPE_COLOR_DSTN:
1102 fbi->lccr0 = LCCR0_SDS;
1103 break;
1104 case LCD_TYPE_COLOR_TFT:
1105 fbi->lccr0 = LCCR0_PAS;
1106 break;
1107 case LCD_TYPE_SMART_PANEL:
1108 fbi->lccr0 = LCCR0_LCDT | LCCR0_PAS;
1109 break;
1110 default:
1111 /* fall back to backward compatibility way */
1112 fbi->lccr0 = inf->lccr0;
1113 fbi->lccr3 = inf->lccr3;
1114 fbi->lccr4 = inf->lccr4;
1115 return -EINVAL;
1116 }
1117
1118 if (lcd_conn == LCD_MONO_STN_8BPP)
1119 fbi->lccr0 |= LCCR0_DPD;
1120
1121 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff);
1122 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
1123 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;
1124
1125 pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes);
1126 return 0;
1127}
1128
1068static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) 1129static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
1069{ 1130{
1070 struct pxafb_info *fbi; 1131 struct pxafb_info *fbi;
1071 void *addr; 1132 void *addr;
1072 struct pxafb_mach_info *inf = dev->platform_data; 1133 struct pxafb_mach_info *inf = dev->platform_data;
1073 struct pxafb_mode_info *mode = inf->modes; 1134 struct pxafb_mode_info *mode = inf->modes;
1074 int i, smemlen;
1075 1135
1076 /* Alloc the pxafb_info and pseudo_palette in one step */ 1136 /* Alloc the pxafb_info and pseudo_palette in one step */
1077 fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); 1137 fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1111,22 +1171,10 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
1111 addr = addr + sizeof(struct pxafb_info); 1171 addr = addr + sizeof(struct pxafb_info);
1112 fbi->fb.pseudo_palette = addr; 1172 fbi->fb.pseudo_palette = addr;
1113 1173
1114 pxafb_setmode(&fbi->fb.var, mode);
1115
1116 fbi->cmap_inverse = inf->cmap_inverse;
1117 fbi->cmap_static = inf->cmap_static;
1118
1119 fbi->lccr0 = inf->lccr0;
1120 fbi->lccr3 = inf->lccr3;
1121 fbi->lccr4 = inf->lccr4;
1122 fbi->state = C_STARTUP; 1174 fbi->state = C_STARTUP;
1123 fbi->task_state = (u_char)-1; 1175 fbi->task_state = (u_char)-1;
1124 1176
1125 for (i = 0; i < inf->num_modes; i++) { 1177 pxafb_decode_mach_info(fbi, inf);
1126 smemlen = mode[i].xres * mode[i].yres * mode[i].bpp / 8;
1127 if (smemlen > fbi->fb.fix.smem_len)
1128 fbi->fb.fix.smem_len = smemlen;
1129 }
1130 1178
1131 init_waitqueue_head(&fbi->ctrlr_wait); 1179 init_waitqueue_head(&fbi->ctrlr_wait);
1132 INIT_WORK(&fbi->task, pxafb_task); 1180 INIT_WORK(&fbi->task, pxafb_task);
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index 5cf51a5137b7..41a6c2297f9f 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -16,6 +16,48 @@
16#include <asm/arch/regs-lcd.h> 16#include <asm/arch/regs-lcd.h>
17 17
18/* 18/*
19 * Supported LCD connections
20 *
21 * bits 0 - 3: for LCD panel type:
22 *
23 * STN - for passive matrix
24 * DSTN - for dual scan passive matrix
25 * TFT - for active matrix
26 *
27 * bits 4 - 9 : for bus width
28 * bits 10-17 : for AC Bias Pin Frequency
29 * bit 18 : for output enable polarity
30 * bit 19 : for pixel clock edge
31 */
32#define LCD_CONN_TYPE(_x) ((_x) & 0x0f)
33#define LCD_CONN_WIDTH(_x) (((_x) >> 4) & 0x1f)
34
35#define LCD_TYPE_UNKNOWN 0
36#define LCD_TYPE_MONO_STN 1
37#define LCD_TYPE_MONO_DSTN 2
38#define LCD_TYPE_COLOR_STN 3
39#define LCD_TYPE_COLOR_DSTN 4
40#define LCD_TYPE_COLOR_TFT 5
41#define LCD_TYPE_SMART_PANEL 6
42#define LCD_TYPE_MAX 7
43
44#define LCD_MONO_STN_4BPP ((4 << 4) | LCD_TYPE_MONO_STN)
45#define LCD_MONO_STN_8BPP ((8 << 4) | LCD_TYPE_MONO_STN)
46#define LCD_MONO_DSTN_8BPP ((8 << 4) | LCD_TYPE_MONO_DSTN)
47#define LCD_COLOR_STN_8BPP ((8 << 4) | LCD_TYPE_COLOR_STN)
48#define LCD_COLOR_DSTN_16BPP ((16 << 4) | LCD_TYPE_COLOR_DSTN)
49#define LCD_COLOR_TFT_16BPP ((16 << 4) | LCD_TYPE_COLOR_TFT)
50#define LCD_COLOR_TFT_18BPP ((18 << 4) | LCD_TYPE_COLOR_TFT)
51#define LCD_SMART_PANEL_16BPP ((16 << 4) | LCD_TYPE_SMART_PANEL)
52#define LCD_SMART_PANEL_18BPP ((18 << 4) | LCD_TYPE_SMART_PANEL)
53
54#define LCD_AC_BIAS_FREQ(x) (((x) & 0xff) << 10)
55#define LCD_BIAS_ACTIVE_HIGH (0 << 17)
56#define LCD_BIAS_ACTIVE_LOW (1 << 17)
57#define LCD_PCLK_EDGE_RISE (0 << 18)
58#define LCD_PCLK_EDGE_FALL (1 << 18)
59
60/*
19 * This structure describes the machine which we are running on. 61 * This structure describes the machine which we are running on.
20 * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine 62 * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine
21 * of linux/drivers/video/pxafb.c 63 * of linux/drivers/video/pxafb.c
@@ -44,6 +86,8 @@ struct pxafb_mach_info {
44 struct pxafb_mode_info *modes; 86 struct pxafb_mode_info *modes;
45 unsigned int num_modes; 87 unsigned int num_modes;
46 88
89 unsigned int lcd_conn;
90
47 u_int fixed_modes:1, 91 u_int fixed_modes:1,
48 cmap_inverse:1, 92 cmap_inverse:1,
49 cmap_static:1, 93 cmap_static:1,