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

devices.c (7116B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  RouterBoard 500 Platform devices
      4 *
      5 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
      6 *  Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
      7 */
      8#include <linux/kernel.h>
      9#include <linux/export.h>
     10#include <linux/init.h>
     11#include <linux/ctype.h>
     12#include <linux/string.h>
     13#include <linux/platform_device.h>
     14#include <linux/mtd/platnand.h>
     15#include <linux/mtd/mtd.h>
     16#include <linux/gpio.h>
     17#include <linux/gpio/machine.h>
     18#include <linux/gpio_keys.h>
     19#include <linux/input.h>
     20#include <linux/serial_8250.h>
     21
     22#include <asm/bootinfo.h>
     23
     24#include <asm/mach-rc32434/rc32434.h>
     25#include <asm/mach-rc32434/dma.h>
     26#include <asm/mach-rc32434/dma_v.h>
     27#include <asm/mach-rc32434/eth.h>
     28#include <asm/mach-rc32434/rb.h>
     29#include <asm/mach-rc32434/integ.h>
     30#include <asm/mach-rc32434/gpio.h>
     31#include <asm/mach-rc32434/irq.h>
     32
     33#define ETH0_RX_DMA_ADDR  (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
     34#define ETH0_TX_DMA_ADDR  (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
     35
     36extern unsigned int idt_cpu_freq;
     37
     38static struct mpmc_device dev3;
     39
     40void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
     41{
     42	unsigned long flags;
     43
     44	spin_lock_irqsave(&dev3.lock, flags);
     45
     46	dev3.state = (dev3.state | or_mask) & ~nand_mask;
     47	writeb(dev3.state, dev3.base);
     48
     49	spin_unlock_irqrestore(&dev3.lock, flags);
     50}
     51EXPORT_SYMBOL(set_latch_u5);
     52
     53unsigned char get_latch_u5(void)
     54{
     55	return dev3.state;
     56}
     57EXPORT_SYMBOL(get_latch_u5);
     58
     59static struct resource korina_dev0_res[] = {
     60	{
     61		.name = "emac",
     62		.start = ETH0_BASE_ADDR,
     63		.end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
     64		.flags = IORESOURCE_MEM,
     65	 }, {
     66		.name = "rx",
     67		.start = ETH0_DMA_RX_IRQ,
     68		.end = ETH0_DMA_RX_IRQ,
     69		.flags = IORESOURCE_IRQ
     70	}, {
     71		.name = "tx",
     72		.start = ETH0_DMA_TX_IRQ,
     73		.end = ETH0_DMA_TX_IRQ,
     74		.flags = IORESOURCE_IRQ
     75	}, {
     76		.name = "dma_rx",
     77		.start = ETH0_RX_DMA_ADDR,
     78		.end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
     79		.flags = IORESOURCE_MEM,
     80	 }, {
     81		.name = "dma_tx",
     82		.start = ETH0_TX_DMA_ADDR,
     83		.end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
     84		.flags = IORESOURCE_MEM,
     85	 }
     86};
     87
     88static struct korina_device korina_dev0_data = {
     89	.name = "korina0",
     90	.mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee}
     91};
     92
     93static struct platform_device korina_dev0 = {
     94	.id = -1,
     95	.name = "korina",
     96	.resource = korina_dev0_res,
     97	.num_resources = ARRAY_SIZE(korina_dev0_res),
     98	.dev = {
     99		.platform_data = &korina_dev0_data.mac,
    100	}
    101};
    102
    103static struct resource cf_slot0_res[] = {
    104	{
    105		.name = "cf_membase",
    106		.flags = IORESOURCE_MEM
    107	}, {
    108		.name = "cf_irq",
    109		.start = (8 + 4 * 32 + CF_GPIO_NUM),	/* 149 */
    110		.end = (8 + 4 * 32 + CF_GPIO_NUM),
    111		.flags = IORESOURCE_IRQ
    112	}
    113};
    114
    115static struct gpiod_lookup_table cf_slot0_gpio_table = {
    116	.dev_id = "pata-rb532-cf",
    117	.table = {
    118		GPIO_LOOKUP("gpio0", CF_GPIO_NUM,
    119			    NULL, GPIO_ACTIVE_HIGH),
    120		{ },
    121	},
    122};
    123
    124static struct platform_device cf_slot0 = {
    125	.id = -1,
    126	.name = "pata-rb532-cf",
    127	.resource = cf_slot0_res,
    128	.num_resources = ARRAY_SIZE(cf_slot0_res),
    129};
    130
    131/* Resources and device for NAND */
    132static int rb532_dev_ready(struct nand_chip *chip)
    133{
    134	return gpio_get_value(GPIO_RDY);
    135}
    136
    137static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
    138{
    139	unsigned char orbits, nandbits;
    140
    141	if (ctrl & NAND_CTRL_CHANGE) {
    142		orbits = (ctrl & NAND_CLE) << 1;
    143		orbits |= (ctrl & NAND_ALE) >> 1;
    144
    145		nandbits = (~ctrl & NAND_CLE) << 1;
    146		nandbits |= (~ctrl & NAND_ALE) >> 1;
    147
    148		set_latch_u5(orbits, nandbits);
    149	}
    150	if (cmd != NAND_CMD_NONE)
    151		writeb(cmd, chip->legacy.IO_ADDR_W);
    152}
    153
    154static struct resource nand_slot0_res[] = {
    155	[0] = {
    156		.name = "nand_membase",
    157		.flags = IORESOURCE_MEM
    158	}
    159};
    160
    161static struct platform_nand_data rb532_nand_data = {
    162	.ctrl.dev_ready = rb532_dev_ready,
    163	.ctrl.cmd_ctrl	= rb532_cmd_ctrl,
    164};
    165
    166static struct platform_device nand_slot0 = {
    167	.name = "gen_nand",
    168	.id = -1,
    169	.resource = nand_slot0_res,
    170	.num_resources = ARRAY_SIZE(nand_slot0_res),
    171	.dev.platform_data = &rb532_nand_data,
    172};
    173
    174static struct mtd_partition rb532_partition_info[] = {
    175	{
    176		.name = "Routerboard NAND boot",
    177		.offset = 0,
    178		.size = 4 * 1024 * 1024,
    179	}, {
    180		.name = "rootfs",
    181		.offset = MTDPART_OFS_NXTBLK,
    182		.size = MTDPART_SIZ_FULL,
    183	}
    184};
    185
    186static struct platform_device rb532_led = {
    187	.name = "rb532-led",
    188	.id = -1,
    189};
    190
    191static struct platform_device rb532_button = {
    192	.name	= "rb532-button",
    193	.id	= -1,
    194};
    195
    196static struct resource rb532_wdt_res[] = {
    197	{
    198		.name = "rb532_wdt_res",
    199		.start = INTEG0_BASE_ADDR,
    200		.end = INTEG0_BASE_ADDR + sizeof(struct integ),
    201		.flags = IORESOURCE_MEM,
    202	}
    203};
    204
    205static struct platform_device rb532_wdt = {
    206	.name		= "rc32434_wdt",
    207	.id		= -1,
    208	.resource	= rb532_wdt_res,
    209	.num_resources	= ARRAY_SIZE(rb532_wdt_res),
    210};
    211
    212static struct plat_serial8250_port rb532_uart_res[] = {
    213	{
    214		.type           = PORT_16550A,
    215		.membase	= (char *)KSEG1ADDR(REGBASE + UART0BASE),
    216		.irq		= UART0_IRQ,
    217		.regshift	= 2,
    218		.iotype		= UPIO_MEM,
    219		.flags		= UPF_BOOT_AUTOCONF,
    220	},
    221	{
    222		.flags		= 0,
    223	}
    224};
    225
    226static struct platform_device rb532_uart = {
    227	.name		   = "serial8250",
    228	.id		   = PLAT8250_DEV_PLATFORM,
    229	.dev.platform_data = &rb532_uart_res,
    230};
    231
    232static struct platform_device *rb532_devs[] = {
    233	&korina_dev0,
    234	&nand_slot0,
    235	&cf_slot0,
    236	&rb532_led,
    237	&rb532_button,
    238	&rb532_uart,
    239	&rb532_wdt
    240};
    241
    242/* NAND definitions */
    243#define NAND_CHIP_DELAY 25
    244
    245static void __init rb532_nand_setup(void)
    246{
    247	switch (mips_machtype) {
    248	case MACH_MIKROTIK_RB532A:
    249		set_latch_u5(LO_FOFF | LO_CEX,
    250				LO_ULED | LO_ALE | LO_CLE | LO_WPX);
    251		break;
    252	default:
    253		set_latch_u5(LO_WPX | LO_FOFF | LO_CEX,
    254				LO_ULED | LO_ALE | LO_CLE);
    255		break;
    256	}
    257
    258	/* Setup NAND specific settings */
    259	rb532_nand_data.chip.nr_chips = 1;
    260	rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info);
    261	rb532_nand_data.chip.partitions = rb532_partition_info;
    262	rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
    263}
    264
    265
    266static int __init plat_setup_devices(void)
    267{
    268	/* Look for the CF card reader */
    269	if (!readl(IDT434_REG_BASE + DEV1MASK))
    270		rb532_devs[2] = NULL;	/* disable cf_slot0 at index 2 */
    271	else {
    272		cf_slot0_res[0].start =
    273		    readl(IDT434_REG_BASE + DEV1BASE);
    274		cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
    275	}
    276
    277	/* Read the NAND resources from the device controller */
    278	nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE);
    279	nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
    280
    281	/* Read and map device controller 3 */
    282	dev3.base = ioremap(readl(IDT434_REG_BASE + DEV3BASE), 1);
    283
    284	if (!dev3.base) {
    285		printk(KERN_ERR "rb532: cannot remap device controller 3\n");
    286		return -ENXIO;
    287	}
    288
    289	/* Initialise the NAND device */
    290	rb532_nand_setup();
    291
    292	/* set the uart clock to the current cpu frequency */
    293	rb532_uart_res[0].uartclk = idt_cpu_freq;
    294
    295	gpiod_add_lookup_table(&cf_slot0_gpio_table);
    296	return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
    297}
    298
    299#ifdef CONFIG_NET
    300
    301static int __init setup_kmac(char *s)
    302{
    303	printk(KERN_INFO "korina mac = %s\n", s);
    304	if (!mac_pton(s, korina_dev0_data.mac))
    305		printk(KERN_ERR "Invalid mac\n");
    306	return 1;
    307}
    308
    309__setup("kmac=", setup_kmac);
    310
    311#endif /* CONFIG_NET */
    312
    313arch_initcall(plat_setup_devices);