Lines Matching refs:ispi
164 static void intel_spi_dump_regs(struct intel_spi *ispi) in intel_spi_dump_regs() argument
169 dev_dbg(ispi->dev, "BFPREG=0x%08x\n", readl(ispi->base + BFPREG)); in intel_spi_dump_regs()
171 value = readl(ispi->base + HSFSTS_CTL); in intel_spi_dump_regs()
172 dev_dbg(ispi->dev, "HSFSTS_CTL=0x%08x\n", value); in intel_spi_dump_regs()
174 dev_dbg(ispi->dev, "-> Locked\n"); in intel_spi_dump_regs()
176 dev_dbg(ispi->dev, "FADDR=0x%08x\n", readl(ispi->base + FADDR)); in intel_spi_dump_regs()
177 dev_dbg(ispi->dev, "DLOCK=0x%08x\n", readl(ispi->base + DLOCK)); in intel_spi_dump_regs()
180 dev_dbg(ispi->dev, "FDATA(%d)=0x%08x\n", in intel_spi_dump_regs()
181 i, readl(ispi->base + FDATA(i))); in intel_spi_dump_regs()
183 dev_dbg(ispi->dev, "FRACC=0x%08x\n", readl(ispi->base + FRACC)); in intel_spi_dump_regs()
185 for (i = 0; i < ispi->nregions; i++) in intel_spi_dump_regs()
186 dev_dbg(ispi->dev, "FREG(%d)=0x%08x\n", i, in intel_spi_dump_regs()
187 readl(ispi->base + FREG(i))); in intel_spi_dump_regs()
188 for (i = 0; i < ispi->pr_num; i++) in intel_spi_dump_regs()
189 dev_dbg(ispi->dev, "PR(%d)=0x%08x\n", i, in intel_spi_dump_regs()
190 readl(ispi->pregs + PR(i))); in intel_spi_dump_regs()
192 if (ispi->sregs) { in intel_spi_dump_regs()
193 value = readl(ispi->sregs + SSFSTS_CTL); in intel_spi_dump_regs()
194 dev_dbg(ispi->dev, "SSFSTS_CTL=0x%08x\n", value); in intel_spi_dump_regs()
195 dev_dbg(ispi->dev, "PREOP_OPTYPE=0x%08x\n", in intel_spi_dump_regs()
196 readl(ispi->sregs + PREOP_OPTYPE)); in intel_spi_dump_regs()
197 dev_dbg(ispi->dev, "OPMENU0=0x%08x\n", in intel_spi_dump_regs()
198 readl(ispi->sregs + OPMENU0)); in intel_spi_dump_regs()
199 dev_dbg(ispi->dev, "OPMENU1=0x%08x\n", in intel_spi_dump_regs()
200 readl(ispi->sregs + OPMENU1)); in intel_spi_dump_regs()
203 if (ispi->info->type == INTEL_SPI_BYT) in intel_spi_dump_regs()
204 dev_dbg(ispi->dev, "BCR=0x%08x\n", readl(ispi->base + BYT_BCR)); in intel_spi_dump_regs()
206 dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC)); in intel_spi_dump_regs()
207 dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC)); in intel_spi_dump_regs()
209 dev_dbg(ispi->dev, "Protected regions:\n"); in intel_spi_dump_regs()
210 for (i = 0; i < ispi->pr_num; i++) { in intel_spi_dump_regs()
213 value = readl(ispi->pregs + PR(i)); in intel_spi_dump_regs()
220 dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x [%c%c]\n", in intel_spi_dump_regs()
226 dev_dbg(ispi->dev, "Flash regions:\n"); in intel_spi_dump_regs()
227 for (i = 0; i < ispi->nregions; i++) { in intel_spi_dump_regs()
230 region = readl(ispi->base + FREG(i)); in intel_spi_dump_regs()
235 dev_dbg(ispi->dev, " %02d disabled\n", i); in intel_spi_dump_regs()
237 dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x\n", in intel_spi_dump_regs()
241 dev_dbg(ispi->dev, "Using %cW sequencer for register access\n", in intel_spi_dump_regs()
242 ispi->swseq_reg ? 'S' : 'H'); in intel_spi_dump_regs()
243 dev_dbg(ispi->dev, "Using %cW sequencer for erase operation\n", in intel_spi_dump_regs()
244 ispi->swseq_erase ? 'S' : 'H'); in intel_spi_dump_regs()
248 static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size) in intel_spi_read_block() argument
258 memcpy_fromio(buf, ispi->base + FDATA(i), bytes); in intel_spi_read_block()
268 static int intel_spi_write_block(struct intel_spi *ispi, const void *buf, in intel_spi_write_block() argument
279 memcpy_toio(ispi->base + FDATA(i), buf, bytes); in intel_spi_write_block()
288 static int intel_spi_wait_hw_busy(struct intel_spi *ispi) in intel_spi_wait_hw_busy() argument
292 return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, in intel_spi_wait_hw_busy()
297 static int intel_spi_wait_sw_busy(struct intel_spi *ispi) in intel_spi_wait_sw_busy() argument
301 return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, in intel_spi_wait_sw_busy()
306 static bool intel_spi_set_writeable(struct intel_spi *ispi) in intel_spi_set_writeable() argument
308 if (!ispi->info->set_writeable) in intel_spi_set_writeable()
311 return ispi->info->set_writeable(ispi->base, ispi->info->data); in intel_spi_set_writeable()
314 static int intel_spi_init(struct intel_spi *ispi) in intel_spi_init() argument
319 switch (ispi->info->type) { in intel_spi_init()
321 ispi->sregs = ispi->base + BYT_SSFSTS_CTL; in intel_spi_init()
322 ispi->pregs = ispi->base + BYT_PR; in intel_spi_init()
323 ispi->nregions = BYT_FREG_NUM; in intel_spi_init()
324 ispi->pr_num = BYT_PR_NUM; in intel_spi_init()
325 ispi->swseq_reg = true; in intel_spi_init()
329 ispi->sregs = ispi->base + LPT_SSFSTS_CTL; in intel_spi_init()
330 ispi->pregs = ispi->base + LPT_PR; in intel_spi_init()
331 ispi->nregions = LPT_FREG_NUM; in intel_spi_init()
332 ispi->pr_num = LPT_PR_NUM; in intel_spi_init()
333 ispi->swseq_reg = true; in intel_spi_init()
337 ispi->sregs = ispi->base + BXT_SSFSTS_CTL; in intel_spi_init()
338 ispi->pregs = ispi->base + BXT_PR; in intel_spi_init()
339 ispi->nregions = BXT_FREG_NUM; in intel_spi_init()
340 ispi->pr_num = BXT_PR_NUM; in intel_spi_init()
341 ispi->erase_64k = true; in intel_spi_init()
345 ispi->sregs = NULL; in intel_spi_init()
346 ispi->pregs = ispi->base + CNL_PR; in intel_spi_init()
347 ispi->nregions = CNL_FREG_NUM; in intel_spi_init()
348 ispi->pr_num = CNL_PR_NUM; in intel_spi_init()
356 if (writeable && !intel_spi_set_writeable(ispi)) { in intel_spi_init()
357 dev_warn(ispi->dev, "can't disable chip write protection\n"); in intel_spi_init()
362 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_init()
364 writel(val, ispi->base + HSFSTS_CTL); in intel_spi_init()
374 lvscc = readl(ispi->base + LVSCC); in intel_spi_init()
375 uvscc = readl(ispi->base + UVSCC); in intel_spi_init()
377 ispi->swseq_erase = true; in intel_spi_init()
379 if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase) in intel_spi_init()
382 ispi->erase_64k = false; in intel_spi_init()
384 if (ispi->sregs == NULL && (ispi->swseq_reg || ispi->swseq_erase)) { in intel_spi_init()
385 dev_err(ispi->dev, "software sequencer not supported, but required\n"); in intel_spi_init()
394 if (ispi->swseq_reg) { in intel_spi_init()
396 val = readl(ispi->sregs + SSFSTS_CTL); in intel_spi_init()
398 writel(val, ispi->sregs + SSFSTS_CTL); in intel_spi_init()
402 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_init()
403 ispi->locked = !!(val & HSFSTS_CTL_FLOCKDN); in intel_spi_init()
405 if (ispi->locked && ispi->sregs) { in intel_spi_init()
411 opmenu0 = readl(ispi->sregs + OPMENU0); in intel_spi_init()
412 opmenu1 = readl(ispi->sregs + OPMENU1); in intel_spi_init()
415 for (i = 0; i < ARRAY_SIZE(ispi->opcodes) / 2; i++) { in intel_spi_init()
416 ispi->opcodes[i] = opmenu0 >> i * 8; in intel_spi_init()
417 ispi->opcodes[i + 4] = opmenu1 >> i * 8; in intel_spi_init()
422 intel_spi_dump_regs(ispi); in intel_spi_init()
427 static int intel_spi_opcode_index(struct intel_spi *ispi, u8 opcode, int optype) in intel_spi_opcode_index() argument
432 if (ispi->locked) { in intel_spi_opcode_index()
433 for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) in intel_spi_opcode_index()
434 if (ispi->opcodes[i] == opcode) in intel_spi_opcode_index()
441 writel(opcode, ispi->sregs + OPMENU0); in intel_spi_opcode_index()
442 preop = readw(ispi->sregs + PREOP_OPTYPE); in intel_spi_opcode_index()
443 writel(optype << 16 | preop, ispi->sregs + PREOP_OPTYPE); in intel_spi_opcode_index()
448 static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len) in intel_spi_hw_cycle() argument
453 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_hw_cycle()
476 writel(val, ispi->base + HSFSTS_CTL); in intel_spi_hw_cycle()
478 ret = intel_spi_wait_hw_busy(ispi); in intel_spi_hw_cycle()
482 status = readl(ispi->base + HSFSTS_CTL); in intel_spi_hw_cycle()
491 static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, in intel_spi_sw_cycle() argument
498 ret = intel_spi_opcode_index(ispi, opcode, optype); in intel_spi_sw_cycle()
509 atomic_preopcode = ispi->atomic_preopcode; in intel_spi_sw_cycle()
510 ispi->atomic_preopcode = 0; in intel_spi_sw_cycle()
525 preop = readw(ispi->sregs + PREOP_OPTYPE); in intel_spi_sw_cycle()
542 writel(val, ispi->sregs + SSFSTS_CTL); in intel_spi_sw_cycle()
544 ret = intel_spi_wait_sw_busy(ispi); in intel_spi_sw_cycle()
548 status = readl(ispi->sregs + SSFSTS_CTL); in intel_spi_sw_cycle()
560 struct intel_spi *ispi = nor->priv; in intel_spi_read_reg() local
564 writel(0, ispi->base + FADDR); in intel_spi_read_reg()
566 if (ispi->swseq_reg) in intel_spi_read_reg()
567 ret = intel_spi_sw_cycle(ispi, opcode, len, in intel_spi_read_reg()
570 ret = intel_spi_hw_cycle(ispi, opcode, len); in intel_spi_read_reg()
575 return intel_spi_read_block(ispi, buf, len); in intel_spi_read_reg()
581 struct intel_spi *ispi = nor->priv; in intel_spi_write_reg() local
596 if (!ispi->swseq_reg) in intel_spi_write_reg()
599 preop = readw(ispi->sregs + PREOP_OPTYPE); in intel_spi_write_reg()
601 if (ispi->locked) in intel_spi_write_reg()
603 writel(opcode, ispi->sregs + PREOP_OPTYPE); in intel_spi_write_reg()
610 ispi->atomic_preopcode = opcode; in intel_spi_write_reg()
623 writel(0, ispi->base + FADDR); in intel_spi_write_reg()
626 ret = intel_spi_write_block(ispi, buf, len); in intel_spi_write_reg()
630 if (ispi->swseq_reg) in intel_spi_write_reg()
631 return intel_spi_sw_cycle(ispi, opcode, len, in intel_spi_write_reg()
633 return intel_spi_hw_cycle(ispi, opcode, len); in intel_spi_write_reg()
639 struct intel_spi *ispi = nor->priv; in intel_spi_read() local
648 if (WARN_ON_ONCE(ispi->atomic_preopcode)) in intel_spi_read()
649 ispi->atomic_preopcode = 0; in intel_spi_read()
668 writel(from, ispi->base + FADDR); in intel_spi_read()
670 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_read()
676 writel(val, ispi->base + HSFSTS_CTL); in intel_spi_read()
678 ret = intel_spi_wait_hw_busy(ispi); in intel_spi_read()
682 status = readl(ispi->base + HSFSTS_CTL); in intel_spi_read()
689 dev_err(ispi->dev, "read error: %llx: %#x\n", from, in intel_spi_read()
694 ret = intel_spi_read_block(ispi, read_buf, block_size); in intel_spi_read()
710 struct intel_spi *ispi = nor->priv; in intel_spi_write() local
716 ispi->atomic_preopcode = 0; in intel_spi_write()
725 writel(to, ispi->base + FADDR); in intel_spi_write()
727 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_write()
733 ret = intel_spi_write_block(ispi, write_buf, block_size); in intel_spi_write()
735 dev_err(ispi->dev, "failed to write block\n"); in intel_spi_write()
741 writel(val, ispi->base + HSFSTS_CTL); in intel_spi_write()
743 ret = intel_spi_wait_hw_busy(ispi); in intel_spi_write()
745 dev_err(ispi->dev, "timeout\n"); in intel_spi_write()
749 status = readl(ispi->base + HSFSTS_CTL); in intel_spi_write()
756 dev_err(ispi->dev, "write error: %llx: %#x\n", to, in intel_spi_write()
773 struct intel_spi *ispi = nor->priv; in intel_spi_erase() local
778 if (len >= SZ_64K && ispi->erase_64k) { in intel_spi_erase()
786 if (ispi->swseq_erase) { in intel_spi_erase()
788 writel(offs, ispi->base + FADDR); in intel_spi_erase()
790 ret = intel_spi_sw_cycle(ispi, nor->erase_opcode, in intel_spi_erase()
803 ispi->atomic_preopcode = 0; in intel_spi_erase()
806 writel(offs, ispi->base + FADDR); in intel_spi_erase()
808 val = readl(ispi->base + HSFSTS_CTL); in intel_spi_erase()
813 writel(val, ispi->base + HSFSTS_CTL); in intel_spi_erase()
815 ret = intel_spi_wait_hw_busy(ispi); in intel_spi_erase()
819 status = readl(ispi->base + HSFSTS_CTL); in intel_spi_erase()
832 static bool intel_spi_is_protected(const struct intel_spi *ispi, in intel_spi_is_protected() argument
837 for (i = 0; i < ispi->pr_num; i++) { in intel_spi_is_protected()
840 pr_value = readl(ispi->pregs + PR(i)); in intel_spi_is_protected()
858 static void intel_spi_fill_partition(struct intel_spi *ispi, in intel_spi_fill_partition() argument
874 for (i = 1; i < ispi->nregions; i++) { in intel_spi_fill_partition()
877 region = readl(ispi->base + FREG(i)); in intel_spi_fill_partition()
891 if (!writeable || intel_spi_is_protected(ispi, base, limit)) in intel_spi_fill_partition()
917 struct intel_spi *ispi; in intel_spi_probe() local
923 ispi = devm_kzalloc(dev, sizeof(*ispi), GFP_KERNEL); in intel_spi_probe()
924 if (!ispi) in intel_spi_probe()
927 ispi->base = devm_ioremap_resource(dev, mem); in intel_spi_probe()
928 if (IS_ERR(ispi->base)) in intel_spi_probe()
929 return ERR_CAST(ispi->base); in intel_spi_probe()
931 ispi->dev = dev; in intel_spi_probe()
932 ispi->info = info; in intel_spi_probe()
934 ret = intel_spi_init(ispi); in intel_spi_probe()
938 ispi->nor.dev = ispi->dev; in intel_spi_probe()
939 ispi->nor.priv = ispi; in intel_spi_probe()
940 ispi->nor.controller_ops = &intel_spi_controller_ops; in intel_spi_probe()
942 ret = spi_nor_scan(&ispi->nor, NULL, &hwcaps); in intel_spi_probe()
948 intel_spi_fill_partition(ispi, &part); in intel_spi_probe()
950 ret = mtd_device_register(&ispi->nor.mtd, &part, 1); in intel_spi_probe()
954 return ispi; in intel_spi_probe()
958 int intel_spi_remove(struct intel_spi *ispi) in intel_spi_remove() argument
960 return mtd_device_unregister(&ispi->nor.mtd); in intel_spi_remove()