diff options
-rw-r--r-- | drivers/video/pxafb.c | 76 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/pxafb.h | 44 |
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 | ||
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); |
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, |