aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorMarcin Wojtas <mw@semihalf.com>2016-04-29 03:49:07 -0400
committerVinod Koul <vinod.koul@intel.com>2016-05-03 02:57:47 -0400
commitac5f0f3f863e9e6703a3038aa72814d2d0e8a056 (patch)
treebc9da076d8ea0de1f1a2da61ef329d48e620b150 /drivers/dma
parentdd130c652cb745e82b70cb71a3cf2dd876295e96 (diff)
dmaengine: mv_xor: add support for Armada 3700 SoC
Armada 3700 SoC comprise a single XOR engine compliant with the ones used in older Marvell SoC's like Armada XP or 38x. The only thing that needs modification is the Mbus configuration, which has to be done on two levels: global and in device. The first one is inherited from the bootloader. The latter can be opened in a default way, leaving arbitration to the bus controller. Hence filled mbus_dram_target_info structure is not needed. Patch "dmaengine: mv_xor: optimize performance by using a subset of the XOR channels" introduced limitation for using XOR engines and channels vs number of available CPU's. Those constraints do not however fit Armada 3700 architecture with two possible CPU's and single, dual-channel engine. Hence in this commit an adjustment for setting maximum available channels is added. This patch enables XOR access to DRAM by opening default window to 4GB space with specific attribute. Signed-off-by: Marcin Wojtas <mw@semihalf.com> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/mv_xor.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 6d012a56b97b..25d1dadcddd1 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -34,6 +34,7 @@
34enum mv_xor_type { 34enum mv_xor_type {
35 XOR_ORION, 35 XOR_ORION,
36 XOR_ARMADA_38X, 36 XOR_ARMADA_38X,
37 XOR_ARMADA_37XX,
37}; 38};
38 39
39enum mv_xor_mode { 40enum mv_xor_mode {
@@ -1093,6 +1094,33 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev,
1093 writel(0, base + WINDOW_OVERRIDE_CTRL(1)); 1094 writel(0, base + WINDOW_OVERRIDE_CTRL(1));
1094} 1095}
1095 1096
1097static void
1098mv_xor_conf_mbus_windows_a3700(struct mv_xor_device *xordev)
1099{
1100 void __iomem *base = xordev->xor_high_base;
1101 u32 win_enable = 0;
1102 int i;
1103
1104 for (i = 0; i < 8; i++) {
1105 writel(0, base + WINDOW_BASE(i));
1106 writel(0, base + WINDOW_SIZE(i));
1107 if (i < 4)
1108 writel(0, base + WINDOW_REMAP_HIGH(i));
1109 }
1110 /*
1111 * For Armada3700 open default 4GB Mbus window. The dram
1112 * related configuration are done at AXIS level.
1113 */
1114 writel(0xffff0000, base + WINDOW_SIZE(0));
1115 win_enable |= 1;
1116 win_enable |= 3 << 16;
1117
1118 writel(win_enable, base + WINDOW_BAR_ENABLE(0));
1119 writel(win_enable, base + WINDOW_BAR_ENABLE(1));
1120 writel(0, base + WINDOW_OVERRIDE_CTRL(0));
1121 writel(0, base + WINDOW_OVERRIDE_CTRL(1));
1122}
1123
1096/* 1124/*
1097 * Since this XOR driver is basically used only for RAID5, we don't 1125 * Since this XOR driver is basically used only for RAID5, we don't
1098 * need to care about synchronizing ->suspend with DMA activity, 1126 * need to care about synchronizing ->suspend with DMA activity,
@@ -1137,6 +1165,11 @@ static int mv_xor_resume(struct platform_device *dev)
1137 XOR_INTR_MASK(mv_chan)); 1165 XOR_INTR_MASK(mv_chan));
1138 } 1166 }
1139 1167
1168 if (xordev->xor_type == XOR_ARMADA_37XX) {
1169 mv_xor_conf_mbus_windows_a3700(xordev);
1170 return 0;
1171 }
1172
1140 dram = mv_mbus_dram_info(); 1173 dram = mv_mbus_dram_info();
1141 if (dram) 1174 if (dram)
1142 mv_xor_conf_mbus_windows(xordev, dram); 1175 mv_xor_conf_mbus_windows(xordev, dram);
@@ -1147,6 +1180,7 @@ static int mv_xor_resume(struct platform_device *dev)
1147static const struct of_device_id mv_xor_dt_ids[] = { 1180static const struct of_device_id mv_xor_dt_ids[] = {
1148 { .compatible = "marvell,orion-xor", .data = (void *)XOR_ORION }, 1181 { .compatible = "marvell,orion-xor", .data = (void *)XOR_ORION },
1149 { .compatible = "marvell,armada-380-xor", .data = (void *)XOR_ARMADA_38X }, 1182 { .compatible = "marvell,armada-380-xor", .data = (void *)XOR_ARMADA_38X },
1183 { .compatible = "marvell,armada-3700-xor", .data = (void *)XOR_ARMADA_37XX },
1150 {}, 1184 {},
1151}; 1185};
1152 1186
@@ -1204,9 +1238,13 @@ static int mv_xor_probe(struct platform_device *pdev)
1204 /* 1238 /*
1205 * (Re-)program MBUS remapping windows if we are asked to. 1239 * (Re-)program MBUS remapping windows if we are asked to.
1206 */ 1240 */
1207 dram = mv_mbus_dram_info(); 1241 if (xordev->xor_type == XOR_ARMADA_37XX) {
1208 if (dram) 1242 mv_xor_conf_mbus_windows_a3700(xordev);
1209 mv_xor_conf_mbus_windows(xordev, dram); 1243 } else {
1244 dram = mv_mbus_dram_info();
1245 if (dram)
1246 mv_xor_conf_mbus_windows(xordev, dram);
1247 }
1210 1248
1211 /* Not all platforms can gate the clock, so it is not 1249 /* Not all platforms can gate the clock, so it is not
1212 * an error if the clock does not exists. 1250 * an error if the clock does not exists.
@@ -1220,12 +1258,16 @@ static int mv_xor_probe(struct platform_device *pdev)
1220 * order for async_tx to perform well. So we limit the number 1258 * order for async_tx to perform well. So we limit the number
1221 * of engines and channels so that we take into account this 1259 * of engines and channels so that we take into account this
1222 * constraint. Note that we also want to use channels from 1260 * constraint. Note that we also want to use channels from
1223 * separate engines when possible. 1261 * separate engines when possible. For dual-CPU Armada 3700
1262 * SoC with single XOR engine allow using its both channels.
1224 */ 1263 */
1225 max_engines = num_present_cpus(); 1264 max_engines = num_present_cpus();
1226 max_channels = min_t(unsigned int, 1265 if (xordev->xor_type == XOR_ARMADA_37XX)
1227 MV_XOR_MAX_CHANNELS, 1266 max_channels = num_present_cpus();
1228 DIV_ROUND_UP(num_present_cpus(), 2)); 1267 else
1268 max_channels = min_t(unsigned int,
1269 MV_XOR_MAX_CHANNELS,
1270 DIV_ROUND_UP(num_present_cpus(), 2));
1229 1271
1230 if (mv_xor_engine_count >= max_engines) 1272 if (mv_xor_engine_count >= max_engines)
1231 return 0; 1273 return 0;