diff options
| -rw-r--r-- | drivers/ata/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/ata/ahci.c | 15 | ||||
| -rw-r--r-- | drivers/ata/ahci.h | 1 | ||||
| -rw-r--r-- | drivers/ata/ahci_imx.c | 179 | ||||
| -rw-r--r-- | drivers/ata/libahci.c | 7 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 9 |
6 files changed, 205 insertions, 8 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index c2706047337f..0033fafc470b 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -815,7 +815,7 @@ config PATA_AT32 | |||
| 815 | 815 | ||
| 816 | config PATA_AT91 | 816 | config PATA_AT91 |
| 817 | tristate "PATA support for AT91SAM9260" | 817 | tristate "PATA support for AT91SAM9260" |
| 818 | depends on ARM && ARCH_AT91 | 818 | depends on ARM && SOC_AT91SAM9 |
| 819 | help | 819 | help |
| 820 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | 820 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. |
| 821 | 821 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 71e15b73513d..60707814a84b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -1115,6 +1115,17 @@ static bool ahci_broken_online(struct pci_dev *pdev) | |||
| 1115 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); | 1115 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); |
| 1116 | } | 1116 | } |
| 1117 | 1117 | ||
| 1118 | static bool ahci_broken_devslp(struct pci_dev *pdev) | ||
| 1119 | { | ||
| 1120 | /* device with broken DEVSLP but still showing SDS capability */ | ||
| 1121 | static const struct pci_device_id ids[] = { | ||
| 1122 | { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */ | ||
| 1123 | {} | ||
| 1124 | }; | ||
| 1125 | |||
| 1126 | return pci_match_id(ids, pdev); | ||
| 1127 | } | ||
| 1128 | |||
| 1118 | #ifdef CONFIG_ATA_ACPI | 1129 | #ifdef CONFIG_ATA_ACPI |
| 1119 | static void ahci_gtf_filter_workaround(struct ata_host *host) | 1130 | static void ahci_gtf_filter_workaround(struct ata_host *host) |
| 1120 | { | 1131 | { |
| @@ -1364,6 +1375,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1364 | 1375 | ||
| 1365 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; | 1376 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; |
| 1366 | 1377 | ||
| 1378 | /* must set flag prior to save config in order to take effect */ | ||
| 1379 | if (ahci_broken_devslp(pdev)) | ||
| 1380 | hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; | ||
| 1381 | |||
| 1367 | /* save initial config */ | 1382 | /* save initial config */ |
| 1368 | ahci_pci_save_initial_config(pdev, hpriv); | 1383 | ahci_pci_save_initial_config(pdev, hpriv); |
| 1369 | 1384 | ||
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index b5eb886da226..af63c75c2001 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
| @@ -236,6 +236,7 @@ enum { | |||
| 236 | port start (wait until | 236 | port start (wait until |
| 237 | error-handling stage) */ | 237 | error-handling stage) */ |
| 238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ | 238 | AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ |
| 239 | AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ | ||
| 239 | 240 | ||
| 240 | /* ap->flags bits */ | 241 | /* ap->flags bits */ |
| 241 | 242 | ||
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 497c7abe1c7d..8befeb69eeb1 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c | |||
| @@ -29,9 +29,25 @@ | |||
| 29 | #include "ahci.h" | 29 | #include "ahci.h" |
| 30 | 30 | ||
| 31 | enum { | 31 | enum { |
| 32 | PORT_PHY_CTL = 0x178, /* Port0 PHY Control */ | 32 | /* Timer 1-ms Register */ |
| 33 | PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */ | 33 | IMX_TIMER1MS = 0x00e0, |
| 34 | HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ | 34 | /* Port0 PHY Control Register */ |
| 35 | IMX_P0PHYCR = 0x0178, | ||
| 36 | IMX_P0PHYCR_TEST_PDDQ = 1 << 20, | ||
| 37 | IMX_P0PHYCR_CR_READ = 1 << 19, | ||
| 38 | IMX_P0PHYCR_CR_WRITE = 1 << 18, | ||
| 39 | IMX_P0PHYCR_CR_CAP_DATA = 1 << 17, | ||
| 40 | IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16, | ||
| 41 | /* Port0 PHY Status Register */ | ||
| 42 | IMX_P0PHYSR = 0x017c, | ||
| 43 | IMX_P0PHYSR_CR_ACK = 1 << 18, | ||
| 44 | IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0, | ||
| 45 | /* Lane0 Output Status Register */ | ||
| 46 | IMX_LANE0_OUT_STAT = 0x2003, | ||
| 47 | IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1, | ||
| 48 | /* Clock Reset Register */ | ||
| 49 | IMX_CLOCK_RESET = 0x7f3f, | ||
| 50 | IMX_CLOCK_RESET_RESET = 1 << 0, | ||
| 35 | }; | 51 | }; |
| 36 | 52 | ||
| 37 | enum ahci_imx_type { | 53 | enum ahci_imx_type { |
| @@ -54,9 +70,149 @@ MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support | |||
| 54 | 70 | ||
| 55 | static void ahci_imx_host_stop(struct ata_host *host); | 71 | static void ahci_imx_host_stop(struct ata_host *host); |
| 56 | 72 | ||
| 73 | static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert) | ||
| 74 | { | ||
| 75 | int timeout = 10; | ||
| 76 | u32 crval; | ||
| 77 | u32 srval; | ||
| 78 | |||
| 79 | /* Assert or deassert the bit */ | ||
| 80 | crval = readl(mmio + IMX_P0PHYCR); | ||
| 81 | if (assert) | ||
| 82 | crval |= bit; | ||
| 83 | else | ||
| 84 | crval &= ~bit; | ||
| 85 | writel(crval, mmio + IMX_P0PHYCR); | ||
| 86 | |||
| 87 | /* Wait for the cr_ack signal */ | ||
| 88 | do { | ||
| 89 | srval = readl(mmio + IMX_P0PHYSR); | ||
| 90 | if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK) | ||
| 91 | break; | ||
| 92 | usleep_range(100, 200); | ||
| 93 | } while (--timeout); | ||
| 94 | |||
| 95 | return timeout ? 0 : -ETIMEDOUT; | ||
| 96 | } | ||
| 97 | |||
| 98 | static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio) | ||
| 99 | { | ||
| 100 | u32 crval = addr; | ||
| 101 | int ret; | ||
| 102 | |||
| 103 | /* Supply the address on cr_data_in */ | ||
| 104 | writel(crval, mmio + IMX_P0PHYCR); | ||
| 105 | |||
| 106 | /* Assert the cr_cap_addr signal */ | ||
| 107 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true); | ||
| 108 | if (ret) | ||
| 109 | return ret; | ||
| 110 | |||
| 111 | /* Deassert cr_cap_addr */ | ||
| 112 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false); | ||
| 113 | if (ret) | ||
| 114 | return ret; | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int imx_phy_reg_write(u16 val, void __iomem *mmio) | ||
| 120 | { | ||
| 121 | u32 crval = val; | ||
| 122 | int ret; | ||
| 123 | |||
| 124 | /* Supply the data on cr_data_in */ | ||
| 125 | writel(crval, mmio + IMX_P0PHYCR); | ||
| 126 | |||
| 127 | /* Assert the cr_cap_data signal */ | ||
| 128 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true); | ||
| 129 | if (ret) | ||
| 130 | return ret; | ||
| 131 | |||
| 132 | /* Deassert cr_cap_data */ | ||
| 133 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false); | ||
| 134 | if (ret) | ||
| 135 | return ret; | ||
| 136 | |||
| 137 | if (val & IMX_CLOCK_RESET_RESET) { | ||
| 138 | /* | ||
| 139 | * In case we're resetting the phy, it's unable to acknowledge, | ||
| 140 | * so we return immediately here. | ||
| 141 | */ | ||
| 142 | crval |= IMX_P0PHYCR_CR_WRITE; | ||
| 143 | writel(crval, mmio + IMX_P0PHYCR); | ||
| 144 | goto out; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* Assert the cr_write signal */ | ||
| 148 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true); | ||
| 149 | if (ret) | ||
| 150 | return ret; | ||
| 151 | |||
| 152 | /* Deassert cr_write */ | ||
| 153 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false); | ||
| 154 | if (ret) | ||
| 155 | return ret; | ||
| 156 | |||
| 157 | out: | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | |||
| 161 | static int imx_phy_reg_read(u16 *val, void __iomem *mmio) | ||
| 162 | { | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | /* Assert the cr_read signal */ | ||
| 166 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true); | ||
| 167 | if (ret) | ||
| 168 | return ret; | ||
| 169 | |||
| 170 | /* Capture the data from cr_data_out[] */ | ||
| 171 | *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT; | ||
| 172 | |||
| 173 | /* Deassert cr_read */ | ||
| 174 | ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false); | ||
| 175 | if (ret) | ||
| 176 | return ret; | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static int imx_sata_phy_reset(struct ahci_host_priv *hpriv) | ||
| 182 | { | ||
| 183 | void __iomem *mmio = hpriv->mmio; | ||
| 184 | int timeout = 10; | ||
| 185 | u16 val; | ||
| 186 | int ret; | ||
| 187 | |||
| 188 | /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */ | ||
| 189 | ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio); | ||
| 190 | if (ret) | ||
| 191 | return ret; | ||
| 192 | ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio); | ||
| 193 | if (ret) | ||
| 194 | return ret; | ||
| 195 | |||
| 196 | /* Wait for PHY RX_PLL to be stable */ | ||
| 197 | do { | ||
| 198 | usleep_range(100, 200); | ||
| 199 | ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio); | ||
| 200 | if (ret) | ||
| 201 | return ret; | ||
| 202 | ret = imx_phy_reg_read(&val, mmio); | ||
| 203 | if (ret) | ||
| 204 | return ret; | ||
| 205 | if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE) | ||
| 206 | break; | ||
| 207 | } while (--timeout); | ||
| 208 | |||
| 209 | return timeout ? 0 : -ETIMEDOUT; | ||
| 210 | } | ||
| 211 | |||
| 57 | static int imx_sata_enable(struct ahci_host_priv *hpriv) | 212 | static int imx_sata_enable(struct ahci_host_priv *hpriv) |
| 58 | { | 213 | { |
| 59 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; | 214 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; |
| 215 | struct device *dev = &imxpriv->ahci_pdev->dev; | ||
| 60 | int ret; | 216 | int ret; |
| 61 | 217 | ||
| 62 | if (imxpriv->no_device) | 218 | if (imxpriv->no_device) |
| @@ -101,6 +257,14 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv) | |||
| 101 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, | 257 | regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, |
| 102 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, | 258 | IMX6Q_GPR13_SATA_MPLL_CLK_EN, |
| 103 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); | 259 | IMX6Q_GPR13_SATA_MPLL_CLK_EN); |
| 260 | |||
| 261 | usleep_range(100, 200); | ||
| 262 | |||
| 263 | ret = imx_sata_phy_reset(hpriv); | ||
| 264 | if (ret) { | ||
| 265 | dev_err(dev, "failed to reset phy: %d\n", ret); | ||
| 266 | goto disable_regulator; | ||
| 267 | } | ||
| 104 | } | 268 | } |
| 105 | 269 | ||
| 106 | usleep_range(1000, 2000); | 270 | usleep_range(1000, 2000); |
| @@ -156,8 +320,8 @@ static void ahci_imx_error_handler(struct ata_port *ap) | |||
| 156 | * without full reset once the pddq mode is enabled making it | 320 | * without full reset once the pddq mode is enabled making it |
| 157 | * impossible to use as part of libata LPM. | 321 | * impossible to use as part of libata LPM. |
| 158 | */ | 322 | */ |
| 159 | reg_val = readl(mmio + PORT_PHY_CTL); | 323 | reg_val = readl(mmio + IMX_P0PHYCR); |
| 160 | writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL); | 324 | writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); |
| 161 | imx_sata_disable(hpriv); | 325 | imx_sata_disable(hpriv); |
| 162 | imxpriv->no_device = true; | 326 | imxpriv->no_device = true; |
| 163 | } | 327 | } |
| @@ -217,6 +381,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
| 217 | if (!imxpriv) | 381 | if (!imxpriv) |
| 218 | return -ENOMEM; | 382 | return -ENOMEM; |
| 219 | 383 | ||
| 384 | imxpriv->ahci_pdev = pdev; | ||
| 220 | imxpriv->no_device = false; | 385 | imxpriv->no_device = false; |
| 221 | imxpriv->first_time = true; | 386 | imxpriv->first_time = true; |
| 222 | imxpriv->type = (enum ahci_imx_type)of_id->data; | 387 | imxpriv->type = (enum ahci_imx_type)of_id->data; |
| @@ -248,7 +413,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
| 248 | 413 | ||
| 249 | /* | 414 | /* |
| 250 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, | 415 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, |
| 251 | * and IP vendor specific register HOST_TIMER1MS. | 416 | * and IP vendor specific register IMX_TIMER1MS. |
| 252 | * Configure CAP_SSS (support stagered spin up). | 417 | * Configure CAP_SSS (support stagered spin up). |
| 253 | * Implement the port0. | 418 | * Implement the port0. |
| 254 | * Get the ahb clock rate, and configure the TIMER1MS register. | 419 | * Get the ahb clock rate, and configure the TIMER1MS register. |
| @@ -265,7 +430,7 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
| 265 | } | 430 | } |
| 266 | 431 | ||
| 267 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; | 432 | reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; |
| 268 | writel(reg_val, hpriv->mmio + HOST_TIMER1MS); | 433 | writel(reg_val, hpriv->mmio + IMX_TIMER1MS); |
| 269 | 434 | ||
| 270 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0); | 435 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0); |
| 271 | if (ret) | 436 | if (ret) |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 6bd4f660b4e1..b9861453fc81 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -452,6 +452,13 @@ void ahci_save_initial_config(struct device *dev, | |||
| 452 | cap &= ~HOST_CAP_SNTF; | 452 | cap &= ~HOST_CAP_SNTF; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | if ((cap2 & HOST_CAP2_SDS) && (hpriv->flags & AHCI_HFLAG_NO_DEVSLP)) { | ||
| 456 | dev_info(dev, | ||
| 457 | "controller can't do DEVSLP, turning off\n"); | ||
| 458 | cap2 &= ~HOST_CAP2_SDS; | ||
| 459 | cap2 &= ~HOST_CAP2_SADM; | ||
| 460 | } | ||
| 461 | |||
| 455 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { | 462 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { |
| 456 | dev_info(dev, "controller can do FBS, turning on CAP_FBS\n"); | 463 | dev_info(dev, "controller can do FBS, turning on CAP_FBS\n"); |
| 457 | cap |= HOST_CAP_FBS; | 464 | cap |= HOST_CAP_FBS; |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 943cc8b83e59..ea83828bfea9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -6314,6 +6314,8 @@ int ata_host_activate(struct ata_host *host, int irq, | |||
| 6314 | static void ata_port_detach(struct ata_port *ap) | 6314 | static void ata_port_detach(struct ata_port *ap) |
| 6315 | { | 6315 | { |
| 6316 | unsigned long flags; | 6316 | unsigned long flags; |
| 6317 | struct ata_link *link; | ||
| 6318 | struct ata_device *dev; | ||
| 6317 | 6319 | ||
| 6318 | if (!ap->ops->error_handler) | 6320 | if (!ap->ops->error_handler) |
| 6319 | goto skip_eh; | 6321 | goto skip_eh; |
| @@ -6333,6 +6335,13 @@ static void ata_port_detach(struct ata_port *ap) | |||
| 6333 | cancel_delayed_work_sync(&ap->hotplug_task); | 6335 | cancel_delayed_work_sync(&ap->hotplug_task); |
| 6334 | 6336 | ||
| 6335 | skip_eh: | 6337 | skip_eh: |
| 6338 | /* clean up zpodd on port removal */ | ||
| 6339 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
| 6340 | ata_for_each_dev(dev, link, ALL) { | ||
| 6341 | if (zpodd_dev_enabled(dev)) | ||
| 6342 | zpodd_exit(dev); | ||
| 6343 | } | ||
| 6344 | } | ||
| 6336 | if (ap->pmp_link) { | 6345 | if (ap->pmp_link) { |
| 6337 | int i; | 6346 | int i; |
| 6338 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) | 6347 | for (i = 0; i < SATA_PMP_MAX_PORTS; i++) |
