diff options
author | Shawn Lin <shawn.lin@rock-chips.com> | 2016-11-23 20:54:20 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-12-07 16:06:20 -0500 |
commit | 9e663d3f11ee34dfe92dcea98992151cae55e1ea (patch) | |
tree | 04c8f3c86e323498ae433a85a7de9b40ab8dd134 | |
parent | f37500b8aac47b436fe3fe3e63b7169f8eff190d (diff) |
PCI: rockchip: Split out rockchip_cfg_atu()
Split out a new function, rockchip_cfg_atu(), in order to re-configure the
ATU when missing these information after wakeup from S3.
[bhelgaas: add "dev" temporary, return 0 when known]
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Brian Norris <briannorris@chromium.org>
-rw-r--r-- | drivers/pci/host/pcie-rockchip.c | 104 |
1 files changed, 55 insertions, 49 deletions
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index 989642761877..89c219d935b5 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c | |||
@@ -208,6 +208,11 @@ struct rockchip_pcie { | |||
208 | int link_gen; | 208 | int link_gen; |
209 | struct device *dev; | 209 | struct device *dev; |
210 | struct irq_domain *irq_domain; | 210 | struct irq_domain *irq_domain; |
211 | u32 io_size; | ||
212 | int offset; | ||
213 | phys_addr_t io_bus_addr; | ||
214 | u32 mem_size; | ||
215 | phys_addr_t mem_bus_addr; | ||
211 | }; | 216 | }; |
212 | 217 | ||
213 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) | 218 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) |
@@ -1140,6 +1145,50 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip, | |||
1140 | return 0; | 1145 | return 0; |
1141 | } | 1146 | } |
1142 | 1147 | ||
1148 | static int rockchip_cfg_atu(struct rockchip_pcie *rockchip) | ||
1149 | { | ||
1150 | struct device *dev = rockchip->dev; | ||
1151 | int offset; | ||
1152 | int err; | ||
1153 | int reg_no; | ||
1154 | |||
1155 | for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) { | ||
1156 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1157 | AXI_WRAPPER_MEM_WRITE, | ||
1158 | 20 - 1, | ||
1159 | rockchip->mem_bus_addr + | ||
1160 | (reg_no << 20), | ||
1161 | 0); | ||
1162 | if (err) { | ||
1163 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1164 | return err; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1169 | if (err) { | ||
1170 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1171 | return err; | ||
1172 | } | ||
1173 | |||
1174 | offset = rockchip->mem_size >> 20; | ||
1175 | for (reg_no = 0; reg_no < (rockchip->io_size >> 20); reg_no++) { | ||
1176 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1177 | reg_no + 1 + offset, | ||
1178 | AXI_WRAPPER_IO_WRITE, | ||
1179 | 20 - 1, | ||
1180 | rockchip->io_bus_addr + | ||
1181 | (reg_no << 20), | ||
1182 | 0); | ||
1183 | if (err) { | ||
1184 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1185 | return err; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1143 | static int rockchip_pcie_probe(struct platform_device *pdev) | 1192 | static int rockchip_pcie_probe(struct platform_device *pdev) |
1144 | { | 1193 | { |
1145 | struct rockchip_pcie *rockchip; | 1194 | struct rockchip_pcie *rockchip; |
@@ -1149,13 +1198,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1149 | resource_size_t io_base; | 1198 | resource_size_t io_base; |
1150 | struct resource *mem; | 1199 | struct resource *mem; |
1151 | struct resource *io; | 1200 | struct resource *io; |
1152 | phys_addr_t io_bus_addr = 0; | ||
1153 | u32 io_size; | ||
1154 | phys_addr_t mem_bus_addr = 0; | ||
1155 | u32 mem_size = 0; | ||
1156 | int reg_no; | ||
1157 | int err; | 1201 | int err; |
1158 | int offset; | ||
1159 | 1202 | ||
1160 | LIST_HEAD(res); | 1203 | LIST_HEAD(res); |
1161 | 1204 | ||
@@ -1222,14 +1265,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1222 | goto err_vpcie; | 1265 | goto err_vpcie; |
1223 | 1266 | ||
1224 | /* Get the I/O and memory ranges from DT */ | 1267 | /* Get the I/O and memory ranges from DT */ |
1225 | io_size = 0; | ||
1226 | resource_list_for_each_entry(win, &res) { | 1268 | resource_list_for_each_entry(win, &res) { |
1227 | switch (resource_type(win->res)) { | 1269 | switch (resource_type(win->res)) { |
1228 | case IORESOURCE_IO: | 1270 | case IORESOURCE_IO: |
1229 | io = win->res; | 1271 | io = win->res; |
1230 | io->name = "I/O"; | 1272 | io->name = "I/O"; |
1231 | io_size = resource_size(io); | 1273 | rockchip->io_size = resource_size(io); |
1232 | io_bus_addr = io->start - win->offset; | 1274 | rockchip->io_bus_addr = io->start - win->offset; |
1233 | err = pci_remap_iospace(io, io_base); | 1275 | err = pci_remap_iospace(io, io_base); |
1234 | if (err) { | 1276 | if (err) { |
1235 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 1277 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
@@ -1240,8 +1282,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1240 | case IORESOURCE_MEM: | 1282 | case IORESOURCE_MEM: |
1241 | mem = win->res; | 1283 | mem = win->res; |
1242 | mem->name = "MEM"; | 1284 | mem->name = "MEM"; |
1243 | mem_size = resource_size(mem); | 1285 | rockchip->mem_size = resource_size(mem); |
1244 | mem_bus_addr = mem->start - win->offset; | 1286 | rockchip->mem_bus_addr = mem->start - win->offset; |
1245 | break; | 1287 | break; |
1246 | case IORESOURCE_BUS: | 1288 | case IORESOURCE_BUS: |
1247 | rockchip->root_bus_nr = win->res->start; | 1289 | rockchip->root_bus_nr = win->res->start; |
@@ -1251,45 +1293,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1251 | } | 1293 | } |
1252 | } | 1294 | } |
1253 | 1295 | ||
1254 | if (mem_size) { | 1296 | err = rockchip_cfg_atu(rockchip); |
1255 | for (reg_no = 0; reg_no < (mem_size >> 20); reg_no++) { | 1297 | if (err) |
1256 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1257 | AXI_WRAPPER_MEM_WRITE, | ||
1258 | 20 - 1, | ||
1259 | mem_bus_addr + | ||
1260 | (reg_no << 20), | ||
1261 | 0); | ||
1262 | if (err) { | ||
1263 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1264 | goto err_vpcie; | ||
1265 | } | ||
1266 | } | ||
1267 | } | ||
1268 | |||
1269 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1270 | if (err) { | ||
1271 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1272 | goto err_vpcie; | 1298 | goto err_vpcie; |
1273 | } | ||
1274 | |||
1275 | offset = mem_size >> 20; | ||
1276 | |||
1277 | if (io_size) { | ||
1278 | for (reg_no = 0; reg_no < (io_size >> 20); reg_no++) { | ||
1279 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1280 | reg_no + 1 + offset, | ||
1281 | AXI_WRAPPER_IO_WRITE, | ||
1282 | 20 - 1, | ||
1283 | io_bus_addr + | ||
1284 | (reg_no << 20), | ||
1285 | 0); | ||
1286 | if (err) { | ||
1287 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1288 | goto err_vpcie; | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); | 1299 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); |
1294 | if (!bus) { | 1300 | if (!bus) { |
1295 | err = -ENOMEM; | 1301 | err = -ENOMEM; |