layerscape: add linux 4.9 support
[openwrt/staging/wigyori.git] / target / linux / layerscape / patches-4.9 / 801-ata-support-layerscape.patch
1 From 505eb62bdb7a4cc25b13491dd5c68d0741c5d6da Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 12:21:13 +0800
4 Subject: [PATCH] ata: support layerscape
5
6 This is a integrated patch for layerscape sata support.
7
8 Signed-off-by: Tang Yuantian <Yuantian.Tang@nxp.com>
9 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
10 ---
11 drivers/ata/ahci_qoriq.c | 63 ++++++++++++++++++++++++++++++++++++++++++------
12 1 file changed, 56 insertions(+), 7 deletions(-)
13
14 diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
15 index 1eba8dff..2f30a39f 100644
16 --- a/drivers/ata/ahci_qoriq.c
17 +++ b/drivers/ata/ahci_qoriq.c
18 @@ -1,7 +1,7 @@
19 /*
20 * Freescale QorIQ AHCI SATA platform driver
21 *
22 - * Copyright 2015 Freescale, Inc.
23 + * Copyright (C) 2015 Freescale Semiconductor, Inc.
24 * Tang Yuantian <Yuantian.Tang@freescale.com>
25 *
26 * This program is free software; you can redistribute it and/or modify
27 @@ -46,23 +46,32 @@
28 #define LS1021A_AXICC_ADDR 0xC0
29
30 #define SATA_ECC_DISABLE 0x00020000
31 +#define ECC_DIS_ARMV8_CH2 0x80000000
32 +#define ECC_DIS_LS1088A 0x40000000
33
34 enum ahci_qoriq_type {
35 AHCI_LS1021A,
36 AHCI_LS1043A,
37 AHCI_LS2080A,
38 + AHCI_LS1046A,
39 + AHCI_LS1088A,
40 + AHCI_LS2088A,
41 };
42
43 struct ahci_qoriq_priv {
44 struct ccsr_ahci *reg_base;
45 enum ahci_qoriq_type type;
46 void __iomem *ecc_addr;
47 + bool is_dmacoherent;
48 };
49
50 static const struct of_device_id ahci_qoriq_of_match[] = {
51 { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
52 { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
53 { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
54 + { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
55 + { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
56 + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
57 {},
58 };
59 MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
60 @@ -154,6 +163,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
61
62 switch (qpriv->type) {
63 case AHCI_LS1021A:
64 + if (!qpriv->ecc_addr)
65 + return -EINVAL;
66 writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
67 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
68 writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
69 @@ -161,19 +172,56 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
70 writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
71 writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
72 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
73 - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
74 + if (qpriv->is_dmacoherent)
75 + writel(AHCI_PORT_AXICC_CFG,
76 + reg_base + LS1021A_AXICC_ADDR);
77 break;
78
79 case AHCI_LS1043A:
80 + if (!qpriv->ecc_addr)
81 + return -EINVAL;
82 + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
83 + qpriv->ecc_addr);
84 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
85 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
86 - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
87 + if (qpriv->is_dmacoherent)
88 + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
89 break;
90
91 case AHCI_LS2080A:
92 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
93 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
94 - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
95 + if (qpriv->is_dmacoherent)
96 + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
97 + break;
98 +
99 + case AHCI_LS1046A:
100 + if (!qpriv->ecc_addr)
101 + return -EINVAL;
102 + writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
103 + qpriv->ecc_addr);
104 + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
105 + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
106 + if (qpriv->is_dmacoherent)
107 + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
108 + break;
109 +
110 + case AHCI_LS1088A:
111 + if (!qpriv->ecc_addr)
112 + return -EINVAL;
113 + writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
114 + qpriv->ecc_addr);
115 + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
116 + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
117 + if (qpriv->is_dmacoherent)
118 + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
119 + break;
120 +
121 + case AHCI_LS2088A:
122 + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
123 + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
124 + if (qpriv->is_dmacoherent)
125 + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
126 break;
127 }
128
129 @@ -204,13 +252,14 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
130
131 qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
132
133 - if (qoriq_priv->type == AHCI_LS1021A) {
134 - res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
135 - "sata-ecc");
136 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
137 + "sata-ecc");
138 + if (res) {
139 qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
140 if (IS_ERR(qoriq_priv->ecc_addr))
141 return PTR_ERR(qoriq_priv->ecc_addr);
142 }
143 + qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
144
145 rc = ahci_platform_enable_resources(hpriv);
146 if (rc)
147 --
148 2.14.1
149