sdio.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /**
  3. ******************************************************************************
  4. * @file sdio.c
  5. * @author StarFive Technology
  6. * @version V1.0
  7. * @date 07/24/2020
  8. * @brief
  9. ******************************************************************************
  10. * @copy
  11. *
  12. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  13. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  14. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  15. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  16. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  17. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
  20. */
  21. #include "comdef.h"
  22. #include "sys.h"
  23. #include "ezGPIO_fullMux_ctrl_macro.h"
  24. #include "dwmmc.h"
  25. #include "gpt.h"
  26. struct dwmci_host local_host0;
  27. struct mmc local_mmc0;
  28. #define DWMMC_BUS_FREQ 100000000
  29. #define DWMMC_MAX_FREQ 10000000
  30. #define DWMMC_MIN_FREQ 400000
  31. #define GPT_BLOCK_SIZE 512
  32. static void sdio0_gpio_mux_select()
  33. {
  34. #if 0//for fpga
  35. SET_GPIO_18_dout_sdio0_pad_cclk_out;
  36. //SET_GPIO_18_doen_sdio0_pad_cclk_out;
  37. SET_GPIO_18_doen_LOW;
  38. //_SET_SYSCON_REG_register9_SCFG_gpio_pad_ctrl_9(5);
  39. SET_GPIO_17_doen_reverse_(1);
  40. SET_GPIO_17_doen_sdio0_pad_ccmd_oe;
  41. SET_GPIO_17_dout_sdio0_pad_ccmd_out;
  42. SET_GPIO_sdio0_pad_ccmd_in(17);
  43. SET_GPIO_15_doen_reverse_(1);
  44. SET_GPIO_16_doen_reverse_(1);
  45. SET_GPIO_19_doen_reverse_(1);
  46. SET_GPIO_20_doen_reverse_(1);
  47. SET_GPIO_19_doen_sdio0_pad_cdata_oe_bit0;
  48. SET_GPIO_19_dout_sdio0_pad_cdata_out_bit0;
  49. SET_GPIO_sdio0_pad_cdata_in_bit0(19);
  50. // _SET_SYSCON_REG_register9_SCFG_gpio_pad_ctrl_9(5);
  51. SET_GPIO_20_doen_sdio0_pad_cdata_oe_bit1;
  52. SET_GPIO_20_dout_sdio0_pad_cdata_out_bit1;
  53. SET_GPIO_sdio0_pad_cdata_in_bit1(20);
  54. //_SET_SYSCON_REG_register10_SCFG_gpio_pad_ctrl_10(5);
  55. SET_GPIO_15_doen_sdio0_pad_cdata_oe_bit2;
  56. SET_GPIO_15_dout_sdio0_pad_cdata_out_bit2;
  57. SET_GPIO_sdio0_pad_cdata_in_bit2(15);
  58. SET_GPIO_16_doen_sdio0_pad_cdata_oe_bit3;
  59. SET_GPIO_16_dout_sdio0_pad_cdata_out_bit3;
  60. SET_GPIO_sdio0_pad_cdata_in_bit3(16);
  61. #endif
  62. SET_GPIO_sdio0_pad_card_detect_n(26);
  63. SET_GPIO_26_doen_HIGH;
  64. SET_GPIO_33_dout_sdio0_pad_cclk_out;
  65. SET_GPIO_33_doen_LOW;
  66. SET_GPIO_34_doen_reverse_(1);
  67. SET_GPIO_34_doen_sdio0_pad_ccmd_oe;
  68. SET_GPIO_34_dout_sdio0_pad_ccmd_out;
  69. SET_GPIO_sdio0_pad_ccmd_in(34);
  70. SET_GPIO_32_doen_reverse_(1);
  71. SET_GPIO_31_doen_reverse_(1);
  72. SET_GPIO_30_doen_reverse_(1);
  73. SET_GPIO_36_doen_reverse_(1);
  74. SET_GPIO_32_doen_sdio0_pad_cdata_oe_bit0;
  75. SET_GPIO_32_dout_sdio0_pad_cdata_out_bit0;
  76. SET_GPIO_sdio0_pad_cdata_in_bit0(32);
  77. SET_GPIO_31_doen_sdio0_pad_cdata_oe_bit1;
  78. SET_GPIO_31_dout_sdio0_pad_cdata_out_bit1;
  79. SET_GPIO_sdio0_pad_cdata_in_bit1(31);
  80. SET_GPIO_30_doen_sdio0_pad_cdata_oe_bit2;
  81. SET_GPIO_30_dout_sdio0_pad_cdata_out_bit2;
  82. SET_GPIO_sdio0_pad_cdata_in_bit2(30);
  83. SET_GPIO_36_doen_sdio0_pad_cdata_oe_bit3;
  84. SET_GPIO_36_dout_sdio0_pad_cdata_out_bit3;
  85. SET_GPIO_sdio0_pad_cdata_in_bit3(36);
  86. }
  87. static struct mmc *init_mmc_device(int dev, unsigned int force_init)
  88. {
  89. struct mmc *mmc;
  90. if(dev != 0)
  91. return NULL;
  92. mmc = &local_mmc0;
  93. if (force_init)
  94. mmc->has_init = 0;
  95. if (mmc_init(mmc))
  96. return NULL;
  97. return mmc;
  98. }
  99. int boot_sdio_init(void)
  100. {
  101. struct dwmci_host *host;
  102. u32 fifo_depth = 32;
  103. /*HOST 0*/
  104. host = &local_host0;
  105. host->ioaddr = (void *)SDIO0_BASE_ADDR;
  106. host->name = "VIC DWMMC0";
  107. host->dev_index = 0;
  108. sdio0_gpio_mux_select();
  109. host->fifoth_val = MSIZE(0x2) |
  110. RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
  111. host->buswidth = 4;
  112. host->bus_hz = DWMMC_BUS_FREQ;
  113. /* Add the mmc channel to be registered with mmc core */
  114. if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ, 0)) {
  115. printk("DWMMC0 registration failed\n");
  116. return -1;
  117. }
  118. if(init_mmc_device(0, 0) == NULL)
  119. {
  120. printk("init dev fail.");
  121. return -1;
  122. }
  123. return 0;
  124. }
  125. static int sd_read_data(int dev_num,uint32_t start_lba, size_t blkcnt,void* dst)
  126. {
  127. struct mmc *mmc=&local_mmc0;
  128. int size;
  129. size = mmc->block_dev.block_read(dev_num,start_lba,blkcnt,dst);
  130. if(size != blkcnt)
  131. {
  132. printk("sd_read_data size:%d blkcnt:%d\n",size,blkcnt);
  133. return -1;
  134. }
  135. return 0;
  136. }
  137. static gpt_partition_range find_sd_gpt_partition(
  138. uint64_t partition_entries_lba,
  139. uint32_t num_partition_entries,
  140. uint32_t partition_entry_size,
  141. const gpt_guid* partition_type_guid,
  142. void* block_buf // Used to temporarily load blocks of SD card
  143. )
  144. {
  145. // Exclusive end
  146. uint16_t partition_entries_lba_end = (
  147. partition_entries_lba +
  148. (num_partition_entries * partition_entry_size + GPT_BLOCK_SIZE - 1) / GPT_BLOCK_SIZE
  149. );
  150. for (uint16_t i = partition_entries_lba; i < partition_entries_lba_end; i++)
  151. {
  152. sd_read_data(0, i, 1,block_buf);
  153. gpt_partition_range range = gpt_find_partition_by_guid(block_buf, partition_type_guid, GPT_BLOCK_SIZE / partition_entry_size);
  154. if (gpt_is_valid_partition_range(range))
  155. return range;
  156. }
  157. return gpt_invalid_partition_range();
  158. }
  159. /*read data from sd to dst*/
  160. int boot_load_gpt_partition(void* dst, const gpt_guid* partition_type_guid)
  161. {
  162. uint8_t gpt_buf[GPT_BLOCK_SIZE];
  163. gpt_partition_range part_range;
  164. /*READ LBA1*/
  165. sd_read_data(0,1,1,gpt_buf);
  166. {
  167. // header will be overwritten by find_sd_gpt_partition(), so locally
  168. // scope it.
  169. gpt_header* header = (gpt_header*) gpt_buf;
  170. part_range = find_sd_gpt_partition(
  171. header->partition_entries_lba,
  172. header->num_partition_entries,
  173. header->partition_entry_size,
  174. partition_type_guid,
  175. gpt_buf
  176. );
  177. }
  178. printk("gpt_partition %d:%d\n",part_range.first_lba,part_range.last_lba);
  179. sd_read_data(0,part_range.first_lba,part_range.last_lba + 1 - part_range.first_lba,dst);
  180. }