X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Fath79%2Fmach-mr18.c;fp=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Fath79%2Fmach-mr18.c;h=0000000000000000000000000000000000000000;hp=2d2fb6e84ccf6de791b66943f9a58d3d066e4d7e;hb=4e4ee4649553ab536225060a27fc320bf54e458c;hpb=47b2ee2d9a9a1790f9bf8a528640c333af39e4ba diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c deleted file mode 100644 index 2d2fb6e84c..0000000000 --- a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Cisco Meraki MR18 board support - * - * Copyright (C) 2015 Chris Blake - * Copyright (C) 2015 Christian Lamparter - * Copyright (C) 2015 Thomas Hebb - * - * Based on Cisco Meraki GPL Release r23-20150601 MR18 Device Config - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "common.h" -#include "dev-eth.h" -#include "pci.h" -#include "dev-gpio-buttons.h" -#include "dev-leds-gpio.h" -#include "dev-nfc.h" -#include "dev-wmac.h" -#include "machtypes.h" - -#define MR18_GPIO_LED_POWER_WHITE 18 -#define MR18_GPIO_LED_POWER_ORANGE 21 - -#define MR18_GPIO_BTN_RESET 17 -#define MR18_KEYS_POLL_INTERVAL 20 /* msecs */ -#define MR18_KEYS_DEBOUNCE_INTERVAL (3 * MR18_KEYS_POLL_INTERVAL) - -#define MR18_WAN_PHYADDR 3 - -/* used for eth calibration */ -#define MR18_OTP_BASE (AR71XX_APB_BASE + 0x130000) -#define MR18_OTP_SIZE (0x2000) /* just a guess */ -#define MR18_OTP_MEM_0_REG (0x0000) -#define MR18_OTP_INTF2_REG (0x1008) -#define MR18_OTP_STATUS0_REG (0x1018) -#define MR18_OTP_STATUS0_EFUSE_VALID BIT(2) - -#define MR18_OTP_STATUS1_REG (0x101c) -#define MR18_OTP_LDO_CTRL_REG (0x1024) -#define MR18_OTP_LDO_STATUS_REG (0x102c) -#define MR18_OTP_LDO_STATUS_POWER_ON BIT(0) - -static struct gpio_led MR18_leds_gpio[] __initdata = { - { - .name = "mr18:white:power", - .gpio = MR18_GPIO_LED_POWER_WHITE, - .active_low = 1, - }, { - .name = "mr18:orange:power", - .gpio = MR18_GPIO_LED_POWER_ORANGE, - .active_low = 0, - }, -}; - -static struct gpio_keys_button MR18_gpio_keys[] __initdata = { - { - .desc = "reset", - .type = EV_KEY, - .code = KEY_RESTART, - .debounce_interval = MR18_KEYS_DEBOUNCE_INTERVAL, - .gpio = MR18_GPIO_BTN_RESET, - .active_low = 1, - }, -}; - -static struct led_nu801_template tricolor_led_template = { - .device_name = "mr18", - .name = "tricolor", - .num_leds = 1, - .cki = 11, - .sdi = 12, - .lei = -1, - .ndelay = 500, - .init_brightness = { - LED_OFF, - LED_OFF, - LED_OFF, - }, - .default_trigger = "none", - .led_colors = { "red", "green", "blue" }, -}; - -static struct led_nu801_platform_data tricolor_led_data = { - .num_controllers = 1, - .template = &tricolor_led_template, -}; - -static struct platform_device tricolor_leds = { - .name = "leds-nu801", - .id = -1, - .dev.platform_data = &tricolor_led_data, -}; - -static int mr18_extract_sgmii_res_cal(void) -{ - void __iomem *base; - unsigned int reversed_sgmii_value; - - unsigned int otp_value, otp_per_val, rbias_per, read_data; - unsigned int rbias_pos_or_neg; - unsigned int sgmii_res_cal_value; - int res_cal_val; - - base = ioremap_nocache(MR18_OTP_BASE, MR18_OTP_SIZE); - if (!base) - return -EIO; - - __raw_writel(0x7d, base + MR18_OTP_INTF2_REG); - __raw_writel(0x00, base + MR18_OTP_LDO_CTRL_REG); - - while (__raw_readl(base + MR18_OTP_LDO_STATUS_REG) & - MR18_OTP_LDO_STATUS_POWER_ON); - - __raw_readl(base + MR18_OTP_MEM_0_REG + 4); - - while (!(__raw_readl(base + MR18_OTP_STATUS0_REG) & - MR18_OTP_STATUS0_EFUSE_VALID)); - - read_data = __raw_readl(base + MR18_OTP_STATUS1_REG); - - iounmap(base); - - if (!(read_data & 0x1fff)) - return -ENODEV; - - if (read_data & 0x00001000) - otp_value = (read_data & 0xfc0) >> 6; - else - otp_value = read_data & 0x3f; - - if (otp_value > 31) { - otp_per_val = 63 - otp_value; - rbias_pos_or_neg = 1; - } else { - otp_per_val = otp_value; - rbias_pos_or_neg = 0; - } - - rbias_per = otp_per_val * 15; - - if (rbias_pos_or_neg == 1) - res_cal_val = (rbias_per + 34) / 21; - else if (rbias_per > 34) - res_cal_val = -((rbias_per - 34) / 21); - else - res_cal_val = (34 - rbias_per) / 21; - - sgmii_res_cal_value = (8 + res_cal_val) & 0xf; - - reversed_sgmii_value = (sgmii_res_cal_value & 8) >> 3; - reversed_sgmii_value |= (sgmii_res_cal_value & 4) >> 1; - reversed_sgmii_value |= (sgmii_res_cal_value & 2) << 1; - reversed_sgmii_value |= (sgmii_res_cal_value & 1) << 3; - printk(KERN_INFO "SGMII cal value = 0x%x\n", reversed_sgmii_value); - return reversed_sgmii_value; -} - -static void mr18_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value) -{ - void __iomem *ethbase, *pllbase; - u32 t; - - ethbase = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); - pllbase = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); - - /* To Check the locking of the SGMII PLL */ - t = __raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES); - t &= ~(QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK << - QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT); - t |= (sgmii_value & QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK) << - QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT; - __raw_writel(t, ethbase + QCA955X_GMAC_REG_SGMII_SERDES); - - __raw_writel(QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT | - QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK | - QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL, - pllbase + QCA955X_PLL_ETH_SGMII_SERDES_REG); - - ath79_device_reset_clear(QCA955X_RESET_SGMII_ANALOG); - ath79_device_reset_clear(QCA955X_RESET_SGMII); - - while (!(__raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES) & - QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS)); - - iounmap(ethbase); - iounmap(pllbase); -} - -static struct ath9k_platform_data pci_main_wifi_data = { - .led_pin = -1, -}; -static struct ath9k_platform_data pci_scan_wifi_data = { - .led_pin = -1, -}; - -static int mr18_dual_pci_plat_dev_init(struct pci_dev *dev) -{ - /* The PCIE devices are attached to different busses but they - * both share the same slot number. Checking the PCI_SLOT vals - * does not work. - */ - switch (dev->bus->number) { - case 0: - dev->dev.platform_data = &pci_main_wifi_data; - break; - case 1: - dev->dev.platform_data = &pci_scan_wifi_data; - break; - } - - return 0; -} - -static void __init mr18_setup(void) -{ - int res; - - /* NAND */ - ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH); - ath79_register_nfc(); - - /* even though, the PHY is connected via RGMII, - * the SGMII/SERDES PLLs need to be calibrated and locked. - * Or else, the PHY won't be working for this platfrom. - * - * Figuring this out took such a long time, that we want to - * point this quirk out, before someone wants to remove it. - */ - res = mr18_extract_sgmii_res_cal(); - if (res >= 0) { - /* Setup SoC Eth Config */ - ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN | - (3 << QCA955X_ETH_CFG_RXD_DELAY_SHIFT) | - (3 << QCA955X_ETH_CFG_RDV_DELAY_SHIFT)); - - /* MDIO Interface */ - ath79_register_mdio(0, 0x0); - - mr18_setup_qca955x_eth_serdes_cal(res); - - /* GMAC0 is connected to an Atheros AR8035-A */ - ath79_init_mac(ath79_eth0_data.mac_addr, NULL, 0); - ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; - ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; - ath79_eth0_data.phy_mask = BIT(MR18_WAN_PHYADDR); - ath79_eth0_pll_data.pll_1000 = 0xa6000000; - ath79_eth0_pll_data.pll_100 = 0xa0000101; - ath79_eth0_pll_data.pll_10 = 0x80001313; - ath79_register_eth(0); - } else { - printk(KERN_ERR "failed to read EFUSE for ethernet cal\n"); - } - - /* LEDs and Buttons */ - platform_device_register(&tricolor_leds); - ath79_register_leds_gpio(-1, ARRAY_SIZE(MR18_leds_gpio), - MR18_leds_gpio); - ath79_register_gpio_keys_polled(-1, MR18_KEYS_POLL_INTERVAL, - ARRAY_SIZE(MR18_gpio_keys), - MR18_gpio_keys); - - /* Clear RTC reset (Needed by SoC WiFi) */ - ath79_device_reset_clear(QCA955X_RESET_RTC); - - /* WiFi */ - ath79_register_wmac_simple(); - - pci_main_wifi_data.eeprom_name = "pci_wmac0.eeprom"; - pci_scan_wifi_data.eeprom_name = "pci_wmac1.eeprom"; - ath79_pci_set_plat_dev_init(mr18_dual_pci_plat_dev_init); - ath79_register_pci(); -} -MIPS_MACHINE(ATH79_MACH_MR18, "MR18", "Meraki MR18", mr18_setup);