【轉】Linux SD卡/SDIO驅動開發0-基本知識

Linux驅動子系統-sdio子系統

sdio系統概述

MMC SD SDIO三種卡,從發展歷程來看,是先有MMC卡,後來有SD卡,這兩種都是純粹的存儲卡,而SDIO是什麼呢,從字面意思理解,應該是SD+IO,也就是既有存儲功能,又有IO控制功能,不過也有純IO功能的SDIO設備(本人用到的WIFI模塊就是這種)。並且,這三種卡可以使用同一個插槽,系統還能正確的識別!!,可能是由於歷史原因,在開始有Linux的時候,還只存在mmc卡(不存在SD和SDIO卡),所以在linux系統裏面關於這三種卡的名稱統統用“mmc“來命名。

SDIO總線和USB總線類似,SDIO總線也有兩端,其中一端是主機(HOST)端,另一端是設備端(DEVICE),採用HOST- DEVICE這樣的設計是爲了簡化DEVICE的設計,所有的通信都是由HOST端發出命令開始的。在DEVICE端只要能解析HOST的命令,就可以同HOST進行通信了,SDIO的HOST可以連接多個DEVICE。

SDIO的信號傳輸模式有SPI、1-bit、4-bit三種。在SPI模式中,第8腳位被當成中斷信號。其它腳位的功能和通信協定與SD記憶卡的標準規範一樣。在SDIO總線定義中,DAT1信號線複用爲中斷線。在SDIO的1BIT模式下DAT0用來傳輸數據,DAT1用作中斷線。在SDIO的4BIT模式下DAT0-DAT3用來傳輸數據,其中DAT1複用作中斷線

判斷sd卡是否識別

log信息如下:

[  115.399427] mmc0: new ultra high speed SDR50 SDHC card at address aaaa
[  115.401103] mmcblk0: mmc0:aaaa SS32G 29.7 GiB 
[  115.411808]  mmcblk0: p1
說明tf卡已經被正確識別,並且可用的分區p1
  • 1
  • 2
  • 3
  • 4
確認板子上的linux系統是否識別SD卡
    fdisk -l ---對應/dev/mmcblk0,/dev/mmcblk0p1
看看到底有沒有mmc相關的分區
    cat /proc/partitions
    179       64   31166976 mmcblk0
    179       65   31165440 mmcblk0p1  
掛載
    mount /dev/mmcblk0p1 /mnt
卸載
    umount /mnt
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

判斷sdio wifi是否識別

log如下:

[    2.464027] mmc0: new high speed SDIO card at address 0001
[    2.464116] hdj stdio_bus.c sdio_add_func 341 mmc0:0001:1
  • 1
  • 2

節點信息:

cat /sys/bus/sdio/devices/mmc0:0001:1/uevent //可查看SDIO設備ID
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/mmcx/ios //可查看WIFI_sdio 相關信息

# cat /sys/bus/sdio/devices/mmc0\:0001\:1/uevent         
DRIVER=rtl88x2cs             
SDIO_CLASS=07   
SDIO_ID=024C:C822                           
MODALIAS=sdio:c07v024CdC822  
  • 1
  • 2
  • 3
  • 4
  • 5
