mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
258 lines
6.9 KiB
C
258 lines
6.9 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <linux/errno.h>
|
|
#include <asm/io.h>
|
|
#include <asm/addrspace.h>
|
|
#include <asm/types.h>
|
|
#include <mach/ath79.h>
|
|
#include <mach/ar71xx_regs.h>
|
|
|
|
void _machine_restart(void)
|
|
{
|
|
void __iomem *base;
|
|
u32 reg = 0;
|
|
|
|
base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
if (soc_is_ar71xx())
|
|
reg = AR71XX_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_ar724x())
|
|
reg = AR724X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_ar913x())
|
|
reg = AR913X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_ar933x())
|
|
reg = AR933X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_ar934x())
|
|
reg = AR934X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_qca953x())
|
|
reg = QCA953X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_qca955x())
|
|
reg = QCA955X_RESET_REG_RESET_MODULE;
|
|
else if (soc_is_qca956x())
|
|
reg = QCA956X_RESET_REG_RESET_MODULE;
|
|
else
|
|
puts("Reset register not defined for this SOC\n");
|
|
|
|
if (reg)
|
|
setbits_be32(base + reg, AR71XX_RESET_FULL_CHIP);
|
|
|
|
while (1)
|
|
/* NOP */;
|
|
}
|
|
|
|
u32 ath79_get_bootstrap(void)
|
|
{
|
|
void __iomem *base;
|
|
u32 reg = 0;
|
|
|
|
base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
if (soc_is_ar933x())
|
|
reg = AR933X_RESET_REG_BOOTSTRAP;
|
|
else if (soc_is_ar934x())
|
|
reg = AR934X_RESET_REG_BOOTSTRAP;
|
|
else if (soc_is_qca953x())
|
|
reg = QCA953X_RESET_REG_BOOTSTRAP;
|
|
else if (soc_is_qca955x())
|
|
reg = QCA955X_RESET_REG_BOOTSTRAP;
|
|
else if (soc_is_qca956x())
|
|
reg = QCA956X_RESET_REG_BOOTSTRAP;
|
|
else
|
|
puts("Bootstrap register not defined for this SOC\n");
|
|
|
|
if (reg)
|
|
return readl(base + reg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int eth_init_ar933x(void)
|
|
{
|
|
void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
|
MAP_NOCACHE);
|
|
void __iomem *gregs = map_physmem(AR933X_GMAC_BASE, AR933X_GMAC_SIZE,
|
|
MAP_NOCACHE);
|
|
const u32 mask = AR933X_RESET_GE0_MAC | AR933X_RESET_GE0_MDIO |
|
|
AR933X_RESET_GE1_MAC | AR933X_RESET_GE1_MDIO |
|
|
AR933X_RESET_ETH_SWITCH |
|
|
AR933X_RESET_ETH_SWITCH_ANALOG;
|
|
|
|
/* Clear MDIO slave EN bit. */
|
|
clrbits_be32(rregs + AR933X_RESET_REG_BOOTSTRAP, BIT(17));
|
|
mdelay(10);
|
|
|
|
/* Get Atheros S26 PHY out of reset. */
|
|
clrsetbits_be32(pregs + AR933X_PLL_SWITCH_CLOCK_CONTROL_REG,
|
|
0x1f, 0x10);
|
|
mdelay(10);
|
|
|
|
setbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(10);
|
|
clrbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(10);
|
|
|
|
/* Configure AR93xx GMAC register. */
|
|
clrsetbits_be32(gregs + AR933X_GMAC_REG_ETH_CFG,
|
|
AR933X_ETH_CFG_MII_GE0_MASTER |
|
|
AR933X_ETH_CFG_MII_GE0_SLAVE,
|
|
AR933X_ETH_CFG_MII_GE0_SLAVE);
|
|
return 0;
|
|
}
|
|
|
|
static int eth_init_ar934x(void)
|
|
{
|
|
void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
|
MAP_NOCACHE);
|
|
void __iomem *gregs = map_physmem(AR934X_GMAC_BASE, AR934X_GMAC_SIZE,
|
|
MAP_NOCACHE);
|
|
const u32 mask = AR934X_RESET_GE0_MAC | AR934X_RESET_GE0_MDIO |
|
|
AR934X_RESET_GE1_MAC | AR934X_RESET_GE1_MDIO |
|
|
AR934X_RESET_ETH_SWITCH_ANALOG;
|
|
u32 reg;
|
|
|
|
reg = readl(rregs + AR934X_RESET_REG_BOOTSTRAP);
|
|
if (reg & AR934X_BOOTSTRAP_REF_CLK_40)
|
|
writel(0x570, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
|
|
else
|
|
writel(0x271, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
|
|
writel(BIT(26) | BIT(25), pregs + AR934X_PLL_ETH_XMII_CONTROL_REG);
|
|
|
|
setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(1);
|
|
clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(1);
|
|
|
|
/* Configure AR934x GMAC register. */
|
|
writel(AR934X_ETH_CFG_RGMII_GMAC0, gregs + AR934X_GMAC_REG_ETH_CFG);
|
|
return 0;
|
|
}
|
|
|
|
static int eth_init_qca953x(void)
|
|
{
|
|
void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
|
|
QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
|
|
QCA953X_RESET_ETH_SWITCH_ANALOG |
|
|
QCA953X_RESET_ETH_SWITCH;
|
|
|
|
setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(1);
|
|
clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
|
mdelay(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ath79_eth_reset(void)
|
|
{
|
|
/*
|
|
* Un-reset ethernet. DM still doesn't have any notion of reset
|
|
* framework, so we do it by hand here.
|
|
*/
|
|
if (soc_is_ar933x())
|
|
return eth_init_ar933x();
|
|
if (soc_is_ar934x())
|
|
return eth_init_ar934x();
|
|
if (soc_is_qca953x())
|
|
return eth_init_qca953x();
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
static int usb_reset_ar933x(void __iomem *reset_regs)
|
|
{
|
|
/* Ungate the USB block */
|
|
setbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
|
AR933X_RESET_USBSUS_OVERRIDE);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
|
AR933X_RESET_USB_HOST);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
|
AR933X_RESET_USB_PHY);
|
|
mdelay(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int usb_reset_ar934x(void __iomem *reset_regs)
|
|
{
|
|
/* Ungate the USB block */
|
|
setbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
|
AR934X_RESET_USBSUS_OVERRIDE);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
|
AR934X_RESET_USB_PHY);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
|
AR934X_RESET_USB_PHY_ANALOG);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
|
AR934X_RESET_USB_HOST);
|
|
mdelay(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int usb_reset_qca953x(void __iomem *reset_regs)
|
|
{
|
|
void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
|
MAP_NOCACHE);
|
|
|
|
clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
|
|
0xf00, 0x200);
|
|
mdelay(10);
|
|
|
|
/* Ungate the USB block */
|
|
setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
|
|
QCA953X_RESET_USBSUS_OVERRIDE);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
|
|
QCA953X_RESET_USB_PHY);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
|
|
QCA953X_RESET_USB_PHY_ANALOG);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
|
|
QCA953X_RESET_USB_HOST);
|
|
mdelay(1);
|
|
clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
|
|
QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
|
|
mdelay(1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ath79_usb_reset(void)
|
|
{
|
|
void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
|
|
AR71XX_USB_CTRL_SIZE,
|
|
MAP_NOCACHE);
|
|
void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
|
|
AR71XX_RESET_SIZE,
|
|
MAP_NOCACHE);
|
|
/*
|
|
* Turn on the Buff and Desc swap bits.
|
|
* NOTE: This write into an undocumented register in mandatory to
|
|
* get the USB controller operational in BigEndian mode.
|
|
*/
|
|
writel(0xf0000, usbc_regs + AR71XX_USB_CTRL_REG_CONFIG);
|
|
|
|
if (soc_is_ar933x())
|
|
return usb_reset_ar933x(reset_regs);
|
|
if (soc_is_ar934x())
|
|
return usb_reset_ar934x(reset_regs);
|
|
if (soc_is_qca953x())
|
|
return usb_reset_qca953x(reset_regs);
|
|
|
|
return -EINVAL;
|
|
}
|