aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/pxafb.c
diff options
context:
space:
mode:
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);