From owner-svn-src-head@freebsd.org Sun Jan 24 19:10:31 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B9E5AA31DE8; Sun, 24 Jan 2016 19:10:31 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 93C259EB; Sun, 24 Jan 2016 19:10:31 +0000 (UTC) (envelope-from andrew@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0OJAUgW073140; Sun, 24 Jan 2016 19:10:30 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0OJAUUD073138; Sun, 24 Jan 2016 19:10:30 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201601241910.u0OJAUUD073138@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Sun, 24 Jan 2016 19:10:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r294675 - head/sys/arm/allwinner X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Jan 2016 19:10:31 -0000 Author: andrew Date: Sun Jan 24 19:10:30 2016 New Revision: 294675 URL: https://svnweb.freebsd.org/changeset/base/294675 Log: Add support for controlling the clocks for the audio codec and DMA engines. Submitted by: Jared McNeill Differential Revision: https://reviews.freebsd.org/D5052 Modified: head/sys/arm/allwinner/a10_clk.c head/sys/arm/allwinner/a10_clk.h Modified: head/sys/arm/allwinner/a10_clk.c ============================================================================== --- head/sys/arm/allwinner/a10_clk.c Sun Jan 24 18:54:55 2016 (r294674) +++ head/sys/arm/allwinner/a10_clk.c Sun Jan 24 19:10:30 2016 (r294675) @@ -255,6 +255,58 @@ a10_clk_pll6_get_rate(void) return ((CCM_CLK_REF_FREQ * n * k) / 2); } +static int +a10_clk_pll2_set_rate(unsigned int freq) +{ + struct a10_ccm_softc *sc; + uint32_t reg_value; + unsigned int prediv, postdiv, n; + + sc = a10_ccm_sc; + if (sc == NULL) + return (ENXIO); + + + reg_value = ccm_read_4(sc, CCM_PLL2_CFG); + reg_value &= ~(CCM_PLL2_CFG_PREDIV | CCM_PLL2_CFG_POSTDIV | + CCM_PLL_CFG_FACTOR_N); + + /* + * Audio Codec needs PLL2 to be either 24576000 Hz or 22579200 Hz + * + * PLL2 output frequency is 24MHz * n / prediv / postdiv. + * To get as close as possible to the desired rate, we use a + * pre-divider of 21 and a post-divider of 4. With these values, + * a multiplier of 86 or 79 gets us close to the target rates. + */ + prediv = 21; + postdiv = 4; + + switch (freq) { + case 24576000: + n = 86; + reg_value |= CCM_PLL_CFG_ENABLE; + break; + case 22579200: + n = 79; + reg_value |= CCM_PLL_CFG_ENABLE; + break; + case 0: + n = 1; + reg_value &= ~CCM_PLL_CFG_ENABLE; + break; + default: + return (EINVAL); + } + + reg_value |= (prediv << CCM_PLL2_CFG_PREDIV_SHIFT); + reg_value |= (postdiv << CCM_PLL2_CFG_POSTDIV_SHIFT); + reg_value |= (n << CCM_PLL_CFG_FACTOR_N_SHIFT); + ccm_write_4(sc, CCM_PLL2_CFG, reg_value); + + return (0); +} + int a10_clk_ahci_activate(void) { @@ -347,3 +399,46 @@ a10_clk_mmc_cfg(int devid, int freq) return (0); } + +int +a10_clk_dmac_activate(void) +{ + struct a10_ccm_softc *sc; + uint32_t reg_value; + + sc = a10_ccm_sc; + if (sc == NULL) + return (ENXIO); + + /* Gating AHB clock for DMA controller */ + reg_value = ccm_read_4(sc, CCM_AHB_GATING0); + reg_value |= CCM_AHB_GATING_DMA; + ccm_write_4(sc, CCM_AHB_GATING0, reg_value); + + return (0); +} + +int +a10_clk_codec_activate(unsigned int freq) +{ + struct a10_ccm_softc *sc; + uint32_t reg_value; + + sc = a10_ccm_sc; + if (sc == NULL) + return (ENXIO); + + a10_clk_pll2_set_rate(freq); + + /* Gating APB clock for ADDA */ + reg_value = ccm_read_4(sc, CCM_APB0_GATING); + reg_value |= CCM_APB0_GATING_ADDA; + ccm_write_4(sc, CCM_APB0_GATING, reg_value); + + /* Enable audio codec clock */ + reg_value = ccm_read_4(sc, CCM_AUDIO_CODEC_CLK); + reg_value |= CCM_AUDIO_CODEC_ENABLE; + ccm_write_4(sc, CCM_AUDIO_CODEC_CLK, reg_value); + + return (0); +} Modified: head/sys/arm/allwinner/a10_clk.h ============================================================================== --- head/sys/arm/allwinner/a10_clk.h Sun Jan 24 18:54:55 2016 (r294674) +++ head/sys/arm/allwinner/a10_clk.h Sun Jan 24 19:10:30 2016 (r294675) @@ -106,10 +106,14 @@ #define CCM_GMAC_CLK_EXT_RGMII 0x1 #define CCM_GMAC_CLK_RGMII 0x2 +/* APB0_GATING */ +#define CCM_APB0_GATING_ADDA (1 << 0) + /* AHB_GATING_REG0 */ #define CCM_AHB_GATING_USB0 (1 << 0) #define CCM_AHB_GATING_EHCI0 (1 << 1) #define CCM_AHB_GATING_EHCI1 (1 << 3) +#define CCM_AHB_GATING_DMA (1 << 6) #define CCM_AHB_GATING_SDMMC0 (1 << 8) #define CCM_AHB_GATING_EMAC (1 << 17) #define CCM_AHB_GATING_SATA (1 << 25) @@ -132,6 +136,11 @@ #define CCM_PLL_CFG_FACTOR_K_SHIFT 4 #define CCM_PLL_CFG_FACTOR_M 0x3 +#define CCM_PLL2_CFG_POSTDIV 0x3c000000 +#define CCM_PLL2_CFG_POSTDIV_SHIFT 26 +#define CCM_PLL2_CFG_PREDIV 0x1f +#define CCM_PLL2_CFG_PREDIV_SHIFT 0 + #define CCM_PLL6_CFG_SATA_CLKEN (1U << 14) #define CCM_SD_CLK_SRC_SEL 0x3000000 @@ -146,6 +155,8 @@ #define CCM_SD_CLK_OPHASE_CTR_SHIFT 8 #define CCM_SD_CLK_DIV_RATIO_M 0xf +#define CCM_AUDIO_CODEC_ENABLE (1U << 31) + #define CCM_CLK_REF_FREQ 24000000U int a10_clk_usb_activate(void); @@ -155,5 +166,7 @@ int a10_clk_gmac_activate(phandle_t); int a10_clk_ahci_activate(void); int a10_clk_mmc_activate(int); int a10_clk_mmc_cfg(int, int); +int a10_clk_dmac_activate(void); +int a10_clk_codec_activate(unsigned int); #endif /* _A10_CLK_H_ */