aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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