aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2011-05-09 15:29:40 -0400
committerKumar Gala <galak@kernel.crashing.org>2011-05-19 02:13:53 -0400
commitf46dad270b7f425d7d4ec08676f2513732d11c2b (patch)
tree94c0cf8d35a52515b00e3edf5678b4e69549ea69
parente0be2c21649107282930837f0805c71dfe29e2cc (diff)
powerpc/86xx: don't pretend that we support 8-bit pixels on the MPC8610 HPCD
If the video mode is set to 16-, 24-, or 32-bit pixels, then the pixel data contains actual levels of red, blue, and green. However, if the video mode is set to 8-bit pixels, then the 8-bit value represents an index into color table. This is called "palette mode" on the Freescale DIU video controller. The DIU driver does not currently support palette mode, but the MPC8610 HPCD board file returned a non-zero (although incorrect) pixel format value for 8-bit mode. Signed-off-by: Timur Tabi <timur@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c97
1 files changed, 64 insertions, 33 deletions
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index efadd3be8e6e..a896511690c2 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -105,45 +105,77 @@ machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
105 105
106#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 106#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
107 107
108static u32 get_busfreq(void) 108/*
109{ 109 * DIU Area Descriptor
110 struct device_node *node; 110 *
111 111 * The MPC8610 reference manual shows the bits of the AD register in
112 u32 fs_busfreq = 0; 112 * little-endian order, which causes the BLUE_C field to be split into two
113 node = of_find_node_by_type(NULL, "cpu"); 113 * parts. To simplify the definition of the MAKE_AD() macro, we define the
114 if (node) { 114 * fields in big-endian order and byte-swap the result.
115 unsigned int size; 115 *
116 const unsigned int *prop = 116 * So even though the registers don't look like they're in the
117 of_get_property(node, "bus-frequency", &size); 117 * same bit positions as they are on the P1022, the same value is written to
118 if (prop) 118 * the AD register on the MPC8610 and on the P1022.
119 fs_busfreq = *prop; 119 */
120 of_node_put(node); 120#define AD_BYTE_F 0x10000000
121 }; 121#define AD_ALPHA_C_MASK 0x0E000000
122 return fs_busfreq; 122#define AD_ALPHA_C_SHIFT 25
123} 123#define AD_BLUE_C_MASK 0x01800000
124#define AD_BLUE_C_SHIFT 23
125#define AD_GREEN_C_MASK 0x00600000
126#define AD_GREEN_C_SHIFT 21
127#define AD_RED_C_MASK 0x00180000
128#define AD_RED_C_SHIFT 19
129#define AD_PALETTE 0x00040000
130#define AD_PIXEL_S_MASK 0x00030000
131#define AD_PIXEL_S_SHIFT 16
132#define AD_COMP_3_MASK 0x0000F000
133#define AD_COMP_3_SHIFT 12
134#define AD_COMP_2_MASK 0x00000F00
135#define AD_COMP_2_SHIFT 8
136#define AD_COMP_1_MASK 0x000000F0
137#define AD_COMP_1_SHIFT 4
138#define AD_COMP_0_MASK 0x0000000F
139#define AD_COMP_0_SHIFT 0
140
141#define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
142 cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
143 (blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
144 (red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
145 (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
146 (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
124 147
125unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel, 148unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
126 int monitor_port) 149 int monitor_port)
127{ 150{
128 static const unsigned long pixelformat[][3] = { 151 static const unsigned long pixelformat[][3] = {
129 {0x88882317, 0x88083218, 0x65052119}, 152 {
130 {0x88883316, 0x88082219, 0x65053118}, 153 MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
154 MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
155 MAKE_AD(4, 0, 2, 1, 1, 5, 6, 5, 0)
156 },
157 {
158 MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8),
159 MAKE_AD(4, 0, 2, 1, 2, 8, 8, 8, 0),
160 MAKE_AD(4, 2, 0, 1, 1, 5, 6, 5, 0)
161 },
131 }; 162 };
132 unsigned int pix_fmt, arch_monitor; 163 unsigned int arch_monitor;
133 164
165 /* The DVI port is mis-wired on revision 1 of this board. */
134 arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1; 166 arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1;
135 /* DVI port for board version 0x01 */ 167
136 168 switch (bits_per_pixel) {
137 if (bits_per_pixel == 32) 169 case 32:
138 pix_fmt = pixelformat[arch_monitor][0]; 170 return pixelformat[arch_monitor][0];
139 else if (bits_per_pixel == 24) 171 case 24:
140 pix_fmt = pixelformat[arch_monitor][1]; 172 return pixelformat[arch_monitor][1];
141 else if (bits_per_pixel == 16) 173 case 16:
142 pix_fmt = pixelformat[arch_monitor][2]; 174 return pixelformat[arch_monitor][2];
143 else 175 default:
144 pix_fmt = pixelformat[1][0]; 176 pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel);
145 177 return 0;
146 return pix_fmt; 178 }
147} 179}
148 180
149void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base) 181void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
@@ -190,8 +222,7 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
190 } 222 }
191 223
192 /* Pixel Clock configuration */ 224 /* Pixel Clock configuration */
193 pr_debug("DIU: Bus Frequency = %d\n", get_busfreq()); 225 speed_ccb = fsl_get_sys_freq();
194 speed_ccb = get_busfreq();
195 226
196 /* Calculate the pixel clock with the smallest error */ 227 /* Calculate the pixel clock with the smallest error */
197 /* calculate the following in steps to avoid overflow */ 228 /* calculate the following in steps to avoid overflow */