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

platform.c (6948B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2011-2016 Zhang, Keguang <keguang.zhang@gmail.com>
      4 */
      5
      6#include <linux/clk.h>
      7#include <linux/dma-mapping.h>
      8#include <linux/err.h>
      9#include <linux/mtd/partitions.h>
     10#include <linux/sizes.h>
     11#include <linux/phy.h>
     12#include <linux/serial_8250.h>
     13#include <linux/stmmac.h>
     14#include <linux/usb/ehci_pdriver.h>
     15
     16#include <platform.h>
     17#include <loongson1.h>
     18#include <cpufreq.h>
     19#include <dma.h>
     20#include <nand.h>
     21
     22/* 8250/16550 compatible UART */
     23#define LS1X_UART(_id)						\
     24	{							\
     25		.mapbase	= LS1X_UART ## _id ## _BASE,	\
     26		.irq		= LS1X_UART ## _id ## _IRQ,	\
     27		.iotype		= UPIO_MEM,			\
     28		.flags		= UPF_IOREMAP | UPF_FIXED_TYPE, \
     29		.type		= PORT_16550A,			\
     30	}
     31
     32static struct plat_serial8250_port ls1x_serial8250_pdata[] = {
     33	LS1X_UART(0),
     34	LS1X_UART(1),
     35	LS1X_UART(2),
     36	LS1X_UART(3),
     37	{},
     38};
     39
     40struct platform_device ls1x_uart_pdev = {
     41	.name		= "serial8250",
     42	.id		= PLAT8250_DEV_PLATFORM,
     43	.dev		= {
     44		.platform_data = ls1x_serial8250_pdata,
     45	},
     46};
     47
     48void __init ls1x_serial_set_uartclk(struct platform_device *pdev)
     49{
     50	struct clk *clk;
     51	struct plat_serial8250_port *p;
     52
     53	clk = clk_get(&pdev->dev, pdev->name);
     54	if (IS_ERR(clk)) {
     55		pr_err("unable to get %s clock, err=%ld",
     56		       pdev->name, PTR_ERR(clk));
     57		return;
     58	}
     59	clk_prepare_enable(clk);
     60
     61	for (p = pdev->dev.platform_data; p->flags != 0; ++p)
     62		p->uartclk = clk_get_rate(clk);
     63}
     64
     65/* CPUFreq */
     66static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = {
     67	.clk_name	= "cpu_clk",
     68	.osc_clk_name	= "osc_clk",
     69	.max_freq	= 266 * 1000,
     70	.min_freq	= 33 * 1000,
     71};
     72
     73struct platform_device ls1x_cpufreq_pdev = {
     74	.name		= "ls1x-cpufreq",
     75	.dev		= {
     76		.platform_data = &ls1x_cpufreq_pdata,
     77	},
     78};
     79
     80/* Synopsys Ethernet GMAC */
     81static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
     82	.phy_mask	= 0,
     83};
     84
     85static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
     86	.pbl		= 1,
     87};
     88
     89int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
     90{
     91	struct plat_stmmacenet_data *plat_dat = NULL;
     92	u32 val;
     93
     94	val = __raw_readl(LS1X_MUX_CTRL1);
     95
     96#if defined(CONFIG_LOONGSON1_LS1B)
     97	plat_dat = dev_get_platdata(&pdev->dev);
     98	if (plat_dat->bus_id) {
     99		__raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
    100			     GMAC1_USE_UART0, LS1X_MUX_CTRL0);
    101		switch (plat_dat->interface) {
    102		case PHY_INTERFACE_MODE_RGMII:
    103			val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
    104			break;
    105		case PHY_INTERFACE_MODE_MII:
    106			val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
    107			break;
    108		default:
    109			pr_err("unsupported mii mode %d\n",
    110			       plat_dat->interface);
    111			return -ENOTSUPP;
    112		}
    113		val &= ~GMAC1_SHUT;
    114	} else {
    115		switch (plat_dat->interface) {
    116		case PHY_INTERFACE_MODE_RGMII:
    117			val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
    118			break;
    119		case PHY_INTERFACE_MODE_MII:
    120			val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
    121			break;
    122		default:
    123			pr_err("unsupported mii mode %d\n",
    124			       plat_dat->interface);
    125			return -ENOTSUPP;
    126		}
    127		val &= ~GMAC0_SHUT;
    128	}
    129	__raw_writel(val, LS1X_MUX_CTRL1);
    130#elif defined(CONFIG_LOONGSON1_LS1C)
    131	plat_dat = dev_get_platdata(&pdev->dev);
    132
    133	val &= ~PHY_INTF_SELI;
    134	if (plat_dat->interface == PHY_INTERFACE_MODE_RMII)
    135		val |= 0x4 << PHY_INTF_SELI_SHIFT;
    136	__raw_writel(val, LS1X_MUX_CTRL1);
    137
    138	val = __raw_readl(LS1X_MUX_CTRL0);
    139	__raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0);
    140#endif
    141
    142	return 0;
    143}
    144
    145static struct plat_stmmacenet_data ls1x_eth0_pdata = {
    146	.bus_id			= 0,
    147	.phy_addr		= -1,
    148#if defined(CONFIG_LOONGSON1_LS1B)
    149	.interface		= PHY_INTERFACE_MODE_MII,
    150#elif defined(CONFIG_LOONGSON1_LS1C)
    151	.interface		= PHY_INTERFACE_MODE_RMII,
    152#endif
    153	.mdio_bus_data		= &ls1x_mdio_bus_data,
    154	.dma_cfg		= &ls1x_eth_dma_cfg,
    155	.has_gmac		= 1,
    156	.tx_coe			= 1,
    157	.rx_queues_to_use	= 1,
    158	.tx_queues_to_use	= 1,
    159	.init			= ls1x_eth_mux_init,
    160};
    161
    162static struct resource ls1x_eth0_resources[] = {
    163	[0] = {
    164		.start	= LS1X_GMAC0_BASE,
    165		.end	= LS1X_GMAC0_BASE + SZ_64K - 1,
    166		.flags	= IORESOURCE_MEM,
    167	},
    168	[1] = {
    169		.name	= "macirq",
    170		.start	= LS1X_GMAC0_IRQ,
    171		.flags	= IORESOURCE_IRQ,
    172	},
    173};
    174
    175struct platform_device ls1x_eth0_pdev = {
    176	.name		= "stmmaceth",
    177	.id		= 0,
    178	.num_resources	= ARRAY_SIZE(ls1x_eth0_resources),
    179	.resource	= ls1x_eth0_resources,
    180	.dev		= {
    181		.platform_data = &ls1x_eth0_pdata,
    182	},
    183};
    184
    185#ifdef CONFIG_LOONGSON1_LS1B
    186static struct plat_stmmacenet_data ls1x_eth1_pdata = {
    187	.bus_id			= 1,
    188	.phy_addr		= -1,
    189	.interface		= PHY_INTERFACE_MODE_MII,
    190	.mdio_bus_data		= &ls1x_mdio_bus_data,
    191	.dma_cfg		= &ls1x_eth_dma_cfg,
    192	.has_gmac		= 1,
    193	.tx_coe			= 1,
    194	.rx_queues_to_use	= 1,
    195	.tx_queues_to_use	= 1,
    196	.init			= ls1x_eth_mux_init,
    197};
    198
    199static struct resource ls1x_eth1_resources[] = {
    200	[0] = {
    201		.start	= LS1X_GMAC1_BASE,
    202		.end	= LS1X_GMAC1_BASE + SZ_64K - 1,
    203		.flags	= IORESOURCE_MEM,
    204	},
    205	[1] = {
    206		.name	= "macirq",
    207		.start	= LS1X_GMAC1_IRQ,
    208		.flags	= IORESOURCE_IRQ,
    209	},
    210};
    211
    212struct platform_device ls1x_eth1_pdev = {
    213	.name		= "stmmaceth",
    214	.id		= 1,
    215	.num_resources	= ARRAY_SIZE(ls1x_eth1_resources),
    216	.resource	= ls1x_eth1_resources,
    217	.dev		= {
    218		.platform_data = &ls1x_eth1_pdata,
    219	},
    220};
    221#endif	/* CONFIG_LOONGSON1_LS1B */
    222
    223/* GPIO */
    224static struct resource ls1x_gpio0_resources[] = {
    225	[0] = {
    226		.start	= LS1X_GPIO0_BASE,
    227		.end	= LS1X_GPIO0_BASE + SZ_4 - 1,
    228		.flags	= IORESOURCE_MEM,
    229	},
    230};
    231
    232struct platform_device ls1x_gpio0_pdev = {
    233	.name		= "ls1x-gpio",
    234	.id		= 0,
    235	.num_resources	= ARRAY_SIZE(ls1x_gpio0_resources),
    236	.resource	= ls1x_gpio0_resources,
    237};
    238
    239static struct resource ls1x_gpio1_resources[] = {
    240	[0] = {
    241		.start	= LS1X_GPIO1_BASE,
    242		.end	= LS1X_GPIO1_BASE + SZ_4 - 1,
    243		.flags	= IORESOURCE_MEM,
    244	},
    245};
    246
    247struct platform_device ls1x_gpio1_pdev = {
    248	.name		= "ls1x-gpio",
    249	.id		= 1,
    250	.num_resources	= ARRAY_SIZE(ls1x_gpio1_resources),
    251	.resource	= ls1x_gpio1_resources,
    252};
    253
    254/* USB EHCI */
    255static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
    256
    257static struct resource ls1x_ehci_resources[] = {
    258	[0] = {
    259		.start	= LS1X_EHCI_BASE,
    260		.end	= LS1X_EHCI_BASE + SZ_32K - 1,
    261		.flags	= IORESOURCE_MEM,
    262	},
    263	[1] = {
    264		.start	= LS1X_EHCI_IRQ,
    265		.flags	= IORESOURCE_IRQ,
    266	},
    267};
    268
    269static struct usb_ehci_pdata ls1x_ehci_pdata = {
    270};
    271
    272struct platform_device ls1x_ehci_pdev = {
    273	.name		= "ehci-platform",
    274	.id		= -1,
    275	.num_resources	= ARRAY_SIZE(ls1x_ehci_resources),
    276	.resource	= ls1x_ehci_resources,
    277	.dev		= {
    278		.dma_mask = &ls1x_ehci_dmamask,
    279		.platform_data = &ls1x_ehci_pdata,
    280	},
    281};
    282
    283/* Real Time Clock */
    284void __init ls1x_rtc_set_extclk(struct platform_device *pdev)
    285{
    286	u32 val = __raw_readl(LS1X_RTC_CTRL);
    287
    288	if (!(val & RTC_EXTCLK_OK))
    289		__raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL);
    290}
    291
    292struct platform_device ls1x_rtc_pdev = {
    293	.name		= "ls1x-rtc",
    294	.id		= -1,
    295};
    296
    297/* Watchdog */
    298static struct resource ls1x_wdt_resources[] = {
    299	{
    300		.start	= LS1X_WDT_BASE,
    301		.end	= LS1X_WDT_BASE + SZ_16 - 1,
    302		.flags	= IORESOURCE_MEM,
    303	},
    304};
    305
    306struct platform_device ls1x_wdt_pdev = {
    307	.name		= "ls1x-wdt",
    308	.id		= -1,
    309	.num_resources	= ARRAY_SIZE(ls1x_wdt_resources),
    310	.resource	= ls1x_wdt_resources,
    311};