From patchwork Fri Nov 14 16:54:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 410913 X-Patchwork-Delegate: ijc@hellion.org.uk Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 6ACC8140082 for ; Sat, 15 Nov 2014 03:55:13 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AAF144B9E5; Fri, 14 Nov 2014 17:55:11 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SOMnLibWfdMy; Fri, 14 Nov 2014 17:55:11 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 266F94B9D2; Fri, 14 Nov 2014 17:55:11 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D117E4B9E3 for ; Fri, 14 Nov 2014 17:55:06 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ccWQywfzaZSG for ; Fri, 14 Nov 2014 17:55:06 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by theia.denx.de (Postfix) with ESMTPS id 513AD4B9D7 for ; Fri, 14 Nov 2014 17:55:04 +0100 (CET) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sAEGsr0u025500 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 14 Nov 2014 11:54:54 -0500 Received: from shalem.localdomain.com (vpn1-4-211.ams2.redhat.com [10.36.4.211]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sAEGsmpj003570; Fri, 14 Nov 2014 11:54:52 -0500 From: Hans de Goede To: Anatolij Gustschin , Ian Campbell Date: Fri, 14 Nov 2014 17:54:44 +0100 Message-Id: <1415984088-6800-3-git-send-email-hdegoede@redhat.com> In-Reply-To: <1415984088-6800-1-git-send-email-hdegoede@redhat.com> References: <1415984088-6800-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/6] sunxi: Add video pll clock functions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This is a preparation patch for adding support for HDMI out. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 27 ++++++++++++ arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 29 +++++++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 2 + arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 45 ++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 59 ++++++++++++++++++++++++++- 5 files changed, 161 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c index a0e49d1..49f4032 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c @@ -180,6 +180,21 @@ void clock_set_pll1(unsigned int hz) } #endif +void clock_set_pll3(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + if (clk == 0) { + clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN); + return; + } + + /* PLL3 rate = 3000000 * m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_M(clk / 3000000), &ccm->pll3_cfg); +} + unsigned int clock_get_pll5p(void) { struct sunxi_ccm_reg *const ccm = @@ -200,3 +215,15 @@ unsigned int clock_get_pll6(void) int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; return 24000000 * n * k / 2; } + +void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) +{ + int pll = clock_get_pll5p(); + int div = 1; + + while ((pll / div) > hz) + div++; + + writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_RST | CCM_DE_CTRL_PLL5P | + CCM_DE_CTRL_M(div), clk_cfg); +} diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 16ab6f3..8e949c6 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -127,6 +127,23 @@ void clock_set_pll1(unsigned int clk) } #endif +void clock_set_pll3(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int m = 8; /* 3 MHz steps just like sun4i, sun5i and sun7i */ + + if (clk == 0) { + clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN); + return; + } + + /* PLL3 rate = 24000000 * n / m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_N(clk / (24000000 / m)) | CCM_PLL3_CTRL_M(m), + &ccm->pll3_cfg); +} + void clock_set_pll5(unsigned int clk) { struct sunxi_ccm_reg * const ccm = @@ -151,3 +168,15 @@ unsigned int clock_get_pll6(void) int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; return 24000000 * n * k / 2; } + +void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) +{ + int pll = clock_get_pll6() * 2; + int div = 1; + + while ((pll / div) > hz) + div++; + + writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_PLL6_2X | CCM_DE_CTRL_M(div), + clk_cfg); +} diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index b40c16b..64acff3 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -25,9 +25,11 @@ int clock_init(void); int clock_twi_onoff(int port, int state); void clock_set_pll1(unsigned int hz); +void clock_set_pll3(unsigned int hz); void clock_set_pll5(unsigned int hz); unsigned int clock_get_pll5p(void); unsigned int clock_get_pll6(void); +void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz); void clock_init_safe(void); void clock_init_uart(void); #endif diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h index 6c0430c..eb88969 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h @@ -186,12 +186,20 @@ struct sunxi_ccm_reg { /* ahb clock gate bit offset (second register) */ #define AHB_GATE_OFFSET_GMAC 17 +#define AHB_GATE_OFFSET_DE_BE0 12 +#define AHB_GATE_OFFSET_HDMI 11 +#define AHB_GATE_OFFSET_LCD1 5 +#define AHB_GATE_OFFSET_LCD0 4 #define CCM_AHB_GATE_GPS (0x1 << 26) #define CCM_AHB_GATE_SDRAM (0x1 << 14) #define CCM_AHB_GATE_DLL (0x1 << 15) #define CCM_AHB_GATE_ACE (0x1 << 16) +#define CCM_PLL3_CTRL_M(n) (((n) & 0x7f) << 0) +#define CCM_PLL3_CTRL_INTEGER_MODE (0x1 << 15) +#define CCM_PLL3_CTRL_EN (0x1 << 31) + #define CCM_PLL5_CTRL_M(n) (((n) & 0x3) << 0) #define CCM_PLL5_CTRL_M_MASK CCM_PLL5_CTRL_M(0x3) #define CCM_PLL5_CTRL_M_X(n) ((n) - 1) @@ -253,6 +261,34 @@ struct sunxi_ccm_reg { #define CCM_MMC_CTRL_ENABLE (0x1 << 31) +#define CCM_DRAM_GATE_OFFSET_DE_BE0 26 + +#define CCM_LCD_CH0_CTRL_PLL3 (0 << 24) +#define CCM_LCD_CH0_CTRL_PLL7 (1 << 24) +#define CCM_LCD_CH0_CTRL_PLL3_2X (2 << 24) +#define CCM_LCD_CH0_CTRL_PLL7_2X (3 << 24) +#define CCM_LCD_CH0_CTRL_RST (0x1 << 30) +#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31) + +#define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +/* We leave bit 11 set to 0, so sclk1 == sclk2 */ +#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24) +#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24) +#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24) +#define CCM_LCD_CH1_CTRL_PLL7_2X (3 << 24) +/* Enable / disable both ch1 sclk1 and sclk2 at the same time */ +#define CCM_LCD_CH1_CTRL_GATE (0x1 << 31 | 0x1 << 15) + +#define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_HDMI_CTRL_PLL_MASK (3 << 24) +#define CCM_HDMI_CTRL_PLL3 (0 << 24) +#define CCM_HDMI_CTRL_PLL7 (1 << 24) +#define CCM_HDMI_CTRL_PLL3_2X (2 << 24) +#define CCM_HDMI_CTRL_PLL7_2X (3 << 24) +/* No separate ddc gate on sun4i, sun5i and sun7i */ +#define CCM_HDMI_CTRL_DDC_GATE 0 +#define CCM_HDMI_CTRL_GATE (0x1 << 31) + #define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 #define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 #define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 @@ -266,4 +302,13 @@ struct sunxi_ccm_reg { #define CCM_USB_CTRL_PHY1_CLK 0 #define CCM_USB_CTRL_PHY2_CLK 0 +/* CCM bits common to all Display Engine (and IEP) clock ctrl regs */ +#define CCM_DE_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_DE_CTRL_PLL_MASK (3 << 24) +#define CCM_DE_CTRL_PLL3 (0 << 24) +#define CCM_DE_CTRL_PLL7 (1 << 24) +#define CCM_DE_CTRL_PLL5P (2 << 24) +#define CCM_DE_CTRL_RST (1 << 30) +#define CCM_DE_CTRL_GATE (1 << 31) + #endif /* _SUNXI_CLOCK_SUN4I_H */ diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index e16a764..50a4b69 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -176,13 +176,18 @@ struct sunxi_ccm_reg { #define CCM_PLL1_CTRL_MAGIC (0x1 << 16) #define CCM_PLL1_CTRL_EN (0x1 << 31) +#define CCM_PLL3_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_PLL3_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) +#define CCM_PLL3_CTRL_INTEGER_MODE (0x1 << 24) +#define CCM_PLL3_CTRL_EN (0x1 << 31) + #define CCM_PLL5_CTRL_M(n) ((((n) - 1) & 0x3) << 0) #define CCM_PLL5_CTRL_K(n) ((((n) - 1) & 0x3) << 4) #define CCM_PLL5_CTRL_N(n) ((((n) - 1) & 0x1f) << 8) #define CCM_PLL5_CTRL_UPD (0x1 << 20) #define CCM_PLL5_CTRL_EN (0x1 << 31) -#define PLL6_CFG_DEFAULT 0x90041811 +#define PLL6_CFG_DEFAULT 0x90041811 /* 600 MHz */ #define CCM_PLL6_CTRL_N_SHIFT 8 #define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) @@ -193,6 +198,7 @@ struct sunxi_ccm_reg { #define AXI_GATE_OFFSET_DRAM 0 +/* ahb_gate0 offsets */ #define AHB_GATE_OFFSET_USB_OHCI1 30 #define AHB_GATE_OFFSET_USB_OHCI0 29 #define AHB_GATE_OFFSET_USB_EHCI1 27 @@ -204,6 +210,13 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_MMC0 8 #define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) +/* ahb_gate1 offsets */ +#define AHB_GATE_OFFSET_DRC0 25 +#define AHB_GATE_OFFSET_DE_BE0 12 +#define AHB_GATE_OFFSET_HDMI 11 +#define AHB_GATE_OFFSET_LCD1 5 +#define AHB_GATE_OFFSET_LCD0 4 + #define CCM_MMC_CTRL_OSCM24 (0x0 << 24) #define CCM_MMC_CTRL_PLL6 (0x1 << 24) @@ -223,8 +236,34 @@ struct sunxi_ccm_reg { #define CCM_DRAMCLK_CFG_UPD (0x1 << 16) #define CCM_DRAMCLK_CFG_RST (0x1 << 31) +#define CCM_DRAM_GATE_OFFSET_DE_BE0 26 + +#define CCM_LCD_CH0_CTRL_PLL3 (0 << 24) +#define CCM_LCD_CH0_CTRL_PLL7 (1 << 24) +#define CCM_LCD_CH0_CTRL_PLL3_2X (2 << 24) +#define CCM_LCD_CH0_CTRL_PLL7_2X (3 << 24) +#define CCM_LCD_CH0_CTRL_MIPI_PLL (4 << 24) +#define CCM_LCD_CH0_CTRL_GATE (0x1 << 31) + +#define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_LCD_CH1_CTRL_PLL3 (0 << 24) +#define CCM_LCD_CH1_CTRL_PLL7 (1 << 24) +#define CCM_LCD_CH1_CTRL_PLL3_2X (2 << 24) +#define CCM_LCD_CH1_CTRL_PLL7_2X (3 << 24) +#define CCM_LCD_CH1_CTRL_GATE (0x1 << 31) + +#define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_HDMI_CTRL_PLL_MASK (3 << 24) +#define CCM_HDMI_CTRL_PLL3 (0 << 24) +#define CCM_HDMI_CTRL_PLL7 (1 << 24) +#define CCM_HDMI_CTRL_PLL3_2X (2 << 24) +#define CCM_HDMI_CTRL_PLL7_2X (3 << 24) +#define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) +#define CCM_HDMI_CTRL_GATE (0x1 << 31) + #define MBUS_CLK_DEFAULT 0x81000001 /* PLL6 / 2 */ +/* ahb_reset0 offsets */ #define AHB_RESET_OFFSET_MCTL 14 #define AHB_RESET_OFFSET_MMC3 11 #define AHB_RESET_OFFSET_MMC2 10 @@ -232,10 +271,28 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_MMC0 8 #define AHB_RESET_OFFSET_MMC(n) (AHB_RESET_OFFSET_MMC0 + (n)) +/* ahb_reset0 offsets */ +#define AHB_RESET_OFFSET_DRC0 25 +#define AHB_RESET_OFFSET_DE_BE0 12 +#define AHB_RESET_OFFSET_HDMI 11 +#define AHB_RESET_OFFSET_LCD1 5 +#define AHB_RESET_OFFSET_LCD0 4 + /* apb2 reset */ #define APB2_RESET_UART_SHIFT (16) #define APB2_RESET_UART_MASK (0xff << APB2_RESET_UART_SHIFT) #define APB2_RESET_TWI_SHIFT (0) #define APB2_RESET_TWI_MASK (0xf << APB2_RESET_TWI_SHIFT) +/* CCM bits common to all Display Engine (and IEP) clock ctrl regs */ +#define CCM_DE_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_DE_CTRL_PLL_MASK (0xf << 24) +#define CCM_DE_CTRL_PLL3 (0 << 24) +#define CCM_DE_CTRL_PLL7 (1 << 24) +#define CCM_DE_CTRL_PLL6_2X (2 << 24) +#define CCM_DE_CTRL_PLL8 (3 << 24) +#define CCM_DE_CTRL_PLL9 (4 << 24) +#define CCM_DE_CTRL_PLL10 (5 << 24) +#define CCM_DE_CTRL_GATE (1 << 31) + #endif /* _SUNXI_CLOCK_SUN6I_H */