diff --git a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c index 97c00b4..fb654bb 100644 --- a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c +++ b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c @@ -98,6 +98,7 @@ void enable_basic_clocks(void) &cmper->emiffwclkctrl, &cmper->emifclkctrl, &cmper->otfaemifclkctrl, + &cmper->qspiclkctrl, 0 }; diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index 9febfa2..0736258 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -332,7 +332,9 @@ struct cm_perpll { unsigned int mcasp1clkctrl; /* offset 0x240 */ unsigned int resv11; unsigned int mmc2clkctrl; /* offset 0x248 */ - unsigned int resv12[5]; + unsigned int resv12[3]; + unsigned int qspiclkctrl; /* offset 0x258 */ + unsigned int resv121; unsigned int usb0clkctrl; /* offset 0x260 */ unsigned int resv13[103]; unsigned int l4lsclkstctrl; /* offset 0x400 */ diff --git a/arch/arm/include/asm/arch-am33xx/omap.h b/arch/arm/include/asm/arch-am33xx/omap.h index 7a7d91b..0855d16 100644 --- a/arch/arm/include/asm/arch-am33xx/omap.h +++ b/arch/arm/include/asm/arch-am33xx/omap.h @@ -29,5 +29,6 @@ #define SRAM_SCRATCH_SPACE_ADDR 0x40337C00 #define AM4372_BOARD_NAME_START SRAM_SCRATCH_SPACE_ADDR #define AM4372_BOARD_NAME_END SRAM_SCRATCH_SPACE_ADDR + 0xC +#define QSPI_BASE 0x47900000 #endif #endif diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h index 4955ccf..054c680 100644 --- a/arch/arm/include/asm/arch-mx5/imx-regs.h +++ b/arch/arm/include/asm/arch-mx5/imx-regs.h @@ -230,9 +230,10 @@ #define MXC_CSPICTRL_CHAN 18 /* Bit position inside CON register to be associated with SS */ -#define MXC_CSPICON_POL 4 -#define MXC_CSPICON_PHA 0 -#define MXC_CSPICON_SSPOL 12 +#define MXC_CSPICON_PHA 0 /* SCLK phase control */ +#define MXC_CSPICON_POL 4 /* SCLK polarity */ +#define MXC_CSPICON_SSPOL 12 /* SS polarity */ +#define MXC_CSPICON_CTL 20 /* inactive state of SCLK */ #define MXC_SPI_BASE_ADDRESSES \ CSPI1_BASE_ADDR, \ CSPI2_BASE_ADDR, \ diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index c2d210a..1f19727 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -406,10 +406,11 @@ struct cspi_regs { #define MXC_CSPICTRL_CHAN 18 /* Bit position inside CON register to be associated with SS */ -#define MXC_CSPICON_POL 4 -#define MXC_CSPICON_PHA 0 -#define MXC_CSPICON_SSPOL 12 -#ifdef CONFIG_MX6SL +#define MXC_CSPICON_PHA 0 /* SCLK phase control */ +#define MXC_CSPICON_POL 4 /* SCLK polarity */ +#define MXC_CSPICON_SSPOL 12 /* SS polarity */ +#define MXC_CSPICON_CTL 20 /* inactive state of SCLK */ +#if defined(CONFIG_MX6SL) || defined(CONFIG_MX6DL) #define MXC_SPI_BASE_ADDRESSES \ ECSPI1_BASE_ADDR, \ ECSPI2_BASE_ADDR, \ diff --git a/board/ti/am43xx/mux.c b/board/ti/am43xx/mux.c index 810b194..f96c56f 100644 --- a/board/ti/am43xx/mux.c +++ b/board/ti/am43xx/mux.c @@ -38,6 +38,16 @@ static struct module_pin_mux gpio0_22_pin_mux[] = { {-1}, }; +static struct module_pin_mux qspi_pin_mux[] = { + {OFFSET(gpmc_csn0), (MODE(3) | PULLUP_EN | RXACTIVE)}, /* QSPI_CS0 */ + {OFFSET(gpmc_csn3), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* QSPI_CLK */ + {OFFSET(gpmc_advn_ale), (MODE(3) | PULLUP_EN | RXACTIVE)}, /* QSPI_D0 */ + {OFFSET(gpmc_oen_ren), (MODE(3) | PULLUP_EN | RXACTIVE)}, /* QSPI_D1 */ + {OFFSET(gpmc_wen), (MODE(3) | PULLUP_EN | RXACTIVE)}, /* QSPI_D2 */ + {OFFSET(gpmc_be0n_cle), (MODE(3) | PULLUP_EN | RXACTIVE)}, /* QSPI_D3 */ + {-1}, +}; + void enable_uart0_pin_mux(void) { configure_module_pin_mux(uart0_pin_mux); @@ -50,6 +60,7 @@ void enable_board_pin_mux(void) if (board_is_gpevm()) configure_module_pin_mux(gpio0_22_pin_mux); + configure_module_pin_mux(qspi_pin_mux); } void enable_i2c0_pin_mux(void) diff --git a/doc/SPI/README.ti_qspi_am43x_test b/doc/SPI/README.ti_qspi_am43x_test new file mode 100644 index 0000000..8fbf10b --- /dev/null +++ b/doc/SPI/README.ti_qspi_am43x_test @@ -0,0 +1,76 @@ +Testing details- +---------------- + +This doc simply illustrated the testing details of qspi flash +driver with Macronix M25L51235 flash device. + +The test includes +- probing the flash device +- erasing the flash device +- Writing to flash +- Reading the contents of the flash. + +Test Log +-------- + +Hit any key to stop autoboot: 0 +U-Boot# sf probe 0 +SF: Detected MX25L51235F with page size 256 Bytes, erase size 64 KiB, total 64 MiB, mapped at 30000000 +U-Boot# sf erase 0 0x80000 +SF: 524288 bytes @ 0x0 Erased: OK +U-Boot# mw 81000000 0xdededede 0x40000 +U-Boot# sf write 81000000 0 0x40000 +SF: 262144 bytes @ 0x0 Written: OK +U-Boot# sf read 82000000 0 0x40000 +SF: 262144 bytes @ 0x0 Read: OK +U-Boot# md 0x82000000 +82000000: dededede dededede dededede dededede ................ +82000010: dededede dededede dededede dededede ................ +82000020: dededede dededede dededede dededede ................ +82000030: dededede dededede dededede dededede ................ +82000040: dededede dededede dededede dededede ................ +82000050: dededede dededede dededede dededede ................ +82000060: dededede dededede dededede dededede ................ +82000070: dededede dededede dededede dededede ................ +82000080: dededede dededede dededede dededede ................ +82000090: dededede dededede dededede dededede ................ +820000a0: dededede dededede dededede dededede ................ +820000b0: dededede dededede dededede dededede ................ +820000c0: dededede dededede dededede dededede ................ +820000d0: dededede dededede dededede dededede ................ +820000e0: dededede dededede dededede dededede ................ +820000f0: dededede dededede dededede dededede ................ +U-Boot# md 0x82010000 +82010000: dededede dededede dededede dededede ................ +82010010: dededede dededede dededede dededede ................ +82010020: dededede dededede dededede dededede ................ +82010030: dededede dededede dededede dededede ................ +82010040: dededede dededede dededede dededede ................ +82010050: dededede dededede dededede dededede ................ +82010060: dededede dededede dededede dededede ................ +82010070: dededede dededede dededede dededede ................ +82010080: dededede dededede dededede dededede ................ +82010090: dededede dededede dededede dededede ................ +820100a0: dededede dededede dededede dededede ................ +820100b0: dededede dededede dededede dededede ................ +820100c0: dededede dededede dededede dededede ................ +820100d0: dededede dededede dededede dededede ................ +820100e0: dededede dededede dededede dededede ................ +820100f0: dededede dededede dededede dededede ................ +U-Boot# md 0x82030000 +82030000: dededede dededede dededede dededede ................ +82030010: dededede dededede dededede dededede ................ +82030020: dededede dededede dededede dededede ................ +82030030: dededede dededede dededede dededede ................ +82030040: dededede dededede dededede dededede ................ +82030050: dededede dededede dededede dededede ................ +82030060: dededede dededede dededede dededede ................ +82030070: dededede dededede dededede dededede ................ +82030080: dededede dededede dededede dededede ................ +82030090: dededede dededede dededede dededede ................ +820300a0: dededede dededede dededede dededede ................ +820300b0: dededede dededede dededede dededede ................ +820300c0: dededede dededede dededede dededede ................ +820300d0: dededede dededede dededede dededede ................ +820300e0: dededede dededede dededede dededede ................ +820300f0: dededede dededede dededede dededede ................ diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index 95dd03f..f3f029d 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -115,7 +115,8 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, { u32 clk_src = mxc_get_clock(MXC_CSPI_CLK); s32 reg_ctrl, reg_config; - u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, pre_div = 0, post_div = 0; + u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, sclkctl = 0; + u32 pre_div = 0, post_div = 0; struct cspi_regs *regs = (struct cspi_regs *)mxcs->base; if (max_hz == 0) { @@ -164,8 +165,10 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, if (mode & SPI_CS_HIGH) ss_pol = 1; - if (mode & SPI_CPOL) + if (mode & SPI_CPOL) { sclkpol = 1; + sclkctl = 1; + } if (mode & SPI_CPHA) sclkpha = 1; @@ -180,6 +183,8 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs, (ss_pol << (cs + MXC_CSPICON_SSPOL)); reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_POL))) | (sclkpol << (cs + MXC_CSPICON_POL)); + reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_CTL))) | + (sclkctl << (cs + MXC_CSPICON_CTL)); reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_PHA))) | (sclkpha << (cs + MXC_CSPICON_PHA)); diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 5a5b482..dfa5d0c 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include /* ti qpsi register bit masks */ #define QSPI_TIMEOUT 2000000 @@ -39,7 +41,8 @@ #define MM_SWITCH 0x01 #define MEM_CS 0x100 #define MEM_CS_UNSELECT 0xfffff0ff -#define MMAP_START_ADDR 0x5c000000 +#define MMAP_START_ADDR_DRA 0x5c000000 +#define MMAP_START_ADDR_AM43x 0x30000000 #define CORE_CTRL_IO 0x4a002558 #define QSPI_CMD_READ (0x3 << 0) @@ -99,7 +102,11 @@ static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) struct spi_slave *slave = &qslave->slave; u32 memval = 0; - slave->memory_map = (void *)MMAP_START_ADDR; +#ifdef CONFIG_DRA7XX + slave->memory_map = (void *)MMAP_START_ADDR_DRA; +#else + slave->memory_map = (void *)MMAP_START_ADDR_AM43x; +#endif memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | QSPI_SETUP0_NUM_D_BYTES_NO_BITS | @@ -165,6 +172,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, { struct ti_qspi_slave *qslave; +#ifdef CONFIG_AM43XX + gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio"); + gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1); +#endif + qslave = spi_alloc_slave(struct ti_qspi_slave, bus, cs); if (!qslave) { printf("SPI_error: Fail to allocate ti_qspi_slave\n"); @@ -229,7 +241,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, const uchar *txp = dout; uchar *rxp = din; uint status; - int timeout, val; + int timeout; + +#ifdef CONFIG_DRA7XX + int val; +#endif debug("spi_xfer: bus:%i cs:%i bitlen:%i words:%i flags:%lx\n", slave->bus, slave->cs, bitlen, words, flags); @@ -237,15 +253,19 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* Setup mmap flags */ if (flags & SPI_XFER_MMAP) { writel(MM_SWITCH, &qslave->base->memswitch); +#ifdef CONFIG_DRA7XX val = readl(CORE_CTRL_IO); val |= MEM_CS; writel(val, CORE_CTRL_IO); +#endif return 0; } else if (flags & SPI_XFER_MMAP_END) { writel(~MM_SWITCH, &qslave->base->memswitch); +#ifdef CONFIG_DRA7XX val = readl(CORE_CTRL_IO); val &= MEM_CS_UNSELECT; writel(val, CORE_CTRL_IO); +#endif return 0; } @@ -265,6 +285,13 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, qslave->cmd |= QSPI_3_PIN; qslave->cmd |= 0xfff; +/* FIXME: This delay is required for successfull + * completion of read/write/erase. Once its root + * caused, it will be remove from the driver. + */ +#ifdef CONFIG_AM43XX + udelay(100); +#endif while (words--) { if (txp) { debug("tx cmd %08x dc %08x data %02x\n", diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 5ac0184..56d99d1 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -149,6 +149,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, const unsigned char *txp = dout; unsigned char *rxp = din; unsigned rxecount = 17; /* max. 16 elements in FIFO, leftover 1 */ + unsigned global_timeout; debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, slave->bus, slave->cs, bitlen, bytes, flags); @@ -176,11 +177,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, if (flags & SPI_XFER_BEGIN) spi_cs_activate(slave); - while (bytes--) { - unsigned timeout = /* at least 1usec or greater, leftover 1 */ - xilspi->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : + /* at least 1usec or greater, leftover 1 */ + global_timeout = xilspi->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : (XILSPI_MAX_XFER_BITS * 1000000 / xilspi->freq) + 1; + while (bytes--) { + unsigned timeout = global_timeout; /* get Tx element from data out buffer and count up */ unsigned char d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL; debug("%s: tx:%x ", __func__, d); diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index d3c4756..9a44990 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -84,6 +84,26 @@ #define CONFIG_OMAP_USB_PHY #define CONFIG_AM437X_USB2PHY2_HOST +/* SPI */ +#undef CONFIG_OMAP3_SPI +#define CONFIG_TI_QSPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_MACRONIX +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_TI_SPI_MMAP +#define CONFIG_QSPI_SEL_GPIO 48 +#define CONFIG_SF_DEFAULT_SPEED 48000000 +#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 + +/* SPI SPL */ +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 + #ifndef CONFIG_SPL_BUILD #define CONFIG_EXTRA_ENV_SETTINGS \ "loadaddr=0x80200000\0" \