123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /* SPDX-License-Identifier: GPL-2.0-or-later */
- /**
- ******************************************************************************
- * @file sdio.c
- * @author StarFive Technology
- * @version V1.0
- * @date 07/24/2020
- * @brief
- ******************************************************************************
- * @copy
- *
- * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
- */
- #include "comdef.h"
- #include "sys.h"
- #include "ezGPIO_fullMux_ctrl_macro.h"
- #include "dwmmc.h"
- #include "gpt.h"
- struct dwmci_host local_host0;
- struct mmc local_mmc0;
- #define DWMMC_BUS_FREQ 100000000
- #define DWMMC_MAX_FREQ 10000000
- #define DWMMC_MIN_FREQ 400000
- #define GPT_BLOCK_SIZE 512
- static void sdio0_gpio_mux_select()
- {
- #if 0//for fpga
- SET_GPIO_18_dout_sdio0_pad_cclk_out;
- //SET_GPIO_18_doen_sdio0_pad_cclk_out;
- SET_GPIO_18_doen_LOW;
- //_SET_SYSCON_REG_register9_SCFG_gpio_pad_ctrl_9(5);
- SET_GPIO_17_doen_reverse_(1);
- SET_GPIO_17_doen_sdio0_pad_ccmd_oe;
- SET_GPIO_17_dout_sdio0_pad_ccmd_out;
- SET_GPIO_sdio0_pad_ccmd_in(17);
- SET_GPIO_15_doen_reverse_(1);
- SET_GPIO_16_doen_reverse_(1);
- SET_GPIO_19_doen_reverse_(1);
- SET_GPIO_20_doen_reverse_(1);
- SET_GPIO_19_doen_sdio0_pad_cdata_oe_bit0;
- SET_GPIO_19_dout_sdio0_pad_cdata_out_bit0;
- SET_GPIO_sdio0_pad_cdata_in_bit0(19);
- // _SET_SYSCON_REG_register9_SCFG_gpio_pad_ctrl_9(5);
- SET_GPIO_20_doen_sdio0_pad_cdata_oe_bit1;
- SET_GPIO_20_dout_sdio0_pad_cdata_out_bit1;
- SET_GPIO_sdio0_pad_cdata_in_bit1(20);
- //_SET_SYSCON_REG_register10_SCFG_gpio_pad_ctrl_10(5);
- SET_GPIO_15_doen_sdio0_pad_cdata_oe_bit2;
- SET_GPIO_15_dout_sdio0_pad_cdata_out_bit2;
- SET_GPIO_sdio0_pad_cdata_in_bit2(15);
- SET_GPIO_16_doen_sdio0_pad_cdata_oe_bit3;
- SET_GPIO_16_dout_sdio0_pad_cdata_out_bit3;
- SET_GPIO_sdio0_pad_cdata_in_bit3(16);
- #endif
- SET_GPIO_sdio0_pad_card_detect_n(26);
- SET_GPIO_26_doen_HIGH;
- SET_GPIO_33_dout_sdio0_pad_cclk_out;
- SET_GPIO_33_doen_LOW;
- SET_GPIO_34_doen_reverse_(1);
- SET_GPIO_34_doen_sdio0_pad_ccmd_oe;
- SET_GPIO_34_dout_sdio0_pad_ccmd_out;
- SET_GPIO_sdio0_pad_ccmd_in(34);
- SET_GPIO_32_doen_reverse_(1);
- SET_GPIO_31_doen_reverse_(1);
- SET_GPIO_30_doen_reverse_(1);
- SET_GPIO_36_doen_reverse_(1);
- SET_GPIO_32_doen_sdio0_pad_cdata_oe_bit0;
- SET_GPIO_32_dout_sdio0_pad_cdata_out_bit0;
- SET_GPIO_sdio0_pad_cdata_in_bit0(32);
- SET_GPIO_31_doen_sdio0_pad_cdata_oe_bit1;
- SET_GPIO_31_dout_sdio0_pad_cdata_out_bit1;
- SET_GPIO_sdio0_pad_cdata_in_bit1(31);
- SET_GPIO_30_doen_sdio0_pad_cdata_oe_bit2;
- SET_GPIO_30_dout_sdio0_pad_cdata_out_bit2;
- SET_GPIO_sdio0_pad_cdata_in_bit2(30);
- SET_GPIO_36_doen_sdio0_pad_cdata_oe_bit3;
- SET_GPIO_36_dout_sdio0_pad_cdata_out_bit3;
- SET_GPIO_sdio0_pad_cdata_in_bit3(36);
- }
- static struct mmc *init_mmc_device(int dev, unsigned int force_init)
- {
- struct mmc *mmc;
- if(dev != 0)
- return NULL;
-
- mmc = &local_mmc0;
- if (force_init)
- mmc->has_init = 0;
- if (mmc_init(mmc))
- return NULL;
- return mmc;
- }
- int boot_sdio_init(void)
- {
- struct dwmci_host *host;
- u32 fifo_depth = 32;
- /*HOST 0*/
- host = &local_host0;
- host->ioaddr = (void *)SDIO0_BASE_ADDR;
- host->name = "VIC DWMMC0";
- host->dev_index = 0;
- sdio0_gpio_mux_select();
- host->fifoth_val = MSIZE(0x2) |
- RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
- host->buswidth = 4;
- host->bus_hz = DWMMC_BUS_FREQ;
-
- /* Add the mmc channel to be registered with mmc core */
- if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ, 0)) {
- printk("DWMMC0 registration failed\n");
- return -1;
- }
- if(init_mmc_device(0, 0) == NULL)
- {
- printk("init dev fail.");
- return -1;
- }
- return 0;
- }
- static int sd_read_data(int dev_num,uint32_t start_lba, size_t blkcnt,void* dst)
- {
- struct mmc *mmc=&local_mmc0;
- int size;
-
- size = mmc->block_dev.block_read(dev_num,start_lba,blkcnt,dst);
- if(size != blkcnt)
- {
- printk("sd_read_data size:%d blkcnt:%d\n",size,blkcnt);
- return -1;
- }
- return 0;
- }
- static gpt_partition_range find_sd_gpt_partition(
- uint64_t partition_entries_lba,
- uint32_t num_partition_entries,
- uint32_t partition_entry_size,
- const gpt_guid* partition_type_guid,
- void* block_buf // Used to temporarily load blocks of SD card
- )
- {
- // Exclusive end
- uint16_t partition_entries_lba_end = (
- partition_entries_lba +
- (num_partition_entries * partition_entry_size + GPT_BLOCK_SIZE - 1) / GPT_BLOCK_SIZE
- );
- for (uint16_t i = partition_entries_lba; i < partition_entries_lba_end; i++)
- {
- sd_read_data(0, i, 1,block_buf);
- gpt_partition_range range = gpt_find_partition_by_guid(block_buf, partition_type_guid, GPT_BLOCK_SIZE / partition_entry_size);
- if (gpt_is_valid_partition_range(range))
- return range;
- }
- return gpt_invalid_partition_range();
- }
- /*read data from sd to dst*/
- int boot_load_gpt_partition(void* dst, const gpt_guid* partition_type_guid)
- {
- uint8_t gpt_buf[GPT_BLOCK_SIZE];
- gpt_partition_range part_range;
- /*READ LBA1*/
- sd_read_data(0,1,1,gpt_buf);
- {
- // header will be overwritten by find_sd_gpt_partition(), so locally
- // scope it.
- gpt_header* header = (gpt_header*) gpt_buf;
- part_range = find_sd_gpt_partition(
- header->partition_entries_lba,
- header->num_partition_entries,
- header->partition_entry_size,
- partition_type_guid,
- gpt_buf
- );
- }
- printk("gpt_partition %d:%d\n",part_range.first_lba,part_range.last_lba);
- sd_read_data(0,part_range.first_lba,part_range.last_lba + 1 - part_range.first_lba,dst);
- }
|