mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
emmc: add sd emmc driver
PD#138714: add sd/emmc driver support 1 add emmc hs200/hs400 mode 2 add sd highspeed mode 3 add sd hotplug detect 4 add emmc clock tree supported 5 add sdio get_wifi_inf & sdio_reinit 6 add partitions on dts 7 add sd/emmc pinmux set Change-Id: I449e61517844cb4cb9ad3aaa2f79c911e8658356 Signed-off-by: Nan Li <nan.li@amlogic.com>
This commit is contained in:
23
MAINTAINERS
23
MAINTAINERS
@@ -13578,3 +13578,26 @@ F: include/uapi/linux/rc_common.h
|
||||
F: arch/arm64/boot/dts/amlogic/mesongxl.dtsi
|
||||
F: arch/arm64/boot/dts/amlogic/mesongxm.dtsi
|
||||
|
||||
AMLOGIC SD/MMC DIRVER SUPPORT
|
||||
M: Nan Li <nan.li@amlogic.com>
|
||||
F: arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
|
||||
F: arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
|
||||
F: arch/arm64/boot/dts/amlogic/mesongxl.dtsi
|
||||
F: arch/arm64/configs/meson64_defconfig
|
||||
F: drivers/amlogic/Kconfig
|
||||
F: drivers/amlogic/Makefile
|
||||
F: drivers/amlogic/mmc/Kconfig
|
||||
F: drivers/amlogic/mmc/Makefile
|
||||
F: drivers/amlogic/mmc/aml_sd_emmc.c
|
||||
F: drivers/amlogic/mmc/emmc_partitions.c
|
||||
F: drivers/amlogic/mmc/amlsd_of.c
|
||||
F: drivers/amlogic/mmc/amlsd.c
|
||||
F: drivers/mmc/card/block.c
|
||||
F: drivers/mmc/core/bus.c
|
||||
F: drivers/mmc/core/core.c
|
||||
F: drivers/mmc/core/mmc.c
|
||||
F: include/linux/amlogic/amlsd.h
|
||||
F: include/linux/amlogic/sd.h
|
||||
F: include/linux/mmc/emmc_partitions.h
|
||||
F: include/linux/mmc/host.h
|
||||
|
||||
|
||||
@@ -107,11 +107,156 @@
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_c: emmc@d0074000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0074000 0x0 0x2000>;
|
||||
interrupts = <0 218 1>;
|
||||
pinctrl-names = "emmc_clk_cmd_pins", "emmc_all_pins";
|
||||
pinctrl-0 = <&emmc_clk_cmd_pins>;
|
||||
pinctrl-1 = <&emmc_conf_pull_up &emmc_conf_pull_done>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_C>,
|
||||
<&clkc CLKID_SD_EMMC_C_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <8>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
emmc {
|
||||
status = "disabled";
|
||||
pinname = "emmc";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_8_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_1_8V_DDR",
|
||||
"MMC_CAP_HW_RESET",
|
||||
"MMC_CAP_ERASE",
|
||||
"MMC_CAP_CMD23";
|
||||
caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400";
|
||||
f_min = <300000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <1>;
|
||||
/* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD)
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_b:sd@d0072000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0072000 0x0 0x2000>;
|
||||
interrupts = <0 217 1>;
|
||||
pinctrl-names = "sd_all_pins",
|
||||
"sd_clk_cmd_pins",
|
||||
"sd_clk_cmd_uart_pins",
|
||||
"sd_to_ao_uart_pins",
|
||||
"ao_to_sd_uart_pins";
|
||||
pinctrl-0 = <&sd_all_pins>;
|
||||
pinctrl-1 = <&sd_clk_cmd_pins>;
|
||||
pinctrl-2 = <&sd_clk_cmd_pins &ao_to_sd_uart_pins>;
|
||||
pinctrl-3 = <&sd_to_ao_uart_pins>;
|
||||
pinctrl-4 = <&ao_to_sd_uart_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_B>,
|
||||
<&clkc CLKID_SD_EMMC_B_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
disable-wp;
|
||||
sd {
|
||||
status = "disabled";
|
||||
pinname = "sd";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED";
|
||||
/* "MMC_CAP_UHS_SDR12",
|
||||
* "MMC_CAP_UHS_SDR25",
|
||||
* "MMC_CAP_UHS_SDR50",
|
||||
* "MMC_CAP_UHS_SDR104";
|
||||
*/
|
||||
f_min = <400000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD),
|
||||
* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card,
|
||||
* 5:NON sdio device(means sd/mmc card),
|
||||
* other:reserved
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_a:sdio@d0070000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0070000 0x0 0x2000>;
|
||||
interrupts = <0 216 4>;
|
||||
pinctrl-names = "sdio_clk_cmd_pins", "sdio_all_pins";
|
||||
pinctrl-0 = <&sdio_clk_cmd_pins>;
|
||||
pinctrl-1 = <&sdio_all_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_A>,
|
||||
<&clkc CLKID_SD_EMMC_A_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
sdio {
|
||||
status = "disabled";
|
||||
pinname = "sdio";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_UHS_SDR12",
|
||||
"MMC_CAP_UHS_SDR25",
|
||||
"MMC_CAP_UHS_SDR50",
|
||||
"MMC_CAP_UHS_SDR104",
|
||||
"MMC_PM_KEEP_POWER",
|
||||
"MMC_CAP_SDIO_IRQ";
|
||||
f_min = <400000>;
|
||||
f_max = <200000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
card_type = <3>;
|
||||
/* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
uart_AO: serial@c81004c0 {
|
||||
compatible = "amlogic, meson-uart";
|
||||
reg = <0x0 0xc81004c0 0x0 0x18>;
|
||||
interrupts = <0 193 1>;
|
||||
status = "okay";
|
||||
clocks = <&xtal>;
|
||||
clock-names = "clk_uart";
|
||||
xtal_tick_en = <1>;
|
||||
fifosize = < 64 >;
|
||||
pinctrl-names = "default";
|
||||
@@ -364,6 +509,81 @@
|
||||
interrupts = <0 89 1>;
|
||||
interrupt-names = "rdma";
|
||||
};
|
||||
|
||||
partitions: partitions{
|
||||
parts = <11>;
|
||||
part-0 = <&logo>;
|
||||
part-1 = <&recovery>;
|
||||
part-2 = <&rsv>;
|
||||
part-3 = <&tee>;
|
||||
part-4 = <&crypt>;
|
||||
part-5 = <&misc>;
|
||||
part-6 = <&instaboot>;
|
||||
part-7 = <&boot>;
|
||||
part-8 = <&system>;
|
||||
part-9 = <&cache>;
|
||||
part-10 = <&data>;
|
||||
|
||||
logo:logo{
|
||||
pname = "logo";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
recovery:recovery{
|
||||
pname = "recovery";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
rsv:rsv{
|
||||
pname = "rsv";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
tee:tee{
|
||||
pname = "tee";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
crypt:crypt{
|
||||
pname = "crypt";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
misc:misc{
|
||||
pname = "misc";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
instaboot:instaboot{
|
||||
pname = "instaboot";
|
||||
size = <0x0 0x400000>;
|
||||
mask = <1>;
|
||||
};
|
||||
boot:boot
|
||||
{
|
||||
pname = "boot";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
system:system
|
||||
{
|
||||
pname = "system";
|
||||
size = <0x0 0x80000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
cache:cache
|
||||
{
|
||||
pname = "cache";
|
||||
size = <0x0 0x20000000>;
|
||||
mask = <2>;
|
||||
};
|
||||
data:data
|
||||
{
|
||||
pname = "data";
|
||||
size = <0xffffffff 0xffffffff>;
|
||||
mask = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
&efuse {
|
||||
status = "ok";
|
||||
|
||||
@@ -108,6 +108,149 @@
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_c: emmc@d0074000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0074000 0x0 0x2000>;
|
||||
interrupts = <0 218 1>;
|
||||
pinctrl-names = "emmc_clk_cmd_pins", "emmc_all_pins";
|
||||
pinctrl-0 = <&emmc_clk_cmd_pins>;
|
||||
pinctrl-1 = <&emmc_conf_pull_up &emmc_conf_pull_done>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_C>,
|
||||
<&clkc CLKID_SD_EMMC_C_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <8>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
emmc {
|
||||
status = "disabled";
|
||||
pinname = "emmc";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_8_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_1_8V_DDR",
|
||||
"MMC_CAP_HW_RESET",
|
||||
"MMC_CAP_ERASE",
|
||||
"MMC_CAP_CMD23";
|
||||
caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400";
|
||||
f_min = <300000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <1>;
|
||||
/* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD)
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_b:sd@d0072000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0072000 0x0 0x2000>;
|
||||
interrupts = <0 217 1>;
|
||||
pinctrl-names = "sd_all_pins",
|
||||
"sd_clk_cmd_pins",
|
||||
"sd_clk_cmd_uart_pins",
|
||||
"sd_to_ao_uart_pins",
|
||||
"ao_to_sd_uart_pins";
|
||||
pinctrl-0 = <&sd_all_pins>;
|
||||
pinctrl-1 = <&sd_clk_cmd_pins>;
|
||||
pinctrl-2 = <&sd_clk_cmd_pins &ao_to_sd_uart_pins>;
|
||||
pinctrl-3 = <&sd_to_ao_uart_pins>;
|
||||
pinctrl-4 = <&ao_to_sd_uart_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_B>,
|
||||
<&clkc CLKID_SD_EMMC_B_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
disable-wp;
|
||||
sd {
|
||||
status = "disabled";
|
||||
pinname = "sd";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED";
|
||||
/* "MMC_CAP_UHS_SDR12",
|
||||
* "MMC_CAP_UHS_SDR25",
|
||||
* "MMC_CAP_UHS_SDR50",
|
||||
* "MMC_CAP_UHS_SDR104";
|
||||
*/
|
||||
f_min = <400000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD),
|
||||
* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card,
|
||||
* 5:NON sdio device(means sd/mmc card),
|
||||
* other:reserved
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_a:sdio@d0070000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0070000 0x0 0x2000>;
|
||||
interrupts = <0 216 4>;
|
||||
pinctrl-names = "sdio_clk_cmd_pins", "sdio_all_pins";
|
||||
pinctrl-0 = <&sdio_clk_cmd_pins>;
|
||||
pinctrl-1 = <&sdio_all_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_A>,
|
||||
<&clkc CLKID_SD_EMMC_A_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
sdio {
|
||||
status = "disabled";
|
||||
pinname = "sdio";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_UHS_SDR12",
|
||||
"MMC_CAP_UHS_SDR25",
|
||||
"MMC_CAP_UHS_SDR50",
|
||||
"MMC_CAP_UHS_SDR104",
|
||||
"MMC_PM_KEEP_POWER",
|
||||
"MMC_CAP_SDIO_IRQ";
|
||||
f_min = <400000>;
|
||||
f_max = <200000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
card_type = <3>;
|
||||
/* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
uart_AO: serial@c81004c0 {
|
||||
compatible = "amlogic, meson-uart";
|
||||
reg = <0x0 0xc81004c0 0x0 0x18>;
|
||||
@@ -364,6 +507,81 @@
|
||||
interrupts = <0 89 1>;
|
||||
interrupt-names = "rdma";
|
||||
};
|
||||
|
||||
partitions: partitions{
|
||||
parts = <11>;
|
||||
part-0 = <&logo>;
|
||||
part-1 = <&recovery>;
|
||||
part-2 = <&rsv>;
|
||||
part-3 = <&tee>;
|
||||
part-4 = <&crypt>;
|
||||
part-5 = <&misc>;
|
||||
part-6 = <&instaboot>;
|
||||
part-7 = <&boot>;
|
||||
part-8 = <&system>;
|
||||
part-9 = <&cache>;
|
||||
part-10 = <&data>;
|
||||
|
||||
logo:logo{
|
||||
pname = "logo";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
recovery:recovery{
|
||||
pname = "recovery";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
rsv:rsv{
|
||||
pname = "rsv";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
tee:tee{
|
||||
pname = "tee";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
crypt:crypt{
|
||||
pname = "crypt";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
misc:misc{
|
||||
pname = "misc";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
instaboot:instaboot{
|
||||
pname = "instaboot";
|
||||
size = <0x0 0x400000>;
|
||||
mask = <1>;
|
||||
};
|
||||
boot:boot
|
||||
{
|
||||
pname = "boot";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
system:system
|
||||
{
|
||||
pname = "system";
|
||||
size = <0x0 0x80000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
cache:cache
|
||||
{
|
||||
pname = "cache";
|
||||
size = <0x0 0x20000000>;
|
||||
mask = <2>;
|
||||
};
|
||||
data:data
|
||||
{
|
||||
pname = "data";
|
||||
size = <0xffffffff 0xffffffff>;
|
||||
mask = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
&efuse {
|
||||
status = "ok";
|
||||
|
||||
@@ -107,11 +107,156 @@
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_c: emmc@d0074000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0074000 0x0 0x2000>;
|
||||
interrupts = <0 218 1>;
|
||||
pinctrl-names = "emmc_clk_cmd_pins", "emmc_all_pins";
|
||||
pinctrl-0 = <&emmc_clk_cmd_pins>;
|
||||
pinctrl-1 = <&emmc_conf_pull_up &emmc_conf_pull_done>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_C>,
|
||||
<&clkc CLKID_SD_EMMC_C_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <8>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
emmc {
|
||||
status = "disabled";
|
||||
pinname = "emmc";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_8_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_1_8V_DDR",
|
||||
"MMC_CAP_HW_RESET",
|
||||
"MMC_CAP_ERASE",
|
||||
"MMC_CAP_CMD23";
|
||||
caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400";
|
||||
f_min = <300000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <1>;
|
||||
/* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD)
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_b:sd@d0072000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0072000 0x0 0x2000>;
|
||||
interrupts = <0 217 1>;
|
||||
pinctrl-names = "sd_all_pins",
|
||||
"sd_clk_cmd_pins",
|
||||
"sd_clk_cmd_uart_pins",
|
||||
"sd_to_ao_uart_pins",
|
||||
"ao_to_sd_uart_pins";
|
||||
pinctrl-0 = <&sd_all_pins>;
|
||||
pinctrl-1 = <&sd_clk_cmd_pins>;
|
||||
pinctrl-2 = <&sd_clk_cmd_pins &ao_to_sd_uart_pins>;
|
||||
pinctrl-3 = <&sd_to_ao_uart_pins>;
|
||||
pinctrl-4 = <&ao_to_sd_uart_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_B>,
|
||||
<&clkc CLKID_SD_EMMC_B_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
disable-wp;
|
||||
sd {
|
||||
status = "disabled";
|
||||
pinname = "sd";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED";
|
||||
/* "MMC_CAP_UHS_SDR12",
|
||||
* "MMC_CAP_UHS_SDR25",
|
||||
* "MMC_CAP_UHS_SDR50",
|
||||
* "MMC_CAP_UHS_SDR104";
|
||||
*/
|
||||
f_min = <400000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD),
|
||||
* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card,
|
||||
* 5:NON sdio device(means sd/mmc card),
|
||||
* other:reserved
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_a:sdio@d0070000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0070000 0x0 0x2000>;
|
||||
interrupts = <0 216 4>;
|
||||
pinctrl-names = "sdio_clk_cmd_pins", "sdio_all_pins";
|
||||
pinctrl-0 = <&sdio_clk_cmd_pins>;
|
||||
pinctrl-1 = <&sdio_all_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_A>,
|
||||
<&clkc CLKID_SD_EMMC_A_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
sdio {
|
||||
status = "disabled";
|
||||
pinname = "sdio";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_UHS_SDR12",
|
||||
"MMC_CAP_UHS_SDR25",
|
||||
"MMC_CAP_UHS_SDR50",
|
||||
"MMC_CAP_UHS_SDR104",
|
||||
"MMC_PM_KEEP_POWER",
|
||||
"MMC_CAP_SDIO_IRQ";
|
||||
f_min = <400000>;
|
||||
f_max = <200000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
card_type = <3>;
|
||||
/* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
uart_AO: serial@c81004c0 {
|
||||
compatible = "amlogic, meson-uart";
|
||||
reg = <0x0 0xc81004c0 0x0 0x18>;
|
||||
interrupts = <0 193 1>;
|
||||
status = "okay";
|
||||
clocks = <&xtal>;
|
||||
clock-names = "clk_uart";
|
||||
xtal_tick_en = <1>;
|
||||
fifosize = < 64 >;
|
||||
pinctrl-names = "default";
|
||||
@@ -363,6 +508,81 @@
|
||||
interrupts = <0 89 1>;
|
||||
interrupt-names = "rdma";
|
||||
};
|
||||
|
||||
partitions: partitions{
|
||||
parts = <11>;
|
||||
part-0 = <&logo>;
|
||||
part-1 = <&recovery>;
|
||||
part-2 = <&rsv>;
|
||||
part-3 = <&tee>;
|
||||
part-4 = <&crypt>;
|
||||
part-5 = <&misc>;
|
||||
part-6 = <&instaboot>;
|
||||
part-7 = <&boot>;
|
||||
part-8 = <&system>;
|
||||
part-9 = <&cache>;
|
||||
part-10 = <&data>;
|
||||
|
||||
logo:logo{
|
||||
pname = "logo";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
recovery:recovery{
|
||||
pname = "recovery";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
rsv:rsv{
|
||||
pname = "rsv";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
tee:tee{
|
||||
pname = "tee";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
crypt:crypt{
|
||||
pname = "crypt";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
misc:misc{
|
||||
pname = "misc";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
instaboot:instaboot{
|
||||
pname = "instaboot";
|
||||
size = <0x0 0x400000>;
|
||||
mask = <1>;
|
||||
};
|
||||
boot:boot
|
||||
{
|
||||
pname = "boot";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
system:system
|
||||
{
|
||||
pname = "system";
|
||||
size = <0x0 0x80000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
cache:cache
|
||||
{
|
||||
pname = "cache";
|
||||
size = <0x0 0x20000000>;
|
||||
mask = <2>;
|
||||
};
|
||||
data:data
|
||||
{
|
||||
pname = "data";
|
||||
size = <0xffffffff 0xffffffff>;
|
||||
mask = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
&efuse {
|
||||
status = "ok";
|
||||
|
||||
@@ -108,6 +108,149 @@
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_c: emmc@d0074000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0074000 0x0 0x2000>;
|
||||
interrupts = <0 218 1>;
|
||||
pinctrl-names = "emmc_clk_cmd_pins", "emmc_all_pins";
|
||||
pinctrl-0 = <&emmc_clk_cmd_pins>;
|
||||
pinctrl-1 = <&emmc_conf_pull_up &emmc_conf_pull_done>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_C>,
|
||||
<&clkc CLKID_SD_EMMC_C_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <8>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
emmc {
|
||||
status = "disabled";
|
||||
pinname = "emmc";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_8_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_1_8V_DDR",
|
||||
"MMC_CAP_HW_RESET",
|
||||
"MMC_CAP_ERASE",
|
||||
"MMC_CAP_CMD23";
|
||||
caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400";
|
||||
f_min = <300000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
hw_reset = <&gpio BOOT_9 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <1>;
|
||||
/* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD)
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_b:sd@d0072000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0072000 0x0 0x2000>;
|
||||
interrupts = <0 217 1>;
|
||||
pinctrl-names = "sd_all_pins",
|
||||
"sd_clk_cmd_pins",
|
||||
"sd_clk_cmd_uart_pins",
|
||||
"sd_to_ao_uart_pins",
|
||||
"ao_to_sd_uart_pins";
|
||||
pinctrl-0 = <&sd_all_pins>;
|
||||
pinctrl-1 = <&sd_clk_cmd_pins>;
|
||||
pinctrl-2 = <&sd_clk_cmd_pins &ao_to_sd_uart_pins>;
|
||||
pinctrl-3 = <&sd_to_ao_uart_pins>;
|
||||
pinctrl-4 = <&ao_to_sd_uart_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_B>,
|
||||
<&clkc CLKID_SD_EMMC_B_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
disable-wp;
|
||||
sd {
|
||||
status = "disabled";
|
||||
pinname = "sd";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED";
|
||||
/* "MMC_CAP_UHS_SDR12",
|
||||
* "MMC_CAP_UHS_SDR25",
|
||||
* "MMC_CAP_UHS_SDR50",
|
||||
* "MMC_CAP_UHS_SDR104";
|
||||
*/
|
||||
f_min = <400000>;
|
||||
f_max = <100000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
gpio_dat3 = <&gpio CARD_4 GPIO_ACTIVE_HIGH>;
|
||||
jtag_pin = <&gpio CARD_0 GPIO_ACTIVE_HIGH>;
|
||||
gpio_cd = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
|
||||
card_type = <5>;
|
||||
/* 0:unknown,
|
||||
* 1:mmc card(include eMMC),
|
||||
* 2:sd card(include tSD),
|
||||
* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card,
|
||||
* 5:NON sdio device(means sd/mmc card),
|
||||
* other:reserved
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
sd_emmc_a:sdio@d0070000 {
|
||||
status = "okay";
|
||||
compatible = "amlogic, meson-aml-mmc";
|
||||
reg = <0x0 0xd0070000 0x0 0x2000>;
|
||||
interrupts = <0 216 4>;
|
||||
pinctrl-names = "sdio_clk_cmd_pins", "sdio_all_pins";
|
||||
pinctrl-0 = <&sdio_clk_cmd_pins>;
|
||||
pinctrl-1 = <&sdio_all_pins>;
|
||||
clocks = <&clkc CLKID_SD_EMMC_A>,
|
||||
<&clkc CLKID_SD_EMMC_A_P0_COMP>,
|
||||
<&clkc CLKID_FCLK_DIV2>;
|
||||
clock-names = "core", "clkin0", "clkin1";
|
||||
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
max-frequency = <100000000>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
sdio {
|
||||
status = "disabled";
|
||||
pinname = "sdio";
|
||||
ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */
|
||||
caps = "MMC_CAP_4_BIT_DATA",
|
||||
"MMC_CAP_MMC_HIGHSPEED",
|
||||
"MMC_CAP_SD_HIGHSPEED",
|
||||
"MMC_CAP_NONREMOVABLE",
|
||||
"MMC_CAP_UHS_SDR12",
|
||||
"MMC_CAP_UHS_SDR25",
|
||||
"MMC_CAP_UHS_SDR50",
|
||||
"MMC_CAP_UHS_SDR104",
|
||||
"MMC_PM_KEEP_POWER",
|
||||
"MMC_CAP_SDIO_IRQ";
|
||||
f_min = <400000>;
|
||||
f_max = <200000000>;
|
||||
max_req_size = <0x20000>; /**128KB*/
|
||||
card_type = <3>;
|
||||
/* 3:sdio device(ie:sdio-wifi),
|
||||
* 4:SD combo (IO+mem) card
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
uart_AO: serial@c81004c0 {
|
||||
compatible = "amlogic, meson-uart";
|
||||
reg = <0x0 0xc81004c0 0x0 0x18>;
|
||||
@@ -115,6 +258,8 @@
|
||||
status = "okay";
|
||||
xtal_tick_en = <1>;
|
||||
fifosize = < 64 >;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ao_uart_pins>;
|
||||
support-sysrq = <0>; /* 0 not support , 1 support */
|
||||
};
|
||||
|
||||
@@ -208,6 +353,25 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
amhdmitx: amhdmitx{
|
||||
compatible = "amlogic, amhdmitx";
|
||||
dev_name = "amhdmitx";
|
||||
status = "okay";
|
||||
vend-data = <&vend_data>;
|
||||
pinctrl-names="hdmitx_hpd", "hdmitx_ddc";
|
||||
pinctrl-0=<&hdmitx_hpd>;
|
||||
pinctrl-1=<&hdmitx_ddc>;
|
||||
/* HPD, 57 + 32 = 89; CEC, 151 + 32 = 183*/
|
||||
interrupts = <0 57 1>;
|
||||
interrupt-names = "hdmitx_hpd";
|
||||
vend_data: vend_data{ /* Should modified by Customer */
|
||||
vendor_name = "Amlogic"; /* Max Chars: 8 */
|
||||
/* standards.ieee.org/develop/regauth/oui/oui.txt */
|
||||
vendor_id = <0x000000>;
|
||||
product_desc = "MBox Meson Ref"; /* Max Chars: 16 */
|
||||
};
|
||||
};
|
||||
|
||||
meson-fb {
|
||||
compatible = "amlogic, meson-fb";
|
||||
/* memory-region = <&fb_reserved>; */
|
||||
@@ -245,27 +409,82 @@
|
||||
interrupts = <0 89 1>;
|
||||
interrupt-names = "rdma";
|
||||
};
|
||||
amhdmitx: amhdmitx{
|
||||
compatible = "amlogic, amhdmitx";
|
||||
dev_name = "amhdmitx";
|
||||
status = "okay";
|
||||
vend-data = <&vend_data>;
|
||||
pinctrl-names="hdmitx_hpd", "hdmitx_ddc";
|
||||
pinctrl-0=<&hdmitx_hpd>;
|
||||
pinctrl-1=<&hdmitx_ddc>;
|
||||
/* HPD, 57 + 32 = 89; CEC, 151 + 32 = 183*/
|
||||
interrupts = <0 57 1>;
|
||||
interrupt-names = "hdmitx_hpd";
|
||||
ranges;
|
||||
vend_data: vend_data{ /* Should modified by Customer */
|
||||
vendor_name = "Amlogic"; /* Max Chars: 8 */
|
||||
/* standards.ieee.org/develop/regauth/oui/oui.txt */
|
||||
vendor_id = <0x000000>;
|
||||
product_desc = "MBox Meson Ref"; /* Max Chars: 16 */
|
||||
|
||||
partitions: partitions{
|
||||
parts = <11>;
|
||||
part-0 = <&logo>;
|
||||
part-1 = <&recovery>;
|
||||
part-2 = <&rsv>;
|
||||
part-3 = <&tee>;
|
||||
part-4 = <&crypt>;
|
||||
part-5 = <&misc>;
|
||||
part-6 = <&instaboot>;
|
||||
part-7 = <&boot>;
|
||||
part-8 = <&system>;
|
||||
part-9 = <&cache>;
|
||||
part-10 = <&data>;
|
||||
|
||||
logo:logo{
|
||||
pname = "logo";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
recovery:recovery{
|
||||
pname = "recovery";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
rsv:rsv{
|
||||
pname = "rsv";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
tee:tee{
|
||||
pname = "tee";
|
||||
size = <0x0 0x800000>;
|
||||
mask = <1>;
|
||||
};
|
||||
crypt:crypt{
|
||||
pname = "crypt";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
misc:misc{
|
||||
pname = "misc";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
instaboot:instaboot{
|
||||
pname = "instaboot";
|
||||
size = <0x0 0x400000>;
|
||||
mask = <1>;
|
||||
};
|
||||
boot:boot
|
||||
{
|
||||
pname = "boot";
|
||||
size = <0x0 0x2000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
system:system
|
||||
{
|
||||
pname = "system";
|
||||
size = <0x0 0x80000000>;
|
||||
mask = <1>;
|
||||
};
|
||||
cache:cache
|
||||
{
|
||||
pname = "cache";
|
||||
size = <0x0 0x20000000>;
|
||||
mask = <2>;
|
||||
};
|
||||
data:data
|
||||
{
|
||||
pname = "data";
|
||||
size = <0xffffffff 0xffffffff>;
|
||||
mask = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&efuse {
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <dt-bindings/reset/amlogic,gxl-reset.h>
|
||||
#include <dt-bindings/clock/amlogic,gxl-clkc.h>
|
||||
#include <dt-bindings/gpio/gxl.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/input/meson_rc.h>
|
||||
@@ -396,6 +397,15 @@
|
||||
function = "remote";
|
||||
};
|
||||
};
|
||||
sd_to_ao_uart_pins:sd_to_ao_uart_pins {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a_0",
|
||||
"uart_rx_ao_a_0";
|
||||
function = "uart_ao";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
|
||||
ao_uart_pins:ao_uart {
|
||||
mux {
|
||||
@@ -552,32 +562,29 @@
|
||||
* };
|
||||
* sd_1bit_uart_pins:sd_1bit_uart_pins {
|
||||
* };
|
||||
* sd_to_ao_uart_pins:sd_to_ao_uart_pins {
|
||||
* };
|
||||
* ao_to_sd_uart_pins:ao_to_sd_uart_pins {
|
||||
* };
|
||||
* sd_to_ao_jtag_pins:sd_to_ao_jtag_pins{
|
||||
* };
|
||||
*/
|
||||
ao_to_sd_uart_pins:ao_to_sd_uart_pins {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a_1",
|
||||
"uart_rx_ao_a_1";
|
||||
function = "uart_ao_a_1";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_clk_cmd_pins:emmc_clk_cmd_pins {
|
||||
mux {
|
||||
groups = "emmc_cmd",
|
||||
"emmc_clk";
|
||||
function = "emmc";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_pins: emmc {
|
||||
mux {
|
||||
groups = "emmc_nand_d07",
|
||||
"emmc_cmd",
|
||||
"emmc_clk";
|
||||
function = "emmc";
|
||||
};
|
||||
};
|
||||
|
||||
emmc_conf_pull_up:emmc_conf_pull_up {
|
||||
mux {
|
||||
@@ -585,6 +592,7 @@
|
||||
"emmc_clk",
|
||||
"emmc_cmd";
|
||||
function = "emmc";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
@@ -593,17 +601,32 @@
|
||||
mux {
|
||||
groups = "emmc_ds";
|
||||
function = "emmc";
|
||||
input-enable;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_all_pins:emmc_all_pins {
|
||||
sd_clk_cmd_pins:sd_clk_cmd_pins{
|
||||
mux {
|
||||
groups = "emmc_nand_d07",
|
||||
"emmc_clk",
|
||||
"emmc_cmd";
|
||||
function = "emmc";
|
||||
groups = "sdcard_cmd",
|
||||
"sdcard_clk";
|
||||
function = "sdcard";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
sd_all_pins:sd_all_pins{
|
||||
mux {
|
||||
groups = "sdcard_d0",
|
||||
"sdcard_d1",
|
||||
"sdcard_d2",
|
||||
"sdcard_d3",
|
||||
"sdcard_cmd",
|
||||
"sdcard_clk";
|
||||
function = "sdcard";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <dt-bindings/reset/amlogic,gxl-reset.h>
|
||||
#include <dt-bindings/clock/amlogic,gxl-clkc.h>
|
||||
#include <dt-bindings/gpio/gxl.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/input/meson_rc.h>
|
||||
@@ -448,6 +449,15 @@
|
||||
function = "remote";
|
||||
};
|
||||
};
|
||||
sd_to_ao_uart_pins:sd_to_ao_uart_pins {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a_0",
|
||||
"uart_rx_ao_a_0";
|
||||
function = "uart_ao";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
|
||||
ao_uart_pins:ao_uart {
|
||||
mux {
|
||||
@@ -604,32 +614,29 @@
|
||||
* };
|
||||
* sd_1bit_uart_pins:sd_1bit_uart_pins {
|
||||
* };
|
||||
* sd_to_ao_uart_pins:sd_to_ao_uart_pins {
|
||||
* };
|
||||
* ao_to_sd_uart_pins:ao_to_sd_uart_pins {
|
||||
* };
|
||||
* sd_to_ao_jtag_pins:sd_to_ao_jtag_pins{
|
||||
* };
|
||||
*/
|
||||
ao_to_sd_uart_pins:ao_to_sd_uart_pins {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a_1",
|
||||
"uart_rx_ao_a_1";
|
||||
function = "uart_ao_a_1";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_clk_cmd_pins:emmc_clk_cmd_pins {
|
||||
mux {
|
||||
groups = "emmc_cmd",
|
||||
"emmc_clk";
|
||||
function = "emmc";
|
||||
bias-pull-up;
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_pins: emmc {
|
||||
mux {
|
||||
groups = "emmc_nand_d07",
|
||||
"emmc_cmd",
|
||||
"emmc_clk";
|
||||
function = "emmc";
|
||||
};
|
||||
};
|
||||
|
||||
emmc_conf_pull_up:emmc_conf_pull_up {
|
||||
mux {
|
||||
@@ -637,6 +644,7 @@
|
||||
"emmc_clk",
|
||||
"emmc_cmd";
|
||||
function = "emmc";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
@@ -645,17 +653,32 @@
|
||||
mux {
|
||||
groups = "emmc_ds";
|
||||
function = "emmc";
|
||||
input-enable;
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
|
||||
emmc_all_pins:emmc_all_pins {
|
||||
sd_clk_cmd_pins:sd_clk_cmd_pins{
|
||||
mux {
|
||||
groups = "emmc_nand_d07",
|
||||
"emmc_clk",
|
||||
"emmc_cmd";
|
||||
function = "emmc";
|
||||
groups = "sdcard_cmd",
|
||||
"sdcard_clk";
|
||||
function = "sdcard";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
sd_all_pins:sd_all_pins{
|
||||
mux {
|
||||
groups = "sdcard_d0",
|
||||
"sdcard_d1",
|
||||
"sdcard_d2",
|
||||
"sdcard_d3",
|
||||
"sdcard_cmd",
|
||||
"sdcard_clk";
|
||||
function = "sdcard";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA=y
|
||||
CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE=y
|
||||
CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR=y
|
||||
CONFIG_AMLOGIC_HDMITX=y
|
||||
CONFIG_AMLOGIC_MMC=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
@@ -287,6 +288,9 @@ CONFIG_USB_ISP1301=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_ARMMMCI=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
|
||||
@@ -51,5 +51,7 @@ source "drivers/amlogic/pwm/Kconfig"
|
||||
|
||||
source "drivers/amlogic/media/Kconfig"
|
||||
|
||||
source "drivers/amlogic/mmc/Kconfig"
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
||||
@@ -47,3 +47,6 @@ obj-$(CONFIG_AMLOGIC_PWM) += pwm/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_ENABLE) += media/
|
||||
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_MMC) += mmc/
|
||||
|
||||
|
||||
19
drivers/amlogic/mmc/Kconfig
Normal file
19
drivers/amlogic/mmc/Kconfig
Normal file
@@ -0,0 +1,19 @@
|
||||
# Amlogic MMC driver
|
||||
|
||||
comment "MMC/SD/SDIO Host Controller Drivers"
|
||||
|
||||
menu "Multimedia Card support"
|
||||
|
||||
config AMLOGIC_MMC
|
||||
bool "Amlogic Multimedia Card support"
|
||||
depends on MMC
|
||||
depends on MMC_BLOCK
|
||||
depends on MMC_BLOCK_BOUNCE
|
||||
default n
|
||||
help
|
||||
This selects support for the Amlogic SD/MMC Host Controller
|
||||
found on the S912/GXM family of SoCs. This controller is
|
||||
MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces.
|
||||
If you have a controller with this interface, say Y here.
|
||||
|
||||
endmenu
|
||||
5
drivers/amlogic/mmc/Makefile
Normal file
5
drivers/amlogic/mmc/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Amlogic MMC specific Makefile
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_MMC) += amlsd.o amlsd_of.o emmc_partitions.o aml_sd_emmc.o
|
||||
2921
drivers/amlogic/mmc/aml_sd_emmc.c
Normal file
2921
drivers/amlogic/mmc/aml_sd_emmc.c
Normal file
File diff suppressed because it is too large
Load Diff
542
drivers/amlogic/mmc/amlsd.c
Normal file
542
drivers/amlogic/mmc/amlsd.c
Normal file
@@ -0,0 +1,542 @@
|
||||
/*
|
||||
* drivers/amlogic/mmc/amlsd.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/sdio.h>
|
||||
#include <linux/mmc/sd.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/amlogic/sd.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
/* #include <linux/amlogic/aml_gpio_consumer.h> */
|
||||
#include <linux/amlogic/amlsd.h>
|
||||
|
||||
const u8 tuning_blk_pattern_4bit[64] = {
|
||||
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
|
||||
0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
|
||||
0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
|
||||
0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
|
||||
0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
|
||||
0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
|
||||
0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
|
||||
0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
|
||||
};
|
||||
const u8 tuning_blk_pattern_8bit[128] = {
|
||||
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
|
||||
0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
|
||||
0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
|
||||
0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
|
||||
0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
|
||||
0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
|
||||
0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
|
||||
0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
|
||||
0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
|
||||
0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
|
||||
0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
|
||||
0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
|
||||
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
|
||||
};
|
||||
|
||||
void aml_mmc_ver_msg_show(void)
|
||||
{
|
||||
static bool one_time_flag;
|
||||
|
||||
if (!one_time_flag) {
|
||||
pr_info("mmc driver version: %d.%02d, %s\n",
|
||||
AML_MMC_MAJOR_VERSION, AML_MMC_MINOR_VERSION,
|
||||
AML_MMC_VER_MESSAGE);
|
||||
|
||||
one_time_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int aml_is_card_insert(struct amlsd_platform *pdata)
|
||||
{
|
||||
int ret = 0, in_count = 0, out_count = 0, i;
|
||||
|
||||
if (pdata->gpio_cd) {
|
||||
mdelay(pdata->card_in_delay);
|
||||
for (i = 0; i < 200; i++) {
|
||||
ret = gpio_get_value(pdata->gpio_cd);
|
||||
if (ret)
|
||||
out_count++;
|
||||
in_count++;
|
||||
if ((out_count > 100) || (in_count > 100))
|
||||
break;
|
||||
}
|
||||
if (out_count > 100)
|
||||
ret = 1;
|
||||
else if (in_count > 100)
|
||||
ret = 0;
|
||||
}
|
||||
sdio_err("card %s\n", ret?"OUT":"IN");
|
||||
if (!pdata->gpio_cd_level)
|
||||
ret = !ret; /* reverse, so ---- 0: no inserted 1: inserted */
|
||||
|
||||
return ret;
|
||||
}
|
||||
int aml_sd_uart_detect(struct amlsd_host *host)
|
||||
{
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
|
||||
if (aml_is_card_insert(pdata)) {
|
||||
if (pdata->is_in)
|
||||
return 1;
|
||||
pdata->is_in = true;
|
||||
pr_info("normal card in\n");
|
||||
if (pdata->caps & MMC_CAP_4_BIT_DATA)
|
||||
host->mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
} else {
|
||||
if (!pdata->is_in)
|
||||
return 1;
|
||||
pdata->is_in = false;
|
||||
pr_info("card out\n");
|
||||
|
||||
pdata->is_tuned = false;
|
||||
if (host->mmc && host->mmc->card)
|
||||
mmc_card_set_removed(host->mmc->card);
|
||||
/* switch to 3.3V */
|
||||
aml_sd_voltage_switch(host->mmc,
|
||||
MMC_SIGNAL_VOLTAGE_330);
|
||||
|
||||
if (pdata->caps & MMC_CAP_4_BIT_DATA)
|
||||
host->mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int card_dealed;
|
||||
irqreturn_t aml_irq_cd_thread(int irq, void *data)
|
||||
{
|
||||
struct amlsd_host *host = (struct amlsd_host *)data;
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&pdata->in_out_lock);
|
||||
if (card_dealed == 1) {
|
||||
card_dealed = 0;
|
||||
mutex_unlock(&pdata->in_out_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
ret = aml_sd_uart_detect(host);
|
||||
if (ret == 1) {/* the same as the last*/
|
||||
mutex_unlock(&pdata->in_out_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
card_dealed = 1;
|
||||
if ((pdata->is_in == 0) && aml_card_type_non_sdio(pdata))
|
||||
host->init_flag = 0;
|
||||
mutex_unlock(&pdata->in_out_lock);
|
||||
|
||||
/* mdelay(500); */
|
||||
if (pdata->is_in)
|
||||
mmc_detect_change(host->mmc, msecs_to_jiffies(100));
|
||||
else
|
||||
mmc_detect_change(host->mmc, msecs_to_jiffies(0));
|
||||
|
||||
card_dealed = 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
irqreturn_t aml_sd_irq_cd(int irq, void *dev_id)
|
||||
{
|
||||
/* pr_info("cd dev_id %x\n", (unsigned)dev_id); */
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static int aml_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&host->mrq_lock, flags);
|
||||
mrq->cmd->error = -EINVAL;
|
||||
spin_unlock_irqrestore(&host->mrq_lock, flags);
|
||||
mmc_request_done(mmc, mrq);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int aml_rpmb_cmd_invalid(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&host->mrq_lock, flags);
|
||||
host->xfer_step = XFER_FINISHED;
|
||||
host->mrq = NULL;
|
||||
host->status = HOST_INVALID;
|
||||
spin_unlock_irqrestore(&host->mrq_lock, flags);
|
||||
mrq->data->bytes_xfered = mrq->data->blksz*mrq->data->blocks;
|
||||
mmc_request_done(mmc, mrq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int aml_check_unsupport_cmd(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
u32 opcode, arg;
|
||||
|
||||
opcode = mrq->cmd->opcode;
|
||||
arg = mrq->cmd->arg;
|
||||
/* CMD3 means the first time initialized flow is running */
|
||||
if (opcode == 3)
|
||||
mmc->first_init_flag = false;
|
||||
|
||||
if (aml_card_type_mmc(pdata)) {
|
||||
if (opcode == 6) {
|
||||
if (arg == 0x3B30301)
|
||||
pdata->rmpb_cmd_flag = 1;
|
||||
else
|
||||
pdata->rmpb_cmd_flag = 0;
|
||||
}
|
||||
if (pdata->rmpb_cmd_flag && (!pdata->rpmb_valid_command)) {
|
||||
if ((opcode == 18)
|
||||
|| (opcode == 25))
|
||||
return aml_rpmb_cmd_invalid(mmc, mrq);
|
||||
}
|
||||
if (pdata->rmpb_cmd_flag && (opcode == 23))
|
||||
pdata->rpmb_valid_command = 1;
|
||||
else
|
||||
pdata->rpmb_valid_command = 0;
|
||||
}
|
||||
|
||||
if (mmc->caps & MMC_CAP_NONREMOVABLE) { /* nonremovable device */
|
||||
if (mmc->first_init_flag) { /* init for the first time */
|
||||
/* for 8189ETV needs ssdio reset when starts */
|
||||
if (aml_card_type_sdio(pdata)) {
|
||||
/* if (opcode == SD_IO_RW_DIRECT
|
||||
* || opcode == SD_IO_RW_EXTENDED
|
||||
* || opcode == SD_SEND_IF_COND)
|
||||
* return aml_cmd_invalid(mmc, mrq);
|
||||
*/
|
||||
return 0;
|
||||
} else if (aml_card_type_mmc(pdata)) {
|
||||
if (opcode == SD_IO_SEND_OP_COND
|
||||
|| opcode == SD_IO_RW_DIRECT
|
||||
|| opcode == SD_IO_RW_EXTENDED
|
||||
|| opcode == SD_SEND_IF_COND
|
||||
|| opcode == MMC_APP_CMD)
|
||||
return aml_cmd_invalid(mmc, mrq);
|
||||
} else if (aml_card_type_sd(pdata)
|
||||
|| aml_card_type_non_sdio(pdata)) {
|
||||
if (opcode == SD_IO_SEND_OP_COND
|
||||
|| opcode == SD_IO_RW_DIRECT
|
||||
|| opcode == SD_IO_RW_EXTENDED)
|
||||
return aml_cmd_invalid(mmc, mrq);
|
||||
}
|
||||
}
|
||||
} else { /* removable device */
|
||||
/* filter cmd 5/52/53 for a non-sdio device */
|
||||
if (!aml_card_type_sdio(pdata)
|
||||
&& !aml_card_type_unknown(pdata)) {
|
||||
if (opcode == SD_IO_SEND_OP_COND
|
||||
|| opcode == SD_IO_RW_DIRECT
|
||||
|| opcode == SD_IO_RW_EXTENDED)
|
||||
return aml_cmd_invalid(mmc, mrq);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aml_sd_voltage_switch(struct mmc_host *mmc, char signal_voltage)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
int ret = 0;
|
||||
|
||||
/* voltage is the same, return directly */
|
||||
if (!aml_card_type_non_sdio(pdata)
|
||||
|| (pdata->signal_voltage == signal_voltage)) {
|
||||
if (aml_card_type_sdio(pdata))
|
||||
host->sd_sdio_switch_volat_done = 1;
|
||||
return 0;
|
||||
}
|
||||
if (pdata->vol_switch) {
|
||||
if (pdata->signal_voltage == 0xff) {
|
||||
gpio_free(pdata->vol_switch);
|
||||
ret = gpio_request_one(pdata->vol_switch,
|
||||
GPIOF_OUT_INIT_HIGH, MODULE_NAME);
|
||||
if (ret) {
|
||||
pr_err("%s [%d] request error\n",
|
||||
__func__, __LINE__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
|
||||
ret = gpio_direction_output(pdata->vol_switch,
|
||||
pdata->vol_switch_18);
|
||||
else
|
||||
ret = gpio_direction_output(pdata->vol_switch,
|
||||
(!pdata->vol_switch_18));
|
||||
CHECK_RET(ret);
|
||||
if (!ret)
|
||||
pdata->signal_voltage = signal_voltage;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
host->sd_sdio_switch_volat_done = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* boot9 here */
|
||||
void aml_emmc_hw_reset(struct mmc_host *mmc)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
u32 ret;
|
||||
|
||||
if (!aml_card_type_mmc(pdata) || !pdata->hw_reset)
|
||||
return;
|
||||
|
||||
/* boot_9 used as eMMC hw_rst pin here. */
|
||||
gpio_free(pdata->hw_reset);
|
||||
ret = gpio_request_one(pdata->hw_reset,
|
||||
GPIOF_OUT_INIT_HIGH, MODULE_NAME);
|
||||
CHECK_RET(ret);
|
||||
if (ret) {
|
||||
pr_err("%s [%d] request error\n",
|
||||
__func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
ret = gpio_direction_output(pdata->hw_reset, 0);
|
||||
CHECK_RET(ret);
|
||||
if (ret) {
|
||||
pr_err("%s [%d] output high error\n",
|
||||
__func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
mdelay(2);
|
||||
ret = gpio_direction_output(pdata->hw_reset, 1);
|
||||
CHECK_RET(ret);
|
||||
if (ret) {
|
||||
pr_err("%s [%d] output high error\n",
|
||||
__func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
mdelay(2);
|
||||
}
|
||||
|
||||
static void sdio_rescan(struct mmc_host *mmc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mmc->rescan_entered = 0;
|
||||
/* mmc->host_rescan_disable = false;*/
|
||||
mmc_detect_change(mmc, 0);
|
||||
/* start the delayed_work */
|
||||
ret = flush_work(&(mmc->detect.work));
|
||||
/* wait for the delayed_work to finish */
|
||||
if (!ret)
|
||||
pr_info("Error: delayed_work mmc_rescan() already idle!\n");
|
||||
}
|
||||
|
||||
void sdio_reinit(void)
|
||||
{
|
||||
if (sdio_host) {
|
||||
if (sdio_host->card)
|
||||
sdio_reset_comm(sdio_host->card);
|
||||
else
|
||||
sdio_rescan(sdio_host);
|
||||
} else {
|
||||
pr_info("Error: sdio_host is NULL\n");
|
||||
}
|
||||
|
||||
pr_info("[%s] finish\n", __func__);
|
||||
}
|
||||
EXPORT_SYMBOL(sdio_reinit);
|
||||
|
||||
void of_amlsd_irq_init(struct amlsd_platform *pdata)
|
||||
{
|
||||
if (aml_card_type_non_sdio(pdata))
|
||||
pdata->irq_cd = gpio_to_irq(pdata->gpio_cd);
|
||||
pr_info("sd irq num = %d\n", pdata->irq_cd);
|
||||
}
|
||||
|
||||
int of_amlsd_init(struct amlsd_platform *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
WARN_ON(!pdata);
|
||||
|
||||
if (pdata->gpio_cd) {
|
||||
pr_info("gpio_cd = %x\n", pdata->gpio_cd);
|
||||
ret = gpio_request_one(pdata->gpio_cd,
|
||||
GPIOF_IN, MODULE_NAME);
|
||||
CHECK_RET(ret);
|
||||
}
|
||||
|
||||
/* if(pdata->port == MESON_SDIO_PORT_A) */
|
||||
/* wifi_setup_dt(); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aml_devm_pinctrl_put(struct amlsd_host *host)
|
||||
{
|
||||
if (host->pinctrl) {
|
||||
devm_pinctrl_put(host->pinctrl);
|
||||
host->pinctrl = NULL;
|
||||
|
||||
host->pinctrl_name[0] = '\0';
|
||||
/* sdio_err("Put Pinctrl\n"); */
|
||||
}
|
||||
}
|
||||
|
||||
static struct pinctrl * __must_check aml_devm_pinctrl_get_select(
|
||||
struct amlsd_host *host, const char *name)
|
||||
{
|
||||
struct pinctrl *p = host->pinctrl;
|
||||
struct pinctrl_state *s;
|
||||
int ret;
|
||||
|
||||
if (!p) {
|
||||
p = devm_pinctrl_get(&host->pdev->dev);
|
||||
|
||||
if (IS_ERR(p))
|
||||
return p;
|
||||
|
||||
host->pinctrl = p;
|
||||
/* sdio_err("switch %s\n", name); */
|
||||
}
|
||||
|
||||
s = pinctrl_lookup_state(p, name);
|
||||
if (IS_ERR(s)) {
|
||||
sdio_err("lookup %s fail\n", name);
|
||||
devm_pinctrl_put(p);
|
||||
return ERR_CAST(s);
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(p, s);
|
||||
if (ret < 0) {
|
||||
sdio_err("select %s fail\n", name);
|
||||
devm_pinctrl_put(p);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void of_amlsd_xfer_pre(struct mmc_host *mmc)
|
||||
{
|
||||
struct amlsd_host *host = mmc_priv(mmc);
|
||||
struct amlsd_platform *pdata = host->pdata;
|
||||
char pinctrl[30];
|
||||
char *p = pinctrl;
|
||||
int i, size = 0;
|
||||
struct pinctrl *ppin;
|
||||
|
||||
size = sizeof(pinctrl);
|
||||
if (mmc->ios.chip_select == MMC_CS_DONTCARE) {
|
||||
if ((mmc->caps & MMC_CAP_4_BIT_DATA)
|
||||
|| (strcmp(pdata->pinname, "sd"))
|
||||
|| (mmc->caps & MMC_CAP_8_BIT_DATA))
|
||||
aml_snprint(&p, &size, "%s_all_pins", pdata->pinname);
|
||||
} else { /* MMC_CS_HIGH */
|
||||
if (pdata->is_sduart && (!strcmp(pdata->pinname, "sd"))) {
|
||||
aml_snprint(&p, &size,
|
||||
"%s_clk_cmd_uart_pins", pdata->pinname);
|
||||
} else {
|
||||
aml_snprint(&p, &size,
|
||||
"%s_clk_cmd_pins", pdata->pinname);
|
||||
}
|
||||
}
|
||||
|
||||
/* if pinmux setting is changed (pinctrl_name is different) */
|
||||
if (strncmp(host->pinctrl_name, pinctrl,
|
||||
sizeof(host->pinctrl_name))) {
|
||||
if (strlcpy(host->pinctrl_name, pinctrl,
|
||||
sizeof(host->pinctrl_name))
|
||||
>= sizeof(host->pinctrl_name)) {
|
||||
|
||||
sdio_err("Pinctrl name is too long!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
mutex_lock(&host->pinmux_lock);
|
||||
ppin = aml_devm_pinctrl_get_select(host, pinctrl);
|
||||
mutex_unlock(&host->pinmux_lock);
|
||||
if (!IS_ERR(ppin)) {
|
||||
/* pdata->host->pinctrl = ppin; */
|
||||
break;
|
||||
}
|
||||
/* else -> aml_irq_cdin_thread()
|
||||
*should be using one of the GPIO of card,
|
||||
* then we should wait here until the GPIO is free,
|
||||
* otherwise something must be wrong.
|
||||
*/
|
||||
mdelay(1);
|
||||
}
|
||||
if (i == 100)
|
||||
sdhc_err("CMD%d: get pinctrl %s fail.\n",
|
||||
host->opcode, pinctrl);
|
||||
}
|
||||
}
|
||||
|
||||
void of_amlsd_xfer_post(struct mmc_host *mmc)
|
||||
{
|
||||
}
|
||||
|
||||
int of_amlsd_ro(struct amlsd_platform *pdata)
|
||||
{
|
||||
int ret = 0; /* 0--read&write, 1--read only */
|
||||
|
||||
if (pdata->gpio_ro)
|
||||
ret = gpio_get_value(pdata->gpio_ro);
|
||||
/* sdio_err("read-only?--%s\n", ret?"YES":"NO"); */
|
||||
return ret;
|
||||
}
|
||||
|
||||
void aml_snprint (char **pp, int *left_size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p = *pp;
|
||||
int size;
|
||||
|
||||
if (*left_size <= 1) {
|
||||
sdhc_err("buf is full\n");
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
size = vsnprintf(p, *left_size, fmt, args);
|
||||
va_end(args);
|
||||
*pp += size;
|
||||
*left_size -= size;
|
||||
}
|
||||
|
||||
|
||||
210
drivers/amlogic/mmc/amlsd_of.c
Normal file
210
drivers/amlogic/mmc/amlsd_of.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* drivers/amlogic/mmc/amlsd_of.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/amlogic/sd.h>
|
||||
/*#include <linux/of_address.h>*/
|
||||
/*#include <linux/amlogic/aml_gpio_consumer.h>*/
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/amlogic/amlsd.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
unsigned int sd_emmc_debug;
|
||||
|
||||
static const struct sd_caps host_caps[] = {
|
||||
SD_CAPS(MMC_CAP_4_BIT_DATA, "MMC_CAP_4_BIT_DATA"),
|
||||
SD_CAPS(MMC_CAP_MMC_HIGHSPEED, "MMC_CAP_MMC_HIGHSPEED"),
|
||||
SD_CAPS(MMC_CAP_SD_HIGHSPEED, "MMC_CAP_SD_HIGHSPEED"),
|
||||
SD_CAPS(MMC_CAP_SDIO_IRQ, "MMC_CAP_SDIO_IRQ"),
|
||||
SD_CAPS(MMC_CAP_SPI, "MMC_CAP_SPI"),
|
||||
SD_CAPS(MMC_CAP_NEEDS_POLL, "MMC_CAP_NEEDS_POLL"),
|
||||
SD_CAPS(MMC_CAP_8_BIT_DATA, "MMC_CAP_8_BIT_DATA"),
|
||||
SD_CAPS(MMC_CAP_NONREMOVABLE, "MMC_CAP_NONREMOVABLE"),
|
||||
SD_CAPS(MMC_CAP_WAIT_WHILE_BUSY, "MMC_CAP_WAIT_WHILE_BUSY"),
|
||||
SD_CAPS(MMC_CAP_ERASE, "MMC_CAP_ERASE"),
|
||||
SD_CAPS(MMC_CAP_1_8V_DDR, "MMC_CAP_1_8V_DDR"),
|
||||
SD_CAPS(MMC_CAP_1_2V_DDR, "MMC_CAP_1_2V_DDR"),
|
||||
SD_CAPS(MMC_CAP_POWER_OFF_CARD, "MMC_CAP_POWER_OFF_CARD"),
|
||||
SD_CAPS(MMC_CAP_BUS_WIDTH_TEST, "MMC_CAP_BUS_WIDTH_TEST"),
|
||||
SD_CAPS(MMC_CAP_UHS_SDR12, "MMC_CAP_UHS_SDR12"),
|
||||
SD_CAPS(MMC_CAP_UHS_SDR25, "MMC_CAP_UHS_SDR25"),
|
||||
SD_CAPS(MMC_CAP_UHS_SDR50, "MMC_CAP_UHS_SDR50"),
|
||||
SD_CAPS(MMC_CAP_UHS_SDR104, "MMC_CAP_UHS_SDR104"),
|
||||
SD_CAPS(MMC_CAP_UHS_DDR50, "MMC_CAP_UHS_DDR50"),
|
||||
SD_CAPS(MMC_CAP_DRIVER_TYPE_A, "MMC_CAP_DRIVER_TYPE_A"),
|
||||
SD_CAPS(MMC_CAP_DRIVER_TYPE_C, "MMC_CAP_DRIVER_TYPE_C"),
|
||||
SD_CAPS(MMC_CAP_DRIVER_TYPE_D, "MMC_CAP_DRIVER_TYPE_D"),
|
||||
SD_CAPS(MMC_CAP_CMD23, "MMC_CAP_CMD23"),
|
||||
SD_CAPS(MMC_CAP_HW_RESET, "MMC_CAP_HW_RESET"),
|
||||
SD_CAPS(MMC_CAP_AGGRESSIVE_PM, "MMC_CAP_AGGRESSIVE_PM"),
|
||||
SD_CAPS(MMC_PM_KEEP_POWER, "MMC_PM_KEEP_POWER"),
|
||||
};
|
||||
|
||||
static int amlsd_get_host_caps(struct device_node *of_node,
|
||||
struct amlsd_platform *pdata)
|
||||
{
|
||||
const char *str_caps;
|
||||
struct property *prop;
|
||||
u32 i, caps = 0;
|
||||
|
||||
of_property_for_each_string(of_node, "caps", prop, str_caps) {
|
||||
for (i = 0; i < ARRAY_SIZE(host_caps); i++) {
|
||||
if (!strcasecmp(host_caps[i].name, str_caps))
|
||||
caps |= host_caps[i].caps;
|
||||
}
|
||||
};
|
||||
if (caps & MMC_CAP_8_BIT_DATA)
|
||||
caps |= MMC_CAP_4_BIT_DATA;
|
||||
|
||||
pdata->caps = caps;
|
||||
pr_info("%s:pdata->caps = %x\n", pdata->pinname, pdata->caps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sd_caps host_caps2[] = {
|
||||
SD_CAPS(MMC_CAP2_BOOTPART_NOACC, "MMC_CAP2_BOOTPART_NOACC"),
|
||||
/*SD_CAPS(MMC_CAP2_CACHE_CTRL, "MMC_CAP2_CACHE_CTRL"),*/
|
||||
/* SD_CAPS(MMC_CAP2_POWEROFF_NOTIFY, "MMC_CAP2_POWEROFF_NOTIFY"), */
|
||||
SD_CAPS(MMC_CAP2_NO_MULTI_READ, "MMC_CAP2_NO_MULTI_READ"),
|
||||
/*SD_CAPS(MMC_CAP2_NO_SLEEP_CMD, "MMC_CAP2_NO_SLEEP_CMD"),*/
|
||||
SD_CAPS(MMC_CAP2_HS200_1_8V_SDR, "MMC_CAP2_HS200_1_8V_SDR"),
|
||||
SD_CAPS(MMC_CAP2_HS200_1_2V_SDR, "MMC_CAP2_HS200_1_2V_SDR"),
|
||||
SD_CAPS(MMC_CAP2_HS200, "MMC_CAP2_HS200"),
|
||||
SD_CAPS(MMC_CAP2_HS400_1_8V, "MMC_CAP2_HS400_1_8V"),
|
||||
SD_CAPS(MMC_CAP2_HS400_1_2V, "MMC_CAP2_HS400_1_2V"),
|
||||
SD_CAPS(MMC_CAP2_HS400, "MMC_CAP2_HS400"),
|
||||
/*SD_CAPS(MMC_CAP2_BROKEN_VOLTAGE, "MMC_CAP2_BROKEN_VOLTAGE"),*/
|
||||
/* SD_CAPS(MMC_CAP2_DETECT_ON_ERR, "MMC_CAP2_DETECT_ON_ERR"), */
|
||||
SD_CAPS(MMC_CAP2_HC_ERASE_SZ, "MMC_CAP2_HC_ERASE_SZ"),
|
||||
SD_CAPS(MMC_CAP2_CD_ACTIVE_HIGH, "MMC_CAP2_CD_ACTIVE_HIGH"),
|
||||
SD_CAPS(MMC_CAP2_RO_ACTIVE_HIGH, "MMC_CAP2_RO_ACTIVE_HIGH"),
|
||||
};
|
||||
|
||||
static int amlsd_get_host_caps2(struct device_node *of_node,
|
||||
struct amlsd_platform *pdata)
|
||||
{
|
||||
const char *str_caps;
|
||||
struct property *prop;
|
||||
u32 i, caps = 0;
|
||||
|
||||
of_property_for_each_string(of_node, "caps2", prop, str_caps) {
|
||||
for (i = 0; i < ARRAY_SIZE(host_caps2); i++) {
|
||||
if (!strcasecmp(host_caps2[i].name, str_caps))
|
||||
caps |= host_caps2[i].caps;
|
||||
}
|
||||
};
|
||||
pdata->caps2 = caps;
|
||||
pr_info("%s:pdata->caps2 = %x\n", pdata->pinname, pdata->caps2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amlsd_get_platform_data(struct amlsd_platform *pdata,
|
||||
struct mmc_host *mmc, u32 index)
|
||||
{
|
||||
struct device_node *of_node;
|
||||
struct device_node *child;
|
||||
u32 i, prop;
|
||||
const char *str = "none";
|
||||
|
||||
if (!mmc->parent || !mmc->parent->of_node)
|
||||
return 0;
|
||||
|
||||
of_node = mmc->parent->of_node;
|
||||
if (of_node) {
|
||||
child = of_node->child;
|
||||
WARN_ON(!child);
|
||||
WARN_ON(index >= MMC_MAX_DEVICE);
|
||||
for (i = 0; i < index; i++)
|
||||
child = child->sibling;
|
||||
if (!child)
|
||||
return -EINVAL;
|
||||
|
||||
/* amlsd_init_pins_input(child, pdata);*/
|
||||
|
||||
SD_PARSE_U32_PROP_HEX(child, "port",
|
||||
prop, pdata->port);
|
||||
SD_PARSE_U32_PROP_HEX(child, "ocr_avail",
|
||||
prop, pdata->ocr_avail);
|
||||
WARN_ON(!pdata->ocr_avail);
|
||||
SD_PARSE_U32_PROP_DEC(child, "f_min",
|
||||
prop, pdata->f_min);
|
||||
SD_PARSE_U32_PROP_DEC(child, "f_max",
|
||||
prop, pdata->f_max);
|
||||
SD_PARSE_U32_PROP_HEX(child, "max_req_size", prop,
|
||||
pdata->max_req_size);
|
||||
SD_PARSE_GPIO_NUM_PROP(child, "gpio_cd",
|
||||
str, pdata->gpio_cd);
|
||||
SD_PARSE_GPIO_NUM_PROP(child, "gpio_ro",
|
||||
str, pdata->gpio_ro);
|
||||
SD_PARSE_GPIO_NUM_PROP(child, "vol_switch",
|
||||
str, pdata->vol_switch);
|
||||
|
||||
SD_PARSE_U32_PROP_HEX(child, "power_level",
|
||||
prop, pdata->power_level);
|
||||
|
||||
SD_PARSE_U32_PROP_DEC(child, "gpio_cd_level",
|
||||
prop, pdata->gpio_cd_level);
|
||||
SD_PARSE_STRING_PROP(child, "pinname",
|
||||
str, pdata->pinname);
|
||||
SD_PARSE_U32_PROP_DEC(child, "auto_clk_close",
|
||||
prop, pdata->auto_clk_close);
|
||||
SD_PARSE_U32_PROP_DEC(child, "vol_switch_18",
|
||||
prop, pdata->vol_switch_18);
|
||||
SD_PARSE_U32_PROP_DEC(child, "vol_switch_delay",
|
||||
prop, pdata->vol_switch_delay);
|
||||
SD_PARSE_U32_PROP_DEC(child, "card_type",
|
||||
prop, pdata->card_type);
|
||||
if (aml_card_type_mmc(pdata)) {
|
||||
/*tx_phase set default value first*/
|
||||
if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB)
|
||||
pdata->tx_phase = 1;
|
||||
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)
|
||||
pdata->tx_delay = 3;
|
||||
SD_PARSE_U32_PROP_DEC(child, "tx_phase",
|
||||
prop, pdata->tx_phase);
|
||||
}
|
||||
if (aml_card_type_non_sdio(pdata)) {
|
||||
/*card in default value*/
|
||||
pdata->card_in_delay = 0;
|
||||
SD_PARSE_U32_PROP_DEC(child, "card_in_delay",
|
||||
prop, pdata->card_in_delay);
|
||||
}
|
||||
SD_PARSE_GPIO_NUM_PROP(child, "hw_reset",
|
||||
str, pdata->hw_reset);
|
||||
SD_PARSE_GPIO_NUM_PROP(child, "gpio_dat3",
|
||||
str, pdata->gpio_dat3);
|
||||
|
||||
pdata->xfer_pre = of_amlsd_xfer_pre;
|
||||
pdata->xfer_post = of_amlsd_xfer_post;
|
||||
|
||||
amlsd_get_host_caps(child, pdata);
|
||||
amlsd_get_host_caps2(child, pdata);
|
||||
pdata->port_init = of_amlsd_init;
|
||||
pdata->irq_init = of_amlsd_irq_init;
|
||||
pdata->ro = of_amlsd_ro;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
1011
drivers/amlogic/mmc/emmc_partitions.c
Normal file
1011
drivers/amlogic/mmc/emmc_partitions.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,9 @@
|
||||
|
||||
#include "queue.h"
|
||||
#include "block.h"
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
#include <linux/mmc/emmc_partitions.h>
|
||||
#endif
|
||||
|
||||
MODULE_ALIAS("mmc:block");
|
||||
#ifdef MODULE_PARAM_PREFIX
|
||||
@@ -2607,6 +2610,11 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
if (mmc_add_disk(md))
|
||||
goto out;
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
/* amlogic add emmc partitions ops */
|
||||
aml_emmc_partition_ops(card, md->disk);
|
||||
#endif
|
||||
|
||||
list_for_each_entry(part_md, &md->part, part) {
|
||||
if (mmc_add_disk(part_md))
|
||||
goto out;
|
||||
|
||||
@@ -284,6 +284,10 @@ int mmc_add_card(struct mmc_card *card)
|
||||
int ret;
|
||||
const char *type;
|
||||
const char *uhs_bus_speed_mode = "";
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
int width;
|
||||
struct mmc_host *mmc = card->host;
|
||||
#endif
|
||||
static const char *const uhs_speeds[] = {
|
||||
[UHS_SDR12_BUS_SPEED] = "SDR12 ",
|
||||
[UHS_SDR25_BUS_SPEED] = "SDR25 ",
|
||||
@@ -332,6 +336,23 @@ int mmc_add_card(struct mmc_card *card)
|
||||
mmc_card_ddr52(card) ? "DDR " : "",
|
||||
type);
|
||||
} else {
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
switch (mmc->ios.bus_width) {
|
||||
case MMC_BUS_WIDTH_1:
|
||||
width = 1;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_4:
|
||||
width = 4;
|
||||
break;
|
||||
case MMC_BUS_WIDTH_8:
|
||||
width = 8;
|
||||
break;
|
||||
default:
|
||||
width = -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
pr_info("%s: new %s%s%s%s%s%s card at address %04x\n",
|
||||
mmc_hostname(card->host),
|
||||
mmc_card_uhs(card) ? "ultra high speed " :
|
||||
@@ -341,6 +362,12 @@ int mmc_add_card(struct mmc_card *card)
|
||||
mmc_card_hs400es(card) ? "Enhanced strobe " : "",
|
||||
mmc_card_ddr52(card) ? "DDR " : "",
|
||||
uhs_bus_speed_mode, type, card->rca);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
pr_info("%s: clock %d, %u-bit-bus-width\n ",
|
||||
mmc_hostname(card->host),
|
||||
mmc->actual_clock, width);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
@@ -2635,6 +2635,9 @@ EXPORT_SYMBOL(mmc_hw_reset);
|
||||
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
|
||||
{
|
||||
host->f_init = freq;
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
host->first_init_flag = 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MMC_DEBUG
|
||||
pr_info("%s: %s: trying to init card at %u Hz\n",
|
||||
|
||||
@@ -1159,8 +1159,29 @@ static int mmc_select_hs400(struct mmc_card *card)
|
||||
}
|
||||
|
||||
/* Switch card to HS400 */
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
if (card->ext_csd.raw_driver_strength & (1 << 1)) {
|
||||
val =
|
||||
(0x1 << EXT_CSD_DRV_STR_SHIFT)
|
||||
| EXT_CSD_TIMING_HS400;
|
||||
pr_info("%s: support driver strength type 1\n",
|
||||
mmc_hostname(host));
|
||||
} else if (card->ext_csd.raw_driver_strength & (1 << 4)) {
|
||||
val =
|
||||
(0x4 << EXT_CSD_DRV_STR_SHIFT)
|
||||
| EXT_CSD_TIMING_HS400;
|
||||
pr_info("%s: support driver strength type 4\n",
|
||||
mmc_hostname(host));
|
||||
} else {
|
||||
val = EXT_CSD_TIMING_HS400;
|
||||
pr_info("%s: no support driver strength type 1 and 4\n",
|
||||
mmc_hostname(host));
|
||||
}
|
||||
#else
|
||||
val = EXT_CSD_TIMING_HS400 |
|
||||
card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
|
||||
#endif
|
||||
|
||||
err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_HS_TIMING, val,
|
||||
card->ext_csd.generic_cmd6_time,
|
||||
@@ -1560,6 +1581,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
||||
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
host->first_init_flag = 0;
|
||||
#endif
|
||||
if (!oldcard) {
|
||||
/*
|
||||
* Fetch CSD from card.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "core.h"
|
||||
#include "bus.h"
|
||||
#include "host.h"
|
||||
#include "sd.h"
|
||||
#include "sdio_bus.h"
|
||||
#include "mmc_ops.h"
|
||||
@@ -1172,4 +1173,43 @@ err:
|
||||
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
int sdio_reset_comm(struct mmc_card *card)
|
||||
{
|
||||
struct mmc_host *host = card->host;
|
||||
u32 ocr;
|
||||
u32 rocr;
|
||||
int err;
|
||||
|
||||
pr_info("%s():\n", __func__);
|
||||
mmc_claim_host(host);
|
||||
|
||||
mmc_retune_disable(host);
|
||||
mmc_go_idle(host);
|
||||
|
||||
mmc_set_clock(host, host->f_min);
|
||||
|
||||
err = mmc_send_io_op_cond(host, 0, &ocr);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
rocr = mmc_select_voltage(host, ocr);
|
||||
if (!rocr) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = mmc_sdio_init_card(host, rocr, card, 0);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
mmc_release_host(host);
|
||||
return 0;
|
||||
err:
|
||||
pr_err("%s: Error resetting SDIO communications (%d)\n",
|
||||
mmc_hostname(host), err);
|
||||
mmc_release_host(host);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(sdio_reset_comm);
|
||||
#endif
|
||||
|
||||
229
include/linux/amlogic/amlsd.h
Normal file
229
include/linux/amlogic/amlsd.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* include/linux/amlogic/amlsd.h
|
||||
*
|
||||
* Copyright (C) 2016 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AMLSD_H
|
||||
#define AMLSD_H
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#define AML_MMC_MAJOR_VERSION 1
|
||||
#define AML_MMC_MINOR_VERSION 07
|
||||
#define AML_MMC_VERSION \
|
||||
((AML_MMC_MAJOR_VERSION << 8) | AML_MMC_MINOR_VERSION)
|
||||
#define AML_MMC_VER_MESSAGE \
|
||||
"2015-01-21: fix a bug in tuning which caused eMMC data CRC error"
|
||||
|
||||
extern unsigned int sdhc_debug;
|
||||
extern unsigned int sdio_debug;
|
||||
extern unsigned int sd_emmc_debug;
|
||||
extern const u8 tuning_blk_pattern_4bit[64];
|
||||
extern const u8 tuning_blk_pattern_8bit[128];
|
||||
#define DEBUG_SD_OF 1
|
||||
/* #define DEBUG_SD_OF 0 */
|
||||
|
||||
#define MODULE_NAME "amlsd"
|
||||
|
||||
#if 0
|
||||
#define A0_GP_CFG0 (0xc8100240)
|
||||
#define A0_GP_CFG2 (0xc8100248)
|
||||
#define STORAGE_DEV_NOSET (0)
|
||||
#define STORAGE_DEV_EMMC (1)
|
||||
#define STORAGE_DEV_NAND (2)
|
||||
#define STORAGE_DEV_SPI (3)
|
||||
#define STORAGE_DEV_SDCARD (4)
|
||||
#define STORAGE_DEV_USB (5)
|
||||
#define LDO4DAC_REG_ADDR 0x4f
|
||||
#define LDO4DAC_REG_1_8_V 0x24
|
||||
#define LDO4DAC_REG_2_8_V 0x4c
|
||||
#define LDO4DAC_REG_3_3_V 0x60
|
||||
|
||||
#endif
|
||||
#define AMLSD_DBG_COMMON (1<<0)
|
||||
#define AMLSD_DBG_REQ (1<<1)
|
||||
#define AMLSD_DBG_RESP (1<<2)
|
||||
#define AMLSD_DBG_REG (1<<3)
|
||||
#define AMLSD_DBG_RD_TIME (1<<4)
|
||||
#define AMLSD_DBG_WR_TIME (1<<5)
|
||||
#define AMLSD_DBG_BUSY_TIME (1<<6)
|
||||
#define AMLSD_DBG_RD_DATA (1<<7)
|
||||
#define AMLSD_DBG_WR_DATA (1<<8)
|
||||
#define AMLSD_DBG_IOS (1<<9)
|
||||
#define AMLSD_DBG_IRQ (1<<10)
|
||||
#define AMLSD_DBG_CLKC (1<<11)
|
||||
#define AMLSD_DBG_TUNING (1<<12)
|
||||
|
||||
#define DETECT_CARD_IN 1
|
||||
#define DETECT_CARD_OUT 2
|
||||
#define DETECT_CARD_JTAG_IN 3
|
||||
#define DETECT_CARD_JTAG_OUT 4
|
||||
|
||||
#define EMMC_DAT3_PINMUX_CLR 0
|
||||
#define EMMC_DAT3_PINMUX_SET 1
|
||||
|
||||
#define CHECK_RET(ret) { \
|
||||
if (ret) \
|
||||
pr_info("[%s] gpio op failed(%d) at line %d\n",\
|
||||
__func__, ret, __LINE__); \
|
||||
}
|
||||
|
||||
#define sdhc_dbg(dbg_level, fmt, args...) do {\
|
||||
if (dbg_level & sdhc_debug) \
|
||||
pr_info("[%s]" fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define sdhc_err(fmt, args...) \
|
||||
pr_info("[%s] " fmt, __func__, ##args)
|
||||
|
||||
|
||||
#define sdio_dbg(dbg_level, fmt, args...) do {\
|
||||
if (dbg_level & sdio_debug) \
|
||||
pr_info("[%s]" fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define sdio_err(fmt, args...) \
|
||||
pr_info("[%s] " fmt, __func__, ##args)
|
||||
|
||||
#define sd_emmc_dbg(dbg_level, fmt, args...) do {\
|
||||
if (dbg_level & sd_emmc_debug) \
|
||||
pr_info("[%s]" fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
#define sd_emmc_err(fmt, args...) \
|
||||
pr_warn("[%s] " fmt, __func__, ##args)
|
||||
|
||||
#define SD_PARSE_U32_PROP_HEX(node, prop_name, prop, value) do { \
|
||||
if (!of_property_read_u32(node, prop_name, &prop)) {\
|
||||
value = prop;\
|
||||
prop = 0;\
|
||||
if (DEBUG_SD_OF) { \
|
||||
pr_info("get property:%25s, value:0x%08x\n", \
|
||||
prop_name, (unsigned int)value); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SD_PARSE_U32_PROP_DEC(node, prop_name, prop, value) do { \
|
||||
if (!of_property_read_u32(node, prop_name, &prop)) {\
|
||||
value = prop;\
|
||||
prop = 0;\
|
||||
if (DEBUG_SD_OF) { \
|
||||
pr_info("get property:%25s, value:%d\n", \
|
||||
prop_name, (unsigned int)value); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SD_PARSE_GPIO_NUM_PROP(node, prop_name, str, gpio_pin) {\
|
||||
if (!of_property_read_string(node, prop_name, &str)) {\
|
||||
gpio_pin = \
|
||||
of_get_named_gpio(node, \
|
||||
prop_name, 0);\
|
||||
if (DEBUG_SD_OF) { \
|
||||
pr_info("get property:%25s, str:%s\n",\
|
||||
prop_name, str);\
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SD_PARSE_STRING_PROP(node, prop_name, str, prop) {\
|
||||
if (!of_property_read_string(node, prop_name, &str)) {\
|
||||
strcpy(prop, str);\
|
||||
if (DEBUG_SD_OF) {\
|
||||
pr_info("get property:%25s, str:%s\n",\
|
||||
prop_name, prop); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SD_CAPS(a, b) { .caps = a, .name = b }
|
||||
|
||||
struct sd_caps {
|
||||
unsigned int caps;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void aml_mmc_ver_msg_show(void);
|
||||
extern int sdio_reset_comm(struct mmc_card *card);
|
||||
#if 0
|
||||
extern int storage_flag;
|
||||
|
||||
extern void aml_debug_print_buf(char *buf, int size);
|
||||
extern int aml_buf_verify(int *buf, int blocks, int lba);
|
||||
extern void aml_sdhc_init_debugfs(struct mmc_host *mmc);
|
||||
void aml_sdhc_print_reg_(u32 *buf);
|
||||
extern void aml_sdhc_print_reg(struct amlsd_host *host);
|
||||
extern void aml_sdio_init_debugfs(struct mmc_host *mmc);
|
||||
extern void aml_sd_emmc_init_debugfs(struct mmc_host *mmc);
|
||||
extern void aml_sdio_print_reg(struct amlsd_host *host);
|
||||
extern void aml_sd_emmc_print_reg(struct amlsd_host *host);
|
||||
|
||||
extern int add_part_table(struct mtd_partition *part, unsigned int nr_part);
|
||||
extern int add_emmc_partition(struct gendisk *disk);
|
||||
extern size_t aml_sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
|
||||
void *buf, size_t buflen, int to_buffer);
|
||||
#endif
|
||||
int amlsd_get_platform_data(struct amlsd_platform *pdata,
|
||||
struct mmc_host *mmc, u32 index);
|
||||
|
||||
void of_amlsd_irq_init(struct amlsd_platform *pdata);
|
||||
int of_amlsd_init(struct amlsd_platform *pdata);
|
||||
#if 0
|
||||
int amlsd_get_reg_base(struct platform_device *pdev,
|
||||
struct amlsd_host *host);
|
||||
|
||||
/* int of_amlsd_detect(struct amlsd_platform* pdata); */
|
||||
void of_amlsd_pwr_prepare(struct amlsd_platform *pdata);
|
||||
void of_amlsd_pwr_on(struct amlsd_platform *pdata);
|
||||
void of_amlsd_pwr_off(struct amlsd_platform *pdata);
|
||||
|
||||
int aml_sd_uart_detect(struct amlsd_platform *pdata);
|
||||
void aml_sd_uart_detect_clr(struct amlsd_platform *pdata);
|
||||
#endif
|
||||
void of_amlsd_xfer_pre(struct mmc_host *mmc);
|
||||
void of_amlsd_xfer_post(struct mmc_host *mmc);
|
||||
|
||||
irqreturn_t aml_sd_irq_cd(int irq, void *dev_id);
|
||||
irqreturn_t aml_irq_cd_thread(int irq, void *data);
|
||||
#if 0
|
||||
void aml_sduart_pre(struct amlsd_platform *pdata);
|
||||
|
||||
/* chip select high */
|
||||
void aml_cs_high(struct amlsd_platform *pdata);
|
||||
|
||||
/* chip select don't care */
|
||||
void aml_cs_dont_care(struct amlsd_platform *pdata);
|
||||
|
||||
/* is eMMC/tSD exist */
|
||||
bool is_emmc_exist(struct amlsd_host *host);
|
||||
void aml_devm_pinctrl_put(struct amlsd_host *host);
|
||||
/* void of_init_pins (struct amlsd_platform* pdata); */
|
||||
|
||||
void aml_dbg_print_pinmux(void);
|
||||
#ifdef CONFIG_MMC_AML_DEBUG
|
||||
void aml_dbg_verify_pull_up(struct amlsd_platform *pdata);
|
||||
int aml_dbg_verify_pinmux(struct amlsd_platform *pdata);
|
||||
#endif
|
||||
#endif
|
||||
void aml_snprint (char **pp, int *left_size, const char *fmt, ...);
|
||||
|
||||
int of_amlsd_ro(struct amlsd_platform *pdata);
|
||||
int aml_sd_voltage_switch(struct mmc_host *mmc, char signal_voltage);
|
||||
int aml_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios);
|
||||
|
||||
int aml_check_unsupport_cmd(struct mmc_host *mmc, struct mmc_request *mrq);
|
||||
extern void aml_emmc_hw_reset(struct mmc_host *mmc);
|
||||
#endif
|
||||
|
||||
|
||||
1507
include/linux/amlogic/sd.h
Normal file
1507
include/linux/amlogic/sd.h
Normal file
File diff suppressed because it is too large
Load Diff
78
include/linux/mmc/emmc_partitions.h
Normal file
78
include/linux/mmc/emmc_partitions.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef _EMMC_PARTITIONS_H
|
||||
#define _EMMC_PARTITIONS_H
|
||||
|
||||
#include<linux/genhd.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
#include <linux/mmc/core.h>
|
||||
|
||||
/* #include <mach/register.h> */
|
||||
/* #include <mach/am_regs.h> */
|
||||
#define CONFIG_DTB_SIZE (256*1024U)
|
||||
#define STORE_CODE 1
|
||||
#define STORE_CACHE (1<<1)
|
||||
#define STORE_DATA (1<<2)
|
||||
|
||||
#define MAX_PART_NAME_LEN 16
|
||||
#define MAX_MMC_PART_NUM 32
|
||||
|
||||
/* MMC Partition Table */
|
||||
#define MMC_PARTITIONS_MAGIC "MPT"
|
||||
#define MMC_RESERVED_NAME "reserved"
|
||||
|
||||
#define SZ_1M 0x00100000
|
||||
|
||||
/* the size of bootloader partition */
|
||||
#define MMC_BOOT_PARTITION_SIZE (4*SZ_1M)
|
||||
|
||||
/* the size of reserve space behind bootloader partition */
|
||||
#define MMC_BOOT_PARTITION_RESERVED (32*SZ_1M)
|
||||
|
||||
#define RESULT_OK 0
|
||||
#define RESULT_FAIL 1
|
||||
#define RESULT_UNSUP_HOST 2
|
||||
#define RESULT_UNSUP_CARD 3
|
||||
|
||||
struct partitions {
|
||||
/* identifier string */
|
||||
char name[MAX_PART_NAME_LEN];
|
||||
/* partition size, byte unit */
|
||||
uint64_t size;
|
||||
/* offset within the master space, byte unit */
|
||||
uint64_t offset;
|
||||
/* master flags to mask out for this partition */
|
||||
unsigned mask_flags;
|
||||
};
|
||||
|
||||
struct mmc_partitions_fmt {
|
||||
char magic[4];
|
||||
unsigned char version[12];
|
||||
int part_num;
|
||||
int checksum;
|
||||
struct partitions partitions[MAX_MMC_PART_NUM];
|
||||
};
|
||||
/*#ifdef CONFIG_MMC_AML*/
|
||||
int aml_emmc_partition_ops(struct mmc_card *card, struct gendisk *disk);
|
||||
/*
|
||||
*#else
|
||||
*static inline int aml_emmc_partition_ops(struct mmc_card *card,
|
||||
* struct gendisk *disk)
|
||||
*{
|
||||
* return -1;
|
||||
*}
|
||||
*#endif
|
||||
*/
|
||||
unsigned int mmc_capacity(struct mmc_card *card);
|
||||
int mmc_read_internal(struct mmc_card *card,
|
||||
unsigned dev_addr, unsigned blocks, void *buf);
|
||||
int mmc_write_internal(struct mmc_card *card,
|
||||
unsigned dev_addr, unsigned blocks, void *buf);
|
||||
int get_reserve_partition_off_from_tbl(void);
|
||||
int get_reserve_partition_off(struct mmc_card *card);/* byte unit */
|
||||
|
||||
#endif
|
||||
|
||||
extern struct mmc_partitions_fmt *pt_fmt;
|
||||
|
||||
@@ -225,6 +225,9 @@ struct mmc_host {
|
||||
unsigned int f_min;
|
||||
unsigned int f_max;
|
||||
unsigned int f_init;
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
u8 first_init_flag;
|
||||
#endif
|
||||
u32 ocr_avail;
|
||||
u32 ocr_avail_sdio; /* SDIO-specific OCR */
|
||||
u32 ocr_avail_sd; /* SD-specific OCR */
|
||||
@@ -287,8 +290,11 @@ struct mmc_host {
|
||||
|
||||
u32 caps2; /* More host capabilities */
|
||||
|
||||
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
|
||||
#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */
|
||||
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
|
||||
#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */
|
||||
#ifdef CONFIG_AMLOGIC_MMC
|
||||
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
|
||||
#endif
|
||||
#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
|
||||
#define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */
|
||||
#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
|
||||
|
||||
Reference in New Issue
Block a user