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

n2100.c (8144B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * arch/arm/mach-iop32x/n2100.c
      4 *
      5 * Board support code for the Thecus N2100 platform.
      6 *
      7 * Author: Rory Bolt <rorybolt@pacbell.net>
      8 * Copyright (C) 2002 Rory Bolt
      9 * Copyright 2003 (c) MontaVista, Software, Inc.
     10 * Copyright (C) 2004 Intel Corp.
     11 */
     12
     13#include <linux/mm.h>
     14#include <linux/init.h>
     15#include <linux/f75375s.h>
     16#include <linux/leds-pca9532.h>
     17#include <linux/delay.h>
     18#include <linux/kernel.h>
     19#include <linux/pci.h>
     20#include <linux/pm.h>
     21#include <linux/string.h>
     22#include <linux/serial_core.h>
     23#include <linux/serial_8250.h>
     24#include <linux/mtd/physmap.h>
     25#include <linux/i2c.h>
     26#include <linux/platform_device.h>
     27#include <linux/reboot.h>
     28#include <linux/io.h>
     29#include <linux/gpio.h>
     30#include <linux/gpio/machine.h>
     31#include <asm/irq.h>
     32#include <asm/mach/arch.h>
     33#include <asm/mach/map.h>
     34#include <asm/mach/pci.h>
     35#include <asm/mach/time.h>
     36#include <asm/mach-types.h>
     37#include <asm/page.h>
     38
     39#include "hardware.h"
     40#include "irqs.h"
     41#include "gpio-iop32x.h"
     42
     43/*
     44 * N2100 timer tick configuration.
     45 */
     46static void __init n2100_timer_init(void)
     47{
     48	/* 33.000 MHz crystal.  */
     49	iop_init_time(198000000);
     50}
     51
     52
     53/*
     54 * N2100 I/O.
     55 */
     56static struct map_desc n2100_io_desc[] __initdata = {
     57	{	/* on-board devices */
     58		.virtual	= N2100_UART,
     59		.pfn		= __phys_to_pfn(N2100_UART),
     60		.length		= 0x00100000,
     61		.type		= MT_DEVICE
     62	},
     63};
     64
     65void __init n2100_map_io(void)
     66{
     67	iop3xx_map_io();
     68	iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc));
     69}
     70
     71
     72/*
     73 * N2100 PCI.
     74 */
     75static int n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
     76{
     77	int irq;
     78
     79	if (PCI_SLOT(dev->devfn) == 1) {
     80		/* RTL8110SB #1 */
     81		irq = IRQ_IOP32X_XINT0;
     82	} else if (PCI_SLOT(dev->devfn) == 2) {
     83		/* RTL8110SB #2 */
     84		irq = IRQ_IOP32X_XINT3;
     85	} else if (PCI_SLOT(dev->devfn) == 3) {
     86		/* Sil3512 */
     87		irq = IRQ_IOP32X_XINT2;
     88	} else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) {
     89		/* VT6212 INTA */
     90		irq = IRQ_IOP32X_XINT1;
     91	} else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) {
     92		/* VT6212 INTB */
     93		irq = IRQ_IOP32X_XINT0;
     94	} else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) {
     95		/* VT6212 INTC */
     96		irq = IRQ_IOP32X_XINT2;
     97	} else if (PCI_SLOT(dev->devfn) == 5) {
     98		/* Mini-PCI slot */
     99		irq = IRQ_IOP32X_XINT3;
    100	} else {
    101		printk(KERN_ERR "n2100_pci_map_irq() called for unknown "
    102			"device PCI:%d:%d:%d\n", dev->bus->number,
    103			PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
    104		irq = -1;
    105	}
    106
    107	return irq;
    108}
    109
    110static struct hw_pci n2100_pci __initdata = {
    111	.nr_controllers = 1,
    112	.ops		= &iop3xx_ops,
    113	.setup		= iop3xx_pci_setup,
    114	.preinit	= iop3xx_pci_preinit,
    115	.map_irq	= n2100_pci_map_irq,
    116};
    117
    118/*
    119 * Both r8169 chips on the n2100 exhibit PCI parity problems.  Turn
    120 * off parity reporting for both ports so we don't get error interrupts
    121 * for them.
    122 */
    123static void n2100_fixup_r8169(struct pci_dev *dev)
    124{
    125	if (dev->bus->number == 0 &&
    126	    (dev->devfn == PCI_DEVFN(1, 0) ||
    127	     dev->devfn == PCI_DEVFN(2, 0)))
    128		pci_disable_parity(dev);
    129}
    130DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169);
    131
    132static int __init n2100_pci_init(void)
    133{
    134	if (machine_is_n2100())
    135		pci_common_init(&n2100_pci);
    136
    137	return 0;
    138}
    139
    140subsys_initcall(n2100_pci_init);
    141
    142
    143/*
    144 * N2100 machine initialisation.
    145 */
    146static struct physmap_flash_data n2100_flash_data = {
    147	.width		= 2,
    148};
    149
    150static struct resource n2100_flash_resource = {
    151	.start		= 0xf0000000,
    152	.end		= 0xf0ffffff,
    153	.flags		= IORESOURCE_MEM,
    154};
    155
    156static struct platform_device n2100_flash_device = {
    157	.name		= "physmap-flash",
    158	.id		= 0,
    159	.dev		= {
    160		.platform_data	= &n2100_flash_data,
    161	},
    162	.num_resources	= 1,
    163	.resource	= &n2100_flash_resource,
    164};
    165
    166
    167static struct plat_serial8250_port n2100_serial_port[] = {
    168	{
    169		.mapbase	= N2100_UART,
    170		.membase	= (char *)N2100_UART,
    171		.irq		= 0,
    172		.flags		= UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ,
    173		.iotype		= UPIO_MEM,
    174		.regshift	= 0,
    175		.uartclk	= 1843200,
    176	},
    177	{ },
    178};
    179
    180static struct resource n2100_uart_resource = {
    181	.start		= N2100_UART,
    182	.end		= N2100_UART + 7,
    183	.flags		= IORESOURCE_MEM,
    184};
    185
    186static struct platform_device n2100_serial_device = {
    187	.name		= "serial8250",
    188	.id		= PLAT8250_DEV_PLATFORM,
    189	.dev		= {
    190		.platform_data		= n2100_serial_port,
    191	},
    192	.num_resources	= 1,
    193	.resource	= &n2100_uart_resource,
    194};
    195
    196static struct f75375s_platform_data n2100_f75375s = {
    197	.pwm		= { 255, 255 },
    198	.pwm_enable = { 0, 0 },
    199};
    200
    201static struct pca9532_platform_data n2100_leds = {
    202	.leds = {
    203	{	.name = "n2100:red:satafail0",
    204		.state = PCA9532_OFF,
    205		.type = PCA9532_TYPE_LED,
    206	},
    207	{	.name = "n2100:red:satafail1",
    208		.state = PCA9532_OFF,
    209		.type = PCA9532_TYPE_LED,
    210	},
    211	{	.name = "n2100:blue:usb",
    212		.state = PCA9532_OFF,
    213		.type = PCA9532_TYPE_LED,
    214	},
    215	{ 	.type = PCA9532_TYPE_NONE },
    216
    217	{ 	.type = PCA9532_TYPE_NONE },
    218	{ 	.type = PCA9532_TYPE_NONE },
    219	{ 	.type = PCA9532_TYPE_NONE },
    220	{	.name = "n2100:red:usb",
    221		.state = PCA9532_OFF,
    222		.type = PCA9532_TYPE_LED,
    223	},
    224
    225	{	.type = PCA9532_TYPE_NONE }, /* power OFF gpio */
    226	{	.type = PCA9532_TYPE_NONE }, /* reset gpio */
    227	{	.type = PCA9532_TYPE_NONE },
    228	{	.type = PCA9532_TYPE_NONE },
    229
    230	{	.type = PCA9532_TYPE_NONE },
    231	{	.name = "n2100:orange:system",
    232		.state = PCA9532_OFF,
    233		.type = PCA9532_TYPE_LED,
    234	},
    235	{	.name = "n2100:red:system",
    236		.state = PCA9532_OFF,
    237		.type = PCA9532_TYPE_LED,
    238	},
    239	{	.name = "N2100 beeper"  ,
    240		.state =  PCA9532_OFF,
    241		.type = PCA9532_TYPE_N2100_BEEP,
    242	},
    243	},
    244	.psc = { 0, 0 },
    245	.pwm = { 0, 0 },
    246};
    247
    248static struct i2c_board_info __initdata n2100_i2c_devices[] = {
    249	{
    250		I2C_BOARD_INFO("rs5c372b", 0x32),
    251	},
    252	{
    253		I2C_BOARD_INFO("f75375", 0x2e),
    254		.platform_data = &n2100_f75375s,
    255	},
    256	{
    257		I2C_BOARD_INFO("pca9532", 0x60),
    258		.platform_data = &n2100_leds,
    259	},
    260};
    261
    262/*
    263 * Pull PCA9532 GPIO #8 low to power off the machine.
    264 */
    265static void n2100_power_off(void)
    266{
    267	local_irq_disable();
    268
    269	/* Start condition, I2C address of PCA9532, write transaction.  */
    270	*IOP3XX_IDBR0 = 0xc0;
    271	*IOP3XX_ICR0 = 0xe9;
    272	mdelay(1);
    273
    274	/* Write address 0x08.  */
    275	*IOP3XX_IDBR0 = 0x08;
    276	*IOP3XX_ICR0 = 0xe8;
    277	mdelay(1);
    278
    279	/* Write data 0x01, stop condition.  */
    280	*IOP3XX_IDBR0 = 0x01;
    281	*IOP3XX_ICR0 = 0xea;
    282
    283	while (1)
    284		;
    285}
    286
    287static void n2100_restart(enum reboot_mode mode, const char *cmd)
    288{
    289	int ret;
    290
    291	ret = gpio_direction_output(N2100_HARDWARE_RESET, 0);
    292	if (ret) {
    293		pr_crit("could not drive reset GPIO low\n");
    294		return;
    295	}
    296	/* Wait for reset to happen */
    297	while (1)
    298		;
    299}
    300
    301
    302static struct timer_list power_button_poll_timer;
    303
    304static void power_button_poll(struct timer_list *unused)
    305{
    306	if (gpio_get_value(N2100_POWER_BUTTON) == 0) {
    307		ctrl_alt_del();
    308		return;
    309	}
    310
    311	power_button_poll_timer.expires = jiffies + (HZ / 10);
    312	add_timer(&power_button_poll_timer);
    313}
    314
    315static int __init n2100_request_gpios(void)
    316{
    317	int ret;
    318
    319	if (!machine_is_n2100())
    320		return 0;
    321
    322	ret = gpio_request(N2100_HARDWARE_RESET, "reset");
    323	if (ret)
    324		pr_err("could not request reset GPIO\n");
    325
    326	ret = gpio_request(N2100_POWER_BUTTON, "power");
    327	if (ret)
    328		pr_err("could not request power GPIO\n");
    329	else {
    330		ret = gpio_direction_input(N2100_POWER_BUTTON);
    331		if (ret)
    332			pr_err("could not set power GPIO as input\n");
    333	}
    334	/* Set up power button poll timer */
    335	timer_setup(&power_button_poll_timer, power_button_poll, 0);
    336	power_button_poll_timer.expires = jiffies + (HZ / 10);
    337	add_timer(&power_button_poll_timer);
    338	return 0;
    339}
    340device_initcall(n2100_request_gpios);
    341
    342static void __init n2100_init_machine(void)
    343{
    344	register_iop32x_gpio();
    345	gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup);
    346	platform_device_register(&iop3xx_i2c0_device);
    347	platform_device_register(&n2100_flash_device);
    348	platform_device_register(&n2100_serial_device);
    349	platform_device_register(&iop3xx_dma_0_channel);
    350	platform_device_register(&iop3xx_dma_1_channel);
    351
    352	i2c_register_board_info(0, n2100_i2c_devices,
    353		ARRAY_SIZE(n2100_i2c_devices));
    354
    355	pm_power_off = n2100_power_off;
    356}
    357
    358MACHINE_START(N2100, "Thecus N2100")
    359	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
    360	.atag_offset	= 0x100,
    361	.nr_irqs	= IOP32X_NR_IRQS,
    362	.map_io		= n2100_map_io,
    363	.init_irq	= iop32x_init_irq,
    364	.init_time	= n2100_timer_init,
    365	.init_machine	= n2100_init_machine,
    366	.restart	= n2100_restart,
    367MACHINE_END