^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Broadcom SATA3 AHCI Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright © 2009-2015 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ahci_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/libata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "ahci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DRV_NAME "brcm-ahci"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SATA_TOP_CTRL_VERSION 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SATA_TOP_CTRL_BUS_CTRL 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PIODATA_ENDIAN_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ENDIAN_SWAP_NONE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ENDIAN_SWAP_FULL 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define SATA_TOP_CTRL_TP_CTRL 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SATA_TOP_CTRL_PHY_CTRL 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SATA_TOP_CTRL_PHY_CTRL_1 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SATA_TOP_CTRL_PHY_CTRL_2 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SATA_TOP_CTRL_PHY_OFFS 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SATA_TOP_MAX_PHYS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SATA_FIRST_PORT_CTRL 0x700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SATA_NEXT_PORT_CTRL_OFFSET 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* On big-endian MIPS, buses are reversed to big endian, so switch them back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DATA_ENDIAN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MMIO_ENDIAN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define BUS_CTRL_ENDIAN_CONF \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BUS_CTRL_ENDIAN_NSP_CONF \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define BUS_CTRL_ENDIAN_CONF_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) enum brcm_ahci_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) BRCM_SATA_BCM7425 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) BRCM_SATA_BCM7445,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) BRCM_SATA_NSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) BRCM_SATA_BCM7216,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) enum brcm_ahci_quirks {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct brcm_ahci_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) void __iomem *top_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u32 port_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) enum brcm_ahci_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct reset_control *rcdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline u32 brcm_sata_readreg(void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * MIPS endianness is configured by boot strap, which also reverses all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * bus endianness (i.e., big-endian CPU + big endian bus ==> native
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * endian I/O).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Other architectures (e.g., ARM) either do not support big endian, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * else leave I/O in little endian mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return __raw_readl(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return readl_relaxed(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* See brcm_sata_readreg() comments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) __raw_writel(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) writel_relaxed(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct brcm_ahci_priv *priv = hpriv->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u32 port_ctrl, host_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Enable support for ALPM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) host_caps = readl(hpriv->mmio + HOST_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (!(host_caps & HOST_CAP_ALPM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) hpriv->flags |= AHCI_HFLAG_YES_ALPM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Adjust timeout to allow PLL sufficient time to lock while waking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * up from slumber mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) i < SATA_TOP_MAX_PHYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (priv->port_mask & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) writel(0xff1003fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) (port * SATA_TOP_CTRL_PHY_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void __iomem *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* clear PHY_DEFAULT_POWER_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* reset the PHY digital logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) SATA_TOP_CTRL_2_SW_RST_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) reg |= SATA_TOP_CTRL_2_SW_RST_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) (void)brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) (port * SATA_TOP_CTRL_PHY_OFFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void __iomem *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* power-off the PHY digital logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) SATA_TOP_CTRL_2_PHY_GLOBAL_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* set PHY_DEFAULT_POWER_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) reg = brcm_sata_readreg(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) brcm_sata_writereg(reg, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (priv->port_mask & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) brcm_sata_phy_enable(priv, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (priv->port_mask & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) brcm_sata_phy_disable(priv, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct brcm_ahci_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u32 impl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) impl = readl(hpriv->mmio + HOST_PORTS_IMPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (fls(impl) > SATA_TOP_MAX_PHYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) impl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) else if (!impl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_info(priv->dev, "no ports found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return impl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void brcm_sata_init(struct brcm_ahci_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Configure endianness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) data = brcm_sata_readreg(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) data &= ~BUS_CTRL_ENDIAN_CONF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (priv->version == BRCM_SATA_NSP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) data |= BUS_CTRL_ENDIAN_NSP_CONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) data |= BUS_CTRL_ENDIAN_CONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) brcm_sata_writereg(data, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static unsigned int brcm_ahci_read_id(struct ata_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct ata_taskfile *tf, u16 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct ata_port *ap = dev->link->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct ata_host *host = ap->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct ahci_host_priv *hpriv = host->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct brcm_ahci_priv *priv = hpriv->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) void __iomem *mmio = hpriv->mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned int err_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Try to read the device ID and, if this fails, proceed with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * recovery sequence below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) err_mask = ata_do_dev_read_id(dev, tf, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (likely(!err_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return err_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Disable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ctl = readl(mmio + HOST_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ctl &= ~HOST_IRQ_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) writel(ctl, mmio + HOST_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) readl(mmio + HOST_CTL); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Perform the SATA PHY reset sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) brcm_sata_phy_disable(priv, ap->port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Reset the SATA clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ahci_platform_disable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ahci_platform_enable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Bring the PHY back on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) brcm_sata_phy_enable(priv, ap->port_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* Re-initialize and calibrate the PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) for (i = 0; i < hpriv->nports; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) rc = phy_init(hpriv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto disable_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) rc = phy_calibrate(hpriv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) phy_exit(hpriv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) goto disable_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Re-enable host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ctl = readl(mmio + HOST_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ctl |= HOST_IRQ_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) writel(ctl, mmio + HOST_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) readl(mmio + HOST_CTL); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return ata_do_dev_read_id(dev, tf, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) disable_phys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) phy_power_off(hpriv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) phy_exit(hpriv->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return AC_ERR_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void brcm_ahci_host_stop(struct ata_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct ahci_host_priv *hpriv = host->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ahci_platform_disable_resources(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static struct ata_port_operations ahci_brcm_platform_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .inherits = &ahci_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .host_stop = brcm_ahci_host_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .read_id = brcm_ahci_read_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static const struct ata_port_info ahci_brcm_port_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .link_flags = ATA_LFLAG_NO_DB_DELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .pio_mask = ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .udma_mask = ATA_UDMA6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .port_ops = &ahci_brcm_platform_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int brcm_ahci_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct ata_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct ahci_host_priv *hpriv = host->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct brcm_ahci_priv *priv = hpriv->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) brcm_sata_phys_disable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (IS_ENABLED(CONFIG_PM_SLEEP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = ahci_platform_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (priv->version != BRCM_SATA_BCM7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) reset_control_assert(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int __maybe_unused brcm_ahci_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct ata_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct ahci_host_priv *hpriv = host->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct brcm_ahci_priv *priv = hpriv->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (priv->version == BRCM_SATA_BCM7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = reset_control_reset(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = reset_control_deassert(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Make sure clocks are turned on before re-configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = ahci_platform_enable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = ahci_platform_enable_regulators(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto out_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) brcm_sata_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) brcm_sata_phys_enable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) brcm_sata_alpm_init(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Since we had to enable clocks earlier on, we cannot use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * ahci_platform_resume() as-is since a second call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * ahci_platform_enable_resources() would bump up the resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * (regulators, clocks, PHYs) count artificially so we copy the part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * after ahci_platform_enable_resources().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ret = ahci_platform_enable_phys(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) goto out_disable_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ret = ahci_platform_resume_host(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto out_disable_platform_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* We resumed so update PM runtime state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) out_disable_platform_phys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ahci_platform_disable_phys(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) out_disable_phys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) brcm_sata_phys_disable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ahci_platform_disable_regulators(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) out_disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ahci_platform_disable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static struct scsi_host_template ahci_platform_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) AHCI_SHT(DRV_NAME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static const struct of_device_id ahci_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) MODULE_DEVICE_TABLE(of, ahci_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int brcm_ahci_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) const char *reset_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct brcm_ahci_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct ahci_host_priv *hpriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!of_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) priv->version = (enum brcm_ahci_version)of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) priv->top_ctrl = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (IS_ERR(priv->top_ctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return PTR_ERR(priv->top_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Reset is optional depending on platform and named differently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (priv->version == BRCM_SATA_BCM7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) reset_name = "rescal";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) reset_name = "ahci";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) priv->rcdev = devm_reset_control_get_optional(&pdev->dev, reset_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (IS_ERR(priv->rcdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return PTR_ERR(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) hpriv = ahci_platform_get_resources(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (IS_ERR(hpriv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return PTR_ERR(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) hpriv->plat_data = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) switch (priv->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case BRCM_SATA_BCM7425:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case BRCM_SATA_NSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) hpriv->flags |= AHCI_HFLAG_NO_NCQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (priv->version == BRCM_SATA_BCM7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = reset_control_reset(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ret = reset_control_deassert(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = ahci_platform_enable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) goto out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = ahci_platform_enable_regulators(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto out_disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Must be first so as to configure endianness including that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * of the standard AHCI register space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) brcm_sata_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* Initializes priv->port_mask which is used below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) priv->port_mask = brcm_ahci_get_portmask(hpriv, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (!priv->port_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto out_disable_regulators;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* Must be done before ahci_platform_enable_phys() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) brcm_sata_phys_enable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) brcm_sata_alpm_init(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ret = ahci_platform_enable_phys(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) goto out_disable_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) &ahci_platform_sht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out_disable_platform_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dev_info(dev, "Broadcom AHCI SATA3 registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) out_disable_platform_phys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ahci_platform_disable_phys(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) out_disable_phys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) brcm_sata_phys_disable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) out_disable_regulators:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ahci_platform_disable_regulators(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) out_disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ahci_platform_disable_clks(hpriv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (priv->version != BRCM_SATA_BCM7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) reset_control_assert(priv->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int brcm_ahci_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct ata_host *host = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct ahci_host_priv *hpriv = host->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct brcm_ahci_priv *priv = hpriv->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) brcm_sata_phys_disable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = ata_platform_remove_one(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static void brcm_ahci_shutdown(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* All resources releasing happens via devres, but our device, unlike a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * proper remove is not disappearing, therefore using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * brcm_ahci_suspend() here which does explicit power management is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = brcm_ahci_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_err(&pdev->dev, "failed to shutdown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static struct platform_driver brcm_ahci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .probe = brcm_ahci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .remove = brcm_ahci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .shutdown = brcm_ahci_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .of_match_table = ahci_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .pm = &ahci_brcm_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) module_platform_driver(brcm_ahci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) MODULE_AUTHOR("Brian Norris");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) MODULE_ALIAS("platform:sata-brcmstb");