123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #include <drivers/flash.h>
- #include <drivers/spi.h>
- #include <logging/log.h>
- #include <soc.h>
- #include "spi_flash.h"
- extern void xspi_nor_enable_status_qe(struct spinor_info *sni);
- #define SPI_CTL_AHB_REQ (1<<8)
- #define SPI_STATUS_READY (1<<8)
- #define SPI_CTL_ADDR_MODE_MASK (1<<27)
- #define SPI_CTL_ADDR_MODE_2X4X (0<<27)
- #define SPI_CTL_ADDR_MODE_DUAL_QUAD (1<<27)
- static inline void spi_delay(void)
- {
- volatile int i = 100000;
- while (i--)
- ;
- }
- static inline void spi_setup_bus_width(struct spinor_info *sni, u8_t bus_width)
- {
- struct acts_spi_reg *spi= (struct acts_spi_reg *)sni->spi.base;
- spi->ctrl = (spi->ctrl & ~(0x3 << 10)) | (((bus_width & 0x7) / 2 + 1) << 10);
- spi_delay();
- }
- __ramfunc static void _nor_set_spi_read_mode(struct spinor_info *sni)
- {
- struct spi_info *si = (struct spi_info *)&sni->spi;
- if(sni->spi.bus_width == 4) {
- printk("nor is 4 line mode\n");
- xspi_nor_enable_status_qe(sni);
- /* enable 4x mode */
- spi_setup_bus_width(sni, 4);
- } else if(sni->spi.bus_width == 2) {
- printk("nor is 2 line mode\n");
- /* enable 2x mode */
- spi_setup_bus_width(sni, 2);
- } else {
- sni->spi.bus_width = 1;
- printk("nor is 1 line mode\n");
- /* enable 1x mode */
- spi_setup_bus_width(sni, 1);
- }
- }
- #define COMPARE_BYTES (32)
- void _nor_read_mode_try(struct spinor_info *sni, unsigned char bus_width)
- {
- u8_t temp_data[COMPARE_BYTES], src_data[COMPARE_BYTES];
- printk("_nor_read_mode_try:%d bit bus width\n", bus_width);
- sni->spi.bus_width = 1;
- sni->spi.flag &= ~SPI_FLAG_SPI_4XIO;
- memset(src_data, 0xff, COMPARE_BYTES);
- p_spinor_api->read(sni, 0, src_data, COMPARE_BYTES);
- /* try io mode */
- sni->spi.bus_width = bus_width;
- sni->spi.flag |= SPI_FLAG_SPI_4XIO;
- if (sni->spi.bus_width == 4) {
- xspi_nor_enable_status_qe(sni);
- }
- memset(temp_data, 0x00, COMPARE_BYTES);
- p_spinor_api->read(sni, 0, temp_data, COMPARE_BYTES);
- if (memcmp(temp_data, src_data, COMPARE_BYTES) == 0) {
- return ;
- }
- /* try output mode */
- sni->spi.flag &= ~SPI_FLAG_SPI_4XIO;
- memset(temp_data, 0x00, COMPARE_BYTES);
- p_spinor_api->read(sni, 0, temp_data, COMPARE_BYTES);
- if (memcmp(temp_data, src_data, COMPARE_BYTES) != 0) {
- sni->spi.bus_width = 1;
- }
- }
- void nor_dual_quad_read_mode_try(struct spinor_info *sni)
- {
- if(sni->spi.bus_width == 4) {
- _nor_read_mode_try(sni, 4);
- } else if(sni->spi.bus_width == 2) {
- _nor_read_mode_try(sni, 2);
- }
- _nor_set_spi_read_mode(sni);
- }
|