Module Name: src
Committed By: hkenken
Date: Thu Jun 20 08:16:20 UTC 2019
Modified Files:
src/sys/arch/arm/imx: files.imx6 if_enet_imx6.c if_enetvar.h
imx6_ahcisata.c imx6_ccm.c imx6_ccmreg.h imx6_ccmvar.h imx6_i2c.c
imx6_pcie.c imx6_usb.c imx6_usbphy.c imx6_usdhc.c imxi2cvar.h
imxusbvar.h
src/sys/arch/evbarm/nitrogen6: nitrogen6_usb.c
Log Message:
Add support for clk subsystem in imx6 CCM driver.
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/imx/files.imx6
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/if_enet_imx6.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/if_enetvar.h \
src/sys/arch/arm/imx/imx6_i2c.c src/sys/arch/arm/imx/imxi2cvar.h
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/imx/imx6_ahcisata.c \
src/sys/arch/arm/imx/imx6_pcie.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/imx/imx6_ccm.c \
src/sys/arch/arm/imx/imx6_ccmreg.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/imx/imx6_ccmvar.h
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/imx/imx6_usb.c \
src/sys/arch/arm/imx/imxusbvar.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imx6_usbphy.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/imx/imx6_usdhc.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/imx/files.imx6
diff -u src/sys/arch/arm/imx/files.imx6:1.14 src/sys/arch/arm/imx/files.imx6:1.15
--- src/sys/arch/arm/imx/files.imx6:1.14 Wed Jun 20 07:05:37 2018
+++ src/sys/arch/arm/imx/files.imx6 Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-# $NetBSD: files.imx6,v 1.14 2018/06/20 07:05:37 hkenken Exp $
+# $NetBSD: files.imx6,v 1.15 2019/06/20 08:16:19 hkenken Exp $
#
# Configuration info for the Freescale i.MX6
#
@@ -32,12 +32,15 @@ attach imxpcie at axi
file arch/arm/imx/imx6_pcie.c imxpcie
# iMX6 Clock Control Module
-device imxccm
+device imxccm : clk
attach imxccm at axi
file arch/arm/imx/imx6_ccm.c imxccm needs-flag
defflag opt_imx6clk.h IMXCCMDEBUG
defparam opt_imx6clk.h IMX6_OSC_FREQ
defparam opt_imx6clk.h IMX6_CKIL_FREQ
+defparam opt_imx6clk.h IMX6_CKIH_FREQ
+defparam opt_imx6clk.h IMX6_ANACLK1_FREQ
+defparam opt_imx6clk.h IMX6_ANACLK2_FREQ
# iMX6 Enhanced Periodic Interrupt Timer
device imxclock
Index: src/sys/arch/arm/imx/if_enet_imx6.c
diff -u src/sys/arch/arm/imx/if_enet_imx6.c:1.3 src/sys/arch/arm/imx/if_enet_imx6.c:1.4
--- src/sys/arch/arm/imx/if_enet_imx6.c:1.3 Fri Jun 9 18:14:59 2017
+++ src/sys/arch/arm/imx/if_enet_imx6.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: if_enet_imx6.c,v 1.3 2017/06/09 18:14:59 ryo Exp $ */
+/* $NetBSD: if_enet_imx6.c,v 1.4 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_enet_imx6.c,v 1.3 2017/06/09 18:14:59 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_enet_imx6.c,v 1.4 2019/06/20 08:16:19 hkenken Exp $");
#include "locators.h"
#include "imxccm.h"
@@ -47,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_enet_imx6
#include <arm/imx/if_enetreg.h>
#include <arm/imx/if_enetvar.h>
+static int enet_init_clocks(struct enet_softc *);
+
int
enet_match(device_t parent __unused, struct cfdata *match __unused, void *aux)
{
@@ -108,28 +110,9 @@ enet_attach(device_t parent, device_t se
sc->sc_enaddr[5] = eaddr + sc->sc_unit;
#endif
-#if NIMXCCM > 0
- /* PLL power up */
- if (imx6_pll_power(CCM_ANALOG_PLL_ENET, 1,
- CCM_ANALOG_PLL_ENET_ENABLE) != 0) {
- aprint_error_dev(sc->sc_dev,
- "couldn't enable CCM_ANALOG_PLL_ENET\n");
- return;
- }
-
if (IMX6_CHIPID_MAJOR(imx6_chip_id()) == CHIPID_MAJOR_IMX6UL) {
uint32_t v;
- /* iMX6UL */
- if ((imx6_pll_power(CCM_ANALOG_PLL_ENET, 1,
- CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN) != 0) ||
- (imx6_pll_power(CCM_ANALOG_PLL_ENET, 1,
- CCM_ANALOG_PLL_ENET_ENET2_125M_EN) != 0)) {
- aprint_error_dev(sc->sc_dev,
- "couldn't enable CCM_ANALOG_PLL_ENET\n");
- return;
- }
-
v = iomux_read(IMX6UL_IOMUX_GPR1);
switch (sc->sc_unit) {
case 0:
@@ -144,11 +127,42 @@ enet_attach(device_t parent, device_t se
iomux_write(IMX6UL_IOMUX_GPR1, v);
}
- sc->sc_pllclock = imx6_get_clock(IMX6CLK_PLL6);
-#else
- sc->sc_pllclock = 50000000;
-#endif
+ sc->sc_clk_enet = imx6_get_clock("enet");
+ if (sc->sc_clk_enet == NULL) {
+ aprint_error(": couldn't get clock enet\n");
+ return;
+ }
+ sc->sc_clk_enet_ref = imx6_get_clock("enet_ref");
+ if (sc->sc_clk_enet_ref == NULL) {
+ aprint_error(": couldn't get clock enet_ref\n");
+ return;
+ }
+ if (enet_init_clocks(sc) != 0) {
+ aprint_error_dev(self, "couldn't init clocks\n");
+ return;
+ }
+
+ sc->sc_pllclock = clk_get_rate(sc->sc_clk_enet_ref);
enet_attach_common(self, aa->aa_iot, aa->aa_dmat, aa->aa_addr,
aa->aa_size, aa->aa_irq);
}
+
+static int
+enet_init_clocks(struct enet_softc *sc)
+{
+ int error;
+
+ error = clk_enable(sc->sc_clk_enet);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable enet: %d\n", error);
+ return error;
+ }
+ error = clk_enable(sc->sc_clk_enet_ref);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable enet-ref: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
Index: src/sys/arch/arm/imx/if_enetvar.h
diff -u src/sys/arch/arm/imx/if_enetvar.h:1.2 src/sys/arch/arm/imx/if_enetvar.h:1.3
--- src/sys/arch/arm/imx/if_enetvar.h:1.2 Fri Jun 9 18:14:59 2017
+++ src/sys/arch/arm/imx/if_enetvar.h Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: if_enetvar.h,v 1.2 2017/06/09 18:14:59 ryo Exp $ */
+/* $NetBSD: if_enetvar.h,v 1.3 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -61,6 +61,9 @@ struct enet_softc {
int sc_rgmii;
unsigned int sc_pllclock;
+ struct clk *sc_clk_enet;
+ struct clk *sc_clk_enet_ref;
+
/* interrupts */
void *sc_ih;
void *sc_ih2; /* for i.MX7 */
Index: src/sys/arch/arm/imx/imx6_i2c.c
diff -u src/sys/arch/arm/imx/imx6_i2c.c:1.2 src/sys/arch/arm/imx/imx6_i2c.c:1.3
--- src/sys/arch/arm/imx/imx6_i2c.c:1.2 Fri Mar 27 05:31:23 2015
+++ src/sys/arch/arm/imx/imx6_i2c.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_i2c.c,v 1.2 2015/03/27 05:31:23 hkenken Exp $ */
+/* $NetBSD: imx6_i2c.c,v 1.3 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_i2c.c,v 1.2 2015/03/27 05:31:23 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_i2c.c,v 1.3 2019/06/20 08:16:19 hkenken Exp $");
#include "opt_imx.h"
@@ -65,11 +65,34 @@ void
imxi2c_attach(device_t parent __unused, device_t self, void *aux)
{
struct axi_attach_args *aa = aux;
+ struct imxi2c_softc *sc = device_private(self);
if (aa->aa_size <= 0)
aa->aa_size = I2C_SIZE;
- imxi2c_set_freq(self, imx6_get_clock(IMX6CLK_PERCLK), 400000);
+ switch (device_unit(self)) {
+ case 0:
+ sc->sc_clk = imx6_get_clock("i2c1");
+ break;
+ case 1:
+ sc->sc_clk = imx6_get_clock("i2c2");
+ break;
+ case 2:
+ sc->sc_clk = imx6_get_clock("i2c3");
+ break;
+ }
+ if (sc->sc_clk == NULL) {
+ aprint_error(": couldn't get clock sata\n");
+ return;
+ }
+
+ int error = clk_enable(sc->sc_clk);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error);
+ return;
+ }
+
+ imxi2c_set_freq(self, clk_get_rate(sc->sc_clk), 400000);
imxi2c_attach_common(parent, self,
aa->aa_iot, aa->aa_addr, aa->aa_size, aa->aa_irq, 0);
}
Index: src/sys/arch/arm/imx/imxi2cvar.h
diff -u src/sys/arch/arm/imx/imxi2cvar.h:1.2 src/sys/arch/arm/imx/imxi2cvar.h:1.3
--- src/sys/arch/arm/imx/imxi2cvar.h:1.2 Fri Mar 27 05:31:23 2015
+++ src/sys/arch/arm/imx/imxi2cvar.h Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imxi2cvar.h,v 1.2 2015/03/27 05:31:23 hkenken Exp $ */
+/* $NetBSD: imxi2cvar.h,v 1.3 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2012, 2015 Genetec Corporation. All rights reserved.
@@ -36,6 +36,8 @@ struct imxi2c_softc {
device_t sc_dev;
struct motoi2c_softc sc_motoi2c;
struct motoi2c_settings sc_motoi2c_settings;
+
+ struct clk *sc_clk;
};
int imxi2c_attach_common(device_t, device_t,
Index: src/sys/arch/arm/imx/imx6_ahcisata.c
diff -u src/sys/arch/arm/imx/imx6_ahcisata.c:1.8 src/sys/arch/arm/imx/imx6_ahcisata.c:1.9
--- src/sys/arch/arm/imx/imx6_ahcisata.c:1.8 Wed Jun 20 05:53:19 2018
+++ src/sys/arch/arm/imx/imx6_ahcisata.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ahcisata.c,v 1.8 2018/06/20 05:53:19 hkenken Exp $ */
+/* $NetBSD: imx6_ahcisata.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_ahcisata.c,v 1.8 2018/06/20 05:53:19 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_ahcisata.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $");
#include "locators.h"
#include "opt_imx.h"
@@ -47,23 +47,28 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_ahcisat
#include <dev/ic/ahcisatavar.h>
struct imx_ahci_softc {
+ struct ahci_softc sc_ahcisc;
+
device_t sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
void *sc_ih;
- struct ahci_softc sc_ahcisc;
+ struct clk *sc_clk_sata;
+ struct clk *sc_clk_sata_ref;
+ struct clk *sc_clk_ahb;
};
static int imx6_ahcisata_match(device_t, cfdata_t, void *);
static void imx6_ahcisata_attach(device_t, device_t, void *);
static int imx6_ahcisata_detach(device_t, int);
-static int imx6_ahcisata_init(struct imx_ahci_softc *);
static int imx6_ahcisata_phy_ctrl(struct imx_ahci_softc *, uint32_t, int);
static int imx6_ahcisata_phy_addr(struct imx_ahci_softc *, uint32_t);
static int imx6_ahcisata_phy_write(struct imx_ahci_softc *, uint32_t, uint16_t);
static int imx6_ahcisata_phy_read(struct imx_ahci_softc *, uint32_t);
+static int imx6_ahcisata_init(struct imx_ahci_softc *);
+static int imx6_ahcisata_init_clocks(struct imx_ahci_softc *);
CFATTACH_DECL_NEW(imx6_ahcisata, sizeof(struct imx_ahci_softc),
imx6_ahcisata_match, imx6_ahcisata_attach, imx6_ahcisata_detach, NULL);
@@ -114,6 +119,26 @@ imx6_ahcisata_attach(device_t parent, de
return;
}
+ sc->sc_clk_sata = imx6_get_clock("sata");
+ if (sc->sc_clk_sata == NULL) {
+ aprint_error(": couldn't get clock sata\n");
+ return;
+ }
+ sc->sc_clk_sata_ref = imx6_get_clock("sata_ref");
+ if (sc->sc_clk_sata_ref == NULL) {
+ aprint_error(": couldn't get clock sata_ref\n");
+ return;
+ }
+ sc->sc_clk_ahb = imx6_get_clock("ahb");
+ if (sc->sc_clk_ahb == NULL) {
+ aprint_error(": couldn't get clock ahb\n");
+ return;
+ }
+ if (imx6_ahcisata_init_clocks(sc) != 0) {
+ aprint_error_dev(self, "couldn't init clocks\n");
+ return;
+ }
+
if (imx6_ahcisata_init(sc) != 0) {
aprint_error_dev(self, "couldn't init ahci\n");
return;
@@ -262,21 +287,6 @@ imx6_ahcisata_init(struct imx_ahci_softc
uint32_t v;
int timeout, pllstat;
- /* AHCISATA clock enable */
- v = imx6_ccm_read(CCM_CCGR5);
- imx6_ccm_write(CCM_CCGR5, v | __SHIFTIN(3, CCM_CCGR5_SATA_CLK_ENABLE));
-
- /* PLL power up */
- if (imx6_pll_power(CCM_ANALOG_PLL_ENET, 1,
- CCM_ANALOG_PLL_ENET_ENABLE_100M) != 0) {
- aprint_error_dev(sc->sc_dev,
- "couldn't enable CCM_ANALOG_PLL_ENET\n");
- return -1;
- }
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_ENET);
- v |= CCM_ANALOG_PLL_ENET_ENABLE_100M;
- imx6_ccm_analog_write(CCM_ANALOG_PLL_ENET, v);
-
v = iomux_read(IOMUX_GPR13);
/* clear */
v &= ~(IOMUX_GPR13_SATA_PHY_8(7) |
@@ -332,7 +342,32 @@ imx6_ahcisata_init(struct imx_ahci_softc
/* set 1ms-timer = AHB clock / 1000 */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS,
- imx6_get_clock(IMX6CLK_AHB) / 1000);
+ clk_get_rate(sc->sc_clk_ahb) / 1000);
return 0;
}
+
+static int
+imx6_ahcisata_init_clocks(struct imx_ahci_softc *sc)
+{
+ int error;
+
+ error = clk_enable(sc->sc_clk_sata);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable sata: %d\n", error);
+ return error;
+ }
+ error = clk_enable(sc->sc_clk_sata_ref);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable sata-ref: %d\n", error);
+ return error;
+ }
+ error = clk_enable(sc->sc_clk_ahb);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable anb: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
Index: src/sys/arch/arm/imx/imx6_pcie.c
diff -u src/sys/arch/arm/imx/imx6_pcie.c:1.8 src/sys/arch/arm/imx/imx6_pcie.c:1.9
--- src/sys/arch/arm/imx/imx6_pcie.c:1.8 Fri Mar 1 09:25:59 2019
+++ src/sys/arch/arm/imx/imx6_pcie.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_pcie.c,v 1.8 2019/03/01 09:25:59 msaitoh Exp $ */
+/* $NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2016 Genetec Corporation. All rights reserved.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.8 2019/03/01 09:25:59 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $");
#include "opt_pci.h"
@@ -104,6 +104,10 @@ struct imx6pcie_softc {
int32_t sc_gpio_reset_active;
int32_t sc_gpio_pwren;
int32_t sc_gpio_pwren_active;
+
+ struct clk *sc_clk_pcie_axi;
+ struct clk *sc_clk_lvds1_gate;
+ struct clk *sc_clk_pcie_ref;
};
#define PCIE_CONF_LOCK(s) (s) = disable_interrupts(I32_bit)
@@ -160,41 +164,28 @@ imx6pcie_valid_device(struct imx6pcie_so
return 1;
}
-static void
-imx6pcie_clock_enable(struct imx6pcie_softc *sc)
+static int
+imx6pcie_init_clocks(struct imx6pcie_softc *sc)
{
- uint32_t v;
+ int error;
- v = imx6_ccm_analog_read(CCM_ANALOG_MISC1);
- v &= ~CCM_ANALOG_MISC1_LVDS_CLK1_IBEN;
- v &= ~CCM_ANALOG_MISC1_LVDS_CLK1_SRC;
- v |= CCM_ANALOG_MISC1_LVDS_CLK1_OBEN;
- v |= CCM_ANALOG_MISC1_LVDS_CLK1_SRC_SATA;
- imx6_ccm_analog_write(CCM_ANALOG_MISC1, v);
-
- /* select PCIe clock source from axi */
- v = imx6_ccm_read(CCM_CBCMR);
- v &= ~CCM_CBCMR_PCIE_AXI_CLK_SEL;
- imx6_ccm_write(CCM_CBCMR, v);
-
- /* AHCISATA clock enable */
- v = imx6_ccm_read(CCM_CCGR5);
- v |= __SHIFTIN(3, CCM_CCGR5_SATA_CLK_ENABLE);
- imx6_ccm_write(CCM_CCGR5, v);
-
- /* PCIe clock enable */
- v = imx6_ccm_read(CCM_CCGR4);
- v |= __SHIFTIN(3, CCM_CCGR4_PCIE_ROOT_ENABLE);
- imx6_ccm_write(CCM_CCGR4, v);
-
- /* PLL power up */
- if (imx6_pll_power(CCM_ANALOG_PLL_ENET, 1,
- CCM_ANALOG_PLL_ENET_ENABLE_125M |
- CCM_ANALOG_PLL_ENET_ENABLE_100M) != 0) {
- aprint_error_dev(sc->sc_dev,
- "couldn't enable CCM_ANALOG_PLL_ENET\n");
- return;
+ error = clk_enable(sc->sc_clk_pcie_axi);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error);
+ return error;
+ }
+ error = clk_enable(sc->sc_clk_lvds1_gate);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error);
+ return error;
}
+ error = clk_enable(sc->sc_clk_pcie_ref);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error);
+ return error;
+ }
+
+ return 0;
}
static int
@@ -375,8 +366,6 @@ imx6pcie_deassert_core_reset(struct imx6
}
#endif
- imx6pcie_clock_enable(sc);
-
v = iomux_read(IOMUX_GPR1);
#if defined(IMX6DQP)
@@ -545,6 +534,8 @@ imx6pcie_match(device_t parent, cfdata_t
switch (aa->aa_addr) {
case (IMX6_PCIE_BASE):
return 1;
+ default:
+ break;
}
return 0;
@@ -583,6 +574,24 @@ imx6pcie_attach(device_t parent, device_
imx6_set_gpio(self, "imx6pcie-pwren-gpio", &sc->sc_gpio_pwren,
&sc->sc_gpio_pwren_active, GPIO_DIR_OUT);
+ sc->sc_clk_pcie_axi = imx6_get_clock("pcie_axi");
+ if (sc->sc_clk_pcie_axi == NULL) {
+ aprint_error(": couldn't get clock pcie_axi\n");
+ return;
+ }
+ sc->sc_clk_lvds1_gate = imx6_get_clock("lvds1_gate");
+ if (sc->sc_clk_lvds1_gate == NULL) {
+ aprint_error(": couldn't get clock lvds1_gate\n");
+ return;
+ }
+ sc->sc_clk_pcie_ref = imx6_get_clock("pcie_ref_125m");
+ if (sc->sc_clk_pcie_ref == NULL) {
+ aprint_error(": couldn't get clock pcie_ref\n");
+ return;
+ }
+
+ imx6pcie_init_clocks(sc);
+
imx6pcie_linkup(sc);
TAILQ_INIT(&sc->sc_intrs);
Index: src/sys/arch/arm/imx/imx6_ccm.c
diff -u src/sys/arch/arm/imx/imx6_ccm.c:1.9 src/sys/arch/arm/imx/imx6_ccm.c:1.10
--- src/sys/arch/arm/imx/imx6_ccm.c:1.9 Wed Jun 20 07:05:37 2018
+++ src/sys/arch/arm/imx/imx6_ccm.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ccm.c,v 1.9 2018/06/20 07:05:37 hkenken Exp $ */
+/* $NetBSD: imx6_ccm.c,v 1.10 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2010-2012, 2014 Genetec Corporation. All rights reserved.
@@ -25,13 +25,12 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
/*
* Clock Controller Module (CCM) for i.MX6
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.9 2018/06/20 07:05:37 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.10 2019/06/20 08:16:19 hkenken Exp $");
#include "opt_imx.h"
#include "opt_imx6clk.h"
@@ -59,37 +58,607 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v
#include <arm/imx/imx6var.h>
#include <arm/imx/imx6_reg.h>
+#include <dev/clk/clk_backend.h>
+
struct imxccm_softc {
device_t sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_space_handle_t sc_ioh_analog;
- /* for sysctl */
- struct sysctllog *sc_log;
- int sc_sysctlnode_pll1_arm;
- int sc_sysctlnode_pll2_sys;
- int sc_sysctlnode_pll3_usb1;
- int sc_sysctlnode_pll7_usb2;
- int sc_sysctlnode_pll4_audio;
- int sc_sysctlnode_pll5_video;
- int sc_sysctlnode_pll6_enet;
-/* int sc_sysctlnode_pll8_mlb; */
- int sc_sysctlnode_arm;
- int sc_sysctlnode_periph;
- int sc_sysctlnode_ahb;
- int sc_sysctlnode_ipg;
- int sc_sysctlnode_axi;
+ struct clk_domain sc_clkdom;
+};
+
+/* Clock Parents Tables */
+static const char *step_p[] = {
+ "osc",
+ "pll2_pfd2_396m"
+};
+
+static const char *pll1_sw_p[] = {
+ "pll1_sys",
+ "step"
+};
+
+static const char *periph_pre_p[] = {
+ "pll2_bus",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m",
+ "pll2_198m"
+};
+
+static const char *periph_clk2_p[] = {
+ "pll3_usb_otg",
+ "osc",
+ "osc",
+ "dummy"
+};
+
+static const char *periph2_clk2_p[] = {
+ "pll3_usb_otg",
+ "pll2_bus"
+};
+
+static const char *axi_p[] = {
+ "periph",
+ "pll2_pfd2_396m",
+ "periph",
+ "pll3_pfd1_540m"
+};
+
+static const char *audio_p[] = {
+ "pll4_audio_div",
+ "pll3_pfd2_508m",
+ "pll3_pfd3_454m",
+ "pll3_usb_otg"
+};
+
+static const char *gpu2d_core_p[] = {
+ "axi",
+ "pll3_usb_otg",
+ "pll2_pfd0_352m",
+ "pll2_pfd2_396m"
+};
+
+static const char *gpu3d_core_p[] = {
+ "mmdc_ch0_axi",
+ "pll3_usb_otg",
+ "pll2_pfd1_594m",
+ "pll2_pfd2_396m"
+};
+
+static const char *gpu3d_shader_p[] = {
+ "mmdc_ch0_axi",
+ "pll3_usb_otg",
+ "pll2_pfd1_594m",
+ "pll3_pfd0_720m"
+};
+
+static const char *ipu_p[] = {
+ "mmdc_ch0_axi",
+ "pll2_pfd2_396m",
+ "pll3_120m",
+ "pll3_pfd1_540m"
+};
+
+static const char *pll_bypass_src_p[] = {
+ "osc",
+ "lvds1_in",
+ "lvds2_in",
+ "dummy"
+};
+
+static const char *pll1_bypass_p[] = {
+ "pll1",
+ "pll1_bypass_src"
+};
+
+static const char *pll2_bypass_p[] = {
+ "pll2",
+ "pll2_bypass_src"
+};
+
+static const char *pll3_bypass_p[] = {
+ "pll3",
+ "pll3_bypass_src"
+};
+
+static const char *pll4_bypass_p[] = {
+ "pll4",
+ "pll4_bypass_src"
+};
+
+static const char *pll5_bypass_p[] = {
+ "pll5",
+ "pll5_bypass_src"
+};
+
+static const char *pll6_bypass_p[] = {
+ "pll6",
+ "pll6_bypass_src"
+};
+
+static const char *pll7_bypass_p[] = {
+ "pll7",
+ "pll7_bypass_src"
};
-struct imxccm_softc *ccm_softc;
+static const char *ipu_di_pre_p[] = {
+ "mmdc_ch0_axi",
+ "pll3_usb_otg",
+ "pll5_video_div",
+ "pll2_pfd0_352m",
+ "pll2_pfd2_396m",
+ "pll3_pfd1_540m"
+};
+
+static const char *ipu1_di0_p[] = {
+ "ipu1_di0_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0",
+ "ldb_di1"
+};
+
+static const char *ipu1_di1_p[] = {
+ "ipu1_di1_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0",
+ "ldb_di1"
+};
+
+static const char *ipu2_di0_p[] = {
+ "ipu2_di0_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0",
+ "ldb_di1"
+};
+
+static const char *ipu2_di1_p[] = {
+ "ipu2_di1_pre",
+ "dummy",
+ "dummy",
+ "ldb_di0",
+ "ldb_di1"
+};
+
+static const char *ldb_di_p[] = {
+ "pll5_video_div",
+ "pll2_pfd0_352m",
+ "pll2_pfd2_396m",
+ "mmdc_ch1_axi",
+ "pll3_usb_otg"
+};
+
+static const char *periph_p[] = {
+ "periph_pre",
+ "periph_clk2"
+};
+
+static const char *periph2_p[] = {
+ "periph2_pre",
+ "periph2_clk2"
+};
+
+static const char *vdo_axi_p[] = {
+ "axi",
+ "ahb"
+};
+
+static const char *vpu_axi_p[] = {
+ "axi",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m"
+};
+
+static const char *cko1_p[] = {
+ "pll3_usb_otg",
+ "pll2_bus",
+ "pll1_sys",
+ "pll5_video_div",
+ "dummy",
+ "axi",
+ "enfc",
+ "ipu1_di0",
+ "ipu1_di1",
+ "ipu2_di0",
+ "ipu2_di1",
+ "ahb",
+ "ipg",
+ "ipg_per",
+ "ckil",
+ "pll4_audio_div"
+};
+
+static const char *cko2_p[] = {
+ "mmdc_ch0_axi",
+ "mmdc_ch1_axi",
+ "usdhc4",
+ "usdhc1",
+ "gpu2d_axi",
+ "dummy",
+ "ecspi_root",
+ "gpu3d_axi",
+ "usdhc3",
+ "dummy",
+ "arm",
+ "ipu1",
+ "ipu2",
+ "vdo_axi",
+ "osc",
+ "gpu2d_core",
+ "gpu3d_core",
+ "usdhc2",
+ "ssi1",
+ "ssi2",
+ "ssi3",
+ "gpu3d_shader",
+ "vpu_axi",
+ "can_root",
+ "ldb_di0",
+ "ldb_di1",
+ "esai_extal",
+ "eim_slow",
+ "uart_serial",
+ "spdif",
+ "asrc",
+ "hsi_tx"
+};
+
+static const char *cko_p[] = {
+ "cko1",
+ "cko2"
+};
+
+static const char *hsi_tx_p[] = {
+ "pll3_120m",
+ "pll2_pfd2_396m"
+};
+
+static const char *pcie_axi_p[] = {
+ "axi",
+ "ahb"
+};
+
+static const char *ssi_p[] = {
+ "pll3_pfd2_508m",
+ "pll3_pfd3_454m",
+ "pll4_audio_div"
+};
+
+static const char *usdhc_p[] = {
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m"
+};
+
+static const char *eim_p[] = {
+ "pll2_pfd2_396m",
+ "pll3_usb_otg",
+ "axi",
+ "pll2_pfd0_352m"
+};
+
+static const char *eim_slow_p[] = {
+ "axi",
+ "pll3_usb_otg",
+ "pll2_pfd2_396m",
+ "pll2_pfd0_352m"
+};
+
+static const char *enfc_p[] = {
+ "pll2_pfd0_352m",
+ "pll2_bus",
+ "pll3_usb_otg",
+ "pll2_pfd2_396m"
+};
+
+static const char *lvds_p[] = {
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "dummy",
+ "pll4_audio",
+ "pll5_video",
+ "pll8_mlb",
+ "enet_ref",
+ "pcie_ref_125m",
+ "sata_ref_100m"
+};
+
+/* Clock Divider Tables */
+static const int enet_ref_tbl[] = { 20, 10, 5, 4, 0 };
+static const int post_div_tbl[] = { 4, 2, 1, 0 };
+static const int audiovideo_div_tbl[] = { 1, 2, 1, 4, 0 };
+
+static struct imx6_clk imx6_clks[] = {
+ CLK_FIXED("dummy", 0),
+
+ CLK_FIXED("ckil", IMX6_CKIL_FREQ),
+ CLK_FIXED("ckih", IMX6_CKIH_FREQ),
+ CLK_FIXED("osc", IMX6_OSC_FREQ),
+ CLK_FIXED("anaclk1", IMX6_ANACLK1_FREQ),
+ CLK_FIXED("anaclk2", IMX6_ANACLK2_FREQ),
+
+ CLK_FIXED_FACTOR("sata_ref", "pll6_enet", 5, 1),
+ CLK_FIXED_FACTOR("pcie_ref", "pll6_enet", 4, 1),
+ CLK_FIXED_FACTOR("pll2_198m", "pll2_pfd2_396m", 2, 1),
+ CLK_FIXED_FACTOR("pll3_120m", "pll3_usb_otg", 4, 1),
+ CLK_FIXED_FACTOR("pll3_80m", "pll3_usb_otg", 6, 1),
+ CLK_FIXED_FACTOR("pll3_60m", "pll3_usb_otg", 8, 1),
+ CLK_FIXED_FACTOR("twd", "arm", 2, 1),
+ CLK_FIXED_FACTOR("gpt_3m", "osc", 8, 1),
+ CLK_FIXED_FACTOR("video_27m", "pll3_pfd1_540m", 20, 1),
+ CLK_FIXED_FACTOR("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1),
+ CLK_FIXED_FACTOR("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1),
+ CLK_FIXED_FACTOR("ldb_di0_div_3_5", "ldb_di0_sel", 7, 2),
+ CLK_FIXED_FACTOR("ldb_di1_div_3_5", "ldb_di1_sel", 7, 2),
+
+ CLK_PFD("pll2_pfd0_352m", "pll2_bus", PFD_528, 0),
+ CLK_PFD("pll2_pfd1_594m", "pll2_bus", PFD_528, 1),
+ CLK_PFD("pll2_pfd2_396m", "pll2_bus", PFD_528, 2),
+ CLK_PFD("pll3_pfd0_720m", "pll3_usb_otg", PFD_480, 0),
+ CLK_PFD("pll3_pfd1_540m", "pll3_usb_otg", PFD_480, 1),
+ CLK_PFD("pll3_pfd2_508m", "pll3_usb_otg", PFD_480, 2),
+ CLK_PFD("pll3_pfd3_454m", "pll3_usb_otg", PFD_480, 3),
+
+ CLK_PLL("pll1", "osc", SYS, PLL_ARM, DIV_SELECT, POWERDOWN, 0),
+ CLK_PLL("pll2", "osc", GENNERIC, PLL_SYS, DIV_SELECT, POWERDOWN, 0),
+ CLK_PLL("pll3", "osc", USB, PLL_USB1, DIV_SELECT, POWER, 0),
+ CLK_PLL("pll4", "osc", AUDIO_VIDEO, PLL_AUDIO, DIV_SELECT, POWERDOWN, 0),
+ CLK_PLL("pll5", "osc", AUDIO_VIDEO, PLL_VIDEO, DIV_SELECT, POWERDOWN, 0),
+ CLK_PLL("pll6", "osc", ENET, PLL_ENET, DIV_SELECT, POWERDOWN, 500000000),
+ CLK_PLL("pll7", "osc", USB, PLL_USB2, DIV_SELECT, POWER, 0),
+
+ CLK_DIV("periph_clk2", "periph_clk2_sel", CBCDR, PERIPH_CLK2_PODF),
+ CLK_DIV("periph2_clk2", "periph2_clk2_sel", CBCDR, PERIPH2_CLK2_PODF),
+ CLK_DIV("ipg", "ahb", CBCDR, IPG_PODF),
+ CLK_DIV("esai_pred", "esai_sel", CS1CDR, ESAI_CLK_PRED),
+ CLK_DIV("esai_podf", "esai_pred", CS1CDR, ESAI_CLK_PODF),
+ CLK_DIV("asrc_pred", "asrc_sel", CDCDR, SPDIF1_CLK_PRED),
+ CLK_DIV("asrc_podf", "asrc_pred", CDCDR, SPDIF1_CLK_PODF),
+ CLK_DIV("spdif_pred", "spdif_sel", CDCDR, SPDIF0_CLK_PRED),
+ CLK_DIV("spdif_podf", "spdif_pred", CDCDR, SPDIF0_CLK_PODF),
+ CLK_DIV("ecspi_root", "pll3_60m", CSCDR2, ECSPI_CLK_PODF),
+ CLK_DIV("can_root", "pll3_60m", CSCMR2, CAN_CLK_PODF),
+ CLK_DIV("uart_serial_podf", "pll3_80m", CSCDR1, UART_CLK_PODF),
+ CLK_DIV("gpu2d_core_podf", "gpu2d_core_sel", CBCMR, GPU2D_CORE_CLK_PODF),
+ CLK_DIV("gpu3d_core_podf", "gpu3d_core_sel", CBCMR, GPU3D_CORE_PODF),
+ CLK_DIV("gpu3d_shader", "gpu3d_shader_sel", CBCMR, GPU3D_SHADER_PODF),
+ CLK_DIV("ipu1_podf", "ipu1_sel", CSCDR3, IPU1_HSP_PODF),
+ CLK_DIV("ipu2_podf", "ipu2_sel", CSCDR3, IPU2_HSP_PODF),
+ CLK_DIV("ldb_di0_podf", "ldb_di0_div_3_5", CSCMR2, LDB_DI0_IPU_DIV),
+ CLK_DIV("ldb_di1_podf", "ldb_di1_div_3_5", CSCMR2, LDB_DI1_IPU_DIV),
+ CLK_DIV("ipu1_di0_pre", "ipu1_di0_pre_sel", CHSCCDR, IPU1_DI0_PODF),
+ CLK_DIV("ipu1_di1_pre", "ipu1_di1_pre_sel", CHSCCDR, IPU1_DI1_PODF),
+ CLK_DIV("ipu2_di0_pre", "ipu2_di0_pre_sel", CSCDR2, IPU2_DI0_PODF),
+ CLK_DIV("ipu2_di1_pre", "ipu2_di1_pre_sel", CSCDR2, IPU2_DI1_PODF),
+ CLK_DIV("hsi_tx_podf", "hsi_tx_sel", CDCDR, HSI_TX_PODF),
+ CLK_DIV("ssi1_pred", "ssi1_sel", CS1CDR, SSI1_CLK_PRED),
+ CLK_DIV("ssi1_podf", "ssi1_pred", CS1CDR, SSI1_CLK_PODF),
+ CLK_DIV("ssi2_pred", "ssi2_sel", CS2CDR, SSI2_CLK_PRED),
+ CLK_DIV("ssi2_podf", "ssi2_pred", CS2CDR, SSI2_CLK_PODF),
+ CLK_DIV("ssi3_pred", "ssi3_sel", CS1CDR, SSI3_CLK_PRED),
+ CLK_DIV("ssi3_podf", "ssi3_pred", CS1CDR, SSI3_CLK_PODF),
+ CLK_DIV("usdhc1_podf", "usdhc1_sel", CSCDR1, USDHC1_PODF),
+ CLK_DIV("usdhc2_podf", "usdhc2_sel", CSCDR1, USDHC2_PODF),
+ CLK_DIV("usdhc3_podf", "usdhc3_sel", CSCDR1, USDHC3_PODF),
+ CLK_DIV("usdhc4_podf", "usdhc4_sel", CSCDR1, USDHC4_PODF),
+ CLK_DIV("enfc_pred", "enfc_sel", CS2CDR, ENFC_CLK_PRED),
+ CLK_DIV("enfc_podf", "enfc_pred", CS2CDR, ENFC_CLK_PODF),
+ CLK_DIV("vpu_axi_podf", "vpu_axi_sel", CSCDR1, VPU_AXI_PODF),
+ CLK_DIV("cko1_podf", "cko1_sel", CCOSR, CLKO1_DIV),
+ CLK_DIV("cko2_podf", "cko2_sel", CCOSR, CLKO2_DIV),
+ CLK_DIV("ipg_per", "ipg", CSCMR1, PERCLK_PODF),
+ CLK_DIV("eim_podf", "eim_sel", CSCMR1, ACLK_PODF),
+ CLK_DIV("eim_slow_podf", "eim_slow_sel", CSCMR1, ACLK_EIM_SLOW_PODF),
+
+ CLK_DIV_BUSY("axi", "axi_sel", CBCDR, AXI_PODF, CDHIPR, AXI_PODF_BUSY),
+ CLK_DIV_BUSY("mmdc_ch0_axi_podf", "periph", CBCDR, MMDC_CH0_AXI_PODF, CDHIPR, MMDC_CH0_PODF_BUSY),
+ CLK_DIV_BUSY("mmdc_ch1_axi_podf", "periph2", CBCDR, MMDC_CH1_AXI_PODF, CDHIPR, MMDC_CH1_PODF_BUSY),
+ CLK_DIV_BUSY("arm", "pll1_sw", CACRR, ARM_PODF, CDHIPR, ARM_PODF_BUSY),
+ CLK_DIV_BUSY("ahb", "periph", CBCDR, AHB_PODF, CDHIPR, AHB_PODF_BUSY),
+
+ CLK_DIV_TABLE("pll4_post_div", "pll4_audio", PLL_AUDIO, POST_DIV_SELECT, post_div_tbl),
+ CLK_DIV_TABLE("pll4_audio_div", "pll4_post_div", MISC2, AUDIO_DIV_LSB, audiovideo_div_tbl),
+ CLK_DIV_TABLE("pll5_post_div", "pll5_video", PLL_VIDEO, POST_DIV_SELECT, post_div_tbl),
+ CLK_DIV_TABLE("pll5_video_div", "pll5_post_div", MISC2, VIDEO_DIV, audiovideo_div_tbl),
+ CLK_DIV_TABLE("enet_ref", "pll6_enet", PLL_ENET, DIV_SELECT, enet_ref_tbl),
+
+ CLK_MUX("step", step_p, CCM, CCSR, STEP_SEL),
+ CLK_MUX("pll1_sw", pll1_sw_p, CCM, CCSR, PLL1_SW_CLK_SEL),
+ CLK_MUX("periph_pre", periph_pre_p, CCM, CBCMR, PRE_PERIPH_CLK_SEL),
+ CLK_MUX("periph2_pre", periph_pre_p, CCM, CBCMR, PRE_PERIPH2_CLK_SEL),
+ CLK_MUX("periph_clk2_sel", periph_clk2_p, CCM,CBCMR, PERIPH_CLK2_SEL),
+ CLK_MUX("periph2_clk2_sel", periph2_clk2_p, CCM,CBCMR, PERIPH2_CLK2_SEL),
+ CLK_MUX("axi_sel", axi_p, CCM, CBCDR, AXI_SEL),
+ CLK_MUX("asrc_sel", audio_p, CCM, CDCDR, SPDIF1_CLK_SEL),
+ CLK_MUX("spdif_sel", audio_p, CCM, CDCDR, SPDIF0_CLK_SEL),
+ CLK_MUX("gpu2d_core_sel", gpu2d_core_p, CCM, CBCMR, GPU2D_CLK_SEL),
+ CLK_MUX("gpu3d_core_sel", gpu3d_core_p, CCM, CBCMR, GPU3D_CORE_CLK_SEL),
+ CLK_MUX("gpu3d_shader_sel", gpu3d_shader_p, CCM,CBCMR, GPU3D_SHADER_CLK_SEL),
+ CLK_MUX("esai_sel", audio_p, CCM, CSCMR2, ESAI_CLK_SEL),
+ CLK_MUX("ipu1_sel", ipu_p, CCM, CSCDR3, IPU1_HSP_CLK_SEL),
+ CLK_MUX("ipu2_sel", ipu_p, CCM, CSCDR3, IPU2_HSP_CLK_SEL),
+ CLK_MUX("ipu1_di0_pre_sel", ipu_di_pre_p, CCM, CHSCCDR, IPU1_DI0_PRE_CLK_SEL),
+ CLK_MUX("ipu1_di1_pre_sel", ipu_di_pre_p, CCM, CHSCCDR, IPU1_DI1_PRE_CLK_SEL),
+ CLK_MUX("ipu2_di0_pre_sel", ipu_di_pre_p, CCM, CSCDR2, IPU2_DI0_PRE_CLK_SEL),
+ CLK_MUX("ipu2_di1_pre_sel", ipu_di_pre_p, CCM, CSCDR2, IPU2_DI1_PRE_CLK_SEL),
+ CLK_MUX("ipu1_di0_sel", ipu1_di0_p, CCM, CHSCCDR, IPU1_DI0_CLK_SEL),
+ CLK_MUX("ipu1_di1_sel", ipu1_di1_p, CCM, CHSCCDR, IPU1_DI1_CLK_SEL),
+ CLK_MUX("ipu2_di0_sel", ipu2_di0_p, CCM, CSCDR2, IPU2_DI0_CLK_SEL),
+ CLK_MUX("ipu2_di1_sel", ipu2_di1_p, CCM, CSCDR2, IPU2_DI1_CLK_SEL),
+ CLK_MUX("ldb_di0_sel", ldb_di_p, CCM, CS2CDR, LDB_DI0_CLK_SEL),
+ CLK_MUX("ldb_di1_sel", ldb_di_p, CCM, CS2CDR, LDB_DI1_CLK_SEL),
+ CLK_MUX("vdo_axi_sel", vdo_axi_p, CCM, CBCMR, VDOAXI_CLK_SEL),
+ CLK_MUX("vpu_axi_sel", vpu_axi_p, CCM, CBCMR, VPU_AXI_CLK_SEL),
+ CLK_MUX("cko1_sel", cko1_p, CCM, CCOSR, CLKO1_SEL),
+ CLK_MUX("cko2_sel", cko2_p, CCM, CCOSR, CLKO2_SEL),
+ CLK_MUX("cko", cko_p, CCM, CCOSR, CLK_OUT_SEL),
+ CLK_MUX("hsi_tx_sel", hsi_tx_p, CCM, CDCDR, HSI_TX_CLK_SEL),
+ CLK_MUX("pcie_axi_sel", pcie_axi_p, CCM, CBCMR, PCIE_AXI_CLK_SEL),
+ CLK_MUX("ssi1_sel", ssi_p, CCM, CSCMR1, SSI1_CLK_SEL),
+ CLK_MUX("ssi2_sel", ssi_p, CCM, CSCMR1, SSI2_CLK_SEL),
+ CLK_MUX("ssi3_sel", ssi_p, CCM, CSCMR1, SSI3_CLK_SEL),
+ CLK_MUX("usdhc1_sel", usdhc_p, CCM, CSCMR1, USDHC1_CLK_SEL),
+ CLK_MUX("usdhc2_sel", usdhc_p, CCM, CSCMR1, USDHC2_CLK_SEL),
+ CLK_MUX("usdhc3_sel", usdhc_p, CCM, CSCMR1, USDHC3_CLK_SEL),
+ CLK_MUX("usdhc4_sel", usdhc_p, CCM, CSCMR1, USDHC4_CLK_SEL),
+ CLK_MUX("eim_sel", eim_p, CCM, CSCMR1, ACLK_SEL),
+ CLK_MUX("eim_slow_sel", eim_slow_p, CCM, CSCMR1, ACLK_EIM_SLOW_SEL),
+ CLK_MUX("enfc_sel", enfc_p, CCM, CS2CDR, ENFC_CLK_SEL),
+
+ CLK_MUX("pll1_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_ARM, BYPASS_CLK_SRC),
+ CLK_MUX("pll2_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_SYS, BYPASS_CLK_SRC),
+ CLK_MUX("pll3_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_USB1, BYPASS_CLK_SRC),
+ CLK_MUX("pll4_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_AUDIO, BYPASS_CLK_SRC),
+ CLK_MUX("pll5_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_VIDEO, BYPASS_CLK_SRC),
+ CLK_MUX("pll6_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_ENET, BYPASS_CLK_SRC),
+ CLK_MUX("pll7_bypass_src", pll_bypass_src_p, CCM_ANALOG, PLL_USB2, BYPASS_CLK_SRC),
+ CLK_MUX("pll1_bypass", pll1_bypass_p, CCM_ANALOG, PLL_ARM, BYPASS),
+ CLK_MUX("pll2_bypass", pll2_bypass_p, CCM_ANALOG, PLL_SYS, BYPASS),
+ CLK_MUX("pll3_bypass", pll3_bypass_p, CCM_ANALOG, PLL_USB1, BYPASS),
+ CLK_MUX("pll4_bypass", pll4_bypass_p, CCM_ANALOG, PLL_AUDIO, BYPASS),
+ CLK_MUX("pll5_bypass", pll5_bypass_p, CCM_ANALOG, PLL_VIDEO, BYPASS),
+ CLK_MUX("pll6_bypass", pll6_bypass_p, CCM_ANALOG, PLL_ENET, BYPASS),
+ CLK_MUX("pll7_bypass", pll7_bypass_p, CCM_ANALOG, PLL_USB2, BYPASS),
+
+ CLK_MUX("lvds1_sel", lvds_p, CCM_ANALOG, MISC1, LVDS_CLK1_SRC),
+ CLK_MUX("lvds2_sel", lvds_p, CCM_ANALOG, MISC1, LVDS_CLK2_SRC),
+
+ CLK_MUX_BUSY("periph", periph_p, CBCDR, PERIPH_CLK_SEL, CDHIPR, PERIPH_CLK_SEL_BUSY),
+ CLK_MUX_BUSY("periph2", periph2_p, CBCDR, PERIPH2_CLK_SEL, CDHIPR, PERIPH2_CLK_SEL_BUSY),
+
+ CLK_GATE("apbh_dma", "usdhc3", CCM, CCGR0, APBHDMA_HCLK_ENABLE),
+ CLK_GATE("asrc", "asrc_podf", CCM, CCGR0, ASRC_CLK_ENABLE),
+ CLK_GATE("asrc_ipg", "ahb", CCM, CCGR0, ASRC_CLK_ENABLE),
+ CLK_GATE("asrc_mem", "ahb", CCM, CCGR0, ASRC_CLK_ENABLE),
+ CLK_GATE("caam_mem", "ahb", CCM, CCGR0, CAAM_SECURE_MEM_CLK_ENABLE),
+ CLK_GATE("caam_aclk", "ahb", CCM, CCGR0, CAAM_WRAPPER_ACLK_ENABLE),
+ CLK_GATE("caam_ipg", "ipg", CCM, CCGR0, CAAM_WRAPPER_IPG_ENABLE),
+ CLK_GATE("can1_ipg", "ipg", CCM, CCGR0, CAN1_CLK_ENABLE),
+ CLK_GATE("can1_serial", "can_root", CCM, CCGR0, CAN1_SERIAL_CLK_ENABLE),
+ CLK_GATE("can2_ipg", "ipg", CCM, CCGR0, CAN2_CLK_ENABLE),
+ CLK_GATE("can2_serial", "can_root", CCM, CCGR0, CAN2_SERIAL_CLK_ENABLE),
+ CLK_GATE("ecspi1", "ecspi_root", CCM, CCGR1, ECSPI1_CLK_ENABLE),
+ CLK_GATE("ecspi2", "ecspi_root", CCM, CCGR1, ECSPI2_CLK_ENABLE),
+ CLK_GATE("ecspi3", "ecspi_root", CCM, CCGR1, ECSPI3_CLK_ENABLE),
+ CLK_GATE("ecspi4", "ecspi_root", CCM, CCGR1, ECSPI4_CLK_ENABLE),
+ CLK_GATE("ecspi5", "ecspi_root", CCM, CCGR1, ECSPI5_CLK_ENABLE),
+ CLK_GATE("enet", "ipg", CCM, CCGR1, ENET_CLK_ENABLE),
+ CLK_GATE("esai_extal", "esai_podf", CCM, CCGR1, ESAI_CLK_ENABLE),
+ CLK_GATE("esai_ipg", "ahb", CCM, CCGR1, ESAI_CLK_ENABLE),
+ CLK_GATE("esai_mem", "ahb", CCM, CCGR1, ESAI_CLK_ENABLE),
+ CLK_GATE("gpt_ipg", "ipg", CCM, CCGR1, GPT_CLK_ENABLE),
+ CLK_GATE("gpt_ipg_per", "ipg_per", CCM, CCGR1, GPT_SERIAL_CLK_ENABLE),
+ CLK_GATE("gpu2d_core", "gpu2d_core_podf", CCM, CCGR1, GPU2D_CLK_ENABLE),
+ CLK_GATE("gpu3d_core", "gpu3d_core_podf", CCM, CCGR1, GPU3D_CLK_ENABLE),
+ CLK_GATE("hdmi_iahb", "ahb", CCM, CCGR2, HDMI_TX_IAHBCLK_ENABLE),
+ CLK_GATE("hdmi_isfr", "video_27m", CCM, CCGR2, HDMI_TX_ISFRCLK_ENABLE),
+ CLK_GATE("i2c1", "ipg_per", CCM, CCGR2, I2C1_SERIAL_CLK_ENABLE),
+ CLK_GATE("i2c2", "ipg_per", CCM, CCGR2, I2C2_SERIAL_CLK_ENABLE),
+ CLK_GATE("i2c3", "ipg_per", CCM, CCGR2, I2C3_SERIAL_CLK_ENABLE),
+ CLK_GATE("iim", "ipg", CCM, CCGR2, IIM_CLK_ENABLE),
+ CLK_GATE("enfc", "enfc_podf", CCM, CCGR2, IOMUX_IPT_CLK_IO_CLK_ENABLE),
+ CLK_GATE("vdoa", "vdo_axi", CCM, CCGR2, IPSYNC_VDOA_IPG_CLK_ENABLE),
+ CLK_GATE("ipu1", "ipu1_podf", CCM, CCGR3, IPU1_IPU_CLK_ENABLE),
+ CLK_GATE("ipu1_di0", "ipu1_di0_sel", CCM, CCGR3, IPU1_IPU_DI0_CLK_ENABLE),
+ CLK_GATE("ipu1_di1", "ipu1_di1_sel", CCM, CCGR3, IPU1_IPU_DI1_CLK_ENABLE),
+ CLK_GATE("ipu2", "ipu2_podf", CCM, CCGR3, IPU2_IPU_CLK_ENABLE),
+ CLK_GATE("ipu2_di0", "ipu2_di0_sel", CCM, CCGR3, IPU2_IPU_DI0_CLK_ENABLE),
+ CLK_GATE("ldb_di0", "ldb_di0_podf", CCM, CCGR3, LDB_DI0_CLK_ENABLE),
+ CLK_GATE("ldb_di1", "ldb_di1_podf", CCM, CCGR3, LDB_DI1_CLK_ENABLE),
+ CLK_GATE("ipu2_di1", "ipu2_di1_sel", CCM, CCGR3, IPU2_IPU_DI1_CLK_ENABLE),
+ CLK_GATE("hsi_tx", "hsi_tx_podf", CCM, CCGR3, MIPI_CORE_CFG_CLK_ENABLE),
+ CLK_GATE("mipi_core_cfg", "video_27m", CCM, CCGR3, MIPI_CORE_CFG_CLK_ENABLE),
+ CLK_GATE("mipi_ipg", "ipg", CCM, CCGR3, MIPI_CORE_CFG_CLK_ENABLE),
+ CLK_GATE("mlb", "axi", CCM, CCGR3, MLB_CLK_ENABLE),
+ CLK_GATE("mmdc_ch0_axi", "mmdc_ch0_axi_podf", CCM, CCGR3, MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE),
+ CLK_GATE("mmdc_ch1_axi", "mmdc_ch1_axi_podf", CCM, CCGR3, MMDC_CORE_ACLK_FAST_CORE_P1_ENABLE),
+ CLK_GATE("ocram", "ahb", CCM, CCGR3, OCRAM_CLK_ENABLE),
+ CLK_GATE("openvg_axi", "axi", CCM, CCGR3, OPENVGAXICLK_CLK_ROOT_ENABLE),
+ CLK_GATE("pcie_axi", "pcie_axi_sel", CCM, CCGR4, PCIE_ROOT_ENABLE),
+ CLK_GATE("per1_bch", "usdhc3", CCM, CCGR4, PL301_MX6QPER1_BCHCLK_ENABLE),
+ CLK_GATE("pwm1", "ipg_per", CCM, CCGR4, PWM1_CLK_ENABLE),
+ CLK_GATE("pwm2", "ipg_per", CCM, CCGR4, PWM2_CLK_ENABLE),
+ CLK_GATE("pwm3", "ipg_per", CCM, CCGR4, PWM3_CLK_ENABLE),
+ CLK_GATE("pwm4", "ipg_per", CCM, CCGR4, PWM4_CLK_ENABLE),
+ CLK_GATE("gpmi_bch_apb", "usdhc3", CCM, CCGR4, RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE),
+ CLK_GATE("gpmi_bch", "usdhc4", CCM, CCGR4, RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE),
+ CLK_GATE("gpmi_io", "enfc", CCM, CCGR4, RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE),
+ CLK_GATE("gpmi_apb", "usdhc3", CCM, CCGR4, RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE),
+ CLK_GATE("rom", "ahb", CCM, CCGR5, ROM_CLK_ENABLE),
+ CLK_GATE("sata", "ahb", CCM, CCGR5, SATA_CLK_ENABLE),
+ CLK_GATE("sdma", "ahb", CCM, CCGR5, SDMA_CLK_ENABLE),
+ CLK_GATE("spba", "ipg", CCM, CCGR5, SPBA_CLK_ENABLE),
+ CLK_GATE("spdif", "spdif_podf", CCM, CCGR5, SPDIF_CLK_ENABLE),
+ CLK_GATE("spdif_gclk", "ipg", CCM, CCGR5, SPDIF_CLK_ENABLE),
+ CLK_GATE("ssi1_ipg", "ipg", CCM, CCGR5, SSI1_CLK_ENABLE),
+ CLK_GATE("ssi2_ipg", "ipg", CCM, CCGR5, SSI2_CLK_ENABLE),
+ CLK_GATE("ssi3_ipg", "ipg", CCM, CCGR5, SSI3_CLK_ENABLE),
+ CLK_GATE("ssi1", "ssi1_podf", CCM, CCGR5, SSI1_CLK_ENABLE),
+ CLK_GATE("ssi2", "ssi2_podf", CCM, CCGR5, SSI2_CLK_ENABLE),
+ CLK_GATE("ssi3", "ssi3_podf", CCM, CCGR5, SSI3_CLK_ENABLE),
+ CLK_GATE("uart_ipg", "ipg", CCM, CCGR5, UART_CLK_ENABLE),
+ CLK_GATE("uart_serial", "uart_serial_podf", CCM, CCGR5, UART_SERIAL_CLK_ENABLE),
+ CLK_GATE("usboh3", "ipg", CCM, CCGR6, USBOH3_CLK_ENABLE),
+ CLK_GATE("usdhc1", "usdhc1_podf", CCM, CCGR6, USDHC1_CLK_ENABLE),
+ CLK_GATE("usdhc2", "usdhc2_podf", CCM, CCGR6, USDHC2_CLK_ENABLE),
+ CLK_GATE("usdhc3", "usdhc3_podf", CCM, CCGR6, USDHC3_CLK_ENABLE),
+ CLK_GATE("usdhc4", "usdhc4_podf", CCM, CCGR6, USDHC4_CLK_ENABLE),
+ CLK_GATE("eim_slow", "eim_slow_podf", CCM, CCGR6, EIM_SLOW_CLK_ENABLE),
+ CLK_GATE("vdo_axi", "vdo_axi_sel", CCM, CCGR6, VDOAXICLK_CLK_ENABLE),
+ CLK_GATE("vpu_axi", "vpu_axi_podf", CCM, CCGR6, VPU_CLK_ENABLE),
+ CLK_GATE("cko1", "cko1_podf", CCM, CCOSR, CLKO1_EN),
+ CLK_GATE("cko2", "cko2_podf", CCM, CCOSR, CLKO2_EN),
+
+ CLK_GATE("sata_ref_100m", "sata_ref", CCM_ANALOG, PLL_ENET, ENABLE_100M),
+ CLK_GATE("pcie_ref_125m", "pcie_ref", CCM_ANALOG, PLL_ENET, ENABLE_125M),
+
+ CLK_GATE("pll1_sys", "pll1_bypass", CCM_ANALOG, PLL_ARM, ENABLE),
+ CLK_GATE("pll2_bus", "pll2_bypass", CCM_ANALOG, PLL_SYS, ENABLE),
+ CLK_GATE("pll3_usb_otg", "pll3_bypass", CCM_ANALOG, PLL_USB1, ENABLE),
+ CLK_GATE("pll4_audio", "pll4_bypass", CCM_ANALOG, PLL_AUDIO, ENABLE),
+ CLK_GATE("pll5_video", "pll5_bypass", CCM_ANALOG, PLL_VIDEO, ENABLE),
+ CLK_GATE("pll6_enet", "pll6_bypass", CCM_ANALOG, PLL_ENET, ENABLE),
+ CLK_GATE("pll7_usb_host", "pll7_bypass", CCM_ANALOG, PLL_USB2, ENABLE),
+
+ CLK_GATE("usbphy1", "pll3_usb_otg", CCM_ANALOG, PLL_USB1, RESERVED),
+ CLK_GATE("usbphy2", "pll7_usb_host", CCM_ANALOG, PLL_USB2, RESERVED),
+
+ CLK_GATE_EXCLUSIVE("lvds1_gate", "lvds1_sel", CCM_ANALOG, MISC1, LVDS_CLK1_OBEN, LVDS_CLK1_IBEN),
+ CLK_GATE_EXCLUSIVE("lvds2_gate", "lvds2_sel", CCM_ANALOG, MISC1, LVDS_CLK2_OBEN, LVDS_CLK2_IBEN),
+};
+
+static struct imx6_clk *imx6_clk_find(const char *);
+
+static void imxccm_init_clocks(struct imxccm_softc *);
+static struct clk *imxccm_clk_get(void *, const char *);
+static void imxccm_clk_put(void *, struct clk *);
+static u_int imxccm_clk_get_rate(void *, struct clk *);
+static int imxccm_clk_set_rate(void *, struct clk *, u_int);
+static int imxccm_clk_enable(void *, struct clk *);
+static int imxccm_clk_disable(void *, struct clk *);
+static int imxccm_clk_set_parent(void *, struct clk *, struct clk *);
+static struct clk *imxccm_clk_get_parent(void *, struct clk *);
+
+static const struct clk_funcs imxccm_clk_funcs = {
+ .get = imxccm_clk_get,
+ .put = imxccm_clk_put,
+ .get_rate = imxccm_clk_get_rate,
+ .set_rate = imxccm_clk_set_rate,
+ .enable = imxccm_clk_enable,
+ .disable = imxccm_clk_disable,
+ .set_parent = imxccm_clk_set_parent,
+ .get_parent = imxccm_clk_get_parent,
+};
static int imxccm_match(device_t, cfdata_t, void *);
static void imxccm_attach(device_t, device_t, void *);
-static int imxccm_sysctl_freq_helper(SYSCTLFN_PROTO);
-static int imxccm_sysctl_setup(struct imxccm_softc *);
-
CFATTACH_DECL_NEW(imxccm, sizeof(struct imxccm_softc),
imxccm_match, imxccm_attach, NULL, NULL);
@@ -98,9 +667,6 @@ imxccm_match(device_t parent, cfdata_t c
{
struct axi_attach_args *aa = aux;
- if (ccm_softc != NULL)
- return 0;
-
if (aa->aa_addr == IMX6_AIPS1_BASE + AIPS1_CCM_BASE)
return 1;
@@ -114,10 +680,8 @@ imxccm_attach(device_t parent, device_t
struct axi_attach_args *aa = aux;
bus_space_tag_t iot = aa->aa_iot;
- ccm_softc = sc;
sc->sc_dev = self;
sc->sc_iot = iot;
- sc->sc_log = NULL;
if (bus_space_map(iot, aa->aa_addr, AIPS1_CCM_SIZE, 0, &sc->sc_ioh)) {
aprint_error(": can't map CCM registers\n");
@@ -131,817 +695,571 @@ imxccm_attach(device_t parent, device_t
return;
}
- aprint_normal(": Clock Control Module\n");
aprint_naive("\n");
+ aprint_normal(": Clock Control Module\n");
+
+ sc->sc_clkdom.name = device_xname(self);
+ sc->sc_clkdom.funcs = &imxccm_clk_funcs;
+ sc->sc_clkdom.priv = sc;
+ for (u_int n = 0; n < __arraycount(imx6_clks); n++) {
+ imx6_clks[n].base.domain = &sc->sc_clkdom;
+ clk_attach(&imx6_clks[n].base);
+ }
- imxccm_sysctl_setup(sc);
+ imxccm_init_clocks(sc);
- aprint_verbose_dev(self, "PLL_ARM clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL1));
- aprint_verbose_dev(self, "PLL_SYS clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL2));
- aprint_verbose_dev(self, "PLL_USB1 clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL3));
- aprint_verbose_dev(self, "PLL_USB2 clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL7));
- aprint_verbose_dev(self, "PLL_AUDIO clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL4));
- aprint_verbose_dev(self, "PLL_VIDEO clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL5));
- aprint_verbose_dev(self, "PLL_ENET clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL6));
- aprint_verbose_dev(self, "PLL_MLB clock=%d\n",
- imx6_get_clock(IMX6CLK_PLL7));
-
- aprint_verbose_dev(self, "IMX6CLK_PLL2_PFD0=%d\n",
- imx6_get_clock(IMX6CLK_PLL2_PFD0));
- aprint_verbose_dev(self, "IMX6CLK_PLL2_PFD1=%d\n",
- imx6_get_clock(IMX6CLK_PLL2_PFD1));
- aprint_verbose_dev(self, "IMX6CLK_PLL2_PFD2=%d\n",
- imx6_get_clock(IMX6CLK_PLL2_PFD2));
- aprint_verbose_dev(self, "IMX6CLK_PLL3_PFD0=%d\n",
- imx6_get_clock(IMX6CLK_PLL3_PFD0));
- aprint_verbose_dev(self, "IMX6CLK_PLL3_PFD1=%d\n",
- imx6_get_clock(IMX6CLK_PLL3_PFD1));
- aprint_verbose_dev(self, "IMX6CLK_PLL3_PFD2=%d\n",
- imx6_get_clock(IMX6CLK_PLL3_PFD2));
- aprint_verbose_dev(self, "IMX6CLK_PLL3_PFD3=%d\n",
- imx6_get_clock(IMX6CLK_PLL3_PFD3));
- aprint_verbose_dev(self, "IMX6CLK_ARM_ROOT=%d\n",
- imx6_get_clock(IMX6CLK_ARM_ROOT));
- aprint_verbose_dev(self, "IMX6CLK_PERIPH=%d\n",
- imx6_get_clock(IMX6CLK_PERIPH));
- aprint_verbose_dev(self, "IMX6CLK_AHB=%d\n",
- imx6_get_clock(IMX6CLK_AHB));
- aprint_verbose_dev(self, "IMX6CLK_IPG=%d\n",
- imx6_get_clock(IMX6CLK_IPG));
- aprint_verbose_dev(self, "IMX6CLK_AXI=%d\n",
- imx6_get_clock(IMX6CLK_AXI));
-
- aprint_verbose_dev(self, "IMX6CLK_USDHC1=%d\n",
- imx6_get_clock(IMX6CLK_USDHC1));
- aprint_verbose_dev(self, "IMX6CLK_USDHC2=%d\n",
- imx6_get_clock(IMX6CLK_USDHC2));
- aprint_verbose_dev(self, "IMX6CLK_USDHC3=%d\n",
- imx6_get_clock(IMX6CLK_USDHC3));
- aprint_verbose_dev(self, "IMX6CLK_USDHC4=%d\n",
- imx6_get_clock(IMX6CLK_USDHC4));
+ for (int n = 0; n < __arraycount(imx6_clks); n++) {
+ struct clk *clk = &imx6_clks[n].base;
+ struct clk *clk_parent = clk_get_parent(clk);
+ const char *parent_str = clk_parent ? clk_parent->name : "none";
+ aprint_verbose_dev(self, "%s (%s): %u Hz\n", clk->name,
+ parent_str, clk_get_rate(clk));
+ }
}
-static int
-imxccm_sysctl_setup(struct imxccm_softc *sc)
+struct clk *
+imx6_get_clock(const char *name)
{
- const struct sysctlnode *node, *imxnode, *freqnode, *pllnode;
- int rv;
+ struct imx6_clk *iclk;
+ iclk = imx6_clk_find(name);
- rv = sysctl_createv(&sc->sc_log, 0, NULL, &node,
- CTLFLAG_PERMANENT, CTLTYPE_NODE,
- "machdep", NULL,
- NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
- if (rv != 0)
- goto fail;
-
- rv = sysctl_createv(&sc->sc_log, 0, &node, &imxnode,
- 0, CTLTYPE_NODE,
- "imx6", NULL,
- NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
-
- rv = sysctl_createv(&sc->sc_log, 0, &imxnode, &freqnode,
- 0, CTLTYPE_NODE,
- "frequency", NULL,
- NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
-
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &pllnode,
- 0, CTLTYPE_NODE,
- "pll", NULL,
- NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- CTLFLAG_READWRITE, CTLTYPE_INT,
- "arm", SYSCTL_DESCR("frequency of ARM clock (PLL1)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll1_arm= node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "system", SYSCTL_DESCR("frequency of system clock (PLL2)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll2_sys = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "usb1", SYSCTL_DESCR("frequency of USB1 clock (PLL3)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll3_usb1 = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "usb2", SYSCTL_DESCR("frequency of USB2 clock (PLL7)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll7_usb2 = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "audio", SYSCTL_DESCR("frequency of AUDIO clock (PLL4)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll4_audio = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "video", SYSCTL_DESCR("frequency of VIDEO clock (PLL5)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll5_video = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "enet", SYSCTL_DESCR("frequency of ENET clock (PLL6)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll6_enet = node->sysctl_num;
-
-#if 0
- rv = sysctl_createv(&sc->sc_log, 0, &pllnode, &node,
- 0, CTLTYPE_INT,
- "mlb", SYSCTL_DESCR("frequency of MediaLinkBus clock (PLL8)"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_pll8_mlb = node->sysctl_num;
-#endif
+ if (iclk == NULL)
+ return NULL;
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
- CTLFLAG_READWRITE, CTLTYPE_INT,
- "arm", SYSCTL_DESCR("frequency of ARM Root clock"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_arm = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
- 0, CTLTYPE_INT,
- "peripheral", SYSCTL_DESCR("current frequency of Peripheral clock"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_periph = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
- 0, CTLTYPE_INT,
- "ahb", SYSCTL_DESCR("current frequency of AHB clock"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_ahb = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
- 0, CTLTYPE_INT,
- "ipg", SYSCTL_DESCR("current frequency of IPG clock"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_ipg = node->sysctl_num;
-
- rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
- 0, CTLTYPE_INT,
- "axi", SYSCTL_DESCR("current frequency of AXI clock"),
- imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
- if (rv != 0)
- goto fail;
- sc->sc_sysctlnode_axi = node->sysctl_num;
+ return &iclk->base;
+}
- return 0;
+static struct imx6_clk *
+imx6_clk_find(const char *name)
+{
+ if (name == NULL)
+ return NULL;
+
+ for (int n = 0; n < __arraycount(imx6_clks); n++) {
+ if (strcmp(imx6_clks[n].base.name, name) == 0)
+ return &imx6_clks[n];
+ }
+
+ return NULL;
+}
- fail:
- aprint_error_dev(sc->sc_dev, "cannot initialize sysctl (err=%d)\n", rv);
+struct imxccm_init_parent {
+ const char *clock;
+ const char *parent;
+} imxccm_init_parents[] = {
+ { "pll1_bypass", "pll1" },
+ { "pll2_bypass", "pll2" },
+ { "pll3_bypass", "pll3" },
+ { "pll4_bypass", "pll4" },
+ { "pll5_bypass", "pll5" },
+ { "pll6_bypass", "pll6" },
+ { "pll7_bypass", "pll7" },
+ { "lvds1_sel", "sata_ref_100m" },
+};
- sysctl_teardown(&sc->sc_log);
- sc->sc_log = NULL;
+static void
+imxccm_init_clocks(struct imxccm_softc *sc)
+{
+ struct clk *clk;
+ struct clk *clk_parent;
- return -1;
+ for (u_int n = 0; n < __arraycount(imxccm_init_parents); n++) {
+ clk = clk_get(&sc->sc_clkdom, imxccm_init_parents[n].clock);
+ KASSERT(clk != NULL);
+ clk_parent = clk_get(&sc->sc_clkdom, imxccm_init_parents[n].parent);
+ KASSERT(clk_parent != NULL);
+
+ int error = clk_set_parent(clk, clk_parent);
+ if (error) {
+ aprint_error_dev(sc->sc_dev,
+ "couldn't set '%s' parent to '%s': %d\n",
+ clk->name, clk_parent->name, error);
+ }
+ clk_put(clk_parent);
+ clk_put(clk);
+ }
}
-static int
-imxccm_sysctl_freq_helper(SYSCTLFN_ARGS)
+static u_int
+imxccm_clk_get_rate_pll_generic(struct imxccm_softc *sc, struct imx6_clk *iclk,
+ const u_int rate_parent)
{
- struct sysctlnode node;
- struct imxccm_softc *sc;
- int value, ovalue, err;
-
- node = *rnode;
- sc = node.sysctl_data;
-
- /* for sysctl read */
- if (rnode->sysctl_num == sc->sc_sysctlnode_pll1_arm)
- value = imx6_get_clock(IMX6CLK_PLL1);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll2_sys)
- value = imx6_get_clock(IMX6CLK_PLL2);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll3_usb1)
- value = imx6_get_clock(IMX6CLK_PLL3);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll7_usb2)
- value = imx6_get_clock(IMX6CLK_PLL7);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll4_audio)
- value = imx6_get_clock(IMX6CLK_PLL4);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll5_video)
- value = imx6_get_clock(IMX6CLK_PLL5);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll6_enet)
- value = imx6_get_clock(IMX6CLK_PLL6);
-#if 0
- else if (rnode->sysctl_num == sc->sc_sysctlnode_pll8_mlb)
- value = imx6_get_clock(IMX6CLK_PLL8);
-#endif
- else if (rnode->sysctl_num == sc->sc_sysctlnode_arm)
- value = imx6_get_clock(IMX6CLK_ARM_ROOT);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_periph)
- value = imx6_get_clock(IMX6CLK_PERIPH);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_ipg)
- value = imx6_get_clock(IMX6CLK_IPG);
- else if (rnode->sysctl_num == sc->sc_sysctlnode_axi)
- value = imx6_get_clock(IMX6CLK_AXI);
- else
- return EOPNOTSUPP;
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
-#ifdef SYSCTL_BY_MHZ
- value /= 1000 * 1000; /* Hz -> MHz */
-#endif
- ovalue = value;
+ KASSERT((pll->type == IMX6_CLK_PLL_GENNERIC) ||
+ (pll->type == IMX6_CLK_PLL_USB));
- node.sysctl_data = &value;
- err = sysctl_lookup(SYSCTLFN_CALL(&node));
- if (err != 0 || newp == NULL)
- return err;
+ uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog, pll->reg);
+ uint32_t div = __SHIFTOUT(v, pll->mask);
- /* for sysctl write */
- if (value == ovalue)
- return 0;
+ return rate_parent * ((div == 1) ? 22 : 20);
+}
-#ifdef SYSCTL_BY_MHZ
- value *= 1000 * 1000; /* MHz -> Hz */
-#endif
+static u_int
+imxccm_clk_get_rate_pll_sys(struct imxccm_softc *sc, struct imx6_clk *iclk,
+ const u_int rate_parent)
+{
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
- if (rnode->sysctl_num == sc->sc_sysctlnode_arm)
- return imx6_set_clock(IMX6CLK_ARM_ROOT, value);
+ KASSERT(pll->type == IMX6_CLK_PLL_SYS);
- return 0;
+ uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog, pll->reg);
+ uint32_t div = __SHIFTOUT(v, pll->mask);
+
+ return rate_parent * div / 2;
}
+#define PLL_AUDIO_VIDEO_NUM_OFFSET 0x10
+#define PLL_AUDIO_VIDEO_DENOM_OFFSET 0x20
-uint32_t
-imx6_ccm_read(uint32_t reg)
+static u_int
+imxccm_clk_get_rate_pll_audio_video(struct imxccm_softc *sc,
+ struct imx6_clk *iclk, const u_int rate_parent)
{
- if (ccm_softc == NULL)
- return 0;
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
+ uint64_t freq;
+
+ KASSERT(pll->type == IMX6_CLK_PLL_AUDIO_VIDEO);
+
+ uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog, pll->reg);
+ uint32_t div = __SHIFTOUT(v, pll->mask);
+ uint32_t num = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog,
+ pll->reg + PLL_AUDIO_VIDEO_NUM_OFFSET);
+ uint32_t denom = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog,
+ pll->reg + PLL_AUDIO_VIDEO_DENOM_OFFSET);
+
+ uint64_t tmp = rate_parent * num / denom;
+ freq = (uint64_t)rate_parent * div + tmp;
- return bus_space_read_4(ccm_softc->sc_iot, ccm_softc->sc_ioh, reg);
+ return freq;
}
-void
-imx6_ccm_write(uint32_t reg, uint32_t val)
+static u_int
+imxccm_clk_get_rate_pll_enet(struct imxccm_softc *sc,
+ struct imx6_clk *iclk, const u_int rate_parent)
{
- if (ccm_softc == NULL)
- return;
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
- bus_space_write_4(ccm_softc->sc_iot, ccm_softc->sc_ioh, reg, val);
-}
+ KASSERT(pll->type == IMX6_CLK_PLL_ENET);
+ return pll->ref;
+}
-uint32_t
-imx6_ccm_analog_read(uint32_t reg)
+static u_int
+imxccm_clk_get_rate_fixed_factor(struct imxccm_softc *sc, struct imx6_clk *iclk)
{
- if (ccm_softc == NULL)
- return 0;
+ struct imx6_clk_fixed_factor *fixed_factor = &iclk->clk.fixed_factor;
+ struct imx6_clk *parent;
- return bus_space_read_4(ccm_softc->sc_iot, ccm_softc->sc_ioh_analog,
- reg);
+ KASSERT(iclk->type == IMX6_CLK_FIXED_FACTOR);
+
+ parent = imx6_clk_find(iclk->parent);
+ KASSERT(parent != NULL);
+
+ const u_int rate_parent = imxccm_clk_get_rate(sc, &parent->base);
+
+ return rate_parent * fixed_factor->mult / fixed_factor->div;
}
-void
-imx6_ccm_analog_write(uint32_t reg, uint32_t val)
+static u_int
+imxccm_clk_get_rate_pll(struct imxccm_softc *sc, struct imx6_clk *iclk)
{
- if (ccm_softc == NULL)
- return;
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
+ struct imx6_clk *parent;
+
+ KASSERT(iclk->type == IMX6_CLK_PLL);
- bus_space_write_4(ccm_softc->sc_iot, ccm_softc->sc_ioh_analog, reg,
- val);
+ parent = imx6_clk_find(iclk->parent);
+ KASSERT(parent != NULL);
+
+ const u_int rate_parent = imxccm_clk_get_rate(sc, &parent->base);
+
+ switch(pll->type) {
+ case IMX6_CLK_PLL_GENNERIC:
+ return imxccm_clk_get_rate_pll_generic(sc, iclk, rate_parent);
+ case IMX6_CLK_PLL_SYS:
+ return imxccm_clk_get_rate_pll_sys(sc, iclk, rate_parent);
+ case IMX6_CLK_PLL_USB:
+ return imxccm_clk_get_rate_pll_generic(sc, iclk, rate_parent);
+ case IMX6_CLK_PLL_AUDIO_VIDEO:
+ return imxccm_clk_get_rate_pll_audio_video(sc, iclk, rate_parent);
+ case IMX6_CLK_PLL_ENET:
+ return imxccm_clk_get_rate_pll_enet(sc, iclk, rate_parent);
+ default:
+ panic("imx6: unknown pll type %d", iclk->type);
+ }
}
-int
-imx6_set_clock(enum imx6_clock_id clk, uint32_t freq)
+static u_int
+imxccm_clk_get_rate_div(struct imxccm_softc *sc, struct imx6_clk *iclk)
{
- uint32_t v;
+ struct imx6_clk_div *div = &iclk->clk.div;
+ struct imx6_clk *parent;
- if (ccm_softc == NULL)
- return 0;
+ KASSERT(iclk->type == IMX6_CLK_DIV);
- switch (clk) {
- case IMX6CLK_ARM_ROOT:
- {
- uint32_t pll;
- int cacrr;
-
- for (cacrr = 7; cacrr >= 0; cacrr--) {
- pll = (uint64_t)freq * (cacrr + 1) * 2 / IMX6_OSC_FREQ;
- if (pll >= 54 && pll <= 108) {
-
- v = imx6_ccm_read(CCM_CACRR);
- v &= ~CCM_CACRR_ARM_PODF;
- imx6_ccm_write(CCM_CACRR,
- v | __SHIFTIN(cacrr, CCM_CACRR_ARM_PODF));
-
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_ARM);
- v &= ~CCM_ANALOG_PLL_ARM_DIV_SELECT;
- imx6_ccm_analog_write(CCM_ANALOG_PLL_ARM,
- v | __SHIFTIN(pll, CCM_ANALOG_PLL_ARM_DIV_SELECT));
+ parent = imx6_clk_find(iclk->parent);
+ KASSERT(parent != NULL);
- v = imx6_get_clock(IMX6CLK_ARM_ROOT);
- cpufreq_set_all(v);
-#ifdef CPU_CORTEXA9
- a9tmr_update_freq(v / IMX6_PERIPHCLK_N);
-#endif
- return 0;
- }
- }
- return EINVAL;
- }
- break;
+ u_int rate = imxccm_clk_get_rate(sc, &parent->base);
- default:
- aprint_error_dev(ccm_softc->sc_dev,
- "clock %d: not supported yet\n", clk);
- return EINVAL;
+ bus_space_handle_t ioh;
+ if (div->base == IMX6_CLK_REG_CCM_ANALOG)
+ ioh = sc->sc_ioh_analog;
+ else
+ ioh = sc->sc_ioh;
+
+ uint32_t v = bus_space_read_4(sc->sc_iot, ioh, div->reg);
+ uint32_t n = __SHIFTOUT(v, div->mask);
+
+ if (div->type == IMX6_CLK_DIV_TABLE) {
+ KASSERT(div->tbl != NULL);
+
+ for (int i = 0; div->tbl[i] != 0; i++)
+ if (div->tbl[i] == n)
+ rate /= div->tbl[i];
+ } else {
+ rate /= n + 1;
}
- return 0;
+ return rate;
}
-uint32_t
-imx6_get_clock(enum imx6_clock_id clk)
+static u_int
+imxccm_clk_get_rate_pfd(struct imxccm_softc *sc, struct imx6_clk *iclk)
{
- uint32_t d, denom, num, sel, v;
- uint64_t freq;
+ struct imx6_clk_pfd *pfd = &iclk->clk.pfd;
+ struct imx6_clk *parent;
- if (ccm_softc == NULL)
- return 0;
+ KASSERT(iclk->type == IMX6_CLK_PFD);
- switch (clk) {
- /* CLOCK SWITCHER */
- case IMX6CLK_PLL1:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_ARM);
- freq = IMX6_OSC_FREQ * (v & CCM_ANALOG_PLL_ARM_DIV_SELECT) / 2;
- break;
- case IMX6CLK_PLL2:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_SYS);
- freq = IMX6_OSC_FREQ * ((v & CCM_ANALOG_PLL_SYS_DIV_SELECT) ? 22 : 20);
- break;
- case IMX6CLK_PLL3:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_USB1);
- freq = IMX6_OSC_FREQ * ((v & CCM_ANALOG_PLL_USB1_DIV_SELECT) ? 22 : 20);
- break;
+ parent = imx6_clk_find(iclk->parent);
+ KASSERT(parent != NULL);
- case IMX6CLK_PLL4:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_AUDIO);
- d = __SHIFTOUT(v, CCM_ANALOG_PLL_AUDIO_DIV_SELECT);
- num = imx6_ccm_analog_read(CCM_ANALOG_PLL_AUDIO_NUM);
- denom = imx6_ccm_analog_read(CCM_ANALOG_PLL_AUDIO_DENOM);
- freq = (uint64_t)IMX6_OSC_FREQ * (d + num / denom);
- d = __SHIFTOUT(v, CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT);
- freq = freq >> (2 - d);
- break;
+ const u_int rate_parent = imxccm_clk_get_rate(sc, &parent->base);
- case IMX6CLK_PLL5:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_VIDEO);
- d = __SHIFTOUT(v, CCM_ANALOG_PLL_VIDEO_DIV_SELECT);
- num = imx6_ccm_analog_read(CCM_ANALOG_PLL_VIDEO_NUM);
- denom = imx6_ccm_analog_read(CCM_ANALOG_PLL_VIDEO_DENOM);
- freq = (uint64_t)IMX6_OSC_FREQ * (d + num / denom);
- d = __SHIFTOUT(v, CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT);
- freq = freq >> (2 - d);
- break;
+ uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh_analog, pfd->reg);
+ uint32_t n = __SHIFTOUT(v, __BITS(5, 0) << (pfd->index * 8));
- case IMX6CLK_PLL6:
- /* XXX: iMX6UL has 2 div. which? */
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_ENET);
- switch (v & CCM_ANALOG_PLL_ENET_DIV_SELECT) {
- case 0:
- freq = 25 * 1000 * 1000;
- break;
- case 1:
- freq = 50 * 1000 * 1000;
- break;
- case 2:
- freq = 100 * 1000 * 1000;
- break;
- case 3:
- freq = 125 * 1000 * 1000;
+ KASSERT(n != 0);
+
+ return (rate_parent * 18) / n;
+}
+
+static int
+imxccm_clk_mux_wait(struct imxccm_softc *sc, struct imx6_clk_mux *mux)
+{
+ KASSERT(mux->busy_reg == 0);
+ KASSERT(mux->busy_mask == 0);
+
+ bus_space_handle_t ioh;
+ if (mux->base == IMX6_CLK_REG_CCM_ANALOG)
+ ioh = sc->sc_ioh_analog;
+ else
+ ioh = sc->sc_ioh;
+
+ while (bus_space_read_4(sc->sc_iot, ioh, mux->busy_reg) & mux->busy_mask)
+ delay(10);
+
+ return 0;
+}
+
+static int
+imxccm_clk_set_parent_mux(struct imxccm_softc *sc,
+ struct imx6_clk *iclk, struct clk *parent)
+{
+ struct imx6_clk_mux *mux = &iclk->clk.mux;
+ const char *pname = parent->name;
+ u_int sel;
+
+ KASSERT(iclk->type == IMX6_CLK_MUX);
+
+ for (sel = 0; sel < mux->nparents; sel++)
+ if (strcmp(pname, mux->parents[sel]) == 0)
break;
- }
- break;
- case IMX6CLK_PLL7:
- v = imx6_ccm_analog_read(CCM_ANALOG_PLL_USB2);
- freq = IMX6_OSC_FREQ * ((v & CCM_ANALOG_PLL_DIV_SELECT) ? 22 : 20);
- break;
-#if 0
- case IMX6CLK_PLL8:
- /* XXX notyet */
- break;
-#endif
+ if (sel == mux->nparents)
+ return EINVAL;
- case IMX6CLK_PLL2_PFD0:
- freq = imx6_get_clock(IMX6CLK_PLL2);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_528);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_528_PFD0_FRAC);
- break;
- case IMX6CLK_PLL2_PFD1:
- freq = imx6_get_clock(IMX6CLK_PLL2);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_528);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_528_PFD1_FRAC);
- break;
- case IMX6CLK_PLL2_PFD2:
- freq = imx6_get_clock(IMX6CLK_PLL2);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_528);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_528_PFD2_FRAC);
- break;
- case IMX6CLK_PLL3_PFD3:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_480);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480_PFD3_FRAC);
- break;
- case IMX6CLK_PLL3_PFD2:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_480);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480_PFD2_FRAC);
- break;
- case IMX6CLK_PLL3_PFD1:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_480);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480_PFD1_FRAC);
- break;
- case IMX6CLK_PLL3_PFD0:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- v = imx6_ccm_analog_read(CCM_ANALOG_PFD_480);
- freq = freq * 18 / __SHIFTOUT(v, CCM_ANALOG_PFD_480_PFD0_FRAC);
- break;
+ bus_space_handle_t ioh;
+ if (mux->base == IMX6_CLK_REG_CCM_ANALOG)
+ ioh = sc->sc_ioh_analog;
+ else
+ ioh = sc->sc_ioh;
- /* CLOCK ROOT GEN */
- case IMX6CLK_ARM_ROOT:
- freq = imx6_get_clock(IMX6CLK_PLL1);
- v = __SHIFTOUT(imx6_ccm_read(CCM_CACRR), CCM_CACRR_ARM_PODF);
- freq = freq / (v + 1);
- break;
+ uint32_t v = bus_space_read_4(sc->sc_iot, ioh, mux->reg);
+ v &= ~mux->mask;
+ v |= __SHIFTIN(sel, mux->mask);
- case IMX6CLK_PERIPH:
- v = imx6_ccm_read(CCM_CBCDR);
- if (v & CCM_CBCDR_PERIPH_CLK_SEL) {
- v = imx6_ccm_read(CCM_CBCMR);
- sel = __SHIFTOUT(v, CCM_CBCMR_PERIPH_CLK2_SEL);
- switch (sel) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- break;
- case 1:
- case 2:
- freq = IMX6_OSC_FREQ;
- break;
- case 3:
- freq = 0;
- aprint_error_dev(ccm_softc->sc_dev,
- "IMX6CLK_PERIPH: CCM_CBCMR:CCM_CBCMR_PERIPH_CLK2_SEL is set reserved value\n");
- break;
- }
- } else {
- v = imx6_ccm_read(CCM_CBCMR);
- sel = __SHIFTOUT(v, CCM_CBCMR_PRE_PERIPH_CLK_SEL);
- switch (sel) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_PLL2);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2) / 2;
- break;
- }
- }
- break;
- case IMX6CLK_AHB:
- freq = imx6_get_clock(IMX6CLK_PERIPH);
- v = imx6_ccm_read(CCM_CBCDR);
- freq = freq / (__SHIFTOUT(v, CCM_CBCDR_AHB_PODF) + 1);
- break;
- case IMX6CLK_IPG:
- freq = imx6_get_clock(IMX6CLK_AHB);
- v = imx6_ccm_read(CCM_CBCDR);
- freq = freq / (__SHIFTOUT(v, CCM_CBCDR_IPG_PODF) + 1);
- break;
- case IMX6CLK_AXI:
- v = imx6_ccm_read(CCM_CBCDR);
- if (v & CCM_CBCDR_AXI_SEL) {
- if (v & CCM_CBCDR_AXI_ALT_SEL) {
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- } else {
- freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
- }
- } else {
- freq = imx6_get_clock(IMX6CLK_PERIPH);
- freq = freq / (__SHIFTOUT(v, CCM_CBCDR_AXI_PODF) + 1);
- }
- break;
+ bus_space_write_4(sc->sc_iot, ioh, mux->reg, v);
- case IMX6CLK_USDHC1:
- v = imx6_ccm_read(CCM_CSCMR1);
- freq = imx6_get_clock((v & CCM_CSCMR1_USDHC1_CLK_SEL) ?
- IMX6CLK_PLL2_PFD0 : IMX6CLK_PLL2_PFD2);
- v = imx6_ccm_read(CCM_CSCDR1);
- freq = freq / (__SHIFTOUT(v, CCM_CSCDR1_USDHC1_PODF) + 1);
- break;
- case IMX6CLK_USDHC2:
- v = imx6_ccm_read(CCM_CSCMR1);
- freq = imx6_get_clock((v & CCM_CSCMR1_USDHC2_CLK_SEL) ?
- IMX6CLK_PLL2_PFD0 : IMX6CLK_PLL2_PFD2);
- v = imx6_ccm_read(CCM_CSCDR1);
- freq = freq / (__SHIFTOUT(v, CCM_CSCDR1_USDHC2_PODF) + 1);
- break;
- case IMX6CLK_USDHC3:
- v = imx6_ccm_read(CCM_CSCMR1);
- freq = imx6_get_clock((v & CCM_CSCMR1_USDHC3_CLK_SEL) ?
- IMX6CLK_PLL2_PFD0 : IMX6CLK_PLL2_PFD2);
- v = imx6_ccm_read(CCM_CSCDR1);
- freq = freq / (__SHIFTOUT(v, CCM_CSCDR1_USDHC3_PODF) + 1);
- break;
- case IMX6CLK_USDHC4:
- v = imx6_ccm_read(CCM_CSCMR1);
- freq = imx6_get_clock((v & CCM_CSCMR1_USDHC4_CLK_SEL) ?
- IMX6CLK_PLL2_PFD0 : IMX6CLK_PLL2_PFD2);
- v = imx6_ccm_read(CCM_CSCDR1);
- freq = freq / (__SHIFTOUT(v, CCM_CSCDR1_USDHC4_PODF) + 1);
- break;
+ iclk->parent = pname;
- case IMX6CLK_PERCLK:
- freq = imx6_get_clock(IMX6CLK_IPG);
- v = imx6_ccm_read(CCM_CSCMR1);
- freq = freq / (__SHIFTOUT(v, CCM_CSCMR1_PERCLK_PODF) + 1);
- break;
+ if (mux->type == IMX6_CLK_MUX_BUSY)
+ imxccm_clk_mux_wait(sc, mux);
- case IMX6CLK_MMDC_CH1_CLK_ROOT:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH1);
- v = __SHIFTOUT(imx6_ccm_read(CCM_CBCDR), CCM_CBCDR_MMDC_CH1_AXI_PODF);
- freq = freq / (v + 1);
- break;
+ return 0;
+}
- case IMX6CLK_MMDC_CH0_CLK_ROOT:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
- v = __SHIFTOUT(imx6_ccm_read(CCM_CBCDR), CCM_CBCDR_MMDC_CH0_AXI_PODF);
- freq = freq / (v + 1);
- break;
+static struct imx6_clk *
+imxccm_clk_get_parent_mux(struct imxccm_softc *sc, struct imx6_clk *iclk)
+{
+ struct imx6_clk_mux *mux = &iclk->clk.mux;
- case IMX6CLK_MMDC_CH0:
- case IMX6CLK_MMDC_CH1:
- v = imx6_ccm_read(CCM_CBCMR);
- sel = (clk == IMX6CLK_MMDC_CH0) ?
- __SHIFTOUT(v, CCM_CBCMR_PRE_PERIPH_CLK_SEL) :
- __SHIFTOUT(v, CCM_CBCMR_PRE_PERIPH2_CLK_SEL);
- switch (sel) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_PLL2);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2) / 2;
- break;
- }
- break;
+ KASSERT(iclk->type == IMX6_CLK_MUX);
- case IMX6CLK_IPU1_HSP_CLK_ROOT:
- v = imx6_ccm_read(CCM_CSCDR3);
- switch (__SHIFTOUT(v, CCM_CSCDR3_IPU1_HSP_CLK_SEL)) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL3) / 4;
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
- break;
- }
- v = __SHIFTOUT(v, CCM_CSCDR3_IPU1_HSP_CLK_SEL);
- freq = freq / (v + 1);
- break;
- case IMX6CLK_IPU2_HSP_CLK_ROOT:
- v = imx6_ccm_read(CCM_CSCDR3);
- switch (__SHIFTOUT(v, CCM_CSCDR3_IPU2_HSP_CLK_SEL)) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL3) / 4;
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
- break;
- }
- v = __SHIFTOUT(v, CCM_CSCDR3_IPU2_HSP_CLK_SEL);
- freq = freq / (v + 1);
- break;
+ bus_space_handle_t ioh;
+ if (mux->base == IMX6_CLK_REG_CCM_ANALOG)
+ ioh = sc->sc_ioh_analog;
+ else
+ ioh = sc->sc_ioh;
- case IMX6CLK_IPU1_DI0_CLK_ROOT:
- case IMX6CLK_IPU1_DI1_CLK_ROOT:
- v = imx6_ccm_read(CCM_CHSCCDR);
- sel = (clk == IMX6CLK_IPU1_DI0_CLK_ROOT) ?
- __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_CLK_SEL) :
- __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_CLK_SEL);
- switch (sel) {
- case 0:
- sel = (clk == IMX6CLK_IPU1_DI0_CLK_ROOT) ?
- __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL) :
- __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL);
- switch (sel) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL5);
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
- break;
- case 4:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 5:
- freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
- break;
- default:
- /* reserved */
- freq = 0;
- }
- if (clk == IMX6CLK_IPU1_DI0_CLK_ROOT)
- freq = freq / (__SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_PODF) + 1);
- else
- freq = freq / (__SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_PODF) + 1);
- break;
- case 1:
- case 2:
- /* IPP_DI[01]_CLK is an external clock */
- freq = 0;
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_LDB_DI0_IPU);
- break;
- case 4:
- freq = imx6_get_clock(IMX6CLK_LDB_DI1_IPU);
- break;
- default:
- /* reserved */
- freq = 0;
- }
- break;
+ uint32_t v = bus_space_read_4(sc->sc_iot, ioh, mux->reg);
+ u_int sel = __SHIFTOUT(v, mux->mask);
- case IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT:
- case IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT:
- v = imx6_ccm_read(CCM_CS2CDR);
- sel = (clk == IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT) ?
- __SHIFTOUT(v, CCM_CS2CDR_LDB_DI0_CLK_SEL) :
- __SHIFTOUT(v, CCM_CS2CDR_LDB_DI1_CLK_SEL);
- switch (sel) {
- case 0:
- freq = imx6_get_clock(IMX6CLK_PLL5);
- break;
- case 1:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
- break;
- case 2:
- freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
- break;
- case 3:
- freq = imx6_get_clock(IMX6CLK_MMDC_CH1);
- break;
- case 4:
- freq = imx6_get_clock(IMX6CLK_PLL3);
- break;
- case 5:
- default:
- /* reserved */
- freq = 0;
- }
- break;
+ KASSERT(sel < mux->nparents);
- case IMX6CLK_LDB_DI0_IPU:
- freq = imx6_get_clock(IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT);
- v = imx6_ccm_read(CCM_CSCMR2);
- if (!ISSET(v, CCM_CSCMR2_LDB_DI0_IPU_DIV))
- freq *= 2;
- freq /= 7;
- break;
- case IMX6CLK_LDB_DI1_IPU:
- freq = imx6_get_clock(IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT);
- v = imx6_ccm_read(CCM_CSCMR2);
- if (!ISSET(v, CCM_CSCMR2_LDB_DI1_IPU_DIV))
- freq *= 2;
- freq /= 7;
- break;
+ iclk->parent = mux->parents[sel];
+
+ return imx6_clk_find(iclk->parent);
+}
+
+static int
+imxccm_clk_set_rate_pll(struct imxccm_softc *sc,
+ struct imx6_clk *eclk, u_int rate)
+{
+ /* ToDo */
+
+ return EOPNOTSUPP;
+}
+
+/*
+ * CLK Driver APIs
+ */
+static struct clk *
+imxccm_clk_get(void *priv, const char *name)
+{
+ struct imx6_clk *iclk;
+
+ iclk = imx6_clk_find(name);
+ if (iclk == NULL)
+ return NULL;
+
+ atomic_inc_uint(&iclk->refcnt);
+
+ return &iclk->base;
+}
+
+static void
+imxccm_clk_put(void *priv, struct clk *clk)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+
+ KASSERT(iclk->refcnt > 0);
+ atomic_dec_uint(&iclk->refcnt);
+}
+
+static u_int
+imxccm_clk_get_rate(void *priv, struct clk *clk)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct clk *parent;
+ struct imxccm_softc *sc = priv;
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ return iclk->clk.fixed.rate;
+ case IMX6_CLK_FIXED_FACTOR:
+ return imxccm_clk_get_rate_fixed_factor(sc, iclk);
+ case IMX6_CLK_PLL:
+ return imxccm_clk_get_rate_pll(sc, iclk);
+ case IMX6_CLK_MUX:
+ case IMX6_CLK_GATE:
+ parent = imxccm_clk_get_parent(sc, clk);
+ return imxccm_clk_get_rate(sc, parent);
+ case IMX6_CLK_DIV:
+ return imxccm_clk_get_rate_div(sc, iclk);
+ case IMX6_CLK_PFD:
+ return imxccm_clk_get_rate_pfd(sc, iclk);
default:
- aprint_error_dev(ccm_softc->sc_dev,
- "clock %d: not supported yet\n", clk);
- return 0;
+ panic("imx6: unknown clk type %d", iclk->type);
}
+}
- return freq;
+static int
+imxccm_clk_set_rate(void *priv, struct clk *clk, u_int rate)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct imxccm_softc *sc = priv;
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ case IMX6_CLK_FIXED_FACTOR:
+ return EIO;
+ case IMX6_CLK_PLL:
+ return imxccm_clk_set_rate_pll(sc, iclk, rate);
+ case IMX6_CLK_MUX:
+ return EIO;
+ case IMX6_CLK_GATE:
+ case IMX6_CLK_DIV:
+ case IMX6_CLK_PFD:
+ return EINVAL;
+ default:
+ panic("imx6: unknown clk type %d", iclk->type);
+ }
}
-int
-imx6_pll_power(uint32_t pllreg, int on, uint32_t en)
+static int
+imxccm_clk_enable_pll(struct imxccm_softc *sc, struct imx6_clk *iclk, bool enable)
{
- uint32_t v;
- int timeout;
+ struct imx6_clk_pll *pll = &iclk->clk.pll;
- switch (pllreg) {
- case CCM_ANALOG_PLL_USB1:
- case CCM_ANALOG_PLL_USB2:
- v = imx6_ccm_analog_read(pllreg);
- if (on) {
- v |= en;
- v &= ~CCM_ANALOG_PLL_BYPASS;
- } else {
- v &= ~en;
- }
- imx6_ccm_analog_write(pllreg, v);
+ KASSERT(iclk->type == IMX6_CLK_PLL);
+
+ /* Power up bit */
+ if (pll->type == IMX6_CLK_PLL_USB)
+ enable = !enable;
+
+ bus_space_handle_t ioh = sc->sc_ioh_analog;
+ uint32_t v = bus_space_read_4(sc->sc_iot, ioh, pll->reg);
+ if (__SHIFTOUT(v, pll->powerdown) != enable)
return 0;
+ if (enable)
+ v &= ~pll->powerdown;
+ else
+ v |= pll->powerdown;
+ bus_space_write_4(sc->sc_iot, ioh, pll->reg, v);
- case CCM_ANALOG_PLL_ENET:
- v = imx6_ccm_analog_read(pllreg);
- if (on)
- v &= ~CCM_ANALOG_PLL_ENET_POWERDOWN;
- else
- v |= CCM_ANALOG_PLL_ENET_POWERDOWN;
- imx6_ccm_analog_write(pllreg, v);
-
- for (timeout = 100000; timeout > 0; timeout--) {
- if (imx6_ccm_analog_read(pllreg) &
- CCM_ANALOG_PLL_ENET_LOCK)
- break;
- }
- if (timeout <= 0)
- break;
+ /* wait look */
+ while (!(bus_space_read_4(sc->sc_iot, ioh, pll->reg) & CCM_ANALOG_PLL_LOCK))
+ delay(10);
- v |= CCM_ANALOG_PLL_ENET_ENABLE;
- if (on) {
- v &= ~CCM_ANALOG_PLL_ENET_BYPASS;
- imx6_ccm_analog_write(pllreg, v);
- v |= en;
- } else {
- v &= ~en;
- }
- imx6_ccm_analog_write(pllreg, v);
+ return 0;
+}
+
+static int
+imxccm_clk_enable_gate(struct imxccm_softc *sc, struct imx6_clk *iclk, bool enable)
+{
+ struct imx6_clk_gate *gate = &iclk->clk.gate;
+
+ KASSERT(iclk->type == IMX6_CLK_GATE);
+
+ bus_space_handle_t ioh;
+ if (gate->base == IMX6_CLK_REG_CCM_ANALOG)
+ ioh = sc->sc_ioh_analog;
+ else
+ ioh = sc->sc_ioh;
+
+ uint32_t v = bus_space_read_4(sc->sc_iot, ioh, gate->reg);
+ if (enable) {
+ if (gate->exclusive_mask)
+ v &= ~gate->exclusive_mask;
+ v |= gate->mask;
+ } else {
+ if (gate->exclusive_mask)
+ v |= gate->exclusive_mask;
+ v &= ~gate->mask;
+ }
+ bus_space_write_4(sc->sc_iot, ioh, gate->reg, v);
+
+ return 0;
+}
+
+static int
+imxccm_clk_enable(void *priv, struct clk *clk)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct imx6_clk *parent = NULL;
+ struct imxccm_softc *sc = priv;
+
+ if ((parent = imx6_clk_find(iclk->parent)) != NULL)
+ imxccm_clk_enable(sc, &parent->base);
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ case IMX6_CLK_FIXED_FACTOR:
+ return 0; /* always on */
+ case IMX6_CLK_PLL:
+ return imxccm_clk_enable_pll(sc, iclk, true);
+ case IMX6_CLK_MUX:
+ case IMX6_CLK_DIV:
+ case IMX6_CLK_PFD:
return 0;
+ case IMX6_CLK_GATE:
+ return imxccm_clk_enable_gate(sc, iclk, true);
+ default:
+ panic("imx6: unknown clk type %d", iclk->type);
+ }
+}
- case CCM_ANALOG_PLL_ARM:
- case CCM_ANALOG_PLL_SYS:
- case CCM_ANALOG_PLL_AUDIO:
- case CCM_ANALOG_PLL_VIDEO:
- case CCM_ANALOG_PLL_MLB:
- /* notyet */
+static int
+imxccm_clk_disable(void *priv, struct clk *clk)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct imxccm_softc *sc = priv;
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ case IMX6_CLK_FIXED_FACTOR:
+ return EINVAL; /* always on */
+ case IMX6_CLK_PLL:
+ return imxccm_clk_enable_pll(sc, iclk, false);
+ case IMX6_CLK_MUX:
+ case IMX6_CLK_DIV:
+ case IMX6_CLK_PFD:
+ return EINVAL;
+ case IMX6_CLK_GATE:
+ return imxccm_clk_enable_gate(sc, iclk, false);
default:
+ panic("imx6: unknown clk type %d", iclk->type);
+ }
+}
+
+static int
+imxccm_clk_set_parent(void *priv, struct clk *clk, struct clk *parent)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct imxccm_softc *sc = priv;
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ case IMX6_CLK_FIXED_FACTOR:
+ case IMX6_CLK_PLL:
+ case IMX6_CLK_GATE:
+ case IMX6_CLK_DIV:
+ case IMX6_CLK_PFD:
+ return EINVAL;
+ case IMX6_CLK_MUX:
+ return imxccm_clk_set_parent_mux(sc, iclk, parent);
+ default:
+ panic("imx6: unknown clk type %d", iclk->type);
+ }
+}
+
+static struct clk *
+imxccm_clk_get_parent(void *priv, struct clk *clk)
+{
+ struct imx6_clk *iclk = (struct imx6_clk *)clk;
+ struct imx6_clk *parent = NULL;
+ struct imxccm_softc *sc = priv;
+
+ switch (iclk->type) {
+ case IMX6_CLK_FIXED:
+ case IMX6_CLK_FIXED_FACTOR:
+ case IMX6_CLK_PLL:
+ case IMX6_CLK_GATE:
+ case IMX6_CLK_DIV:
+ case IMX6_CLK_PFD:
+ if (iclk->parent != NULL)
+ parent = imx6_clk_find(iclk->parent);
break;
+ case IMX6_CLK_MUX:
+ parent = imxccm_clk_get_parent_mux(sc, iclk);
+ break;
+ default:
+ panic("imx6: unknown clk type %d", iclk->type);
}
- return -1;
+ return (struct clk *)parent;
}
Index: src/sys/arch/arm/imx/imx6_ccmreg.h
diff -u src/sys/arch/arm/imx/imx6_ccmreg.h:1.9 src/sys/arch/arm/imx/imx6_ccmreg.h:1.10
--- src/sys/arch/arm/imx/imx6_ccmreg.h:1.9 Sun Sep 16 09:25:46 2018
+++ src/sys/arch/arm/imx/imx6_ccmreg.h Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ccmreg.h,v 1.9 2018/09/16 09:25:46 skrll Exp $ */
+/* $NetBSD: imx6_ccmreg.h,v 1.10 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -41,11 +41,20 @@
#define IMX6_PERIPHCLK_N 2
#endif
+#ifndef IMX6_CKIL_FREQ
+#define IMX6_CKIL_FREQ 32768
+#endif
+#ifndef IMX6_CKIH_FREQ
+#define IMX6_CKIH_FREQ 0
+#endif
#ifndef IMX6_OSC_FREQ
#define IMX6_OSC_FREQ (24 * 1000 * 1000) /* 24MHz */
#endif
-#ifndef IMX6_CKIL_FREQ
-#define IMX6_CKIL_FREQ 32768
+#ifndef IMX6_ANACLK1_FREQ
+#define IMX6_ANACLK1_FREQ 0
+#endif
+#ifndef IMX6_ANACLK2_FREQ
+#define IMX6_ANACLK2_FREQ 0
#endif
#define CCM_CCR 0x00000000
@@ -321,6 +330,7 @@
#define CCM_ANALOG_PLL_USB1_CLR 0x00000018
#define CCM_ANALOG_PLL_USB1_TOG 0x0000001c
#define CCM_ANALOG_PLL_USB1_LOCK __BIT(31)
+#define CCM_ANALOG_PLL_USB1_RESERVED __BIT(20)
#define CCM_ANALOG_PLL_USB1_BYPASS __BIT(16)
#define CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC __BITS(15, 14)
#define CCM_ANALOG_PLL_USB1_ENABLE __BIT(13)
@@ -333,6 +343,7 @@
#define CCM_ANALOG_PLL_USB2_CLR 0x00000028
#define CCM_ANALOG_PLL_USB2_TOG 0x0000002c
#define CCM_ANALOG_PLL_USB2_LOCK __BIT(31)
+#define CCM_ANALOG_PLL_USB2_RESERVED __BIT(20)
#define CCM_ANALOG_PLL_USB2_BYPASS __BIT(16)
#define CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC __BITS(15, 14)
#define CCM_ANALOG_PLL_USB2_ENABLE __BIT(13)
@@ -436,6 +447,7 @@
#define CCM_ANALOG_MISC1_LVDS_CLK1_SRC __BITS(4, 0)
#define CCM_ANALOG_MISC1_LVDS_CLK1_SRC_PCIE __SHIFTIN(0xa, CCM_ANALOG_MISC1_LVDS_CLK1_SRC)
#define CCM_ANALOG_MISC1_LVDS_CLK1_SRC_SATA __SHIFTIN(0xb, CCM_ANALOG_MISC1_LVDS_CLK1_SRC)
+#define CCM_ANALOG_MISC1_LVDS_CLK2_SRC __BITS(9, 5)
#define CCM_ANALOG_MISC1_LVDS_CLK1_OBEN __BIT(10)
#define CCM_ANALOG_MISC1_LVDS_CLK2_OBEN __BIT(11)
#define CCM_ANALOG_MISC1_LVDS_CLK1_IBEN __BIT(12)
Index: src/sys/arch/arm/imx/imx6_ccmvar.h
diff -u src/sys/arch/arm/imx/imx6_ccmvar.h:1.5 src/sys/arch/arm/imx/imx6_ccmvar.h:1.6
--- src/sys/arch/arm/imx/imx6_ccmvar.h:1.5 Thu Nov 9 05:57:23 2017
+++ src/sys/arch/arm/imx/imx6_ccmvar.h Thu Jun 20 08:16:19 2019
@@ -1,6 +1,6 @@
-/* $NetBSD: imx6_ccmvar.h,v 1.5 2017/11/09 05:57:23 hkenken Exp $ */
+/* $NetBSD: imx6_ccmvar.h,v 1.6 2019/06/20 08:16:19 hkenken Exp $ */
/*
- * Copyright (c) 2012 Genetec Corporation. All rights reserved.
+ * Copyright (c) 2012,2019 Genetec Corporation. All rights reserved.
* Written by Hashimoto Kenichi for Genetec Corporation.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,58 +28,530 @@
#ifndef _ARM_IMX_IMX6_CCMVAR_H_
#define _ARM_IMX_IMX6_CCMVAR_H_
-enum imx6_clock_id {
- IMX6CLK_PLL1, /* = PLL_ARM */
- IMX6CLK_PLL2, /* = PLL_SYS = 528_PLL (24MHz * 22) */
- IMX6CLK_PLL3, /* = PLL_USB1 = 480_PLL1 */
- /* (USB/OTG PHY, 480PFD0-480PFD3, 24MHz*20) */
- IMX6CLK_PLL4, /* = PLL_AUDIO */
- IMX6CLK_PLL5, /* = PLL_VIDEO */
- IMX6CLK_PLL6, /* = PLL_ENET (20MHz = 24MHz * 5/6) */
- IMX6CLK_PLL7, /* = PLL_USB2 (USB2 PHY, HOST PHY, 24MHz*20) */
- IMX6CLK_PLL8, /* = PLL_MLB (Media Link Bus) */
- IMX6CLK_PLL2_PFD0,
- IMX6CLK_PLL2_PFD1,
- IMX6CLK_PLL2_PFD2,
- IMX6CLK_PLL3_PFD0,
- IMX6CLK_PLL3_PFD1,
- IMX6CLK_PLL3_PFD2,
- IMX6CLK_PLL3_PFD3,
-
- IMX6CLK_ARM_ROOT, /* CPU clock of ARM core */
- IMX6CLK_PERIPH,
- IMX6CLK_AHB,
- IMX6CLK_IPG,
- IMX6CLK_AXI,
- IMX6CLK_MMDC_CH0,
- IMX6CLK_MMDC_CH1,
- IMX6CLK_MMDC_CH0_CLK_ROOT,
- IMX6CLK_MMDC_CH1_CLK_ROOT,
-
- IMX6CLK_USDHC1,
- IMX6CLK_USDHC2,
- IMX6CLK_USDHC3,
- IMX6CLK_USDHC4,
-
- IMX6CLK_PERCLK,
-
- IMX6CLK_IPU1_HSP_CLK_ROOT,
- IMX6CLK_IPU2_HSP_CLK_ROOT,
- IMX6CLK_IPU1_DI0_CLK_ROOT,
- IMX6CLK_IPU1_DI1_CLK_ROOT,
- IMX6CLK_LDB_DI0_IPU,
- IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT,
- IMX6CLK_LDB_DI1_IPU,
- IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT,
-};
-
-uint32_t imx6_get_clock(enum imx6_clock_id);
-int imx6_set_clock(enum imx6_clock_id, uint32_t);
-int imx6_pll_power(uint32_t, int, uint32_t);
-
-uint32_t imx6_ccm_read(uint32_t);
-void imx6_ccm_write(uint32_t, uint32_t);
-uint32_t imx6_ccm_analog_read(uint32_t);
-void imx6_ccm_analog_write(uint32_t, uint32_t);
+#include <dev/clk/clk.h>
+#include <dev/clk/clk_backend.h>
+
+struct clk *imx6_get_clock(const char *name);
+
+/* Clock IDs */
+#define IMX6CLK_DUMMY 0
+#define IMX6CLK_CKIL 1
+#define IMX6CLK_CKIH 2
+#define IMX6CLK_OSC 3
+#define IMX6CLK_PLL2_PFD0_352M 4
+#define IMX6CLK_PLL2_PFD1_594M 5
+#define IMX6CLK_PLL2_PFD2_396M 6
+#define IMX6CLK_PLL3_PFD0_720M 7
+#define IMX6CLK_PLL3_PFD1_540M 8
+#define IMX6CLK_PLL3_PFD2_508M 9
+#define IMX6CLK_PLL3_PFD3_454M 10
+#define IMX6CLK_PLL2_198M 11
+#define IMX6CLK_PLL3_120M 12
+#define IMX6CLK_PLL3_80M 13
+#define IMX6CLK_PLL3_60M 14
+#define IMX6CLK_TWD 15
+#define IMX6CLK_STEP 16
+#define IMX6CLK_PLL1_SW 17
+#define IMX6CLK_PERIPH_PRE 18
+#define IMX6CLK_PERIPH2_PRE 19
+#define IMX6CLK_PERIPH_CLK2_SEL 20
+#define IMX6CLK_PERIPH2_CLK2_SEL 21
+#define IMX6CLK_AXI_SEL 22
+#define IMX6CLK_ESAI_SEL 23
+#define IMX6CLK_ASRC_SEL 24
+#define IMX6CLK_SPDIF_SEL 25
+#define IMX6CLK_GPU2D_AXI 26
+#define IMX6CLK_GPU3D_AXI 27
+#define IMX6CLK_GPU2D_CORE_SEL 28
+#define IMX6CLK_GPU3D_CORE_SEL 29
+#define IMX6CLK_GPU3D_SHADER_SEL 30
+#define IMX6CLK_IPU1_SEL 31
+#define IMX6CLK_IPU2_SEL 32
+#define IMX6CLK_LDB_DI0_SEL 33
+#define IMX6CLK_LDB_DI1_SEL 34
+#define IMX6CLK_IPU1_DI0_PRE_SEL 35
+#define IMX6CLK_IPU1_DI1_PRE_SEL 36
+#define IMX6CLK_IPU2_DI0_PRE_SEL 37
+#define IMX6CLK_IPU2_DI1_PRE_SEL 38
+#define IMX6CLK_IPU1_DI0_SEL 39
+#define IMX6CLK_IPU1_DI1_SEL 40
+#define IMX6CLK_IPU2_DI0_SEL 41
+#define IMX6CLK_IPU2_DI1_SEL 42
+#define IMX6CLK_HSI_TX_SEL 43
+#define IMX6CLK_PCIE_AXI_SEL 44
+#define IMX6CLK_SSI1_SEL 45
+#define IMX6CLK_SSI2_SEL 46
+#define IMX6CLK_SSI3_SEL 47
+#define IMX6CLK_USDHC1_SEL 48
+#define IMX6CLK_USDHC2_SEL 49
+#define IMX6CLK_USDHC3_SEL 50
+#define IMX6CLK_USDHC4_SEL 51
+#define IMX6CLK_ENFC_SEL 52
+#define IMX6CLK_EIM_SEL 53
+#define IMX6CLK_EIM_SLOW_SEL 54
+#define IMX6CLK_VDO_AXI_SEL 55
+#define IMX6CLK_VPU_AXI_SEL 56
+#define IMX6CLK_CKO1_SEL 57
+#define IMX6CLK_PERIPH 58
+#define IMX6CLK_PERIPH2 59
+#define IMX6CLK_PERIPH_CLK2 60
+#define IMX6CLK_PERIPH2_CLK2 61
+#define IMX6CLK_IPG 62
+#define IMX6CLK_IPG_PER 63
+#define IMX6CLK_ESAI_PRED 64
+#define IMX6CLK_ESAI_PODF 65
+#define IMX6CLK_ASRC_PRED 66
+#define IMX6CLK_ASRC_PODF 67
+#define IMX6CLK_SPDIF_PRED 68
+#define IMX6CLK_SPDIF_PODF 69
+#define IMX6CLK_CAN_ROOT 70
+#define IMX6CLK_ECSPI_ROOT 71
+#define IMX6CLK_GPU2D_CORE_PODF 72
+#define IMX6CLK_GPU3D_CORE_PODF 73
+#define IMX6CLK_GPU3D_SHADER 74
+#define IMX6CLK_IPU1_PODF 75
+#define IMX6CLK_IPU2_PODF 76
+#define IMX6CLK_LDB_DI0_PODF 77
+#define IMX6CLK_LDB_DI1_PODF 78
+#define IMX6CLK_IPU1_DI0_PRE 79
+#define IMX6CLK_IPU1_DI1_PRE 80
+#define IMX6CLK_IPU2_DI0_PRE 81
+#define IMX6CLK_IPU2_DI1_PRE 82
+#define IMX6CLK_HSI_TX_PODF 83
+#define IMX6CLK_SSI1_PRED 84
+#define IMX6CLK_SSI1_PODF 85
+#define IMX6CLK_SSI2_PRED 86
+#define IMX6CLK_SSI2_PODF 87
+#define IMX6CLK_SSI3_PRED 88
+#define IMX6CLK_SSI3_PODF 89
+#define IMX6CLK_UART_SERIAL_PODF 90
+#define IMX6CLK_USDHC1_PODF 91
+#define IMX6CLK_USDHC2_PODF 92
+#define IMX6CLK_USDHC3_PODF 93
+#define IMX6CLK_USDHC4_PODF 94
+#define IMX6CLK_ENFC_PRED 95
+#define IMX6CLK_ENFC_PODF 96
+#define IMX6CLK_EIM_PODF 97
+#define IMX6CLK_EIM_SLOW_PODF 98
+#define IMX6CLK_VPU_AXI_PODF 99
+#define IMX6CLK_CKO1_PODF 100
+#define IMX6CLK_AXI 101
+#define IMX6CLK_MMDC_CH0_AXI_PODF 102
+#define IMX6CLK_MMDC_CH1_AXI_PODF 103
+#define IMX6CLK_ARM 104
+#define IMX6CLK_AHB 105
+#define IMX6CLK_APBH_DMA 106
+#define IMX6CLK_ASRC 107
+#define IMX6CLK_CAN1_IPG 108
+#define IMX6CLK_CAN1_SERIAL 109
+#define IMX6CLK_CAN2_IPG 110
+#define IMX6CLK_CAN2_SERIAL 111
+#define IMX6CLK_ECSPI1 112
+#define IMX6CLK_ECSPI2 113
+#define IMX6CLK_ECSPI3 114
+#define IMX6CLK_ECSPI4 115
+#define IMX6CLK_ECSPI5 116 /* i.MX6Q */
+#define IMX6CLK_I2C4 116 /* i.MX6DL */
+#define IMX6CLK_ENET 117
+#define IMX6CLK_ESAI_EXTAL 118
+#define IMX6CLK_GPT_IPG 119
+#define IMX6CLK_GPT_IPG_PER 120
+#define IMX6CLK_GPU2D_CORE 121
+#define IMX6CLK_GPU3D_CORE 122
+#define IMX6CLK_HDMI_IAHB 123
+#define IMX6CLK_HDMI_ISFR 124
+#define IMX6CLK_I2C1 125
+#define IMX6CLK_I2C2 126
+#define IMX6CLK_I2C3 127
+#define IMX6CLK_IIM 128
+#define IMX6CLK_ENFC 129
+#define IMX6CLK_IPU1 130
+#define IMX6CLK_IPU1_DI0 131
+#define IMX6CLK_IPU1_DI1 132
+#define IMX6CLK_IPU2 133
+#define IMX6CLK_IPU2_DI0 134
+#define IMX6CLK_LDB_DI0 135
+#define IMX6CLK_LDB_DI1 136
+#define IMX6CLK_IPU2_DI1 137
+#define IMX6CLK_HSI_TX 138
+#define IMX6CLK_MLB 139
+#define IMX6CLK_MMDC_CH0_AXI 140
+#define IMX6CLK_MMDC_CH1_AXI 141
+#define IMX6CLK_OCRAM 142
+#define IMX6CLK_OPENVG_AXI 143
+#define IMX6CLK_PCIE_AXI 144
+#define IMX6CLK_PWM1 145
+#define IMX6CLK_PWM2 146
+#define IMX6CLK_PWM3 147
+#define IMX6CLK_PWM4 148
+#define IMX6CLK_PER1_BCH 149
+#define IMX6CLK_GPMI_BCH_APB 150
+#define IMX6CLK_GPMI_BCH 151
+#define IMX6CLK_GPMI_IO 152
+#define IMX6CLK_GPMI_APB 153
+#define IMX6CLK_SATA 154
+#define IMX6CLK_SDMA 155
+#define IMX6CLK_SPBA 156
+#define IMX6CLK_SSI1 157
+#define IMX6CLK_SSI2 158
+#define IMX6CLK_SSI3 159
+#define IMX6CLK_UART_IPG 160
+#define IMX6CLK_UART_SERIAL 161
+#define IMX6CLK_USBOH3 162
+#define IMX6CLK_USDHC1 163
+#define IMX6CLK_USDHC2 164
+#define IMX6CLK_USDHC3 165
+#define IMX6CLK_USDHC4 166
+#define IMX6CLK_VDO_AXI 167
+#define IMX6CLK_VPU_AXI 168
+#define IMX6CLK_CKO1 169
+#define IMX6CLK_PLL1_SYS 170
+#define IMX6CLK_PLL2_BUS 171
+#define IMX6CLK_PLL3_USB_OTG 172
+#define IMX6CLK_PLL4_AUDIO 173
+#define IMX6CLK_PLL5_VIDEO 174
+#define IMX6CLK_PLL8_MLB 175
+#define IMX6CLK_PLL7_USB_HOST 176
+#define IMX6CLK_PLL6_ENET 177
+#define IMX6CLK_SSI1_IPG 178
+#define IMX6CLK_SSI2_IPG 179
+#define IMX6CLK_SSI3_IPG 180
+#define IMX6CLK_ROM 181
+#define IMX6CLK_USBPHY1 182
+#define IMX6CLK_USBPHY2 183
+#define IMX6CLK_LDB_DI0_DIV_3_5 184
+#define IMX6CLK_LDB_DI1_DIV_3_5 185
+#define IMX6CLK_SATA_REF 186
+#define IMX6CLK_SATA_REF_100M 187
+#define IMX6CLK_PCIE_REF 188
+#define IMX6CLK_PCIE_REF_125M 189
+#define IMX6CLK_ENET_REF 190
+#define IMX6CLK_USBPHY1_GATE 191
+#define IMX6CLK_USBPHY2_GATE 192
+#define IMX6CLK_PLL4_POST_DIV 193
+#define IMX6CLK_PLL5_POST_DIV 194
+#define IMX6CLK_PLL5_VIDEO_DIV 195
+#define IMX6CLK_EIM_SLOW 196
+#define IMX6CLK_SPDIF 197
+#define IMX6CLK_CKO2_SEL 198
+#define IMX6CLK_CKO2_PODF 199
+#define IMX6CLK_CKO2 200
+#define IMX6CLK_CKO 201
+#define IMX6CLK_VDOA 202
+#define IMX6CLK_PLL4_AUDIO_DIV 203
+#define IMX6CLK_LVDS1_SEL 204
+#define IMX6CLK_LVDS2_SEL 205
+#define IMX6CLK_LVDS1_GATE 206
+#define IMX6CLK_LVDS2_GATE 207
+#define IMX6CLK_ESAI_IPG 208
+#define IMX6CLK_ESAI_MEM 209
+#define IMX6CLK_ASRC_IPG 210
+#define IMX6CLK_ASRC_MEM 211
+#define IMX6CLK_LVDS1_IN 212
+#define IMX6CLK_LVDS2_IN 213
+#define IMX6CLK_ANACLK1 214
+#define IMX6CLK_ANACLK2 215
+#define IMX6CLK_PLL1_BYPASS_SRC 216
+#define IMX6CLK_PLL2_BYPASS_SRC 217
+#define IMX6CLK_PLL3_BYPASS_SRC 218
+#define IMX6CLK_PLL4_BYPASS_SRC 219
+#define IMX6CLK_PLL5_BYPASS_SRC 220
+#define IMX6CLK_PLL6_BYPASS_SRC 221
+#define IMX6CLK_PLL7_BYPASS_SRC 222
+#define IMX6CLK_PLL1 223
+#define IMX6CLK_PLL2 224
+#define IMX6CLK_PLL3 225
+#define IMX6CLK_PLL4 226
+#define IMX6CLK_PLL5 227
+#define IMX6CLK_PLL6 228
+#define IMX6CLK_PLL7 229
+#define IMX6CLK_PLL1_BYPASS 230
+#define IMX6CLK_PLL2_BYPASS 231
+#define IMX6CLK_PLL3_BYPASS 232
+#define IMX6CLK_PLL4_BYPASS 233
+#define IMX6CLK_PLL5_BYPASS 234
+#define IMX6CLK_PLL6_BYPASS 235
+#define IMX6CLK_PLL7_BYPASS 236
+#define IMX6CLK_GPT_3M 237
+#define IMX6CLK_VIDEO_27M 238
+#define IMX6CLK_MIPI_CORE_CFG 239
+#define IMX6CLK_MIPI_IPG 240
+#define IMX6CLK_CAAM_MEM 241
+#define IMX6CLK_CAAM_ACLK 242
+#define IMX6CLK_CAAM_IPG 243
+#define IMX6CLK_SPDIF_GCLK 244
+#define IMX6CLK_UART_SEL 245
+#define IMX6CLK_IPG_PER_SEL 246
+#define IMX6CLK_ECSPI_SEL 247
+#define IMX6CLK_CAN_SEL 248
+#define IMX6CLK_MMDC_CH1_AXI_CG 249
+#define IMX6CLK_PRE0 250
+#define IMX6CLK_PRE1 251
+#define IMX6CLK_PRE2 252
+#define IMX6CLK_PRE3 253
+#define IMX6CLK_PRG0_AXI 254
+#define IMX6CLK_PRG1_AXI 255
+#define IMX6CLK_PRG0_APB 256
+#define IMX6CLK_PRG1_APB 257
+#define IMX6CLK_PRE_AXI 258
+#define IMX6CLK_MLB_SEL 259
+#define IMX6CLK_MLB_PODF 260
+#define IMX6CLK_END 261
+
+enum imx6_clk_type {
+ IMX6_CLK_FIXED,
+ IMX6_CLK_FIXED_FACTOR,
+ IMX6_CLK_PLL,
+ IMX6_CLK_MUX,
+ IMX6_CLK_GATE,
+ IMX6_CLK_PFD,
+ IMX6_CLK_DIV,
+};
+
+enum imx6_clk_reg {
+ IMX6_CLK_REG_CCM,
+ IMX6_CLK_REG_CCM_ANALOG,
+};
+
+enum imx6_clk_pll_type {
+ IMX6_CLK_PLL_GENNERIC,
+ IMX6_CLK_PLL_SYS,
+ IMX6_CLK_PLL_USB,
+ IMX6_CLK_PLL_AUDIO_VIDEO,
+ IMX6_CLK_PLL_ENET,
+};
+
+enum imx6_clk_div_type {
+ IMX6_CLK_DIV_NORMAL,
+ IMX6_CLK_DIV_BUSY,
+ IMX6_CLK_DIV_TABLE,
+};
+
+enum imx6_clk_mux_type {
+ IMX6_CLK_MUX_NORMAL,
+ IMX6_CLK_MUX_BUSY,
+};
+
+struct imx6_clk_fixed {
+ u_int rate;
+};
+
+struct imx6_clk_fixed_factor {
+ u_int div;
+ u_int mult;
+};
+
+struct imx6_clk_pfd {
+ uint32_t reg;
+ int index;
+};
+
+struct imx6_clk_pll {
+ enum imx6_clk_pll_type type;
+ uint32_t reg;
+ uint32_t mask;
+ uint32_t powerdown;
+ unsigned long ref;
+};
+
+struct imx6_clk_div {
+ enum imx6_clk_div_type type;
+ enum imx6_clk_reg base;
+ uint32_t reg;
+ uint32_t mask;
+ uint32_t busy_reg;
+ uint32_t busy_mask;
+ const int *tbl;
+};
+
+struct imx6_clk_mux {
+ enum imx6_clk_mux_type type;
+ enum imx6_clk_reg base;
+ uint32_t reg;
+ uint32_t mask;
+ const char **parents;
+ u_int nparents;
+ uint32_t busy_reg;
+ uint32_t busy_mask;
+};
+
+struct imx6_clk_gate {
+ enum imx6_clk_reg base;
+ uint32_t reg;
+ uint32_t mask;
+ uint32_t exclusive_mask;
+};
+
+struct imx6_clk {
+ struct clk base; /* must be first */
+
+ const char *parent;
+ u_int refcnt;
+
+ enum imx6_clk_type type;
+ union {
+ struct imx6_clk_fixed fixed;
+ struct imx6_clk_fixed_factor fixed_factor;
+ struct imx6_clk_pfd pfd;
+ struct imx6_clk_pll pll;
+ struct imx6_clk_div div;
+ struct imx6_clk_mux mux;
+ struct imx6_clk_gate gate;
+ } clk;
+};
+
+#define CLK_FIXED(_name, _rate) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_FIXED, \
+ .clk = { \
+ .fixed = { \
+ .rate = (_rate), \
+ } \
+ } \
+}
+
+#define CLK_FIXED_FACTOR(_name, _parent, _div, _mult) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_FIXED_FACTOR, \
+ .parent = (_parent), \
+ .clk = { \
+ .fixed_factor = { \
+ .div = (_div), \
+ .mult = (_mult), \
+ } \
+ } \
+}
+
+#define CLK_PFD(_name, _parent, _reg, _index) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_PFD, \
+ .parent = (_parent), \
+ .clk = { \
+ .pfd = { \
+ .reg = (CCM_ANALOG_##_reg), \
+ .index = (_index), \
+ } \
+ } \
+}
+
+#define CLK_PLL(_name, _parent, _type, _reg, _mask, _powerdown, _ref) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_PLL, \
+ .parent = (_parent), \
+ .clk = { \
+ .pll = { \
+ .type = (IMX6_CLK_PLL_##_type), \
+ .reg = (CCM_ANALOG_##_reg), \
+ .mask = (CCM_ANALOG_##_reg##_##_mask), \
+ .powerdown = (CCM_ANALOG_##_reg##_##_powerdown), \
+ .ref = (_ref), \
+ } \
+ } \
+}
+
+#define CLK_DIV(_name, _parent, _reg, _mask) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_DIV, \
+ .parent = (_parent), \
+ .clk = { \
+ .div = { \
+ .type = (IMX6_CLK_DIV_NORMAL), \
+ .base = (IMX6_CLK_REG_CCM), \
+ .reg = (CCM_##_reg), \
+ .mask = (CCM_##_reg##_##_mask), \
+ } \
+ } \
+}
+
+#define CLK_DIV_BUSY(_name, _parent, _reg, _mask, _busy_reg, _busy_mask) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_DIV, \
+ .parent = (_parent), \
+ .clk = { \
+ .div = { \
+ .type = (IMX6_CLK_DIV_BUSY), \
+ .base = (IMX6_CLK_REG_CCM), \
+ .reg = (CCM_##_reg), \
+ .mask = (CCM_##_reg##_##_mask), \
+ .busy_reg = (CCM_##_busy_reg), \
+ .busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
+ } \
+ } \
+}
+
+#define CLK_DIV_TABLE(_name, _parent, _reg, _mask, _tbl) { \
+ .base = { .name = (_name) }, \
+ .type = IMX6_CLK_DIV, \
+ .parent = (_parent), \
+ .clk = { \
+ .div = { \
+ .type = (IMX6_CLK_DIV_TABLE), \
+ .base = (IMX6_CLK_REG_CCM_ANALOG), \
+ .reg = (CCM_ANALOG_##_reg), \
+ .mask = (CCM_ANALOG_##_reg##_##_mask), \
+ .tbl = (_tbl) \
+ } \
+ } \
+}
+
+#define CLK_MUX(_name, _parents, _base, _reg, _mask) { \
+ .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
+ .type = IMX6_CLK_MUX, \
+ .clk = { \
+ .mux = { \
+ .type = (IMX6_CLK_MUX_NORMAL), \
+ .base = (IMX6_CLK_REG_##_base), \
+ .reg = (_base##_##_reg), \
+ .mask = (_base##_##_reg##_##_mask), \
+ .parents = (_parents), \
+ .nparents = __arraycount(_parents) \
+ } \
+ } \
+}
+
+#define CLK_MUX_BUSY(_name, _parents, _reg, _mask, _busy_reg, _busy_mask) { \
+ .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
+ .type = IMX6_CLK_MUX, \
+ .clk = { \
+ .mux = { \
+ .type = (IMX6_CLK_MUX_BUSY), \
+ .base = (IMX6_CLK_REG_CCM), \
+ .reg = (CCM_##_reg), \
+ .mask = (CCM_##_reg##_##_mask), \
+ .parents = (_parents), \
+ .nparents = __arraycount(_parents), \
+ .busy_reg = (CCM_##_busy_reg), \
+ .busy_mask = (CCM_##_busy_reg##_##_busy_mask) \
+ } \
+ } \
+}
+
+#define CLK_GATE(_name, _parent, _base, _reg, _mask) { \
+ .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
+ .type = IMX6_CLK_GATE, \
+ .parent = (_parent), \
+ .clk = { \
+ .gate = { \
+ .base = (IMX6_CLK_REG_##_base), \
+ .reg = (_base##_##_reg), \
+ .mask = (_base##_##_reg##_##_mask), \
+ .exclusive_mask = 0 \
+ } \
+ } \
+}
+
+#define CLK_GATE_EXCLUSIVE(_name, _parent, _base, _reg, _mask, _exclusive_mask) { \
+ .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \
+ .type = IMX6_CLK_GATE, \
+ .parent = (_parent), \
+ .clk = { \
+ .gate = { \
+ .base = (IMX6_CLK_REG_##_base), \
+ .reg = (_base##_##_reg), \
+ .mask = (_base##_##_reg##_##_mask), \
+ .exclusive_mask = (_base##_##_reg##_##_exclusive_mask) \
+ } \
+ } \
+}
#endif /* _ARM_IMX_IMX6_CCMVAR_H_ */
Index: src/sys/arch/arm/imx/imx6_usb.c
diff -u src/sys/arch/arm/imx/imx6_usb.c:1.4 src/sys/arch/arm/imx/imx6_usb.c:1.5
--- src/sys/arch/arm/imx/imx6_usb.c:1.4 Wed May 23 10:42:05 2018
+++ src/sys/arch/arm/imx/imx6_usb.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_usb.c,v 1.4 2018/05/23 10:42:05 hkenken Exp $ */
+/* $NetBSD: imx6_usb.c,v 1.5 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2012 Genetec Corporation. All rights reserved.
@@ -26,7 +26,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v 1.4 2018/05/23 10:42:05 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v 1.5 2019/06/20 08:16:19 hkenken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -48,31 +48,38 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v
#include <arm/imx/imx6var.h>
#include <arm/imx/imx6_ccmreg.h>
#include <arm/imx/imx6_ccmvar.h>
+#include <arm/imx/imx6_usbreg.h>
#include <arm/imx/imxusbvar.h>
#include "locators.h"
static int imxusbc_search(device_t, cfdata_t, const int *, void *);
static int imxusbc_print(void *, const char *);
+static int imxusbc_init_clocks(struct imxusbc_softc *);
int
imxusbc_attach_common(device_t parent, device_t self, bus_space_tag_t iot)
{
struct imxusbc_softc *sc;
- uint32_t v;
sc = device_private(self);
sc->sc_iot = iot;
/* Map entire USBOH registers. Host controller drivers
* re-use subregions of this. */
- if (bus_space_map(iot, IMX6_AIPS2_BASE + AIPS2_USBOH_BASE, /* XXX */
+ if (bus_space_map(iot, IMX6_AIPS2_BASE + AIPS2_USBOH_BASE,
AIPS2_USBOH_SIZE, 0, &sc->sc_ioh))
return -1;
- /* USBOH3 clock enable */
- v = imx6_ccm_read(CCM_CCGR6);
- imx6_ccm_write(CCM_CCGR6, v | __SHIFTIN(3, CCM_CCGR6_USBOH3_CLK_ENABLE));
+ sc->sc_clk = imx6_get_clock("usboh3");
+ if (sc->sc_clk == NULL) {
+ aprint_error(": couldn't get clock usboh3\n");
+ return -1;
+ }
+ if (imxusbc_init_clocks(sc) != 0) {
+ aprint_error_dev(self, "couldn't init clocks\n");
+ return -1;
+ }
/* attach OTG/EHCI host controllers */
config_search_ia(imxusbc_search, self, "imxusbc", NULL);
@@ -110,3 +117,18 @@ imxusbc_print(void *aux, const char *nam
aprint_normal(" unit %d intr %d", iaa->aa_unit, iaa->aa_irq);
return UNCONF;
}
+
+static int
+imxusbc_init_clocks(struct imxusbc_softc *sc)
+{
+ int error;
+
+ error = clk_enable(sc->sc_clk);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable usboh3: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
Index: src/sys/arch/arm/imx/imxusbvar.h
diff -u src/sys/arch/arm/imx/imxusbvar.h:1.4 src/sys/arch/arm/imx/imxusbvar.h:1.5
--- src/sys/arch/arm/imx/imxusbvar.h:1.4 Tue May 17 06:44:46 2016
+++ src/sys/arch/arm/imx/imxusbvar.h Thu Jun 20 08:16:19 2019
@@ -1,3 +1,30 @@
+/* $NetBSD: imxusbvar.h,v 1.5 2019/06/20 08:16:19 hkenken Exp $ */
+/*
+ * Copyright (c) 2019 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef _ARM_IMX_IMXUSBVAR_H
#define _ARM_IMX_IMXUSBVAR_H
@@ -13,6 +40,8 @@ struct imxusbc_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ struct clk *sc_clk;
+
/* filled in by platform dependent param & routine */
bus_size_t sc_ehci_size;
void (* sc_init_md_hook)(struct imxehci_softc *);
Index: src/sys/arch/arm/imx/imx6_usbphy.c
diff -u src/sys/arch/arm/imx/imx6_usbphy.c:1.1 src/sys/arch/arm/imx/imx6_usbphy.c:1.2
--- src/sys/arch/arm/imx/imx6_usbphy.c:1.1 Thu Nov 9 05:57:23 2017
+++ src/sys/arch/arm/imx/imx6_usbphy.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_usbphy.c,v 1.1 2017/11/09 05:57:23 hkenken Exp $ */
+/* $NetBSD: imx6_usbphy.c,v 1.2 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2017 Genetec Corporation. All rights reserved.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: imx6_usbphy.c,v 1.1 2017/11/09 05:57:23 hkenken Exp $");
+__KERNEL_RCSID(1, "$NetBSD: imx6_usbphy.c,v 1.2 2019/06/20 08:16:19 hkenken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -53,12 +53,15 @@ __KERNEL_RCSID(1, "$NetBSD: imx6_usbphy.
#include <arm/imx/imx6_reg.h>
#include <arm/imx/imx6var.h>
+#include <arm/imx/imx6_ccmvar.h>
#include <arm/imx/imx6_usbphyreg.h>
struct imx6_usbphy_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+
+ struct clk *sc_clk;
};
static int imx6_usbphy_match(device_t, cfdata_t, void *);
@@ -73,7 +76,7 @@ CFATTACH_DECL_NEW(imxusbphy, sizeof(stru
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static int
-imx6_usbphy_enable(device_t dev, void *priv, bool enable)
+imx6_usbphy_enable(device_t dev, bool enable)
{
struct imx6_usbphy_softc * const sc = device_private(dev);
@@ -99,6 +102,20 @@ imx6_usbphy_enable(device_t dev, void *p
}
static int
+imx6_usbphy_init_clocks(device_t dev)
+{
+ struct imx6_usbphy_softc * const sc = device_private(dev);
+
+ int error = clk_enable(sc->sc_clk);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+
+static int
imx6_usbphy_match(device_t parent, cfdata_t cf, void *aux)
{
struct axi_attach_args *aa = aux;
@@ -132,8 +149,18 @@ imx6_usbphy_attach(device_t parent, devi
return;
}
+ switch (device_unit(self)) {
+ case 0:
+ sc->sc_clk = imx6_get_clock("usbphy1");
+ break;
+ case 1:
+ sc->sc_clk = imx6_get_clock("usbphy2");
+ break;
+ }
+
aprint_naive("\n");
aprint_normal(": USB PHY\n");
- imx6_usbphy_enable(self, NULL, true);
+ imx6_usbphy_init_clocks(self);
+ imx6_usbphy_enable(self, true);
}
Index: src/sys/arch/arm/imx/imx6_usdhc.c
diff -u src/sys/arch/arm/imx/imx6_usdhc.c:1.6 src/sys/arch/arm/imx/imx6_usdhc.c:1.7
--- src/sys/arch/arm/imx/imx6_usdhc.c:1.6 Wed May 23 10:42:05 2018
+++ src/sys/arch/arm/imx/imx6_usdhc.c Thu Jun 20 08:16:19 2019
@@ -1,5 +1,4 @@
-/* $NetBSD: imx6_usdhc.c,v 1.6 2018/05/23 10:42:05 hkenken Exp $ */
-
+/* $NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $ */
/*-
* Copyright (c) 2012 Genetec Corporation. All rights reserved.
* Written by Hiroyuki Bessho for Genetec Corporation.
@@ -28,9 +27,8 @@
* SUCH DAMAGE.
*/
-
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.6 2018/05/23 10:42:05 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $");
#include "imxgpio.h"
@@ -53,19 +51,23 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c
#include <arm/imx/imx6_ccmreg.h>
#include <arm/imx/imxgpiovar.h>
-
struct sdhc_axi_softc {
struct sdhc_softc sc_sdhc;
+
/* we have only one slot */
struct sdhc_host *sc_hosts[1];
int32_t sc_gpio_cd;
int32_t sc_gpio_cd_active;
+
void *sc_ih;
+
+ struct clk *sc_clk;
};
static int sdhc_match(device_t, cfdata_t, void *);
static void sdhc_attach(device_t, device_t, void *);
static int imx6_sdhc_card_detect(struct sdhc_softc *);
+static int imx6_sdhc_init_clocks(struct sdhc_axi_softc *);
CFATTACH_DECL_NEW(sdhc_axi, sizeof(struct sdhc_axi_softc),
sdhc_match, sdhc_attach, NULL, NULL);
@@ -89,25 +91,6 @@ sdhc_match(device_t parent, cfdata_t cf,
return 0;
}
-static int
-imx6_sdhc_card_detect(struct sdhc_softc *ssc)
-{
- int detect;
-#if NIMXGPIO > 0
- struct sdhc_axi_softc *sc;
-
- sc = device_private(ssc->sc_dev);
- if (sc->sc_gpio_cd >= 0) {
- detect = gpio_data_read(sc->sc_gpio_cd);
- if (sc->sc_gpio_cd_active == GPIO_PIN_LOW)
- detect = !detect;
- } else
-#endif
- detect = 1;
-
- return detect;
-}
-
static void
sdhc_attach(device_t parent, device_t self, void *aux)
{
@@ -115,7 +98,6 @@ sdhc_attach(device_t parent, device_t se
struct axi_attach_args *aa = aux;
bus_space_tag_t iot = aa->aa_iot;
bus_space_handle_t ioh;
- u_int perclk = 0, v;
sc->sc_sdhc.sc_dev = self;
sc->sc_sdhc.sc_dmat = aa->aa_dmat;
@@ -131,36 +113,37 @@ sdhc_attach(device_t parent, device_t se
switch (aa->aa_addr) {
case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE:
- v = imx6_ccm_read(CCM_CCGR6);
- imx6_ccm_write(CCM_CCGR6, v | __SHIFTIN(3, CCM_CCGR6_USDHC1_CLK_ENABLE));
- perclk = imx6_get_clock(IMX6CLK_USDHC1);
+ sc->sc_clk = imx6_get_clock("usdhc1");
imx6_set_gpio(self, "usdhc1-cd-gpio", &sc->sc_gpio_cd,
&sc->sc_gpio_cd_active, GPIO_DIR_IN);
break;
case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE:
- v = imx6_ccm_read(CCM_CCGR6);
- imx6_ccm_write(CCM_CCGR6, v | __SHIFTIN(3, CCM_CCGR6_USDHC2_CLK_ENABLE));
- perclk = imx6_get_clock(IMX6CLK_USDHC2);
+ sc->sc_clk = imx6_get_clock("usdhc2");
imx6_set_gpio(self, "usdhc2-cd-gpio", &sc->sc_gpio_cd,
&sc->sc_gpio_cd_active, GPIO_DIR_IN);
break;
case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE:
- v = imx6_ccm_read(CCM_CCGR6);
- imx6_ccm_write(CCM_CCGR6, v | __SHIFTIN(3, CCM_CCGR6_USDHC3_CLK_ENABLE));
- perclk = imx6_get_clock(IMX6CLK_USDHC3);
+ sc->sc_clk = imx6_get_clock("usdhc3");
imx6_set_gpio(self, "usdhc3-cd-gpio", &sc->sc_gpio_cd,
&sc->sc_gpio_cd_active, GPIO_DIR_IN);
break;
case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE:
- v = imx6_ccm_read(CCM_CCGR6);
- imx6_ccm_write(CCM_CCGR6, v | __SHIFTIN(3, CCM_CCGR6_USDHC4_CLK_ENABLE));
- perclk = imx6_get_clock(IMX6CLK_USDHC4);
+ sc->sc_clk = imx6_get_clock("usdhc4");
imx6_set_gpio(self, "usdhc4-cd-gpio", &sc->sc_gpio_cd,
&sc->sc_gpio_cd_active, GPIO_DIR_IN);
break;
}
- sc->sc_sdhc.sc_clkbase = perclk / 1000;
+ if (sc->sc_clk == NULL) {
+ aprint_error(": couldn't get clock usdhc\n");
+ return;
+ }
+ if (imx6_sdhc_init_clocks(sc) != 0) {
+ aprint_error_dev(self, "couldn't init clocks\n");
+ return;
+ }
+
+ sc->sc_sdhc.sc_clkbase = clk_get_rate(sc->sc_clk) / 1000;
sc->sc_sdhc.sc_flags |=
SDHC_FLAG_USE_DMA |
SDHC_FLAG_NO_PWR0 |
@@ -189,3 +172,36 @@ sdhc_attach(device_t parent, device_t se
aprint_error_dev(self, "can't establish power hook\n");
}
}
+
+static int
+imx6_sdhc_card_detect(struct sdhc_softc *ssc)
+{
+ int detect;
+#if NIMXGPIO > 0
+ struct sdhc_axi_softc *sc;
+
+ sc = device_private(ssc->sc_dev);
+ if (sc->sc_gpio_cd >= 0) {
+ detect = gpio_data_read(sc->sc_gpio_cd);
+ if (sc->sc_gpio_cd_active == GPIO_PIN_LOW)
+ detect = !detect;
+ } else
+#endif
+ detect = 1;
+
+ return detect;
+}
+
+static int
+imx6_sdhc_init_clocks(struct sdhc_axi_softc *sc)
+{
+ int error;
+
+ error = clk_enable(sc->sc_clk);
+ if (error) {
+ aprint_error_dev(sc->sc_sdhc.sc_dev, "couldn't enable: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
Index: src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c
diff -u src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c:1.4 src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c:1.5
--- src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c:1.4 Wed Jun 20 07:05:37 2018
+++ src/sys/arch/evbarm/nitrogen6/nitrogen6_usb.c Thu Jun 20 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nitrogen6_usb.c,v 1.4 2018/06/20 07:05:37 hkenken Exp $ */
+/* $NetBSD: nitrogen6_usb.c,v 1.5 2019/06/20 08:16:19 hkenken Exp $ */
/*
* Copyright (c) 2013 Genetec Corporation. All rights reserved.
@@ -27,7 +27,7 @@
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nitrogen6_usb.c,v 1.4 2018/06/20 07:05:37 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nitrogen6_usb.c,v 1.5 2019/06/20 08:16:19 hkenken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -123,18 +123,6 @@ init_otg(struct imxehci_softc *sc)
sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE;
- /* USB1 power */
- imx6_ccm_analog_write(USB_ANALOG_USB1_CHRG_DETECT,
- USB_ANALOG_USB_CHRG_DETECT_EN_B |
- USB_ANALOG_USB_CHRG_DETECT_CHK_CHRG_B);
- imx6_pll_power(CCM_ANALOG_PLL_USB1, 1, CCM_ANALOG_PLL_ENABLE);
- imx6_ccm_analog_write(CCM_ANALOG_PLL_USB1_CLR,
- CCM_ANALOG_PLL_BYPASS);
- imx6_ccm_analog_write(CCM_ANALOG_PLL_USB1_SET,
- CCM_ANALOG_PLL_ENABLE |
- CCM_ANALOG_PLL_POWER |
- CCM_ANALOG_PLL_EN_USB_CLK);
-
imxehci_reset(sc);
v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh, USBNC_USB_OTG_CTRL);
@@ -153,16 +141,6 @@ init_h1(struct imxehci_softc *sc)
sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE;
- imx6_ccm_analog_write(USB_ANALOG_USB2_CHRG_DETECT,
- USB_ANALOG_USB_CHRG_DETECT_EN_B |
- USB_ANALOG_USB_CHRG_DETECT_CHK_CHRG_B);
- imx6_ccm_analog_write(CCM_ANALOG_PLL_USB2_CLR,
- CCM_ANALOG_PLL_BYPASS);
- imx6_ccm_analog_write(CCM_ANALOG_PLL_USB2_SET,
- CCM_ANALOG_PLL_ENABLE |
- CCM_ANALOG_PLL_POWER |
- CCM_ANALOG_PLL_EN_USB_CLK);
-
v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh, USBNC_USB_UH1_CTRL);
v |= USBNC_USB_UH1_CTRL_OVER_CUR_POL;
v |= USBNC_USB_UH1_CTRL_OVER_CUR_DIS;