aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/pxafb.c
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 /drivers/video/pxafb.c
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>
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r--drivers/video/pxafb.c76
1 files changed, 62 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);