Lines Matching full:qspi

25 #include "spi-bcm-qspi.h"
234 static inline bool has_bspi(struct bcm_qspi *qspi) in has_bspi() argument
236 return qspi->bspi_mode; in has_bspi()
240 static inline bool bcm_qspi_has_fastbr(struct bcm_qspi *qspi) in bcm_qspi_has_fastbr() argument
242 if (!has_bspi(qspi) && in bcm_qspi_has_fastbr()
243 ((qspi->mspi_maj_rev >= 1) && in bcm_qspi_has_fastbr()
244 (qspi->mspi_min_rev >= 5))) in bcm_qspi_has_fastbr()
251 static inline bool bcm_qspi_has_sysclk_108(struct bcm_qspi *qspi) in bcm_qspi_has_sysclk_108() argument
253 if (!has_bspi(qspi) && (qspi->mspi_spcr3_sysclk || in bcm_qspi_has_sysclk_108()
254 ((qspi->mspi_maj_rev >= 1) && in bcm_qspi_has_sysclk_108()
255 (qspi->mspi_min_rev >= 6)))) in bcm_qspi_has_sysclk_108()
261 static inline int bcm_qspi_spbr_min(struct bcm_qspi *qspi) in bcm_qspi_spbr_min() argument
263 if (bcm_qspi_has_fastbr(qspi)) in bcm_qspi_spbr_min()
269 /* Read qspi controller register*/
270 static inline u32 bcm_qspi_read(struct bcm_qspi *qspi, enum base_type type, in bcm_qspi_read() argument
273 return bcm_qspi_readl(qspi->big_endian, qspi->base[type] + offset); in bcm_qspi_read()
276 /* Write qspi controller register*/
277 static inline void bcm_qspi_write(struct bcm_qspi *qspi, enum base_type type, in bcm_qspi_write() argument
280 bcm_qspi_writel(qspi->big_endian, data, qspi->base[type] + offset); in bcm_qspi_write()
284 static int bcm_qspi_bspi_busy_poll(struct bcm_qspi *qspi) in bcm_qspi_bspi_busy_poll() argument
290 if (!(bcm_qspi_read(qspi, BSPI, BSPI_BUSY_STATUS) & 1)) in bcm_qspi_bspi_busy_poll()
294 dev_warn(&qspi->pdev->dev, "timeout waiting for !busy_status\n"); in bcm_qspi_bspi_busy_poll()
298 static inline bool bcm_qspi_bspi_ver_three(struct bcm_qspi *qspi) in bcm_qspi_bspi_ver_three() argument
300 if (qspi->bspi_maj_rev < 4) in bcm_qspi_bspi_ver_three()
305 static void bcm_qspi_bspi_flush_prefetch_buffers(struct bcm_qspi *qspi) in bcm_qspi_bspi_flush_prefetch_buffers() argument
307 bcm_qspi_bspi_busy_poll(qspi); in bcm_qspi_bspi_flush_prefetch_buffers()
309 bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 1); in bcm_qspi_bspi_flush_prefetch_buffers()
310 bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 1); in bcm_qspi_bspi_flush_prefetch_buffers()
311 bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0); in bcm_qspi_bspi_flush_prefetch_buffers()
312 bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0); in bcm_qspi_bspi_flush_prefetch_buffers()
315 static int bcm_qspi_bspi_lr_is_fifo_empty(struct bcm_qspi *qspi) in bcm_qspi_bspi_lr_is_fifo_empty() argument
317 return (bcm_qspi_read(qspi, BSPI, BSPI_RAF_STATUS) & in bcm_qspi_bspi_lr_is_fifo_empty()
321 static inline u32 bcm_qspi_bspi_lr_read_fifo(struct bcm_qspi *qspi) in bcm_qspi_bspi_lr_read_fifo() argument
323 u32 data = bcm_qspi_read(qspi, BSPI, BSPI_RAF_READ_DATA); in bcm_qspi_bspi_lr_read_fifo()
326 if (bcm_qspi_bspi_ver_three(qspi)) in bcm_qspi_bspi_lr_read_fifo()
332 static inline void bcm_qspi_bspi_lr_start(struct bcm_qspi *qspi) in bcm_qspi_bspi_lr_start() argument
334 bcm_qspi_bspi_busy_poll(qspi); in bcm_qspi_bspi_lr_start()
335 bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL, in bcm_qspi_bspi_lr_start()
339 static inline void bcm_qspi_bspi_lr_clear(struct bcm_qspi *qspi) in bcm_qspi_bspi_lr_clear() argument
341 bcm_qspi_write(qspi, BSPI, BSPI_RAF_CTRL, in bcm_qspi_bspi_lr_clear()
343 bcm_qspi_bspi_flush_prefetch_buffers(qspi); in bcm_qspi_bspi_lr_clear()
346 static void bcm_qspi_bspi_lr_data_read(struct bcm_qspi *qspi) in bcm_qspi_bspi_lr_data_read() argument
348 u32 *buf = (u32 *)qspi->bspi_rf_op->data.buf.in; in bcm_qspi_bspi_lr_data_read()
351 dev_dbg(&qspi->pdev->dev, "xfer %p rx %p rxlen %d\n", qspi->bspi_rf_op, in bcm_qspi_bspi_lr_data_read()
352 qspi->bspi_rf_op->data.buf.in, qspi->bspi_rf_op_len); in bcm_qspi_bspi_lr_data_read()
353 while (!bcm_qspi_bspi_lr_is_fifo_empty(qspi)) { in bcm_qspi_bspi_lr_data_read()
354 data = bcm_qspi_bspi_lr_read_fifo(qspi); in bcm_qspi_bspi_lr_data_read()
355 if (likely(qspi->bspi_rf_op_len >= 4) && in bcm_qspi_bspi_lr_data_read()
357 buf[qspi->bspi_rf_op_idx++] = data; in bcm_qspi_bspi_lr_data_read()
358 qspi->bspi_rf_op_len -= 4; in bcm_qspi_bspi_lr_data_read()
361 u8 *cbuf = (u8 *)&buf[qspi->bspi_rf_op_idx]; in bcm_qspi_bspi_lr_data_read()
364 while (qspi->bspi_rf_op_len) { in bcm_qspi_bspi_lr_data_read()
367 qspi->bspi_rf_op_len--; in bcm_qspi_bspi_lr_data_read()
373 static void bcm_qspi_bspi_set_xfer_params(struct bcm_qspi *qspi, u8 cmd_byte, in bcm_qspi_bspi_set_xfer_params() argument
376 bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); in bcm_qspi_bspi_set_xfer_params()
377 bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_CYCLE, bpc); in bcm_qspi_bspi_set_xfer_params()
378 bcm_qspi_write(qspi, BSPI, BSPI_BITS_PER_PHASE, bpp); in bcm_qspi_bspi_set_xfer_params()
379 bcm_qspi_write(qspi, BSPI, BSPI_CMD_AND_MODE_BYTE, cmd_byte); in bcm_qspi_bspi_set_xfer_params()
380 bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, flex_mode); in bcm_qspi_bspi_set_xfer_params()
383 static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, in bcm_qspi_bspi_set_flex_mode() argument
392 dev_dbg(&qspi->pdev->dev, "set flex mode w %x addrlen %x hp %d\n", in bcm_qspi_bspi_set_flex_mode()
424 bcm_qspi_bspi_set_xfer_params(qspi, command, bpp, bpc, flex_mode); in bcm_qspi_bspi_set_flex_mode()
429 static int bcm_qspi_bspi_set_override(struct bcm_qspi *qspi, in bcm_qspi_bspi_set_override() argument
434 u32 data = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); in bcm_qspi_bspi_set_override()
436 dev_dbg(&qspi->pdev->dev, "set override mode w %x addrlen %x hp %d\n", in bcm_qspi_bspi_set_override()
468 bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, data); in bcm_qspi_bspi_set_override()
469 bcm_qspi_bspi_set_xfer_params(qspi, op->cmd.opcode, 0, 0, 0); in bcm_qspi_bspi_set_override()
474 static int bcm_qspi_bspi_set_mode(struct bcm_qspi *qspi, in bcm_qspi_bspi_set_mode() argument
482 qspi->xfer_mode.flex_mode = true; in bcm_qspi_bspi_set_mode()
484 if (!bcm_qspi_bspi_ver_three(qspi)) { in bcm_qspi_bspi_set_mode()
487 val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); in bcm_qspi_bspi_set_mode()
489 if (val & mask || qspi->s3_strap_override_ctrl & mask) { in bcm_qspi_bspi_set_mode()
490 qspi->xfer_mode.flex_mode = false; in bcm_qspi_bspi_set_mode()
491 bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); in bcm_qspi_bspi_set_mode()
492 error = bcm_qspi_bspi_set_override(qspi, op, hp); in bcm_qspi_bspi_set_mode()
496 if (qspi->xfer_mode.flex_mode) in bcm_qspi_bspi_set_mode()
497 error = bcm_qspi_bspi_set_flex_mode(qspi, op, hp); in bcm_qspi_bspi_set_mode()
500 dev_warn(&qspi->pdev->dev, in bcm_qspi_bspi_set_mode()
503 } else if (qspi->xfer_mode.width != width || in bcm_qspi_bspi_set_mode()
504 qspi->xfer_mode.addrlen != addrlen || in bcm_qspi_bspi_set_mode()
505 qspi->xfer_mode.hp != hp) { in bcm_qspi_bspi_set_mode()
506 qspi->xfer_mode.width = width; in bcm_qspi_bspi_set_mode()
507 qspi->xfer_mode.addrlen = addrlen; in bcm_qspi_bspi_set_mode()
508 qspi->xfer_mode.hp = hp; in bcm_qspi_bspi_set_mode()
509 dev_dbg(&qspi->pdev->dev, in bcm_qspi_bspi_set_mode()
511 qspi->curr_cs, in bcm_qspi_bspi_set_mode()
512 qspi->xfer_mode.width, in bcm_qspi_bspi_set_mode()
513 qspi->xfer_mode.addrlen, in bcm_qspi_bspi_set_mode()
514 qspi->xfer_mode.hp != -1 ? ", hp mode" : ""); in bcm_qspi_bspi_set_mode()
520 static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi) in bcm_qspi_enable_bspi() argument
522 if (!has_bspi(qspi)) in bcm_qspi_enable_bspi()
525 qspi->bspi_enabled = 1; in bcm_qspi_enable_bspi()
526 if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1) == 0) in bcm_qspi_enable_bspi()
529 bcm_qspi_bspi_flush_prefetch_buffers(qspi); in bcm_qspi_enable_bspi()
531 bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 0); in bcm_qspi_enable_bspi()
535 static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi) in bcm_qspi_disable_bspi() argument
537 if (!has_bspi(qspi)) in bcm_qspi_disable_bspi()
540 qspi->bspi_enabled = 0; in bcm_qspi_disable_bspi()
541 if ((bcm_qspi_read(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL) & 1)) in bcm_qspi_disable_bspi()
544 bcm_qspi_bspi_busy_poll(qspi); in bcm_qspi_disable_bspi()
545 bcm_qspi_write(qspi, BSPI, BSPI_MAST_N_BOOT_CTRL, 1); in bcm_qspi_disable_bspi()
549 static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs) in bcm_qspi_chip_select() argument
554 if (qspi->base[CHIP_SELECT]) { in bcm_qspi_chip_select()
555 rd = bcm_qspi_read(qspi, CHIP_SELECT, 0); in bcm_qspi_chip_select()
559 bcm_qspi_write(qspi, CHIP_SELECT, 0, wr); in bcm_qspi_chip_select()
563 dev_dbg(&qspi->pdev->dev, "using cs:%d\n", cs); in bcm_qspi_chip_select()
564 qspi->curr_cs = cs; in bcm_qspi_chip_select()
568 static void bcm_qspi_hw_set_parms(struct bcm_qspi *qspi, in bcm_qspi_hw_set_parms() argument
574 spbr = qspi->base_clk / (2 * xp->speed_hz); in bcm_qspi_hw_set_parms()
576 spcr = clamp_val(spbr, bcm_qspi_spbr_min(qspi), QSPI_SPBR_MAX); in bcm_qspi_hw_set_parms()
577 bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, spcr); in bcm_qspi_hw_set_parms()
579 if (!qspi->mspi_maj_rev) in bcm_qspi_hw_set_parms()
590 bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_MSB, spcr); in bcm_qspi_hw_set_parms()
592 if (bcm_qspi_has_fastbr(qspi)) { in bcm_qspi_hw_set_parms()
598 if (bcm_qspi_has_sysclk_108(qspi)) { in bcm_qspi_hw_set_parms()
601 qspi->base_clk = MSPI_BASE_FREQ * 4; in bcm_qspi_hw_set_parms()
603 bcm_qspi_write(qspi, MSPI, MSPI_SPCR0_LSB, 4); in bcm_qspi_hw_set_parms()
606 bcm_qspi_write(qspi, MSPI, MSPI_SPCR3, spcr); in bcm_qspi_hw_set_parms()
609 qspi->last_parms = *xp; in bcm_qspi_hw_set_parms()
612 static void bcm_qspi_update_parms(struct bcm_qspi *qspi, in bcm_qspi_update_parms() argument
622 bcm_qspi_hw_set_parms(qspi, &xp); in bcm_qspi_update_parms()
650 static bool bcm_qspi_mspi_transfer_is_last(struct bcm_qspi *qspi, in bcm_qspi_mspi_transfer_is_last() argument
654 spi_transfer_is_last(qspi->master, qt->trans)) in bcm_qspi_mspi_transfer_is_last()
660 static int update_qspi_trans_byte_count(struct bcm_qspi *qspi, in update_qspi_trans_byte_count() argument
681 if (bcm_qspi_mspi_transfer_is_last(qspi, qt)) in update_qspi_trans_byte_count()
689 dev_dbg(&qspi->pdev->dev, "trans %p len %d byte %d ret %x\n", in update_qspi_trans_byte_count()
694 static inline u8 read_rxram_slot_u8(struct bcm_qspi *qspi, int slot) in read_rxram_slot_u8() argument
699 return bcm_qspi_read(qspi, MSPI, slot_offset) & 0xff; in read_rxram_slot_u8()
702 static inline u16 read_rxram_slot_u16(struct bcm_qspi *qspi, int slot) in read_rxram_slot_u16() argument
708 return (bcm_qspi_read(qspi, MSPI, lsb_offset) & 0xff) | in read_rxram_slot_u16()
709 ((bcm_qspi_read(qspi, MSPI, msb_offset) & 0xff) << 8); in read_rxram_slot_u16()
712 static void read_from_hw(struct bcm_qspi *qspi, int slots) in read_from_hw() argument
717 bcm_qspi_disable_bspi(qspi); in read_from_hw()
721 dev_err(&qspi->pdev->dev, "%s: too many slots!\n", __func__); in read_from_hw()
725 tp = qspi->trans_pos; in read_from_hw()
732 buf[tp.byte] = read_rxram_slot_u8(qspi, slot); in read_from_hw()
733 dev_dbg(&qspi->pdev->dev, "RD %02x\n", in read_from_hw()
739 buf[tp.byte / 2] = read_rxram_slot_u16(qspi, in read_from_hw()
741 dev_dbg(&qspi->pdev->dev, "RD %04x\n", in read_from_hw()
745 update_qspi_trans_byte_count(qspi, &tp, in read_from_hw()
749 qspi->trans_pos = tp; in read_from_hw()
752 static inline void write_txram_slot_u8(struct bcm_qspi *qspi, int slot, in write_txram_slot_u8() argument
758 bcm_qspi_write(qspi, MSPI, reg_offset, val); in write_txram_slot_u8()
761 static inline void write_txram_slot_u16(struct bcm_qspi *qspi, int slot, in write_txram_slot_u16() argument
768 bcm_qspi_write(qspi, MSPI, msb_offset, (val >> 8)); in write_txram_slot_u16()
769 bcm_qspi_write(qspi, MSPI, lsb_offset, (val & 0xff)); in write_txram_slot_u16()
772 static inline u32 read_cdram_slot(struct bcm_qspi *qspi, int slot) in read_cdram_slot() argument
774 return bcm_qspi_read(qspi, MSPI, MSPI_CDRAM + (slot << 2)); in read_cdram_slot()
777 static inline void write_cdram_slot(struct bcm_qspi *qspi, int slot, u32 val) in write_cdram_slot() argument
779 bcm_qspi_write(qspi, MSPI, (MSPI_CDRAM + (slot << 2)), val); in write_cdram_slot()
783 static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi) in write_to_hw() argument
789 bcm_qspi_disable_bspi(qspi); in write_to_hw()
790 tp = qspi->trans_pos; in write_to_hw()
791 bcm_qspi_update_parms(qspi, spi, tp.trans); in write_to_hw()
799 write_txram_slot_u8(qspi, slot, val); in write_to_hw()
800 dev_dbg(&qspi->pdev->dev, "WR %02x\n", val); in write_to_hw()
805 write_txram_slot_u16(qspi, slot, val); in write_to_hw()
806 dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); in write_to_hw()
810 if (has_bspi(qspi)) in write_to_hw()
819 write_cdram_slot(qspi, slot, mspi_cdram); in write_to_hw()
821 tstatus = update_qspi_trans_byte_count(qspi, &tp, in write_to_hw()
827 dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__); in write_to_hw()
831 dev_dbg(&qspi->pdev->dev, "submitting %d slots\n", slot); in write_to_hw()
832 bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0); in write_to_hw()
833 bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, slot - 1); in write_to_hw()
845 mspi_cdram = read_cdram_slot(qspi, slot - 1) & in write_to_hw()
847 write_cdram_slot(qspi, slot - 1, mspi_cdram); in write_to_hw()
850 if (has_bspi(qspi)) in write_to_hw()
851 bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 1); in write_to_hw()
856 bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0xe0); in write_to_hw()
865 struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); in bcm_qspi_bspi_exec_mem_op() local
869 struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; in bcm_qspi_bspi_exec_mem_op()
871 if (bcm_qspi_bspi_ver_three(qspi)) in bcm_qspi_bspi_exec_mem_op()
877 bcm_qspi_chip_select(qspi, spi->chip_select); in bcm_qspi_bspi_exec_mem_op()
878 bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); in bcm_qspi_bspi_exec_mem_op()
884 if (bcm_qspi_bspi_ver_three(qspi) == false) { in bcm_qspi_bspi_exec_mem_op()
886 bcm_qspi_write(qspi, BSPI, in bcm_qspi_bspi_exec_mem_op()
890 if (!qspi->xfer_mode.flex_mode) in bcm_qspi_bspi_exec_mem_op()
895 if (bcm_qspi_bspi_ver_three(qspi) == true) in bcm_qspi_bspi_exec_mem_op()
903 qspi->bspi_rf_op_idx = 0; in bcm_qspi_bspi_exec_mem_op()
911 reinit_completion(&qspi->bspi_done); in bcm_qspi_bspi_exec_mem_op()
912 bcm_qspi_enable_bspi(qspi); in bcm_qspi_bspi_exec_mem_op()
914 qspi->bspi_rf_op = op; in bcm_qspi_bspi_exec_mem_op()
915 qspi->bspi_rf_op_status = 0; in bcm_qspi_bspi_exec_mem_op()
916 qspi->bspi_rf_op_len = rdlen; in bcm_qspi_bspi_exec_mem_op()
917 dev_dbg(&qspi->pdev->dev, in bcm_qspi_bspi_exec_mem_op()
919 bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); in bcm_qspi_bspi_exec_mem_op()
920 bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); in bcm_qspi_bspi_exec_mem_op()
921 bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); in bcm_qspi_bspi_exec_mem_op()
922 if (qspi->soc_intc) { in bcm_qspi_bspi_exec_mem_op()
933 bcm_qspi_bspi_lr_start(qspi); in bcm_qspi_bspi_exec_mem_op()
934 if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { in bcm_qspi_bspi_exec_mem_op()
935 dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); in bcm_qspi_bspi_exec_mem_op()
952 struct bcm_qspi *qspi = spi_master_get_devdata(master); in bcm_qspi_transfer_one() local
957 bcm_qspi_chip_select(qspi, spi->chip_select); in bcm_qspi_transfer_one()
958 qspi->trans_pos.trans = trans; in bcm_qspi_transfer_one()
959 qspi->trans_pos.byte = 0; in bcm_qspi_transfer_one()
961 while (qspi->trans_pos.byte < trans->len) { in bcm_qspi_transfer_one()
962 reinit_completion(&qspi->mspi_done); in bcm_qspi_transfer_one()
964 slots = write_to_hw(qspi, spi); in bcm_qspi_transfer_one()
965 if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { in bcm_qspi_transfer_one()
966 dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); in bcm_qspi_transfer_one()
970 read_from_hw(qspi, slots); in bcm_qspi_transfer_one()
972 bcm_qspi_enable_bspi(qspi); in bcm_qspi_transfer_one()
981 struct bcm_qspi *qspi = spi_master_get_devdata(master); in bcm_qspi_mspi_exec_mem_op() local
1000 qspi->trans_pos.mspi_last_trans = false; in bcm_qspi_mspi_exec_mem_op()
1004 qspi->trans_pos.mspi_last_trans = true; in bcm_qspi_mspi_exec_mem_op()
1021 struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); in bcm_qspi_exec_mem_op() local
1035 if (bcm_qspi_bspi_ver_three(qspi) == true) { in bcm_qspi_exec_mem_op()
1057 ret = bcm_qspi_bspi_set_mode(qspi, op, 0); in bcm_qspi_exec_mem_op()
1075 struct bcm_qspi *qspi = qspi_dev_id->dev; in bcm_qspi_mspi_l2_isr() local
1076 u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS); in bcm_qspi_mspi_l2_isr()
1079 struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; in bcm_qspi_mspi_l2_isr()
1082 bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status); in bcm_qspi_mspi_l2_isr()
1083 if (qspi->soc_intc) in bcm_qspi_mspi_l2_isr()
1085 complete(&qspi->mspi_done); in bcm_qspi_mspi_l2_isr()
1095 struct bcm_qspi *qspi = qspi_dev_id->dev; in bcm_qspi_bspi_lr_l2_isr() local
1096 struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; in bcm_qspi_bspi_lr_l2_isr()
1099 if (qspi->bspi_enabled && qspi->bspi_rf_op) { in bcm_qspi_bspi_lr_l2_isr()
1100 bcm_qspi_bspi_lr_data_read(qspi); in bcm_qspi_bspi_lr_l2_isr()
1101 if (qspi->bspi_rf_op_len == 0) { in bcm_qspi_bspi_lr_l2_isr()
1102 qspi->bspi_rf_op = NULL; in bcm_qspi_bspi_lr_l2_isr()
1103 if (qspi->soc_intc) { in bcm_qspi_bspi_lr_l2_isr()
1111 if (qspi->bspi_rf_op_status) in bcm_qspi_bspi_lr_l2_isr()
1112 bcm_qspi_bspi_lr_clear(qspi); in bcm_qspi_bspi_lr_l2_isr()
1114 bcm_qspi_bspi_flush_prefetch_buffers(qspi); in bcm_qspi_bspi_lr_l2_isr()
1117 if (qspi->soc_intc) in bcm_qspi_bspi_lr_l2_isr()
1123 if (qspi->bspi_enabled && status && qspi->bspi_rf_op_len == 0) in bcm_qspi_bspi_lr_l2_isr()
1124 complete(&qspi->bspi_done); in bcm_qspi_bspi_lr_l2_isr()
1132 struct bcm_qspi *qspi = qspi_dev_id->dev; in bcm_qspi_bspi_lr_err_l2_isr() local
1133 struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; in bcm_qspi_bspi_lr_err_l2_isr()
1135 dev_err(&qspi->pdev->dev, "BSPI INT error\n"); in bcm_qspi_bspi_lr_err_l2_isr()
1136 qspi->bspi_rf_op_status = -EIO; in bcm_qspi_bspi_lr_err_l2_isr()
1137 if (qspi->soc_intc) in bcm_qspi_bspi_lr_err_l2_isr()
1141 complete(&qspi->bspi_done); in bcm_qspi_bspi_lr_err_l2_isr()
1148 struct bcm_qspi *qspi = qspi_dev_id->dev; in bcm_qspi_l1_isr() local
1149 struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; in bcm_qspi_l1_isr()
1214 static void bcm_qspi_bspi_init(struct bcm_qspi *qspi) in bcm_qspi_bspi_init() argument
1218 val = bcm_qspi_read(qspi, BSPI, BSPI_REVISION_ID); in bcm_qspi_bspi_init()
1219 qspi->bspi_maj_rev = (val >> 8) & 0xff; in bcm_qspi_bspi_init()
1220 qspi->bspi_min_rev = val & 0xff; in bcm_qspi_bspi_init()
1221 if (!(bcm_qspi_bspi_ver_three(qspi))) { in bcm_qspi_bspi_init()
1223 bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_VALUE, 0); in bcm_qspi_bspi_init()
1224 bcm_qspi_write(qspi, BSPI, BSPI_BSPI_XOR_ENABLE, 1); in bcm_qspi_bspi_init()
1226 qspi->bspi_enabled = 1; in bcm_qspi_bspi_init()
1227 bcm_qspi_disable_bspi(qspi); in bcm_qspi_bspi_init()
1228 bcm_qspi_write(qspi, BSPI, BSPI_B0_CTRL, 0); in bcm_qspi_bspi_init()
1229 bcm_qspi_write(qspi, BSPI, BSPI_B1_CTRL, 0); in bcm_qspi_bspi_init()
1232 static void bcm_qspi_hw_init(struct bcm_qspi *qspi) in bcm_qspi_hw_init() argument
1236 bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_LSB, 0); in bcm_qspi_hw_init()
1237 bcm_qspi_write(qspi, MSPI, MSPI_SPCR1_MSB, 0); in bcm_qspi_hw_init()
1238 bcm_qspi_write(qspi, MSPI, MSPI_NEWQP, 0); in bcm_qspi_hw_init()
1239 bcm_qspi_write(qspi, MSPI, MSPI_ENDQP, 0); in bcm_qspi_hw_init()
1240 bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0x20); in bcm_qspi_hw_init()
1244 parms.speed_hz = qspi->max_speed_hz; in bcm_qspi_hw_init()
1245 bcm_qspi_hw_set_parms(qspi, &parms); in bcm_qspi_hw_init()
1247 if (has_bspi(qspi)) in bcm_qspi_hw_init()
1248 bcm_qspi_bspi_init(qspi); in bcm_qspi_hw_init()
1251 static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi) in bcm_qspi_hw_uninit() argument
1253 bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0); in bcm_qspi_hw_uninit()
1254 if (has_bspi(qspi)) in bcm_qspi_hw_uninit()
1255 bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0); in bcm_qspi_hw_uninit()
1285 .compatible = "brcm,spi-bcm7445-qspi",
1290 .compatible = "brcm,spi-bcm-qspi",
1294 .compatible = "brcm,spi-bcm7216-qspi",
1298 .compatible = "brcm,spi-bcm7278-qspi",
1311 struct bcm_qspi *qspi; in bcm_qspi_probe() local
1336 qspi = spi_master_get_devdata(master); in bcm_qspi_probe()
1338 qspi->clk = devm_clk_get_optional(&pdev->dev, NULL); in bcm_qspi_probe()
1339 if (IS_ERR(qspi->clk)) in bcm_qspi_probe()
1340 return PTR_ERR(qspi->clk); in bcm_qspi_probe()
1342 qspi->pdev = pdev; in bcm_qspi_probe()
1343 qspi->trans_pos.trans = NULL; in bcm_qspi_probe()
1344 qspi->trans_pos.byte = 0; in bcm_qspi_probe()
1345 qspi->trans_pos.mspi_last_trans = true; in bcm_qspi_probe()
1346 qspi->master = master; in bcm_qspi_probe()
1358 qspi->big_endian = of_device_is_big_endian(dev->of_node); in bcm_qspi_probe()
1369 qspi->base[MSPI] = devm_ioremap_resource(dev, res); in bcm_qspi_probe()
1370 if (IS_ERR(qspi->base[MSPI])) in bcm_qspi_probe()
1371 return PTR_ERR(qspi->base[MSPI]); in bcm_qspi_probe()
1378 qspi->base[BSPI] = devm_ioremap_resource(dev, res); in bcm_qspi_probe()
1379 if (IS_ERR(qspi->base[BSPI])) in bcm_qspi_probe()
1380 return PTR_ERR(qspi->base[BSPI]); in bcm_qspi_probe()
1381 qspi->bspi_mode = true; in bcm_qspi_probe()
1383 qspi->bspi_mode = false; in bcm_qspi_probe()
1386 dev_info(dev, "using %smspi mode\n", qspi->bspi_mode ? "bspi-" : ""); in bcm_qspi_probe()
1390 qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); in bcm_qspi_probe()
1391 if (IS_ERR(qspi->base[CHIP_SELECT])) in bcm_qspi_probe()
1392 return PTR_ERR(qspi->base[CHIP_SELECT]); in bcm_qspi_probe()
1395 qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), in bcm_qspi_probe()
1397 if (!qspi->dev_ids) in bcm_qspi_probe()
1415 &qspi->dev_ids[val]); in bcm_qspi_probe()
1421 qspi->dev_ids[val].dev = qspi; in bcm_qspi_probe()
1422 qspi->dev_ids[val].irqp = &qspi_irq_tab[val]; in bcm_qspi_probe()
1441 qspi->soc_intc = soc_intc; in bcm_qspi_probe()
1444 qspi->soc_intc = NULL; in bcm_qspi_probe()
1447 ret = clk_prepare_enable(qspi->clk); in bcm_qspi_probe()
1453 qspi->base_clk = clk_get_rate(qspi->clk); in bcm_qspi_probe()
1456 rev = bcm_qspi_read(qspi, MSPI, MSPI_REV); in bcm_qspi_probe()
1462 qspi->mspi_maj_rev = (rev >> 4) & 0xf; in bcm_qspi_probe()
1463 qspi->mspi_min_rev = rev & 0xf; in bcm_qspi_probe()
1464 qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk; in bcm_qspi_probe()
1466 qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2); in bcm_qspi_probe()
1468 bcm_qspi_hw_init(qspi); in bcm_qspi_probe()
1469 init_completion(&qspi->mspi_done); in bcm_qspi_probe()
1470 init_completion(&qspi->bspi_done); in bcm_qspi_probe()
1471 qspi->curr_cs = -1; in bcm_qspi_probe()
1473 platform_set_drvdata(pdev, qspi); in bcm_qspi_probe()
1475 qspi->xfer_mode.width = -1; in bcm_qspi_probe()
1476 qspi->xfer_mode.addrlen = -1; in bcm_qspi_probe()
1477 qspi->xfer_mode.hp = -1; in bcm_qspi_probe()
1488 bcm_qspi_hw_uninit(qspi); in bcm_qspi_probe()
1489 clk_disable_unprepare(qspi->clk); in bcm_qspi_probe()
1491 kfree(qspi->dev_ids); in bcm_qspi_probe()
1499 struct bcm_qspi *qspi = platform_get_drvdata(pdev); in bcm_qspi_remove() local
1501 spi_unregister_master(qspi->master); in bcm_qspi_remove()
1502 bcm_qspi_hw_uninit(qspi); in bcm_qspi_remove()
1503 clk_disable_unprepare(qspi->clk); in bcm_qspi_remove()
1504 kfree(qspi->dev_ids); in bcm_qspi_remove()
1513 struct bcm_qspi *qspi = dev_get_drvdata(dev); in bcm_qspi_suspend() local
1516 if (!bcm_qspi_bspi_ver_three(qspi)) in bcm_qspi_suspend()
1517 qspi->s3_strap_override_ctrl = in bcm_qspi_suspend()
1518 bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); in bcm_qspi_suspend()
1520 spi_master_suspend(qspi->master); in bcm_qspi_suspend()
1521 clk_disable_unprepare(qspi->clk); in bcm_qspi_suspend()
1522 bcm_qspi_hw_uninit(qspi); in bcm_qspi_suspend()
1529 struct bcm_qspi *qspi = dev_get_drvdata(dev); in bcm_qspi_resume() local
1532 bcm_qspi_hw_init(qspi); in bcm_qspi_resume()
1533 bcm_qspi_chip_select(qspi, qspi->curr_cs); in bcm_qspi_resume()
1534 if (qspi->soc_intc) in bcm_qspi_resume()
1536 qspi->soc_intc->bcm_qspi_int_set(qspi->soc_intc, MSPI_DONE, in bcm_qspi_resume()
1539 ret = clk_prepare_enable(qspi->clk); in bcm_qspi_resume()
1541 spi_master_resume(qspi->master); in bcm_qspi_resume()
1552 MODULE_DESCRIPTION("Broadcom QSPI driver");