1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Copyright (C) 2022 Hewlett-Packard Development Company, L.P. */ 3 4 #include <linux/iopoll.h> 5 #include <linux/of.h> 6 #include <linux/of_device.h> 7 #include <linux/platform_device.h> 8 #include <linux/spi/spi.h> 9 #include <linux/spi/spi-mem.h> 10 11 #define GXP_SPI0_MAX_CHIPSELECT 2 12 #define GXP_SPI_SLEEP_TIME 1 13 #define GXP_SPI_TIMEOUT (130 * 1000000 / GXP_SPI_SLEEP_TIME) 14 15 #define MANUAL_MODE 0 16 #define DIRECT_MODE 1 17 #define SPILDAT_LEN 256 18 19 #define OFFSET_SPIMCFG 0x0 20 #define OFFSET_SPIMCTRL 0x4 21 #define OFFSET_SPICMD 0x5 22 #define OFFSET_SPIDCNT 0x6 23 #define OFFSET_SPIADDR 0x8 24 #define OFFSET_SPIINTSTS 0xc 25 26 #define SPIMCTRL_START 0x01 27 #define SPIMCTRL_BUSY 0x02 28 #define SPIMCTRL_DIR 0x08 29 30 struct gxp_spi; 31 32 struct gxp_spi_chip { 33 struct gxp_spi *spifi; 34 u32 cs; 35 }; 36 37 struct gxp_spi_data { 38 u32 max_cs; 39 u32 mode_bits; 40 }; 41 42 struct gxp_spi { 43 const struct gxp_spi_data *data; 44 void __iomem *reg_base; 45 void __iomem *dat_base; 46 void __iomem *dir_base; 47 struct device *dev; 48 struct gxp_spi_chip chips[GXP_SPI0_MAX_CHIPSELECT]; 49 }; 50 51 static void gxp_spi_set_mode(struct gxp_spi *spifi, int mode) 52 { 53 u8 value; 54 void __iomem *reg_base = spifi->reg_base; 55 56 value = readb(reg_base + OFFSET_SPIMCTRL); 57 58 if (mode == MANUAL_MODE) { 59 writeb(0x55, reg_base + OFFSET_SPICMD); 60 writeb(0xaa, reg_base + OFFSET_SPICMD); 61 value &= ~0x30; 62 } else { 63 value |= 0x30; 64 } 65 writeb(value, reg_base + OFFSET_SPIMCTRL); 66 } 67 68 static int gxp_spi_read_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op) 69 { 70 int ret; 71 struct gxp_spi *spifi = chip->spifi; 72 void __iomem *reg_base = spifi->reg_base; 73 u32 value; 74 75 value = readl(reg_base + OFFSET_SPIMCFG); 76 value &= ~(1 << 24); 77 value |= (chip->cs << 24); 78 value &= ~(0x07 << 16); 79 value &= ~(0x1f << 19); 80 writel(value, reg_base + OFFSET_SPIMCFG); 81 82 writel(0, reg_base + OFFSET_SPIADDR); 83 84 writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD); 85 86 writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT); 87 88 value = readb(reg_base + OFFSET_SPIMCTRL); 89 value &= ~SPIMCTRL_DIR; 90 value |= SPIMCTRL_START; 91 92 writeb(value, reg_base + OFFSET_SPIMCTRL); 93 94 ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value, 95 !(value & SPIMCTRL_BUSY), 96 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT); 97 if (ret) { 98 dev_warn(spifi->dev, "read reg busy time out\n"); 99 return ret; 100 } 101 102 memcpy_fromio(op->data.buf.in, spifi->dat_base, op->data.nbytes); 103 return ret; 104 } 105 106 static int gxp_spi_write_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op) 107 { 108 int ret; 109 struct gxp_spi *spifi = chip->spifi; 110 void __iomem *reg_base = spifi->reg_base; 111 u32 value; 112 113 value = readl(reg_base + OFFSET_SPIMCFG); 114 value &= ~(1 << 24); 115 value |= (chip->cs << 24); 116 value &= ~(0x07 << 16); 117 value &= ~(0x1f << 19); 118 writel(value, reg_base + OFFSET_SPIMCFG); 119 120 writel(0, reg_base + OFFSET_SPIADDR); 121 122 writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD); 123 124 memcpy_toio(spifi->dat_base, op->data.buf.in, op->data.nbytes); 125 126 writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT); 127 128 value = readb(reg_base + OFFSET_SPIMCTRL); 129 value |= SPIMCTRL_DIR; 130 value |= SPIMCTRL_START; 131 132 writeb(value, reg_base + OFFSET_SPIMCTRL); 133 134 ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value, 135 !(value & SPIMCTRL_BUSY), 136 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT); 137 if (ret) 138 dev_warn(spifi->dev, "write reg busy time out\n"); 139 140 return ret; 141 } 142 143 static ssize_t gxp_spi_read(struct gxp_spi_chip *chip, const struct spi_mem_op *op) 144 { 145 struct gxp_spi *spifi = chip->spifi; 146 u32 offset = op->addr.val; 147 148 if (chip->cs == 0) 149 offset += 0x4000000; 150 151 memcpy_fromio(op->data.buf.in, spifi->dir_base + offset, op->data.nbytes); 152 153 return 0; 154 } 155 156 static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op *op) 157 { 158 struct gxp_spi *spifi = chip->spifi; 159 void __iomem *reg_base = spifi->reg_base; 160 u32 write_len; 161 u32 value; 162 int ret; 163 164 write_len = op->data.nbytes; 165 if (write_len > SPILDAT_LEN) 166 write_len = SPILDAT_LEN; 167 168 value = readl(reg_base + OFFSET_SPIMCFG); 169 value &= ~(1 << 24); 170 value |= (chip->cs << 24); 171 value &= ~(0x07 << 16); 172 value |= (op->addr.nbytes << 16); 173 value &= ~(0x1f << 19); 174 writel(value, reg_base + OFFSET_SPIMCFG); 175 176 writel(op->addr.val, reg_base + OFFSET_SPIADDR); 177 178 writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD); 179 180 writew(write_len, reg_base + OFFSET_SPIDCNT); 181 182 memcpy_toio(spifi->dat_base, op->data.buf.in, write_len); 183 184 value = readb(reg_base + OFFSET_SPIMCTRL); 185 value |= SPIMCTRL_DIR; 186 value |= SPIMCTRL_START; 187 188 writeb(value, reg_base + OFFSET_SPIMCTRL); 189 190 ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value, 191 !(value & SPIMCTRL_BUSY), 192 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT); 193 if (ret) { 194 dev_warn(spifi->dev, "write busy time out\n"); 195 return ret; 196 } 197 198 return write_len; 199 } 200 201 static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) 202 { 203 struct gxp_spi *spifi = spi_controller_get_devdata(mem->spi->master); 204 struct gxp_spi_chip *chip = &spifi->chips[spi_get_chipselect(mem->spi, 0)]; 205 int ret; 206 207 if (op->data.dir == SPI_MEM_DATA_IN) { 208 if (!op->addr.nbytes) 209 ret = gxp_spi_read_reg(chip, op); 210 else 211 ret = gxp_spi_read(chip, op); 212 } else { 213 if (!op->addr.nbytes) 214 ret = gxp_spi_write_reg(chip, op); 215 else 216 ret = gxp_spi_write(chip, op); 217 } 218 219 return ret; 220 } 221 222 static int gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) 223 { 224 int ret; 225 226 ret = do_gxp_exec_mem_op(mem, op); 227 if (ret) 228 dev_err(&mem->spi->dev, "operation failed: %d", ret); 229 230 return ret; 231 } 232 233 static const struct spi_controller_mem_ops gxp_spi_mem_ops = { 234 .exec_op = gxp_exec_mem_op, 235 }; 236 237 static int gxp_spi_setup(struct spi_device *spi) 238 { 239 struct gxp_spi *spifi = spi_controller_get_devdata(spi->master); 240 unsigned int cs = spi_get_chipselect(spi, 0); 241 struct gxp_spi_chip *chip = &spifi->chips[cs]; 242 243 chip->spifi = spifi; 244 chip->cs = cs; 245 246 gxp_spi_set_mode(spifi, MANUAL_MODE); 247 248 return 0; 249 } 250 251 static int gxp_spifi_probe(struct platform_device *pdev) 252 { 253 struct device *dev = &pdev->dev; 254 const struct gxp_spi_data *data; 255 struct spi_controller *ctlr; 256 struct gxp_spi *spifi; 257 int ret; 258 259 data = of_device_get_match_data(&pdev->dev); 260 261 ctlr = devm_spi_alloc_master(dev, sizeof(*spifi)); 262 if (!ctlr) 263 return -ENOMEM; 264 265 spifi = spi_controller_get_devdata(ctlr); 266 267 platform_set_drvdata(pdev, spifi); 268 spifi->data = data; 269 spifi->dev = dev; 270 271 spifi->reg_base = devm_platform_ioremap_resource(pdev, 0); 272 if (IS_ERR(spifi->reg_base)) 273 return PTR_ERR(spifi->reg_base); 274 275 spifi->dat_base = devm_platform_ioremap_resource(pdev, 1); 276 if (IS_ERR(spifi->dat_base)) 277 return PTR_ERR(spifi->dat_base); 278 279 spifi->dir_base = devm_platform_ioremap_resource(pdev, 2); 280 if (IS_ERR(spifi->dir_base)) 281 return PTR_ERR(spifi->dir_base); 282 283 ctlr->mode_bits = data->mode_bits; 284 ctlr->bus_num = pdev->id; 285 ctlr->mem_ops = &gxp_spi_mem_ops; 286 ctlr->setup = gxp_spi_setup; 287 ctlr->num_chipselect = data->max_cs; 288 ctlr->dev.of_node = dev->of_node; 289 290 ret = devm_spi_register_controller(dev, ctlr); 291 if (ret) { 292 return dev_err_probe(&pdev->dev, ret, 293 "failed to register spi controller\n"); 294 } 295 296 return 0; 297 } 298 299 static const struct gxp_spi_data gxp_spifi_data = { 300 .max_cs = 2, 301 .mode_bits = 0, 302 }; 303 304 static const struct of_device_id gxp_spifi_match[] = { 305 {.compatible = "hpe,gxp-spifi", .data = &gxp_spifi_data }, 306 { /* null */ } 307 }; 308 MODULE_DEVICE_TABLE(of, gxp_spifi_match); 309 310 static struct platform_driver gxp_spifi_driver = { 311 .probe = gxp_spifi_probe, 312 .driver = { 313 .name = "gxp-spifi", 314 .of_match_table = gxp_spifi_match, 315 }, 316 }; 317 module_platform_driver(gxp_spifi_driver); 318 319 MODULE_DESCRIPTION("HPE GXP SPI Flash Interface driver"); 320 MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>"); 321 MODULE_LICENSE("GPL"); 322