Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets
0004 //
0005 // Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
0006 // Author: John Garry <john.garry@huawei.com>
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/completion.h>
0010 #include <linux/dmi.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/iopoll.h>
0013 #include <linux/module.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/slab.h>
0017 #include <linux/spi/spi.h>
0018 #include <linux/spi/spi-mem.h>
0019 
0020 #define HISI_SFC_V3XX_VERSION (0x1f8)
0021 
0022 #define HISI_SFC_V3XX_GLB_CFG (0x100)
0023 #define HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE BIT(2)
0024 #define HISI_SFC_V3XX_RAW_INT_STAT (0x120)
0025 #define HISI_SFC_V3XX_INT_STAT (0x124)
0026 #define HISI_SFC_V3XX_INT_MASK (0x128)
0027 #define HISI_SFC_V3XX_INT_CLR (0x12c)
0028 #define HISI_SFC_V3XX_CMD_CFG (0x300)
0029 #define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
0030 #define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
0031 #define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7)
0032 #define HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF 4
0033 #define HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK BIT(3)
0034 #define HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF 1
0035 #define HISI_SFC_V3XX_CMD_CFG_START_MSK BIT(0)
0036 #define HISI_SFC_V3XX_CMD_INS (0x308)
0037 #define HISI_SFC_V3XX_CMD_ADDR (0x30c)
0038 #define HISI_SFC_V3XX_CMD_DATABUF0 (0x400)
0039 
0040 /* Common definition of interrupt bit masks */
0041 #define HISI_SFC_V3XX_INT_MASK_ALL (0x1ff)  /* all the masks */
0042 #define HISI_SFC_V3XX_INT_MASK_CPLT BIT(0)  /* command execution complete */
0043 #define HISI_SFC_V3XX_INT_MASK_PP_ERR BIT(2)    /* page progrom error */
0044 #define HISI_SFC_V3XX_INT_MASK_IACCES BIT(5)    /* error visiting inaccessible/
0045                          * protected address
0046                          */
0047 
0048 /* IO Mode definition in HISI_SFC_V3XX_CMD_CFG */
0049 #define HISI_SFC_V3XX_STD (0 << 17)
0050 #define HISI_SFC_V3XX_DIDO (1 << 17)
0051 #define HISI_SFC_V3XX_DIO (2 << 17)
0052 #define HISI_SFC_V3XX_FULL_DIO (3 << 17)
0053 #define HISI_SFC_V3XX_QIQO (5 << 17)
0054 #define HISI_SFC_V3XX_QIO (6 << 17)
0055 #define HISI_SFC_V3XX_FULL_QIO (7 << 17)
0056 
0057 /*
0058  * The IO modes lookup table. hisi_sfc_v3xx_io_modes[(z - 1) / 2][y / 2][x / 2]
0059  * stands for x-y-z mode, as described in SFDP terminology. -EIO indicates
0060  * an invalid mode.
0061  */
0062 static const int hisi_sfc_v3xx_io_modes[2][3][3] = {
0063     {
0064         { HISI_SFC_V3XX_DIDO, HISI_SFC_V3XX_DIDO, HISI_SFC_V3XX_DIDO },
0065         { HISI_SFC_V3XX_DIO, HISI_SFC_V3XX_FULL_DIO, -EIO },
0066         { -EIO, -EIO, -EIO },
0067     },
0068     {
0069         { HISI_SFC_V3XX_QIQO, HISI_SFC_V3XX_QIQO, HISI_SFC_V3XX_QIQO },
0070         { -EIO, -EIO, -EIO },
0071         { HISI_SFC_V3XX_QIO, -EIO, HISI_SFC_V3XX_FULL_QIO },
0072     },
0073 };
0074 
0075 struct hisi_sfc_v3xx_host {
0076     struct device *dev;
0077     void __iomem *regbase;
0078     int max_cmd_dword;
0079     struct completion *completion;
0080     u8 address_mode;
0081     int irq;
0082 };
0083 
0084 static void hisi_sfc_v3xx_disable_int(struct hisi_sfc_v3xx_host *host)
0085 {
0086     writel(0, host->regbase + HISI_SFC_V3XX_INT_MASK);
0087 }
0088 
0089 static void hisi_sfc_v3xx_enable_int(struct hisi_sfc_v3xx_host *host)
0090 {
0091     writel(HISI_SFC_V3XX_INT_MASK_ALL, host->regbase + HISI_SFC_V3XX_INT_MASK);
0092 }
0093 
0094 static void hisi_sfc_v3xx_clear_int(struct hisi_sfc_v3xx_host *host)
0095 {
0096     writel(HISI_SFC_V3XX_INT_MASK_ALL, host->regbase + HISI_SFC_V3XX_INT_CLR);
0097 }
0098 
0099 /*
0100  * The interrupt status register indicates whether an error occurs
0101  * after per operation. Check it, and clear the interrupts for
0102  * next time judgement.
0103  */
0104 static int hisi_sfc_v3xx_handle_completion(struct hisi_sfc_v3xx_host *host)
0105 {
0106     u32 reg;
0107 
0108     reg = readl(host->regbase + HISI_SFC_V3XX_RAW_INT_STAT);
0109     hisi_sfc_v3xx_clear_int(host);
0110 
0111     if (reg & HISI_SFC_V3XX_INT_MASK_IACCES) {
0112         dev_err(host->dev, "fail to access protected address\n");
0113         return -EIO;
0114     }
0115 
0116     if (reg & HISI_SFC_V3XX_INT_MASK_PP_ERR) {
0117         dev_err(host->dev, "page program operation failed\n");
0118         return -EIO;
0119     }
0120 
0121     /*
0122      * The other bits of the interrupt registers is not currently
0123      * used and probably not be triggered in this driver. When it
0124      * happens, we regard it as an unsupported error here.
0125      */
0126     if (!(reg & HISI_SFC_V3XX_INT_MASK_CPLT)) {
0127         dev_err(host->dev, "unsupported error occurred, status=0x%x\n", reg);
0128         return -EIO;
0129     }
0130 
0131     return 0;
0132 }
0133 
0134 #define HISI_SFC_V3XX_WAIT_TIMEOUT_US       1000000
0135 #define HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US 10
0136 
0137 static int hisi_sfc_v3xx_wait_cmd_idle(struct hisi_sfc_v3xx_host *host)
0138 {
0139     u32 reg;
0140 
0141     return readl_poll_timeout(host->regbase + HISI_SFC_V3XX_CMD_CFG, reg,
0142                   !(reg & HISI_SFC_V3XX_CMD_CFG_START_MSK),
0143                   HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US,
0144                   HISI_SFC_V3XX_WAIT_TIMEOUT_US);
0145 }
0146 
0147 static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
0148                     struct spi_mem_op *op)
0149 {
0150     struct spi_device *spi = mem->spi;
0151     struct hisi_sfc_v3xx_host *host;
0152     uintptr_t addr = (uintptr_t)op->data.buf.in;
0153     int max_byte_count;
0154 
0155     host = spi_controller_get_devdata(spi->master);
0156 
0157     max_byte_count = host->max_cmd_dword * 4;
0158 
0159     if (!IS_ALIGNED(addr, 4) && op->data.nbytes >= 4)
0160         op->data.nbytes = 4 - (addr % 4);
0161     else if (op->data.nbytes > max_byte_count)
0162         op->data.nbytes = max_byte_count;
0163 
0164     return 0;
0165 }
0166 
0167 /*
0168  * The controller only supports Standard SPI mode, Duall mode and
0169  * Quad mode. Double sanitize the ops here to avoid OOB access.
0170  */
0171 static bool hisi_sfc_v3xx_supports_op(struct spi_mem *mem,
0172                       const struct spi_mem_op *op)
0173 {
0174     struct spi_device *spi = mem->spi;
0175     struct hisi_sfc_v3xx_host *host;
0176 
0177     host = spi_controller_get_devdata(spi->master);
0178 
0179     if (op->data.buswidth > 4 || op->dummy.buswidth > 4 ||
0180         op->addr.buswidth > 4 || op->cmd.buswidth > 4)
0181         return false;
0182 
0183     if (op->addr.nbytes != host->address_mode && op->addr.nbytes)
0184         return false;
0185 
0186     return spi_mem_default_supports_op(mem, op);
0187 }
0188 
0189 /*
0190  * memcpy_{to,from}io doesn't gurantee 32b accesses - which we require for the
0191  * DATABUF registers -so use __io{read,write}32_copy when possible. For
0192  * trailing bytes, copy them byte-by-byte from the DATABUF register, as we
0193  * can't clobber outside the source/dest buffer.
0194  *
0195  * For efficient data read/write, we try to put any start 32b unaligned data
0196  * into a separate transaction in hisi_sfc_v3xx_adjust_op_size().
0197  */
0198 static void hisi_sfc_v3xx_read_databuf(struct hisi_sfc_v3xx_host *host,
0199                        u8 *to, unsigned int len)
0200 {
0201     void __iomem *from;
0202     int i;
0203 
0204     from = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0;
0205 
0206     if (IS_ALIGNED((uintptr_t)to, 4)) {
0207         int words = len / 4;
0208 
0209         __ioread32_copy(to, from, words);
0210 
0211         len -= words * 4;
0212         if (len) {
0213             u32 val;
0214 
0215             to += words * 4;
0216             from += words * 4;
0217 
0218             val = __raw_readl(from);
0219 
0220             for (i = 0; i < len; i++, val >>= 8, to++)
0221                 *to = (u8)val;
0222         }
0223     } else {
0224         for (i = 0; i < DIV_ROUND_UP(len, 4); i++, from += 4) {
0225             u32 val = __raw_readl(from);
0226             int j;
0227 
0228             for (j = 0; j < 4 && (j + (i * 4) < len);
0229                  to++, val >>= 8, j++)
0230                 *to = (u8)val;
0231         }
0232     }
0233 }
0234 
0235 static void hisi_sfc_v3xx_write_databuf(struct hisi_sfc_v3xx_host *host,
0236                     const u8 *from, unsigned int len)
0237 {
0238     void __iomem *to;
0239     int i;
0240 
0241     to = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0;
0242 
0243     if (IS_ALIGNED((uintptr_t)from, 4)) {
0244         int words = len / 4;
0245 
0246         __iowrite32_copy(to, from, words);
0247 
0248         len -= words * 4;
0249         if (len) {
0250             u32 val = 0;
0251 
0252             to += words * 4;
0253             from += words * 4;
0254 
0255             for (i = 0; i < len; i++, from++)
0256                 val |= *from << i * 8;
0257             __raw_writel(val, to);
0258         }
0259 
0260     } else {
0261         for (i = 0; i < DIV_ROUND_UP(len, 4); i++, to += 4) {
0262             u32 val = 0;
0263             int j;
0264 
0265             for (j = 0; j < 4 && (j + (i * 4) < len);
0266                  from++, j++)
0267                 val |= *from << j * 8;
0268             __raw_writel(val, to);
0269         }
0270     }
0271 }
0272 
0273 static int hisi_sfc_v3xx_start_bus(struct hisi_sfc_v3xx_host *host,
0274                    const struct spi_mem_op *op,
0275                    u8 chip_select)
0276 {
0277     int len = op->data.nbytes, buswidth_mode;
0278     u32 config = 0;
0279 
0280     if (op->addr.nbytes)
0281         config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
0282 
0283     if (op->data.buswidth == 0 || op->data.buswidth == 1) {
0284         buswidth_mode = HISI_SFC_V3XX_STD;
0285     } else {
0286         int data_idx, addr_idx, cmd_idx;
0287 
0288         data_idx = (op->data.buswidth - 1) / 2;
0289         addr_idx = op->addr.buswidth / 2;
0290         cmd_idx = op->cmd.buswidth / 2;
0291         buswidth_mode = hisi_sfc_v3xx_io_modes[data_idx][addr_idx][cmd_idx];
0292     }
0293     if (buswidth_mode < 0)
0294         return buswidth_mode;
0295     config |= buswidth_mode;
0296 
0297     if (op->data.dir != SPI_MEM_NO_DATA) {
0298         config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF;
0299         config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK;
0300     }
0301 
0302     if (op->data.dir == SPI_MEM_DATA_IN)
0303         config |= HISI_SFC_V3XX_CMD_CFG_RW_MSK;
0304 
0305     config |= op->dummy.nbytes << HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF |
0306           chip_select << HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF |
0307           HISI_SFC_V3XX_CMD_CFG_START_MSK;
0308 
0309     writel(op->addr.val, host->regbase + HISI_SFC_V3XX_CMD_ADDR);
0310     writel(op->cmd.opcode, host->regbase + HISI_SFC_V3XX_CMD_INS);
0311 
0312     writel(config, host->regbase + HISI_SFC_V3XX_CMD_CFG);
0313 
0314     return 0;
0315 }
0316 
0317 static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
0318                      const struct spi_mem_op *op,
0319                      u8 chip_select)
0320 {
0321     DECLARE_COMPLETION_ONSTACK(done);
0322     int ret;
0323 
0324     if (host->irq) {
0325         host->completion = &done;
0326         hisi_sfc_v3xx_enable_int(host);
0327     }
0328 
0329     if (op->data.dir == SPI_MEM_DATA_OUT)
0330         hisi_sfc_v3xx_write_databuf(host, op->data.buf.out, op->data.nbytes);
0331 
0332     ret = hisi_sfc_v3xx_start_bus(host, op, chip_select);
0333     if (ret)
0334         return ret;
0335 
0336     if (host->irq) {
0337         ret = wait_for_completion_timeout(host->completion,
0338                           usecs_to_jiffies(HISI_SFC_V3XX_WAIT_TIMEOUT_US));
0339         if (!ret)
0340             ret = -ETIMEDOUT;
0341         else
0342             ret = 0;
0343 
0344         hisi_sfc_v3xx_disable_int(host);
0345         synchronize_irq(host->irq);
0346         host->completion = NULL;
0347     } else {
0348         ret = hisi_sfc_v3xx_wait_cmd_idle(host);
0349     }
0350     if (hisi_sfc_v3xx_handle_completion(host) || ret)
0351         return -EIO;
0352 
0353     if (op->data.dir == SPI_MEM_DATA_IN)
0354         hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, op->data.nbytes);
0355 
0356     return 0;
0357 }
0358 
0359 static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem,
0360                  const struct spi_mem_op *op)
0361 {
0362     struct hisi_sfc_v3xx_host *host;
0363     struct spi_device *spi = mem->spi;
0364     u8 chip_select = spi->chip_select;
0365 
0366     host = spi_controller_get_devdata(spi->master);
0367 
0368     return hisi_sfc_v3xx_generic_exec_op(host, op, chip_select);
0369 }
0370 
0371 static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = {
0372     .adjust_op_size = hisi_sfc_v3xx_adjust_op_size,
0373     .supports_op = hisi_sfc_v3xx_supports_op,
0374     .exec_op = hisi_sfc_v3xx_exec_op,
0375 };
0376 
0377 static irqreturn_t hisi_sfc_v3xx_isr(int irq, void *data)
0378 {
0379     struct hisi_sfc_v3xx_host *host = data;
0380 
0381     hisi_sfc_v3xx_disable_int(host);
0382 
0383     complete(host->completion);
0384 
0385     return IRQ_HANDLED;
0386 }
0387 
0388 static int hisi_sfc_v3xx_buswidth_override_bits;
0389 
0390 /*
0391  * ACPI FW does not allow us to currently set the device buswidth, so quirk it
0392  * depending on the board.
0393  */
0394 static int __init hisi_sfc_v3xx_dmi_quirk(const struct dmi_system_id *d)
0395 {
0396     hisi_sfc_v3xx_buswidth_override_bits = SPI_RX_QUAD | SPI_TX_QUAD;
0397 
0398     return 0;
0399 }
0400 
0401 static const struct dmi_system_id hisi_sfc_v3xx_dmi_quirk_table[]  = {
0402     {
0403     .callback = hisi_sfc_v3xx_dmi_quirk,
0404     .matches = {
0405         DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
0406         DMI_MATCH(DMI_PRODUCT_NAME, "D06"),
0407     },
0408     },
0409     {
0410     .callback = hisi_sfc_v3xx_dmi_quirk,
0411     .matches = {
0412         DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
0413         DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 2280 V2"),
0414     },
0415     },
0416     {
0417     .callback = hisi_sfc_v3xx_dmi_quirk,
0418     .matches = {
0419         DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
0420         DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 200 (Model 2280)"),
0421     },
0422     },
0423     {}
0424 };
0425 
0426 static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
0427 {
0428     struct device *dev = &pdev->dev;
0429     struct hisi_sfc_v3xx_host *host;
0430     struct spi_controller *ctlr;
0431     u32 version, glb_config;
0432     int ret;
0433 
0434     ctlr = spi_alloc_master(&pdev->dev, sizeof(*host));
0435     if (!ctlr)
0436         return -ENOMEM;
0437 
0438     ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
0439               SPI_TX_DUAL | SPI_TX_QUAD;
0440 
0441     ctlr->buswidth_override_bits = hisi_sfc_v3xx_buswidth_override_bits;
0442 
0443     host = spi_controller_get_devdata(ctlr);
0444     host->dev = dev;
0445 
0446     platform_set_drvdata(pdev, host);
0447 
0448     host->regbase = devm_platform_ioremap_resource(pdev, 0);
0449     if (IS_ERR(host->regbase)) {
0450         ret = PTR_ERR(host->regbase);
0451         goto err_put_master;
0452     }
0453 
0454     host->irq = platform_get_irq_optional(pdev, 0);
0455     if (host->irq == -EPROBE_DEFER) {
0456         ret = -EPROBE_DEFER;
0457         goto err_put_master;
0458     }
0459 
0460     hisi_sfc_v3xx_disable_int(host);
0461 
0462     if (host->irq > 0) {
0463         ret = devm_request_irq(dev, host->irq, hisi_sfc_v3xx_isr, 0,
0464                        "hisi-sfc-v3xx", host);
0465 
0466         if (ret) {
0467             dev_err(dev, "failed to request irq%d, ret = %d\n", host->irq, ret);
0468             host->irq = 0;
0469         }
0470     } else {
0471         host->irq = 0;
0472     }
0473 
0474     ctlr->bus_num = -1;
0475     ctlr->num_chipselect = 1;
0476     ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops;
0477 
0478     /*
0479      * The address mode of the controller is either 3 or 4,
0480      * which is indicated by the address mode bit in
0481      * the global config register. The register is read only
0482      * for the OS driver.
0483      */
0484     glb_config = readl(host->regbase + HISI_SFC_V3XX_GLB_CFG);
0485     if (glb_config & HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE)
0486         host->address_mode = 4;
0487     else
0488         host->address_mode = 3;
0489 
0490     version = readl(host->regbase + HISI_SFC_V3XX_VERSION);
0491 
0492     if (version >= 0x351)
0493         host->max_cmd_dword = 64;
0494     else
0495         host->max_cmd_dword = 16;
0496 
0497     ret = devm_spi_register_controller(dev, ctlr);
0498     if (ret)
0499         goto err_put_master;
0500 
0501     dev_info(&pdev->dev, "hw version 0x%x, %s mode.\n",
0502          version, host->irq ? "irq" : "polling");
0503 
0504     return 0;
0505 
0506 err_put_master:
0507     spi_master_put(ctlr);
0508     return ret;
0509 }
0510 
0511 static const struct acpi_device_id hisi_sfc_v3xx_acpi_ids[] = {
0512     {"HISI0341", 0},
0513     {}
0514 };
0515 MODULE_DEVICE_TABLE(acpi, hisi_sfc_v3xx_acpi_ids);
0516 
0517 static struct platform_driver hisi_sfc_v3xx_spi_driver = {
0518     .driver = {
0519         .name   = "hisi-sfc-v3xx",
0520         .acpi_match_table = hisi_sfc_v3xx_acpi_ids,
0521     },
0522     .probe  = hisi_sfc_v3xx_probe,
0523 };
0524 
0525 static int __init hisi_sfc_v3xx_spi_init(void)
0526 {
0527     dmi_check_system(hisi_sfc_v3xx_dmi_quirk_table);
0528 
0529     return platform_driver_register(&hisi_sfc_v3xx_spi_driver);
0530 }
0531 
0532 static void __exit hisi_sfc_v3xx_spi_exit(void)
0533 {
0534     platform_driver_unregister(&hisi_sfc_v3xx_spi_driver);
0535 }
0536 
0537 module_init(hisi_sfc_v3xx_spi_init);
0538 module_exit(hisi_sfc_v3xx_spi_exit);
0539 
0540 MODULE_LICENSE("GPL");
0541 MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
0542 MODULE_DESCRIPTION("HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets");