cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pcm990-baseboard.c (10320B)


      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
     38static 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
     63static void __iomem *pcm990_cpld_base;
     64
     65static u8 pcm990_cpld_readb(unsigned int reg)
     66{
     67	return readb(pcm990_cpld_base + reg);
     68}
     69
     70static 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
     82static 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)
    100static 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
    115static 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)
    122struct 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
    137static 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
    145static struct pwm_lookup pcm990_pwm_lookup[] = {
    146	PWM_LOOKUP("pxa27x-pwm.0", 0, "pwm-backlight.0", NULL, 78770,
    147		   PWM_POLARITY_NORMAL),
    148};
    149
    150static struct platform_pwm_backlight_data pcm990_backlight_data = {
    151	.max_brightness	= 1023,
    152	.dft_brightness	= 1023,
    153};
    154
    155static 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
    251static unsigned long pcm990_irq_enabled;
    252
    253static 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
    262static 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
    278static struct irq_chip pcm990_irq_chip = {
    279	.irq_mask_ack	= pcm990_mask_ack_irq,
    280	.irq_unmask	= pcm990_unmask_irq,
    281};
    282
    283static 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
    303static 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
    322static 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
    336static 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
    352static 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
    359static 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
    367static 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 */
    379void __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}