Merge tag 'mmc-2020-3-9' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- DM support for CAxxxx SoCs - eMMC board for presidio-asic - Add defer probe for mmc sdhci - TI SoCs mmc misc update
This commit is contained in:
commit
36bdcf7f3b
@ -180,6 +180,7 @@ F: board/cortina/common/
|
|||||||
F: drivers/gpio/cortina_gpio.c
|
F: drivers/gpio/cortina_gpio.c
|
||||||
F: drivers/watchdog/cortina_wdt.c
|
F: drivers/watchdog/cortina_wdt.c
|
||||||
F: drivers/serial/serial_cortina.c
|
F: drivers/serial/serial_cortina.c
|
||||||
|
F: drivers/mmc/ca_dw_mmc.c
|
||||||
|
|
||||||
ARM/CZ.NIC TURRIS MOX SUPPORT
|
ARM/CZ.NIC TURRIS MOX SUPPORT
|
||||||
M: Marek Behun <marek.behun@nic.cz>
|
M: Marek Behun <marek.behun@nic.cz>
|
||||||
@ -672,6 +673,7 @@ F: board/cortina/common/
|
|||||||
F: drivers/gpio/cortina_gpio.c
|
F: drivers/gpio/cortina_gpio.c
|
||||||
F: drivers/watchdog/cortina_wdt.c
|
F: drivers/watchdog/cortina_wdt.c
|
||||||
F: drivers/serial/serial_cortina.c
|
F: drivers/serial/serial_cortina.c
|
||||||
|
F: drivers/mmc/ca_dw_mmc.c
|
||||||
|
|
||||||
MIPS MSCC
|
MIPS MSCC
|
||||||
M: Gregory CLEMENT <gregory.clement@bootlin.com>
|
M: Gregory CLEMENT <gregory.clement@bootlin.com>
|
||||||
|
@ -98,7 +98,17 @@
|
|||||||
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
mmc-ddr-1_8v;
|
mmc-ddr-1_8v;
|
||||||
mmc-hs200-1_8v;
|
mmc-hs200-1_8v;
|
||||||
ti,otap-del-sel = <0x2>;
|
ti,otap-del-sel-legacy = <0x0>;
|
||||||
|
ti,otap-del-sel-mmc-hs = <0x0>;
|
||||||
|
ti,otap-del-sel-sd-hs = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr12 = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr25 = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr50 = <0x8>;
|
||||||
|
ti,otap-del-sel-sdr104 = <0x5>;
|
||||||
|
ti,otap-del-sel-ddr50 = <0x5>;
|
||||||
|
ti,otap-del-sel-ddr52 = <0x5>;
|
||||||
|
ti,otap-del-sel-hs200 = <0x5>;
|
||||||
|
ti,otap-del-sel-hs400 = <0x0>;
|
||||||
ti,trm-icp = <0x8>;
|
ti,trm-icp = <0x8>;
|
||||||
dma-coherent;
|
dma-coherent;
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,16 @@
|
|||||||
clock-names = "clk_ahb", "clk_xin";
|
clock-names = "clk_ahb", "clk_xin";
|
||||||
power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>;
|
power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>;
|
||||||
max-frequency = <25000000>;
|
max-frequency = <25000000>;
|
||||||
ti,otap-del-sel = <0x2>;
|
ti,otap-del-sel-legacy = <0x0>;
|
||||||
|
ti,otap-del-sel-mmc-hs = <0x0>;
|
||||||
|
ti,otap-del-sel-sd-hs = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr12 = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr25 = <0x0>;
|
||||||
|
ti,otap-del-sel-sdr50 = <0x8>;
|
||||||
|
ti,otap-del-sel-sdr104 = <0x7>;
|
||||||
|
ti,otap-del-sel-ddr50 = <0x4>;
|
||||||
|
ti,otap-del-sel-ddr52 = <0x4>;
|
||||||
|
ti,otap-del-sel-hs200 = <0x7>;
|
||||||
ti,trm-icp = <0x8>;
|
ti,trm-icp = <0x8>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,9 +232,14 @@
|
|||||||
assigned-clocks = <&k3_clks 91 1>;
|
assigned-clocks = <&k3_clks 91 1>;
|
||||||
assigned-clock-parents = <&k3_clks 91 2>;
|
assigned-clock-parents = <&k3_clks 91 2>;
|
||||||
bus-width = <8>;
|
bus-width = <8>;
|
||||||
ti,otap-del-sel = <0x2>;
|
|
||||||
ti,trm-icp = <0x8>;
|
ti,trm-icp = <0x8>;
|
||||||
dma-coherent;
|
dma-coherent;
|
||||||
|
mmc-ddr-1_8v;
|
||||||
|
ti,otap-del-sel-legacy = <0x0>;
|
||||||
|
ti,otap-del-sel-mmc-hs = <0x0>;
|
||||||
|
ti,otap-del-sel-ddr52 = <0x5>;
|
||||||
|
ti,otap-del-sel-hs200 = <0x6>;
|
||||||
|
ti,otap-del-sel-hs400 = <0x0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
main_sdhci1: sdhci@4fb0000 {
|
main_sdhci1: sdhci@4fb0000 {
|
||||||
@ -246,7 +251,13 @@
|
|||||||
clocks = <&k3_clks 92 0>, <&k3_clks 92 5>;
|
clocks = <&k3_clks 92 0>, <&k3_clks 92 5>;
|
||||||
assigned-clocks = <&k3_clks 92 0>;
|
assigned-clocks = <&k3_clks 92 0>;
|
||||||
assigned-clock-parents = <&k3_clks 92 1>;
|
assigned-clock-parents = <&k3_clks 92 1>;
|
||||||
ti,otap-del-sel = <0x2>;
|
ti,otap-del-sel-legacy = <0x0>;
|
||||||
|
ti,otap-del-sel-sd-hs = <0xf>;
|
||||||
|
ti,otap-del-sel-sdr12 = <0xf>;
|
||||||
|
ti,otap-del-sel-sdr25 = <0xf>;
|
||||||
|
ti,otap-del-sel-sdr50 = <0xc>;
|
||||||
|
ti,otap-del-sel-sdr104 = <0x5>;
|
||||||
|
ti,otap-del-sel-ddr50 = <0xc>;
|
||||||
ti,trm-icp = <0x8>;
|
ti,trm-icp = <0x8>;
|
||||||
dma-coherent;
|
dma-coherent;
|
||||||
};
|
};
|
||||||
|
@ -34,14 +34,14 @@
|
|||||||
u-boot,dm-spl;
|
u-boot,dm-spl;
|
||||||
};
|
};
|
||||||
|
|
||||||
clk_200mhz: dummy_clock {
|
clk_200mhz: dummy_clock_200mhz {
|
||||||
compatible = "fixed-clock";
|
compatible = "fixed-clock";
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
clock-frequency = <200000000>;
|
clock-frequency = <200000000>;
|
||||||
u-boot,dm-spl;
|
u-boot,dm-spl;
|
||||||
};
|
};
|
||||||
|
|
||||||
clk_19_2mhz: dummy_clock {
|
clk_19_2mhz: dummy_clock_19_2mhz {
|
||||||
compatible = "fixed-clock";
|
compatible = "fixed-clock";
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
clock-frequency = <19200000>;
|
clock-frequency = <19200000>;
|
||||||
|
@ -197,7 +197,8 @@ unsigned long spl_spi_get_uboot_offs(struct spi_flash *flash)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_MMC_SUPPORT
|
#ifdef CONFIG_SPL_MMC_SUPPORT
|
||||||
unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
|
unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
||||||
|
unsigned long raw_sect)
|
||||||
{
|
{
|
||||||
int end;
|
int end;
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <dm/uclass-internal.h>
|
#include <dm/uclass-internal.h>
|
||||||
#include <dm/pinctrl.h>
|
#include <dm/pinctrl.h>
|
||||||
#include <linux/soc/ti/ti_sci_protocol.h>
|
#include <linux/soc/ti/ti_sci_protocol.h>
|
||||||
|
#include <mmc.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifdef CONFIG_SPL_BUILD
|
||||||
#ifdef CONFIG_K3_LOAD_SYSFW
|
#ifdef CONFIG_K3_LOAD_SYSFW
|
||||||
@ -86,6 +87,33 @@ static void store_boot_index_from_rom(void)
|
|||||||
bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
|
bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_K3_LOAD_SYSFW)
|
||||||
|
void k3_mmc_stop_clock(void)
|
||||||
|
{
|
||||||
|
if (spl_boot_device() == BOOT_DEVICE_MMC1) {
|
||||||
|
struct mmc *mmc = find_mmc_device(0);
|
||||||
|
|
||||||
|
if (!mmc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmc->saved_clock = mmc->clock;
|
||||||
|
mmc_set_clock(mmc, 0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void k3_mmc_restart_clock(void)
|
||||||
|
{
|
||||||
|
if (spl_boot_device() == BOOT_DEVICE_MMC1) {
|
||||||
|
struct mmc *mmc = find_mmc_device(0);
|
||||||
|
|
||||||
|
if (!mmc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmc_set_clock(mmc, mmc->saved_clock, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void board_init_f(ulong dummy)
|
void board_init_f(ulong dummy)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
|
#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
|
||||||
@ -138,7 +166,10 @@ void board_init_f(ulong dummy)
|
|||||||
* callback hook, effectively switching on (or over) the console
|
* callback hook, effectively switching on (or over) the console
|
||||||
* output.
|
* output.
|
||||||
*/
|
*/
|
||||||
k3_sysfw_loader(preloader_console_init);
|
k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
|
||||||
|
|
||||||
|
/* Prepare console output */
|
||||||
|
preloader_console_init();
|
||||||
|
|
||||||
/* Disable ROM configured firewalls right after loading sysfw */
|
/* Disable ROM configured firewalls right after loading sysfw */
|
||||||
#ifdef CONFIG_TI_SECURE_DEVICE
|
#ifdef CONFIG_TI_SECURE_DEVICE
|
||||||
|
@ -7,6 +7,6 @@
|
|||||||
#ifndef _SYSFW_LOADER_H_
|
#ifndef _SYSFW_LOADER_H_
|
||||||
#define _SYSFW_LOADER_H_
|
#define _SYSFW_LOADER_H_
|
||||||
|
|
||||||
void k3_sysfw_loader(void (*config_pm_done_callback)(void));
|
void k3_sysfw_loader(void (*config_pm_pre_callback)(void), void (*config_pm_done_callback)(void));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <dm/uclass-internal.h>
|
#include <dm/uclass-internal.h>
|
||||||
#include <dm/pinctrl.h>
|
#include <dm/pinctrl.h>
|
||||||
|
#include <mmc.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifdef CONFIG_SPL_BUILD
|
||||||
#ifdef CONFIG_K3_LOAD_SYSFW
|
#ifdef CONFIG_K3_LOAD_SYSFW
|
||||||
@ -100,6 +101,33 @@ static void ctrl_mmr_unlock(void)
|
|||||||
mmr_unlock(CTRL_MMR0_BASE, 7);
|
mmr_unlock(CTRL_MMR0_BASE, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_K3_LOAD_SYSFW)
|
||||||
|
void k3_mmc_stop_clock(void)
|
||||||
|
{
|
||||||
|
if (spl_boot_device() == BOOT_DEVICE_MMC1) {
|
||||||
|
struct mmc *mmc = find_mmc_device(0);
|
||||||
|
|
||||||
|
if (!mmc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmc->saved_clock = mmc->clock;
|
||||||
|
mmc_set_clock(mmc, 0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void k3_mmc_restart_clock(void)
|
||||||
|
{
|
||||||
|
if (spl_boot_device() == BOOT_DEVICE_MMC1) {
|
||||||
|
struct mmc *mmc = find_mmc_device(0);
|
||||||
|
|
||||||
|
if (!mmc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmc_set_clock(mmc, mmc->saved_clock, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This uninitialized global variable would normal end up in the .bss section,
|
* This uninitialized global variable would normal end up in the .bss section,
|
||||||
* but the .bss is cleared between writing and reading this variable, so move
|
* but the .bss is cleared between writing and reading this variable, so move
|
||||||
@ -154,7 +182,10 @@ void board_init_f(ulong dummy)
|
|||||||
* callback hook, effectively switching on (or over) the console
|
* callback hook, effectively switching on (or over) the console
|
||||||
* output.
|
* output.
|
||||||
*/
|
*/
|
||||||
k3_sysfw_loader(preloader_console_init);
|
k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
|
||||||
|
|
||||||
|
/* Prepare console output */
|
||||||
|
preloader_console_init();
|
||||||
|
|
||||||
/* Disable ROM configured firewalls right after loading sysfw */
|
/* Disable ROM configured firewalls right after loading sysfw */
|
||||||
#ifdef CONFIG_TI_SECURE_DEVICE
|
#ifdef CONFIG_TI_SECURE_DEVICE
|
||||||
|
@ -197,7 +197,8 @@ exit:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void k3_sysfw_loader(void (*config_pm_done_callback)(void))
|
void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
|
||||||
|
void (*config_pm_done_callback)(void))
|
||||||
{
|
{
|
||||||
struct spl_image_info spl_image = { 0 };
|
struct spl_image_info spl_image = { 0 };
|
||||||
struct spl_boot_device bootdev = { 0 };
|
struct spl_boot_device bootdev = { 0 };
|
||||||
@ -291,6 +292,9 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
|
|||||||
/* Get handle for accessing SYSFW services */
|
/* Get handle for accessing SYSFW services */
|
||||||
ti_sci = get_ti_sci_handle();
|
ti_sci = get_ti_sci_handle();
|
||||||
|
|
||||||
|
if (config_pm_pre_callback)
|
||||||
|
config_pm_pre_callback();
|
||||||
|
|
||||||
/* Parse and apply the different SYSFW configuration fragments */
|
/* Parse and apply the different SYSFW configuration fragments */
|
||||||
k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);
|
k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);
|
||||||
|
|
||||||
|
@ -317,13 +317,10 @@ int spl_boot_partition(const u32 boot_device)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
|
unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
||||||
|
unsigned long raw_sect)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
|
return raw_sect;
|
||||||
return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int spl_mmc_load(struct spl_image_info *spl_image,
|
int spl_mmc_load(struct spl_image_info *spl_image,
|
||||||
@ -392,7 +389,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_sect = spl_mmc_get_uboot_raw_sector(mmc);
|
raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
|
#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
|
||||||
err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
|
err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
|
||||||
|
@ -74,6 +74,7 @@ CONFIG_DM_KEYBOARD=y
|
|||||||
CONFIG_DM_MAILBOX=y
|
CONFIG_DM_MAILBOX=y
|
||||||
CONFIG_K3_SEC_PROXY=y
|
CONFIG_K3_SEC_PROXY=y
|
||||||
CONFIG_DM_MMC=y
|
CONFIG_DM_MMC=y
|
||||||
|
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_MMC_SDHCI_ADMA=y
|
CONFIG_MMC_SDHCI_ADMA=y
|
||||||
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
||||||
|
@ -73,6 +73,7 @@ CONFIG_K3_SEC_PROXY=y
|
|||||||
CONFIG_MISC=y
|
CONFIG_MISC=y
|
||||||
CONFIG_K3_AVS0=y
|
CONFIG_K3_AVS0=y
|
||||||
CONFIG_DM_MMC=y
|
CONFIG_DM_MMC=y
|
||||||
|
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
||||||
CONFIG_MMC_SDHCI_AM654=y
|
CONFIG_MMC_SDHCI_AM654=y
|
||||||
|
33
configs/cortina_presidio-asic-emmc_defconfig
Normal file
33
configs/cortina_presidio-asic-emmc_defconfig
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
CONFIG_ARM=y
|
||||||
|
# CONFIG_SYS_ARCH_TIMER is not set
|
||||||
|
CONFIG_TARGET_PRESIDIO_ASIC=y
|
||||||
|
CONFIG_SYS_TEXT_BASE=0x04000000
|
||||||
|
CONFIG_ENV_SIZE=0x20000
|
||||||
|
CONFIG_DM_GPIO=y
|
||||||
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
|
CONFIG_IDENT_STRING="Presidio-SoC"
|
||||||
|
CONFIG_SHOW_BOOT_PROGRESS=y
|
||||||
|
CONFIG_BOOTDELAY=3
|
||||||
|
CONFIG_BOARD_EARLY_INIT_R=y
|
||||||
|
CONFIG_SYS_PROMPT="G3#"
|
||||||
|
CONFIG_CMD_MMC=y
|
||||||
|
CONFIG_CMD_PART=y
|
||||||
|
CONFIG_CMD_WDT=y
|
||||||
|
CONFIG_CMD_CACHE=y
|
||||||
|
CONFIG_CMD_TIMER=y
|
||||||
|
CONFIG_CMD_SMC=y
|
||||||
|
CONFIG_CMD_EXT2=y
|
||||||
|
CONFIG_CMD_EXT4=y
|
||||||
|
CONFIG_OF_CONTROL=y
|
||||||
|
CONFIG_OF_LIVE=y
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
|
||||||
|
# CONFIG_NET is not set
|
||||||
|
CONFIG_DM=y
|
||||||
|
CONFIG_CORTINA_GPIO=y
|
||||||
|
CONFIG_DM_MMC=y
|
||||||
|
CONFIG_MMC_DW=y
|
||||||
|
CONFIG_MMC_DW_CORTINA=y
|
||||||
|
CONFIG_DM_SERIAL=y
|
||||||
|
CONFIG_CORTINA_UART=y
|
||||||
|
CONFIG_WDT=y
|
||||||
|
CONFIG_WDT_CORTINA=y
|
@ -29,6 +29,8 @@ CONFIG_SPL_BOARD_INIT=y
|
|||||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||||
CONFIG_SPL_STACK_R=y
|
CONFIG_SPL_STACK_R=y
|
||||||
CONFIG_SPL_SEPARATE_BSS=y
|
CONFIG_SPL_SEPARATE_BSS=y
|
||||||
|
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
|
||||||
|
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
|
||||||
CONFIG_SPL_ENV_SUPPORT=y
|
CONFIG_SPL_ENV_SUPPORT=y
|
||||||
CONFIG_SPL_I2C_SUPPORT=y
|
CONFIG_SPL_I2C_SUPPORT=y
|
||||||
CONFIG_SPL_DM_MAILBOX=y
|
CONFIG_SPL_DM_MAILBOX=y
|
||||||
@ -99,6 +101,7 @@ CONFIG_SYS_I2C_OMAP24XX=y
|
|||||||
CONFIG_DM_MAILBOX=y
|
CONFIG_DM_MAILBOX=y
|
||||||
CONFIG_K3_SEC_PROXY=y
|
CONFIG_K3_SEC_PROXY=y
|
||||||
CONFIG_DM_MMC=y
|
CONFIG_DM_MMC=y
|
||||||
|
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_MMC_SDHCI_ADMA=y
|
CONFIG_MMC_SDHCI_ADMA=y
|
||||||
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
||||||
|
@ -27,6 +27,8 @@ CONFIG_USE_BOOTCOMMAND=y
|
|||||||
CONFIG_SPL_STACK_R=y
|
CONFIG_SPL_STACK_R=y
|
||||||
CONFIG_SPL_SEPARATE_BSS=y
|
CONFIG_SPL_SEPARATE_BSS=y
|
||||||
CONFIG_SPL_EARLY_BSS=y
|
CONFIG_SPL_EARLY_BSS=y
|
||||||
|
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
|
||||||
|
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
|
||||||
CONFIG_SPL_ENV_SUPPORT=y
|
CONFIG_SPL_ENV_SUPPORT=y
|
||||||
CONFIG_SPL_I2C_SUPPORT=y
|
CONFIG_SPL_I2C_SUPPORT=y
|
||||||
CONFIG_SPL_DM_MAILBOX=y
|
CONFIG_SPL_DM_MAILBOX=y
|
||||||
@ -77,6 +79,7 @@ CONFIG_MISC=y
|
|||||||
CONFIG_FS_LOADER=y
|
CONFIG_FS_LOADER=y
|
||||||
CONFIG_K3_AVS0=y
|
CONFIG_K3_AVS0=y
|
||||||
CONFIG_DM_MMC=y
|
CONFIG_DM_MMC=y
|
||||||
|
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||||
CONFIG_MMC_SDHCI=y
|
CONFIG_MMC_SDHCI=y
|
||||||
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
CONFIG_SPL_MMC_SDHCI_ADMA=y
|
||||||
CONFIG_MMC_SDHCI_AM654=y
|
CONFIG_MMC_SDHCI_AM654=y
|
||||||
|
@ -205,6 +205,17 @@ config MMC_DW
|
|||||||
block, this provides host support for SD and MMC interfaces, in both
|
block, this provides host support for SD and MMC interfaces, in both
|
||||||
PIO, internal DMA mode and external DMA mode.
|
PIO, internal DMA mode and external DMA mode.
|
||||||
|
|
||||||
|
config MMC_DW_CORTINA
|
||||||
|
bool "Cortina specific extensions for Synopsys DW Memory Card Interface"
|
||||||
|
depends on DM_MMC
|
||||||
|
depends on MMC_DW
|
||||||
|
depends on BLK
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This selects support for Cortina SoC specific extensions to the
|
||||||
|
Synopsys DesignWare Memory Card Interface driver. Select this option
|
||||||
|
for platforms based on Cortina CAxxxx Soc's.
|
||||||
|
|
||||||
config MMC_DW_EXYNOS
|
config MMC_DW_EXYNOS
|
||||||
bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
|
bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
|
||||||
depends on ARCH_EXYNOS
|
depends on ARCH_EXYNOS
|
||||||
|
@ -20,6 +20,7 @@ endif
|
|||||||
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
|
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
|
||||||
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
|
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
|
||||||
obj-$(CONFIG_MMC_DW) += dw_mmc.o
|
obj-$(CONFIG_MMC_DW) += dw_mmc.o
|
||||||
|
obj-$(CONFIG_MMC_DW_CORTINA) += ca_dw_mmc.o
|
||||||
obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
|
obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
|
||||||
obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
|
obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
|
||||||
obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
|
obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
|
||||||
|
@ -74,7 +74,7 @@ struct am654_sdhci_plat {
|
|||||||
struct mmc mmc;
|
struct mmc mmc;
|
||||||
struct regmap *base;
|
struct regmap *base;
|
||||||
bool non_removable;
|
bool non_removable;
|
||||||
u32 otap_del_sel;
|
u32 otap_del_sel[11];
|
||||||
u32 trm_icp;
|
u32 trm_icp;
|
||||||
u32 drv_strength;
|
u32 drv_strength;
|
||||||
u32 strb_sel;
|
u32 strb_sel;
|
||||||
@ -86,6 +86,25 @@ struct am654_sdhci_plat {
|
|||||||
bool dll_on;
|
bool dll_on;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct timing_data {
|
||||||
|
const char *binding;
|
||||||
|
u32 capability;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct timing_data td[] = {
|
||||||
|
[MMC_LEGACY] = {"ti,otap-del-sel-legacy", 0},
|
||||||
|
[MMC_HS] = {"ti,otap-del-sel-mmc-hs", MMC_CAP(MMC_HS)},
|
||||||
|
[SD_HS] = {"ti,otap-del-sel-sd-hs", MMC_CAP(SD_HS)},
|
||||||
|
[UHS_SDR12] = {"ti,otap-del-sel-sdr12", MMC_CAP(UHS_SDR12)},
|
||||||
|
[UHS_SDR25] = {"ti,otap-del-sel-sdr25", MMC_CAP(UHS_SDR25)},
|
||||||
|
[UHS_SDR50] = {"ti,otap-del-sel-sdr50", MMC_CAP(UHS_SDR50)},
|
||||||
|
[UHS_SDR104] = {"ti,otap-del-sel-sdr104", MMC_CAP(UHS_SDR104)},
|
||||||
|
[UHS_DDR50] = {"ti,otap-del-sel-ddr50", MMC_CAP(UHS_DDR50)},
|
||||||
|
[MMC_DDR_52] = {"ti,otap-del-sel-ddr52", MMC_CAP(MMC_DDR_52)},
|
||||||
|
[MMC_HS_200] = {"ti,otap-del-sel-hs200", MMC_CAP(MMC_HS_200)},
|
||||||
|
[MMC_HS_400] = {"ti,otap-del-sel-hs400", MMC_CAP(MMC_HS_400)},
|
||||||
|
};
|
||||||
|
|
||||||
struct am654_driver_data {
|
struct am654_driver_data {
|
||||||
const struct sdhci_ops *ops;
|
const struct sdhci_ops *ops;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
@ -112,6 +131,7 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
|
|||||||
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
||||||
unsigned int speed = host->mmc->clock;
|
unsigned int speed = host->mmc->clock;
|
||||||
int sel50, sel100, freqsel;
|
int sel50, sel100, freqsel;
|
||||||
|
u32 otap_del_sel;
|
||||||
u32 mask, val;
|
u32 mask, val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -132,9 +152,10 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
|
|||||||
|
|
||||||
/* switch phy back on */
|
/* switch phy back on */
|
||||||
if (speed > AM654_SDHCI_MIN_FREQ) {
|
if (speed > AM654_SDHCI_MIN_FREQ) {
|
||||||
|
otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
|
||||||
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
|
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
|
||||||
val = (1 << OTAPDLYENA_SHIFT) |
|
val = (1 << OTAPDLYENA_SHIFT) |
|
||||||
(plat->otap_del_sel << OTAPDLYSEL_SHIFT);
|
(otap_del_sel << OTAPDLYSEL_SHIFT);
|
||||||
|
|
||||||
/* Write to STRBSEL for HS400 speed mode */
|
/* Write to STRBSEL for HS400 speed mode */
|
||||||
if (host->mmc->selected_mode == MMC_HS_400) {
|
if (host->mmc->selected_mode == MMC_HS_400) {
|
||||||
@ -197,44 +218,6 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sdhci_ops am654_sdhci_ops = {
|
|
||||||
.set_ios_post = &am654_sdhci_set_ios_post,
|
|
||||||
.set_control_reg = &am654_sdhci_set_control_reg,
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct am654_driver_data am654_drv_data = {
|
|
||||||
.ops = &am654_sdhci_ops,
|
|
||||||
.flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | STRBSEL_4_BIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct am654_driver_data j721e_8bit_drv_data = {
|
|
||||||
.ops = &am654_sdhci_ops,
|
|
||||||
.flags = DLL_PRESENT,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
|
|
||||||
{
|
|
||||||
struct udevice *dev = host->mmc->dev;
|
|
||||||
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
|
||||||
u32 mask, val;
|
|
||||||
|
|
||||||
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
|
|
||||||
val = (1 << OTAPDLYENA_SHIFT) |
|
|
||||||
(plat->otap_del_sel << OTAPDLYSEL_SHIFT);
|
|
||||||
regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct sdhci_ops j721e_4bit_sdhci_ops = {
|
|
||||||
.set_ios_post = &j721e_4bit_sdhci_set_ios_post,
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct am654_driver_data j721e_4bit_drv_data = {
|
|
||||||
.ops = &j721e_4bit_sdhci_ops,
|
|
||||||
.flags = IOMUX_PRESENT,
|
|
||||||
};
|
|
||||||
|
|
||||||
int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
||||||
{
|
{
|
||||||
u32 ctl_cfg_2 = 0;
|
u32 ctl_cfg_2 = 0;
|
||||||
@ -281,6 +264,104 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_SDCD_DEBOUNCE_TIME 2000
|
||||||
|
static int am654_sdhci_deferred_probe(struct sdhci_host *host)
|
||||||
|
{
|
||||||
|
struct udevice *dev = host->mmc->dev;
|
||||||
|
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
||||||
|
unsigned long start;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The controller takes about 1 second to debounce the card detect line
|
||||||
|
* and doesn't let us power on until that time is up. Instead of waiting
|
||||||
|
* for 1 second at every stage, poll on the CARD_PRESENT bit upto a
|
||||||
|
* maximum of 2 seconds to be safe..
|
||||||
|
*/
|
||||||
|
start = get_timer(0);
|
||||||
|
do {
|
||||||
|
if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
|
||||||
|
return -ENOMEDIUM;
|
||||||
|
|
||||||
|
val = mmc_getcd(host->mmc);
|
||||||
|
} while (!val);
|
||||||
|
|
||||||
|
am654_sdhci_init(plat);
|
||||||
|
|
||||||
|
return sdhci_probe(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct sdhci_ops am654_sdhci_ops = {
|
||||||
|
.deferred_probe = am654_sdhci_deferred_probe,
|
||||||
|
.set_ios_post = &am654_sdhci_set_ios_post,
|
||||||
|
.set_control_reg = &am654_sdhci_set_control_reg,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct am654_driver_data am654_drv_data = {
|
||||||
|
.ops = &am654_sdhci_ops,
|
||||||
|
.flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | STRBSEL_4_BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct am654_driver_data j721e_8bit_drv_data = {
|
||||||
|
.ops = &am654_sdhci_ops,
|
||||||
|
.flags = DLL_PRESENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
|
||||||
|
{
|
||||||
|
struct udevice *dev = host->mmc->dev;
|
||||||
|
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
||||||
|
u32 otap_del_sel, mask, val;
|
||||||
|
|
||||||
|
otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
|
||||||
|
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
|
||||||
|
val = (1 << OTAPDLYENA_SHIFT) | (otap_del_sel << OTAPDLYSEL_SHIFT);
|
||||||
|
regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct sdhci_ops j721e_4bit_sdhci_ops = {
|
||||||
|
.deferred_probe = am654_sdhci_deferred_probe,
|
||||||
|
.set_ios_post = &j721e_4bit_sdhci_set_ios_post,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct am654_driver_data j721e_4bit_drv_data = {
|
||||||
|
.ops = &j721e_4bit_sdhci_ops,
|
||||||
|
.flags = IOMUX_PRESENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sdhci_am654_get_otap_delay(struct udevice *dev,
|
||||||
|
struct mmc_config *cfg)
|
||||||
|
{
|
||||||
|
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* ti,otap-del-sel-legacy is mandatory */
|
||||||
|
ret = dev_read_u32(dev, "ti,otap-del-sel-legacy",
|
||||||
|
&plat->otap_del_sel[0]);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
/*
|
||||||
|
* Remove the corresponding capability if an otap-del-sel
|
||||||
|
* value is not found
|
||||||
|
*/
|
||||||
|
for (i = MMC_HS; i <= MMC_HS_400; i++) {
|
||||||
|
ret = dev_read_u32(dev, td[i].binding, &plat->otap_del_sel[i]);
|
||||||
|
if (ret) {
|
||||||
|
dev_dbg(dev, "Couldn't find %s\n", td[i].binding);
|
||||||
|
/*
|
||||||
|
* Remove the corresponding capability
|
||||||
|
* if an otap-del-sel value is not found
|
||||||
|
*/
|
||||||
|
cfg->host_caps &= ~td[i].capability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int am654_sdhci_probe(struct udevice *dev)
|
static int am654_sdhci_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct am654_driver_data *drv_data =
|
struct am654_driver_data *drv_data =
|
||||||
@ -313,15 +394,17 @@ static int am654_sdhci_probe(struct udevice *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = sdhci_am654_get_otap_delay(dev, cfg);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
host->ops = drv_data->ops;
|
host->ops = drv_data->ops;
|
||||||
host->mmc->priv = host;
|
host->mmc->priv = host;
|
||||||
upriv->mmc = host->mmc;
|
upriv->mmc = host->mmc;
|
||||||
|
|
||||||
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
|
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
|
||||||
|
|
||||||
am654_sdhci_init(plat);
|
return 0;
|
||||||
|
|
||||||
return sdhci_probe(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
|
static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
|
||||||
@ -336,10 +419,6 @@ static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
|
|||||||
host->ioaddr = (void *)dev_read_addr(dev);
|
host->ioaddr = (void *)dev_read_addr(dev);
|
||||||
plat->non_removable = dev_read_bool(dev, "non-removable");
|
plat->non_removable = dev_read_bool(dev, "non-removable");
|
||||||
|
|
||||||
ret = dev_read_u32(dev, "ti,otap-del-sel", &plat->otap_del_sel);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (plat->flags & DLL_PRESENT) {
|
if (plat->flags & DLL_PRESENT) {
|
||||||
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
|
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
181
drivers/mmc/ca_dw_mmc.c
Normal file
181
drivers/mmc/ca_dw_mmc.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2019 Cortina Access
|
||||||
|
* Arthur Li <arthur.li@cortina-access.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dwmmc.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <linux/libfdt.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <mapmem.h>
|
||||||
|
|
||||||
|
#define SD_CLK_SEL_MASK (0x3)
|
||||||
|
#define SD_DLL_DEFAULT (0x143000)
|
||||||
|
#define SD_SCLK_MAX (200000000)
|
||||||
|
|
||||||
|
#define SD_CLK_SEL_200MHZ (0x2)
|
||||||
|
#define SD_CLK_SEL_100MHZ (0x1)
|
||||||
|
|
||||||
|
#define IO_DRV_SD_DS_OFFSET (16)
|
||||||
|
#define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET)
|
||||||
|
|
||||||
|
#define MIN_FREQ (400000)
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
struct ca_mmc_plat {
|
||||||
|
struct mmc_config cfg;
|
||||||
|
struct mmc mmc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ca_dwmmc_priv_data {
|
||||||
|
struct dwmci_host host;
|
||||||
|
void __iomem *sd_dll_reg;
|
||||||
|
void __iomem *io_drv_reg;
|
||||||
|
u8 ds;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ca_dwmci_clksel(struct dwmci_host *host)
|
||||||
|
{
|
||||||
|
struct ca_dwmmc_priv_data *priv = host->priv;
|
||||||
|
u32 val = readl(priv->sd_dll_reg);
|
||||||
|
|
||||||
|
if (host->bus_hz >= 200000000) {
|
||||||
|
val &= ~SD_CLK_SEL_MASK;
|
||||||
|
val |= SD_CLK_SEL_200MHZ;
|
||||||
|
} else if (host->bus_hz >= 100000000) {
|
||||||
|
val &= ~SD_CLK_SEL_MASK;
|
||||||
|
val |= SD_CLK_SEL_100MHZ;
|
||||||
|
} else {
|
||||||
|
val &= ~SD_CLK_SEL_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(val, priv->sd_dll_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ca_dwmci_board_init(struct dwmci_host *host)
|
||||||
|
{
|
||||||
|
struct ca_dwmmc_priv_data *priv = host->priv;
|
||||||
|
u32 val = readl(priv->io_drv_reg);
|
||||||
|
|
||||||
|
writel(SD_DLL_DEFAULT, priv->sd_dll_reg);
|
||||||
|
|
||||||
|
val &= ~IO_DRV_SD_DS_MASK;
|
||||||
|
if (priv && priv->ds)
|
||||||
|
val |= priv->ds << IO_DRV_SD_DS_OFFSET;
|
||||||
|
writel(val, priv->io_drv_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq)
|
||||||
|
{
|
||||||
|
struct ca_dwmmc_priv_data *priv = host->priv;
|
||||||
|
u8 sd_clk_sel = readl(priv->sd_dll_reg) & SD_CLK_SEL_MASK;
|
||||||
|
u8 clk_div;
|
||||||
|
|
||||||
|
switch (sd_clk_sel) {
|
||||||
|
case 2:
|
||||||
|
clk_div = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
clk_div = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
clk_div = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SD_SCLK_MAX / clk_div / (host->div + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
|
||||||
|
struct dwmci_host *host = &priv->host;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
host->name = dev->name;
|
||||||
|
host->dev_index = 0;
|
||||||
|
|
||||||
|
host->buswidth = dev_read_u32_default(dev, "bus-width", 1);
|
||||||
|
if (host->buswidth != 1 && host->buswidth != 4)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000);
|
||||||
|
priv->ds = dev_read_u32_default(dev, "io_ds", 0x33);
|
||||||
|
host->fifo_mode = dev_read_bool(dev, "fifo-mode");
|
||||||
|
|
||||||
|
dev_read_u32(dev, "sd_dll_ctrl", &tmp);
|
||||||
|
priv->sd_dll_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
|
||||||
|
if (!priv->sd_dll_reg)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dev_read_u32(dev, "io_drv_ctrl", &tmp);
|
||||||
|
priv->io_drv_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
|
||||||
|
if (!priv->io_drv_reg)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
host->ioaddr = dev_read_addr_ptr(dev);
|
||||||
|
if (host->ioaddr == (void *)FDT_ADDR_T_NONE) {
|
||||||
|
printf("DWMMC: base address is invalid\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
host->priv = priv;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dm_mmc_ops ca_dwmci_dm_ops;
|
||||||
|
|
||||||
|
static int ca_dwmmc_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct ca_mmc_plat *plat = dev_get_platdata(dev);
|
||||||
|
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
||||||
|
struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
|
||||||
|
struct dwmci_host *host = &priv->host;
|
||||||
|
|
||||||
|
memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops));
|
||||||
|
|
||||||
|
dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ);
|
||||||
|
if (host->buswidth == 1) {
|
||||||
|
(&plat->cfg)->host_caps &= ~MMC_MODE_8BIT;
|
||||||
|
(&plat->cfg)->host_caps &= ~MMC_MODE_4BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
host->mmc = &plat->mmc;
|
||||||
|
host->mmc->priv = &priv->host;
|
||||||
|
upriv->mmc = host->mmc;
|
||||||
|
host->mmc->dev = dev;
|
||||||
|
host->clksel = ca_dwmci_clksel;
|
||||||
|
host->board_init = ca_dwmci_board_init;
|
||||||
|
host->get_mmc_clk = ca_dwmci_get_mmc_clock;
|
||||||
|
|
||||||
|
return dwmci_probe(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ca_dwmmc_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct ca_mmc_plat *plat = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
return dwmci_bind(dev, &plat->mmc, &plat->cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id ca_dwmmc_ids[] = {
|
||||||
|
{ .compatible = "snps,dw-cortina" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(ca_dwmmc_drv) = {
|
||||||
|
.name = "cortina_dwmmc",
|
||||||
|
.id = UCLASS_MMC,
|
||||||
|
.of_match = ca_dwmmc_ids,
|
||||||
|
.ofdata_to_platdata = ca_dwmmc_ofdata_to_platdata,
|
||||||
|
.bind = ca_dwmmc_bind,
|
||||||
|
.ops = &ca_dwmci_dm_ops,
|
||||||
|
.probe = ca_dwmmc_probe,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct ca_dwmmc_priv_data),
|
||||||
|
.platdata_auto_alloc_size = sizeof(struct ca_mmc_plat),
|
||||||
|
};
|
@ -743,7 +743,6 @@ static int esdhc_set_timing(struct mmc *mmc)
|
|||||||
|
|
||||||
switch (mmc->selected_mode) {
|
switch (mmc->selected_mode) {
|
||||||
case MMC_LEGACY:
|
case MMC_LEGACY:
|
||||||
case SD_LEGACY:
|
|
||||||
esdhc_reset_tuning(mmc);
|
esdhc_reset_tuning(mmc);
|
||||||
writel(mixctrl, ®s->mixctrl);
|
writel(mixctrl, ®s->mixctrl);
|
||||||
break;
|
break;
|
||||||
|
@ -138,6 +138,21 @@ int mmc_host_power_cycle(struct mmc *mmc)
|
|||||||
return dm_mmc_host_power_cycle(mmc->dev);
|
return dm_mmc_host_power_cycle(mmc->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dm_mmc_deferred_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
|
||||||
|
if (ops->deferred_probe)
|
||||||
|
return ops->deferred_probe(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mmc_deferred_probe(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
return dm_mmc_deferred_probe(mmc->dev);
|
||||||
|
}
|
||||||
|
|
||||||
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
|
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
|
@ -132,7 +132,6 @@ const char *mmc_mode_name(enum bus_mode mode)
|
|||||||
{
|
{
|
||||||
static const char *const names[] = {
|
static const char *const names[] = {
|
||||||
[MMC_LEGACY] = "MMC legacy",
|
[MMC_LEGACY] = "MMC legacy",
|
||||||
[SD_LEGACY] = "SD Legacy",
|
|
||||||
[MMC_HS] = "MMC High Speed (26MHz)",
|
[MMC_HS] = "MMC High Speed (26MHz)",
|
||||||
[SD_HS] = "SD High Speed (50MHz)",
|
[SD_HS] = "SD High Speed (50MHz)",
|
||||||
[UHS_SDR12] = "UHS SDR12 (25MHz)",
|
[UHS_SDR12] = "UHS SDR12 (25MHz)",
|
||||||
@ -158,7 +157,6 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
|
|||||||
{
|
{
|
||||||
static const int freqs[] = {
|
static const int freqs[] = {
|
||||||
[MMC_LEGACY] = 25000000,
|
[MMC_LEGACY] = 25000000,
|
||||||
[SD_LEGACY] = 25000000,
|
|
||||||
[MMC_HS] = 26000000,
|
[MMC_HS] = 26000000,
|
||||||
[SD_HS] = 50000000,
|
[SD_HS] = 50000000,
|
||||||
[MMC_HS_52] = 52000000,
|
[MMC_HS_52] = 52000000,
|
||||||
@ -1239,7 +1237,7 @@ static int sd_get_capabilities(struct mmc *mmc)
|
|||||||
u32 sd3_bus_mode;
|
u32 sd3_bus_mode;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
|
mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
|
||||||
|
|
||||||
if (mmc_host_is_spi(mmc))
|
if (mmc_host_is_spi(mmc))
|
||||||
return 0;
|
return 0;
|
||||||
@ -1352,7 +1350,7 @@ static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SD_LEGACY:
|
case MMC_LEGACY:
|
||||||
speed = UHS_SDR12_BUS_SPEED;
|
speed = UHS_SDR12_BUS_SPEED;
|
||||||
break;
|
break;
|
||||||
case SD_HS:
|
case SD_HS:
|
||||||
@ -1695,7 +1693,7 @@ static const struct mode_width_tuning sd_modes_by_pref[] = {
|
|||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
.mode = SD_LEGACY,
|
.mode = MMC_LEGACY,
|
||||||
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
|
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1725,7 +1723,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
|
|||||||
|
|
||||||
if (mmc_host_is_spi(mmc)) {
|
if (mmc_host_is_spi(mmc)) {
|
||||||
mmc_set_bus_width(mmc, 1);
|
mmc_set_bus_width(mmc, 1);
|
||||||
mmc_select_mode(mmc, SD_LEGACY);
|
mmc_select_mode(mmc, MMC_LEGACY);
|
||||||
mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
|
mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1784,7 +1782,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
/* revert to a safer bus speed */
|
/* revert to a safer bus speed */
|
||||||
mmc_select_mode(mmc, SD_LEGACY);
|
mmc_select_mode(mmc, MMC_LEGACY);
|
||||||
mmc_set_clock(mmc, mmc->tran_speed,
|
mmc_set_clock(mmc, mmc->tran_speed,
|
||||||
MMC_CLK_ENABLE);
|
MMC_CLK_ENABLE);
|
||||||
}
|
}
|
||||||
@ -2561,7 +2559,7 @@ static int mmc_startup(struct mmc *mmc)
|
|||||||
|
|
||||||
#if CONFIG_IS_ENABLED(MMC_TINY)
|
#if CONFIG_IS_ENABLED(MMC_TINY)
|
||||||
mmc_set_clock(mmc, mmc->legacy_speed, false);
|
mmc_set_clock(mmc, mmc->legacy_speed, false);
|
||||||
mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
|
mmc_select_mode(mmc, MMC_LEGACY);
|
||||||
mmc_set_bus_width(mmc, 1);
|
mmc_set_bus_width(mmc, 1);
|
||||||
#else
|
#else
|
||||||
if (IS_SD(mmc)) {
|
if (IS_SD(mmc)) {
|
||||||
@ -2843,9 +2841,11 @@ int mmc_start_init(struct mmc *mmc)
|
|||||||
* all hosts are capable of 1 bit bus-width and able to use the legacy
|
* all hosts are capable of 1 bit bus-width and able to use the legacy
|
||||||
* timings.
|
* timings.
|
||||||
*/
|
*/
|
||||||
mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
|
mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(MMC_LEGACY) |
|
||||||
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
|
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
|
||||||
|
#if CONFIG_IS_ENABLED(DM_MMC)
|
||||||
|
mmc_deferred_probe(mmc);
|
||||||
|
#endif
|
||||||
#if !defined(CONFIG_MMC_BROKEN_CD)
|
#if !defined(CONFIG_MMC_BROKEN_CD)
|
||||||
no_card = mmc_getcd(mmc) == 0;
|
no_card = mmc_getcd(mmc) == 0;
|
||||||
#else
|
#else
|
||||||
|
@ -392,7 +392,6 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
|
|||||||
break;
|
break;
|
||||||
case MMC_LEGACY:
|
case MMC_LEGACY:
|
||||||
case MMC_HS:
|
case MMC_HS:
|
||||||
case SD_LEGACY:
|
|
||||||
case UHS_SDR12:
|
case UHS_SDR12:
|
||||||
val |= AC12_UHSMC_SDR12;
|
val |= AC12_UHSMC_SDR12;
|
||||||
break;
|
break;
|
||||||
|
@ -658,6 +658,20 @@ int sdhci_probe(struct udevice *dev)
|
|||||||
return sdhci_init(mmc);
|
return sdhci_init(mmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sdhci_deferred_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||||
|
struct sdhci_host *host = mmc->priv;
|
||||||
|
|
||||||
|
if (host->ops && host->ops->deferred_probe) {
|
||||||
|
err = host->ops->deferred_probe(host);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sdhci_get_cd(struct udevice *dev)
|
static int sdhci_get_cd(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||||
@ -692,6 +706,7 @@ const struct dm_mmc_ops sdhci_ops = {
|
|||||||
.send_cmd = sdhci_send_command,
|
.send_cmd = sdhci_send_command,
|
||||||
.set_ios = sdhci_set_ios,
|
.set_ios = sdhci_set_ios,
|
||||||
.get_cd = sdhci_get_cd,
|
.get_cd = sdhci_get_cd,
|
||||||
|
.deferred_probe = sdhci_deferred_probe,
|
||||||
#ifdef MMC_SUPPORTS_TUNING
|
#ifdef MMC_SUPPORTS_TUNING
|
||||||
.execute_tuning = sdhci_execute_tuning,
|
.execute_tuning = sdhci_execute_tuning,
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,7 +37,6 @@ struct arasan_sdhci_priv {
|
|||||||
|
|
||||||
static const u8 mode2timing[] = {
|
static const u8 mode2timing[] = {
|
||||||
[MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
|
[MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
|
||||||
[SD_LEGACY] = UHS_SDR12_BUS_SPEED,
|
|
||||||
[MMC_HS] = HIGH_SPEED_BUS_SPEED,
|
[MMC_HS] = HIGH_SPEED_BUS_SPEED,
|
||||||
[SD_HS] = HIGH_SPEED_BUS_SPEED,
|
[SD_HS] = HIGH_SPEED_BUS_SPEED,
|
||||||
[MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
|
[MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
|
||||||
|
@ -127,8 +127,6 @@
|
|||||||
#define CONFIG_SYS_MMC_ENV_PART 1
|
#define CONFIG_SYS_MMC_ENV_PART 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_SUPPORT_EMMC_BOOT
|
|
||||||
|
|
||||||
/* Now for the remaining common defines */
|
/* Now for the remaining common defines */
|
||||||
#include <configs/ti_armv7_common.h>
|
#include <configs/ti_armv7_common.h>
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include <linux/dma-direction.h>
|
#include <linux/dma-direction.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
|
|
||||||
|
struct bd_info;
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
|
#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
|
||||||
#define MMC_SUPPORTS_TUNING
|
#define MMC_SUPPORTS_TUNING
|
||||||
#endif
|
#endif
|
||||||
@ -407,6 +409,14 @@ struct mmc;
|
|||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM_MMC)
|
#if CONFIG_IS_ENABLED(DM_MMC)
|
||||||
struct dm_mmc_ops {
|
struct dm_mmc_ops {
|
||||||
|
/**
|
||||||
|
* deferred_probe() - Some configurations that need to be deferred
|
||||||
|
* to just before enumerating the device
|
||||||
|
*
|
||||||
|
* @dev: Device to init
|
||||||
|
* @return 0 if Ok, -ve if error
|
||||||
|
*/
|
||||||
|
int (*deferred_probe)(struct udevice *dev);
|
||||||
/**
|
/**
|
||||||
* send_cmd() - Send a command to the MMC device
|
* send_cmd() - Send a command to the MMC device
|
||||||
*
|
*
|
||||||
@ -490,6 +500,7 @@ int dm_mmc_get_wp(struct udevice *dev);
|
|||||||
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
|
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
|
||||||
int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us);
|
int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us);
|
||||||
int dm_mmc_host_power_cycle(struct udevice *dev);
|
int dm_mmc_host_power_cycle(struct udevice *dev);
|
||||||
|
int dm_mmc_deferred_probe(struct udevice *dev);
|
||||||
|
|
||||||
/* Transition functions for compatibility */
|
/* Transition functions for compatibility */
|
||||||
int mmc_set_ios(struct mmc *mmc);
|
int mmc_set_ios(struct mmc *mmc);
|
||||||
@ -499,6 +510,7 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode);
|
|||||||
int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us);
|
int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us);
|
||||||
int mmc_set_enhanced_strobe(struct mmc *mmc);
|
int mmc_set_enhanced_strobe(struct mmc *mmc);
|
||||||
int mmc_host_power_cycle(struct mmc *mmc);
|
int mmc_host_power_cycle(struct mmc *mmc);
|
||||||
|
int mmc_deferred_probe(struct mmc *mmc);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct mmc_ops {
|
struct mmc_ops {
|
||||||
@ -533,7 +545,6 @@ struct sd_ssr {
|
|||||||
|
|
||||||
enum bus_mode {
|
enum bus_mode {
|
||||||
MMC_LEGACY,
|
MMC_LEGACY,
|
||||||
SD_LEGACY,
|
|
||||||
MMC_HS,
|
MMC_HS,
|
||||||
SD_HS,
|
SD_HS,
|
||||||
MMC_HS_52,
|
MMC_HS_52,
|
||||||
@ -603,6 +614,7 @@ struct mmc {
|
|||||||
bool clk_disable; /* true if the clock can be turned off */
|
bool clk_disable; /* true if the clock can be turned off */
|
||||||
uint bus_width;
|
uint bus_width;
|
||||||
uint clock;
|
uint clock;
|
||||||
|
uint saved_clock;
|
||||||
enum mmc_voltage signal_voltage;
|
enum mmc_voltage signal_voltage;
|
||||||
uint card_caps;
|
uint card_caps;
|
||||||
uint host_caps;
|
uint host_caps;
|
||||||
@ -712,7 +724,7 @@ void mmc_destroy(struct mmc *mmc);
|
|||||||
* @return 0 if OK, -ve on error
|
* @return 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int mmc_unbind(struct udevice *dev);
|
int mmc_unbind(struct udevice *dev);
|
||||||
int mmc_initialize(bd_t *bis);
|
int mmc_initialize(struct bd_info *bis);
|
||||||
int mmc_init_device(int num);
|
int mmc_init_device(int num);
|
||||||
int mmc_init(struct mmc *mmc);
|
int mmc_init(struct mmc *mmc);
|
||||||
int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
|
int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
|
||||||
@ -857,8 +869,8 @@ void mmc_set_preinit(struct mmc *mmc, int preinit);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void board_mmc_power_init(void);
|
void board_mmc_power_init(void);
|
||||||
int board_mmc_init(bd_t *bis);
|
int board_mmc_init(struct bd_info *bis);
|
||||||
int cpu_mmc_init(bd_t *bis);
|
int cpu_mmc_init(struct bd_info *bis);
|
||||||
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
|
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
|
||||||
# ifdef CONFIG_SYS_MMC_ENV_PART
|
# ifdef CONFIG_SYS_MMC_ENV_PART
|
||||||
extern uint mmc_get_env_part(struct mmc *mmc);
|
extern uint mmc_get_env_part(struct mmc *mmc);
|
||||||
|
@ -268,6 +268,7 @@ struct sdhci_ops {
|
|||||||
void (*set_clock)(struct sdhci_host *host, u32 div);
|
void (*set_clock)(struct sdhci_host *host, u32 div);
|
||||||
int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
|
int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
|
||||||
void (*set_delay)(struct sdhci_host *host);
|
void (*set_delay)(struct sdhci_host *host);
|
||||||
|
int (*deferred_probe)(struct sdhci_host *host);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
|
#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
|
||||||
|
Loading…
Reference in New Issue
Block a user