|
91 | 91 | #define MSPI_MSPI_STATUS 0x020
|
92 | 92 | #define MSPI_CPTQP 0x024
|
93 | 93 | #define MSPI_SPCR3 0x028
|
| 94 | +#define MSPI_REV 0x02c |
94 | 95 | #define MSPI_TXRAM 0x040
|
95 | 96 | #define MSPI_RXRAM 0x0c0
|
96 | 97 | #define MSPI_CDRAM 0x140
|
@@ -217,6 +218,8 @@ struct bcm_qspi {
|
217 | 218 | struct bcm_qspi_dev_id *dev_ids;
|
218 | 219 | struct completion mspi_done;
|
219 | 220 | struct completion bspi_done;
|
| 221 | + u8 mspi_maj_rev; |
| 222 | + u8 mspi_min_rev; |
220 | 223 | };
|
221 | 224 |
|
222 | 225 | static inline bool has_bspi(struct bcm_qspi *qspi)
|
@@ -1190,31 +1193,64 @@ static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
|
1190 | 1193 | .exec_op = bcm_qspi_exec_mem_op,
|
1191 | 1194 | };
|
1192 | 1195 |
|
| 1196 | +struct bcm_qspi_data { |
| 1197 | + bool has_mspi_rev; |
| 1198 | +}; |
| 1199 | + |
| 1200 | +static const struct bcm_qspi_data bcm_qspi_no_rev_data = { |
| 1201 | + .has_mspi_rev = false, |
| 1202 | +}; |
| 1203 | + |
| 1204 | +static const struct bcm_qspi_data bcm_qspi_rev_data = { |
| 1205 | + .has_mspi_rev = true, |
| 1206 | +}; |
| 1207 | + |
1193 | 1208 | static const struct of_device_id bcm_qspi_of_match[] = {
|
1194 |
| - { .compatible = "brcm,spi-bcm-qspi" }, |
| 1209 | + { |
| 1210 | + .compatible = "brcm,spi-bcm7425-qspi", |
| 1211 | + .data = &bcm_qspi_no_rev_data, |
| 1212 | + }, |
| 1213 | + { |
| 1214 | + .compatible = "brcm,spi-bcm7429-qspi", |
| 1215 | + .data = &bcm_qspi_no_rev_data, |
| 1216 | + }, |
| 1217 | + { |
| 1218 | + .compatible = "brcm,spi-bcm7435-qspi", |
| 1219 | + .data = &bcm_qspi_no_rev_data, |
| 1220 | + }, |
| 1221 | + { |
| 1222 | + .compatible = "brcm,spi-bcm-qspi", |
| 1223 | + .data = &bcm_qspi_rev_data, |
| 1224 | + }, |
1195 | 1225 | {},
|
1196 | 1226 | };
|
1197 | 1227 | MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
|
1198 | 1228 |
|
1199 | 1229 | int bcm_qspi_probe(struct platform_device *pdev,
|
1200 | 1230 | struct bcm_qspi_soc_intc *soc_intc)
|
1201 | 1231 | {
|
| 1232 | + const struct of_device_id *of_id = NULL; |
| 1233 | + const struct bcm_qspi_data *data; |
1202 | 1234 | struct device *dev = &pdev->dev;
|
1203 | 1235 | struct bcm_qspi *qspi;
|
1204 | 1236 | struct spi_master *master;
|
1205 | 1237 | struct resource *res;
|
1206 | 1238 | int irq, ret = 0, num_ints = 0;
|
1207 | 1239 | u32 val;
|
| 1240 | + u32 rev = 0; |
1208 | 1241 | const char *name = NULL;
|
1209 | 1242 | int num_irqs = ARRAY_SIZE(qspi_irq_tab);
|
1210 | 1243 |
|
1211 | 1244 | /* We only support device-tree instantiation */
|
1212 | 1245 | if (!dev->of_node)
|
1213 | 1246 | return -ENODEV;
|
1214 | 1247 |
|
1215 |
| - if (!of_match_node(bcm_qspi_of_match, dev->of_node)) |
| 1248 | + of_id = of_match_node(bcm_qspi_of_match, dev->of_node); |
| 1249 | + if (!of_id) |
1216 | 1250 | return -ENODEV;
|
1217 | 1251 |
|
| 1252 | + data = of_id->data; |
| 1253 | + |
1218 | 1254 | master = spi_alloc_master(dev, sizeof(struct bcm_qspi));
|
1219 | 1255 | if (!master) {
|
1220 | 1256 | dev_err(dev, "error allocating spi_master\n");
|
@@ -1351,6 +1387,16 @@ int bcm_qspi_probe(struct platform_device *pdev,
|
1351 | 1387 | qspi->base_clk = clk_get_rate(qspi->clk);
|
1352 | 1388 | qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2);
|
1353 | 1389 |
|
| 1390 | + if (data->has_mspi_rev) { |
| 1391 | + rev = bcm_qspi_read(qspi, MSPI, MSPI_REV); |
| 1392 | + /* some older revs do not have a MSPI_REV register */ |
| 1393 | + if ((rev & 0xff) == 0xff) |
| 1394 | + rev = 0; |
| 1395 | + } |
| 1396 | + |
| 1397 | + qspi->mspi_maj_rev = (rev >> 4) & 0xf; |
| 1398 | + qspi->mspi_min_rev = rev & 0xf; |
| 1399 | + |
1354 | 1400 | bcm_qspi_hw_init(qspi);
|
1355 | 1401 | init_completion(&qspi->mspi_done);
|
1356 | 1402 | init_completion(&qspi->bspi_done);
|
|
0 commit comments