summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/Kconfig8
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/at91/Kconfig6
-rw-r--r--drivers/clk/at91/clk-generated.c18
-rw-r--r--drivers/clk/clk_stm32f.c (renamed from drivers/clk/clk_stm32f7.c)272
-rw-r--r--drivers/clk/renesas/clk-rcar-gen3.c60
-rw-r--r--drivers/clk/rockchip/Makefile3
-rw-r--r--drivers/clk/rockchip/clk_rk3128.c596
-rw-r--r--drivers/firmware/psci.c7
-rw-r--r--drivers/gpio/gpio-rcar.c20
-rw-r--r--drivers/i2c/Kconfig6
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/rcar_iic.c271
-rw-r--r--drivers/misc/stm32_rcc.c42
-rw-r--r--drivers/mmc/Kconfig12
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/atmel_sdhci.c12
-rw-r--r--drivers/mmc/ftsdc010_mci.c143
-rw-r--r--drivers/mmc/ftsdc010_mci.h53
-rw-r--r--drivers/mmc/nds32_mmc.c136
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c2
-rw-r--r--drivers/net/ravb.c7
-rw-r--r--drivers/pinctrl/Kconfig10
-rw-r--r--drivers/pinctrl/renesas/pfc.c60
-rw-r--r--drivers/pinctrl/renesas/sh_pfc.h1
-rw-r--r--drivers/pinctrl/rockchip/Makefile4
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3128.c187
-rw-r--r--drivers/ram/rockchip/Makefile1
-rw-r--r--drivers/ram/rockchip/sdram_rk3128.c59
-rw-r--r--drivers/serial/serial_sh.h3
-rw-r--r--drivers/spi/Kconfig10
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/atcspi200_spi.c (renamed from drivers/spi/nds_ae3xx_spi.c)96
-rw-r--r--drivers/timer/Kconfig9
-rw-r--r--drivers/timer/Makefile2
-rw-r--r--drivers/timer/atcpit100_timer.c (renamed from drivers/timer/ae3xx_timer.c)38
36 files changed, 1932 insertions, 228 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index baa60a52e68..f6644ee6d16 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -46,6 +46,14 @@ config CLK_BOSTON
help
Enable this to support the clocks
+config CLK_STM32F
+ bool "Enable clock driver support for STM32F family"
+ depends on CLK && (STM32F7 || STM32F4)
+ default y
+ help
+ This clock driver adds support for RCC clock management
+ for STM32F4 and STM32F7 SoCs.
+
config CLK_ZYNQ
bool "Enable clock driver support for Zynq"
depends on CLK && ARCH_ZYNQ
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 83fe88ce9f5..bcc8f82fb65 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -21,5 +21,5 @@ obj-$(CONFIG_CLK_AT91) += at91/
obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
-obj-$(CONFIG_STM32F7) += clk_stm32f7.o
+obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o
diff --git a/drivers/clk/at91/Kconfig b/drivers/clk/at91/Kconfig
index c6c57618c14..fd56f200b9f 100644
--- a/drivers/clk/at91/Kconfig
+++ b/drivers/clk/at91/Kconfig
@@ -14,11 +14,11 @@ config CLK_AT91
config AT91_UTMI
bool "Support UTMI PLL Clock"
- depends on CLK_AT91 && SPL_DM
+ depends on CLK_AT91
select REGMAP
- select SPL_REGMAP
+ select SPL_REGMAP if SPL_DM
select SYSCON
- select SPL_SYSCON
+ select SPL_SYSCON if SPL_DM
help
This option is used to enable the AT91 UTMI PLL clock
driver. It is the clock provider of USB, and UPLLCK is the
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 8c9a3cb053a..2aacbaef0c0 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -53,16 +53,17 @@ static ulong generic_clk_get_rate(struct clk *clk)
struct clk parent;
ulong clk_rate;
u32 tmp, gckdiv;
- u8 parent_id;
+ u8 clock_source, parent_index;
int ret;
writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
tmp = readl(&pmc->pcr);
- parent_id = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
+ clock_source = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
AT91_PMC_PCR_GCKCSS_MASK;
gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
- ret = clk_get_by_index(dev_get_parent(clk->dev), parent_id, &parent);
+ parent_index = clock_source - 1;
+ ret = clk_get_by_index(dev_get_parent(clk->dev), parent_index, &parent);
if (ret)
return 0;
@@ -82,7 +83,7 @@ static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
ulong tmp_rate, best_rate = rate, parent_rate;
int tmp_diff, best_diff = -1;
u32 div, best_div = 0;
- u8 best_parent_id = 0;
+ u8 best_parent_index, best_clock_source = 0;
u8 i;
u32 tmp;
int ret;
@@ -98,9 +99,7 @@ static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
- if (rate < tmp_rate)
- continue;
- tmp_diff = rate - tmp_rate;
+ tmp_diff = abs(rate - tmp_rate);
if (best_diff < 0 || best_diff > tmp_diff) {
best_rate = tmp_rate;
@@ -108,7 +107,8 @@ static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
best_div = div - 1;
best_parent = parent;
- best_parent_id = i;
+ best_parent_index = i;
+ best_clock_source = best_parent_index + 1;
}
if (!best_diff || tmp_rate < rate)
@@ -129,7 +129,7 @@ static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
tmp = readl(&pmc->pcr);
tmp &= ~(AT91_PMC_PCR_GCKDIV | AT91_PMC_PCR_GCKCSS);
- tmp |= AT91_PMC_PCR_GCKCSS_(best_parent_id) |
+ tmp |= AT91_PMC_PCR_GCKCSS_(best_clock_source) |
AT91_PMC_PCR_CMD_WRITE |
AT91_PMC_PCR_GCKDIV_(best_div) |
AT91_PMC_PCR_GCKEN;
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f.c
index f1a9e9ca44e..634f0717c68 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f.c
@@ -8,10 +8,12 @@
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
+#include <stm32_rcc.h>
+
#include <asm/io.h>
-#include <asm/arch/rcc.h>
#include <asm/arch/stm32.h>
#include <asm/arch/stm32_periph.h>
+#include <asm/arch/stm32_pwr.h>
#include <dt-bindings/mfd/stm32f7-rcc.h>
@@ -22,6 +24,8 @@
#define RCC_CR_CSSON BIT(19)
#define RCC_CR_PLLON BIT(24)
#define RCC_CR_PLLRDY BIT(25)
+#define RCC_CR_PLLSAION BIT(28)
+#define RCC_CR_PLLSAIRDY BIT(29)
#define RCC_PLLCFGR_PLLM_MASK GENMASK(5, 0)
#define RCC_PLLCFGR_PLLN_MASK GENMASK(14, 6)
@@ -52,75 +56,87 @@
#define RCC_CFGR_PPRE1_SHIFT 10
#define RCC_CFGR_PPRE2_SHIFT 13
+#define RCC_PLLCFGR_PLLSAIN_MASK GENMASK(14, 6)
+#define RCC_PLLCFGR_PLLSAIP_MASK GENMASK(17, 16)
+#define RCC_PLLSAICFGR_PLLSAIN_SHIFT 6
+#define RCC_PLLSAICFGR_PLLSAIP_SHIFT 16
+#define RCC_PLLSAICFGR_PLLSAIP_4 BIT(17)
+#define RCC_PLLSAICFGR_PLLSAIQ_4 BIT(26)
+#define RCC_PLLSAICFGR_PLLSAIR_2 BIT(29)
+
+#define RCC_DCKCFGRX_CK48MSEL BIT(27)
+#define RCC_DCKCFGRX_SDMMC1SEL BIT(28)
+#define RCC_DCKCFGR2_SDMMC2SEL BIT(29)
+
+#define RCC_APB2ENR_SAI1EN BIT(22)
+
+/*
+ * RCC AHB1ENR specific definitions
+ */
+#define RCC_AHB1ENR_ETHMAC_EN BIT(25)
+#define RCC_AHB1ENR_ETHMAC_TX_EN BIT(26)
+#define RCC_AHB1ENR_ETHMAC_RX_EN BIT(27)
+
/*
- * Offsets of some PWR registers
+ * RCC APB1ENR specific definitions
*/
-#define PWR_CR1_ODEN BIT(16)
-#define PWR_CR1_ODSWEN BIT(17)
-#define PWR_CSR1_ODRDY BIT(16)
-#define PWR_CSR1_ODSWRDY BIT(17)
-
-struct pll_psc {
- u8 pll_m;
- u16 pll_n;
- u8 pll_p;
- u8 pll_q;
- u8 ahb_psc;
- u8 apb1_psc;
- u8 apb2_psc;
+#define RCC_APB1ENR_TIM2EN BIT(0)
+#define RCC_APB1ENR_PWREN BIT(28)
+
+/*
+ * RCC APB2ENR specific definitions
+ */
+#define RCC_APB2ENR_SYSCFGEN BIT(14)
+
+struct stm32_clk_info stm32f4_clk_info = {
+ /* 180 MHz */
+ .sys_pll_psc = {
+ .pll_m = 8,
+ .pll_n = 360,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2,
+ },
+ .has_overdrive = false,
+ .v2 = false,
};
-#define AHB_PSC_1 0
-#define AHB_PSC_2 0x8
-#define AHB_PSC_4 0x9
-#define AHB_PSC_8 0xA
-#define AHB_PSC_16 0xB
-#define AHB_PSC_64 0xC
-#define AHB_PSC_128 0xD
-#define AHB_PSC_256 0xE
-#define AHB_PSC_512 0xF
-
-#define APB_PSC_1 0
-#define APB_PSC_2 0x4
-#define APB_PSC_4 0x5
-#define APB_PSC_8 0x6
-#define APB_PSC_16 0x7
+struct stm32_clk_info stm32f7_clk_info = {
+ /* 200 MHz */
+ .sys_pll_psc = {
+ .pll_m = 25,
+ .pll_n = 400,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2,
+ },
+ .has_overdrive = true,
+ .v2 = true,
+};
struct stm32_clk {
struct stm32_rcc_regs *base;
+ struct stm32_pwr_regs *pwr_regs;
+ struct stm32_clk_info *info;
};
-#if !defined(CONFIG_STM32_HSE_HZ)
-#error "CONFIG_STM32_HSE_HZ not defined!"
-#else
-#if (CONFIG_STM32_HSE_HZ == 25000000)
-#if (CONFIG_SYS_CLK_FREQ == 200000000)
-/* 200 MHz */
-struct pll_psc sys_pll_psc = {
- .pll_m = 25,
- .pll_n = 400,
- .pll_p = 2,
- .pll_q = 8,
- .ahb_psc = AHB_PSC_1,
- .apb1_psc = APB_PSC_4,
- .apb2_psc = APB_PSC_2
-};
-#endif
-#else
-#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
-#endif
-#endif
-
static int configure_clocks(struct udevice *dev)
{
struct stm32_clk *priv = dev_get_priv(dev);
struct stm32_rcc_regs *regs = priv->base;
+ struct stm32_pwr_regs *pwr = priv->pwr_regs;
+ struct pll_psc sys_pll_psc = priv->info->sys_pll_psc;
+ u32 pllsaicfgr = 0;
/* Reset RCC configuration */
setbits_le32(&regs->cr, RCC_CR_HSION);
writel(0, &regs->cfgr); /* Reset CFGR */
clrbits_le32(&regs->cr, (RCC_CR_HSEON | RCC_CR_CSSON
- | RCC_CR_PLLON));
+ | RCC_CR_PLLON | RCC_CR_PLLSAION));
writel(0x24003010, &regs->pllcfgr); /* Reset value from RM */
clrbits_le32(&regs->cr, RCC_CR_HSEBYP);
writel(0, &regs->cir); /* Disable all interrupts */
@@ -146,23 +162,57 @@ static int configure_clocks(struct udevice *dev)
clrsetbits_le32(&regs->pllcfgr, RCC_PLLCFGR_PLLQ_MASK,
sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT);
+ /* Configure the SAI PLL to get a 48 MHz source */
+ pllsaicfgr = RCC_PLLSAICFGR_PLLSAIR_2 | RCC_PLLSAICFGR_PLLSAIQ_4 |
+ RCC_PLLSAICFGR_PLLSAIP_4;
+ pllsaicfgr |= 192 << RCC_PLLSAICFGR_PLLSAIN_SHIFT;
+ writel(pllsaicfgr, &regs->pllsaicfgr);
+
/* Enable the main PLL */
setbits_le32(&regs->cr, RCC_CR_PLLON);
while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
;
- /* Enable high performance mode, System frequency up to 200 MHz */
- setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
- setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN);
- /* Infinite wait! */
- while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY))
- ;
- /* Enable the Over-drive switch */
- setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODSWEN);
- /* Infinite wait! */
- while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODSWRDY))
+ if (priv->info->v2) { /*stm32f7 case */
+ /* select PLLSAI as 48MHz clock source */
+ setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
+
+ /* select 48MHz as SDMMC1 clock source */
+ clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
+
+ /* select 48MHz as SDMMC2 clock source */
+ clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
+ } else { /* stm32f4 case */
+ /* select PLLSAI as 48MHz clock source */
+ setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
+
+ /* select 48MHz as SDMMC1 clock source */
+ clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL);
+ }
+
+ /* Enable the SAI PLL */
+ setbits_le32(&regs->cr, RCC_CR_PLLSAION);
+ while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
;
+ setbits_le32(&regs->apb1enr, RCC_APB1ENR_PWREN);
+
+ if (priv->info->has_overdrive) {
+ /*
+ * Enable high performance mode
+ * System frequency up to 200 MHz
+ */
+ setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
+ /* Infinite wait! */
+ while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
+ ;
+ /* Enable the Over-drive switch */
+ setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
+ /* Infinite wait! */
+ while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
+ ;
+ }
+
stm32_flash_latency_cfg(5);
clrbits_le32(&regs->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
setbits_le32(&regs->cfgr, RCC_CFGR_SW_PLL);
@@ -170,16 +220,47 @@ static int configure_clocks(struct udevice *dev)
while ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) !=
RCC_CFGR_SWS_PLL)
;
+ /* gate the SAI clock, needed for MMC 1&2 clocks */
+ setbits_le32(&regs->apb2enr, RCC_APB2ENR_SAI1EN);
return 0;
}
+static unsigned long stm32_clk_pll48clk_rate(struct stm32_clk *priv,
+ u32 sysclk)
+{
+ struct stm32_rcc_regs *regs = priv->base;
+ u16 pllq, pllm, pllsain, pllsaip;
+ bool pllsai;
+
+ pllq = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLQ_MASK)
+ >> RCC_PLLCFGR_PLLQ_SHIFT;
+
+ if (priv->info->v2) /*stm32f7 case */
+ pllsai = readl(&regs->dckcfgr2) & RCC_DCKCFGRX_CK48MSEL;
+ else
+ pllsai = readl(&regs->dckcfgr) & RCC_DCKCFGRX_CK48MSEL;
+
+ if (pllsai) {
+ /* PLL48CLK is selected from PLLSAI, get PLLSAI value */
+ pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
+ pllsain = ((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIN_MASK)
+ >> RCC_PLLSAICFGR_PLLSAIN_SHIFT);
+ pllsaip = ((((readl(&regs->pllsaicfgr) & RCC_PLLCFGR_PLLSAIP_MASK)
+ >> RCC_PLLSAICFGR_PLLSAIP_SHIFT) + 1) << 1);
+ return ((CONFIG_STM32_HSE_HZ / pllm) * pllsain) / pllsaip;
+ }
+ /* PLL48CLK is selected from PLLQ */
+ return sysclk / pllq;
+}
+
static unsigned long stm32_clk_get_rate(struct clk *clk)
{
struct stm32_clk *priv = dev_get_priv(clk->dev);
struct stm32_rcc_regs *regs = priv->base;
u32 sysclk = 0;
u32 shift = 0;
+ u16 pllm, plln, pllp;
/* Prescaler table lookups for clock computation */
u8 ahb_psc_table[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
@@ -190,7 +271,6 @@ static unsigned long stm32_clk_get_rate(struct clk *clk)
if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
RCC_CFGR_SWS_PLL) {
- u16 pllm, plln, pllp;
pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
>> RCC_PLLCFGR_PLLN_SHIFT);
@@ -211,25 +291,43 @@ static unsigned long stm32_clk_get_rate(struct clk *clk)
(readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
>> RCC_CFGR_HPRE_SHIFT)];
return sysclk >>= shift;
- break;
/* APB1 CLOCK */
case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
shift = apb_psc_table[(
(readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
>> RCC_CFGR_PPRE1_SHIFT)];
return sysclk >>= shift;
- break;
/* APB2 CLOCK */
case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC):
+ /*
+ * particular case for SDMMC1 and SDMMC2 :
+ * 48Mhz source clock can be from main PLL or from
+ * SAI PLL
+ */
+ switch (clk->id) {
+ case STM32F7_APB2_CLOCK(SDMMC1):
+ if (readl(&regs->dckcfgr2) & RCC_DCKCFGRX_SDMMC1SEL)
+ /* System clock is selected as SDMMC1 clock */
+ return sysclk;
+ else
+ return stm32_clk_pll48clk_rate(priv, sysclk);
+ break;
+ case STM32F7_APB2_CLOCK(SDMMC2):
+ if (readl(&regs->dckcfgr2) & RCC_DCKCFGR2_SDMMC2SEL)
+ /* System clock is selected as SDMMC2 clock */
+ return sysclk;
+ else
+ return stm32_clk_pll48clk_rate(priv, sysclk);
+ break;
+ }
+
shift = apb_psc_table[(
(readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
>> RCC_CFGR_PPRE2_SHIFT)];
return sysclk >>= shift;
- break;
default:
pr_err("clock index %ld out of range\n", clk->id);
return -EINVAL;
- break;
}
}
@@ -268,17 +366,43 @@ void clock_setup(int peripheral)
static int stm32_clk_probe(struct udevice *dev)
{
- debug("%s: stm32_clk_probe\n", __func__);
+ struct ofnode_phandle_args args;
+ int err;
+
+ debug("%s\n", __func__);
struct stm32_clk *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = devfdt_get_addr(dev);
+ addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = (struct stm32_rcc_regs *)addr;
+ switch (dev_get_driver_data(dev)) {
+ case STM32F4:
+ priv->info = &stm32f4_clk_info;
+ break;
+ case STM32F7:
+ priv->info = &stm32f7_clk_info;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (priv->info->has_overdrive) {
+ err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
+ &args);
+ if (err) {
+ debug("%s: can't find syscon device (%d)\n", __func__,
+ err);
+ return err;
+ }
+
+ priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
+ }
+
configure_clocks(dev);
return 0;
@@ -307,15 +431,9 @@ static struct clk_ops stm32_clk_ops = {
.get_rate = stm32_clk_get_rate,
};
-static const struct udevice_id stm32_clk_ids[] = {
- { .compatible = "st,stm32f42xx-rcc"},
- {}
-};
-
-U_BOOT_DRIVER(stm32f7_clk) = {
- .name = "stm32f7_clk",
+U_BOOT_DRIVER(stm32fx_clk) = {
+ .name = "stm32fx_rcc_clock",
.id = UCLASS_CLK,
- .of_match = stm32_clk_ids,
.ops = &stm32_clk_ops,
.probe = stm32_clk_probe,
.priv_auto_alloc_size = sizeof(struct stm32_clk),
diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c
index c821bddc251..5abb171827e 100644
--- a/drivers/clk/renesas/clk-rcar-gen3.c
+++ b/drivers/clk/renesas/clk-rcar-gen3.c
@@ -490,6 +490,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] = {
DEF_MOD("sdif0", 314, R8A7796_CLK_SD0),
DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1),
DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1),
+ DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1),
DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1),
DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1),
DEF_MOD("rwdt", 402, R8A7796_CLK_R),
@@ -1074,6 +1075,64 @@ static int gen3_clk_probe(struct udevice *dev)
return 0;
}
+struct mstp_stop_table {
+ u32 dis;
+ u32 en;
+};
+
+static struct mstp_stop_table r8a7795_mstp_table[] = {
+ { 0x00640800, 0x0 }, { 0xF3EE9390, 0x0 },
+ { 0x340FAFDC, 0x2040 }, { 0xD80C7CDF, 0x400 },
+ { 0x80000184, 0x180 }, { 0x40BFFF46, 0x0 },
+ { 0xE5FBEECF, 0x0 }, { 0x39FFFF0E, 0x0 },
+ { 0x01F19FF4, 0x0 }, { 0xFFDFFFFF, 0x0 },
+ { 0xFFFEFFE0, 0x0 }, { 0x00000000, 0x0 },
+};
+
+static struct mstp_stop_table r8a7796_mstp_table[] = {
+ { 0x00200000, 0x0 }, { 0xFFFFFFFF, 0x0 },
+ { 0x340E2FDC, 0x2040 }, { 0xFFFFFFDF, 0x400 },
+ { 0x80000184, 0x180 }, { 0xC3FFFFFF, 0x0 },
+ { 0xFFFFFFFF, 0x0 }, { 0xFFFFFFFF, 0x0 },
+ { 0x01F1FFF7, 0x0 }, { 0xFFFFFFFE, 0x0 },
+ { 0xFFFEFFE0, 0x0 }, { 0x000000B7, 0x0 },
+};
+
+#define TSTR0 0x04
+#define TSTR0_STR0 BIT(0)
+
+static int gen3_clk_remove(struct udevice *dev)
+{
+ struct gen3_clk_priv *priv = dev_get_priv(dev);
+ enum gen3_clk_model model = dev_get_driver_data(dev);
+ struct mstp_stop_table *tbl;
+ unsigned int i, tbl_size;
+
+ switch (model) {
+ case CLK_R8A7795:
+ tbl = r8a7795_mstp_table;
+ tbl_size = ARRAY_SIZE(r8a7795_mstp_table);
+ break;
+ case CLK_R8A7796:
+ tbl = r8a7796_mstp_table;
+ tbl_size = ARRAY_SIZE(r8a7796_mstp_table);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Stop TMU0 */
+ clrbits_le32(TMU_BASE + TSTR0, TSTR0_STR0);
+
+ /* Stop module clock */
+ for (i = 0; i < tbl_size; i++) {
+ clrsetbits_le32(priv->base + SMSTPCR(i), tbl[i].dis, tbl[i].en);
+ clrsetbits_le32(priv->base + RMSTPCR(i), tbl[i].dis, 0x0);
+ }
+
+ return 0;
+}
+
static const struct udevice_id gen3_clk_ids[] = {
{ .compatible = "renesas,r8a7795-cpg-mssr", .data = CLK_R8A7795 },
{ .compatible = "renesas,r8a7796-cpg-mssr", .data = CLK_R8A7796 },
@@ -1087,4 +1146,5 @@ U_BOOT_DRIVER(clk_gen3) = {
.priv_auto_alloc_size = sizeof(struct gen3_clk_priv),
.ops = &gen3_clk_ops,
.probe = gen3_clk_probe,
+ .remove = gen3_clk_remove,
};
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index c50aff2e93d..eae0ef6a9fb 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -1,10 +1,11 @@
#
-# Copyright (c) 2016 Google, Inc
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
diff --git a/drivers/clk/rockchip/clk_rk3128.c b/drivers/clk/rockchip/clk_rk3128.c
new file mode 100644
index 00000000000..132d50dda38
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3128.c
@@ -0,0 +1,596 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3128.h>
+#include <asm/arch/hardware.h>
+#include <bitfield.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3128-cru.h>
+#include <linux/log2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ VCO_MAX_HZ = 2400U * 1000000,
+ VCO_MIN_HZ = 600 * 1000000,
+ OUTPUT_MAX_HZ = 2400U * 1000000,
+ OUTPUT_MIN_HZ = 24 * 1000000,
+};
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
+
+/* use integer mode*/
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
+static int rkclk_set_pll(struct rk3128_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3128_pll *pll = &cru->pll[pll_id];
+
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
+ uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
+
+ debug("PLL at %p:fd=%d,rd=%d,pd1=%d,pd2=%d,vco=%uHz,output=%uHz\n",
+ pll, div->fbdiv, div->refdiv, div->postdiv1,
+ div->postdiv2, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
+
+ /* use integer mode */
+ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+ /* Power down */
+ rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
+ (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+ div->refdiv << PLL_REFDIV_SHIFT));
+
+ /* Power Up */
+ rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ udelay(1);
+
+ return 0;
+}
+
+static int pll_para_config(u32 freq_hz, struct pll_div *div)
+{
+ u32 ref_khz = OSC_HZ / 1000, refdiv, fbdiv = 0;
+ u32 postdiv1, postdiv2 = 1;
+ u32 fref_khz;
+ u32 diff_khz, best_diff_khz;
+ const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
+ const u32 max_postdiv1 = 7, max_postdiv2 = 7;
+ u32 vco_khz;
+ u32 freq_khz = freq_hz / 1000;
+
+ if (!freq_hz) {
+ printf("%s: the frequency can't be 0 Hz\n", __func__);
+ return -1;
+ }
+
+ postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, freq_khz);
+ if (postdiv1 > max_postdiv1) {
+ postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
+ postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
+ }
+
+ vco_khz = freq_khz * postdiv1 * postdiv2;
+
+ if (vco_khz < (VCO_MIN_HZ / 1000) || vco_khz > (VCO_MAX_HZ / 1000) ||
+ postdiv2 > max_postdiv2) {
+ printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
+ __func__, freq_hz);
+ return -1;
+ }
+
+ div->postdiv1 = postdiv1;
+ div->postdiv2 = postdiv2;
+
+ best_diff_khz = vco_khz;
+ for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
+ fref_khz = ref_khz / refdiv;
+
+ fbdiv = vco_khz / fref_khz;
+ if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
+ continue;
+ diff_khz = vco_khz - fbdiv * fref_khz;
+ if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
+ fbdiv++;
+ diff_khz = fref_khz - diff_khz;
+ }
+
+ if (diff_khz >= best_diff_khz)
+ continue;
+
+ best_diff_khz = diff_khz;
+ div->refdiv = refdiv;
+ div->fbdiv = fbdiv;
+ }
+
+ if (best_diff_khz > 4 * (1000)) {
+ printf("%s: Failed to match output frequency %u bestis %u Hz\n",
+ __func__, freq_hz,
+ best_diff_khz * 1000);
+ return -1;
+ }
+ return 0;
+}
+
+static void rkclk_init(struct rk3128_cru *cru)
+{
+ u32 aclk_div;
+ u32 hclk_div;
+ u32 pclk_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK | APLL_MODE_MASK,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ APLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+
+ /*
+ * select apll as cpu/core clock pll source and
+ * set up dependent divisors for PERI and ACLK clocks.
+ * core hz : apll = 1:1
+ */
+ aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);
+
+ pclk_div = APLL_HZ / CORE_PERI_HZ - 1;
+ assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
+ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+ 0 << CORE_DIV_CON_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CORE_ACLK_DIV_MASK | CORE_PERI_DIV_MASK,
+ aclk_div << CORE_ACLK_DIV_SHIFT |
+ pclk_div << CORE_PERI_DIV_SHIFT);
+
+ /*
+ * select gpll as pd_bus bus clock source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
+ assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
+
+ pclk_div = BUS_ACLK_HZ / BUS_PCLK_HZ - 1;
+ assert((pclk_div + 1) * BUS_PCLK_HZ == BUS_ACLK_HZ && pclk_div <= 0x7);
+
+ hclk_div = BUS_ACLK_HZ / BUS_HCLK_HZ - 1;
+ assert((hclk_div + 1) * BUS_HCLK_HZ == BUS_ACLK_HZ && hclk_div <= 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ BUS_ACLK_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+ BUS_ACLK_PLL_SEL_GPLL << BUS_ACLK_PLL_SEL_SHIFT |
+ aclk_div << BUS_ACLK_DIV_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK,
+ pclk_div << BUS_PCLK_DIV_SHIFT |
+ hclk_div << BUS_HCLK_DIV_SHIFT);
+
+ /*
+ * select gpll as pd_peri bus clock source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && pclk_div < 0x8);
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PLL_SEL_MASK | PERI_PCLK_DIV_MASK |
+ PERI_HCLK_DIV_MASK | PERI_ACLK_DIV_MASK,
+ PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK | APLL_MODE_MASK | CPLL_MODE_MASK,
+ GPLL_MODE_NORM << GPLL_MODE_SHIFT |
+ APLL_MODE_NORM << APLL_MODE_SHIFT |
+ CPLL_MODE_NORM << CPLL_MODE_SHIFT);
+
+ /*fix NAND controller working clock max to 150Mhz */
+ rk_clrsetreg(&cru->cru_clksel_con[2],
+ NANDC_PLL_SEL_MASK | NANDC_CLK_DIV_MASK,
+ NANDC_PLL_SEL_GPLL << NANDC_PLL_SEL_SHIFT |
+ 3 << NANDC_CLK_DIV_SHIFT);
+}
+
+/* Get pll rate by id */
+static u32 rkclk_pll_get_rate(struct rk3128_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ u32 refdiv, fbdiv, postdiv1, postdiv2;
+ u32 con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3128_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT, 0xff
+ };
+ static u32 clk_mask[CLK_COUNT] = {
+ 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
+ GPLL_MODE_MASK, 0xff
+ };
+ uint shift;
+ uint mask;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ mask = clk_mask[clk_id];
+
+ switch ((con & mask) >> shift) {
+ case GPLL_MODE_SLOW:
+ return OSC_HZ;
+ case GPLL_MODE_NORM:
+ /* normal mode */
+ con = readl(&pll->con0);
+ postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+ fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+ con = readl(&pll->con1);
+ postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+ refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
+ return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+ case GPLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3128_cru *cru, uint clk_general_rate,
+ int periph)
+{
+ uint src_rate;
+ uint div, mux;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ case SCLK_EMMC:
+ case SCLK_EMMC_SAMPLE:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
+ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
+ div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
+ return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3128_cru *cru, uint clk_general_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+ int mux;
+
+ debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
+
+ /* mmc clock defaulg div 2 internal, need provide double in cru */
+ src_clk_div = DIV_ROUND_UP(clk_general_rate / 2, freq);
+
+ if (src_clk_div > 128) {
+ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
+ mux = EMMC_SEL_24M;
+ } else {
+ mux = EMMC_SEL_GPLL;
+ }
+
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_PLL_MASK | EMMC_DIV_MASK,
+ mux << EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_PLL_MASK | MMC0_DIV_MASK,
+ mux << MMC0_PLL_SHIFT |
+ (src_clk_div - 1) << MMC0_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+}
+
+static ulong rk3128_peri_get_pclk(struct rk3128_cru *cru, ulong clk_id)
+{
+ u32 div, con;
+
+ switch (clk_id) {
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ con = readl(&cru->cru_clksel_con[10]);
+ div = con >> 12 & 0x3;
+ break;
+ default:
+ printf("do not support this peripheral bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(PERI_ACLK_HZ, div);
+}
+
+static ulong rk3128_peri_set_pclk(struct rk3128_cru *cru, ulong clk_id, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = PERI_ACLK_HZ / hz;
+ assert(src_clk_div - 1 < 4);
+
+ switch (clk_id) {
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ rk_setreg(&cru->cru_clksel_con[10],
+ ((src_clk_div - 1) << 12));
+ break;
+ default:
+ printf("do not support this peripheral bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(PERI_ACLK_HZ, src_clk_div);
+}
+
+static ulong rk3128_saradc_get_clk(struct rk3128_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->cru_clksel_con[24]);
+ div = bitfield_extract(val, SARADC_DIV_CON_SHIFT,
+ SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3128_saradc_set_clk(struct rk3128_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->cru_clksel_con[24],
+ SARADC_DIV_CON_MASK,
+ src_clk_div << SARADC_DIV_CON_SHIFT);
+
+ return rk3128_saradc_get_clk(cru);
+}
+
+static ulong rk3128_vop_set_clk(struct rk3128_cru *cru, ulong clk_id, uint hz)
+{
+ int src_clk_div;
+ struct pll_div cpll_config = {0};
+
+ src_clk_div = GPLL_HZ / hz;
+ assert(src_clk_div - 1 < 31);
+
+ switch (clk_id) {
+ case ACLK_VIO0:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ VIO0_PLL_MASK | VIO0_DIV_MASK,
+ VIO0_SEL_GPLL << VIO0_PLL_SHIFT |
+ (src_clk_div - 1) << VIO0_DIV_SHIFT);
+ break;
+ case ACLK_VIO1:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ VIO1_PLL_MASK | VIO1_DIV_MASK,
+ VIO1_SEL_GPLL << VIO1_PLL_SHIFT |
+ (src_clk_div - 1) << VIO1_DIV_SHIFT);
+ break;
+ case DCLK_LCDC:
+ if (pll_para_config(hz, &cpll_config))
+ return -1;
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_config);
+
+ rk_clrsetreg(&cru->cru_clksel_con[27],
+ DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_CON_MASK,
+ DCLK_VOP_PLL_SEL_CPLL << DCLK_VOP_SEL_SHIFT |
+ (1 - 1) << DCLK_VOP_DIV_CON_SHIFT);
+ break;
+ default:
+ printf("do not support this vop freq\n");
+ return -EINVAL;
+ }
+
+ return hz;
+}
+
+static ulong rk3128_vop_get_rate(struct rk3128_cru *cru, ulong clk_id)
+{
+ u32 div, con, parent;
+
+ switch (clk_id) {
+ case ACLK_VIO0:
+ con = readl(&cru->cru_clksel_con[31]);
+ div = con & 0x1f;
+ parent = GPLL_HZ;
+ break;
+ case ACLK_VIO1:
+ con = readl(&cru->cru_clksel_con[31]);
+ div = (con >> 8) & 0x1f;
+ parent = GPLL_HZ;
+ break;
+ case DCLK_LCDC:
+ con = readl(&cru->cru_clksel_con[27]);
+ div = (con >> 8) & 0xfff;
+ parent = rkclk_pll_get_rate(cru, CLK_CODEC);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3128_clk_get_rate(struct clk *clk)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0 ... 63:
+ return rkclk_pll_get_rate(priv->cru, clk->id);
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ return rk3128_peri_get_pclk(priv->cru, clk->id);
+ case SCLK_SARADC:
+ return rk3128_saradc_get_clk(priv->cru);
+ case DCLK_LCDC:
+ case ACLK_VIO0:
+ case ACLK_VIO1:
+ return rk3128_vop_get_rate(priv->cru, clk->id);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rk3128_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 0 ... 63:
+ return 0;
+ case DCLK_LCDC:
+ case ACLK_VIO0:
+ case ACLK_VIO1:
+ new_rate = rk3128_vop_set_clk(priv->cru,
+ clk->id, rate);
+ break;
+ case HCLK_EMMC:
+ new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
+ clk->id, rate);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ new_rate = rk3128_peri_set_pclk(priv->cru, clk->id, rate);
+ break;
+ case SCLK_SARADC:
+ new_rate = rk3128_saradc_set_clk(priv->cru, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3128_clk_ops = {
+ .get_rate = rk3128_clk_get_rate,
+ .set_rate = rk3128_clk_set_rate,
+};
+
+static int rk3128_clk_probe(struct udevice *dev)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3128_cru *)dev_read_addr(dev);
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rk3128_clk_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *sys_child;
+ struct sysreset_reg *priv;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+ &sys_child);
+ if (ret) {
+ debug("Warning: No sysreset driver: ret=%d\n", ret);
+ } else {
+ priv = malloc(sizeof(struct sysreset_reg));
+ priv->glb_srst_fst_value = offsetof(struct rk3128_cru,
+ cru_glb_srst_fst_value);
+ priv->glb_srst_snd_value = offsetof(struct rk3128_cru,
+ cru_glb_srst_snd_value);
+ sys_child->priv = priv;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id rk3128_clk_ids[] = {
+ { .compatible = "rockchip,rk3128-cru" },
+ { .compatible = "rockchip,rk3126-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3128_cru) = {
+ .name = "clk_rk3128",
+ .id = UCLASS_CLK,
+ .of_match = rk3128_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3128_clk_priv),
+ .ops = &rk3128_clk_ops,
+ .bind = rk3128_clk_bind,
+ .probe = rk3128_clk_probe,
+};
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 451fbdebba3..cef8adc8175 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -13,6 +13,7 @@
#include <libfdt.h>
#include <linux/arm-smccc.h>
#include <linux/errno.h>
+#include <linux/printk.h>
#include <linux/psci.h>
psci_fn *invoke_psci_fn;
@@ -48,7 +49,7 @@ static int psci_bind(struct udevice *dev)
ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset",
NULL);
if (ret)
- debug("PSCI System Reset was not bound.\n");
+ pr_debug("PSCI System Reset was not bound.\n");
}
return 0;
@@ -62,7 +63,7 @@ static int psci_probe(struct udevice *dev)
method = fdt_stringlist_get(gd->fdt_blob, dev_of_offset(dev), "method",
0, NULL);
if (!method) {
- printf("missing \"method\" property\n");
+ pr_warn("missing \"method\" property\n");
return -ENXIO;
}
@@ -71,7 +72,7 @@ static int psci_probe(struct udevice *dev)
} else if (!strcmp("smc", method)) {
invoke_psci_fn = __invoke_psci_fn_smc;
} else {
- printf("invalid \"method\" property: %s\n", method);
+ pr_warn("invalid \"method\" property: %s\n", method);
return -EINVAL;
}
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index 8504dceb849..cb9f4258842 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include "../pinctrl/renesas/sh_pfc.h"
#define GPIO_IOINTSEL 0x00 /* General IO/Interrupt Switching Register */
#define GPIO_INOUTSEL 0x04 /* General Input/Output Switching Register */
@@ -29,7 +30,8 @@
DECLARE_GLOBAL_DATA_PTR;
struct rcar_gpio_priv {
- void __iomem *regs;
+ void __iomem *regs;
+ int pfc_offset;
};
static int rcar_gpio_get_value(struct udevice *dev, unsigned offset)
@@ -113,7 +115,22 @@ static int rcar_gpio_get_function(struct udevice *dev, unsigned offset)
return GPIOF_INPUT;
}
+static int rcar_gpio_request(struct udevice *dev, unsigned offset,
+ const char *label)
+{
+ struct rcar_gpio_priv *priv = dev_get_priv(dev);
+ struct udevice *pctldev;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
+ if (ret)
+ return ret;
+
+ return sh_pfc_config_mux_for_gpio(pctldev, priv->pfc_offset + offset);
+}
+
static const struct dm_gpio_ops rcar_gpio_ops = {
+ .request = rcar_gpio_request,
.direction_input = rcar_gpio_direction_input,
.direction_output = rcar_gpio_direction_output,
.get_value = rcar_gpio_get_value,
@@ -135,6 +152,7 @@ static int rcar_gpio_probe(struct udevice *dev)
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges",
NULL, 3, 0, &args);
+ priv->pfc_offset = ret == 0 ? args.args[1] : -1;
uc_priv->gpio_count = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
ret = clk_get_by_index(dev, 0, &clk);
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 1989f8eb572..cc370b9c57c 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -157,6 +157,12 @@ config SYS_I2C_OMAP24XX
help
Add support for the OMAP2+ I2C driver.
+config SYS_I2C_RCAR_IIC
+ bool "Renesas RCar Gen3 IIC driver"
+ depends on RCAR_GEN3 && DM_I2C
+ help
+ Support for Renesas RCar Gen3 IIC controller.
+
config SYS_I2C_ROCKCHIP
bool "Rockchip I2C driver"
depends on DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 733cd3e92fa..169a2f1d7a9 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o
obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o
obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
+obj-$(CONFIG_SYS_I2C_RCAR_IIC) += rcar_iic.o
obj-$(CONFIG_SYS_I2C_ROCKCHIP) += rk_i2c.o
obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o
obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
diff --git a/drivers/i2c/rcar_iic.c b/drivers/i2c/rcar_iic.c
new file mode 100644
index 00000000000..57ae2f51fca
--- /dev/null
+++ b/drivers/i2c/rcar_iic.c
@@ -0,0 +1,271 @@
+/*
+ * Renesas RCar IIC driver
+ *
+ * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on
+ * Copyright (C) 2011, 2013 Renesas Solutions Corp.
+ * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/io.h>
+
+struct rcar_iic_priv {
+ void __iomem *base;
+ struct clk clk;
+ u8 iccl;
+ u8 icch;
+};
+
+#define RCAR_IIC_ICDR 0x00
+#define RCAR_IIC_ICCR 0x04
+#define RCAR_IIC_ICSR 0x08
+#define RCAR_IIC_ICIC 0x0c
+#define RCAR_IIC_ICCL 0x10
+#define RCAR_IIC_ICCH 0x14
+
+/* ICCR */
+#define RCAR_IIC_ICCR_ICE BIT(7)
+#define RCAR_IIC_ICCR_RACK BIT(6)
+#define RCAR_IIC_ICCR_RTS BIT(4)
+#define RCAR_IIC_ICCR_BUSY BIT(2)
+#define RCAR_IIC_ICCR_SCP BIT(0)
+
+/* ICSR / ICIC */
+#define RCAR_IC_BUSY BIT(4)
+#define RCAR_IC_TACK BIT(2)
+#define RCAR_IC_DTE BIT(0)
+
+#define IRQ_WAIT 1000
+
+static void sh_irq_dte(struct udevice *dev)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < IRQ_WAIT; i++) {
+ if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
+ break;
+ udelay(10);
+ }
+}
+
+static int sh_irq_dte_with_tack(struct udevice *dev)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < IRQ_WAIT; i++) {
+ if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
+ break;
+ if (RCAR_IC_TACK & readb(priv->base + RCAR_IIC_ICSR))
+ return -ETIMEDOUT;
+ udelay(10);
+ }
+ return 0;
+}
+
+static void sh_irq_busy(struct udevice *dev)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < IRQ_WAIT; i++) {
+ if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR)))
+ break;
+ udelay(10);
+ }
+}
+
+static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+
+ clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
+ setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
+
+ writeb(priv->iccl, priv->base + RCAR_IIC_ICCL);
+ writeb(priv->icch, priv->base + RCAR_IIC_ICCH);
+ writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC);
+
+ writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY,
+ priv->base + RCAR_IIC_ICCR);
+ sh_irq_dte(dev);
+
+ clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK);
+ writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR);
+ return sh_irq_dte_with_tack(dev);
+}
+
+static void rcar_iic_finish(struct udevice *dev)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+
+ writeb(0, priv->base + RCAR_IIC_ICSR);
+ clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
+}
+
+static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int i, ret = -EREMOTEIO;
+
+ if (rcar_iic_set_addr(dev, msg->addr, 1) != 0)
+ goto err;
+
+ udelay(10);
+
+ writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
+ priv->base + RCAR_IIC_ICCR);
+
+ for (i = 0; i < msg->len; i++) {
+ if (sh_irq_dte_with_tack(dev) != 0)
+ goto err;
+
+ msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff;
+
+ if (msg->len - 1 == i) {
+ writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK,
+ priv->base + RCAR_IIC_ICCR);
+ }
+ }
+
+ sh_irq_busy(dev);
+ ret = 0;
+
+err:
+ rcar_iic_finish(dev);
+ return ret;
+}
+
+static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int i, ret = -EREMOTEIO;
+
+ if (rcar_iic_set_addr(dev, msg->addr, 0) != 0)
+ goto err;
+
+ udelay(10);
+
+ for (i = 0; i < msg->len; i++) {
+ writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR);
+ if (sh_irq_dte_with_tack(dev) != 0)
+ goto err;
+ }
+
+ if (msg->flags & I2C_M_STOP) {
+ writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS,
+ priv->base + RCAR_IIC_ICCR);
+ if (sh_irq_dte_with_tack(dev) != 0)
+ goto err;
+ }
+
+ sh_irq_busy(dev);
+ ret = 0;
+
+err:
+ rcar_iic_finish(dev);
+ return ret;
+}
+
+static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
+{
+ int ret;
+
+ for (; nmsgs > 0; nmsgs--, msg++) {
+ if (msg->flags & I2C_M_RD)
+ ret = rcar_iic_read_common(dev, msg);
+ else
+ ret = rcar_iic_write_common(dev, msg);
+
+ if (ret)
+ return -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+static int rcar_iic_set_speed(struct udevice *dev, uint speed)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ const unsigned int ratio_high = 4;
+ const unsigned int ratio_low = 5;
+ int clkrate, denom;
+
+ clkrate = clk_get_rate(&priv->clk);
+ if (clkrate < 0)
+ return clkrate;
+
+ /*
+ * Calculate the value for ICCL and ICCH. From the data sheet:
+ * iccl = (p-clock / transfer-rate) * (L / (L + H))
+ * icch = (p clock / transfer rate) * (H / (L + H))
+ * where L and H are the SCL low and high ratio.
+ */
+ denom = speed * (ratio_high + ratio_low);
+ priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom);
+ priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom);
+
+ return 0;
+}
+
+static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ rcar_iic_set_addr(dev, addr, 1);
+ writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
+ priv->base + RCAR_IIC_ICCR);
+ ret = sh_irq_dte_with_tack(dev);
+ rcar_iic_finish(dev);
+
+ return ret;
+}
+
+static int rcar_iic_probe(struct udevice *dev)
+{
+ struct rcar_iic_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = dev_read_addr_ptr(dev);
+
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret)
+ return ret;
+
+ rcar_iic_finish(dev);
+
+ return rcar_iic_set_speed(dev, 100000);
+}
+
+static const struct dm_i2c_ops rcar_iic_ops = {
+ .xfer = rcar_iic_xfer,
+ .probe_chip = rcar_iic_probe_chip,
+ .set_bus_speed = rcar_iic_set_speed,
+};
+
+static const struct udevice_id rcar_iic_ids[] = {
+ { .compatible = "renesas,rmobile-iic" },
+ { }
+};
+
+U_BOOT_DRIVER(iic_rcar) = {
+ .name = "iic_rcar",
+ .id = UCLASS_I2C,
+ .of_match = rcar_iic_ids,
+ .probe = rcar_iic_probe,
+ .priv_auto_alloc_size = sizeof(struct rcar_iic_priv),
+ .ops = &rcar_iic_ops,
+};
diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c
index 32d39719d81..87d9928362b 100644
--- a/drivers/misc/stm32_rcc.c
+++ b/drivers/misc/stm32_rcc.c
@@ -8,31 +8,63 @@
#include <common.h>
#include <dm.h>
#include <misc.h>
+#include <stm32_rcc.h>
+#include <dm/device-internal.h>
#include <dm/lists.h>
+struct stm32_rcc_clk stm32_rcc_clk_f4 = {
+ .drv_name = "stm32fx_rcc_clock",
+ .soc = STM32F4,
+};
+
+struct stm32_rcc_clk stm32_rcc_clk_f7 = {
+ .drv_name = "stm32fx_rcc_clock",
+ .soc = STM32F7,
+};
+
+struct stm32_rcc_clk stm32_rcc_clk_h7 = {
+ .drv_name = "stm32h7_rcc_clock",
+};
+
static int stm32_rcc_bind(struct udevice *dev)
{
- int ret;
struct udevice *child;
+ struct driver *drv;
+ struct stm32_rcc_clk *rcc_clk =
+ (struct stm32_rcc_clk *)dev_get_driver_data(dev);
+ int ret;
debug("%s(dev=%p)\n", __func__, dev);
- ret = device_bind_driver_to_node(dev, "stm32h7_rcc_clock",
- "stm32h7_rcc_clock",
- dev_ofnode(dev), &child);
+ drv = lists_driver_lookup_name(rcc_clk->drv_name);
+ if (!drv) {
+ debug("Cannot find driver '%s'\n", rcc_clk->drv_name);
+ return -ENOENT;
+ }
+
+ ret = device_bind_with_driver_data(dev, drv, rcc_clk->drv_name,
+ rcc_clk->soc,
+ dev_ofnode(dev), &child);
+
if (ret)
return ret;
+#ifdef CONFIG_SPL_BUILD
+ return 0;
+#else
return device_bind_driver_to_node(dev, "stm32_rcc_reset",
"stm32_rcc_reset",
dev_ofnode(dev), &child);
+#endif
}
static const struct misc_ops stm32_rcc_ops = {
};
static const struct udevice_id stm32_rcc_ids[] = {
- {.compatible = "st,stm32h743-rcc"},
+ {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f4 },
+ {.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 },
+ {.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 },
{ }
};
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 62ce0af7d3c..8fbeaa740d6 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -401,6 +401,18 @@ config STM32_SDMMC2
If you have a board based on such a SoC and with a SD/MMC slot,
say Y or M here.
+config MMC_NDS32
+ bool "Andestech SD/MMC controller support"
+ depends on DM_MMC && OF_CONTROL && BLK && FTSDC010
+ help
+ This enables support for the Andestech SD/MMM controller, which is
+ based on Faraday IP.
+
+config FTSDC010
+ bool "Ftsdc010 SD/MMC controller Support"
+ help
+ This SD/MMC controller is present in Andestech SoCs which is based on Faraday IP.
+
endif
config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index d505f37f019..9af375b044a 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MMC_SANDBOX) += sandbox_mmc.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
+obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o
# SDHCI
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index c19a1f36b69..9b37e32c8db 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -13,6 +13,7 @@
#include <asm/arch/clk.h>
#define ATMEL_SDHC_MIN_FREQ 400000
+#define ATMEL_SDHC_GCK_RATE 240000000
#ifndef CONFIG_DM_MMC
int atmel_sdhci_init(void *regbase, u32 id)
@@ -57,9 +58,6 @@ static int atmel_sdhci_probe(struct udevice *dev)
struct atmel_sdhci_plat *plat = dev_get_platdata(dev);
struct sdhci_host *host = dev_get_priv(dev);
u32 max_clk;
- u32 caps, caps_1;
- u32 clk_base, clk_mul;
- ulong gck_rate;
struct clk clk;
int ret;
@@ -78,17 +76,11 @@ static int atmel_sdhci_probe(struct udevice *dev)
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bus-width", 4);
- caps = sdhci_readl(host, SDHCI_CAPABILITIES);
- clk_base = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
- caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
- clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT;
- gck_rate = clk_base * 1000000 * (clk_mul + 1);
-
ret = clk_get_by_index(dev, 1, &clk);
if (ret)
return ret;
- ret = clk_set_rate(&clk, gck_rate);
+ ret = clk_set_rate(&clk, ATMEL_SDHC_GCK_RATE);
if (ret)
return ret;
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c
index 652a718467a..6ac4f83bd1c 100644
--- a/drivers/mmc/ftsdc010_mci.c
+++ b/drivers/mmc/ftsdc010_mci.c
@@ -12,24 +12,15 @@
#include <part.h>
#include <mmc.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/errno.h>
#include <asm/byteorder.h>
#include <faraday/ftsdc010.h>
+#include "ftsdc010_mci.h"
#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
#define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
-struct ftsdc010_chip {
- void __iomem *regs;
- uint32_t wprot; /* write protected (locked) */
- uint32_t rate; /* actual SD clock in Hz */
- uint32_t sclk; /* FTSDC010 source clock in Hz */
- uint32_t fifo; /* fifo depth in bytes */
- uint32_t acmd;
- struct mmc_config cfg; /* mmc configuration */
-};
-
static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
{
struct ftsdc010_chip *chip = mmc->priv;
@@ -127,9 +118,8 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
{
int ret = -ETIMEDOUT;
- uint32_t st, ts;
-
- for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
+ uint32_t st, timeout = 10000000;
+ while (timeout--) {
st = readl(&regs->status);
if (!(st & mask))
continue;
@@ -138,8 +128,9 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
break;
}
- if (ret)
+ if (ret){
debug("ftsdc010: wait st(0x%x) timeout\n", mask);
+ }
return ret;
}
@@ -147,10 +138,16 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
/*
* u-boot mmc api
*/
-
+#ifdef CONFIG_DM_MMC
+static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
+#endif
int ret = -EOPNOTSUPP;
uint32_t len = 0;
struct ftsdc010_chip *chip = mmc->priv;
@@ -245,14 +242,20 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
if (!ret) {
ret = ftsdc010_wait(regs,
- FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_ERROR);
+ FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_CRC_OK);
}
return ret;
}
+#ifdef CONFIG_DM_MMC
+static int ftsdc010_set_ios(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
static int ftsdc010_set_ios(struct mmc *mmc)
{
+#endif
struct ftsdc010_chip *chip = mmc->priv;
struct ftsdc010_mmc __iomem *regs = chip->regs;
@@ -274,20 +277,43 @@ static int ftsdc010_set_ios(struct mmc *mmc)
return 0;
}
-static int ftsdc010_init(struct mmc *mmc)
+#ifdef CONFIG_DM_MMC
+static int ftsdc010_get_cd(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
+static int ftsdc010_get_cd(struct mmc *mmc)
{
+#endif
struct ftsdc010_chip *chip = mmc->priv;
struct ftsdc010_mmc __iomem *regs = chip->regs;
- uint32_t ts;
-
- if (readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT)
- return -ENOMEDIUM;
+ return !(readl(&regs->status) & FTSDC010_STATUS_CARD_DETECT);
+}
+#ifdef CONFIG_DM_MMC
+static int ftsdc010_get_wp(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+#else
+static int ftsdc010_get_wp(struct mmc *mmc)
+{
+#endif
+ struct ftsdc010_chip *chip = mmc->priv;
+ struct ftsdc010_mmc __iomem *regs = chip->regs;
if (readl(&regs->status) & FTSDC010_STATUS_WRITE_PROT) {
printf("ftsdc010: write protected\n");
chip->wprot = 1;
}
+ return 0;
+}
+
+static int ftsdc010_init(struct mmc *mmc)
+{
+ struct ftsdc010_chip *chip = mmc->priv;
+ struct ftsdc010_mmc __iomem *regs = chip->regs;
+ uint32_t ts;
+
chip->fifo = (readl(&regs->feature) & 0xff) << 2;
/* 1. chip reset */
@@ -311,11 +337,69 @@ static int ftsdc010_init(struct mmc *mmc)
return 0;
}
+#ifdef CONFIG_DM_MMC
+int ftsdc010_probe(struct udevice *dev)
+{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ return ftsdc010_init(mmc);
+}
+
+const struct dm_mmc_ops dm_ftsdc010_ops = {
+ .send_cmd = ftsdc010_request,
+ .set_ios = ftsdc010_set_ios,
+ .get_cd = ftsdc010_get_cd,
+ .get_wp = ftsdc010_get_wp,
+};
+
+#else
static const struct mmc_ops ftsdc010_ops = {
.send_cmd = ftsdc010_request,
.set_ios = ftsdc010_set_ios,
+ .getcd = ftsdc010_get_cd,
+ .getwp = ftsdc010_get_wp,
.init = ftsdc010_init,
};
+#endif
+
+void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk)
+{
+ cfg->name = name;
+ cfg->f_min = min_clk;
+ cfg->f_max = max_clk;
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->host_caps = caps;
+ if (buswidth == 8) {
+ cfg->host_caps |= MMC_MODE_8BIT;
+ cfg->host_caps &= ~MMC_MODE_4BIT;
+ } else {
+ cfg->host_caps |= MMC_MODE_4BIT;
+ cfg->host_caps &= ~MMC_MODE_8BIT;
+ }
+ cfg->part_type = PART_TYPE_DOS;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+}
+
+void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
+{
+ switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
+ case FTSDC010_BWR_CAPS_4BIT:
+ cfg->host_caps |= MMC_MODE_4BIT;
+ break;
+ case FTSDC010_BWR_CAPS_8BIT:
+ cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
+ break;
+ default:
+ break;
+ }
+}
+
+#ifdef CONFIG_BLK
+int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+{
+ return mmc_bind(dev, mmc, cfg);
+}
+#else
int ftsdc010_mmc_init(int devid)
{
@@ -345,19 +429,11 @@ int ftsdc010_mmc_init(int devid)
#endif
chip->cfg.name = "ftsdc010";
+#ifndef CONFIG_DM_MMC
chip->cfg.ops = &ftsdc010_ops;
+#endif
chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
- switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
- case FTSDC010_BWR_CAPS_4BIT:
- chip->cfg.host_caps |= MMC_MODE_4BIT;
- break;
- case FTSDC010_BWR_CAPS_8BIT:
- chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
- break;
- default:
- break;
- }
-
+ set_bus_width(regs , &chip->cfg);
chip->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
chip->cfg.f_max = chip->sclk / 2;
chip->cfg.f_min = chip->sclk / 0x100;
@@ -373,3 +449,4 @@ int ftsdc010_mmc_init(int devid)
return 0;
}
+#endif
diff --git a/drivers/mmc/ftsdc010_mci.h b/drivers/mmc/ftsdc010_mci.h
new file mode 100644
index 00000000000..31a27fd7728
--- /dev/null
+++ b/drivers/mmc/ftsdc010_mci.h
@@ -0,0 +1,53 @@
+/*
+ * Faraday FTSDC010 Secure Digital Memory Card Host Controller
+ *
+ * Copyright (C) 2011 Andes Technology Corporation
+ * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <mmc.h>
+
+#ifndef __FTSDC010_MCI_H
+#define __FTSDC010_MCI_H
+
+struct ftsdc010_chip {
+ void __iomem *regs;
+ uint32_t wprot; /* write protected (locked) */
+ uint32_t rate; /* actual SD clock in Hz */
+ uint32_t sclk; /* FTSDC010 source clock in Hz */
+ uint32_t fifo; /* fifo depth in bytes */
+ uint32_t acmd;
+ struct mmc_config cfg; /* mmc configuration */
+ const char *name;
+ void *ioaddr;
+ unsigned int caps;
+ unsigned int version;
+ unsigned int clock;
+ unsigned int bus_hz;
+ unsigned int div;
+ int dev_index;
+ int dev_id;
+ int buswidth;
+ u32 fifoth_val;
+ struct mmc *mmc;
+ void *priv;
+ bool fifo_mode;
+};
+
+
+#ifdef CONFIG_DM_MMC
+/* Export the operations to drivers */
+int ftsdc010_probe(struct udevice *dev);
+extern const struct dm_mmc_ops dm_ftsdc010_ops;
+#endif
+void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk);
+void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
+
+#ifdef CONFIG_BLK
+int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+#endif
+
+
+#endif /* __FTSDC010_MCI_H */
diff --git a/drivers/mmc/nds32_mmc.c b/drivers/mmc/nds32_mmc.c
new file mode 100644
index 00000000000..6d3c8572e50
--- /dev/null
+++ b/drivers/mmc/nds32_mmc.c
@@ -0,0 +1,136 @@
+/*
+ * Andestech ATFSDC010 SD/MMC driver
+ *
+ * (C) Copyright 2017
+ * Rick Chen, NDS32 Software Engineering, rick@andestech.com
+
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <errno.h>
+#include <mapmem.h>
+#include <mmc.h>
+#include <pwrseq.h>
+#include <syscon.h>
+#include <linux/err.h>
+#include <faraday/ftsdc010.h>
+#include "ftsdc010_mci.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+struct nds_mmc {
+ fdt32_t bus_width;
+ bool cap_mmc_highspeed;
+ bool cap_sd_highspeed;
+ fdt32_t clock_freq_min_max[2];
+ struct phandle_2_cell clocks[4];
+ fdt32_t fifo_depth;
+ fdt32_t reg[2];
+};
+#endif
+
+struct nds_mmc_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct nds_mmc dtplat;
+#endif
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+struct ftsdc_priv {
+ struct clk clk;
+ struct ftsdc010_chip chip;
+ int fifo_depth;
+ bool fifo_mode;
+ u32 minmax[2];
+};
+
+static int nds32_mmc_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct ftsdc_priv *priv = dev_get_priv(dev);
+ struct ftsdc010_chip *chip = &priv->chip;
+ chip->name = dev->name;
+ chip->ioaddr = (void *)devfdt_get_addr(dev);
+ chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "bus-width", 4);
+ chip->priv = dev;
+ priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "fifo-depth", 0);
+ priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+ "fifo-mode");
+ if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
+ "clock-freq-min-max", priv->minmax, 2)) {
+ int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "max-frequency", -EINVAL);
+ if (val < 0)
+ return val;
+
+ priv->minmax[0] = 400000; /* 400 kHz */
+ priv->minmax[1] = val;
+ } else {
+ debug("%s: 'clock-freq-min-max' property was deprecated.\n",
+ __func__);
+ }
+#endif
+ chip->sclk = priv->minmax[1];
+ chip->regs = chip->ioaddr;
+ return 0;
+}
+
+static int nds32_mmc_probe(struct udevice *dev)
+{
+ struct nds_mmc_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct ftsdc_priv *priv = dev_get_priv(dev);
+ struct ftsdc010_chip *chip = &priv->chip;
+ struct udevice *pwr_dev __maybe_unused;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ int ret;
+ struct nds_mmc *dtplat = &plat->dtplat;
+ chip->name = dev->name;
+ chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
+ chip->buswidth = dtplat->bus_width;
+ chip->priv = dev;
+ chip->dev_index = 1;
+ memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
+ ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
+ if (ret < 0)
+ return ret;
+#endif
+ ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
+ priv->minmax[1] , priv->minmax[0]);
+ chip->mmc = &plat->mmc;
+ chip->mmc->priv = &priv->chip;
+ chip->mmc->dev = dev;
+ upriv->mmc = chip->mmc;
+ return ftsdc010_probe(dev);
+}
+
+static int nds32_mmc_bind(struct udevice *dev)
+{
+ struct nds_mmc_plat *plat = dev_get_platdata(dev);
+ return ftsdc010_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id nds32_mmc_ids[] = {
+ { .compatible = "andestech,atsdc010" },
+ { }
+};
+
+U_BOOT_DRIVER(nds32_mmc_drv) = {
+ .name = "nds32_mmc",
+ .id = UCLASS_MMC,
+ .of_match = nds32_mmc_ids,
+ .ofdata_to_platdata = nds32_mmc_ofdata_to_platdata,
+ .ops = &dm_ftsdc010_ops,
+ .bind = nds32_mmc_bind,
+ .probe = nds32_mmc_probe,
+ .priv_auto_alloc_size = sizeof(struct ftsdc_priv),
+ .platdata_auto_alloc_size = sizeof(struct nds_mmc_plat),
+};
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 6ab3c8a25ad..cedbb239b68 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -233,6 +233,7 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
{ 0xba20, 16, 16, &timing[3] },
};
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
@@ -255,6 +256,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
.maxblocks = 8, /* Last 8 blocks in each chip */
.pattern = bbt_mirror_pattern
};
+#endif
static struct nand_ecclayout ecc_layout_2KB_bch4bit = {
.eccbytes = 32,
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index dc7a52534e5..26d95f178f7 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -492,8 +492,8 @@ static int ravb_probe(struct udevice *dev)
if (ret < 0)
goto err_mdio_alloc;
- gpio_request_by_name_nodev(dev_ofnode(dev), "reset-gpios", 0,
- &eth->reset_gpio, GPIOD_IS_OUT);
+ gpio_request_by_name(dev, "reset-gpios", 0, &eth->reset_gpio,
+ GPIOD_IS_OUT);
mdiodev = mdio_alloc();
if (!mdiodev) {
@@ -528,7 +528,8 @@ static int ravb_remove(struct udevice *dev)
free(eth->phydev);
mdio_unregister(eth->bus);
mdio_free(eth->bus);
- dm_gpio_free(dev, &eth->reset_gpio);
+ if (dm_gpio_is_valid(&eth->reset_gpio))
+ dm_gpio_free(dev, &eth->reset_gpio);
unmap_physmem(eth->iobase, MAP_NOCACHE);
return 0;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index afca56dff1f..7e8e4b0b276 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -168,6 +168,16 @@ config PINCTRL_ROCKCHIP_RK3036
the GPIO definitions and pin control functions for each available
multiplex function.
+config PINCTRL_ROCKCHIP_RK3128
+ bool "Rockchip rk3128 pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3128 SoCs.
+
+ The driver is controlled by a device tree node which contains both
+ the GPIO definitions and pin control functions for each available
+ multiplex function.
+
config PINCTRL_ROCKCHIP_RK3188
bool "Rockchip rk3188 pin control driver"
depends on DM
diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c
index 1675485d669..66700725045 100644
--- a/drivers/pinctrl/renesas/pfc.c
+++ b/drivers/pinctrl/renesas/pfc.c
@@ -448,6 +448,51 @@ static const char *sh_pfc_pinctrl_get_function_name(struct udevice *dev,
return priv->pfc.info->functions[selector].name;
}
+int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector)
+{
+ struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
+ struct sh_pfc_pinctrl *pmx = &priv->pmx;
+ struct sh_pfc *pfc = &priv->pfc;
+ struct sh_pfc_pin_config *cfg;
+ const struct sh_pfc_pin *pin = NULL;
+ int i, idx;
+
+ for (i = 1; i < pfc->info->nr_pins; i++) {
+ if (priv->pfc.info->pins[i].pin != pin_selector)
+ continue;
+
+ pin = &priv->pfc.info->pins[i];
+ break;
+ }
+
+ if (!pin)
+ return -EINVAL;
+
+ idx = sh_pfc_get_pin_index(pfc, pin->pin);
+ cfg = &pmx->configs[idx];
+
+ if (cfg->type != PINMUX_TYPE_NONE)
+ return -EBUSY;
+
+ return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
+}
+
+static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector,
+ unsigned func_selector)
+{
+ struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
+ struct sh_pfc_pinctrl *pmx = &priv->pmx;
+ struct sh_pfc *pfc = &priv->pfc;
+ const struct sh_pfc_pin *pin = &priv->pfc.info->pins[pin_selector];
+ int idx = sh_pfc_get_pin_index(pfc, pin->pin);
+ struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
+
+ if (cfg->type != PINMUX_TYPE_NONE)
+ return -EBUSY;
+
+ return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION);
+}
+
static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector,
unsigned func_selector)
{
@@ -642,6 +687,19 @@ static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin,
return 0;
}
+static int sh_pfc_pinconf_pin_set(struct udevice *dev,
+ unsigned int pin_selector,
+ unsigned int param, unsigned int arg)
+{
+ struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
+ struct sh_pfc_pinctrl *pmx = &priv->pmx;
+ struct sh_pfc *pfc = &priv->pfc;
+ const struct sh_pfc_pin *pin = &pfc->info->pins[pin_selector];
+
+ sh_pfc_pinconf_set(pmx, pin->pin, param, arg);
+
+ return 0;
+}
static int sh_pfc_pinconf_group_set(struct udevice *dev,
unsigned int group_selector,
@@ -671,8 +729,10 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = {
#if CONFIG_IS_ENABLED(PINCONF)
.pinconf_num_params = ARRAY_SIZE(sh_pfc_pinconf_params),
.pinconf_params = sh_pfc_pinconf_params,
+ .pinconf_set = sh_pfc_pinconf_pin_set,
.pinconf_group_set = sh_pfc_pinconf_group_set,
#endif
+ .pinmux_set = sh_pfc_pinctrl_pin_set,
.pinmux_group_set = sh_pfc_pinctrl_group_set,
.set_state = pinctrl_generic_set_state,
};
diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h
index 7aef2d360b2..f82417b1a34 100644
--- a/drivers/pinctrl/renesas/sh_pfc.h
+++ b/drivers/pinctrl/renesas/sh_pfc.h
@@ -243,6 +243,7 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width, u32 data)
const struct sh_pfc_bias_info *
sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info,
unsigned int num, unsigned int pin);
+int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector);
extern const struct sh_pfc_soc_info r8a7795_pinmux_info;
extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 5251771a106..f09c6e17b4b 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -1,11 +1,11 @@
#
-# Copyright (c) 2015 Google, Inc
-# Written by Simon Glass <sjg@chromium.org>
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3036) += pinctrl_rk3036.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3128) += pinctrl_rk3128.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK322X) += pinctrl_rk322x.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3128.c b/drivers/pinctrl/rockchip/pinctrl_rk3128.c
new file mode 100644
index 00000000000..b1c32ac592a
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3128.c
@@ -0,0 +1,187 @@
+/*
+ * Pinctrl driver for Rockchip 3128 SoCs
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3128.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3128_pinctrl_priv {
+ struct rk3128_grf *grf;
+};
+
+static void pinctrl_rk3128_i2c_config(struct rk3128_grf *grf, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A1_MASK | GPIO0A0_MASK,
+ GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
+ GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
+
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A3_MASK | GPIO0A2_MASK,
+ GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
+ GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio2c_iomux2,
+ GPIO2C5_MASK | GPIO2C4_MASK,
+ GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
+ GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
+ break;
+ case PERIPH_ID_I2C3:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A7_MASK | GPIO0A6_MASK,
+ GPIO0A7_I2C3_SDA << GPIO0A7_SHIFT |
+ GPIO0A6_I2C3_SCL << GPIO0A6_SHIFT);
+
+ break;
+ }
+}
+
+static void pinctrl_rk3128_sdmmc_config(struct rk3128_grf *grf, int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
+ GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
+ GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
+ GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
+ GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
+ GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
+ GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
+ GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
+ GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A5_MASK | GPIO2A7_MASK,
+ GPIO2A5_EMMC_PWREN << GPIO2A5_SHIFT |
+ GPIO2A7_EMMC_CLKOUT << GPIO2A7_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ rk_clrsetreg(&grf->gpio1c_iomux, 0x0fff,
+ GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
+ GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
+ GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
+ GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
+ GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
+ GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
+ break;
+ }
+}
+
+static int rk3128_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ case PERIPH_ID_I2C3:
+ pinctrl_rk3128_i2c_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3128_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3128_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 14:
+ return PERIPH_ID_SDCARD;
+ case 16:
+ return PERIPH_ID_EMMC;
+ case 20:
+ return PERIPH_ID_UART0;
+ case 21:
+ return PERIPH_ID_UART1;
+ case 22:
+ return PERIPH_ID_UART2;
+ case 23:
+ return PERIPH_ID_SPI0;
+ case 24:
+ return PERIPH_ID_I2C0;
+ case 25:
+ return PERIPH_ID_I2C1;
+ case 26:
+ return PERIPH_ID_I2C2;
+ case 27:
+ return PERIPH_ID_I2C3;
+ case 30:
+ return PERIPH_ID_PWM0;
+ }
+ return -ENOENT;
+}
+
+static int rk3128_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3128_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+ return rk3128_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3128_pinctrl_ops = {
+ .set_state_simple = rk3128_pinctrl_set_state_simple,
+ .request = rk3128_pinctrl_request,
+ .get_periph_id = rk3128_pinctrl_get_periph_id,
+};
+
+static int rk3128_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+ return 0;
+}
+
+static const struct udevice_id rk3128_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3128-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3128) = {
+ .name = "pinctrl_rk3128",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3128_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3128_pinctrl_priv),
+ .ops = &rk3128_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = rk3128_pinctrl_probe,
+};
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 45b5fe72471..1a1e5578ca4 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -5,6 +5,7 @@
#
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
diff --git a/drivers/ram/rockchip/sdram_rk3128.c b/drivers/ram/rockchip/sdram_rk3128.c
new file mode 100644
index 00000000000..a33127f4b05
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk3128.c
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3128.h>
+#include <asm/arch/sdram_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+struct dram_info {
+ struct ram_info info;
+ struct rk3128_grf *grf;
+};
+
+static int rk3128_dmc_probe(struct udevice *dev)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+ priv->info.base = CONFIG_SYS_SDRAM_BASE;
+ priv->info.size = rockchip_sdram_size(
+ (phys_addr_t)&priv->grf->os_reg[1]);
+
+ return 0;
+}
+
+static int rk3128_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ *info = priv->info;
+
+ return 0;
+}
+
+static struct ram_ops rk3128_dmc_ops = {
+ .get_info = rk3128_dmc_get_info,
+};
+
+static const struct udevice_id rk3128_dmc_ids[] = {
+ { .compatible = "rockchip,rk3128-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rk3128) = {
+ .name = "rockchip_rk3128_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rk3128_dmc_ids,
+ .ops = &rk3128_dmc_ops,
+ .probe = rk3128_dmc_probe,
+ .priv_auto_alloc_size = sizeof(struct dram_info),
+};
diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h
index 4d271222434..1b8d742f1cf 100644
--- a/drivers/serial/serial_sh.h
+++ b/drivers/serial/serial_sh.h
@@ -226,8 +226,7 @@ struct uart_port {
# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
defined(CONFIG_R8A7792) || defined(CONFIG_R8A7793) || \
- defined(CONFIG_R8A7794) || defined(CONFIG_R8A7795) || \
- defined(CONFIG_R8A7796)
+ defined(CONFIG_R8A7794) || defined(CONFIG_RCAR_GEN3)
# if defined(CONFIG_SCIF_A)
# define SCIF_ORER 0x0200
# else
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 88da9a4c8e7..494639fb019 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -210,12 +210,12 @@ config FSL_QSPI
used to access the SPI NOR flash on platforms embedding this
Freescale IP core.
-config NDS_AE3XX_SPI
- bool "Andestech AE3XX SPI driver"
+config ATCSPI200_SPI
+ bool "Andestech ATCSPI200 SPI driver"
help
- Enable the Andestech AE3XX SPI driver. This driver can be
- used to access the SPI flash on platforms embedding this
- Andestech IP core.
+ Enable the Andestech ATCSPI200 SPI driver. This driver can be
+ used to access the SPI flash on AE3XX and AE250 platforms embedding
+ this Andestech IP core.
config TI_QSPI
bool "TI QSPI driver"
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ad56203cd6f..e3184db67f5 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
obj-$(CONFIG_MXC_SPI) += mxc_spi.o
obj-$(CONFIG_MXS_SPI) += mxs_spi.o
-obj-$(CONFIG_NDS_AE3XX_SPI) += nds_ae3xx_spi.o
+obj-$(CONFIG_ATCSPI200_SPI) += atcspi200_spi.o
obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
obj-$(CONFIG_PIC32_SPI) += pic32_spi.o
obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
diff --git a/drivers/spi/nds_ae3xx_spi.c b/drivers/spi/atcspi200_spi.c
index f5bd99a605b..3e29df03a4d 100644
--- a/drivers/spi/nds_ae3xx_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -1,5 +1,5 @@
/*
- * NDS SPI controller driver.
+ * Andestech ATCSPI200 SPI controller driver.
*
* Copyright 2017 Andes Technology, Inc.
* Author: Rick Chen (rick@andestech.com)
@@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define SPI1_BASE 0xf0f00000
#define NSPI_MAX_CS_NUM 1
-struct ae3xx_spi_regs {
+struct atcspi200_spi_regs {
u32 rev;
u32 reserve1[3];
u32 format; /* 0x10 */
@@ -78,7 +78,7 @@ struct nds_spi_slave {
#ifndef CONFIG_DM_SPI
struct spi_slave slave;
#endif
- volatile struct ae3xx_spi_regs *regs;
+ volatile struct atcspi200_spi_regs *regs;
int to;
unsigned int freq;
ulong clock;
@@ -94,7 +94,7 @@ struct nds_spi_slave {
unsigned int max_transfer_length;
};
-static int __ae3xx_spi_set_speed(struct nds_spi_slave *ns)
+static int __atcspi200_spi_set_speed(struct nds_spi_slave *ns)
{
u32 tm;
u8 div;
@@ -117,7 +117,7 @@ static int __ae3xx_spi_set_speed(struct nds_spi_slave *ns)
}
-static int __ae3xx_spi_claim_bus(struct nds_spi_slave *ns)
+static int __atcspi200_spi_claim_bus(struct nds_spi_slave *ns)
{
unsigned int format=0;
ns->regs->ctrl |= (TXFRST|RXFRST|SPIRST);
@@ -128,18 +128,18 @@ static int __ae3xx_spi_claim_bus(struct nds_spi_slave *ns)
ns->cmd_len = 0;
format = ns->mode|DATA_LENGTH(8);
ns->regs->format = format;
- __ae3xx_spi_set_speed(ns);
+ __atcspi200_spi_set_speed(ns);
return 0;
}
-static int __ae3xx_spi_release_bus(struct nds_spi_slave *ns)
+static int __atcspi200_spi_release_bus(struct nds_spi_slave *ns)
{
/* do nothing */
return 0;
}
-static int __ae3xx_spi_start(struct nds_spi_slave *ns)
+static int __atcspi200_spi_start(struct nds_spi_slave *ns)
{
int i,olen=0;
int tc = ns->regs->tctrl;
@@ -168,7 +168,7 @@ static int __ae3xx_spi_start(struct nds_spi_slave *ns)
return 0;
}
-static int __ae3xx_spi_stop(struct nds_spi_slave *ns)
+static int __atcspi200_spi_stop(struct nds_spi_slave *ns)
{
ns->regs->timing = ns->mtiming;
while ((ns->regs->status & SPIBSY)&&(ns->to--))
@@ -190,7 +190,7 @@ static int __nspi_espi_rx(struct nds_spi_slave *ns, void *din, unsigned int byte
}
-static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
+static int __atcspi200_spi_xfer(struct nds_spi_slave *ns,
unsigned int bitlen, const void *data_out, void *data_in,
unsigned long flags)
{
@@ -230,7 +230,7 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
memcpy(cmd_buf, data_out, cmd_len);
data_out = 0;
data_len = 0;
- __ae3xx_spi_start(ns);
+ __atcspi200_spi_start(ns);
break;
}
debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
@@ -245,7 +245,7 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
num_bytes = (tran_len) % CHUNK_SIZE;
if(num_bytes == 0)
num_bytes = CHUNK_SIZE;
- __ae3xx_spi_start(ns);
+ __atcspi200_spi_start(ns);
while (num_blks) {
event = in_le32(&ns->regs->status);
@@ -279,9 +279,9 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
ns->cmd_buf[3] += ((tran_len)&0xff);
ns->data_len = data_len;
}
- ret = __ae3xx_spi_stop(ns);
+ ret = __atcspi200_spi_stop(ns);
}
- ret = __ae3xx_spi_stop(ns);
+ ret = __atcspi200_spi_stop(ns);
return ret;
}
@@ -300,11 +300,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
switch (bus) {
case SPI0_BUS:
- ns->regs = (struct ae3xx_spi_regs *)SPI0_BASE;
+ ns->regs = (struct atcspi200_spi_regs *)SPI0_BASE;
break;
case SPI1_BUS:
- ns->regs = (struct ae3xx_spi_regs *)SPI1_BASE;
+ ns->regs = (struct atcspi200_spi_regs *)SPI1_BASE;
break;
default:
@@ -336,20 +336,20 @@ void spi_init(void)
int spi_claim_bus(struct spi_slave *slave)
{
struct nds_spi_slave *ns = to_nds_spi_slave(slave);
- return __ae3xx_spi_claim_bus(ns);
+ return __atcspi200_spi_claim_bus(ns);
}
void spi_release_bus(struct spi_slave *slave)
{
struct nds_spi_slave *ns = to_nds_spi_slave(slave);
- __ae3xx_spi_release_bus(ns);
+ __atcspi200_spi_release_bus(ns);
}
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
void *data_in, unsigned long flags)
{
struct nds_spi_slave *ns = to_nds_spi_slave(slave);
- return __ae3xx_spi_xfer(ns, bitlen, data_out, data_in, flags);
+ return __atcspi200_spi_xfer(ns, bitlen, data_out, data_in, flags);
}
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
@@ -360,28 +360,28 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs)
void spi_cs_activate(struct spi_slave *slave)
{
struct nds_spi_slave *ns = to_nds_spi_slave(slave);
- __ae3xx_spi_start(ns);
+ __atcspi200_spi_start(ns);
}
void spi_cs_deactivate(struct spi_slave *slave)
{
struct nds_spi_slave *ns = to_nds_spi_slave(slave);
- __ae3xx_spi_stop(ns);
+ __atcspi200_spi_stop(ns);
}
#else
-static int ae3xx_spi_set_speed(struct udevice *bus, uint max_hz)
+static int atcspi200_spi_set_speed(struct udevice *bus, uint max_hz)
{
struct nds_spi_slave *ns = dev_get_priv(bus);
debug("%s speed %u\n", __func__, max_hz);
ns->freq = max_hz;
- __ae3xx_spi_set_speed(ns);
+ __atcspi200_spi_set_speed(ns);
return 0;
}
-static int ae3xx_spi_set_mode(struct udevice *bus, uint mode)
+static int atcspi200_spi_set_mode(struct udevice *bus, uint mode)
{
struct nds_spi_slave *ns = dev_get_priv(bus);
@@ -391,7 +391,7 @@ static int ae3xx_spi_set_mode(struct udevice *bus, uint mode)
return 0;
}
-static int ae3xx_spi_claim_bus(struct udevice *dev)
+static int atcspi200_spi_claim_bus(struct udevice *dev)
{
struct dm_spi_slave_platdata *slave_plat =
dev_get_parent_platdata(dev);
@@ -403,27 +403,27 @@ static int ae3xx_spi_claim_bus(struct udevice *dev)
return -EINVAL;
}
- return __ae3xx_spi_claim_bus(ns);
+ return __atcspi200_spi_claim_bus(ns);
}
-static int ae3xx_spi_release_bus(struct udevice *dev)
+static int atcspi200_spi_release_bus(struct udevice *dev)
{
struct nds_spi_slave *ns = dev_get_priv(dev->parent);
- return __ae3xx_spi_release_bus(ns);
+ return __atcspi200_spi_release_bus(ns);
}
-static int ae3xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
+static int atcspi200_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din,
unsigned long flags)
{
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
- return __ae3xx_spi_xfer(ns, bitlen, dout, din, flags);
+ return __atcspi200_spi_xfer(ns, bitlen, dout, din, flags);
}
-static int ae3xx_spi_get_clk(struct udevice *bus)
+static int atcspi200_spi_get_clk(struct udevice *bus)
{
struct nds_spi_slave *ns = dev_get_priv(bus);
struct clk clk;
@@ -444,26 +444,26 @@ static int ae3xx_spi_get_clk(struct udevice *bus)
return 0;
}
-static int ae3xx_spi_probe(struct udevice *bus)
+static int atcspi200_spi_probe(struct udevice *bus)
{
struct nds_spi_slave *ns = dev_get_priv(bus);
ns->to = SPI_TIMEOUT;
ns->max_transfer_length = MAX_TRANSFER_LEN;
ns->mtiming = ns->regs->timing;
- ae3xx_spi_get_clk(bus);
+ atcspi200_spi_get_clk(bus);
return 0;
}
-static int ae3xx_ofdata_to_platadata(struct udevice *bus)
+static int atcspi200_ofdata_to_platadata(struct udevice *bus)
{
struct nds_spi_slave *ns = dev_get_priv(bus);
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
ns->regs = map_physmem(devfdt_get_addr(bus),
- sizeof(struct ae3xx_spi_regs),
+ sizeof(struct atcspi200_spi_regs),
MAP_NOCACHE);
if (!ns->regs) {
printf("%s: could not map device address\n", __func__);
@@ -474,26 +474,26 @@ static int ae3xx_ofdata_to_platadata(struct udevice *bus)
return 0;
}
-static const struct dm_spi_ops ae3xx_spi_ops = {
- .claim_bus = ae3xx_spi_claim_bus,
- .release_bus = ae3xx_spi_release_bus,
- .xfer = ae3xx_spi_xfer,
- .set_speed = ae3xx_spi_set_speed,
- .set_mode = ae3xx_spi_set_mode,
+static const struct dm_spi_ops atcspi200_spi_ops = {
+ .claim_bus = atcspi200_spi_claim_bus,
+ .release_bus = atcspi200_spi_release_bus,
+ .xfer = atcspi200_spi_xfer,
+ .set_speed = atcspi200_spi_set_speed,
+ .set_mode = atcspi200_spi_set_mode,
};
-static const struct udevice_id ae3xx_spi_ids[] = {
+static const struct udevice_id atcspi200_spi_ids[] = {
{ .compatible = "andestech,atcspi200" },
{ }
};
-U_BOOT_DRIVER(ae3xx_spi) = {
- .name = "ae3xx_spi",
+U_BOOT_DRIVER(atcspi200_spi) = {
+ .name = "atcspi200_spi",
.id = UCLASS_SPI,
- .of_match = ae3xx_spi_ids,
- .ops = &ae3xx_spi_ops,
- .ofdata_to_platdata = ae3xx_ofdata_to_platadata,
+ .of_match = atcspi200_spi_ids,
+ .ops = &atcspi200_spi_ops,
+ .ofdata_to_platdata = atcspi200_ofdata_to_platadata,
.priv_auto_alloc_size = sizeof(struct nds_spi_slave),
- .probe = ae3xx_spi_probe,
+ .probe = atcspi200_spi_probe,
};
#endif
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 6305bbf01cd..3a1f8311c12 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -105,11 +105,12 @@ config AG101P_TIMER
help
Select this to enable a timer for AG01P devices.
-config AE3XX_TIMER
- bool "AE3XX timer support"
- depends on TIMER && NDS32
+config ATCPIT100_TIMER
+ bool "ATCPIT100 timer support"
+ depends on TIMER
help
- Select this to enable a timer for AE3XX devices.
+ Select this to enable a ATCPIT100 timer which will be embeded
+ in AE3XX, AE250 boards.
config ROCKCHIP_TIMER
bool "Rockchip timer support"
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 69e8961a7ba..15e515407e3 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -13,6 +13,6 @@ obj-$(CONFIG_AST_TIMER) += ast_timer.o
obj-$(CONFIG_STI_TIMER) += sti-timer.o
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
-obj-$(CONFIG_AE3XX_TIMER) += ae3xx_timer.o
+obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
diff --git a/drivers/timer/ae3xx_timer.c b/drivers/timer/atcpit100_timer.c
index bcc07a0c864..963f978d206 100644
--- a/drivers/timer/ae3xx_timer.c
+++ b/drivers/timer/atcpit100_timer.c
@@ -14,7 +14,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#define REG32_TMR(x) (*(unsigned long *) ((plat->regs) + (x>>2)))
+#define REG32_TMR(x) (*(u32 *) ((plat->regs) + (x>>2)))
/*
* Definition of register offsets
@@ -67,51 +67,51 @@ struct atctmr_timer_regs {
u32 int_mask; /* 0x38 */
};
-struct atftmr_timer_platdata {
- unsigned long *regs;
+struct atcpit_timer_platdata {
+ u32 *regs;
};
-static int atftmr_timer_get_count(struct udevice *dev, u64 *count)
+static int atcpit_timer_get_count(struct udevice *dev, u64 *count)
{
- struct atftmr_timer_platdata *plat = dev->platdata;
+ struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
u32 val;
val = ~(REG32_TMR(CH_CNT(1))+0xffffffff);
*count = timer_conv_64(val);
return 0;
}
-static int atctmr_timer_probe(struct udevice *dev)
+static int atcpit_timer_probe(struct udevice *dev)
{
- struct atftmr_timer_platdata *plat = dev->platdata;
+ struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
REG32_TMR(CH_REL(1)) = 0xffffffff;
REG32_TMR(CH_CTL(1)) = APB_CLK|TMR_32;
REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 0);
return 0;
}
-static int atctme_timer_ofdata_to_platdata(struct udevice *dev)
+static int atcpit_timer_ofdata_to_platdata(struct udevice *dev)
{
- struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
+ struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
plat->regs = map_physmem(devfdt_get_addr(dev) , 0x100 , MAP_NOCACHE);
return 0;
}
-static const struct timer_ops ag101p_timer_ops = {
- .get_count = atftmr_timer_get_count,
+static const struct timer_ops atcpit_timer_ops = {
+ .get_count = atcpit_timer_get_count,
};
-static const struct udevice_id ag101p_timer_ids[] = {
+static const struct udevice_id atcpit_timer_ids[] = {
{ .compatible = "andestech,atcpit100" },
{}
};
-U_BOOT_DRIVER(altera_timer) = {
- .name = "ae3xx_timer",
+U_BOOT_DRIVER(atcpit100_timer) = {
+ .name = "atcpit100_timer",
.id = UCLASS_TIMER,
- .of_match = ag101p_timer_ids,
- .ofdata_to_platdata = atctme_timer_ofdata_to_platdata,
- .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata),
- .probe = atctmr_timer_probe,
- .ops = &ag101p_timer_ops,
+ .of_match = atcpit_timer_ids,
+ .ofdata_to_platdata = atcpit_timer_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct atcpit_timer_platdata),
+ .probe = atcpit_timer_probe,
+ .ops = &atcpit_timer_ops,
.flags = DM_FLAG_PRE_RELOC,
};