1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * arch/arm/mach-pxa/pcm990-baseboard.c
4 * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
5 *
6 * Refer
7 * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
8 * for additional hardware info
9 *
10 * Author: Juergen Kilb
11 * Created: April 05, 2005
12 * Copyright: Phytec Messtechnik GmbH
13 * e-Mail: armlinux@phytec.de
14 *
15 * based on Intel Mainstone Board
16 *
17 * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
18 */
19 #include <linux/gpio.h>
20 #include <linux/irq.h>
21 #include <linux/platform_device.h>
22 #include <linux/i2c.h>
23 #include <linux/platform_data/i2c-pxa.h>
24 #include <linux/pwm.h>
25 #include <linux/pwm_backlight.h>
26
27 #include <asm/mach/map.h>
28 #include "pxa27x.h"
29 #include <linux/platform_data/asoc-pxa.h>
30 #include <linux/platform_data/mmc-pxamci.h>
31 #include <linux/platform_data/usb-ohci-pxa27x.h>
32 #include "pcm990_baseboard.h"
33 #include <linux/platform_data/video-pxafb.h>
34
35 #include "devices.h"
36 #include "generic.h"
37
38 static unsigned long pcm990_pin_config[] __initdata = {
39 /* MMC */
40 GPIO32_MMC_CLK,
41 GPIO112_MMC_CMD,
42 GPIO92_MMC_DAT_0,
43 GPIO109_MMC_DAT_1,
44 GPIO110_MMC_DAT_2,
45 GPIO111_MMC_DAT_3,
46 /* USB */
47 GPIO88_USBH1_PWR,
48 GPIO89_USBH1_PEN,
49 /* PWM0 */
50 GPIO16_PWM0_OUT,
51
52 /* I2C */
53 GPIO117_I2C_SCL,
54 GPIO118_I2C_SDA,
55
56 /* AC97 */
57 GPIO28_AC97_BITCLK,
58 GPIO29_AC97_SDATA_IN_0,
59 GPIO30_AC97_SDATA_OUT,
60 GPIO31_AC97_SYNC,
61 };
62
63 static void __iomem *pcm990_cpld_base;
64
pcm990_cpld_readb(unsigned int reg)65 static u8 pcm990_cpld_readb(unsigned int reg)
66 {
67 return readb(pcm990_cpld_base + reg);
68 }
69
pcm990_cpld_writeb(u8 value,unsigned int reg)70 static void pcm990_cpld_writeb(u8 value, unsigned int reg)
71 {
72 writeb(value, pcm990_cpld_base + reg);
73 }
74
75 /*
76 * pcm990_lcd_power - control power supply to the LCD
77 * @on: 0 = switch off, 1 = switch on
78 *
79 * Called by the pxafb driver
80 */
81 #ifndef CONFIG_PCM990_DISPLAY_NONE
pcm990_lcd_power(int on,struct fb_var_screeninfo * var)82 static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
83 {
84 if (on) {
85 /* enable LCD-Latches
86 * power on LCD
87 */
88 pcm990_cpld_writeb(PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON,
89 PCM990_CTRL_REG3);
90 } else {
91 /* disable LCD-Latches
92 * power off LCD
93 */
94 pcm990_cpld_writeb(0, PCM990_CTRL_REG3);
95 }
96 }
97 #endif
98
99 #if defined(CONFIG_PCM990_DISPLAY_SHARP)
100 static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
101 .pixclock = 28000,
102 .xres = 640,
103 .yres = 480,
104 .bpp = 16,
105 .hsync_len = 20,
106 .left_margin = 103,
107 .right_margin = 47,
108 .vsync_len = 6,
109 .upper_margin = 28,
110 .lower_margin = 5,
111 .sync = 0,
112 .cmap_greyscale = 0,
113 };
114
115 static struct pxafb_mach_info pcm990_fbinfo __initdata = {
116 .modes = &fb_info_sharp_lq084v1dg21,
117 .num_modes = 1,
118 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
119 .pxafb_lcd_power = pcm990_lcd_power,
120 };
121 #elif defined(CONFIG_PCM990_DISPLAY_NEC)
122 struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
123 .pixclock = 39720,
124 .xres = 640,
125 .yres = 480,
126 .bpp = 16,
127 .hsync_len = 32,
128 .left_margin = 16,
129 .right_margin = 48,
130 .vsync_len = 2,
131 .upper_margin = 12,
132 .lower_margin = 17,
133 .sync = 0,
134 .cmap_greyscale = 0,
135 };
136
137 static struct pxafb_mach_info pcm990_fbinfo __initdata = {
138 .modes = &fb_info_nec_nl6448bc20_18d,
139 .num_modes = 1,
140 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
141 .pxafb_lcd_power = pcm990_lcd_power,
142 };
143 #endif
144
145 static struct pwm_lookup pcm990_pwm_lookup[] = {
146 PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
147 PWM_POLARITY_NORMAL),
148 };
149
150 static struct platform_pwm_backlight_data pcm990_backlight_data = {
151 .max_brightness = 1023,
152 .dft_brightness = 1023,
153 };
154
155 static struct platform_device pcm990_backlight_device = {
156 .name = "pwm-backlight",
157 .dev = {
158 .parent = &pxa27x_device_pwm0.dev,
159 .platform_data = &pcm990_backlight_data,
160 },
161 };
162
163 /*
164 * The PCM-990 development baseboard uses PCM-027's hardware in the
165 * following way:
166 *
167 * - LCD support is in use
168 * - GPIO16 is output for back light on/off with PWM
169 * - GPIO58 ... GPIO73 are outputs for display data
170 * - GPIO74 is output output for LCDFCLK
171 * - GPIO75 is output for LCDLCLK
172 * - GPIO76 is output for LCDPCLK
173 * - GPIO77 is output for LCDBIAS
174 * - MMC support is in use
175 * - GPIO32 is output for MMCCLK
176 * - GPIO92 is MMDAT0
177 * - GPIO109 is MMDAT1
178 * - GPIO110 is MMCS0
179 * - GPIO111 is MMCS1
180 * - GPIO112 is MMCMD
181 * - IDE/CF card is in use
182 * - GPIO48 is output /POE
183 * - GPIO49 is output /PWE
184 * - GPIO50 is output /PIOR
185 * - GPIO51 is output /PIOW
186 * - GPIO54 is output /PCE2
187 * - GPIO55 is output /PREG
188 * - GPIO56 is input /PWAIT
189 * - GPIO57 is output /PIOS16
190 * - GPIO79 is output PSKTSEL
191 * - GPIO85 is output /PCE1
192 * - FFUART is in use
193 * - GPIO34 is input FFRXD
194 * - GPIO35 is input FFCTS
195 * - GPIO36 is input FFDCD
196 * - GPIO37 is input FFDSR
197 * - GPIO38 is input FFRI
198 * - GPIO39 is output FFTXD
199 * - GPIO40 is output FFDTR
200 * - GPIO41 is output FFRTS
201 * - BTUART is in use
202 * - GPIO42 is input BTRXD
203 * - GPIO43 is output BTTXD
204 * - GPIO44 is input BTCTS
205 * - GPIO45 is output BTRTS
206 * - IRUART is in use
207 * - GPIO46 is input STDRXD
208 * - GPIO47 is output STDTXD
209 * - AC97 is in use*)
210 * - GPIO28 is input AC97CLK
211 * - GPIO29 is input AC97DatIn
212 * - GPIO30 is output AC97DatO
213 * - GPIO31 is output AC97SYNC
214 * - GPIO113 is output AC97_RESET
215 * - SSP is in use
216 * - GPIO23 is output SSPSCLK
217 * - GPIO24 is output chip select to Max7301
218 * - GPIO25 is output SSPTXD
219 * - GPIO26 is input SSPRXD
220 * - GPIO27 is input for Max7301 IRQ
221 * - GPIO53 is input SSPSYSCLK
222 * - SSP3 is in use
223 * - GPIO81 is output SSPTXD3
224 * - GPIO82 is input SSPRXD3
225 * - GPIO83 is output SSPSFRM
226 * - GPIO84 is output SSPCLK3
227 *
228 * Otherwise claimed GPIOs:
229 * GPIO1 -> IRQ from user switch
230 * GPIO9 -> IRQ from power management
231 * GPIO10 -> IRQ from WML9712 AC97 controller
232 * GPIO11 -> IRQ from IDE controller
233 * GPIO12 -> IRQ from CF controller
234 * GPIO13 -> IRQ from CF controller
235 * GPIO14 -> GPIO free
236 * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
237 * GPIO19 -> GPIO free
238 * GPIO20 -> /SDCS2
239 * GPIO21 -> /CS3 PC card socket select
240 * GPIO33 -> /CS5 network controller select
241 * GPIO78 -> /CS2 (16 bit wide data path)
242 * GPIO80 -> /CS4 (16 bit wide data path)
243 * GPIO86 -> GPIO free
244 * GPIO87 -> GPIO free
245 * GPIO90 -> LED0 on CPU module
246 * GPIO91 -> LED1 on CPI module
247 * GPIO117 -> SCL
248 * GPIO118 -> SDA
249 */
250
251 static unsigned long pcm990_irq_enabled;
252
pcm990_mask_ack_irq(struct irq_data * d)253 static void pcm990_mask_ack_irq(struct irq_data *d)
254 {
255 int pcm990_irq = (d->irq - PCM027_IRQ(0));
256
257 pcm990_irq_enabled &= ~(1 << pcm990_irq);
258
259 pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
260 }
261
pcm990_unmask_irq(struct irq_data * d)262 static void pcm990_unmask_irq(struct irq_data *d)
263 {
264 int pcm990_irq = (d->irq - PCM027_IRQ(0));
265 u8 val;
266
267 /* the irq can be acknowledged only if deasserted, so it's done here */
268
269 pcm990_irq_enabled |= (1 << pcm990_irq);
270
271 val = pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
272 val |= 1 << pcm990_irq;
273 pcm990_cpld_writeb(val, PCM990_CTRL_INTSETCLR);
274
275 pcm990_cpld_writeb(pcm990_irq_enabled, PCM990_CTRL_INTMSKENA);
276 }
277
278 static struct irq_chip pcm990_irq_chip = {
279 .irq_mask_ack = pcm990_mask_ack_irq,
280 .irq_unmask = pcm990_unmask_irq,
281 };
282
pcm990_irq_handler(struct irq_desc * desc)283 static void pcm990_irq_handler(struct irq_desc *desc)
284 {
285 unsigned int irq;
286 unsigned long pending;
287
288 pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
289 pending &= pcm990_irq_enabled;
290
291 do {
292 /* clear our parent IRQ */
293 desc->irq_data.chip->irq_ack(&desc->irq_data);
294 if (likely(pending)) {
295 irq = PCM027_IRQ(0) + __ffs(pending);
296 generic_handle_irq(irq);
297 }
298 pending = ~pcm990_cpld_readb(PCM990_CTRL_INTSETCLR);
299 pending &= pcm990_irq_enabled;
300 } while (pending);
301 }
302
pcm990_init_irq(void)303 static void __init pcm990_init_irq(void)
304 {
305 int irq;
306
307 /* setup extra PCM990 irqs */
308 for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
309 irq_set_chip_and_handler(irq, &pcm990_irq_chip,
310 handle_level_irq);
311 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
312 }
313
314 /* disable all Interrupts */
315 pcm990_cpld_writeb(0x0, PCM990_CTRL_INTMSKENA);
316 pcm990_cpld_writeb(0xff, PCM990_CTRL_INTSETCLR);
317
318 irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
319 irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
320 }
321
pcm990_mci_init(struct device * dev,irq_handler_t mci_detect_int,void * data)322 static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
323 void *data)
324 {
325 int err;
326
327 err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, 0,
328 "MMC card detect", data);
329 if (err)
330 printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
331 "card detect IRQ\n");
332
333 return err;
334 }
335
pcm990_mci_setpower(struct device * dev,unsigned int vdd)336 static int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
337 {
338 struct pxamci_platform_data *p_d = dev->platform_data;
339 u8 val;
340
341 val = pcm990_cpld_readb(PCM990_CTRL_REG5);
342
343 if ((1 << vdd) & p_d->ocr_mask)
344 val |= PCM990_CTRL_MMC2PWR;
345 else
346 val &= ~PCM990_CTRL_MMC2PWR;
347
348 pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
349 return 0;
350 }
351
pcm990_mci_exit(struct device * dev,void * data)352 static void pcm990_mci_exit(struct device *dev, void *data)
353 {
354 free_irq(PCM027_MMCDET_IRQ, data);
355 }
356
357 #define MSECS_PER_JIFFY (1000/HZ)
358
359 static struct pxamci_platform_data pcm990_mci_platform_data = {
360 .detect_delay_ms = 250,
361 .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
362 .init = pcm990_mci_init,
363 .setpower = pcm990_mci_setpower,
364 .exit = pcm990_mci_exit,
365 };
366
367 static struct pxaohci_platform_data pcm990_ohci_platform_data = {
368 .port_mode = PMM_PERPORT_MODE,
369 .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
370 .power_on_delay = 10,
371 };
372
373 /*
374 * system init for baseboard usage. Will be called by pcm027 init.
375 *
376 * Add platform devices present on this baseboard and init
377 * them from CPU side as far as required to use them later on
378 */
pcm990_baseboard_init(void)379 void __init pcm990_baseboard_init(void)
380 {
381 pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
382
383 pcm990_cpld_base = ioremap(PCM990_CTRL_PHYS, PCM990_CTRL_SIZE);
384 if (!pcm990_cpld_base) {
385 pr_err("pcm990: failed to ioremap cpld\n");
386 return;
387 }
388
389 /* register CPLD's IRQ controller */
390 pcm990_init_irq();
391
392 #ifndef CONFIG_PCM990_DISPLAY_NONE
393 pxa_set_fb_info(NULL, &pcm990_fbinfo);
394 #endif
395 pwm_add_table(pcm990_pwm_lookup, ARRAY_SIZE(pcm990_pwm_lookup));
396 platform_device_register(&pcm990_backlight_device);
397
398 /* MMC */
399 pxa_set_mci_info(&pcm990_mci_platform_data);
400
401 /* USB host */
402 pxa_set_ohci_info(&pcm990_ohci_platform_data);
403
404 pxa_set_i2c_info(NULL);
405 pxa_set_ac97_info(NULL);
406
407 printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
408 }
409