Path: blob/master/arch/mips/loongson32/common/platform.c
26481 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Copyright (c) 2011-2016 Zhang, Keguang <[email protected]>3*/45#include <linux/clk.h>6#include <linux/dma-mapping.h>7#include <linux/err.h>8#include <linux/mtd/partitions.h>9#include <linux/sizes.h>10#include <linux/phy.h>11#include <linux/serial_8250.h>12#include <linux/stmmac.h>13#include <linux/usb/ehci_pdriver.h>1415#include <platform.h>16#include <loongson1.h>1718/* 8250/16550 compatible UART */19#define LS1X_UART(_id) \20{ \21.mapbase = LS1X_UART ## _id ## _BASE, \22.irq = LS1X_UART ## _id ## _IRQ, \23.iotype = UPIO_MEM, \24.flags = UPF_IOREMAP | UPF_FIXED_TYPE, \25.type = PORT_16550A, \26}2728static struct plat_serial8250_port ls1x_serial8250_pdata[] = {29LS1X_UART(0),30LS1X_UART(1),31LS1X_UART(2),32LS1X_UART(3),33{},34};3536struct platform_device ls1x_uart_pdev = {37.name = "serial8250",38.id = PLAT8250_DEV_PLATFORM,39.dev = {40.platform_data = ls1x_serial8250_pdata,41},42};4344void __init ls1x_serial_set_uartclk(struct platform_device *pdev)45{46struct clk *clk;47struct plat_serial8250_port *p;4849clk = clk_get(&pdev->dev, pdev->name);50if (IS_ERR(clk)) {51pr_err("unable to get %s clock, err=%ld",52pdev->name, PTR_ERR(clk));53return;54}55clk_prepare_enable(clk);5657for (p = pdev->dev.platform_data; p->flags != 0; ++p)58p->uartclk = clk_get_rate(clk);59}6061/* Synopsys Ethernet GMAC */62static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {63.phy_mask = 0,64};6566static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {67.pbl = 1,68};6970int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)71{72struct plat_stmmacenet_data *plat_dat = NULL;73u32 val;7475val = __raw_readl(LS1X_MUX_CTRL1);7677#if defined(CONFIG_LOONGSON1_LS1B)78plat_dat = dev_get_platdata(&pdev->dev);79if (plat_dat->bus_id) {80__raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |81GMAC1_USE_UART0, LS1X_MUX_CTRL0);82switch (plat_dat->phy_interface) {83case PHY_INTERFACE_MODE_RGMII:84val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);85break;86case PHY_INTERFACE_MODE_MII:87val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);88break;89default:90pr_err("unsupported mii mode %d\n",91plat_dat->phy_interface);92return -ENOTSUPP;93}94val &= ~GMAC1_SHUT;95} else {96switch (plat_dat->phy_interface) {97case PHY_INTERFACE_MODE_RGMII:98val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);99break;100case PHY_INTERFACE_MODE_MII:101val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);102break;103default:104pr_err("unsupported mii mode %d\n",105plat_dat->phy_interface);106return -ENOTSUPP;107}108val &= ~GMAC0_SHUT;109}110__raw_writel(val, LS1X_MUX_CTRL1);111#elif defined(CONFIG_LOONGSON1_LS1C)112plat_dat = dev_get_platdata(&pdev->dev);113114val &= ~PHY_INTF_SELI;115if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII)116val |= 0x4 << PHY_INTF_SELI_SHIFT;117__raw_writel(val, LS1X_MUX_CTRL1);118119val = __raw_readl(LS1X_MUX_CTRL0);120__raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0);121#endif122123return 0;124}125126static struct plat_stmmacenet_data ls1x_eth0_pdata = {127.bus_id = 0,128.phy_addr = -1,129#if defined(CONFIG_LOONGSON1_LS1B)130.phy_interface = PHY_INTERFACE_MODE_MII,131#elif defined(CONFIG_LOONGSON1_LS1C)132.phy_interface = PHY_INTERFACE_MODE_RMII,133#endif134.mdio_bus_data = &ls1x_mdio_bus_data,135.dma_cfg = &ls1x_eth_dma_cfg,136.has_gmac = 1,137.tx_coe = 1,138.rx_queues_to_use = 1,139.tx_queues_to_use = 1,140.init = ls1x_eth_mux_init,141};142143static struct resource ls1x_eth0_resources[] = {144[0] = {145.start = LS1X_GMAC0_BASE,146.end = LS1X_GMAC0_BASE + SZ_64K - 1,147.flags = IORESOURCE_MEM,148},149[1] = {150.name = "macirq",151.start = LS1X_GMAC0_IRQ,152.flags = IORESOURCE_IRQ,153},154};155156struct platform_device ls1x_eth0_pdev = {157.name = "stmmaceth",158.id = 0,159.num_resources = ARRAY_SIZE(ls1x_eth0_resources),160.resource = ls1x_eth0_resources,161.dev = {162.platform_data = &ls1x_eth0_pdata,163},164};165166#ifdef CONFIG_LOONGSON1_LS1B167static struct plat_stmmacenet_data ls1x_eth1_pdata = {168.bus_id = 1,169.phy_addr = -1,170.phy_interface = PHY_INTERFACE_MODE_MII,171.mdio_bus_data = &ls1x_mdio_bus_data,172.dma_cfg = &ls1x_eth_dma_cfg,173.has_gmac = 1,174.tx_coe = 1,175.rx_queues_to_use = 1,176.tx_queues_to_use = 1,177.init = ls1x_eth_mux_init,178};179180static struct resource ls1x_eth1_resources[] = {181[0] = {182.start = LS1X_GMAC1_BASE,183.end = LS1X_GMAC1_BASE + SZ_64K - 1,184.flags = IORESOURCE_MEM,185},186[1] = {187.name = "macirq",188.start = LS1X_GMAC1_IRQ,189.flags = IORESOURCE_IRQ,190},191};192193struct platform_device ls1x_eth1_pdev = {194.name = "stmmaceth",195.id = 1,196.num_resources = ARRAY_SIZE(ls1x_eth1_resources),197.resource = ls1x_eth1_resources,198.dev = {199.platform_data = &ls1x_eth1_pdata,200},201};202#endif /* CONFIG_LOONGSON1_LS1B */203204/* GPIO */205static struct resource ls1x_gpio0_resources[] = {206[0] = {207.start = LS1X_GPIO0_BASE,208.end = LS1X_GPIO0_BASE + SZ_4 - 1,209.flags = IORESOURCE_MEM,210},211};212213struct platform_device ls1x_gpio0_pdev = {214.name = "ls1x-gpio",215.id = 0,216.num_resources = ARRAY_SIZE(ls1x_gpio0_resources),217.resource = ls1x_gpio0_resources,218};219220static struct resource ls1x_gpio1_resources[] = {221[0] = {222.start = LS1X_GPIO1_BASE,223.end = LS1X_GPIO1_BASE + SZ_4 - 1,224.flags = IORESOURCE_MEM,225},226};227228struct platform_device ls1x_gpio1_pdev = {229.name = "ls1x-gpio",230.id = 1,231.num_resources = ARRAY_SIZE(ls1x_gpio1_resources),232.resource = ls1x_gpio1_resources,233};234235/* USB EHCI */236static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);237238static struct resource ls1x_ehci_resources[] = {239[0] = {240.start = LS1X_EHCI_BASE,241.end = LS1X_EHCI_BASE + SZ_32K - 1,242.flags = IORESOURCE_MEM,243},244[1] = {245.start = LS1X_EHCI_IRQ,246.flags = IORESOURCE_IRQ,247},248};249250static struct usb_ehci_pdata ls1x_ehci_pdata = {251};252253struct platform_device ls1x_ehci_pdev = {254.name = "ehci-platform",255.id = -1,256.num_resources = ARRAY_SIZE(ls1x_ehci_resources),257.resource = ls1x_ehci_resources,258.dev = {259.dma_mask = &ls1x_ehci_dmamask,260.platform_data = &ls1x_ehci_pdata,261},262};263264/* Real Time Clock */265struct platform_device ls1x_rtc_pdev = {266.name = "ls1x-rtc",267.id = -1,268};269270/* Watchdog */271static struct resource ls1x_wdt_resources[] = {272{273.start = LS1X_WDT_BASE,274.end = LS1X_WDT_BASE + SZ_16 - 1,275.flags = IORESOURCE_MEM,276},277};278279struct platform_device ls1x_wdt_pdev = {280.name = "ls1x-wdt",281.id = -1,282.num_resources = ARRAY_SIZE(ls1x_wdt_resources),283.resource = ls1x_wdt_resources,284};285286287