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

ts209-setup.c (8663B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * QNAP TS-109/TS-209 Board Setup
      4 *
      5 * Maintainer: Byron Bradley <byron.bbradley@gmail.com>
      6 */
      7#include <linux/gpio.h>
      8#include <linux/kernel.h>
      9#include <linux/init.h>
     10#include <linux/platform_device.h>
     11#include <linux/pci.h>
     12#include <linux/irq.h>
     13#include <linux/mtd/physmap.h>
     14#include <linux/mtd/rawnand.h>
     15#include <linux/mv643xx_eth.h>
     16#include <linux/gpio_keys.h>
     17#include <linux/input.h>
     18#include <linux/i2c.h>
     19#include <linux/serial_reg.h>
     20#include <linux/ata_platform.h>
     21#include <asm/mach-types.h>
     22#include <asm/mach/arch.h>
     23#include <asm/mach/pci.h>
     24#include "common.h"
     25#include "mpp.h"
     26#include "orion5x.h"
     27#include "tsx09-common.h"
     28
     29#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
     30#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
     31
     32/****************************************************************************
     33 * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
     34 *     partitions on the device because we want to keep compatibility with
     35 *     existing QNAP firmware.
     36 *
     37 * Layout as used by QNAP:
     38 *  [2] 0x00000000-0x00200000 : "Kernel"
     39 *  [3] 0x00200000-0x00600000 : "RootFS1"
     40 *  [4] 0x00600000-0x00700000 : "RootFS2"
     41 *  [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
     42 *  [5] 0x00760000-0x00780000 : "U-Boot Config"
     43 *  [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
     44 ***************************************************************************/
     45static struct mtd_partition qnap_ts209_partitions[] = {
     46	{
     47		.name		= "U-Boot",
     48		.size		= 0x00080000,
     49		.offset		= 0x00780000,
     50		.mask_flags	= MTD_WRITEABLE,
     51	}, {
     52		.name		= "Kernel",
     53		.size		= 0x00200000,
     54		.offset		= 0,
     55	}, {
     56		.name		= "RootFS1",
     57		.size		= 0x00400000,
     58		.offset		= 0x00200000,
     59	}, {
     60		.name		= "RootFS2",
     61		.size		= 0x00100000,
     62		.offset		= 0x00600000,
     63	}, {
     64		.name		= "U-Boot Config",
     65		.size		= 0x00020000,
     66		.offset		= 0x00760000,
     67	}, {
     68		.name		= "NAS Config",
     69		.size		= 0x00060000,
     70		.offset		= 0x00700000,
     71		.mask_flags	= MTD_WRITEABLE,
     72	},
     73};
     74
     75static struct physmap_flash_data qnap_ts209_nor_flash_data = {
     76	.width		= 1,
     77	.parts		= qnap_ts209_partitions,
     78	.nr_parts	= ARRAY_SIZE(qnap_ts209_partitions)
     79};
     80
     81static struct resource qnap_ts209_nor_flash_resource = {
     82	.flags	= IORESOURCE_MEM,
     83	.start	= QNAP_TS209_NOR_BOOT_BASE,
     84	.end	= QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
     85};
     86
     87static struct platform_device qnap_ts209_nor_flash = {
     88	.name		= "physmap-flash",
     89	.id		= 0,
     90	.dev		= {
     91		.platform_data	= &qnap_ts209_nor_flash_data,
     92	},
     93	.resource	= &qnap_ts209_nor_flash_resource,
     94	.num_resources	= 1,
     95};
     96
     97/*****************************************************************************
     98 * PCI
     99 ****************************************************************************/
    100
    101#define QNAP_TS209_PCI_SLOT0_OFFS	7
    102#define QNAP_TS209_PCI_SLOT0_IRQ_PIN	6
    103#define QNAP_TS209_PCI_SLOT1_IRQ_PIN	7
    104
    105static void __init qnap_ts209_pci_preinit(void)
    106{
    107	int pin;
    108
    109	/*
    110	 * Configure PCI GPIO IRQ pins
    111	 */
    112	pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
    113	if (gpio_request(pin, "PCI Int1") == 0) {
    114		if (gpio_direction_input(pin) == 0) {
    115			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
    116		} else {
    117			printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
    118					"set_irq_type pin %d\n", pin);
    119			gpio_free(pin);
    120		}
    121	} else {
    122		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
    123				"%d\n", pin);
    124	}
    125
    126	pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
    127	if (gpio_request(pin, "PCI Int2") == 0) {
    128		if (gpio_direction_input(pin) == 0) {
    129			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
    130		} else {
    131			printk(KERN_ERR "qnap_ts209_pci_preinit failed "
    132					"to set_irq_type pin %d\n", pin);
    133			gpio_free(pin);
    134		}
    135	} else {
    136		printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
    137				"%d\n", pin);
    138	}
    139}
    140
    141static int __init qnap_ts209_pci_map_irq(const struct pci_dev *dev, u8 slot,
    142	u8 pin)
    143{
    144	int irq;
    145
    146	/*
    147	 * Check for devices with hard-wired IRQs.
    148	 */
    149	irq = orion5x_pci_map_irq(dev, slot, pin);
    150	if (irq != -1)
    151		return irq;
    152
    153	/*
    154	 * PCI IRQs are connected via GPIOs.
    155	 */
    156	switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
    157	case 0:
    158		return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
    159	case 1:
    160		return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
    161	default:
    162		return -1;
    163	}
    164}
    165
    166static struct hw_pci qnap_ts209_pci __initdata = {
    167	.nr_controllers	= 2,
    168	.preinit	= qnap_ts209_pci_preinit,
    169	.setup		= orion5x_pci_sys_setup,
    170	.scan		= orion5x_pci_sys_scan_bus,
    171	.map_irq	= qnap_ts209_pci_map_irq,
    172};
    173
    174static int __init qnap_ts209_pci_init(void)
    175{
    176	if (machine_is_ts209())
    177		pci_common_init(&qnap_ts209_pci);
    178
    179	return 0;
    180}
    181
    182subsys_initcall(qnap_ts209_pci_init);
    183
    184/*****************************************************************************
    185 * RTC S35390A on I2C bus
    186 ****************************************************************************/
    187
    188#define TS209_RTC_GPIO	3
    189
    190static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
    191	I2C_BOARD_INFO("s35390a", 0x30),
    192	.irq	= 0,
    193};
    194
    195/****************************************************************************
    196 * GPIO Attached Keys
    197 *     Power button is attached to the PIC microcontroller
    198 ****************************************************************************/
    199
    200#define QNAP_TS209_GPIO_KEY_MEDIA	1
    201#define QNAP_TS209_GPIO_KEY_RESET	2
    202
    203static struct gpio_keys_button qnap_ts209_buttons[] = {
    204	{
    205		.code		= KEY_COPY,
    206		.gpio		= QNAP_TS209_GPIO_KEY_MEDIA,
    207		.desc		= "USB Copy Button",
    208		.active_low	= 1,
    209	}, {
    210		.code		= KEY_RESTART,
    211		.gpio		= QNAP_TS209_GPIO_KEY_RESET,
    212		.desc		= "Reset Button",
    213		.active_low	= 1,
    214	},
    215};
    216
    217static struct gpio_keys_platform_data qnap_ts209_button_data = {
    218	.buttons	= qnap_ts209_buttons,
    219	.nbuttons	= ARRAY_SIZE(qnap_ts209_buttons),
    220};
    221
    222static struct platform_device qnap_ts209_button_device = {
    223	.name		= "gpio-keys",
    224	.id		= -1,
    225	.num_resources	= 0,
    226	.dev		= {
    227		.platform_data	= &qnap_ts209_button_data,
    228	},
    229};
    230
    231/*****************************************************************************
    232 * SATA
    233 ****************************************************************************/
    234static struct mv_sata_platform_data qnap_ts209_sata_data = {
    235	.n_ports	= 2,
    236};
    237
    238/*****************************************************************************
    239
    240 * General Setup
    241 ****************************************************************************/
    242static unsigned int ts209_mpp_modes[] __initdata = {
    243	MPP0_UNUSED,
    244	MPP1_GPIO,		/* USB copy button */
    245	MPP2_GPIO,		/* Load defaults button */
    246	MPP3_GPIO,		/* GPIO RTC */
    247	MPP4_UNUSED,
    248	MPP5_UNUSED,
    249	MPP6_GPIO,		/* PCI Int A */
    250	MPP7_GPIO,		/* PCI Int B */
    251	MPP8_UNUSED,
    252	MPP9_UNUSED,
    253	MPP10_UNUSED,
    254	MPP11_UNUSED,
    255	MPP12_SATA_LED,		/* SATA 0 presence */
    256	MPP13_SATA_LED,		/* SATA 1 presence */
    257	MPP14_SATA_LED,		/* SATA 0 active */
    258	MPP15_SATA_LED,		/* SATA 1 active */
    259	MPP16_UART,		/* UART1 RXD */
    260	MPP17_UART,		/* UART1 TXD */
    261	MPP18_GPIO,		/* SW_RST */
    262	MPP19_UNUSED,
    263	0,
    264};
    265
    266static void __init qnap_ts209_init(void)
    267{
    268	/*
    269	 * Setup basic Orion functions. Need to be called early.
    270	 */
    271	orion5x_init();
    272
    273	orion5x_mpp_conf(ts209_mpp_modes);
    274
    275	/*
    276	 * MPP[20] PCI clock 0
    277	 * MPP[21] PCI clock 1
    278	 * MPP[22] USB 0 over current
    279	 * MPP[23-25] Reserved
    280	 */
    281
    282	/*
    283	 * Configure peripherals.
    284	 */
    285	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
    286				    ORION_MBUS_DEVBUS_BOOT_ATTR,
    287				    QNAP_TS209_NOR_BOOT_BASE,
    288				    QNAP_TS209_NOR_BOOT_SIZE);
    289	platform_device_register(&qnap_ts209_nor_flash);
    290
    291	orion5x_ehci0_init();
    292	orion5x_ehci1_init();
    293	qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE +
    294				 qnap_ts209_partitions[5].offset,
    295				 qnap_ts209_partitions[5].size);
    296	orion5x_eth_init(&qnap_tsx09_eth_data);
    297	orion5x_i2c_init();
    298	orion5x_sata_init(&qnap_ts209_sata_data);
    299	orion5x_uart0_init();
    300	orion5x_uart1_init();
    301	orion5x_xor_init();
    302
    303	platform_device_register(&qnap_ts209_button_device);
    304
    305	/* Get RTC IRQ and register the chip */
    306	if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) {
    307		if (gpio_direction_input(TS209_RTC_GPIO) == 0)
    308			qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO);
    309		else
    310			gpio_free(TS209_RTC_GPIO);
    311	}
    312	if (qnap_ts209_i2c_rtc.irq == 0)
    313		pr_warn("qnap_ts209_init: failed to get RTC IRQ\n");
    314	i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
    315
    316	/* register tsx09 specific power-off method */
    317	pm_power_off = qnap_tsx09_power_off;
    318}
    319
    320MACHINE_START(TS209, "QNAP TS-109/TS-209")
    321	/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
    322	.atag_offset	= 0x100,
    323	.nr_irqs	= ORION5X_NR_IRQS,
    324	.init_machine	= qnap_ts209_init,
    325	.map_io		= orion5x_map_io,
    326	.init_early	= orion5x_init_early,
    327	.init_irq	= orion5x_init_irq,
    328	.init_time	= orion5x_timer_init,
    329	.fixup		= tag_fixup_mem32,
    330	.restart	= orion5x_restart,
    331MACHINE_END