diff options
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r-- | drivers/video/pxafb.c | 76 |
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 | ||
1068 | static 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 | |||
1083 | static 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 | |||
1068 | static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | 1129 | static 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); |