aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2010-10-07 05:36:43 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-10-14 16:46:27 -0400
commit2c184cd393d1410bb43ac656a6480849fe886b1d (patch)
tree79b4d627d807a976847f57d8cc7e678066741504 /arch/powerpc
parent0f9141c974b2dc29b7d1cf245bbf4685350521be (diff)
powerpc/85xx: add DIU support to the Freecale P1022DS reference board
The Freescale P1022DS has an on-chip video controller called the DIU, and a driver for this device already exists. Update the platform file for the P1022DS reference board to enable the driver, and update the defconfig for Freescale MPC85xx boards to add the driver. [Edited to resolve header add/add conflict and drop #define DEBUG. -- broonie] Signed-off-by: Timur Tabi <timur@freescale.com> Acked-by: Kumar Gala <kumar.gala@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig3
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig3
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c212
3 files changed, 216 insertions, 2 deletions
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index c3b113b2ca31..3aeb5949cfef 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -124,6 +124,9 @@ CONFIG_I2C_CPM=m
124CONFIG_I2C_MPC=y 124CONFIG_I2C_MPC=y
125# CONFIG_HWMON is not set 125# CONFIG_HWMON is not set
126CONFIG_VIDEO_OUTPUT_CONTROL=y 126CONFIG_VIDEO_OUTPUT_CONTROL=y
127CONFIG_FB=y
128CONFIG_FB_FSL_DIU=y
129# CONFIG_VGA_CONSOLE is not set
127CONFIG_SOUND=y 130CONFIG_SOUND=y
128CONFIG_SND=y 131CONFIG_SND=y
129# CONFIG_SND_SUPPORT_OLD_API is not set 132# CONFIG_SND_SUPPORT_OLD_API is not set
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index a075da2ea3fb..d62c8016f4bc 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -126,6 +126,9 @@ CONFIG_I2C_CPM=m
126CONFIG_I2C_MPC=y 126CONFIG_I2C_MPC=y
127# CONFIG_HWMON is not set 127# CONFIG_HWMON is not set
128CONFIG_VIDEO_OUTPUT_CONTROL=y 128CONFIG_VIDEO_OUTPUT_CONTROL=y
129CONFIG_FB=y
130CONFIG_FB_FSL_DIU=y
131# CONFIG_VGA_CONSOLE is not set
129CONFIG_SOUND=y 132CONFIG_SOUND=y
130CONFIG_SND=y 133CONFIG_SND=y
131# CONFIG_SND_SUPPORT_OLD_API is not set 134# CONFIG_SND_SUPPORT_OLD_API is not set
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index e1467c937450..e984d4ea351a 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -8,7 +8,6 @@
8 * Copyright 2010 Freescale Semiconductor, Inc. 8 * Copyright 2010 Freescale Semiconductor, Inc.
9 * 9 *
10 * This file is taken from the Freescale P1022DS BSP, with modifications: 10 * This file is taken from the Freescale P1022DS BSP, with modifications:
11 * 1) No DIU support (pending rewrite of DIU code)
12 * 2) No AMP support 11 * 2) No AMP support
13 * 3) No PCI endpoint support 12 * 3) No PCI endpoint support
14 * 13 *
@@ -20,12 +19,212 @@
20#include <linux/pci.h> 19#include <linux/pci.h>
21#include <linux/of_platform.h> 20#include <linux/of_platform.h>
22#include <linux/lmb.h> 21#include <linux/lmb.h>
23 22#include <linux/memblock.h>
23#include <asm/div64.h>
24#include <asm/mpic.h> 24#include <asm/mpic.h>
25#include <asm/swiotlb.h> 25#include <asm/swiotlb.h>
26 26
27#include <sysdev/fsl_soc.h> 27#include <sysdev/fsl_soc.h>
28#include <sysdev/fsl_pci.h> 28#include <sysdev/fsl_pci.h>
29#include <asm/fsl_guts.h>
30
31#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
32
33/*
34 * Board-specific initialization of the DIU. This code should probably be
35 * executed when the DIU is opened, rather than in arch code, but the DIU
36 * driver does not have a mechanism for this (yet).
37 *
38 * This is especially problematic on the P1022DS because the local bus (eLBC)
39 * and the DIU video signals share the same pins, which means that enabling the
40 * DIU will disable access to NOR flash.
41 */
42
43/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */
44#define CLKDVDR_PXCKEN 0x80000000
45#define CLKDVDR_PXCKINV 0x10000000
46#define CLKDVDR_PXCKDLY 0x06000000
47#define CLKDVDR_PXCLK_MASK 0x00FF0000
48
49/* Some ngPIXIS register definitions */
50#define PX_BRDCFG1_DVIEN 0x80
51#define PX_BRDCFG1_DFPEN 0x40
52#define PX_BRDCFG1_BACKLIGHT 0x20
53#define PX_BRDCFG1_DDCEN 0x10
54
55/*
56 * DIU Area Descriptor
57 *
58 * Note that we need to byte-swap the value before it's written to the AD
59 * register. So even though the registers don't look like they're in the same
60 * bit positions as they are on the MPC8610, the same value is written to the
61 * AD register on the MPC8610 and on the P1022.
62 */
63#define AD_BYTE_F 0x10000000
64#define AD_ALPHA_C_MASK 0x0E000000
65#define AD_ALPHA_C_SHIFT 25
66#define AD_BLUE_C_MASK 0x01800000
67#define AD_BLUE_C_SHIFT 23
68#define AD_GREEN_C_MASK 0x00600000
69#define AD_GREEN_C_SHIFT 21
70#define AD_RED_C_MASK 0x00180000
71#define AD_RED_C_SHIFT 19
72#define AD_PALETTE 0x00040000
73#define AD_PIXEL_S_MASK 0x00030000
74#define AD_PIXEL_S_SHIFT 16
75#define AD_COMP_3_MASK 0x0000F000
76#define AD_COMP_3_SHIFT 12
77#define AD_COMP_2_MASK 0x00000F00
78#define AD_COMP_2_SHIFT 8
79#define AD_COMP_1_MASK 0x000000F0
80#define AD_COMP_1_SHIFT 4
81#define AD_COMP_0_MASK 0x0000000F
82#define AD_COMP_0_SHIFT 0
83
84#define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
85 cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
86 (blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
87 (red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
88 (c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
89 (c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
90
91/**
92 * p1022ds_get_pixel_format: return the Area Descriptor for a given pixel depth
93 *
94 * The Area Descriptor is a 32-bit value that determine which bits in each
95 * pixel are to be used for each color.
96 */
97static unsigned int p1022ds_get_pixel_format(unsigned int bits_per_pixel,
98 int monitor_port)
99{
100 switch (bits_per_pixel) {
101 case 32:
102 /* 0x88883316 */
103 return MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8);
104 case 24:
105 /* 0x88082219 */
106 return MAKE_AD(4, 0, 1, 2, 2, 0, 8, 8, 8);
107 case 16:
108 /* 0x65053118 */
109 return MAKE_AD(4, 2, 1, 0, 1, 5, 6, 5, 0);
110 default:
111 pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel);
112 return 0;
113 }
114}
115
116/**
117 * p1022ds_set_gamma_table: update the gamma table, if necessary
118 *
119 * On some boards, the gamma table for some ports may need to be modified.
120 * This is not the case on the P1022DS, so we do nothing.
121*/
122static void p1022ds_set_gamma_table(int monitor_port, char *gamma_table_base)
123{
124}
125
126/**
127 * p1022ds_set_monitor_port: switch the output to a different monitor port
128 *
129 */
130static void p1022ds_set_monitor_port(int monitor_port)
131{
132 struct device_node *pixis_node;
133 u8 __iomem *brdcfg1;
134
135 pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis");
136 if (!pixis_node) {
137 pr_err("p1022ds: missing ngPIXIS node\n");
138 return;
139 }
140
141 brdcfg1 = of_iomap(pixis_node, 0);
142 if (!brdcfg1) {
143 pr_err("p1022ds: could not map ngPIXIS registers\n");
144 return;
145 }
146 brdcfg1 += 9; /* BRDCFG1 is at offset 9 in the ngPIXIS */
147
148 switch (monitor_port) {
149 case 0: /* DVI */
150 /* Enable the DVI port, disable the DFP and the backlight */
151 clrsetbits_8(brdcfg1, PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT,
152 PX_BRDCFG1_DVIEN);
153 break;
154 case 1: /* Single link LVDS */
155 /* Enable the DFP port, disable the DVI and the backlight */
156 clrsetbits_8(brdcfg1, PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT,
157 PX_BRDCFG1_DFPEN);
158 break;
159 default:
160 pr_err("p1022ds: unsupported monitor port %i\n", monitor_port);
161 }
162}
163
164/**
165 * p1022ds_set_pixel_clock: program the DIU's clock
166 *
167 * @pixclock: the wavelength, in picoseconds, of the clock
168 */
169void p1022ds_set_pixel_clock(unsigned int pixclock)
170{
171 struct device_node *guts_np = NULL;
172 struct ccsr_guts_85xx __iomem *guts;
173 unsigned long freq;
174 u64 temp;
175 u32 pxclk;
176
177 /* Map the global utilities registers. */
178 guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
179 if (!guts_np) {
180 pr_err("p1022ds: missing global utilties device node\n");
181 return;
182 }
183
184 guts = of_iomap(guts_np, 0);
185 of_node_put(guts_np);
186 if (!guts) {
187 pr_err("p1022ds: could not map global utilties device\n");
188 return;
189 }
190
191 /* Convert pixclock from a wavelength to a frequency */
192 temp = 1000000000000ULL;
193 do_div(temp, pixclock);
194 freq = temp;
195
196 /* pixclk is the ratio of the platform clock to the pixel clock */
197 pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
198
199 /* Disable the pixel clock, and set it to non-inverted and no delay */
200 clrbits32(&guts->clkdvdr,
201 CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
202
203 /* Enable the clock and set the pxclk */
204 setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
205}
206
207/**
208 * p1022ds_show_monitor_port: show the current monitor
209 *
210 * This function returns a string indicating whether the current monitor is
211 * set to DVI or LVDS.
212 */
213ssize_t p1022ds_show_monitor_port(int monitor_port, char *buf)
214{
215 return sprintf(buf, "%c0 - DVI\n%c1 - Single link LVDS\n",
216 monitor_port == 0 ? '*' : ' ', monitor_port == 1 ? '*' : ' ');
217}
218
219/**
220 * p1022ds_set_sysfs_monitor_port: set the monitor port for sysfs
221 */
222int p1022ds_set_sysfs_monitor_port(int val)
223{
224 return val < 2 ? val : 0;
225}
226
227#endif
29 228
30void __init p1022_ds_pic_init(void) 229void __init p1022_ds_pic_init(void)
31{ 230{
@@ -92,6 +291,15 @@ static void __init p1022_ds_setup_arch(void)
92 } 291 }
93#endif 292#endif
94 293
294#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
295 diu_ops.get_pixel_format = p1022ds_get_pixel_format;
296 diu_ops.set_gamma_table = p1022ds_set_gamma_table;
297 diu_ops.set_monitor_port = p1022ds_set_monitor_port;
298 diu_ops.set_pixel_clock = p1022ds_set_pixel_clock;
299 diu_ops.show_monitor_port = p1022ds_show_monitor_port;
300 diu_ops.set_sysfs_monitor_port = p1022ds_set_sysfs_monitor_port;
301#endif
302
95#ifdef CONFIG_SMP 303#ifdef CONFIG_SMP
96 mpc85xx_smp_init(); 304 mpc85xx_smp_init();
97#endif 305#endif