From cd3e9062361d37dced6e09b081e3ace88922584d Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 9 Dec 2016 19:07:34 +0100 Subject: [PATCH] sunxi: Add clocks for DE2/HDMI/TCON This is needed for HDMI support, which will be added later. Signed-off-by: Jernej Skrabec [Icenowy: renamed back lcd0_ch0_clk_cfg, add PLL3 for DE2 on V3s, and add CONFIG_SUNXI_DE2] Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 40 +++++++++++++++++++ arch/arm/mach-sunxi/clock_sun6i.c | 28 +++++++++++++ board/sunxi/Kconfig | 5 +++ scripts/config_whitelist.txt | 1 + 4 files changed, 74 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 9e22e15633..775943688f 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -67,7 +67,11 @@ struct sunxi_ccm_reg { u32 dram_pll_cfg; /* 0xf8 PLL_DDR cfg register, A33 only */ u32 mbus_reset; /* 0xfc MBUS reset control, A33 only */ u32 dram_clk_gate; /* 0x100 DRAM module gating */ +#ifdef CONFIG_SUNXI_DE2 + u32 de_clk_cfg; /* 0x104 DE module clock */ +#else u32 be0_clk_cfg; /* 0x104 BE0 module clock */ +#endif u32 be1_clk_cfg; /* 0x108 BE1 module clock */ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ @@ -85,7 +89,11 @@ struct sunxi_ccm_reg { u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ u32 reserved15; u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ +#ifdef CONFIG_SUNXI_DE2 + u32 hdmi_slow_clk_cfg; /* 0x154 HDMI slow module clock */ +#else u32 ps_clk_cfg; /* 0x154 PS module clock */ +#endif u32 mtc_clk_cfg; /* 0x158 MTC module clock */ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ @@ -220,6 +228,15 @@ struct sunxi_ccm_reg { #define CCM_MIPI_PLL_CTRL_LDO_EN (0x3 << 22) #define CCM_MIPI_PLL_CTRL_EN (0x1 << 31) +#define CCM_PLL10_CTRL_M_SHIFT 0 +#define CCM_PLL10_CTRL_M_MASK (0xf << CCM_PLL10_CTRL_M_SHIFT) +#define CCM_PLL10_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_PLL10_CTRL_N_SHIFT 8 +#define CCM_PLL10_CTRL_N_MASK (0x7f << CCM_PLL10_CTRL_N_SHIFT) +#define CCM_PLL10_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) +#define CCM_PLL10_CTRL_INTEGER_MODE (0x1 << 24) +#define CCM_PLL10_CTRL_EN (0x1 << 31) + #define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) #define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) #define CCM_PLL11_CTRL_UPD (0x1 << 30) @@ -271,9 +288,12 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DRC0 25 #define AHB_GATE_OFFSET_DE_FE0 14 #define AHB_GATE_OFFSET_DE_BE0 12 +#define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 +#define AHB_GATE_OFFSET_TCON1 4 +#define AHB_GATE_OFFSET_TCON0 3 #define CCM_MMC_CTRL_M(x) ((x) - 1) #define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8) @@ -346,6 +366,9 @@ struct sunxi_ccm_reg { #define CCM_LCD_CH0_CTRL_RST 0 #define CCM_LCD_CH0_CTRL_GATE (0x1 << 31) +#define CCM_TCON0_CTRL_GATE (0x1 << 31) +#define CCM_TCON0_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + #define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) #define CCM_LCD_CH1_CTRL_HALF_SCLK1 0 /* no seperate sclk1 & 2 on sun6i */ #define CCM_LCD_CH1_CTRL_PLL3 (0 << 24) @@ -355,6 +378,7 @@ struct sunxi_ccm_reg { #define CCM_LCD_CH1_CTRL_GATE (0x1 << 31) #define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_HDMI_CTRL_M_MASK (0xf << 0) #define CCM_HDMI_CTRL_PLL_MASK (3 << 24) #define CCM_HDMI_CTRL_PLL3 (0 << 24) #define CCM_HDMI_CTRL_PLL7 (1 << 24) @@ -363,6 +387,8 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31) +#define CCM_HDMI_SLOW_CTRL_DDC_GATE (1 << 31) + #if defined(CONFIG_MACH_SUN50I) #define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ #elif defined(CONFIG_MACH_SUN8I) @@ -391,9 +417,13 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_DRC0 25 #define AHB_RESET_OFFSET_DE_FE0 14 #define AHB_RESET_OFFSET_DE_BE0 12 +#define AHB_RESET_OFFSET_DE 12 #define AHB_RESET_OFFSET_HDMI 11 +#define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 +#define AHB_RESET_OFFSET_TCON1 4 +#define AHB_RESET_OFFSET_TCON0 3 /* ahb_reset2 offsets */ #define AHB_RESET_OFFSET_EPHY 2 @@ -416,6 +446,14 @@ struct sunxi_ccm_reg { #define CCM_DE_CTRL_PLL10 (5 << 24) #define CCM_DE_CTRL_GATE (1 << 31) +/* CCM bits common to all Display Engine 2.0 clock ctrl regs */ +#define CCM_DE2_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_DE2_CTRL_PLL_MASK (3 << 24) +#define CCM_DE2_CTRL_PLL6_2X (0 << 24) +#define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3 (1 << 24) /* for V3s */ +#define CCM_DE2_CTRL_GATE (1 << 31) + /* CCU security switch, H3 only */ #define CCM_SEC_SWITCH_MBUS_NONSEC (1 << 2) #define CCM_SEC_SWITCH_BUS_NONSEC (1 << 1) @@ -424,7 +462,9 @@ struct sunxi_ccm_reg { #ifndef __ASSEMBLY__ void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); +void clock_set_pll3_factors(int m, int n); void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); +void clock_set_pll10(unsigned int hz); void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); void clock_set_mipi_pll(unsigned int hz); unsigned int clock_get_pll3(void); diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index 474c5a325d..2a5db8f302 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -152,6 +152,17 @@ void clock_set_pll3(unsigned int clk) &ccm->pll3_cfg); } +void clock_set_pll3_factors(int m, int n) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* PLL3 rate = 24000000 * n / m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_N(n) | CCM_PLL3_CTRL_M(m), + &ccm->pll3_cfg); +} + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm = @@ -224,6 +235,23 @@ done: } #endif +void clock_set_pll10(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int m = 2; /* 12 MHz steps */ + + if (clk == 0) { + clrbits_le32(&ccm->pll10_cfg, CCM_PLL10_CTRL_EN); + return; + } + + /* PLL10 rate = 24000000 * n / m */ + writel(CCM_PLL10_CTRL_EN | CCM_PLL10_CTRL_INTEGER_MODE | + CCM_PLL10_CTRL_N(clk / (24000000 / m)) | CCM_PLL10_CTRL_M(m), + &ccm->pll10_cfg); +} + #ifdef CONFIG_MACH_SUN8I_A33 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) { diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 09af3537b2..ed79563f84 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,11 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y +config SUNXI_DE2 + bool + ---help--- + Select this for SoCs with DE2 instead of DE. + # Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 6d614c62cc..8de709b2d5 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4274,6 +4274,7 @@ CONFIG_STV0991_HZ_CLOCK CONFIG_ST_SMI CONFIG_SUN4 CONFIG_SUNXI_AHCI +CONFIG_SUNXI_DE2 CONFIG_SUNXI_EMAC CONFIG_SUNXI_GMAC CONFIG_SUNXI_GPIO