Revert "ar71xx: Allow to set the RXDV, RXD, TXD, TXE delays for QCA955x"
[openwrt.git] / target / linux / ar71xx / files / arch / mips / ath79 / mach-mr18.c
1 /*
2  *  Cisco Meraki MR18 board support
3  *
4  *  Copyright (C) 2015 Chris Blake <chrisrblake93@gmail.com>
5  *  Copyright (C) 2015 Christian Lamparter <chunkeey@googlemail.com>
6  *  Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com>
7  *
8  *  Based on Cisco Meraki GPL Release r23-20150601 MR18 Device Config
9  *
10  *  This program is free software; you can redistribute it and/or modify it
11  *  under the terms of the GNU General Public License version 2 as published
12  *  by the Free Software Foundation.
13  */
14 #include <linux/platform_device.h>
15 #include <linux/ath9k_platform.h>
16 #include <linux/platform/ar934x_nfc.h>
17 #include <linux/platform_data/phy-at803x.h>
18
19 #include <asm/mach-ath79/ath79.h>
20 #include <asm/mach-ath79/ar71xx_regs.h>
21
22 #include <linux/leds-nu801.h>
23 #include <linux/pci.h>
24
25 #include "common.h"
26 #include "dev-eth.h"
27 #include "pci.h"
28 #include "dev-gpio-buttons.h"
29 #include "dev-leds-gpio.h"
30 #include "dev-nfc.h"
31 #include "dev-wmac.h"
32 #include "machtypes.h"
33
34 #define MR18_GPIO_LED_POWER_WHITE    18
35 #define MR18_GPIO_LED_POWER_ORANGE    21
36
37 #define MR18_GPIO_BTN_RESET    17
38 #define MR18_KEYS_POLL_INTERVAL    20  /* msecs */
39 #define MR18_KEYS_DEBOUNCE_INTERVAL  (3 * MR18_KEYS_POLL_INTERVAL)
40
41 #define MR18_WAN_PHYADDR    3
42
43 /* used for eth calibration */
44 #define MR18_OTP_BASE                   (AR71XX_APB_BASE + 0x130000)
45 #define MR18_OTP_SIZE                   (0x2000) /* just a guess */
46 #define MR18_OTP_MEM_0_REG              (0x0000)
47 #define MR18_OTP_INTF2_REG              (0x1008)
48 #define MR18_OTP_STATUS0_REG            (0x1018)
49 #define MR18_OTP_STATUS0_EFUSE_VALID    BIT(2)
50
51 #define MR18_OTP_STATUS1_REG            (0x101c)
52 #define MR18_OTP_LDO_CTRL_REG           (0x1024)
53 #define MR18_OTP_LDO_STATUS_REG         (0x102c)
54 #define MR18_OTP_LDO_STATUS_POWER_ON    BIT(0)
55
56 static struct gpio_led MR18_leds_gpio[] __initdata = {
57         {
58                 .name = "mr18:white:power",
59                 .gpio = MR18_GPIO_LED_POWER_WHITE,
60                 .active_low  = 1,
61         }, {
62                 .name = "mr18:orange:power",
63                 .gpio = MR18_GPIO_LED_POWER_ORANGE,
64                 .active_low  = 0,
65         },
66 };
67
68 static struct gpio_keys_button MR18_gpio_keys[] __initdata = {
69         {
70                 .desc = "reset",
71                 .type = EV_KEY,
72                 .code = KEY_RESTART,
73                 .debounce_interval = MR18_KEYS_DEBOUNCE_INTERVAL,
74                 .gpio    = MR18_GPIO_BTN_RESET,
75                 .active_low  = 1,
76         },
77 };
78
79 static struct led_nu801_template tricolor_led_template = {
80         .device_name = "mr18",
81         .name = "tricolor",
82         .num_leds = 1,
83         .cki = 11,
84         .sdi = 12,
85         .lei = -1,
86         .ndelay = 500,
87         .init_brightness = {
88                 LED_OFF,
89                 LED_OFF,
90                 LED_OFF,
91         },
92         .default_trigger = "none",
93         .led_colors = { "red", "green", "blue" },
94 };
95
96 static struct led_nu801_platform_data tricolor_led_data = {
97         .num_controllers = 1,
98         .template = &tricolor_led_template,
99 };
100
101 static struct platform_device tricolor_leds = {
102         .name = "leds-nu801",
103         .id = -1,
104         .dev.platform_data = &tricolor_led_data,
105 };
106
107 static int mr18_extract_sgmii_res_cal(void)
108 {
109         void __iomem *base;
110         unsigned int reversed_sgmii_value;
111
112         unsigned int otp_value, otp_per_val, rbias_per, read_data;
113         unsigned int rbias_pos_or_neg;
114         unsigned int sgmii_res_cal_value;
115         int res_cal_val;
116
117         base = ioremap_nocache(MR18_OTP_BASE, MR18_OTP_SIZE);
118         if (!base)
119                 return -EIO;
120
121         __raw_writel(0x7d, base + MR18_OTP_INTF2_REG);
122         __raw_writel(0x00, base + MR18_OTP_LDO_CTRL_REG);
123
124         while (__raw_readl(base + MR18_OTP_LDO_STATUS_REG) &
125                 MR18_OTP_LDO_STATUS_POWER_ON);
126
127         __raw_readl(base + MR18_OTP_MEM_0_REG + 4);
128
129         while (!(__raw_readl(base + MR18_OTP_STATUS0_REG) &
130                 MR18_OTP_STATUS0_EFUSE_VALID));
131
132         read_data = __raw_readl(base + MR18_OTP_STATUS1_REG);
133
134         iounmap(base);
135
136         if (!(read_data & 0x1fff))
137                 return -ENODEV;
138
139         if (read_data & 0x00001000)
140                 otp_value = (read_data & 0xfc0) >> 6;
141         else
142                 otp_value = read_data & 0x3f;
143
144         if (otp_value > 31) {
145                 otp_per_val = 63 - otp_value;
146                 rbias_pos_or_neg = 1;
147         } else {
148                 otp_per_val = otp_value;
149                 rbias_pos_or_neg = 0;
150         }
151
152         rbias_per = otp_per_val * 15;
153
154         if (rbias_pos_or_neg == 1)
155                 res_cal_val = (rbias_per + 34) / 21;
156         else if (rbias_per > 34)
157                 res_cal_val = -((rbias_per - 34) / 21);
158         else
159                 res_cal_val = (34 - rbias_per) / 21;
160
161         sgmii_res_cal_value = (8 + res_cal_val) & 0xf;
162
163         reversed_sgmii_value  = (sgmii_res_cal_value & 8) >> 3;
164         reversed_sgmii_value |= (sgmii_res_cal_value & 4) >> 1;
165         reversed_sgmii_value |= (sgmii_res_cal_value & 2) << 1;
166         reversed_sgmii_value |= (sgmii_res_cal_value & 1) << 3;
167         printk(KERN_INFO "SGMII cal value = 0x%x\n", reversed_sgmii_value);
168         return reversed_sgmii_value;
169 }
170
171 #define QCA955X_PLL_ETH_SGMII_SERDES_REG                0x004c
172 #define QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT        BIT(2)
173 #define QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK         BIT(1)
174 #define QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL             BIT(0)
175
176 #define QCA955X_GMAC_REG_SGMII_SERDES                   0x0018
177 #define QCA955X_SGMII_SERDES_RES_CALIBRATION            BIT(23)
178 #define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK       0xf
179 #define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT      23
180 #define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS         BIT(15)
181
182 static void mr18_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value)
183 {
184         void __iomem *ethbase, *pllbase;
185         u32 t;
186
187         ethbase = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE);
188         pllbase = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
189
190         /* To Check the locking of the SGMII PLL */
191         t = __raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES);
192         t &= ~(QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK <<
193                QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT);
194         t |= (sgmii_value & QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK) <<
195              QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT;
196         __raw_writel(t, ethbase + QCA955X_GMAC_REG_SGMII_SERDES);
197
198         __raw_writel(QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT |
199                      QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK |
200                      QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL,
201                      pllbase + QCA955X_PLL_ETH_SGMII_SERDES_REG);
202
203         ath79_device_reset_clear(QCA955X_RESET_SGMII_ANALOG);
204         ath79_device_reset_clear(QCA955X_RESET_SGMII);
205
206         while (!(__raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES) &
207                 QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS));
208
209         iounmap(ethbase);
210         iounmap(pllbase);
211 }
212
213 static struct ath9k_platform_data pci_main_wifi_data = {
214         .led_pin = -1,
215 };
216 static struct ath9k_platform_data pci_scan_wifi_data = {
217         .led_pin = -1,
218 };
219
220 static int mr18_dual_pci_plat_dev_init(struct pci_dev *dev)
221 {
222         /* The PCIE devices are attached to different busses but they
223          * both share the same slot number. Checking the PCI_SLOT vals
224          * does not work.
225          */
226         switch (dev->bus->number) {
227         case 0:
228                 dev->dev.platform_data = &pci_main_wifi_data;
229                 break;
230         case 1:
231                 dev->dev.platform_data = &pci_scan_wifi_data;
232                 break;
233         }
234
235         return 0;
236 }
237
238 static void __init mr18_setup(void)
239 {
240         int res;
241
242         /* NAND */
243         ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH);
244         ath79_register_nfc();
245
246         /* even though, the PHY is connected via RGMII,
247          * the SGMII/SERDES PLLs need to be calibrated and locked.
248          * Or else, the PHY won't be working for this platfrom.
249          *
250          * Figuring this out took such a long time, that we want to
251          * point this quirk out, before someone wants to remove it.
252          */
253         res = mr18_extract_sgmii_res_cal();
254         if (res >= 0) {
255                 /* Setup SoC Eth Config */
256                 ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN |
257                         (3 << QCA955X_ETH_CFG_RXD_DELAY_SHIFT) |
258                         (3 << QCA955X_ETH_CFG_RDV_DELAY_SHIFT));
259
260                 /* MDIO Interface */
261                 ath79_register_mdio(0, 0x0);
262
263                 mr18_setup_qca955x_eth_serdes_cal(res);
264
265                 /* GMAC0 is connected to an Atheros AR8035-A */
266                 ath79_init_mac(ath79_eth0_data.mac_addr, NULL, 0);
267                 ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
268                 ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
269                 ath79_eth0_data.phy_mask = BIT(MR18_WAN_PHYADDR);
270                 ath79_eth0_pll_data.pll_1000 = 0xa6000000;
271                 ath79_eth0_pll_data.pll_100 = 0xa0000101;
272                 ath79_eth0_pll_data.pll_10 = 0x80001313;
273                 ath79_register_eth(0);
274         } else {
275                 printk(KERN_ERR "failed to read EFUSE for ethernet cal\n");
276         }
277
278         /* LEDs and Buttons */
279         platform_device_register(&tricolor_leds);
280         ath79_register_leds_gpio(-1, ARRAY_SIZE(MR18_leds_gpio),
281                                  MR18_leds_gpio);
282         ath79_register_gpio_keys_polled(-1, MR18_KEYS_POLL_INTERVAL,
283                                         ARRAY_SIZE(MR18_gpio_keys),
284                                         MR18_gpio_keys);
285
286         /* Clear RTC reset (Needed by SoC WiFi) */
287         ath79_device_reset_clear(QCA955X_RESET_RTC);
288
289         /* WiFi */
290         ath79_register_wmac_simple();
291
292         pci_main_wifi_data.eeprom_name = "pci_wmac0.eeprom";
293         pci_scan_wifi_data.eeprom_name = "pci_wmac1.eeprom";
294         ath79_pci_set_plat_dev_init(mr18_dual_pci_plat_dev_init);
295         ath79_register_pci();
296 }
297 MIPS_MACHINE(ATH79_MACH_MR18, "MR18", "Meraki MR18", mr18_setup);