/sys/kernel/debug/mmc0 # cat ios   
clock:          50000000 Hz     
vdd:            21 (3.3 ~ 3.4 V)    
bus mode:       2 (push-pull)  
chip select:    0 (don't care) 
power mode:     2 (on)  
bus width:      2 (4 bits)     
timing spec:    2 (sd high-speed)
signal voltage: 0 (3.30 V)               
driver type:    0 (driver type B) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

sd協議

sdmmc 和 sdio接口 控制器相同.

  • 需要注意:
  1. 硬件所在的接口
  2. 供電的選擇

sd協議:https://www.jianshu.com/p/6272e4cb1eeb
SD卡按總線速度模式來分,有下面幾種:


Default Speed mode: 3.3V供電模式,頻率上限25MHz,速度上限 12.5MB/sec
High Speed mode: 3.3V供電模式,頻率上限50MHz,速度上限 25MB/sec
SDR12: UHS-I卡, 1.8V供電模式,頻率上限25MHz,速度上限 12.5MB/sec
SDR25: UHS-I卡, 1.8V供電模式,頻率上限50MHz,速度上限 25MB/sec
SDR50: UHS-I卡, 1.8V供電模式,頻率上限100MHz,速度上限 50MB/sec
SDR104: UHS-I卡, 1.8V供電模式,頻率上限208MHz,速度上限 104MB/sec
DDR50: UHS-I卡, 1.8V供電模式,頻率上限50MHz,性能上限 50MB/sec
UHS156: UHS-II RCLK Frequency Range 26MHz - 52MHz, up to 1.56Gbps per lane.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

SD BUS

物理層定義:
D0-D3 數據傳送
CMD 進行CMD 和Respons
CLK 大家最熟悉的HOST時鐘信號線了
VDD VSS 電源和地

SPI BUS

一般用SPI協議的接口來做
物理層定義:
CLK HOST時鐘信號線了
DATAIN HOST-àSD Card數據信號線
DATAOUT SD Card àHOST數據信號線

硬件接口:

引腳號 SD卡 TF卡(SD模式) TF卡(SPI模式)
1 Data3 Data2 Rsv
2 Cmd Data3 Cs
3 Vss Cmd MOSI
4 Vdd Vdd Vdd
5 Clk Clk Clk
6 Vss Vss Vss
7 Data0 Data0 MOSO
8 Data1 Data1 Rsv
9 Data2

在這裏插入圖片描述

調試的問題

sdmmc接口使用sdio wifi設備
無法識別設備

log 信息


[    3.284993]  mmc_attach_sdio 1109
[    3.285330] err =0
[    3.285333]sdio.c ocr=-1862270977
[    3.285339] dwmmc_rockchip ff0c0000.dwmmc: card claims to support voltages below defined range
[    3.285341] hdj sdio.c mmc_attach_sdio 1133 rocr =200000
[    3.313615] mmc_host mmc0: Voltage change didn't complete
[    3.320214] mmc0: error -5 whilst initialising SDIO card
[    3.325550] hdj mmc0: clock 0Hz busmode 2 powermode 0 cs 0 Vdd 0 width 0 timing 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

電壓問題
vcc_sd爲電壓域ldo供電,不需要電壓調整.
wifi 模組供電請查看模組圖,要求輸入vdd_3.3v
將電壓調整刪除掉
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
sd-uhs-sdr104;
未刪除sdr104 報錯如下,cmd11是電壓切換功能

[    2.963507] dwmmc_rockchip ff0c0000.dwmmc: Unexpected CMD11 timeout
[    2.993507] dwmmc_rockchip ff0c0000.dwmmc: Busy; trying anyway
[    2.993513] mmc_host mmc0: Timeout sending command (cmd 0x202000 arg 0x0 status 0x0)
  • 1
  • 2
  • 3
  • 4

概率不識別

mmc1: new high speed SD card at address b368
mmcblk1: mmc1:b368 SMI 486 MiB
[mmc1] Data transmission error !!!! MINTSTS: [0x00002000]
dwmmc_rockchip ff0c0000.rksdmmc: data FIFO error (status=00002000)
mmcblk1: error ‐110 sending status command, retrying
need_retune:0,brq‐>retune_retry_done:0.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

降頻和增加卡檢測延時增強電源穩定性,如果降頻OK的話,請檢查硬件layout;

&sdmmc {
card‐detect‐delay = <1200>;
}
  • 1
  • 2
  • 3

硬件問題,io電壓異常

Workqueue: kmmcd mmc_rescan
[<c0013e24>] (unwind_backtrace+0x0/0xe0) from [<c001172c>] (show_stack+0x10/0x14)
[<c001172c>] (show_stack+0x10/0x14) from [<c04fa444>] (dw_mci_set_ios+0x9c/0x21c)
[<c04fa444>] (dw_mci_set_ios+0x9c/0x21c) from [<c04e7748>] (mmc_set_chip_select+0x18/0x1c)
[<c04e7748>] (mmc_set_chip_select+0x18/0x1c) from [<c04ebd5c>] (mmc_go_idle+0x94/0xc4)
[<c04ebd5c>] (mmc_go_idle+0x94/0xc4) from [<c0748d80>] (mmc_rescan_try_freq+0x54/0xd0)
[<c0748d80>] (mmc_rescan_try_freq+0x54/0xd0) from [<c04e85d0>] (mmc_rescan+0x2c4/0x390)
[<c04e85d0>] (mmc_rescan+0x2c4/0x390) from [<c004d738>] (process_one_work+0x29c/0x458)
[<c004d738>] (process_one_work+0x29c/0x458) from [<c004da88>] (worker_thread+0x194/0x2d4)
[<c004da88>] (worker_thread+0x194/0x2d4) from [<c0052fb4>] (kthread+0xa0/0xac)
[<c0052fb4>] (kthread+0xa0/0xac) from [<c000da98>] (ret_from_fork+0x14/0x3c)
1409..dw_mci_set_ios: wait for unbusy timeout....... STATUS = 0x306 [mmc1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

請檢查CMD線與DATA的電壓是否在空載狀態下爲高電平。並且檢測IO電壓是否過低,以及IO電壓與電源域的配置
是否一致。如果是SDIO接口,建議排查VCCIO_WL電壓,VBAT_WL和WIFI_REG_ON以及晶振是否正常。另可以嘗
試排查走線太長導致波形質量很差,降頻進行測試

dts 含義解析


&sdio0 {
status = "okay";

max-frequency = &lt;150000000&gt;;  //sd卡的配置,最大運行頻率爲150Mhz

bus-width = &lt;4&gt;;  //此配置同SD卡功能。number of data lines,此配置標識需要使用SD卡的線寬。SD卡最大支持4線模式.

cap-sd-highspeed;   //此配置同SD卡功能,作爲SDIO外設,也有區分是否爲highspeed的SDIO外設

cap-sdio-irq;       //此配置標識該SDIO外設(通常是Wifi)是否支持sdio中斷,,如果你的外設是OOB中斷,

請不要加入此項。支持哪種類型的中斷請聯繫Wifi原廠確定

disable-wp;

keep-power-in-suspend;  //此配置表示是否支持睡眠不斷電,請默認加入該選項。Wifi一般都有深度喚醒的要求。

mmc-pwrseq = &lt;&amp;sdio_pwrseq&gt;;  //此項是SDIO外設(一般是Wifi)的電源控制。爲必須項,否則Wifi無法上電工作

non-removable;  //此項表示該插槽爲不可移動設備且此項爲SDIO設備必須添加項

num-slots = &lt;1&gt;; //此項同SD卡的配置。指定控制器支持的插槽數。

pinctrl-names = "default";

pinctrl-0 = &lt;&amp;sdio0_bus4 &amp;sdio0_cmd &amp;sdio0_clk &amp;sdio0_int&gt;;

sd-uhs-sdr104;  //此項配置決定該SDIO設備是否支持SDIO3.0模式。前提是需要Wifi的IO電壓爲1.8v

supports-sdio;  //標識此插槽爲SDIO功能,爲必須添加項。否則無法初始化SDIO外設。

};

轉自:Linux SD卡/SDIO驅動開發0-基本知識

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章