Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
cf4128e5
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cf4128e5
编写于
1月 26, 2017
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://www.denx.de/git/u-boot-marvell
上级
f59f07ec
e559ef1a
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
624 addition
and
10 deletion
+624
-10
arch/arm/dts/armada-3720-db.dts
arch/arm/dts/armada-3720-db.dts
+21
-0
arch/arm/dts/armada-37xx.dtsi
arch/arm/dts/armada-37xx.dtsi
+16
-0
arch/arm/dts/armada-7040-db.dts
arch/arm/dts/armada-7040-db.dts
+14
-0
arch/arm/dts/armada-ap806.dtsi
arch/arm/dts/armada-ap806.dtsi
+8
-0
arch/arm/dts/armada-cp110-master.dtsi
arch/arm/dts/armada-cp110-master.dtsi
+8
-0
cmd/mvebu/bubt.c
cmd/mvebu/bubt.c
+22
-3
configs/mvebu_db-88f3720_defconfig
configs/mvebu_db-88f3720_defconfig
+5
-1
configs/mvebu_db-88f7040_defconfig
configs/mvebu_db-88f7040_defconfig
+4
-1
configs/mvebu_db-88f8040_defconfig
configs/mvebu_db-88f8040_defconfig
+4
-1
drivers/mmc/Kconfig
drivers/mmc/Kconfig
+11
-0
drivers/mmc/Makefile
drivers/mmc/Makefile
+1
-0
drivers/mmc/sdhci.c
drivers/mmc/sdhci.c
+6
-4
drivers/mmc/xenon_sdhci.c
drivers/mmc/xenon_sdhci.c
+497
-0
include/configs/mvebu_armada-8k.h
include/configs/mvebu_armada-8k.h
+3
-0
include/configs/mvebu_db-88f3720.h
include/configs/mvebu_db-88f3720.h
+3
-0
include/sdhci.h
include/sdhci.h
+1
-0
未找到文件。
arch/arm/dts/armada-3720-db.dts
浏览文件 @
cf4128e5
...
...
@@ -94,6 +94,27 @@
status
=
"okay"
;
};
&
sdhci0
{
bus
-
width
=
<
4
>;
status
=
"okay"
;
};
&
sdhci1
{
non
-
removable
;
bus
-
width
=
<
8
>;
mmc
-
ddr
-
1
_8v
;
mmc
-
hs400
-
1
_8v
;
marvell
,
pad
-
type
=
"fixed-1-8v"
;
status
=
"okay"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
0
>;
mmccard
:
mmccard
@
0
{
compatible
=
"mmc-card"
;
reg
=
<
0
>;
};
};
&
spi0
{
status
=
"okay"
;
...
...
arch/arm/dts/armada-37xx.dtsi
浏览文件 @
cf4128e5
...
...
@@ -133,6 +133,22 @@
};
};
sdhci0
:
sdhci
@
d0000
{
compatible
=
"marvell,armada-3700-sdhci"
,
"marvell,sdhci-xenon"
;
reg
=
<
0xd0000
0x300
0x1e808
0x4
>;
status
=
"disabled"
;
};
sdhci1
:
sdhci
@
d8000
{
compatible
=
"marvell,armada-3700-sdhci"
,
"marvell,sdhci-xenon"
;
reg
=
<
0xd8000
0x300
0x17808
0x4
>;
status
=
"disabled"
;
};
sata
:
sata
@
e0000
{
compatible
=
"marvell,armada-3700-ahci"
;
reg
=
<
0xe0000
0x2000
>;
...
...
arch/arm/dts/armada-7040-db.dts
浏览文件 @
cf4128e5
...
...
@@ -195,3 +195,17 @@
&
cpm_utmi1
{
status
=
"okay"
;
};
&
ap_sdhci0
{
status
=
"okay"
;
bus
-
width
=
<
4
>;
no
-
1
-
8
-
v
;
non
-
removable
;
};
&
cpm_sdhci0
{
status
=
"okay"
;
bus
-
width
=
<
4
>;
no
-
1
-
8
-
v
;
non
-
removable
;
};
arch/arm/dts/armada-ap806.dtsi
浏览文件 @
cf4128e5
...
...
@@ -234,6 +234,14 @@
};
ap_sdhci0
:
sdhci
@
6e0000
{
compatible
=
"marvell,armada-8k-sdhci"
;
reg
=
<
0x6e0000
0x300
>;
interrupts
=
<
GIC_SPI
16
IRQ_TYPE_LEVEL_HIGH
>;
dma
-
coherent
;
status
=
"disabled"
;
};
ap_syscon
:
system
-
controller
@
6f4000
{
compatible
=
"marvell,ap806-system-controller"
,
"syscon"
;
...
...
arch/arm/dts/armada-cp110-master.dtsi
浏览文件 @
cf4128e5
...
...
@@ -206,6 +206,14 @@
utmi-port = <UTMI_PHY_TO_USB_HOST1>;
status = "disabled";
};
cpm_sdhci0: sdhci@780000 {
compatible = "marvell,armada-8k-sdhci";
reg = <0x780000 0x300>;
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
dma-coherent;
status = "disabled";
};
};
cpm_pcie0: pcie@f2600000 {
...
...
cmd/mvebu/bubt.c
浏览文件 @
cf4128e5
...
...
@@ -18,6 +18,9 @@
#include <usb.h>
#include <fs.h>
#include <mmc.h>
#ifdef CONFIG_BLK
#include <blk.h>
#endif
#include <u-boot/sha1.h>
#include <u-boot/sha256.h>
...
...
@@ -116,7 +119,9 @@ static int mmc_burn_image(size_t image_size)
ulong
blk_written
;
int
err
;
const
u8
mmc_dev_num
=
CONFIG_SYS_MMC_ENV_DEV
;
#ifdef CONFIG_BLK
struct
blk_desc
*
blk_desc
;
#endif
mmc
=
find_mmc_device
(
mmc_dev_num
);
if
(
!
mmc
)
{
printf
(
"No SD/MMC/eMMC card found
\n
"
);
...
...
@@ -144,13 +149,27 @@ static int mmc_burn_image(size_t image_size)
* MMC/eMMC boots from LBA-0
*/
start_lba
=
IS_SD
(
mmc
)
?
1
:
0
;
#ifdef CONFIG_BLK
blk_count
=
image_size
/
mmc
->
write_bl_len
;
if
(
image_size
%
mmc
->
write_bl_len
)
blk_count
+=
1
;
blk_desc
=
mmc_get_blk_desc
(
mmc
);
if
(
!
blk_desc
)
{
printf
(
"Error - failed to obtain block descriptor
\n
"
);
return
-
ENODEV
;
}
blk_written
=
blk_dwrite
(
blk_desc
,
start_lba
,
blk_count
,
(
void
*
)
get_load_addr
());
#else
blk_count
=
image_size
/
mmc
->
block_dev
.
blksz
;
if
(
image_size
%
mmc
->
block_dev
.
blksz
)
blk_count
+=
1
;
blk_written
=
mmc
->
block_dev
.
block_write
(
mmc_dev_num
,
start_lba
,
blk_count
,
(
void
*
)
get_load_addr
());
start_lba
,
blk_count
,
(
void
*
)
get_load_addr
());
#endif
/* CONFIG_BLK */
if
(
blk_written
!=
blk_count
)
{
printf
(
"Error - written %#lx blocks
\n
"
,
blk_written
);
return
-
ENOSPC
;
...
...
configs/mvebu_db-88f3720_defconfig
浏览文件 @
cf4128e5
...
...
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MVEBU=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_TARGET_MVEBU_DB_88F3720=y
# CONFIG_MMC is not set
CONFIG_DEFAULT_DEVICE_TREE="armada-3720-db"
CONFIG_AHCI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
...
...
@@ -13,6 +12,7 @@ CONFIG_ARCH_EARLY_INIT_R=y
CONFIG_BOARD_EARLY_INIT_F=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
...
...
@@ -33,6 +33,10 @@ CONFIG_BLOCK_CACHE=y
CONFIG_DM_I2C=y
CONFIG_DM_I2C_COMPAT=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
...
...
configs/mvebu_db-88f7040_defconfig
浏览文件 @
cf4128e5
...
...
@@ -14,6 +14,7 @@ CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
...
...
@@ -35,7 +36,9 @@ CONFIG_BLOCK_CACHE=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_MISC=y
# CONFIG_MMC is not set
CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
...
...
configs/mvebu_db-88f8040_defconfig
浏览文件 @
cf4128e5
...
...
@@ -14,6 +14,7 @@ CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
...
...
@@ -35,7 +36,9 @@ CONFIG_BLOCK_CACHE=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_MISC=y
# CONFIG_MMC is not set
CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_XENON=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
...
...
drivers/mmc/Kconfig
浏览文件 @
cf4128e5
...
...
@@ -287,6 +287,17 @@ config MMC_SDHCI_SPEAR
If unsure, say N.
config MMC_SDHCI_XENON
bool "SDHCI support for the Xenon SDHCI controller"
depends on MMC_SDHCI && DM_MMC && OF_CONTROL
help
Support for Xenon SDHCI host controller on Marvell Armada 3700
7k/8k ARM SoCs platforms
If you have a controller with this interface, say Y here.
If unsure, say N.
config MMC_SDHCI_TEGRA
bool "SDHCI platform support for the Tegra SD/MMC Controller"
depends on TEGRA
...
...
drivers/mmc/Makefile
浏览文件 @
cf4128e5
...
...
@@ -68,6 +68,7 @@ obj-$(CONFIG_MMC_SDHCI_MV) += mv_sdhci.o
obj-$(CONFIG_MMC_SDHCI_S5P)
+=
s5p_sdhci.o
obj-$(CONFIG_MMC_SDHCI_SPEAR)
+=
spear_sdhci.o
obj-$(CONFIG_MMC_SDHCI_TEGRA)
+=
tegra_mmc.o
obj-$(CONFIG_MMC_SDHCI_XENON)
+=
xenon_sdhci.o
obj-$(CONFIG_MMC_SUNXI)
+=
sunxi_mmc.o
obj-$(CONFIG_MMC_UNIPHIER)
+=
uniphier-sd.o
drivers/mmc/sdhci.c
浏览文件 @
cf4128e5
...
...
@@ -295,7 +295,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
static
int
sdhci_set_clock
(
struct
mmc
*
mmc
,
unsigned
int
clock
)
{
struct
sdhci_host
*
host
=
mmc
->
priv
;
unsigned
int
div
,
clk
=
0
,
timeout
,
reg
;
unsigned
int
div
,
clk
=
0
,
timeout
;
/* Wait max 20 ms */
timeout
=
200
;
...
...
@@ -311,9 +311,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
udelay
(
100
);
}
reg
=
sdhci_readw
(
host
,
SDHCI_CLOCK_CONTROL
);
reg
&=
~
(
SDHCI_CLOCK_CARD_EN
|
SDHCI_CLOCK_INT_EN
);
sdhci_writew
(
host
,
reg
,
SDHCI_CLOCK_CONTROL
);
sdhci_writew
(
host
,
0
,
SDHCI_CLOCK_CONTROL
);
if
(
clock
==
0
)
return
0
;
...
...
@@ -460,6 +458,10 @@ static int sdhci_set_ios(struct mmc *mmc)
sdhci_writeb
(
host
,
ctrl
,
SDHCI_HOST_CONTROL
);
/* If available, call the driver specific "post" set_ios() function */
if
(
host
->
ops
&&
host
->
ops
->
set_ios_post
)
host
->
ops
->
set_ios_post
(
host
);
return
0
;
}
...
...
drivers/mmc/xenon_sdhci.c
0 → 100644
浏览文件 @
cf4128e5
/*
* Driver for Marvell SOC Platform Group Xenon SDHC as a platform device
*
* Copyright (C) 2016 Marvell, All Rights Reserved.
*
* Author: Victor Gu <xigu@marvell.com>
* Date: 2016-8-24
*
* Included parts of the Linux driver version which was written by:
* Hu Ziji <huziji@marvell.com>
*
* Ported to from Marvell 2015.01 to mainline U-Boot 2017.01:
* Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <sdhci.h>
DECLARE_GLOBAL_DATA_PTR
;
/* Register Offset of SD Host Controller SOCP self-defined register */
#define SDHC_SYS_CFG_INFO 0x0104
#define SLOT_TYPE_SDIO_SHIFT 24
#define SLOT_TYPE_EMMC_MASK 0xFF
#define SLOT_TYPE_EMMC_SHIFT 16
#define SLOT_TYPE_SD_SDIO_MMC_MASK 0xFF
#define SLOT_TYPE_SD_SDIO_MMC_SHIFT 8
#define NR_SUPPORTED_SLOT_MASK 0x7
#define SDHC_SYS_OP_CTRL 0x0108
#define AUTO_CLKGATE_DISABLE_MASK BIT(20)
#define SDCLK_IDLEOFF_ENABLE_SHIFT 8
#define SLOT_ENABLE_SHIFT 0
#define SDHC_SYS_EXT_OP_CTRL 0x010C
#define MASK_CMD_CONFLICT_ERROR BIT(8)
#define SDHC_SLOT_RETUNING_REQ_CTRL 0x0144
/* retuning compatible */
#define RETUNING_COMPATIBLE 0x1
/* Xenon specific Mode Select value */
#define XENON_SDHCI_CTRL_HS200 0x5
#define XENON_SDHCI_CTRL_HS400 0x6
#define EMMC_PHY_REG_BASE 0x170
#define EMMC_PHY_TIMING_ADJUST EMMC_PHY_REG_BASE
#define OUTPUT_QSN_PHASE_SELECT BIT(17)
#define SAMPL_INV_QSP_PHASE_SELECT BIT(18)
#define SAMPL_INV_QSP_PHASE_SELECT_SHIFT 18
#define EMMC_PHY_SLOW_MODE BIT(29)
#define PHY_INITIALIZAION BIT(31)
#define WAIT_CYCLE_BEFORE_USING_MASK 0xf
#define WAIT_CYCLE_BEFORE_USING_SHIFT 12
#define FC_SYNC_EN_DURATION_MASK 0xf
#define FC_SYNC_EN_DURATION_SHIFT 8
#define FC_SYNC_RST_EN_DURATION_MASK 0xf
#define FC_SYNC_RST_EN_DURATION_SHIFT 4
#define FC_SYNC_RST_DURATION_MASK 0xf
#define FC_SYNC_RST_DURATION_SHIFT 0
#define EMMC_PHY_FUNC_CONTROL (EMMC_PHY_REG_BASE + 0x4)
#define DQ_ASYNC_MODE BIT(4)
#define DQ_DDR_MODE_SHIFT 8
#define DQ_DDR_MODE_MASK 0xff
#define CMD_DDR_MODE BIT(16)
#define EMMC_PHY_PAD_CONTROL (EMMC_PHY_REG_BASE + 0x8)
#define REC_EN_SHIFT 24
#define REC_EN_MASK 0xf
#define FC_DQ_RECEN BIT(24)
#define FC_CMD_RECEN BIT(25)
#define FC_QSP_RECEN BIT(26)
#define FC_QSN_RECEN BIT(27)
#define OEN_QSN BIT(28)
#define AUTO_RECEN_CTRL BIT(30)
#define EMMC_PHY_PAD_CONTROL1 (EMMC_PHY_REG_BASE + 0xc)
#define EMMC5_1_FC_QSP_PD BIT(9)
#define EMMC5_1_FC_QSP_PU BIT(25)
#define EMMC5_1_FC_CMD_PD BIT(8)
#define EMMC5_1_FC_CMD_PU BIT(24)
#define EMMC5_1_FC_DQ_PD 0xff
#define EMMC5_1_FC_DQ_PU (0xff << 16)
#define SDHCI_RETUNE_EVT_INTSIG 0x00001000
/* Hyperion only have one slot 0 */
#define XENON_MMC_SLOT_ID_HYPERION 0
#define MMC_TIMING_LEGACY 0
#define MMC_TIMING_MMC_HS 1
#define MMC_TIMING_SD_HS 2
#define MMC_TIMING_UHS_SDR12 3
#define MMC_TIMING_UHS_SDR25 4
#define MMC_TIMING_UHS_SDR50 5
#define MMC_TIMING_UHS_SDR104 6
#define MMC_TIMING_UHS_DDR50 7
#define MMC_TIMING_MMC_DDR52 8
#define MMC_TIMING_MMC_HS200 9
#define MMC_TIMING_MMC_HS400 10
#define XENON_MMC_MAX_CLK 400000000
enum
soc_pad_ctrl_type
{
SOC_PAD_SD
,
SOC_PAD_FIXED_1_8V
,
};
struct
xenon_sdhci_plat
{
struct
mmc_config
cfg
;
struct
mmc
mmc
;
};
struct
xenon_sdhci_priv
{
struct
sdhci_host
host
;
u8
timing
;
unsigned
int
clock
;
void
*
pad_ctrl_reg
;
int
pad_type
;
};
static
int
xenon_mmc_phy_init
(
struct
sdhci_host
*
host
)
{
struct
xenon_sdhci_priv
*
priv
=
host
->
mmc
->
priv
;
u32
clock
=
priv
->
clock
;
u32
time
;
u32
var
;
/* Enable QSP PHASE SELECT */
var
=
sdhci_readl
(
host
,
EMMC_PHY_TIMING_ADJUST
);
var
|=
SAMPL_INV_QSP_PHASE_SELECT
;
if
((
priv
->
timing
==
MMC_TIMING_UHS_SDR50
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_SDR25
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_SDR12
)
||
(
priv
->
timing
==
MMC_TIMING_SD_HS
)
||
(
priv
->
timing
==
MMC_TIMING_LEGACY
))
var
|=
EMMC_PHY_SLOW_MODE
;
sdhci_writel
(
host
,
var
,
EMMC_PHY_TIMING_ADJUST
);
/* Poll for host MMC PHY clock init to be stable */
/* Wait up to 10ms */
time
=
100
;
while
(
time
--
)
{
var
=
sdhci_readl
(
host
,
SDHCI_CLOCK_CONTROL
);
if
(
var
&
SDHCI_CLOCK_INT_STABLE
)
break
;
udelay
(
100
);
}
if
(
time
<=
0
)
{
error
(
"Failed to enable MMC internal clock in time
\n
"
);
return
-
ETIMEDOUT
;
}
/* Init PHY */
var
=
sdhci_readl
(
host
,
EMMC_PHY_TIMING_ADJUST
);
var
|=
PHY_INITIALIZAION
;
sdhci_writel
(
host
,
var
,
EMMC_PHY_TIMING_ADJUST
);
if
(
clock
==
0
)
{
/* Use the possibly slowest bus frequency value */
clock
=
100000
;
}
/* Poll for host eMMC PHY init to complete */
/* Wait up to 10ms */
time
=
100
;
while
(
time
--
)
{
var
=
sdhci_readl
(
host
,
EMMC_PHY_TIMING_ADJUST
);
var
&=
PHY_INITIALIZAION
;
if
(
!
var
)
break
;
/* wait for host eMMC PHY init to complete */
udelay
(
100
);
}
if
(
time
<=
0
)
{
error
(
"Failed to init MMC PHY in time
\n
"
);
return
-
ETIMEDOUT
;
}
return
0
;
}
#define ARMADA_3700_SOC_PAD_1_8V 0x1
#define ARMADA_3700_SOC_PAD_3_3V 0x0
static
void
armada_3700_soc_pad_voltage_set
(
struct
sdhci_host
*
host
)
{
struct
xenon_sdhci_priv
*
priv
=
host
->
mmc
->
priv
;
if
(
priv
->
pad_type
==
SOC_PAD_FIXED_1_8V
)
writel
(
ARMADA_3700_SOC_PAD_1_8V
,
priv
->
pad_ctrl_reg
);
else
if
(
priv
->
pad_type
==
SOC_PAD_SD
)
writel
(
ARMADA_3700_SOC_PAD_3_3V
,
priv
->
pad_ctrl_reg
);
}
static
void
xenon_mmc_phy_set
(
struct
sdhci_host
*
host
)
{
struct
xenon_sdhci_priv
*
priv
=
host
->
mmc
->
priv
;
u32
var
;
/* Setup pad, set bit[30], bit[28] and bits[26:24] */
var
=
sdhci_readl
(
host
,
EMMC_PHY_PAD_CONTROL
);
var
|=
AUTO_RECEN_CTRL
|
OEN_QSN
|
FC_QSP_RECEN
|
FC_CMD_RECEN
|
FC_DQ_RECEN
;
sdhci_writel
(
host
,
var
,
EMMC_PHY_PAD_CONTROL
);
/* Set CMD and DQ Pull Up */
var
=
sdhci_readl
(
host
,
EMMC_PHY_PAD_CONTROL1
);
var
|=
(
EMMC5_1_FC_CMD_PU
|
EMMC5_1_FC_DQ_PU
);
var
&=
~
(
EMMC5_1_FC_CMD_PD
|
EMMC5_1_FC_DQ_PD
);
sdhci_writel
(
host
,
var
,
EMMC_PHY_PAD_CONTROL1
);
/*
* If timing belongs to high speed, set bit[17] of
* EMMC_PHY_TIMING_ADJUST register
*/
if
((
priv
->
timing
==
MMC_TIMING_MMC_HS400
)
||
(
priv
->
timing
==
MMC_TIMING_MMC_HS200
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_SDR50
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_SDR104
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_DDR50
)
||
(
priv
->
timing
==
MMC_TIMING_UHS_SDR25
)
||
(
priv
->
timing
==
MMC_TIMING_MMC_DDR52
))
{
var
=
sdhci_readl
(
host
,
EMMC_PHY_TIMING_ADJUST
);
var
|=
OUTPUT_QSN_PHASE_SELECT
;
sdhci_writel
(
host
,
var
,
EMMC_PHY_TIMING_ADJUST
);
}
/*
* When setting EMMC_PHY_FUNC_CONTROL register,
* SD clock should be disabled
*/
var
=
sdhci_readl
(
host
,
SDHCI_CLOCK_CONTROL
);
var
&=
~
SDHCI_CLOCK_CARD_EN
;
sdhci_writew
(
host
,
var
,
SDHCI_CLOCK_CONTROL
);
var
=
sdhci_readl
(
host
,
EMMC_PHY_FUNC_CONTROL
);
if
(
host
->
mmc
->
ddr_mode
)
{
var
|=
(
DQ_DDR_MODE_MASK
<<
DQ_DDR_MODE_SHIFT
)
|
CMD_DDR_MODE
;
}
else
{
var
&=
~
((
DQ_DDR_MODE_MASK
<<
DQ_DDR_MODE_SHIFT
)
|
CMD_DDR_MODE
);
}
sdhci_writel
(
host
,
var
,
EMMC_PHY_FUNC_CONTROL
);
/* Enable bus clock */
var
=
sdhci_readl
(
host
,
SDHCI_CLOCK_CONTROL
);
var
|=
SDHCI_CLOCK_CARD_EN
;
sdhci_writew
(
host
,
var
,
SDHCI_CLOCK_CONTROL
);
xenon_mmc_phy_init
(
host
);
}
/* Enable/Disable the Auto Clock Gating function of this slot */
static
void
xenon_mmc_set_acg
(
struct
sdhci_host
*
host
,
bool
enable
)
{
u32
var
;
var
=
sdhci_readl
(
host
,
SDHC_SYS_OP_CTRL
);
if
(
enable
)
var
&=
~
AUTO_CLKGATE_DISABLE_MASK
;
else
var
|=
AUTO_CLKGATE_DISABLE_MASK
;
sdhci_writel
(
host
,
var
,
SDHC_SYS_OP_CTRL
);
}
#define SLOT_MASK(slot) BIT(slot)
/* Enable specific slot */
static
void
xenon_mmc_enable_slot
(
struct
sdhci_host
*
host
,
u8
slot
)
{
u32
var
;
var
=
sdhci_readl
(
host
,
SDHC_SYS_OP_CTRL
);
var
|=
SLOT_MASK
(
slot
)
<<
SLOT_ENABLE_SHIFT
;
sdhci_writel
(
host
,
var
,
SDHC_SYS_OP_CTRL
);
}
/* Enable Parallel Transfer Mode */
static
void
xenon_mmc_enable_parallel_tran
(
struct
sdhci_host
*
host
,
u8
slot
)
{
u32
var
;
var
=
sdhci_readl
(
host
,
SDHC_SYS_EXT_OP_CTRL
);
var
|=
SLOT_MASK
(
slot
);
sdhci_writel
(
host
,
var
,
SDHC_SYS_EXT_OP_CTRL
);
}
static
void
xenon_mmc_disable_tuning
(
struct
sdhci_host
*
host
,
u8
slot
)
{
u32
var
;
/* Clear the Re-Tuning Request functionality */
var
=
sdhci_readl
(
host
,
SDHC_SLOT_RETUNING_REQ_CTRL
);
var
&=
~
RETUNING_COMPATIBLE
;
sdhci_writel
(
host
,
var
,
SDHC_SLOT_RETUNING_REQ_CTRL
);
/* Clear the Re-tuning Event Signal Enable */
var
=
sdhci_readl
(
host
,
SDHCI_SIGNAL_ENABLE
);
var
&=
~
SDHCI_RETUNE_EVT_INTSIG
;
sdhci_writel
(
host
,
var
,
SDHCI_SIGNAL_ENABLE
);
}
/* Mask command conflict error */
static
void
xenon_mask_cmd_conflict_err
(
struct
sdhci_host
*
host
)
{
u32
reg
;
reg
=
sdhci_readl
(
host
,
SDHC_SYS_EXT_OP_CTRL
);
reg
|=
MASK_CMD_CONFLICT_ERROR
;
sdhci_writel
(
host
,
reg
,
SDHC_SYS_EXT_OP_CTRL
);
}
/* Platform specific function for post set_ios configuration */
static
void
xenon_sdhci_set_ios_post
(
struct
sdhci_host
*
host
)
{
struct
xenon_sdhci_priv
*
priv
=
host
->
mmc
->
priv
;
uint
speed
=
host
->
mmc
->
tran_speed
;
int
pwr_18v
=
0
;
if
((
sdhci_readb
(
host
,
SDHCI_POWER_CONTROL
)
&
~
SDHCI_POWER_ON
)
==
SDHCI_POWER_180
)
pwr_18v
=
1
;
/* Set timing variable according to the configured speed */
if
(
IS_SD
(
host
->
mmc
))
{
/* SD/SDIO */
if
(
pwr_18v
)
{
if
(
host
->
mmc
->
ddr_mode
)
priv
->
timing
=
MMC_TIMING_UHS_DDR50
;
else
if
(
speed
<=
25000000
)
priv
->
timing
=
MMC_TIMING_UHS_SDR25
;
else
priv
->
timing
=
MMC_TIMING_UHS_SDR50
;
}
else
{
if
(
speed
<=
25000000
)
priv
->
timing
=
MMC_TIMING_LEGACY
;
else
priv
->
timing
=
MMC_TIMING_SD_HS
;
}
}
else
{
/* eMMC */
if
(
host
->
mmc
->
ddr_mode
)
priv
->
timing
=
MMC_TIMING_MMC_DDR52
;
else
if
(
speed
<=
26000000
)
priv
->
timing
=
MMC_TIMING_LEGACY
;
else
priv
->
timing
=
MMC_TIMING_MMC_HS
;
}
/* Re-init the PHY */
xenon_mmc_phy_set
(
host
);
}
/* Install a driver specific handler for post set_ios configuration */
static
const
struct
sdhci_ops
xenon_sdhci_ops
=
{
.
set_ios_post
=
xenon_sdhci_set_ios_post
};
static
int
xenon_sdhci_probe
(
struct
udevice
*
dev
)
{
struct
xenon_sdhci_plat
*
plat
=
dev_get_platdata
(
dev
);
struct
mmc_uclass_priv
*
upriv
=
dev_get_uclass_priv
(
dev
);
struct
xenon_sdhci_priv
*
priv
=
dev_get_priv
(
dev
);
struct
sdhci_host
*
host
=
dev_get_priv
(
dev
);
int
ret
;
host
->
mmc
=
&
plat
->
mmc
;
host
->
mmc
->
priv
=
host
;
host
->
mmc
->
dev
=
dev
;
upriv
->
mmc
=
host
->
mmc
;
/* Set quirks */
host
->
quirks
=
SDHCI_QUIRK_WAIT_SEND_CMD
|
SDHCI_QUIRK_32BIT_DMA_ADDR
;
/* Set default timing */
priv
->
timing
=
MMC_TIMING_LEGACY
;
/* Disable auto clock gating during init */
xenon_mmc_set_acg
(
host
,
false
);
/* Enable slot */
xenon_mmc_enable_slot
(
host
,
XENON_MMC_SLOT_ID_HYPERION
);
/*
* Set default power on SoC PHY PAD register (currently only
* available on the Armada 3700)
*/
if
(
priv
->
pad_ctrl_reg
)
armada_3700_soc_pad_voltage_set
(
host
);
host
->
host_caps
=
MMC_MODE_HS
|
MMC_MODE_HS_52MHz
|
MMC_MODE_DDR_52MHz
;
switch
(
fdtdec_get_int
(
gd
->
fdt_blob
,
dev
->
of_offset
,
"bus-width"
,
1
))
{
case
8
:
host
->
host_caps
|=
MMC_MODE_8BIT
;
break
;
case
4
:
host
->
host_caps
|=
MMC_MODE_4BIT
;
break
;
case
1
:
break
;
default:
printf
(
"Invalid
\"
bus-width
\"
value
\n
"
);
return
-
EINVAL
;
}
host
->
ops
=
&
xenon_sdhci_ops
;
ret
=
sdhci_setup_cfg
(
&
plat
->
cfg
,
host
,
XENON_MMC_MAX_CLK
,
0
);
if
(
ret
)
return
ret
;
ret
=
sdhci_probe
(
dev
);
if
(
ret
)
return
ret
;
/* Enable parallel transfer */
xenon_mmc_enable_parallel_tran
(
host
,
XENON_MMC_SLOT_ID_HYPERION
);
/* Disable tuning functionality of this slot */
xenon_mmc_disable_tuning
(
host
,
XENON_MMC_SLOT_ID_HYPERION
);
/* Enable auto clock gating after init */
xenon_mmc_set_acg
(
host
,
true
);
xenon_mask_cmd_conflict_err
(
host
);
return
ret
;
}
static
int
xenon_sdhci_ofdata_to_platdata
(
struct
udevice
*
dev
)
{
struct
sdhci_host
*
host
=
dev_get_priv
(
dev
);
struct
xenon_sdhci_priv
*
priv
=
dev_get_priv
(
dev
);
const
char
*
name
;
host
->
name
=
dev
->
name
;
host
->
ioaddr
=
(
void
*
)
dev_get_addr
(
dev
);
if
(
of_device_is_compatible
(
dev
,
"marvell,armada-3700-sdhci"
))
priv
->
pad_ctrl_reg
=
(
void
*
)
dev_get_addr_index
(
dev
,
1
);
name
=
fdt_getprop
(
gd
->
fdt_blob
,
dev
->
of_offset
,
"marvell,pad-type"
,
NULL
);
if
(
name
)
{
if
(
0
==
strncmp
(
name
,
"sd"
,
2
))
{
priv
->
pad_type
=
SOC_PAD_SD
;
}
else
if
(
0
==
strncmp
(
name
,
"fixed-1-8v"
,
10
))
{
priv
->
pad_type
=
SOC_PAD_FIXED_1_8V
;
}
else
{
printf
(
"Unsupported SOC PHY PAD ctrl type %s
\n
"
,
name
);
return
-
EINVAL
;
}
}
return
0
;
}
static
int
xenon_sdhci_bind
(
struct
udevice
*
dev
)
{
struct
xenon_sdhci_plat
*
plat
=
dev_get_platdata
(
dev
);
return
sdhci_bind
(
dev
,
&
plat
->
mmc
,
&
plat
->
cfg
);
}
static
const
struct
udevice_id
xenon_sdhci_ids
[]
=
{
{
.
compatible
=
"marvell,armada-8k-sdhci"
,},
{
.
compatible
=
"marvell,armada-3700-sdhci"
,},
{
}
};
U_BOOT_DRIVER
(
xenon_sdhci_drv
)
=
{
.
name
=
"xenon_sdhci"
,
.
id
=
UCLASS_MMC
,
.
of_match
=
xenon_sdhci_ids
,
.
ofdata_to_platdata
=
xenon_sdhci_ofdata_to_platdata
,
.
ops
=
&
sdhci_ops
,
.
bind
=
xenon_sdhci_bind
,
.
probe
=
xenon_sdhci_probe
,
.
priv_auto_alloc_size
=
sizeof
(
struct
xenon_sdhci_priv
),
.
platdata_auto_alloc_size
=
sizeof
(
struct
xenon_sdhci_plat
),
};
include/configs/mvebu_armada-8k.h
浏览文件 @
cf4128e5
...
...
@@ -114,6 +114,9 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
/* MMC/SD IP block */
#define CONFIG_GENERIC_MMC
#define CONFIG_SUPPORT_VFAT
/* DISK Partition support */
...
...
include/configs/mvebu_db-88f3720.h
浏览文件 @
cf4128e5
...
...
@@ -126,6 +126,9 @@
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
/* MMC/SD IP block */
#define CONFIG_GENERIC_MMC
#define CONFIG_SUPPORT_VFAT
/* DISK Partition support */
...
...
include/sdhci.h
浏览文件 @
cf4128e5
...
...
@@ -235,6 +235,7 @@ struct sdhci_ops {
#endif
int
(
*
get_cd
)(
struct
sdhci_host
*
host
);
void
(
*
set_control_reg
)(
struct
sdhci_host
*
host
);
void
(
*
set_ios_post
)(
struct
sdhci_host
*
host
);
void
(
*
set_clock
)(
struct
sdhci_host
*
host
,
u32
div
);
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录