mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
Improvements:
- RK3188 USB-UART functionality - errors triggering a hard-stop in SPL on the RK3399 are reported - Rockchip RV1108 (SoC) support - MicroCrystal RV3029 (RTC) DM driver Fixes: - RK3188 early UART setup - limit SD-card frequency to 40MHz on the RK3399-Q7 - MIPI fixes - RK3399 CPUB clock initialisation -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJcAab4AAoJECaAFcEOcohNx8gH/0OuW443gsA8Ty0rXpCvbzSi UejfBfqljX4tYcUrgABVdMd2WdUyQ6rSoVgnX6mvfToCxd51L2CQiimrTJRQp/ZQ yCrwC8iFYwgmyM/0UnnjRa03WJvYBi3McWWIxQy7ZywQcZkdIuyn6t5AbcRppGMF 67G0ft9KRwB+dMcgdRuikDThZRhAWZ30MdY4LFZvyGWupuv/mdpyYhjHYyv05CVf BvaUqRFkt86GBAW7Hq+OahH1t/xuZBcPJdt8GC40Blgfmle2uvZOIpoSEezVwFXm qKSj5FSSVQ9XtMeWwWvHLUxKSua0pIX5d7HmK9WqcsUIePDbzth8i+/BdA+5AD4= =EYJx -----END PGP SIGNATURE----- Merge tag 'for-master-20181130' of git://git.denx.de/u-boot-rockchip Improvements: - RK3188 USB-UART functionality - errors triggering a hard-stop in SPL on the RK3399 are reported - Rockchip RV1108 (SoC) support - MicroCrystal RV3029 (RTC) DM driver Fixes: - RK3188 early UART setup - limit SD-card frequency to 40MHz on the RK3399-Q7 - MIPI fixes - RK3399 CPUB clock initialisation
This commit is contained in:
commit
c1d6e0bbfd
21 changed files with 1549 additions and 207 deletions
|
@ -503,7 +503,7 @@
|
|||
&sdmmc {
|
||||
u-boot,dm-pre-reloc;
|
||||
clock-frequency = <150000000>;
|
||||
clock-freq-min-max = <100000 150000000>;
|
||||
max-frequency = <40000000>;
|
||||
supports-sd;
|
||||
bus-width = <4>;
|
||||
cap-mmc-highspeed;
|
||||
|
|
|
@ -121,8 +121,35 @@
|
|||
};
|
||||
|
||||
grf: syscon@10300000 {
|
||||
compatible = "rockchip,rv1108-grf", "syscon";
|
||||
compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd";
|
||||
reg = <0x10300000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
u2phy: usb2-phy@100 {
|
||||
compatible = "rockchip,rv1108-usb2phy";
|
||||
reg = <0x100 0x0c>;
|
||||
clocks = <&cru SCLK_USBPHY>;
|
||||
clock-names = "phyclk";
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "usbphy";
|
||||
rockchip,usbgrf = <&usbgrf>;
|
||||
status = "disabled";
|
||||
|
||||
u2phy_otg: otg-port {
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "otg-mux";
|
||||
#phy-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
u2phy_host: host-port {
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "linestate";
|
||||
#phy-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
saradc: saradc@1038c000 {
|
||||
|
@ -141,6 +168,11 @@
|
|||
reg = <0x20060000 0x1000>;
|
||||
};
|
||||
|
||||
usbgrf: syscon@202a0000 {
|
||||
compatible = "rockchip,rv1108-usbgrf", "syscon";
|
||||
reg = <0x202a0000 0x1000>;
|
||||
};
|
||||
|
||||
cru: clock-controller@20200000 {
|
||||
compatible = "rockchip,rv1108-cru";
|
||||
reg = <0x20200000 0x1000>;
|
||||
|
@ -200,12 +232,19 @@
|
|||
};
|
||||
|
||||
usb20_otg: usb@30180000 {
|
||||
compatible = "rockchip,rv1108-usb", "rockchip,rk3288-usb",
|
||||
compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb",
|
||||
"snps,dwc2";
|
||||
reg = <0x30180000 0x40000>;
|
||||
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
||||
hnp-srp-disable;
|
||||
clocks = <&cru HCLK_OTG>;
|
||||
clock-names = "otg";
|
||||
dr_mode = "otg";
|
||||
g-np-tx-fifo-size = <16>;
|
||||
g-rx-fifo-size = <280>;
|
||||
g-tx-fifo-size = <256 128 128 64 32 16>;
|
||||
g-use-dma;
|
||||
phys = <&u2phy_otg>;
|
||||
phy-names = "usb2-phy";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -427,6 +466,35 @@
|
|||
};
|
||||
};
|
||||
|
||||
emmc {
|
||||
emmc_clk: emmc-clk {
|
||||
rockchip,pins = <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
|
||||
};
|
||||
|
||||
emmc_cmd: emmc-cmd {
|
||||
rockchip,pins = <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
|
||||
};
|
||||
|
||||
emmc_pwren: emmc-pwren {
|
||||
rockchip,pins = <2 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
|
||||
};
|
||||
|
||||
emmc_bus1: emmc-bus1 {
|
||||
rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
|
||||
};
|
||||
|
||||
emmc_bus8: emmc-bus8 {
|
||||
rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA1 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA2 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA3 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA5 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA6 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
|
||||
<2 RK_PA7 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
|
||||
};
|
||||
};
|
||||
|
||||
sdmmc {
|
||||
sdmmc_clk: sdmmc-clk {
|
||||
rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;
|
||||
|
|
|
@ -43,6 +43,12 @@ struct sysreset_reg {
|
|||
unsigned int glb_srst_snd_value;
|
||||
};
|
||||
|
||||
struct softreset_reg {
|
||||
void __iomem *base;
|
||||
unsigned int sf_reset_offset;
|
||||
unsigned int sf_reset_num;
|
||||
};
|
||||
|
||||
/**
|
||||
* clk_get_divisor() - Calculate the required clock divisior
|
||||
*
|
||||
|
|
|
@ -69,16 +69,21 @@ check_member(rk3399_cru, sdio1_con[1], 0x594);
|
|||
#define MHz 1000000
|
||||
#define KHz 1000
|
||||
#define OSC_HZ (24*MHz)
|
||||
#define APLL_HZ (600*MHz)
|
||||
#define LPLL_HZ (600*MHz)
|
||||
#define BPLL_HZ (600*MHz)
|
||||
#define GPLL_HZ (594*MHz)
|
||||
#define CPLL_HZ (384*MHz)
|
||||
#define PPLL_HZ (676*MHz)
|
||||
|
||||
#define PMU_PCLK_HZ (48*MHz)
|
||||
|
||||
#define ACLKM_CORE_HZ (300*MHz)
|
||||
#define ATCLK_CORE_HZ (300*MHz)
|
||||
#define PCLK_DBG_HZ (100*MHz)
|
||||
#define ACLKM_CORE_L_HZ (300*MHz)
|
||||
#define ATCLK_CORE_L_HZ (300*MHz)
|
||||
#define PCLK_DBG_L_HZ (100*MHz)
|
||||
|
||||
#define ACLKM_CORE_B_HZ (300*MHz)
|
||||
#define ATCLK_CORE_B_HZ (300*MHz)
|
||||
#define PCLK_DBG_B_HZ (100*MHz)
|
||||
|
||||
#define PERIHP_ACLK_HZ (148500*KHz)
|
||||
#define PERIHP_HCLK_HZ (148500*KHz)
|
||||
|
@ -98,4 +103,13 @@ enum apll_l_frequencies {
|
|||
APLL_L_600_MHZ,
|
||||
};
|
||||
|
||||
enum apll_b_frequencies {
|
||||
APLL_B_600_MHZ,
|
||||
};
|
||||
|
||||
void rk3399_configure_cpu_l(struct rk3399_cru *cru,
|
||||
enum apll_l_frequencies apll_l_freq);
|
||||
void rk3399_configure_cpu_b(struct rk3399_cru *cru,
|
||||
enum apll_b_frequencies apll_b_freq);
|
||||
|
||||
#endif /* __ASM_ARCH_CRU_RK3399_H_ */
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
#define OSC_HZ (24 * 1000 * 1000)
|
||||
|
||||
#define APLL_HZ (600 * 1000000)
|
||||
#define GPLL_HZ (594 * 1000000)
|
||||
#define GPLL_HZ (1188 * 1000000)
|
||||
#define ACLK_PERI_HZ (148500000)
|
||||
#define HCLK_PERI_HZ (148500000)
|
||||
#define PCLK_PERI_HZ (74250000)
|
||||
#define ACLK_BUS_HZ (148500000)
|
||||
|
||||
struct rv1108_clk_priv {
|
||||
struct rv1108_cru *cru;
|
||||
|
@ -80,6 +84,11 @@ enum {
|
|||
WORK_MODE_NORMAL = 1,
|
||||
DSMPD_SHIFT = 3,
|
||||
DSMPD_MASK = 1 << DSMPD_SHIFT,
|
||||
INTEGER_MODE = 1,
|
||||
GLOBAL_POWER_DOWN_SHIFT = 0,
|
||||
GLOBAL_POWER_DOWN_MASK = 1 << GLOBAL_POWER_DOWN_SHIFT,
|
||||
GLOBAL_POWER_DOWN = 1,
|
||||
GLOBAL_POWER_UP = 0,
|
||||
|
||||
/* CLKSEL0_CON */
|
||||
CORE_PLL_SEL_SHIFT = 8,
|
||||
|
@ -90,11 +99,77 @@ enum {
|
|||
CORE_CLK_DIV_SHIFT = 0,
|
||||
CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL_CON1 */
|
||||
PCLK_DBG_DIV_CON_SHIFT = 4,
|
||||
PCLK_DBG_DIV_CON_MASK = 0xf << PCLK_DBG_DIV_CON_SHIFT,
|
||||
ACLK_CORE_DIV_CON_SHIFT = 0,
|
||||
ACLK_CORE_DIV_CON_MASK = 7 << ACLK_CORE_DIV_CON_SHIFT,
|
||||
|
||||
/* CLKSEL_CON2 */
|
||||
ACLK_BUS_PLL_SEL_SHIFT = 8,
|
||||
ACLK_BUS_PLL_SEL_MASK = 3 << ACLK_BUS_PLL_SEL_SHIFT,
|
||||
ACLK_BUS_PLL_SEL_GPLL = 0,
|
||||
ACLK_BUS_PLL_SEL_APLL = 1,
|
||||
ACLK_BUS_PLL_SEL_DPLL = 2,
|
||||
ACLK_BUS_DIV_CON_SHIFT = 0,
|
||||
ACLK_BUS_DIV_CON_MASK = 0x1f << ACLK_BUS_DIV_CON_SHIFT,
|
||||
ACLK_BUS_DIV_CON_WIDTH = 5,
|
||||
|
||||
/* CLKSEL_CON3 */
|
||||
PCLK_BUS_DIV_CON_SHIFT = 8,
|
||||
PCLK_BUS_DIV_CON_MASK = 0x1f << PCLK_BUS_DIV_CON_SHIFT,
|
||||
HCLK_BUS_DIV_CON_SHIFT = 0,
|
||||
HCLK_BUS_DIV_CON_MASK = 0x1f,
|
||||
|
||||
/* CLKSEL_CON4 */
|
||||
CLK_DDR_PLL_SEL_SHIFT = 8,
|
||||
CLK_DDR_PLL_SEL_MASK = 0x3 << CLK_DDR_PLL_SEL_SHIFT,
|
||||
CLK_DDR_DIV_CON_SHIFT = 0,
|
||||
CLK_DDR_DIV_CON_MASK = 0x3 << CLK_DDR_DIV_CON_SHIFT,
|
||||
|
||||
/* CLKSEL_CON19 */
|
||||
CLK_I2C1_PLL_SEL_SHIFT = 15,
|
||||
CLK_I2C1_PLL_SEL_MASK = 1 << CLK_I2C1_PLL_SEL_SHIFT,
|
||||
CLK_I2C1_PLL_SEL_DPLL = 0,
|
||||
CLK_I2C1_PLL_SEL_GPLL = 1,
|
||||
CLK_I2C1_DIV_CON_SHIFT = 8,
|
||||
CLK_I2C1_DIV_CON_MASK = 0x7f << CLK_I2C1_DIV_CON_SHIFT,
|
||||
CLK_I2C0_PLL_SEL_SHIFT = 7,
|
||||
CLK_I2C0_PLL_SEL_MASK = 1 << CLK_I2C0_PLL_SEL_SHIFT,
|
||||
CLK_I2C0_DIV_CON_SHIFT = 0,
|
||||
CLK_I2C0_DIV_CON_MASK = 0x7f,
|
||||
I2C_DIV_CON_WIDTH = 7,
|
||||
|
||||
/* CLKSEL_CON20 */
|
||||
CLK_I2C3_PLL_SEL_SHIFT = 15,
|
||||
CLK_I2C3_PLL_SEL_MASK = 1 << CLK_I2C3_PLL_SEL_SHIFT,
|
||||
CLK_I2C3_PLL_SEL_DPLL = 0,
|
||||
CLK_I2C3_PLL_SEL_GPLL = 1,
|
||||
CLK_I2C3_DIV_CON_SHIFT = 8,
|
||||
CLK_I2C3_DIV_CON_MASK = 0x7f << CLK_I2C3_DIV_CON_SHIFT,
|
||||
CLK_I2C2_PLL_SEL_SHIFT = 7,
|
||||
CLK_I2C2_PLL_SEL_MASK = 1 << CLK_I2C2_PLL_SEL_SHIFT,
|
||||
CLK_I2C2_DIV_CON_SHIFT = 0,
|
||||
CLK_I2C2_DIV_CON_MASK = 0x7f,
|
||||
|
||||
/* CLKSEL_CON22 */
|
||||
CLK_SARADC_DIV_CON_SHIFT= 0,
|
||||
CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
|
||||
CLK_SARADC_DIV_CON_WIDTH= 10,
|
||||
|
||||
/* CLKSEL_CON23 */
|
||||
ACLK_PERI_PLL_SEL_SHIFT = 15,
|
||||
ACLK_PERI_PLL_SEL_MASK = 1 << ACLK_PERI_PLL_SEL_SHIFT,
|
||||
ACLK_PERI_PLL_SEL_GPLL = 0,
|
||||
ACLK_PERI_PLL_SEL_DPLL = 1,
|
||||
PCLK_PERI_DIV_CON_SHIFT = 10,
|
||||
PCLK_PERI_DIV_CON_MASK = 0x1f << PCLK_PERI_DIV_CON_SHIFT,
|
||||
HCLK_PERI_DIV_CON_SHIFT = 5,
|
||||
HCLK_PERI_DIV_CON_MASK = 0x1f << HCLK_PERI_DIV_CON_SHIFT,
|
||||
ACLK_PERI_DIV_CON_SHIFT = 0,
|
||||
ACLK_PERI_DIV_CON_MASK = 0x1f,
|
||||
PERI_DIV_CON_WIDTH = 5,
|
||||
|
||||
/* CLKSEL24_CON */
|
||||
MAC_PLL_SEL_SHIFT = 12,
|
||||
MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT,
|
||||
|
@ -105,6 +180,17 @@ enum {
|
|||
MAC_CLK_DIV_MASK = 0x1f,
|
||||
MAC_CLK_DIV_SHIFT = 0,
|
||||
|
||||
/* CLKSEL25_CON */
|
||||
EMMC_PLL_SEL_SHIFT = 12,
|
||||
EMMC_PLL_SEL_MASK = 3 << EMMC_PLL_SEL_SHIFT,
|
||||
EMMC_PLL_SEL_DPLL = 0,
|
||||
EMMC_PLL_SEL_GPLL,
|
||||
EMMC_PLL_SEL_OSC,
|
||||
|
||||
/* CLKSEL26_CON */
|
||||
EMMC_CLK_DIV_SHIFT = 8,
|
||||
EMMC_CLK_DIV_MASK = 0xff << EMMC_CLK_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL27_CON */
|
||||
SFC_PLL_SEL_SHIFT = 7,
|
||||
SFC_PLL_SEL_MASK = 1 << SFC_PLL_SEL_SHIFT,
|
||||
|
@ -112,5 +198,61 @@ enum {
|
|||
SFC_PLL_SEL_GPLL = 1,
|
||||
SFC_CLK_DIV_SHIFT = 0,
|
||||
SFC_CLK_DIV_MASK = 0x3f << SFC_CLK_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL28_CON */
|
||||
ACLK_VIO1_PLL_SEL_SHIFT = 14,
|
||||
ACLK_VIO1_PLL_SEL_MASK = 3 << ACLK_VIO1_PLL_SEL_SHIFT,
|
||||
VIO_PLL_SEL_DPLL = 0,
|
||||
VIO_PLL_SEL_GPLL = 1,
|
||||
ACLK_VIO1_CLK_DIV_SHIFT = 8,
|
||||
ACLK_VIO1_CLK_DIV_MASK = 0x1f << ACLK_VIO1_CLK_DIV_SHIFT,
|
||||
CLK_VIO_DIV_CON_WIDTH = 5,
|
||||
ACLK_VIO0_PLL_SEL_SHIFT = 6,
|
||||
ACLK_VIO0_PLL_SEL_MASK = 3 << ACLK_VIO0_PLL_SEL_SHIFT,
|
||||
ACLK_VIO0_CLK_DIV_SHIFT = 0,
|
||||
ACLK_VIO0_CLK_DIV_MASK = 0x1f << ACLK_VIO0_CLK_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL29_CON */
|
||||
PCLK_VIO_CLK_DIV_SHIFT = 8,
|
||||
PCLK_VIO_CLK_DIV_MASK = 0x1f << PCLK_VIO_CLK_DIV_SHIFT,
|
||||
HCLK_VIO_CLK_DIV_SHIFT = 0,
|
||||
HCLK_VIO_CLK_DIV_MASK = 0x1f << HCLK_VIO_CLK_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL32_CON */
|
||||
DCLK_VOP_SEL_SHIFT = 7,
|
||||
DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT,
|
||||
DCLK_VOP_SEL_HDMI = 0,
|
||||
DCLK_VOP_SEL_PLL = 1,
|
||||
DCLK_VOP_PLL_SEL_SHIFT = 6,
|
||||
DCLK_VOP_PLL_SEL_MASK = 1 << DCLK_VOP_PLL_SEL_SHIFT,
|
||||
DCLK_VOP_PLL_SEL_GPLL = 0,
|
||||
DCLK_VOP_PLL_SEL_DPLL = 1,
|
||||
DCLK_VOP_CLK_DIV_SHIFT = 0,
|
||||
DCLK_VOP_CLK_DIV_MASK = 0x3f << DCLK_VOP_CLK_DIV_SHIFT,
|
||||
DCLK_VOP_DIV_CON_WIDTH = 6,
|
||||
|
||||
/* SOFTRST1_CON*/
|
||||
DDRPHY_SRSTN_CLKDIV_REQ_SHIFT = 0,
|
||||
DDRPHY_SRSTN_CLKDIV_REQ = 1,
|
||||
DDRPHY_SRSTN_CLKDIV_DIS = 0,
|
||||
DDRPHY_SRSTN_CLKDIV_REQ_MASK = 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT,
|
||||
DDRPHY_SRSTN_REQ_SHIFT = 1,
|
||||
DDRPHY_SRSTN_REQ = 1,
|
||||
DDRPHY_SRSTN_DIS = 0,
|
||||
DDRPHY_SRSTN_REQ_MASK = 1 << DDRPHY_SRSTN_REQ_SHIFT,
|
||||
DDRPHY_PSRSTN_REQ_SHIFT = 2,
|
||||
DDRPHY_PSRSTN_REQ = 1,
|
||||
DDRPHY_PSRSTN_DIS = 0,
|
||||
DDRPHY_PSRSTN_REQ_MASK = 1 << DDRPHY_PSRSTN_REQ_SHIFT,
|
||||
|
||||
/* SOFTRST2_CON*/
|
||||
DDRUPCTL_PSRSTN_REQ_SHIFT = 0,
|
||||
DDRUPCTL_PSRSTN_REQ = 1,
|
||||
DDRUPCTL_PSRSTN_DIS = 0,
|
||||
DDRUPCTL_PSRSTN_REQ_MASK = 1 << DDRUPCTL_PSRSTN_REQ_SHIFT,
|
||||
DDRUPCTL_NSRSTN_REQ_SHIFT = 1,
|
||||
DDRUPCTL_NSRSTN_REQ = 1,
|
||||
DDRUPCTL_NSRSTN_DIS = 0,
|
||||
DDRUPCTL_NSRSTN_REQ_MASK = 1 << DDRUPCTL_NSRSTN_REQ_SHIFT,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -205,4 +205,46 @@ enum {
|
|||
ATO_AE_SHIFT = 0,
|
||||
ATO_AE_MASK = 1,
|
||||
};
|
||||
|
||||
/* GRF_UOC_CON0 */
|
||||
enum {
|
||||
SIDDQ_SHIFT = 13,
|
||||
SIDDQ_MASK = 1 << SIDDQ_SHIFT,
|
||||
|
||||
BYPASSSEL_SHIFT = 9,
|
||||
BYPASSSEL_MASK = 1 << BYPASSSEL_SHIFT,
|
||||
|
||||
BYPASSDMEN_SHIFT = 8,
|
||||
BYPASSDMEN_MASK = 1 << BYPASSDMEN_SHIFT,
|
||||
|
||||
UOC_DISABLE_SHIFT = 4,
|
||||
UOC_DISABLE_MASK = 1 << UOC_DISABLE_SHIFT,
|
||||
|
||||
COMMON_ON_N_SHIFT = 0,
|
||||
COMMON_ON_N_MASK = 1 << COMMON_ON_N_SHIFT,
|
||||
};
|
||||
|
||||
/* GRF_UOC_CON2 */
|
||||
enum {
|
||||
SOFT_CON_SEL_SHIFT = 2,
|
||||
SOFT_CON_SEL_MASK = 1 << SOFT_CON_SEL_SHIFT,
|
||||
};
|
||||
|
||||
/* GRF_UOC0_CON3 */
|
||||
enum {
|
||||
TERMSEL_FULLSPEED_SHIFT = 5,
|
||||
TERMSEL_FULLSPEED_MASK = 1 << TERMSEL_FULLSPEED_SHIFT,
|
||||
|
||||
XCVRSELECT_SHIFT = 3,
|
||||
XCVRSELECT_FSTRANSC = 1,
|
||||
XCVRSELECT_MASK = 3 << XCVRSELECT_SHIFT,
|
||||
|
||||
OPMODE_SHIFT = 1,
|
||||
OPMODE_NODRIVING = 1,
|
||||
OPMODE_MASK = 3 << OPMODE_SHIFT,
|
||||
|
||||
SUSPENDN_SHIFT = 0,
|
||||
SUSPENDN_MASK = 1 << SUSPENDN_SHIFT,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@ config ROCKCHIP_RK3188
|
|||
select SPL_RAM
|
||||
select SPL_DRIVERS_MISC_SUPPORT
|
||||
select SPL_ROCKCHIP_EARLYRETURN_TO_BROM
|
||||
select DEBUG_UART_BOARD_INIT
|
||||
select BOARD_LATE_INIT
|
||||
select ROCKCHIP_BROM_HELPER
|
||||
help
|
||||
|
@ -156,6 +157,14 @@ config ROCKCHIP_RV1108
|
|||
The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
|
||||
and a DSP.
|
||||
|
||||
config ROCKCHIP_USB_UART
|
||||
bool "Route uart output to usb pins"
|
||||
help
|
||||
Rockchip SoCs have the ability to route the signals of the debug
|
||||
uart through the d+ and d- pins of a specific usb phy to enable
|
||||
some form of closed-case debugging. With this option supported
|
||||
SoCs will enable this routing as a debug measure.
|
||||
|
||||
config SPL_ROCKCHIP_BACK_TO_BROM
|
||||
bool "SPL returns to bootrom"
|
||||
default y if ROCKCHIP_RK3036
|
||||
|
|
|
@ -33,6 +33,7 @@ obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o
|
|||
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108-board.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/arch/bootrom.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/grf_rk3188.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/periph.h>
|
||||
#include <asm/arch/pmu_rk3188.h>
|
||||
|
@ -92,23 +93,38 @@ static int setup_arm_clock(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
void board_debug_uart_init(void)
|
||||
{
|
||||
struct udevice *pinctrl, *dev;
|
||||
int ret;
|
||||
|
||||
/* Example code showing how to enable the debug UART on RK3188 */
|
||||
#ifdef EARLY_UART
|
||||
#include <asm/arch/grf_rk3188.h>
|
||||
/* Enable early UART on the RK3188 */
|
||||
#define GRF_BASE 0x20008000
|
||||
struct rk3188_grf * const grf = (void *)GRF_BASE;
|
||||
enum {
|
||||
GPIO1B1_SHIFT = 2,
|
||||
GPIO1B1_MASK = 3,
|
||||
GPIO1B1_GPIO = 0,
|
||||
GPIO1B1_UART2_SOUT,
|
||||
|
||||
GPIO1B0_SHIFT = 0,
|
||||
GPIO1B0_MASK = 3,
|
||||
GPIO1B0_GPIO = 0,
|
||||
GPIO1B0_UART2_SIN,
|
||||
};
|
||||
|
||||
/* Enable early UART on the RK3188 */
|
||||
rk_clrsetreg(&grf->gpio1b_iomux,
|
||||
GPIO1B1_MASK << GPIO1B1_SHIFT |
|
||||
GPIO1B0_MASK << GPIO1B0_SHIFT,
|
||||
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
|
||||
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
struct udevice *pinctrl, *dev;
|
||||
int ret;
|
||||
|
||||
#define EARLY_UART
|
||||
#ifdef EARLY_UART
|
||||
/*
|
||||
* Debug UART can be used from here if required:
|
||||
*
|
||||
|
@ -124,6 +140,25 @@ void board_init_f(ulong dummy)
|
|||
printch('\n');
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_USB_UART
|
||||
rk_clrsetreg(&grf->uoc0_con[0],
|
||||
SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK,
|
||||
1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT |
|
||||
1 << COMMON_ON_N_SHIFT);
|
||||
rk_clrsetreg(&grf->uoc0_con[2],
|
||||
SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT);
|
||||
rk_clrsetreg(&grf->uoc0_con[3],
|
||||
OPMODE_MASK | XCVRSELECT_MASK |
|
||||
TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK,
|
||||
OPMODE_NODRIVING << OPMODE_SHIFT |
|
||||
XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT |
|
||||
1 << TERMSEL_FULLSPEED_SHIFT |
|
||||
1 << SUSPENDN_SHIFT);
|
||||
rk_clrsetreg(&grf->uoc0_con[0],
|
||||
BYPASSSEL_MASK | BYPASSDMEN_MASK,
|
||||
1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT);
|
||||
#endif
|
||||
|
||||
ret = spl_early_init();
|
||||
if (ret) {
|
||||
debug("spl_early_init() failed: %d\n", ret);
|
||||
|
|
|
@ -202,13 +202,13 @@ void board_init_f(ulong dummy)
|
|||
|
||||
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
|
||||
if (ret) {
|
||||
debug("Pinctrl init failed: %d\n", ret);
|
||||
pr_err("Pinctrl init failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
|
||||
if (ret) {
|
||||
debug("DRAM init failed: %d\n", ret);
|
||||
pr_err("DRAM init failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
81
arch/arm/mach-rockchip/rv1108-board.c
Normal file
81
arch/arm/mach-rockchip/rv1108-board.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
|
||||
#include <usb.h>
|
||||
#include <usb/dwc2_udc.h>
|
||||
|
||||
static struct dwc2_plat_otg_data rv1108_otg_data = {
|
||||
.rx_fifo_sz = 512,
|
||||
.np_tx_fifo_sz = 16,
|
||||
.tx_fifo_sz = 128,
|
||||
};
|
||||
|
||||
int board_usb_init(int index, enum usb_init_type init)
|
||||
{
|
||||
const void *blob = gd->fdt_blob;
|
||||
bool matched = false;
|
||||
int node, phy_node;
|
||||
u32 grf_phy_offset;
|
||||
const char *mode;
|
||||
|
||||
/* find the usb_otg node */
|
||||
node = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3066-usb");
|
||||
while (node > 0) {
|
||||
mode = fdt_getprop(blob, node, "dr_mode", NULL);
|
||||
if (mode && strcmp(mode, "otg") == 0) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, node,
|
||||
"rockchip,rk3066-usb");
|
||||
}
|
||||
|
||||
if (!matched) {
|
||||
debug("usb_otg device not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rv1108_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
|
||||
|
||||
node = fdtdec_lookup_phandle(blob, node, "phys");
|
||||
if (node <= 0) {
|
||||
debug("phys node not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_node = fdt_parent_offset(blob, node);
|
||||
if (phy_node <= 0) {
|
||||
debug("usb phy node not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rv1108_otg_data.phy_of_node = phy_node;
|
||||
grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
|
||||
|
||||
/* find the grf node */
|
||||
node = fdt_node_offset_by_compatible(blob, -1,
|
||||
"rockchip,rv1108-grf");
|
||||
if (node <= 0) {
|
||||
debug("grf node not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rv1108_otg_data.regs_phy = grf_phy_offset + fdtdec_get_addr(blob, node,
|
||||
"reg");
|
||||
|
||||
return dwc2_udc_probe(&rv1108_otg_data);
|
||||
}
|
||||
|
||||
int board_usb_cleanup(int index, enum usb_init_type init)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -56,6 +56,5 @@ CONFIG_ROCKCHIP_TIMER=y
|
|||
CONFIG_USB=y
|
||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
||||
CONFIG_SPL_TINY_MEMSET=y
|
||||
CONFIG_TPL_TINY_MEMSET=y
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
CONFIG_ERRNO_STR=y
|
||||
|
|
|
@ -61,6 +61,11 @@ static const struct pll_div *apll_l_cfgs[] = {
|
|||
[APLL_L_600_MHZ] = &apll_l_600_cfg,
|
||||
};
|
||||
|
||||
static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
|
||||
static const struct pll_div *apll_b_cfgs[] = {
|
||||
[APLL_B_600_MHZ] = &apll_b_600_cfg,
|
||||
};
|
||||
|
||||
enum {
|
||||
/* PLL_CON0 */
|
||||
PLL_FBDIV_MASK = 0xfff,
|
||||
|
@ -128,6 +133,24 @@ enum {
|
|||
ATCLK_CORE_L_DIV_SHIFT = 0,
|
||||
ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL_CON2 */
|
||||
ACLKM_CORE_B_DIV_CON_SHIFT = 8,
|
||||
ACLKM_CORE_B_DIV_CON_MASK = 0x1f << ACLKM_CORE_B_DIV_CON_SHIFT,
|
||||
CLK_CORE_B_PLL_SEL_SHIFT = 6,
|
||||
CLK_CORE_B_PLL_SEL_MASK = 3 << CLK_CORE_B_PLL_SEL_SHIFT,
|
||||
CLK_CORE_B_PLL_SEL_ALPLL = 0x0,
|
||||
CLK_CORE_B_PLL_SEL_ABPLL = 0x1,
|
||||
CLK_CORE_B_PLL_SEL_DPLL = 0x10,
|
||||
CLK_CORE_B_PLL_SEL_GPLL = 0x11,
|
||||
CLK_CORE_B_DIV_MASK = 0x1f,
|
||||
CLK_CORE_B_DIV_SHIFT = 0,
|
||||
|
||||
/* CLKSEL_CON3 */
|
||||
PCLK_DBG_B_DIV_SHIFT = 0x8,
|
||||
PCLK_DBG_B_DIV_MASK = 0x1f << PCLK_DBG_B_DIV_SHIFT,
|
||||
ATCLK_CORE_B_DIV_SHIFT = 0,
|
||||
ATCLK_CORE_B_DIV_MASK = 0x1f << ATCLK_CORE_B_DIV_SHIFT,
|
||||
|
||||
/* CLKSEL_CON14 */
|
||||
PCLK_PERIHP_DIV_CON_SHIFT = 12,
|
||||
PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
|
||||
|
@ -395,25 +418,26 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rk3399_configure_cpu(struct rk3399_cru *cru,
|
||||
enum apll_l_frequencies apll_l_freq)
|
||||
void rk3399_configure_cpu_l(struct rk3399_cru *cru,
|
||||
enum apll_l_frequencies apll_l_freq)
|
||||
{
|
||||
u32 aclkm_div;
|
||||
u32 pclk_dbg_div;
|
||||
u32 atclk_div;
|
||||
|
||||
/* Setup cluster L */
|
||||
rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
|
||||
|
||||
aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1;
|
||||
assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ &&
|
||||
aclkm_div = LPLL_HZ / ACLKM_CORE_L_HZ - 1;
|
||||
assert((aclkm_div + 1) * ACLKM_CORE_L_HZ == LPLL_HZ &&
|
||||
aclkm_div < 0x1f);
|
||||
|
||||
pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1;
|
||||
assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ &&
|
||||
pclk_dbg_div = LPLL_HZ / PCLK_DBG_L_HZ - 1;
|
||||
assert((pclk_dbg_div + 1) * PCLK_DBG_L_HZ == LPLL_HZ &&
|
||||
pclk_dbg_div < 0x1f);
|
||||
|
||||
atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1;
|
||||
assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ &&
|
||||
atclk_div = LPLL_HZ / ATCLK_CORE_L_HZ - 1;
|
||||
assert((atclk_div + 1) * ATCLK_CORE_L_HZ == LPLL_HZ &&
|
||||
atclk_div < 0x1f);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[0],
|
||||
|
@ -428,6 +452,42 @@ void rk3399_configure_cpu(struct rk3399_cru *cru,
|
|||
pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
|
||||
atclk_div << ATCLK_CORE_L_DIV_SHIFT);
|
||||
}
|
||||
|
||||
void rk3399_configure_cpu_b(struct rk3399_cru *cru,
|
||||
enum apll_b_frequencies apll_b_freq)
|
||||
{
|
||||
u32 aclkm_div;
|
||||
u32 pclk_dbg_div;
|
||||
u32 atclk_div;
|
||||
|
||||
/* Setup cluster B */
|
||||
rkclk_set_pll(&cru->apll_b_con[0], apll_b_cfgs[apll_b_freq]);
|
||||
|
||||
aclkm_div = BPLL_HZ / ACLKM_CORE_B_HZ - 1;
|
||||
assert((aclkm_div + 1) * ACLKM_CORE_B_HZ == BPLL_HZ &&
|
||||
aclkm_div < 0x1f);
|
||||
|
||||
pclk_dbg_div = BPLL_HZ / PCLK_DBG_B_HZ - 1;
|
||||
assert((pclk_dbg_div + 1) * PCLK_DBG_B_HZ == BPLL_HZ &&
|
||||
pclk_dbg_div < 0x1f);
|
||||
|
||||
atclk_div = BPLL_HZ / ATCLK_CORE_B_HZ - 1;
|
||||
assert((atclk_div + 1) * ATCLK_CORE_B_HZ == BPLL_HZ &&
|
||||
atclk_div < 0x1f);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[2],
|
||||
ACLKM_CORE_B_DIV_CON_MASK | CLK_CORE_B_PLL_SEL_MASK |
|
||||
CLK_CORE_B_DIV_MASK,
|
||||
aclkm_div << ACLKM_CORE_B_DIV_CON_SHIFT |
|
||||
CLK_CORE_B_PLL_SEL_ABPLL << CLK_CORE_B_PLL_SEL_SHIFT |
|
||||
0 << CLK_CORE_B_DIV_SHIFT);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[3],
|
||||
PCLK_DBG_B_DIV_MASK | ATCLK_CORE_B_DIV_MASK,
|
||||
pclk_dbg_div << PCLK_DBG_B_DIV_SHIFT |
|
||||
atclk_div << ATCLK_CORE_B_DIV_SHIFT);
|
||||
}
|
||||
|
||||
#define I2C_CLK_REG_MASK(bus) \
|
||||
(I2C_DIV_CON_MASK << \
|
||||
CLK_I2C ##bus## _DIV_CON_SHIFT | \
|
||||
|
@ -1026,7 +1086,8 @@ static void rkclk_init(struct rk3399_cru *cru)
|
|||
u32 hclk_div;
|
||||
u32 pclk_div;
|
||||
|
||||
rk3399_configure_cpu(cru, APLL_L_600_MHZ);
|
||||
rk3399_configure_cpu_l(cru, APLL_L_600_MHZ);
|
||||
rk3399_configure_cpu_b(cru, APLL_B_600_MHZ);
|
||||
/*
|
||||
* some cru registers changed by bootrom, we'd better reset them to
|
||||
* reset/default values described in TRM to avoid confusion in kernel.
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <dm/lists.h>
|
||||
#include <dt-bindings/clock/rv1108-cru.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
VCO_MAX_HZ = 2400U * 1000000,
|
||||
VCO_MIN_HZ = 600 * 1000000,
|
||||
|
@ -35,6 +37,9 @@ enum {
|
|||
#hz "Hz cannot be hit with PLL "\
|
||||
"divisors on line " __stringify(__LINE__));
|
||||
|
||||
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);
|
||||
|
||||
/* use integer mode */
|
||||
static inline int rv1108_pll_id(enum rk_clk_id clk_id)
|
||||
{
|
||||
|
@ -57,6 +62,58 @@ static inline int rv1108_pll_id(enum rk_clk_id clk_id)
|
|||
return id;
|
||||
}
|
||||
|
||||
static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
|
||||
const struct pll_div *div)
|
||||
{
|
||||
int pll_id = rv1108_pll_id(clk_id);
|
||||
struct rv1108_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: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\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);
|
||||
|
||||
/*
|
||||
* When power on or changing PLL setting,
|
||||
* we must force PLL into slow mode to ensure output stable clock.
|
||||
*/
|
||||
rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
|
||||
WORK_MODE_SLOW << WORK_MODE_SHIFT);
|
||||
|
||||
/* use integer mode */
|
||||
rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
|
||||
/* Power down */
|
||||
rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
|
||||
|
||||
rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
|
||||
rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
|
||||
(div->postdiv1 << POSTDIV1_SHIFT |
|
||||
div->postdiv2 << POSTDIV2_SHIFT |
|
||||
div->refdiv << REFDIV_SHIFT));
|
||||
rk_clrsetreg(&pll->con2, FRACDIV_MASK,
|
||||
(div->refdiv << REFDIV_SHIFT));
|
||||
|
||||
/* Power Up */
|
||||
rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
|
||||
|
||||
/* waiting for pll lock */
|
||||
while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
|
||||
udelay(1);
|
||||
|
||||
/*
|
||||
* set PLL into normal mode.
|
||||
*/
|
||||
rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
|
||||
WORK_MODE_NORMAL << WORK_MODE_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
|
||||
enum rk_clk_id clk_id)
|
||||
{
|
||||
|
@ -74,7 +131,7 @@ static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
|
|||
fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
|
||||
postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
|
||||
postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
|
||||
refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
|
||||
refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK;
|
||||
freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
|
||||
} else {
|
||||
freq = OSC_HZ;
|
||||
|
@ -154,6 +211,326 @@ static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz)
|
|||
return rv1108_saradc_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
|
||||
val = readl(&cru->clksel_con[28]);
|
||||
div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
|
||||
CLK_VIO_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(GPLL_HZ, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[28],
|
||||
ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
|
||||
(src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
|
||||
(VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
|
||||
|
||||
return rv1108_aclk_vio1_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
|
||||
val = readl(&cru->clksel_con[28]);
|
||||
div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
|
||||
CLK_VIO_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(GPLL_HZ, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[28],
|
||||
ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
|
||||
(src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
|
||||
(VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
|
||||
|
||||
/*HCLK_VIO default div = 4*/
|
||||
rk_clrsetreg(&cru->clksel_con[29],
|
||||
HCLK_VIO_CLK_DIV_MASK,
|
||||
3 << HCLK_VIO_CLK_DIV_SHIFT);
|
||||
/*PCLK_VIO default div = 4*/
|
||||
rk_clrsetreg(&cru->clksel_con[29],
|
||||
PCLK_VIO_CLK_DIV_MASK,
|
||||
3 << PCLK_VIO_CLK_DIV_SHIFT);
|
||||
|
||||
return rv1108_aclk_vio0_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
|
||||
val = readl(&cru->clksel_con[32]);
|
||||
div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
|
||||
DCLK_VOP_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(GPLL_HZ, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
|
||||
assert(src_clk_div < 64);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[32],
|
||||
DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
|
||||
DCLK_VOP_SEL_SHIFT,
|
||||
(src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
|
||||
(DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
|
||||
(DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
|
||||
|
||||
return rv1108_dclk_vop_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
val = readl(&cru->clksel_con[2]);
|
||||
div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
|
||||
ACLK_BUS_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(parent_rate, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[2],
|
||||
ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
|
||||
(src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
|
||||
(ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
|
||||
|
||||
return rv1108_aclk_bus_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
val = readl(&cru->clksel_con[23]);
|
||||
div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
|
||||
PERI_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(parent_rate, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
val = readl(&cru->clksel_con[23]);
|
||||
div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
|
||||
PERI_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(parent_rate, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, val;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
val = readl(&cru->clksel_con[23]);
|
||||
div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
|
||||
PERI_DIV_CON_WIDTH);
|
||||
|
||||
return DIV_TO_RATE(parent_rate, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[23],
|
||||
ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
|
||||
(src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
|
||||
(ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
|
||||
|
||||
return rv1108_aclk_peri_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[23],
|
||||
HCLK_PERI_DIV_CON_MASK,
|
||||
(src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
|
||||
|
||||
return rv1108_hclk_peri_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
|
||||
assert(src_clk_div < 32);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[23],
|
||||
PCLK_PERI_DIV_CON_MASK,
|
||||
(src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
|
||||
|
||||
return rv1108_pclk_peri_get_clk(cru);
|
||||
}
|
||||
|
||||
static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id)
|
||||
{
|
||||
u32 div, con;
|
||||
|
||||
switch (clk_id) {
|
||||
case SCLK_I2C0_PMU:
|
||||
con = readl(&cru->clksel_con[19]);
|
||||
div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
|
||||
I2C_DIV_CON_WIDTH);
|
||||
break;
|
||||
case SCLK_I2C1:
|
||||
con = readl(&cru->clksel_con[19]);
|
||||
div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
|
||||
I2C_DIV_CON_WIDTH);
|
||||
break;
|
||||
case SCLK_I2C2:
|
||||
con = readl(&cru->clksel_con[20]);
|
||||
div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
|
||||
I2C_DIV_CON_WIDTH);
|
||||
break;
|
||||
case SCLK_I2C3:
|
||||
con = readl(&cru->clksel_con[20]);
|
||||
div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
|
||||
I2C_DIV_CON_WIDTH);
|
||||
break;
|
||||
default:
|
||||
printf("do not support this i2c bus\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return DIV_TO_RATE(GPLL_HZ, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz)
|
||||
{
|
||||
int src_clk_div;
|
||||
|
||||
/* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
|
||||
src_clk_div = GPLL_HZ / hz;
|
||||
assert(src_clk_div - 1 <= 127);
|
||||
|
||||
switch (clk_id) {
|
||||
case SCLK_I2C0_PMU:
|
||||
rk_clrsetreg(&cru->clksel_con[19],
|
||||
CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
|
||||
(src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
|
||||
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
|
||||
break;
|
||||
case SCLK_I2C1:
|
||||
rk_clrsetreg(&cru->clksel_con[19],
|
||||
CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
|
||||
(src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
|
||||
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
|
||||
break;
|
||||
case SCLK_I2C2:
|
||||
rk_clrsetreg(&cru->clksel_con[20],
|
||||
CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
|
||||
(src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
|
||||
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
|
||||
break;
|
||||
case SCLK_I2C3:
|
||||
rk_clrsetreg(&cru->clksel_con[20],
|
||||
CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
|
||||
(src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
|
||||
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
|
||||
break;
|
||||
default:
|
||||
printf("do not support this i2c bus\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rv1108_i2c_get_clk(cru, clk_id);
|
||||
}
|
||||
|
||||
static ulong rv1108_mmc_get_clk(struct rv1108_cru *cru)
|
||||
{
|
||||
u32 div, con;
|
||||
ulong mmc_clk;
|
||||
|
||||
con = readl(&cru->clksel_con[26]);
|
||||
div = bitfield_extract(con, EMMC_CLK_DIV_SHIFT, 8);
|
||||
|
||||
con = readl(&cru->clksel_con[25]);
|
||||
|
||||
if ((con & EMMC_PLL_SEL_MASK) >> EMMC_PLL_SEL_SHIFT == EMMC_PLL_SEL_OSC)
|
||||
mmc_clk = DIV_TO_RATE(OSC_HZ, div) / 2;
|
||||
else
|
||||
mmc_clk = DIV_TO_RATE(GPLL_HZ, div) / 2;
|
||||
|
||||
debug("%s div %d get_clk %ld\n", __func__, div, mmc_clk);
|
||||
return mmc_clk;
|
||||
}
|
||||
|
||||
static ulong rv1108_mmc_set_clk(struct rv1108_cru *cru, ulong rate)
|
||||
{
|
||||
int div;
|
||||
u32 pll_rate;
|
||||
|
||||
div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, CLK_GENERAL), rate);
|
||||
|
||||
if (div < 127) {
|
||||
debug("%s source gpll\n", __func__);
|
||||
rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
|
||||
(EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT));
|
||||
pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
} else {
|
||||
debug("%s source 24m\n", __func__);
|
||||
rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK,
|
||||
(EMMC_PLL_SEL_OSC << EMMC_PLL_SEL_SHIFT));
|
||||
pll_rate = OSC_HZ;
|
||||
}
|
||||
|
||||
div = DIV_ROUND_UP(pll_rate / 2, rate);
|
||||
rk_clrsetreg(&cru->clksel_con[26], EMMC_CLK_DIV_MASK,
|
||||
((div - 1) << EMMC_CLK_DIV_SHIFT));
|
||||
|
||||
debug("%s set_rate %ld div %d\n", __func__, rate, div);
|
||||
|
||||
return DIV_TO_RATE(pll_rate, div);
|
||||
}
|
||||
|
||||
static ulong rv1108_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
|
@ -163,6 +540,29 @@ static ulong rv1108_clk_get_rate(struct clk *clk)
|
|||
return rkclk_pll_get_rate(priv->cru, clk->id);
|
||||
case SCLK_SARADC:
|
||||
return rv1108_saradc_get_clk(priv->cru);
|
||||
case ACLK_VIO0:
|
||||
return rv1108_aclk_vio0_get_clk(priv->cru);
|
||||
case ACLK_VIO1:
|
||||
return rv1108_aclk_vio1_get_clk(priv->cru);
|
||||
case DCLK_VOP:
|
||||
return rv1108_dclk_vop_get_clk(priv->cru);
|
||||
case ACLK_PRE:
|
||||
return rv1108_aclk_bus_get_clk(priv->cru);
|
||||
case ACLK_PERI:
|
||||
return rv1108_aclk_peri_get_clk(priv->cru);
|
||||
case HCLK_PERI:
|
||||
return rv1108_hclk_peri_get_clk(priv->cru);
|
||||
case PCLK_PERI:
|
||||
return rv1108_pclk_peri_get_clk(priv->cru);
|
||||
case SCLK_I2C0_PMU:
|
||||
case SCLK_I2C1:
|
||||
case SCLK_I2C2:
|
||||
case SCLK_I2C3:
|
||||
return rv1108_i2c_get_clk(priv->cru, clk->id);
|
||||
case HCLK_EMMC:
|
||||
case SCLK_EMMC:
|
||||
case SCLK_EMMC_SAMPLE:
|
||||
return rv1108_mmc_get_clk(priv->cru);
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
@ -183,6 +583,37 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
|
|||
case SCLK_SARADC:
|
||||
new_rate = rv1108_saradc_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case ACLK_VIO0:
|
||||
new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case ACLK_VIO1:
|
||||
new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case DCLK_VOP:
|
||||
new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case ACLK_PRE:
|
||||
new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case ACLK_PERI:
|
||||
new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case HCLK_PERI:
|
||||
new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case PCLK_PERI:
|
||||
new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
|
||||
break;
|
||||
case SCLK_I2C0_PMU:
|
||||
case SCLK_I2C1:
|
||||
case SCLK_I2C2:
|
||||
case SCLK_I2C3:
|
||||
new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
|
||||
break;
|
||||
case HCLK_EMMC:
|
||||
case SCLK_EMMC:
|
||||
new_rate = rv1108_mmc_set_clk(priv->cru, rate);
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
@ -197,14 +628,34 @@ static const struct clk_ops rv1108_clk_ops = {
|
|||
|
||||
static void rkclk_init(struct rv1108_cru *cru)
|
||||
{
|
||||
unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
|
||||
unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
|
||||
unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
unsigned int apll, dpll, gpll;
|
||||
unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
|
||||
|
||||
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
|
||||
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
|
||||
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
|
||||
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
|
||||
rv1108_aclk_vio0_set_clk(cru, 297000000);
|
||||
rv1108_aclk_vio1_set_clk(cru, 297000000);
|
||||
|
||||
/* configure apll */
|
||||
rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
|
||||
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
|
||||
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
|
||||
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
|
||||
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
|
||||
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
|
||||
|
||||
apll = rkclk_pll_get_rate(cru, CLK_ARM);
|
||||
dpll = rkclk_pll_get_rate(cru, CLK_DDR);
|
||||
gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
|
||||
|
||||
rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
|
||||
0 << MAC_CLK_DIV_SHIFT);
|
||||
|
||||
printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
|
||||
printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
|
||||
aclk_bus, aclk_peri, hclk_peri, pclk_peri);
|
||||
}
|
||||
|
||||
static int rv1108_clk_ofdata_to_platdata(struct udevice *dev)
|
||||
|
@ -228,8 +679,9 @@ static int rv1108_clk_probe(struct udevice *dev)
|
|||
static int rv1108_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct udevice *sys_child, *sf_child;
|
||||
struct sysreset_reg *priv;
|
||||
struct softreset_reg *sf_priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
|
@ -251,6 +703,17 @@ static int rv1108_clk_bind(struct udevice *dev)
|
|||
if (ret)
|
||||
debug("Warning: software reset driver bind faile\n");
|
||||
#endif
|
||||
ret = device_bind_driver_to_node(dev, "rockchip_reset", "reset",
|
||||
dev_ofnode(dev), &sf_child);
|
||||
if (ret) {
|
||||
debug("Warning: No rockchip reset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
sf_priv = malloc(sizeof(struct softreset_reg));
|
||||
sf_priv->sf_reset_offset = offsetof(struct rv1108_cru,
|
||||
softrst_con[0]);
|
||||
sf_priv->sf_reset_num = 13;
|
||||
sf_child->priv = sf_priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -265,8 +728,8 @@ U_BOOT_DRIVER(clk_rv1108) = {
|
|||
.id = UCLASS_CLK,
|
||||
.of_match = rv1108_clk_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct rv1108_clk_priv),
|
||||
.ofdata_to_platdata = rv1108_clk_ofdata_to_platdata,
|
||||
.ops = &rv1108_clk_ops,
|
||||
.bind = rv1108_clk_bind,
|
||||
.ofdata_to_platdata = rv1108_clk_ofdata_to_platdata,
|
||||
.probe = rv1108_clk_probe,
|
||||
};
|
||||
|
|
|
@ -60,6 +60,16 @@ config RTC_ISL1208
|
|||
This driver supports reading and writing the RTC/calendar and detects
|
||||
total power failures.
|
||||
|
||||
config RTC_RV3029
|
||||
bool "Enable RV3029 driver"
|
||||
depends on DM_RTC
|
||||
help
|
||||
The MicroCrystal RV3029 is a I2C Real Time Clock (RTC) with 8-byte
|
||||
battery-backed SRAM.
|
||||
|
||||
This driver supports reading and writing the RTC/calendar and the
|
||||
battery-baced SRAM section.
|
||||
|
||||
config RTC_RX8010SJ
|
||||
bool "Enable RX8010SJ driver"
|
||||
depends on DM_RTC
|
||||
|
|
|
@ -1,189 +1,495 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2010
|
||||
* Heiko Schocher, DENX Software Engineering, hs@denx.de
|
||||
* (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
* Based on a the Linux rtc-rv3029c2.c driver written by:
|
||||
* Gregory Hermant <gregory.hermant@calao-systems.com>
|
||||
* Michael Buesch <m@bues.ch>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#define RTC_RV3029_CTRL1 0x00
|
||||
#define RTC_RV3029_CTRL1_EERE (1 << 3)
|
||||
#define RTC_RV3029_PAGE_LEN 7
|
||||
|
||||
#define RTC_RV3029_CTRL_STATUS 0x03
|
||||
#define RTC_RV3029_CTRLS_EEBUSY (1 << 7)
|
||||
/* control section */
|
||||
#define RV3029_ONOFF_CTRL 0x00
|
||||
#define RV3029_ONOFF_CTRL_WE BIT(0)
|
||||
#define RV3029_ONOFF_CTRL_TE BIT(1)
|
||||
#define RV3029_ONOFF_CTRL_TAR BIT(2)
|
||||
#define RV3029_ONOFF_CTRL_EERE BIT(3)
|
||||
#define RV3029_ONOFF_CTRL_SRON BIT(4)
|
||||
#define RV3029_ONOFF_CTRL_TD0 BIT(5)
|
||||
#define RV3029_ONOFF_CTRL_TD1 BIT(6)
|
||||
#define RV3029_ONOFF_CTRL_CLKINT BIT(7)
|
||||
#define RV3029_IRQ_CTRL 0x01
|
||||
#define RV3029_IRQ_CTRL_AIE BIT(0)
|
||||
#define RV3029_IRQ_CTRL_TIE BIT(1)
|
||||
#define RV3029_IRQ_CTRL_V1IE BIT(2)
|
||||
#define RV3029_IRQ_CTRL_V2IE BIT(3)
|
||||
#define RV3029_IRQ_CTRL_SRIE BIT(4)
|
||||
#define RV3029_IRQ_FLAGS 0x02
|
||||
#define RV3029_IRQ_FLAGS_AF BIT(0)
|
||||
#define RV3029_IRQ_FLAGS_TF BIT(1)
|
||||
#define RV3029_IRQ_FLAGS_V1IF BIT(2)
|
||||
#define RV3029_IRQ_FLAGS_V2IF BIT(3)
|
||||
#define RV3029_IRQ_FLAGS_SRF BIT(4)
|
||||
#define RV3029_STATUS 0x03
|
||||
#define RV3029_STATUS_VLOW1 BIT(2)
|
||||
#define RV3029_STATUS_VLOW2 BIT(3)
|
||||
#define RV3029_STATUS_SR BIT(4)
|
||||
#define RV3029_STATUS_PON BIT(5)
|
||||
#define RV3029_STATUS_EEBUSY BIT(7)
|
||||
#define RV3029_RST_CTRL 0x04
|
||||
#define RV3029_RST_CTRL_SYSR BIT(4)
|
||||
#define RV3029_CONTROL_SECTION_LEN 0x05
|
||||
|
||||
#define RTC_RV3029_CTRL_RESET 0x04
|
||||
#define RTC_RV3029_CTRL_SYS_R (1 << 4)
|
||||
/* watch section */
|
||||
#define RV3029_W_SEC 0x08
|
||||
#define RV3029_W_MINUTES 0x09
|
||||
#define RV3029_W_HOURS 0x0A
|
||||
#define RV3029_REG_HR_12_24 BIT(6) /* 24h/12h mode */
|
||||
#define RV3029_REG_HR_PM BIT(5) /* PM/AM bit in 12h mode */
|
||||
#define RV3029_W_DATE 0x0B
|
||||
#define RV3029_W_DAYS 0x0C
|
||||
#define RV3029_W_MONTHS 0x0D
|
||||
#define RV3029_W_YEARS 0x0E
|
||||
|
||||
#define RTC_RV3029_CLOCK_PAGE 0x08
|
||||
#define RTC_RV3029_PAGE_LEN 7
|
||||
/* eeprom control section */
|
||||
#define RV3029_CONTROL_E2P_EECTRL 0x30
|
||||
#define RV3029_TRICKLE_1K BIT(4) /* 1.5K resistance */
|
||||
#define RV3029_TRICKLE_5K BIT(5) /* 5K resistance */
|
||||
#define RV3029_TRICKLE_20K BIT(6) /* 20K resistance */
|
||||
#define RV3029_TRICKLE_80K BIT(7) /* 80K resistance */
|
||||
#define RV3029_TRICKLE_MASK (RV3029_TRICKLE_1K |\
|
||||
RV3029_TRICKLE_5K |\
|
||||
RV3029_TRICKLE_20K |\
|
||||
RV3029_TRICKLE_80K)
|
||||
#define RV3029_TRICKLE_SHIFT 4
|
||||
|
||||
#define RV3029C2_W_SECONDS 0x00
|
||||
#define RV3029C2_W_MINUTES 0x01
|
||||
#define RV3029C2_W_HOURS 0x02
|
||||
#define RV3029C2_W_DATE 0x03
|
||||
#define RV3029C2_W_DAYS 0x04
|
||||
#define RV3029C2_W_MONTHS 0x05
|
||||
#define RV3029C2_W_YEARS 0x06
|
||||
|
||||
#define RV3029C2_REG_HR_12_24 (1 << 6) /* 24h/12h mode */
|
||||
#define RV3029C2_REG_HR_PM (1 << 5) /* PM/AM bit in 12h mode */
|
||||
|
||||
#define RTC_RV3029_EEPROM_CTRL 0x30
|
||||
#define RTC_RV3029_TRICKLE_1K (1 << 4)
|
||||
#define RTC_RV3029_TRICKLE_5K (1 << 5)
|
||||
#define RTC_RV3029_TRICKLE_20K (1 << 6)
|
||||
#define RTC_RV3029_TRICKLE_80K (1 << 7)
|
||||
|
||||
int rtc_get( struct rtc_time *tmp )
|
||||
static int rv3029_rtc_get(struct udevice *dev, struct rtc_time *tm)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[RTC_RV3029_PAGE_LEN];
|
||||
u8 regs[RTC_RV3029_PAGE_LEN];
|
||||
int ret;
|
||||
|
||||
ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, buf, \
|
||||
RTC_RV3029_PAGE_LEN);
|
||||
if (ret) {
|
||||
ret = dm_i2c_read(dev, RV3029_W_SEC, regs, sizeof(regs));
|
||||
if (ret < 0) {
|
||||
printf("%s: error reading RTC: %x\n", __func__, ret);
|
||||
return -1;
|
||||
return -EIO;
|
||||
}
|
||||
tmp->tm_sec = bcd2bin( buf[RV3029C2_W_SECONDS] & 0x7f);
|
||||
tmp->tm_min = bcd2bin( buf[RV3029C2_W_MINUTES] & 0x7f);
|
||||
if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_12_24) {
|
||||
/* 12h format */
|
||||
tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x1f);
|
||||
if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_PM)
|
||||
/* PM flag set */
|
||||
tmp->tm_hour += 12;
|
||||
} else
|
||||
tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x3f);
|
||||
|
||||
tmp->tm_mday = bcd2bin( buf[RV3029C2_W_DATE] & 0x3F );
|
||||
tmp->tm_mon = bcd2bin( buf[RV3029C2_W_MONTHS] & 0x1F );
|
||||
tmp->tm_wday = bcd2bin( buf[RV3029C2_W_DAYS] & 0x07 );
|
||||
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
|
||||
tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
|
||||
|
||||
/* HR field has a more complex interpretation */
|
||||
{
|
||||
const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
|
||||
|
||||
if (_hr & RV3029_REG_HR_12_24) {
|
||||
/* 12h format */
|
||||
tm->tm_hour = bcd2bin(_hr & 0x1f);
|
||||
if (_hr & RV3029_REG_HR_PM) /* PM flag set */
|
||||
tm->tm_hour += 12;
|
||||
} else {
|
||||
/* 24h format */
|
||||
tm->tm_hour = bcd2bin(_hr & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
|
||||
tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
|
||||
/* RTC supports only years > 1999 */
|
||||
tmp->tm_year = bcd2bin( buf[RV3029C2_W_YEARS]) + 2000;
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst = 0;
|
||||
tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 2000;
|
||||
tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
|
||||
|
||||
debug( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
|
||||
tm->tm_yday = 0;
|
||||
tm->tm_isdst = 0;
|
||||
|
||||
debug("%s: %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
|
||||
__func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_set( struct rtc_time *tmp )
|
||||
static int rv3029_rtc_set(struct udevice *dev, const struct rtc_time *tm)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[RTC_RV3029_PAGE_LEN];
|
||||
u8 regs[RTC_RV3029_PAGE_LEN];
|
||||
|
||||
debug( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
debug("%s: %4d-%02d-%02d (wday=%d( %2d:%02d:%02d\n",
|
||||
__func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
if (tmp->tm_year < 2000) {
|
||||
printf("RTC: year %d < 2000 not possible\n", tmp->tm_year);
|
||||
return -1;
|
||||
|
||||
if (tm->tm_year < 2000) {
|
||||
printf("%s: year %d (before 2000) not supported\n",
|
||||
__func__, tm->tm_year);
|
||||
return -EINVAL;
|
||||
}
|
||||
buf[RV3029C2_W_SECONDS] = bin2bcd(tmp->tm_sec);
|
||||
buf[RV3029C2_W_MINUTES] = bin2bcd(tmp->tm_min);
|
||||
buf[RV3029C2_W_HOURS] = bin2bcd(tmp->tm_hour);
|
||||
/* set 24h format */
|
||||
buf[RV3029C2_W_HOURS] &= ~RV3029C2_REG_HR_12_24;
|
||||
buf[RV3029C2_W_DATE] = bin2bcd(tmp->tm_mday);
|
||||
buf[RV3029C2_W_DAYS] = bin2bcd(tmp->tm_wday);
|
||||
buf[RV3029C2_W_MONTHS] = bin2bcd(tmp->tm_mon);
|
||||
tmp->tm_year -= 2000;
|
||||
buf[RV3029C2_W_YEARS] = bin2bcd(tmp->tm_year);
|
||||
ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1,
|
||||
buf, RTC_RV3029_PAGE_LEN);
|
||||
|
||||
/* give the RTC some time to update */
|
||||
udelay(1000);
|
||||
return ret;
|
||||
regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
|
||||
regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
|
||||
regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
|
||||
regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
|
||||
regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
|
||||
regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
|
||||
regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 2000);
|
||||
|
||||
return dm_i2c_write(dev, RV3029_W_SEC, regs, sizeof(regs));
|
||||
}
|
||||
|
||||
/* sets EERE-Bit (automatic EEPROM refresh) */
|
||||
static void set_eere_bit(int state)
|
||||
static int rv3029_rtc_reset(struct udevice *dev)
|
||||
{
|
||||
unsigned char reg_ctrl1;
|
||||
u8 ctrl = RV3029_RST_CTRL_SYSR;
|
||||
unsigned long start;
|
||||
const unsigned long timeout_ms = 10000;
|
||||
int ret;
|
||||
|
||||
(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
|
||||
®_ctrl1, 1);
|
||||
/* trigger the system-reset */
|
||||
ret = dm_i2c_write(dev, RV3029_RST_CTRL, &ctrl, 1);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
if (state)
|
||||
reg_ctrl1 |= RTC_RV3029_CTRL1_EERE;
|
||||
else
|
||||
reg_ctrl1 &= (~RTC_RV3029_CTRL1_EERE);
|
||||
/* wait for the system-reset to complete */
|
||||
start = get_timer(0);
|
||||
do {
|
||||
if (get_timer(start) > timeout_ms)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
|
||||
®_ctrl1, 1);
|
||||
ret = dm_i2c_read(dev, RV3029_RST_CTRL, &ctrl, 1);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
} while (ctrl & RV3029_RST_CTRL_SYSR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* waits until EEPROM page is no longer busy (times out after 10ms*loops) */
|
||||
static int wait_eebusy(int loops)
|
||||
static int rv3029_rtc_read8(struct udevice *dev, unsigned int reg)
|
||||
{
|
||||
int i;
|
||||
unsigned char ctrl_status;
|
||||
u8 data;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < loops; i++) {
|
||||
(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_STATUS,
|
||||
1, &ctrl_status, 1);
|
||||
ret = dm_i2c_read(dev, reg, &data, sizeof(data));
|
||||
return ret < 0 ? ret : data;
|
||||
}
|
||||
|
||||
if ((ctrl_status & RTC_RV3029_CTRLS_EEBUSY) == 0)
|
||||
static int rv3029_rtc_write8(struct udevice *dev, unsigned int reg, int val)
|
||||
{
|
||||
u8 data = val;
|
||||
|
||||
return dm_i2c_write(dev, reg, &data, 1);
|
||||
}
|
||||
|
||||
#if defined(OF_CONTROL)
|
||||
static int rv3029_get_sr(struct udevice *dev, u8 *buf)
|
||||
{
|
||||
int ret = dm_i2c_read(dev, RV3029_STATUS, buf, 1);
|
||||
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv3029_set_sr(struct udevice *dev, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, RV3029_STATUS, &val, 1);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
dev_dbg(dev, "status = 0x%.2x (%d)\n", val, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_busywait(struct udevice *dev)
|
||||
{
|
||||
int i, ret;
|
||||
u8 sr;
|
||||
|
||||
for (i = 100; i > 0; i--) {
|
||||
ret = rv3029_get_sr(dev, &sr);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (!(sr & RV3029_STATUS_EEBUSY))
|
||||
break;
|
||||
udelay(10000);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
unsigned char buf[RTC_RV3029_PAGE_LEN];
|
||||
|
||||
buf[0] = RTC_RV3029_CTRL_SYS_R;
|
||||
(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1,
|
||||
buf, 1);
|
||||
|
||||
#if defined(CONFIG_SYS_RV3029_TCR)
|
||||
/*
|
||||
* because EEPROM_CTRL register is in EEPROM page it is necessary to
|
||||
* disable automatic EEPROM refresh and check if EEPROM is busy
|
||||
* before EEPORM_CTRL register may be accessed
|
||||
*/
|
||||
set_eere_bit(0);
|
||||
wait_eebusy(100);
|
||||
/* read current trickle charger setting */
|
||||
(void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_EEPROM_CTRL,
|
||||
1, buf, 1);
|
||||
/* enable automatic EEPROM refresh again */
|
||||
set_eere_bit(1);
|
||||
|
||||
/*
|
||||
* to minimize EEPROM access write trickle charger setting only if it
|
||||
* differs from current value
|
||||
*/
|
||||
if ((buf[0] & 0xF0) != CONFIG_SYS_RV3029_TCR) {
|
||||
buf[0] = (buf[0] & 0x0F) | CONFIG_SYS_RV3029_TCR;
|
||||
/*
|
||||
* write trickle charger setting (disable autom. EEPROM
|
||||
* refresh and wait until EEPROM is idle)
|
||||
*/
|
||||
set_eere_bit(0);
|
||||
wait_eebusy(100);
|
||||
(void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR,
|
||||
RTC_RV3029_EEPROM_CTRL, 1, buf, 1);
|
||||
/*
|
||||
* it is necessary to wait 10ms before EEBUSY-Bit may be read
|
||||
* (this is not documented in the data sheet yet, but the
|
||||
* manufacturer recommends it)
|
||||
*/
|
||||
udelay(10000);
|
||||
/* wait until EEPROM write access is finished */
|
||||
wait_eebusy(100);
|
||||
set_eere_bit(1);
|
||||
if (i <= 0) {
|
||||
dev_err(dev, "EEPROM busy wait timeout.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rv3029_update_bits(struct udevice *dev, u8 reg, u8 mask, u8 set)
|
||||
{
|
||||
u8 buf;
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, &buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((buf & mask) == (set && mask))
|
||||
return 0;
|
||||
|
||||
buf = (buf & ~mask) | (set & mask);
|
||||
ret = dm_i2c_read(dev, reg, &buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_exit(struct udevice *dev)
|
||||
{
|
||||
/* Re-enable eeprom refresh */
|
||||
return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
|
||||
RV3029_ONOFF_CTRL_EERE,
|
||||
RV3029_ONOFF_CTRL_EERE);
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_enter(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
u8 sr;
|
||||
|
||||
/* Check whether we are in the allowed voltage range. */
|
||||
ret = rv3029_get_sr(dev, &sr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
|
||||
/* We clear the bits and retry once just in case
|
||||
* we had a brown out in early startup.
|
||||
*/
|
||||
sr &= ~RV3029_STATUS_VLOW1;
|
||||
sr &= ~RV3029_STATUS_VLOW2;
|
||||
ret = rv3029_set_sr(dev, sr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
udelay(10000);
|
||||
ret = rv3029_get_sr(dev, &sr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
|
||||
dev_err(dev, "Supply voltage is too low to safely access the EEPROM.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable eeprom refresh. */
|
||||
ret = rv3029_update_bits(dev,
|
||||
RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Wait for any previous eeprom accesses to finish. */
|
||||
ret = rv3029_eeprom_busywait(dev);
|
||||
if (ret < 0)
|
||||
rv3029_eeprom_exit(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_read(struct udevice *dev, u8 reg,
|
||||
u8 buf[], size_t len)
|
||||
{
|
||||
int ret, err;
|
||||
|
||||
err = rv3029_eeprom_enter(dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buf, len);
|
||||
|
||||
err = rv3029_eeprom_exit(dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_write(struct udevice *dev, u8 reg,
|
||||
u8 const buf[], size_t len)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
u8 tmp;
|
||||
|
||||
ret = rv3029_eeprom_enter(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < len; i++, reg++) {
|
||||
ret = dm_i2c_read(dev, reg, &tmp, 1);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (tmp != buf[i]) {
|
||||
ret = dm_i2c_write(dev, reg, &buf[i], 1);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
ret = rv3029_eeprom_busywait(dev);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = rv3029_eeprom_exit(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rv3029_eeprom_update_bits(struct udevice *dev,
|
||||
u8 reg, u8 mask, u8 set)
|
||||
{
|
||||
u8 buf;
|
||||
int ret;
|
||||
|
||||
ret = rv3029_eeprom_read(dev, reg, &buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If the EEPROM already reads the correct bitpattern, we don't need
|
||||
* to update it.
|
||||
*/
|
||||
if ((buf & mask) == (set & mask))
|
||||
return 0;
|
||||
|
||||
buf = (buf & ~mask) | (set & mask);
|
||||
ret = rv3029_eeprom_write(dev, reg, &buf, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rv3029_trickle_config(struct udevice *dev)
|
||||
{
|
||||
static const struct rv3029_trickle_tab_elem {
|
||||
u32 r; /* resistance in ohms */
|
||||
u8 conf; /* trickle config bits */
|
||||
} rv3029_trickle_tab[] = {
|
||||
{
|
||||
.r = 1076,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
|
||||
RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 1091,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
|
||||
RV3029_TRICKLE_20K,
|
||||
}, {
|
||||
.r = 1137,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
|
||||
RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 1154,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
|
||||
}, {
|
||||
.r = 1371,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
|
||||
RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 1395,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
|
||||
}, {
|
||||
.r = 1472,
|
||||
.conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 1500,
|
||||
.conf = RV3029_TRICKLE_1K,
|
||||
}, {
|
||||
.r = 3810,
|
||||
.conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
|
||||
RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 4000,
|
||||
.conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
|
||||
}, {
|
||||
.r = 4706,
|
||||
.conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 5000,
|
||||
.conf = RV3029_TRICKLE_5K,
|
||||
}, {
|
||||
.r = 16000,
|
||||
.conf = RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
|
||||
}, {
|
||||
.r = 20000,
|
||||
.conf = RV3029_TRICKLE_20K,
|
||||
}, {
|
||||
.r = 80000,
|
||||
.conf = RV3029_TRICKLE_80K,
|
||||
},
|
||||
};
|
||||
int err;
|
||||
u32 ohms;
|
||||
u8 trickle_set_bits = 0;
|
||||
|
||||
/* Configure the trickle charger. */
|
||||
err = dev_read_u32(dev, "trickle-resistor-ohms", &ohms);
|
||||
|
||||
if (!err) {
|
||||
/* Find trickle-charger config */
|
||||
for (int i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++)
|
||||
if (rv3029_trickle_tab[i].r >= ohms) {
|
||||
dev_dbg(dev, "trickle charger at %d ohms\n",
|
||||
rv3029_trickle_tab[i].r);
|
||||
trickle_set_bits = rv3029_trickle_tab[i].conf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "trickle charger config 0x%x\n", trickle_set_bits);
|
||||
err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
|
||||
RV3029_TRICKLE_MASK,
|
||||
trickle_set_bits);
|
||||
if (err < 0)
|
||||
dev_dbg(dev, "failed to update trickle charger\n");
|
||||
}
|
||||
#else
|
||||
static inline void rv3029_trickle_config(struct udevice *dev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rv3029_probe(struct udevice *dev)
|
||||
{
|
||||
i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
|
||||
DM_I2C_CHIP_WR_ADDRESS);
|
||||
|
||||
rv3029_trickle_config(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_ops rv3029_rtc_ops = {
|
||||
.get = rv3029_rtc_get,
|
||||
.set = rv3029_rtc_set,
|
||||
.read8 = rv3029_rtc_read8,
|
||||
.write8 = rv3029_rtc_write8,
|
||||
.reset = rv3029_rtc_reset,
|
||||
};
|
||||
|
||||
static const struct udevice_id rv3029_rtc_ids[] = {
|
||||
{ .compatible = "mc,rv3029" },
|
||||
{ .compatible = "mc,rv3029c2" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rtc_rv3029) = {
|
||||
.name = "rtc-rv3029",
|
||||
.id = UCLASS_RTC,
|
||||
.probe = rv3029_probe,
|
||||
.of_match = rv3029_rtc_ids,
|
||||
.ops = &rv3029_rtc_ops,
|
||||
};
|
||||
|
|
|
@ -106,7 +106,7 @@ int rk_mipi_dsi_enable(struct udevice *dev,
|
|||
rk_mipi_dsi_write(regs, VSYNC_ACTIVE_LOW, val);
|
||||
|
||||
val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
|
||||
rk_mipi_dsi_write(regs, DISPLAY_FLAGS_DE_LOW, val);
|
||||
rk_mipi_dsi_write(regs, DATAEN_ACTIVE_LOW, val);
|
||||
|
||||
val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
|
||||
rk_mipi_dsi_write(regs, COLORM_ACTIVE_LOW, val);
|
||||
|
@ -241,7 +241,7 @@ int rk_mipi_phy_enable(struct udevice *dev)
|
|||
|
||||
/* select the suitable value for fsfreqrang reg */
|
||||
for (i = 0; i < ARRAY_SIZE(freq_rang); i++) {
|
||||
if (ddr_clk / (MHz) >= freq_rang[i][0])
|
||||
if (ddr_clk / (MHz) <= freq_rang[i][0])
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(freq_rang)) {
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
/*
|
||||
* Default environment settings
|
||||
*/
|
||||
#undef CONFIG_EXTRA_ENV_SETTINGS
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"netdev=eth0\0" \
|
||||
"ipaddr=172.16.12.50\0" \
|
||||
"serverip=172.16.12.69\0" \
|
||||
""
|
||||
|
||||
#undef CONFIG_BOOTCOMMAND
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"sf probe;" \
|
||||
"sf read 0x62000000 0x140800 0x500000;" \
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#define CONFIG_SYS_TIMER_BASE 0x10350020
|
||||
#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
|
||||
|
||||
/* MMC/SD IP block */
|
||||
#define CONFIG_BOUNCE_BUFFER
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x60000000
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x100000)
|
||||
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x2000000)
|
||||
|
@ -25,3 +28,18 @@
|
|||
#define CONFIG_USB_OHCI_NEW
|
||||
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#define ENV_MEM_LAYOUT_SETTINGS \
|
||||
"scriptaddr=0x60000000\0" \
|
||||
"fdt_addr_r=0x61f00000\0" \
|
||||
"kernel_addr_r=0x62000000\0" \
|
||||
"ramdisk_addr_r=0x64000000\0"
|
||||
|
||||
#include <config_distro_bootcmd.h>
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
ENV_MEM_LAYOUT_SETTINGS \
|
||||
"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
|
||||
"partitions=" PARTS_DEFAULT \
|
||||
BOOTENV
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#define ARMCLK 3
|
||||
|
||||
/* sclk gates (special clocks) */
|
||||
#define SCLK_MAC 64
|
||||
#define SCLK_SPI0 65
|
||||
#define SCLK_NANDC 67
|
||||
#define SCLK_SDMMC 68
|
||||
|
@ -35,20 +34,77 @@
|
|||
#define SCLK_SDMMC_SAMPLE 84
|
||||
#define SCLK_SDIO_SAMPLE 85
|
||||
#define SCLK_EMMC_SAMPLE 86
|
||||
#define SCLK_MAC_RX 87
|
||||
#define SCLK_MAC_TX 88
|
||||
#define SCLK_MACREF 89
|
||||
#define SCLK_MACREF_OUT 90
|
||||
#define SCLK_SARADC 91
|
||||
#define SCLK_VENC_CORE 87
|
||||
#define SCLK_HEVC_CORE 88
|
||||
#define SCLK_HEVC_CABAC 89
|
||||
#define SCLK_PWM0_PMU 90
|
||||
#define SCLK_I2C0_PMU 91
|
||||
#define SCLK_WIFI 92
|
||||
#define SCLK_CIFOUT 93
|
||||
#define SCLK_MIPI_CSI_OUT 94
|
||||
#define SCLK_CIF0 95
|
||||
#define SCLK_CIF1 96
|
||||
#define SCLK_CIF2 97
|
||||
#define SCLK_CIF3 98
|
||||
#define SCLK_DSP 99
|
||||
#define SCLK_DSP_IOP 100
|
||||
#define SCLK_DSP_EPP 101
|
||||
#define SCLK_DSP_EDP 102
|
||||
#define SCLK_DSP_EDAP 103
|
||||
#define SCLK_CVBS_HOST 104
|
||||
#define SCLK_HDMI_SFR 105
|
||||
#define SCLK_HDMI_CEC 106
|
||||
#define SCLK_CRYPTO 107
|
||||
#define SCLK_SPI 108
|
||||
#define SCLK_SARADC 109
|
||||
#define SCLK_TSADC 110
|
||||
#define SCLK_MAC_PRE 111
|
||||
#define SCLK_MAC 112
|
||||
#define SCLK_MAC_RX 113
|
||||
#define SCLK_MAC_REF 114
|
||||
#define SCLK_MAC_REFOUT 115
|
||||
#define SCLK_DSP_PFM 116
|
||||
#define SCLK_RGA 117
|
||||
#define SCLK_I2C1 118
|
||||
#define SCLK_I2C2 119
|
||||
#define SCLK_I2C3 120
|
||||
#define SCLK_PWM 121
|
||||
#define SCLK_ISP 122
|
||||
#define SCLK_USBPHY 123
|
||||
#define SCLK_I2S0_SRC 124
|
||||
#define SCLK_I2S1_SRC 125
|
||||
#define SCLK_I2S2_SRC 126
|
||||
#define SCLK_UART0_SRC 127
|
||||
#define SCLK_UART1_SRC 128
|
||||
#define SCLK_UART2_SRC 129
|
||||
#define SCLK_MAC_TX 130
|
||||
#define SCLK_MACREF 131
|
||||
#define SCLK_MACREF_OUT 132
|
||||
|
||||
#define DCLK_VOP_SRC 185
|
||||
#define DCLK_HDMIPHY 186
|
||||
#define DCLK_VOP 187
|
||||
|
||||
/* aclk gates */
|
||||
#define ACLK_DMAC 192
|
||||
#define ACLK_PRE 193
|
||||
#define ACLK_CORE 194
|
||||
#define ACLK_ENMCORE 195
|
||||
#define ACLK_GMAC 196
|
||||
|
||||
#define ACLK_RKVENC 196
|
||||
#define ACLK_RKVDEC 197
|
||||
#define ACLK_VPU 198
|
||||
#define ACLK_CIF0 199
|
||||
#define ACLK_VIO0 200
|
||||
#define ACLK_VIO1 201
|
||||
#define ACLK_VOP 202
|
||||
#define ACLK_IEP 203
|
||||
#define ACLK_RGA 204
|
||||
#define ACLK_ISP 205
|
||||
#define ACLK_CIF1 206
|
||||
#define ACLK_CIF2 207
|
||||
#define ACLK_CIF3 208
|
||||
#define ACLK_PERI 209
|
||||
#define ACLK_GMAC 210
|
||||
|
||||
/* pclk gates */
|
||||
#define PCLK_GPIO1 256
|
||||
|
@ -67,12 +123,24 @@
|
|||
#define PCLK_PWM 269
|
||||
#define PCLK_TIMER 270
|
||||
#define PCLK_PERI 271
|
||||
#define PCLK_GMAC 272
|
||||
#define PCLK_SARADC 273
|
||||
#define PCLK_GPIO0_PMU 272
|
||||
#define PCLK_I2C0_PMU 273
|
||||
#define PCLK_PWM0_PMU 274
|
||||
#define PCLK_ISP 275
|
||||
#define PCLK_VIO 276
|
||||
#define PCLK_MIPI_DSI 277
|
||||
#define PCLK_HDMI_CTRL 278
|
||||
#define PCLK_SARADC 279
|
||||
#define PCLK_DSP_CFG 280
|
||||
#define PCLK_BUS 281
|
||||
#define PCLK_EFUSE0 282
|
||||
#define PCLK_EFUSE1 283
|
||||
#define PCLK_WDT 284
|
||||
#define PCLK_GMAC 285
|
||||
|
||||
/* hclk gates */
|
||||
#define HCLK_I2S0_8CH 320
|
||||
#define HCLK_I2S1_8CH 321
|
||||
#define HCLK_I2S1_2CH 321
|
||||
#define HCLK_I2S2_2CH 322
|
||||
#define HCLK_NANDC 323
|
||||
#define HCLK_SDMMC 324
|
||||
|
@ -80,20 +148,37 @@
|
|||
#define HCLK_EMMC 326
|
||||
#define HCLK_PERI 327
|
||||
#define HCLK_SFC 328
|
||||
#define HCLK_RKVENC 329
|
||||
#define HCLK_RKVDEC 330
|
||||
#define HCLK_CIF0 331
|
||||
#define HCLK_VIO 332
|
||||
#define HCLK_VOP 333
|
||||
#define HCLK_IEP 334
|
||||
#define HCLK_RGA 335
|
||||
#define HCLK_ISP 336
|
||||
#define HCLK_CRYPTO_MST 337
|
||||
#define HCLK_CRYPTO_SLV 338
|
||||
#define HCLK_HOST0 339
|
||||
#define HCLK_OTG 340
|
||||
#define HCLK_CIF1 341
|
||||
#define HCLK_CIF2 342
|
||||
#define HCLK_CIF3 343
|
||||
#define HCLK_BUS 344
|
||||
#define HCLK_VPU 345
|
||||
|
||||
#define CLK_NR_CLKS (HCLK_SFC + 1)
|
||||
#define CLK_NR_CLKS (HCLK_VPU + 1)
|
||||
|
||||
/* reset id */
|
||||
#define SRST_CORE_PO_AD 0
|
||||
#define SRST_CORE_PO_AD 0
|
||||
#define SRST_CORE_AD 1
|
||||
#define SRST_L2_AD 2
|
||||
#define SRST_CPU_NIU_AD 3
|
||||
#define SRST_CPU_NIU_AD 3
|
||||
#define SRST_CORE_PO 4
|
||||
#define SRST_CORE 5
|
||||
#define SRST_L2 6
|
||||
#define SRST_L2 6
|
||||
#define SRST_CORE_DBG 8
|
||||
#define PRST_DBG 9
|
||||
#define RST_DAP 10
|
||||
#define RST_DAP 10
|
||||
#define PRST_DBG_NIU 11
|
||||
#define ARST_STRC_SYS_AD 15
|
||||
|
||||
|
@ -160,9 +245,9 @@
|
|||
#define HRST_SYSBUS 75
|
||||
#define PRST_USBGRF 76
|
||||
|
||||
#define ARST_PERIPH_NIU 80
|
||||
#define HRST_PERIPH_NIU 81
|
||||
#define PRST_PERIPH_NIU 82
|
||||
#define ARST_PERIPH_NIU 80
|
||||
#define HRST_PERIPH_NIU 81
|
||||
#define PRST_PERIPH_NIU 82
|
||||
#define HRST_PERIPH 83
|
||||
#define HRST_SDMMC 84
|
||||
#define HRST_SDIO 85
|
||||
|
@ -180,7 +265,7 @@
|
|||
#define HRST_HOST0_AUX 96
|
||||
#define HRST_HOST0_ARB 97
|
||||
#define SRST_HOST0_EHCIPHY 98
|
||||
#define SRST_HOST0_UTMI 99
|
||||
#define SRST_HOST0_UTMI 99
|
||||
#define SRST_USBPOR 100
|
||||
#define SRST_UTMI0 101
|
||||
#define SRST_UTMI1 102
|
||||
|
@ -227,21 +312,21 @@
|
|||
#define HRST_VPU_NIU 141
|
||||
#define ARST_VPU 142
|
||||
#define HRST_VPU 143
|
||||
#define ARST_RKVDEC_NIU 144
|
||||
#define HRST_RKVDEC_NIU 145
|
||||
#define ARST_RKVDEC_NIU 144
|
||||
#define HRST_RKVDEC_NIU 145
|
||||
#define ARST_RKVDEC 146
|
||||
#define HRST_RKVDEC 147
|
||||
#define SRST_RKVDEC_CABAC 148
|
||||
#define SRST_RKVDEC_CORE 149
|
||||
#define ARST_RKVENC_NIU 150
|
||||
#define HRST_RKVENC_NIU 151
|
||||
#define ARST_RKVENC_NIU 150
|
||||
#define HRST_RKVENC_NIU 151
|
||||
#define ARST_RKVENC 152
|
||||
#define HRST_RKVENC 153
|
||||
#define SRST_RKVENC_CORE 154
|
||||
|
||||
#define SRST_DSP_CORE 156
|
||||
#define SRST_DSP_SYS 157
|
||||
#define SRST_DSP_GLOBAL 158
|
||||
#define SRST_DSP_GLOBAL 158
|
||||
#define SRST_DSP_OECM 159
|
||||
#define PRST_DSP_IOP_NIU 160
|
||||
#define ARST_DSP_EPP_NIU 161
|
||||
|
@ -259,7 +344,7 @@
|
|||
#define SRST_PMU_I2C0 173
|
||||
#define PRST_PMU_I2C0 174
|
||||
#define PRST_PMU_GPIO0 175
|
||||
#define PRST_PMU_INTMEM 176
|
||||
#define PRST_PMU_INTMEM 176
|
||||
#define PRST_PMU_PWM0 177
|
||||
#define SRST_PMU_PWM0 178
|
||||
#define PRST_PMU_GRF 179
|
||||
|
|
|
@ -4054,7 +4054,6 @@ CONFIG_SYS_RTC_CNT
|
|||
CONFIG_SYS_RTC_OSCILLATOR
|
||||
CONFIG_SYS_RTC_REG_BASE_ADDR
|
||||
CONFIG_SYS_RTC_SETUP
|
||||
CONFIG_SYS_RV3029_TCR
|
||||
CONFIG_SYS_RX_ETH_BUFFER
|
||||
CONFIG_SYS_SATA
|
||||
CONFIG_SYS_SATA1
|
||||
|
|
Loading…
Reference in a new issue