123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- #include <drivers/flash.h>
- #include <drivers/spi.h>
- #include <logging/log.h>
- #include <soc.h>
- #include <board_cfg.h>
- #include "spi_flash.h"
- #ifdef CONFIG_SOC_LEOPARD
- #define DELAY_CHAIN_NUM 64
- #else
- #define DELAY_CHAIN_NUM 16
- #endif
- extern unsigned char spi_flash_set_delaytran(const struct device *dev, off_t offset, unsigned char delaytran);
- //static inline void test_setup_delaychain(struct spinor_info *sni, u8_t ns)
- //{
- //struct acts_spi_reg *spi= (struct acts_spi_reg *)sni->spi.base;
- //spi->ctrl = (spi->ctrl & ~(0xF << 16)) | (ns << 16);
- //volatile int i = 100000;
- //while (i--);
- //}
- #define TEST_READ_WRITE
- #ifdef TEST_READ_WRITE
- #if defined(CONFIG_SPI_FLASH_GPIO_2CS) && (CONFIG_SPI_FLASH_GPIO_2CS == 1)
- extern unsigned int nor_cs0_size;
- static u32_t TEST_ADDR = 0x200000;
- static u32_t TEST_ADDR_END = 0x400000;
- #else
- #define TEST_ADDR 0x200000
- #define TEST_ADDR_END 0x400000
- #endif
- #define TEST_SIZE (1024*4)
- static u32_t nor_test_buf[TEST_SIZE/4];
- static u32_t nor_test_start= 0x200000;
- __ramfunc int test_read_write_try(const struct device *dev, u8_t delay_chain)
- {
- int ret, i;
- struct spinor_info *sni = (struct spinor_info *)(dev)->data;
- spi_flash_set_delaytran(dev, TEST_ADDR, delay_chain);
- //sni->spi.delay_chain = delay_chain;
- if(nor_test_start < TEST_ADDR || nor_test_start >= TEST_ADDR_END)
- nor_test_start = TEST_ADDR;
- ret = flash_erase(dev, nor_test_start, TEST_SIZE);
- for(i = 0; i < TEST_SIZE/4; i++)
- nor_test_buf[i] = nor_test_start + i;
- ret = flash_write(dev, nor_test_start, nor_test_buf, TEST_SIZE);
- memset(nor_test_buf, 0 , TEST_SIZE);
- ret = flash_read(dev, nor_test_start, nor_test_buf, TEST_SIZE);
- if(ret){
- //test_setup_delaychain(sni, CONFIG_SPI_FLASH_DELAY_CHAIN);
- printk("read write fail =0x%x\n", nor_test_start);
- return -1;
- }
- for(i = 0; i < TEST_SIZE/4; i++){
- if( nor_test_buf[i] != nor_test_start + i){
- //test_setup_delaychain(sni, CONFIG_SPI_FLASH_DELAY_CHAIN);
- printk("of=%x, read 0x%x != 0x%x\n",nor_test_start, nor_test_start + i, nor_test_buf[i]);
- nor_test_start += TEST_SIZE;
- return -1;
- }
- }
- nor_test_start += TEST_SIZE;
- return 0;
- }
- #endif
- __ramfunc u32_t test_delaychain_read_id(const struct device *dev, u8_t delay_chain)
- {
- u32_t nor_id, mid;
- struct spinor_info *sni = (struct spinor_info *)(dev)->data;
- //sni->spi.delay_chain = delay_chain;
- spi_flash_set_delaytran(dev, TEST_ADDR, delay_chain);
- /* configure delay chain */
- //test_setup_delaychain(sni, sni->spi.delay_chain);
- //k_busy_wait(50);
- nor_id = p_spinor_api->read_chipid(sni) & 0xffffff;
- mid = nor_id & 0xff;
- if ((mid == 0xff) || (mid == 0x00))
- return 0;
- return nor_id;
- }
- __ramfunc s32_t test_delaychain_try(const struct device *dev, u8_t *ret_delaychain, u32_t chipid_ref)
- {
- u32_t i, try_delaychain;
- bool match_flag = 0;
- //u32_t nor_id_value_check;
- u32_t local_irq_save;
- local_irq_save = irq_lock();
- ret_delaychain[0] = 0;
- for (try_delaychain = 1; try_delaychain < DELAY_CHAIN_NUM; try_delaychain++) {
- match_flag = 1;
- printk("try_delaychain :%d\n", try_delaychain);
- soc_udelay(5000);
- #ifdef TEST_READ_WRITE
- for (i = 0; i < 2; i++) {
- if(test_read_write_try(dev, try_delaychain)){
- match_flag = 0;
- break;
- }
- }
- #else
- for (i = 0; i < 64; i++) {
- nor_id_value_check = test_delaychain_read_id(dev, try_delaychain);
- if (nor_id_value_check != chipid_ref) {
- printk("read:0x%x @ %d\n", nor_id_value_check, try_delaychain);
- match_flag = 0;
- break;
- }
- }
- #endif
- ret_delaychain[try_delaychain] = match_flag;
- }
- //test_delaychain_read_id(dev, CONFIG_SPI_FLASH_DELAY_CHAIN);
- irq_unlock(local_irq_save);
- return 0;
- }
- __ramfunc u32_t nor_read_chipid(const struct device *dev)
- {
- u32_t nor_id;
- u32_t local_irq_save;
- struct spinor_info *sni = (struct spinor_info *)(dev)->data;
- local_irq_save = irq_lock();
- nor_id = p_spinor_api->read_chipid(sni) & 0xffffff;
- irq_unlock(local_irq_save);
- return nor_id;
- }
- __ramfunc u8_t spinor_test_delaychain(const struct device *test_nor_dev)
- {
- u8_t ret_delaychain = 0;
- u8_t delaychain_flag[DELAY_CHAIN_NUM];
- u8_t delaychain_total[DELAY_CHAIN_NUM];
- u8_t start = 0, end, middle, i;
- u8_t expect_max_count_delay_chain = 0, max_count_delay_chain;
- //u32_t freq;
- u32_t chipid_ref;
- u8_t bak_delaytran;
- //struct device *test_nor_dev = device_get_binding(CONFIG_SPI_FLASH_NAME);
- struct spinor_info *sni = (struct spinor_info *)(test_nor_dev)->data;
- bak_delaytran = spi_flash_set_delaytran(test_nor_dev, TEST_ADDR, sni->spi.delay_chain);
- printk("spinor test delaychain start\n");
- chipid_ref = nor_read_chipid(test_nor_dev);
- printk("delaytran=0x%x, chipid = 0x%x\n", bak_delaytran, chipid_ref);
- memset(delaychain_total, 0x0, DELAY_CHAIN_NUM);
- //for (freq = 6; freq <= 222; freq += 6) {
- expect_max_count_delay_chain++;
- // soc_freq_set_cpu_clk(0, freq);
- // printk("set cpu freq : %d\n", freq);
- if (test_delaychain_try(test_nor_dev, delaychain_flag, chipid_ref) == 0) {
- for (i = 0; i < DELAY_CHAIN_NUM; i++)
- delaychain_total[i] += delaychain_flag[i];
- } else {
- printk("test_delaychain_try error!!\n");
- goto delay_chain_exit;
- }
- //}
- spi_flash_set_delaytran(test_nor_dev, TEST_ADDR, bak_delaytran);
- //sni->spi.delay_chain = bak_delaytran;
- printk("delaychain_total : ");
- for (i = 0; i < DELAY_CHAIN_NUM; i++)
- printk("%d,", delaychain_total[i]);
- printk("\n");
- max_count_delay_chain = 0;
- for (i = 0; i < DELAY_CHAIN_NUM; i++) {
- if (delaychain_total[i] > max_count_delay_chain)
- max_count_delay_chain = delaychain_total[i];
- }
- for (i = 0; i < DELAY_CHAIN_NUM; i++) {
- if (delaychain_total[i] == max_count_delay_chain) {
- start = i;
- break;
- }
- }
- end = start;
- for (i = start + 1; i < DELAY_CHAIN_NUM; i++) {
- if (delaychain_total[i] != max_count_delay_chain)
- break;
- end = i;
- }
- if (max_count_delay_chain < expect_max_count_delay_chain) {
- printk("test delaychain max count is %d, less then expect %d!!\n",
- max_count_delay_chain, expect_max_count_delay_chain);
- goto delay_chain_exit;
- }
- if ((end - start + 1) < 3) {
- printk("test delaychain only %d ok!! too less!!\n", end - start + 1);
- goto delay_chain_exit;
- }
- middle = (start + end) / 2;
- printk("test delaychain pass, best delaychain is : %d\n\n", middle);
- ret_delaychain = middle;
- delay_chain_exit:
- return ret_delaychain;
- }
- /*
- leopard: vdd < 1000 spi clk 64MHZ else 93MHZ
- */
- #define NUM_VDD_ITEM 4
- const uint16_t g_vdd_volt[NUM_VDD_ITEM] = {1200, 1100, 1000, 950};
- //const uint16_t g_vdd_volt[NUM_VDD_ITEM] = {1000, 950};
- __ramfunc int nor_test_delaychain(const struct device *dev)
- {
- int i;
- uint16_t vdd;
- //printk_dma_switch(0);
- printk("-----nor_test_delaychain =0x%x----\n", sys_read32(SPI1_DELAYCHAIN));
- sys_write32((sys_read32(SPI1_DELAYCHAIN)&(~0xf))|0x06, SPI1_DELAYCHAIN);
- soc_freq_set_cpu_clk(70,70);
- sys_write32(0, WD_CTL);
- #if 1
- for(i = 0; i < NUM_VDD_ITEM; i++){
- if(g_vdd_volt[i] == 950){
- printk("set spi0/spi1 clk 0.95V\n");
- sys_write32((sys_read32(SPI1_DELAYCHAIN)&(~0xf))|0x03, SPI1_DELAYCHAIN);
- clk_set_rate(CLOCK_ID_SPI1, MHZ(70) * 2);
- clk_set_rate(CLOCK_ID_SPI0, MHZ(64));
- }
- soc_pmu_set_vdd_voltage(g_vdd_volt[i]);
- soc_udelay(1000);
- printk("-----%d vdd set %d mv, try delaytran----\n", i, g_vdd_volt[i]);
- printk("%d, vdd=%d mv, delaychain : %d\n", i, g_vdd_volt[i], spinor_test_delaychain(dev));
- }
- #endif
- #if defined(CONFIG_SPI_FLASH_GPIO_2CS) && (CONFIG_SPI_FLASH_GPIO_2CS == 1)
- for(i = NUM_VDD_ITEM-1; i >= 0; i--){
- vdd = g_vdd_volt[i];
- soc_pmu_set_vdd_voltage(vdd);
- soc_udelay(1000);
- if(g_vdd_volt[i] == 1000){
- printk("set spi0/spi1 clk 1.0V\n");
- sys_write32((sys_read32(SPI1_DELAYCHAIN)&(~0xf))|0x06, SPI1_DELAYCHAIN);
- clk_set_rate(CLOCK_ID_SPI1, MHZ(140) * 2);
- clk_set_rate(CLOCK_ID_SPI0, MHZ(100));
- }
- }
- printk("\n\n---------------try cs1 nor-----------------\n\n");
- TEST_ADDR = 0x200000+nor_cs0_size;
- TEST_ADDR_END = 0x400000+nor_cs0_size;
- nor_test_start= TEST_ADDR;
- for(i = 0; i < NUM_VDD_ITEM; i++){
- if(g_vdd_volt[i] == 950){
- printk("set spi0/spi1 clk 0.95V\n");
- sys_write32((sys_read32(SPI1_DELAYCHAIN)&(~0xf))|0x03, SPI1_DELAYCHAIN);
- clk_set_rate(CLOCK_ID_SPI1, MHZ(70) * 2);
- clk_set_rate(CLOCK_ID_SPI0, MHZ(64));
- }
- soc_pmu_set_vdd_voltage(g_vdd_volt[i]);
- soc_udelay(1000);
- printk("--start cs1---%d vdd set %d mv, try delaytran----\n", i, g_vdd_volt[i]);
- printk("--end cs1 %d, vdd=%d mv, best delaychain : %d\n\n", i, g_vdd_volt[i], spinor_test_delaychain(dev));
- }
- #endif
- printk("\n ----nor_test_delaychain-- finshed-----\n");
- while(1);
- return 0;
- }
|