imx51_ccm.c revision 250357
1248557Sray/* $NetBSD: imx51_ccm.c,v 1.1 2012/04/17 09:33:31 bsh Exp $ */ 2248557Sray/* 3248557Sray * Copyright (c) 2010, 2011, 2012 Genetec Corporation. All rights reserved. 4248557Sray * Written by Hashimoto Kenichi for Genetec Corporation. 5248557Sray * 6248557Sray * Redistribution and use in source and binary forms, with or without 7248557Sray * modification, are permitted provided that the following conditions 8248557Sray * are met: 9248557Sray * 1. Redistributions of source code must retain the above copyright 10248557Sray * notice, this list of conditions and the following disclaimer. 11248557Sray * 2. Redistributions in binary form must reproduce the above copyright 12248557Sray * notice, this list of conditions and the following disclaimer in the 13248557Sray * documentation and/or other materials provided with the distribution. 14248557Sray * 15248557Sray * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 16248557Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17248557Sray * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18248557Sray * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 19248557Sray * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20248557Sray * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21248557Sray * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22248557Sray * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23248557Sray * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24248557Sray * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25248557Sray * POSSIBILITY OF SUCH DAMAGE. 26248557Sray */ 27248557Sray 28248557Sray/*- 29250357Sray * Copyright (c) 2012, 2013 The FreeBSD Foundation 30248557Sray * All rights reserved. 31248557Sray * 32248557Sray * Portions of this software were developed by Oleksandr Rybalko 33248557Sray * under sponsorship from the FreeBSD Foundation. 34248557Sray * 35248557Sray * Redistribution and use in source and binary forms, with or without 36248557Sray * modification, are permitted provided that the following conditions 37248557Sray * are met: 38248557Sray * 1. Redistributions of source code must retain the above copyright 39248557Sray * notice, this list of conditions and the following disclaimer. 40248557Sray * 2. Redistributions in binary form must reproduce the above copyright 41248557Sray * notice, this list of conditions and the following disclaimer in the 42248557Sray * documentation and/or other materials provided with the distribution. 43248557Sray * 44248557Sray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 45248557Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46248557Sray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47248557Sray * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 48248557Sray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49248557Sray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50248557Sray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51248557Sray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52248557Sray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53248557Sray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54248557Sray * SUCH DAMAGE. 55248557Sray */ 56248557Sray 57248557Sray/* 58248557Sray * Clock Controller Module (CCM) 59248557Sray */ 60248557Sray 61248557Sray#include <sys/cdefs.h> 62248557Sray__FBSDID("$FreeBSD: head/sys/arm/freescale/imx/imx51_ccm.c 250357 2013-05-08 09:42:50Z ray $"); 63248557Sray 64248557Sray#include <sys/param.h> 65248557Sray#include <sys/systm.h> 66248557Sray#include <sys/bus.h> 67248557Sray#include <sys/kernel.h> 68248557Sray#include <sys/module.h> 69248557Sray#include <sys/malloc.h> 70248557Sray#include <sys/rman.h> 71248557Sray#include <machine/bus.h> 72248557Sray#include <machine/cpu.h> 73248557Sray#include <machine/intr.h> 74248557Sray 75248557Sray#include <dev/fdt/fdt_common.h> 76248557Sray#include <dev/ofw/openfirm.h> 77248557Sray#include <dev/ofw/ofw_bus.h> 78248557Sray#include <dev/ofw/ofw_bus_subr.h> 79248557Sray 80248557Sray#include <machine/bus.h> 81248557Sray#include <machine/fdt.h> 82248557Sray 83248557Sray#include <arm/freescale/imx/imx51_ccmvar.h> 84248557Sray#include <arm/freescale/imx/imx51_ccmreg.h> 85248557Sray#include <arm/freescale/imx/imx51_dpllreg.h> 86248557Sray 87248557Sray#define IMXCCMDEBUG 88248557Sray#undef IMXCCMDEBUG 89248557Sray 90248557Sray#ifndef IMX51_OSC_FREQ 91248557Sray#define IMX51_OSC_FREQ (24 * 1000 * 1000) /* 24MHz */ 92248557Sray#endif 93248557Sray 94248557Sray#ifndef IMX51_CKIL_FREQ 95248557Sray#define IMX51_CKIL_FREQ 32768 96248557Sray#endif 97248557Sray 98248557Sraystruct imxccm_softc { 99248557Sray device_t sc_dev; 100248557Sray struct resource *res[7]; 101248557Sray u_int64_t pll_freq[IMX51_N_DPLLS]; 102248557Sray}; 103248557Sray 104248557Sraystruct imxccm_softc *ccm_softc = NULL; 105248557Sray 106248557Sraystatic uint64_t imx51_get_pll_freq(u_int); 107248557Sray 108248557Sraystatic int imxccm_match(device_t); 109248557Sraystatic int imxccm_attach(device_t); 110248557Sray 111248557Sraystatic device_method_t imxccm_methods[] = { 112248557Sray DEVMETHOD(device_probe, imxccm_match), 113248557Sray DEVMETHOD(device_attach, imxccm_attach), 114248557Sray 115248557Sray DEVMETHOD_END 116248557Sray}; 117248557Sray 118248557Sraystatic driver_t imxccm_driver = { 119248557Sray "imxccm", 120248557Sray imxccm_methods, 121248557Sray sizeof(struct imxccm_softc), 122248557Sray}; 123248557Sray 124248557Sraystatic devclass_t imxccm_devclass; 125248557Sray 126248557SrayEARLY_DRIVER_MODULE(imxccm, simplebus, imxccm_driver, imxccm_devclass, 0, 0, 127248557Sray BUS_PASS_CPU); 128248557Sray 129248557Sraystatic struct resource_spec imxccm_spec[] = { 130248557Sray { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Global registers */ 131248557Sray { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* DPLLIP1 */ 132248557Sray { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DPLLIP2 */ 133248557Sray { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* DPLLIP3 */ 134248557Sray { SYS_RES_IRQ, 0, RF_ACTIVE }, /* 71 */ 135248557Sray { SYS_RES_IRQ, 1, RF_ACTIVE }, /* 72 */ 136248557Sray { -1, 0 } 137248557Sray}; 138248557Sray 139248557Sraystatic int 140248557Srayimxccm_match(device_t dev) 141248557Sray{ 142248557Sray 143248557Sray if (!ofw_bus_is_compatible(dev, "fsl,imx51-ccm")) 144248557Sray return (ENXIO); 145248557Sray 146248557Sray device_set_desc(dev, "Freescale Clock Control Module"); 147248557Sray return (BUS_PROBE_DEFAULT); 148248557Sray} 149248557Sray 150248557Sraystatic int 151248557Srayimxccm_attach(device_t dev) 152248557Sray{ 153248557Sray struct imxccm_softc *sc; 154248557Sray 155248557Sray sc = device_get_softc(dev); 156248557Sray sc->sc_dev = dev; 157248557Sray 158248557Sray if (bus_alloc_resources(dev, imxccm_spec, sc->res)) { 159248557Sray device_printf(dev, "could not allocate resources\n"); 160248557Sray return (ENXIO); 161248557Sray } 162248557Sray 163248557Sray ccm_softc = sc; 164248557Sray 165248557Sray imx51_get_pll_freq(1); 166248557Sray imx51_get_pll_freq(2); 167248557Sray imx51_get_pll_freq(3); 168248557Sray 169248557Sray device_printf(dev, "PLL1=%lluMHz, PLL2=%lluMHz, PLL3=%lluMHz\n", 170248557Sray sc->pll_freq[0] / 1000000, 171248557Sray sc->pll_freq[1] / 1000000, 172248557Sray sc->pll_freq[2] / 1000000); 173248557Sray device_printf(dev, "CPU clock=%d, UART clock=%d\n", 174248557Sray imx51_get_clock(IMX51CLK_ARM_ROOT), 175248557Sray imx51_get_clock(IMX51CLK_UART_CLK_ROOT)); 176248557Sray device_printf(dev, 177248557Sray "mainbus clock=%d, ahb clock=%d ipg clock=%d perclk=%d\n", 178248557Sray imx51_get_clock(IMX51CLK_MAIN_BUS_CLK), 179248557Sray imx51_get_clock(IMX51CLK_AHB_CLK_ROOT), 180248557Sray imx51_get_clock(IMX51CLK_IPG_CLK_ROOT), 181248557Sray imx51_get_clock(IMX51CLK_PERCLK_ROOT)); 182248557Sray 183248557Sray 184248557Sray return (0); 185248557Sray} 186248557Sray 187248557Srayu_int 188248557Srayimx51_get_clock(enum imx51_clock clk) 189248557Sray{ 190248557Sray u_int freq; 191248557Sray u_int sel; 192248557Sray uint32_t cacrr; /* ARM clock root register */ 193248557Sray uint32_t ccsr; 194248557Sray uint32_t cscdr1; 195248557Sray uint32_t cscmr1; 196248557Sray uint32_t cbcdr; 197248557Sray uint32_t cbcmr; 198248557Sray uint32_t cdcr; 199248557Sray 200248557Sray if (ccm_softc == NULL) 201248557Sray return (0); 202248557Sray 203248557Sray switch (clk) { 204248557Sray case IMX51CLK_PLL1: 205248557Sray case IMX51CLK_PLL2: 206248557Sray case IMX51CLK_PLL3: 207248557Sray return ccm_softc->pll_freq[clk-IMX51CLK_PLL1]; 208248557Sray case IMX51CLK_PLL1SW: 209248557Sray ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); 210248557Sray if ((ccsr & CCSR_PLL1_SW_CLK_SEL) == 0) 211248557Sray return ccm_softc->pll_freq[1-1]; 212248557Sray /* step clock */ 213248557Sray /* FALLTHROUGH */ 214248557Sray case IMX51CLK_PLL1STEP: 215248557Sray ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); 216248557Sray switch ((ccsr & CCSR_STEP_SEL_MASK) >> CCSR_STEP_SEL_SHIFT) { 217248557Sray case 0: 218248557Sray return imx51_get_clock(IMX51CLK_LP_APM); 219248557Sray case 1: 220248557Sray return 0; /* XXX PLL bypass clock */ 221248557Sray case 2: 222248557Sray return ccm_softc->pll_freq[2-1] / 223248557Sray (1 + ((ccsr & CCSR_PLL2_DIV_PODF_MASK) >> 224248557Sray CCSR_PLL2_DIV_PODF_SHIFT)); 225248557Sray case 3: 226248557Sray return ccm_softc->pll_freq[3-1] / 227248557Sray (1 + ((ccsr & CCSR_PLL3_DIV_PODF_MASK) >> 228248557Sray CCSR_PLL3_DIV_PODF_SHIFT)); 229248557Sray } 230248557Sray /*NOTREACHED*/ 231248557Sray case IMX51CLK_PLL2SW: 232248557Sray ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); 233248557Sray if ((ccsr & CCSR_PLL2_SW_CLK_SEL) == 0) 234248557Sray return imx51_get_clock(IMX51CLK_PLL2); 235248557Sray return 0; /* XXX PLL2 bypass clk */ 236248557Sray case IMX51CLK_PLL3SW: 237248557Sray ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); 238248557Sray if ((ccsr & CCSR_PLL3_SW_CLK_SEL) == 0) 239248557Sray return imx51_get_clock(IMX51CLK_PLL3); 240248557Sray return 0; /* XXX PLL3 bypass clk */ 241248557Sray 242248557Sray case IMX51CLK_LP_APM: 243248557Sray ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); 244248557Sray return (ccsr & CCSR_LP_APM) ? 245248557Sray imx51_get_clock(IMX51CLK_FPM) : IMX51_OSC_FREQ; 246248557Sray 247248557Sray case IMX51CLK_ARM_ROOT: 248248557Sray freq = imx51_get_clock(IMX51CLK_PLL1SW); 249248557Sray cacrr = bus_read_4(ccm_softc->res[0], CCMC_CACRR); 250248557Sray return freq / (cacrr + 1); 251248557Sray 252248557Sray /* ... */ 253248557Sray case IMX51CLK_MAIN_BUS_CLK_SRC: 254248557Sray cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); 255248557Sray if ((cbcdr & CBCDR_PERIPH_CLK_SEL) == 0) 256248557Sray freq = imx51_get_clock(IMX51CLK_PLL2SW); 257248557Sray else { 258248557Sray freq = 0; 259248557Sray cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); 260248557Sray switch ((cbcmr & CBCMR_PERIPH_APM_SEL_MASK) >> 261248557Sray CBCMR_PERIPH_APM_SEL_SHIFT) { 262248557Sray case 0: 263248557Sray freq = imx51_get_clock(IMX51CLK_PLL1SW); 264248557Sray break; 265248557Sray case 1: 266248557Sray freq = imx51_get_clock(IMX51CLK_PLL3SW); 267248557Sray break; 268248557Sray case 2: 269248557Sray freq = imx51_get_clock(IMX51CLK_LP_APM); 270248557Sray break; 271248557Sray case 3: 272248557Sray /* XXX: error */ 273248557Sray break; 274248557Sray } 275248557Sray } 276248557Sray return freq; 277248557Sray case IMX51CLK_MAIN_BUS_CLK: 278248557Sray freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC); 279248557Sray cdcr = bus_read_4(ccm_softc->res[0], CCMC_CDCR); 280248557Sray return freq / (cdcr & CDCR_PERIPH_CLK_DVFS_PODF_MASK) >> 281248557Sray CDCR_PERIPH_CLK_DVFS_PODF_SHIFT; 282248557Sray case IMX51CLK_AHB_CLK_ROOT: 283248557Sray freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK); 284248557Sray cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); 285248557Sray return freq / (1 + ((cbcdr & CBCDR_AHB_PODF_MASK) >> 286248557Sray CBCDR_AHB_PODF_SHIFT)); 287248557Sray case IMX51CLK_IPG_CLK_ROOT: 288248557Sray freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT); 289248557Sray cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); 290248557Sray return freq / (1 + ((cbcdr & CBCDR_IPG_PODF_MASK) >> 291248557Sray CBCDR_IPG_PODF_SHIFT)); 292248557Sray 293248557Sray case IMX51CLK_PERCLK_ROOT: 294248557Sray cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); 295248557Sray if (cbcmr & CBCMR_PERCLK_IPG_SEL) 296248557Sray return imx51_get_clock(IMX51CLK_IPG_CLK_ROOT); 297248557Sray if (cbcmr & CBCMR_PERCLK_LP_APM_SEL) 298248557Sray freq = imx51_get_clock(IMX51CLK_LP_APM); 299248557Sray else 300248557Sray freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC); 301248557Sray cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); 302248557Sray 303248557Sray#ifdef IMXCCMDEBUG 304248557Sray printf("cbcmr=%x cbcdr=%x\n", cbcmr, cbcdr); 305248557Sray#endif 306248557Sray 307248557Sray freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED1_MASK) >> 308248557Sray CBCDR_PERCLK_PRED1_SHIFT); 309248557Sray freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED2_MASK) >> 310248557Sray CBCDR_PERCLK_PRED2_SHIFT); 311248557Sray freq /= 1 + ((cbcdr & CBCDR_PERCLK_PODF_MASK) >> 312248557Sray CBCDR_PERCLK_PODF_SHIFT); 313248557Sray return freq; 314248557Sray case IMX51CLK_UART_CLK_ROOT: 315248557Sray cscdr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1); 316248557Sray cscmr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1); 317248557Sray 318248557Sray#ifdef IMXCCMDEBUG 319248557Sray printf("cscdr1=%x cscmr1=%x\n", cscdr1, cscmr1); 320248557Sray#endif 321248557Sray 322248557Sray sel = (cscmr1 & CSCMR1_UART_CLK_SEL_MASK) >> 323248557Sray CSCMR1_UART_CLK_SEL_SHIFT; 324248557Sray 325248557Sray freq = 0; /* shut up GCC */ 326248557Sray switch (sel) { 327248557Sray case 0: 328248557Sray case 1: 329248557Sray case 2: 330248557Sray freq = imx51_get_clock(IMX51CLK_PLL1SW + sel); 331248557Sray break; 332248557Sray case 3: 333248557Sray freq = imx51_get_clock(IMX51CLK_LP_APM); 334248557Sray break; 335248557Sray } 336248557Sray 337248557Sray return freq / (1 + ((cscdr1 & CSCDR1_UART_CLK_PRED_MASK) >> 338248557Sray CSCDR1_UART_CLK_PRED_SHIFT)) / 339248557Sray (1 + ((cscdr1 & CSCDR1_UART_CLK_PODF_MASK) >> 340248557Sray CSCDR1_UART_CLK_PODF_SHIFT)); 341248557Sray case IMX51CLK_IPU_HSP_CLK_ROOT: 342248557Sray freq = 0; 343248557Sray cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); 344248557Sray switch ((cbcmr & CBCMR_IPU_HSP_CLK_SEL_MASK) >> 345248557Sray CBCMR_IPU_HSP_CLK_SEL_SHIFT) { 346248557Sray case 0: 347248557Sray freq = imx51_get_clock(IMX51CLK_ARM_AXI_A_CLK); 348248557Sray break; 349248557Sray case 1: 350248557Sray freq = imx51_get_clock(IMX51CLK_ARM_AXI_B_CLK); 351248557Sray break; 352248557Sray case 2: 353248557Sray freq = imx51_get_clock( 354248557Sray IMX51CLK_EMI_SLOW_CLK_ROOT); 355248557Sray break; 356248557Sray case 3: 357248557Sray freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT); 358248557Sray break; 359248557Sray } 360248557Sray return freq; 361248557Sray default: 362248557Sray device_printf(ccm_softc->sc_dev, 363248557Sray "clock %d: not supported yet\n", clk); 364248557Sray return 0; 365248557Sray } 366248557Sray} 367248557Sray 368248557Sray 369248557Sraystatic uint64_t 370248557Srayimx51_get_pll_freq(u_int pll_no) 371248557Sray{ 372248557Sray uint32_t dp_ctrl; 373248557Sray uint32_t dp_op; 374248557Sray uint32_t dp_mfd; 375248557Sray uint32_t dp_mfn; 376248557Sray uint32_t mfi; 377248557Sray int32_t mfn; 378248557Sray uint32_t mfd; 379248557Sray uint32_t pdf; 380248557Sray uint32_t ccr; 381248557Sray uint64_t freq = 0; 382248557Sray u_int ref = 0; 383248557Sray 384248557Sray KASSERT(1 <= pll_no && pll_no <= IMX51_N_DPLLS, ("Wrong PLL id")); 385248557Sray 386248557Sray dp_ctrl = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_CTL); 387248557Sray 388248557Sray if (dp_ctrl & DP_CTL_HFSM) { 389248557Sray dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_OP); 390248557Sray dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFD); 391248557Sray dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFN); 392248557Sray } else { 393248557Sray dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_OP); 394248557Sray dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFD); 395248557Sray dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFN); 396248557Sray } 397248557Sray 398248557Sray pdf = dp_op & DP_OP_PDF_MASK; 399248557Sray mfi = max(5, (dp_op & DP_OP_MFI_MASK) >> DP_OP_MFI_SHIFT); 400248557Sray mfd = dp_mfd; 401248557Sray if (dp_mfn & 0x04000000) 402248557Sray /* 27bit signed value */ 403248557Sray mfn = (uint32_t)(0xf8000000 | dp_mfn); 404248557Sray else 405248557Sray mfn = dp_mfn; 406248557Sray 407248557Sray switch (dp_ctrl & DP_CTL_REF_CLK_SEL_MASK) { 408248557Sray case DP_CTL_REF_CLK_SEL_COSC: 409248557Sray /* Internal Oscillator */ 410248557Sray /* TODO: get from FDT "fsl,imx-osc" */ 411248557Sray ref = 24000000; /* IMX51_OSC_FREQ */ 412248557Sray break; 413248557Sray case DP_CTL_REF_CLK_SEL_FPM: 414248557Sray ccr = bus_read_4(ccm_softc->res[0], CCMC_CCR); 415248557Sray if (ccr & CCR_FPM_MULT) 416248557Sray /* TODO: get from FDT "fsl,imx-ckil" */ 417248557Sray ref = 32768 * 1024; 418248557Sray else 419248557Sray /* TODO: get from FDT "fsl,imx-ckil" */ 420248557Sray ref = 32768 * 512; 421248557Sray break; 422248557Sray default: 423248557Sray ref = 0; 424248557Sray } 425248557Sray 426248557Sray if (dp_ctrl & DP_CTL_REF_CLK_DIV) 427248557Sray ref /= 2; 428248557Sray 429248557Sray ref *= 4; 430248557Sray freq = (int64_t)ref * mfi + (int64_t)ref * mfn / (mfd + 1); 431248557Sray freq /= pdf + 1; 432248557Sray 433248557Sray if (!(dp_ctrl & DP_CTL_DPDCK0_2_EN)) 434248557Sray freq /= 2; 435248557Sray 436248557Sray#ifdef IMXCCMDEBUG 437248557Sray printf("ref: %dKHz ", ref); 438248557Sray printf("dp_ctl: %08x ", dp_ctrl); 439248557Sray printf("pdf: %3d ", pdf); 440248557Sray printf("mfi: %3d ", mfi); 441248557Sray printf("mfd: %3d ", mfd); 442248557Sray printf("mfn: %3d ", mfn); 443248557Sray printf("pll: %d\n", (uint32_t)freq); 444248557Sray#endif 445248557Sray 446248557Sray ccm_softc->pll_freq[pll_no-1] = freq; 447248557Sray 448248557Sray return (freq); 449248557Sray} 450248557Sray 451248557Srayvoid 452248557Srayimx51_clk_gating(int clk_src, int mode) 453248557Sray{ 454248557Sray int field, group; 455248557Sray uint32_t reg; 456248557Sray 457248557Sray group = CCMR_CCGR_MODULE(clk_src); 458248557Sray field = clk_src % CCMR_CCGR_NSOURCE; 459248557Sray reg = bus_read_4(ccm_softc->res[0], CCMC_CCGR(group)); 460248557Sray reg &= ~(0x03 << field * 2); 461248557Sray reg |= (mode << field * 2); 462248557Sray bus_write_4(ccm_softc->res[0], CCMC_CCGR(group), reg); 463248557Sray} 464248557Sray 465248557Srayint 466248557Srayimx51_get_clk_gating(int clk_src) 467248557Sray{ 468248557Sray uint32_t reg; 469248557Sray 470248557Sray reg = bus_read_4(ccm_softc->res[0], 471248557Sray CCMC_CCGR(CCMR_CCGR_MODULE(clk_src))); 472248557Sray return ((reg >> (clk_src % CCMR_CCGR_NSOURCE) * 2) & 0x03); 473248557Sray} 474248557Sray 475