diff options
| -rw-r--r-- | drivers/dma/amba-pl08x.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index a84db8b39ba1..9aa2bd4452d3 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
| @@ -1048,50 +1048,42 @@ pl08x_dma_tx_status(struct dma_chan *chan, | |||
| 1048 | 1048 | ||
| 1049 | /* PrimeCell DMA extension */ | 1049 | /* PrimeCell DMA extension */ |
| 1050 | struct burst_table { | 1050 | struct burst_table { |
| 1051 | int burstwords; | 1051 | u32 burstwords; |
| 1052 | u32 reg; | 1052 | u32 reg; |
| 1053 | }; | 1053 | }; |
| 1054 | 1054 | ||
| 1055 | static const struct burst_table burst_sizes[] = { | 1055 | static const struct burst_table burst_sizes[] = { |
| 1056 | { | 1056 | { |
| 1057 | .burstwords = 256, | 1057 | .burstwords = 256, |
| 1058 | .reg = (PL080_BSIZE_256 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1058 | .reg = PL080_BSIZE_256, |
| 1059 | (PL080_BSIZE_256 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1060 | }, | 1059 | }, |
| 1061 | { | 1060 | { |
| 1062 | .burstwords = 128, | 1061 | .burstwords = 128, |
| 1063 | .reg = (PL080_BSIZE_128 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1062 | .reg = PL080_BSIZE_128, |
| 1064 | (PL080_BSIZE_128 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1065 | }, | 1063 | }, |
| 1066 | { | 1064 | { |
| 1067 | .burstwords = 64, | 1065 | .burstwords = 64, |
| 1068 | .reg = (PL080_BSIZE_64 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1066 | .reg = PL080_BSIZE_64, |
| 1069 | (PL080_BSIZE_64 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1070 | }, | 1067 | }, |
| 1071 | { | 1068 | { |
| 1072 | .burstwords = 32, | 1069 | .burstwords = 32, |
| 1073 | .reg = (PL080_BSIZE_32 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1070 | .reg = PL080_BSIZE_32, |
| 1074 | (PL080_BSIZE_32 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1075 | }, | 1071 | }, |
| 1076 | { | 1072 | { |
| 1077 | .burstwords = 16, | 1073 | .burstwords = 16, |
| 1078 | .reg = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1074 | .reg = PL080_BSIZE_16, |
| 1079 | (PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1080 | }, | 1075 | }, |
| 1081 | { | 1076 | { |
| 1082 | .burstwords = 8, | 1077 | .burstwords = 8, |
| 1083 | .reg = (PL080_BSIZE_8 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1078 | .reg = PL080_BSIZE_8, |
| 1084 | (PL080_BSIZE_8 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1085 | }, | 1079 | }, |
| 1086 | { | 1080 | { |
| 1087 | .burstwords = 4, | 1081 | .burstwords = 4, |
| 1088 | .reg = (PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1082 | .reg = PL080_BSIZE_4, |
| 1089 | (PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1090 | }, | 1083 | }, |
| 1091 | { | 1084 | { |
| 1092 | .burstwords = 1, | 1085 | .burstwords = 0, |
| 1093 | .reg = (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1086 | .reg = PL080_BSIZE_1, |
| 1094 | (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT), | ||
| 1095 | }, | 1087 | }, |
| 1096 | }; | 1088 | }; |
| 1097 | 1089 | ||
| @@ -1135,15 +1127,25 @@ static u32 pl08x_width(enum dma_slave_buswidth width) | |||
| 1135 | return ~0; | 1127 | return ~0; |
| 1136 | } | 1128 | } |
| 1137 | 1129 | ||
| 1130 | static u32 pl08x_burst(u32 maxburst) | ||
| 1131 | { | ||
| 1132 | int i; | ||
| 1133 | |||
| 1134 | for (i = 0; i < ARRAY_SIZE(burst_sizes); i++) | ||
| 1135 | if (burst_sizes[i].burstwords <= maxburst) | ||
| 1136 | break; | ||
| 1137 | |||
| 1138 | return burst_sizes[i].reg; | ||
| 1139 | } | ||
| 1140 | |||
| 1138 | static int dma_set_runtime_config(struct dma_chan *chan, | 1141 | static int dma_set_runtime_config(struct dma_chan *chan, |
| 1139 | struct dma_slave_config *config) | 1142 | struct dma_slave_config *config) |
| 1140 | { | 1143 | { |
| 1141 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); | 1144 | struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); |
| 1142 | struct pl08x_driver_data *pl08x = plchan->host; | 1145 | struct pl08x_driver_data *pl08x = plchan->host; |
| 1143 | enum dma_slave_buswidth addr_width; | 1146 | enum dma_slave_buswidth addr_width; |
| 1144 | u32 width, maxburst; | 1147 | u32 width, burst, maxburst; |
| 1145 | u32 cctl = 0; | 1148 | u32 cctl = 0; |
| 1146 | int i; | ||
| 1147 | 1149 | ||
| 1148 | if (!plchan->slave) | 1150 | if (!plchan->slave) |
| 1149 | return -EINVAL; | 1151 | return -EINVAL; |
| @@ -1173,20 +1175,16 @@ static int dma_set_runtime_config(struct dma_chan *chan, | |||
| 1173 | cctl |= width << PL080_CONTROL_DWIDTH_SHIFT; | 1175 | cctl |= width << PL080_CONTROL_DWIDTH_SHIFT; |
| 1174 | 1176 | ||
| 1175 | /* | 1177 | /* |
| 1176 | * Now decide on a maxburst: | ||
| 1177 | * If this channel will only request single transfers, set this | 1178 | * If this channel will only request single transfers, set this |
| 1178 | * down to ONE element. Also select one element if no maxburst | 1179 | * down to ONE element. Also select one element if no maxburst |
| 1179 | * is specified. | 1180 | * is specified. |
| 1180 | */ | 1181 | */ |
| 1181 | if (plchan->cd->single || maxburst == 0) { | 1182 | if (plchan->cd->single) |
| 1182 | cctl |= (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1183 | maxburst = 1; |
| 1183 | (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT); | 1184 | |
| 1184 | } else { | 1185 | burst = pl08x_burst(maxburst); |
| 1185 | for (i = 0; i < ARRAY_SIZE(burst_sizes); i++) | 1186 | cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT; |
| 1186 | if (burst_sizes[i].burstwords <= maxburst) | 1187 | cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT; |
| 1187 | break; | ||
| 1188 | cctl |= burst_sizes[i].reg; | ||
| 1189 | } | ||
| 1190 | 1188 | ||
| 1191 | if (plchan->runtime_direction == DMA_FROM_DEVICE) { | 1189 | if (plchan->runtime_direction == DMA_FROM_DEVICE) { |
| 1192 | plchan->src_addr = config->src_addr; | 1190 | plchan->src_addr = config->src_addr; |
