1 #include <linux/mmc/sdio_func.h>
3 #include "slc_host_register.h"
6 #ifdef SIF_DEBUG_DSR_DUMP_REG
7 static void dump_slc_regs(struct slc_host_regs *regs);
8 #endif /* SIF_DEBUG_DSR_DUMP_REG */
10 int esp_common_read(struct esp_pub *epub, u8 *buf, u32 len, int sync, bool noround)
14 return sif_lldesc_read_sync(epub, buf, len);
17 //return sif_spi_read_sync(epub, buf, len, NOT_CHECK_IDLE);
18 return sif_spi_read_sync(epub, buf, len, NOT_DUMMYMODE,0);
22 return sif_lldesc_read_raw(epub, buf, len, noround);
25 //return sif_spi_read_nosync(epub, buf, len, NOT_CHECK_IDLE, noround);
26 return sif_spi_read_nosync(epub, buf, len, NOT_DUMMYMODE, noround,0);
32 int esp_common_write(struct esp_pub *epub, u8 *buf, u32 len, int sync)
36 return sif_lldesc_write_sync(epub, buf, len);
39 //return sif_spi_write_sync(epub, buf, len, NOT_CHECK_IDLE);
40 return sif_spi_write_sync(epub, buf, len, NOT_DUMMYMODE,0);
44 return sif_lldesc_write_raw(epub, buf, len);
47 //return sif_spi_write_nosync(epub, buf, len, NOT_CHECK_IDLE);
48 return sif_spi_write_nosync(epub, buf, len, NOT_DUMMYMODE,0);
54 int esp_common_read_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, u32 len, int sync)
58 return sif_io_sync(epub, addr, buf, len, SIF_FROM_DEVICE | SIF_SYNC | SIF_BYTE_BASIS | SIF_INC_ADDR);
61 return sif_spi_epub_read_mix_sync(epub, addr, buf, len, NOT_DUMMYMODE,0);
65 return sif_io_raw(epub, addr, buf, len, SIF_FROM_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR);
68 return sif_spi_epub_read_mix_nosync(epub, addr, buf, len, NOT_DUMMYMODE,0);
75 int esp_common_write_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, u32 len, int sync)
79 return sif_io_sync(epub, addr, buf, len, SIF_TO_DEVICE | SIF_SYNC | SIF_BYTE_BASIS | SIF_INC_ADDR);
82 return sif_spi_epub_write_mix_sync(epub, addr, buf, len, NOT_DUMMYMODE,0);
86 return sif_io_raw(epub, addr, buf, len, SIF_TO_DEVICE | SIF_BYTE_BASIS | SIF_INC_ADDR);
89 return sif_spi_epub_write_mix_nosync(epub, addr, buf, len, NOT_DUMMYMODE,0);
94 int esp_common_readbyte_with_addr(struct esp_pub *epub, u32 addr, u8 *buf, int sync)
100 *buf = sdio_io_readb(epub, addr, &res);
101 sif_unlock_bus(epub);
105 return sif_spi_epub_read_mix_sync(epub, addr, buf, 1, NOT_DUMMYMODE,0);
110 *buf = sdio_io_readb(epub, addr, &res);
114 return sif_spi_epub_read_mix_nosync(epub, addr, buf, 1, NOT_DUMMYMODE,0);
122 int esp_common_writebyte_with_addr(struct esp_pub *epub, u32 addr, u8 buf, int sync)
128 sdio_io_writeb(epub, buf, addr, &res);
129 sif_unlock_bus(epub);
133 return sif_spi_epub_write_mix_sync(epub, addr, &buf, 1, NOT_DUMMYMODE,0 );
138 sdio_io_writeb(epub, buf, addr, &res);
142 return sif_spi_epub_write_mix_nosync(epub, addr, &buf, 1, NOT_DUMMYMODE,0);
147 typedef enum _SDIO_INTR_MODE {
149 SDIO_INTR_OOB_TOGGLE,
150 SDIO_INTR_OOB_HIGH_LEVEL,
151 SDIO_INTR_OOB_LOW_LEVEL,
154 #define GEN_GPIO_SEL(_gpio_num, _sel_func, _intr_mode, _offset) (((_offset)<< 9 ) |((_intr_mode) << 7)|((_sel_func) << 4)|(_gpio_num))
155 //bit[3:0] = gpio num, 2
156 //bit[6:4] = gpio sel func, 0
157 //bit[8:7] = gpio intr mode, SDIO_INTR_OOB_TOGGLE
158 //bit[15:9] = register offset, 0x38
160 u16 gpio_sel_sets[17] = {
161 GEN_GPIO_SEL(0, 0, SDIO_INTR_OOB_TOGGLE, 0x34),//GPIO0
162 GEN_GPIO_SEL(1, 3, SDIO_INTR_OOB_TOGGLE, 0x18),//U0TXD
163 GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38),//GPIO2
164 GEN_GPIO_SEL(3, 3, SDIO_INTR_OOB_TOGGLE, 0x14),//U0RXD
165 GEN_GPIO_SEL(4, 0, SDIO_INTR_OOB_TOGGLE, 0x3C),//GPIO4
166 GEN_GPIO_SEL(5, 0, SDIO_INTR_OOB_TOGGLE, 0x40),//GPIO5
167 GEN_GPIO_SEL(6, 3, SDIO_INTR_OOB_TOGGLE, 0x1C),//SD_CLK
168 GEN_GPIO_SEL(7, 3, SDIO_INTR_OOB_TOGGLE, 0x20),//SD_DATA0
169 GEN_GPIO_SEL(8, 3, SDIO_INTR_OOB_TOGGLE, 0x24),//SD_DATA1
170 GEN_GPIO_SEL(9, 3, SDIO_INTR_OOB_TOGGLE, 0x28),//SD_DATA2
171 GEN_GPIO_SEL(10, 3, SDIO_INTR_OOB_TOGGLE, 0x2C),//SD_DATA3
172 GEN_GPIO_SEL(11, 3, SDIO_INTR_OOB_TOGGLE, 0x30),//SD_CMD
173 GEN_GPIO_SEL(12, 3, SDIO_INTR_OOB_TOGGLE, 0x04),//MTDI
174 GEN_GPIO_SEL(13, 3, SDIO_INTR_OOB_TOGGLE, 0x08),//MTCK
175 GEN_GPIO_SEL(14, 3, SDIO_INTR_OOB_TOGGLE, 0x0C),//MTMS
176 GEN_GPIO_SEL(15, 3, SDIO_INTR_OOB_TOGGLE, 0x10),//MTDO
177 //pls do not change sel before, if you want to change intr mode,change the one blow
178 //GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_TOGGLE, 0x38)
179 GEN_GPIO_SEL(2, 0, SDIO_INTR_OOB_LOW_LEVEL, 0x38)
181 #if defined(USE_EXT_GPIO)
182 u16 gpio_forbidden = 0;
185 int sif_interrupt_target(struct esp_pub *epub, u8 index)
187 u8 low_byte = BIT(index);
188 return esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W4 + 2, low_byte, ESP_SIF_NOSYNC);
193 int sif_config_gpio_mode(struct esp_pub *epub, u8 gpio_num, u8 gpio_mode)
198 if((BIT(gpio_num) & gpio_forbidden) || gpio_num > 15)
201 p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
204 *p_tbuf = (gpio_mode << 16) | gpio_sel_sets[gpio_num];
205 err = esp_common_write_with_addr(epub, SLC_HOST_CONF_W1, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
210 return sif_interrupt_target(epub, 4);
213 int sif_set_gpio_output(struct esp_pub *epub, u16 mask, u16 value)
218 mask &= ~gpio_forbidden;
219 p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
222 *p_tbuf = (mask << 16) | value;
223 err = esp_common_write_with_addr(epub, SLC_HOST_CONF_W2, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
228 return sif_interrupt_target(epub, 5);
231 int sif_get_gpio_intr(struct esp_pub *epub, u16 intr_mask, u16 *value)
236 p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
240 err = esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
246 *value = *p_tbuf & intr_mask;
250 return sif_interrupt_target(epub, 6);
253 int sif_get_gpio_input(struct esp_pub *epub, u16 *mask, u16 *value)
258 err = sif_interrupt_target(epub, 3);
263 p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
267 err = esp_common_read_with_addr(epub, SLC_HOST_CONF_W3, (u8*)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
273 *mask = *p_tbuf >> 16;
274 *value = *p_tbuf & *mask;
281 void sif_raw_dummy_read(struct esp_pub *epub ,int ext_gpio)
286 static u32 read_err_cnt = 0;
287 static u32 write_err_cnt = 0;
288 static u32 unknow_err_cnt = 0;
289 static u32 check_cnt = 0;
299 if (atomic_read(&epub->ps.state) == ESP_PM_ON ||ext_gpio == 1 ) {
302 // if (atomic_read(&epub->ps.state) == ESP_PM_ON ) {
303 atomic_set(&epub->ps.state, ESP_PM_OFF);
308 p_tbuf = kzalloc(sizeof(u32), GFP_KERNEL);
309 ESSERT(p_tbuf != NULL);
312 // *p_tbuf = 0x010001ff;
318 write_err = sif_spi_epub_write_mix_nosync(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, DUMMYMODE,0);
324 esp_common_write_with_addr(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, ESP_SIF_NOSYNC);
328 *p_tbuf = 0xffffffff;
331 read_err = sif_spi_epub_read_mix_nosync(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), DUMMYMODE,0);
332 if(read_err == -4 || read_err == -5)
337 esp_common_read_with_addr(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
340 esp_dbg(ESP_DBG_ERROR, "w4 = %x,dummy time = %d\n",p_tbuf[0],dummy_time);
342 if(*p_tbuf == 0x020001ff){
347 esp_common_write_with_addr(epub, SLC_HOST_CONF_W4, (u8 *)p_tbuf, sizeof(u32), ESP_SIF_NOSYNC);
356 if(*p_tbuf == 0x010001ff){
359 }else if(*p_tbuf == 0x000001ff){
362 }else if(*p_tbuf == 0xffffffff){
371 // *p_tbuf = 0x010001ff;
375 write_err = sif_spi_epub_write_mix_nosync(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, DUMMYMODE,0);
381 esp_common_write_with_addr(epub, SLC_HOST_CONF_W4+3, (u8 *)p_tbuf, 1, ESP_SIF_NOSYNC);
383 } while (retry++ < 1000);
387 if(read_err_cnt || write_err_cnt || unknow_err_cnt){
388 if((check_cnt & 0xf) == 0)
389 //esp_dbg(ESP_DBG_ERROR, "==============sdio err===============\n,read:%u, write:%u, unknow:%u\n", read_err_cnt,write_err_cnt,unknow_err_cnt);
390 esp_dbg(ESP_DBG_ERROR, "r%u,w%u,u%u\n", read_err_cnt,write_err_cnt,unknow_err_cnt);
396 esp_dbg(ESP_DBG_ERROR, "spierr sleep_time = %d,read_err = %d,write_err = %d\n", sleep_time,read_err,write_err);
401 // esp_dbg(ESP_DBG_ERROR, "=========%s tried %d times===========\n", __func__, retry - 1);
407 #endif /* disable dummy read func */
410 void check_target_id(struct esp_pub *epub)
416 EPUB_CTRL_CHECK(epub, _err);
420 for(i = 0; i < 4; i++) {
421 err = esp_common_readbyte_with_addr(epub, SLC_HOST_DATE + i, (u8 *)&date + i, ESP_SIF_NOSYNC);
422 err = esp_common_readbyte_with_addr(epub, SLC_HOST_ID + i, (u8 *)&EPUB_TO_CTRL(epub)->target_id + i, ESP_SIF_NOSYNC);
425 sif_unlock_bus(epub);
427 esp_dbg(ESP_DBG_LOG, "\n\n \t\t SLC data 0x%08x, ID 0x%08x\n\n", date, EPUB_TO_CTRL(epub)->target_id);
429 switch(EPUB_TO_CTRL(epub)->target_id) {
431 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000;
434 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000 - 0x800;
443 gpio_sel = gpio_sel_sets[16];
445 high_byte = gpio_sel >> 8;
447 gpio_forbidden |= BIT(gpio_sel & 0xf);
448 #endif /* USE_EXT_GPIO */
449 #endif /* USE_OOB_INTR */
451 if(sif_get_bt_config() == 1 && sif_get_rst_config() != 1){
452 u8 gpio_num = sif_get_wakeup_gpio_config();
453 gpio_sel = gpio_sel_sets[gpio_num];
455 byte3 = gpio_sel >> 8;
457 gpio_forbidden |= BIT(gpio_num);
461 err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1, low_byte, ESP_SIF_NOSYNC);
462 err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 1, high_byte, ESP_SIF_NOSYNC);
463 err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 2, byte2, ESP_SIF_NOSYNC);
464 err = esp_common_writebyte_with_addr(epub, SLC_HOST_CONF_W1 + 3, byte3, ESP_SIF_NOSYNC);
465 sif_unlock_bus(epub);
469 EPUB_TO_CTRL(epub)->slc_window_end_addr = 0x20000;
476 u32 sif_get_blksz(struct esp_pub *epub)
478 EPUB_CTRL_CHECK(epub, _err);
480 return EPUB_TO_CTRL(epub)->slc_blk_sz;
485 u32 sif_get_target_id(struct esp_pub *epub)
487 EPUB_CTRL_CHECK(epub, _err);
489 return EPUB_TO_CTRL(epub)->target_id;
495 #ifdef SIF_CHECK_FIRST_INTR
496 static bool first_intr_checked = false;
497 #endif //SIF_CHECK_FIRST_INTR
500 void sif_dsr(struct sdio_func *func)
502 struct esp_sdio_ctrl *sctrl = sdio_get_drvdata(func);
504 void sif_dsr(struct spi_device *spi)
506 struct esp_spi_ctrl *sctrl = spi_get_drvdata(spi);
510 static int dsr_cnt = 0, real_intr_cnt = 0, bogus_intr_cnt = 0;
511 struct slc_host_regs *regs = &(sctrl->slc_regs);
512 esp_dbg(ESP_DBG_TRACE, " %s enter %d \n", __func__, dsr_cnt++);
513 #endif /* SIF_DSR_WAR */
517 if(sctrl->epub->wait_reset == 1)
523 if(sctrl->epub->enable_int == 1)
525 sif_spi_epub_read_mix_sync(sctrl->epub, 0x3, buf, 512, NOT_DUMMYMODE,1);
526 buf[0]=buf[0]|(1<<2);
528 sif_spi_epub_write_mix_sync(sctrl->epub, 0x3, buf, 512, NOT_DUMMYMODE,1);
530 sctrl->epub->enable_int = 0;
533 atomic_set(&sctrl->irq_handling, 1);
536 sdio_release_host(sctrl->func);
540 sif_lock_bus(sctrl->epub);
546 #ifdef SIF_CHECK_FIRST_INTR
547 if (likely(first_intr_checked)) {
548 esp_dsr(sctrl->epub);
551 #endif //SIF_CHECK_FIRST_INTR
553 memset(regs, 0x0, sizeof(struct slc_host_regs));
555 ret = esp_common_read_with_addr(sctrl->epub, REG_SLC_HOST_BASE + 8, (u8 *)regs, sizeof(struct slc_host_regs), ESP_SIF_NOSYNC);
556 if ( (regs->intr_status & SLC_HOST_RX_ST) && (regs->intr_raw & SLC_HOST_RX_ST) && (ret == 0) ) {
557 #ifdef SIF_CHECK_FIRST_INTR
558 first_intr_checked = true;
559 #endif //SIF_CHECK_FIRST_INTR
560 esp_dbg(ESP_DBG_TRACE, "%s eal intr cnt: %d", __func__, ++real_intr_cnt);
562 esp_dsr(sctrl->epub);
565 #ifdef ESP_ACK_INTERRUPT
566 sif_platform_ack_interrupt(sctrl->epub);
567 #endif //ESP_ACK_INTERRUPT
568 sif_unlock_bus(sctrl->epub);
570 esp_dbg(ESP_DBG_TRACE, "%s bogus_intr_cnt %d\n", __func__, ++bogus_intr_cnt);
573 #ifdef SIF_DEBUG_DSR_DUMP_REG
575 #endif /* SIF_DEBUG_DUMP_DSR */
580 esp_dsr(sctrl->epub);
581 #endif /* SIF_DSR_WAR */
584 sdio_claim_host(func);
587 atomic_set(&sctrl->irq_handling, 0);
591 struct slc_host_regs * sif_get_regs(struct esp_pub *epub)
593 EPUB_CTRL_CHECK(epub, _err);
595 return &EPUB_TO_CTRL(epub)->slc_regs;
600 void sif_disable_target_interrupt(struct esp_pub *epub)
602 EPUB_FUNC_CHECK(epub, _exit);
604 #ifdef HOST_RESET_BUG
607 sif_raw_dummy_read(epub,0);
608 memset(EPUB_TO_CTRL(epub)->dma_buffer, 0x00, sizeof(u32));
609 esp_common_write_with_addr(epub, SLC_HOST_INT_ENA, EPUB_TO_CTRL(epub)->dma_buffer, sizeof(u32), ESP_SIF_NOSYNC);
610 #ifdef HOST_RESET_BUG
614 sif_unlock_bus(epub);
619 sif_raw_dummy_read(epub,0);
620 sif_interrupt_target(epub, 7);
621 sif_unlock_bus(epub);
626 #ifdef SIF_DEBUG_DSR_DUMP_REG
627 static void dump_slc_regs(struct slc_host_regs *regs)
629 esp_dbg(ESP_DBG_TRACE, "\n\n ------- %s --------------\n", __func__);
631 esp_dbg(ESP_DBG_TRACE, " \
632 intr_raw 0x%08X \t \n \
633 state_w0 0x%08X \t state_w1 0x%08X \n \
634 config_w0 0x%08X \t config_w1 0x%08X \n \
635 intr_status 0x%08X \t config_w2 0x%08X \n \
636 config_w3 0x%08X \t config_w4 0x%08X \n \
637 token_wdata 0x%08X \t intr_clear 0x%08X \n \
638 intr_enable 0x%08X \n\n", regs->intr_raw, \
639 regs->state_w0, regs->state_w1, regs->config_w0, regs->config_w1, \
641 regs->config_w2, regs->config_w3, regs->config_w4, regs->token_wdata, \
642 regs->intr_clear, regs->intr_enable);
644 #endif /* SIF_DEBUG_DSR_DUMP_REG */
646 static int bt_config = 0;
647 void sif_record_bt_config(int value)
652 int sif_get_bt_config(void)
657 static int rst_config = 0;
658 void sif_record_rst_config(int value)
663 int sif_get_rst_config(void)
668 static int ate_test = 0;
669 void sif_record_ate_config(int value)
674 int sif_get_ate_config(void)
679 static int retry_reset = 0;
680 void sif_record_retry_config(void)
685 int sif_get_retry_config(void)
690 static int wakeup_gpio = 12;
691 void sif_record_wakeup_gpio_config(int value)
696 int sif_get_wakeup_gpio_config(void)