summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-12-28 22:45:25 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-12-28 22:45:25 +0000
commit60c8277d806b8bfdab967ba11febbd0842c58cd7 (patch)
treeb7fef91069ad15a3927292b82e583e66d3dab72c /sys
parente986b7b3f586db0e5ae350705054bf6fafa704de (diff)
Use the generic clock framework.
ok jsg@, patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/armv7/imx/imxccm.c104
-rw-r--r--sys/arch/armv7/imx/imxccm_clocks.h31
-rw-r--r--sys/arch/armv7/imx/imxccmvar.h7
-rw-r--r--sys/arch/armv7/imx/imxehci.c6
-rw-r--r--sys/arch/armv7/imx/imxesdhc.c10
-rw-r--r--sys/arch/armv7/imx/imxiic.c12
-rw-r--r--sys/arch/armv7/imx/imxuart.c17
7 files changed, 136 insertions, 51 deletions
diff --git a/sys/arch/armv7/imx/imxccm.c b/sys/arch/armv7/imx/imxccm.c
index e56848b5a22..87514aec1e4 100644
--- a/sys/arch/armv7/imx/imxccm.c
+++ b/sys/arch/armv7/imx/imxccm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxccm.c,v 1.7 2016/12/26 14:01:21 kettenis Exp $ */
+/* $OpenBSD: imxccm.c,v 1.8 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -30,6 +30,7 @@
#include <machine/fdt.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/fdt.h>
/* registers */
@@ -117,10 +118,8 @@
#define CCM_CSCDR1_USDHCx_PODF_MASK 0x7
#define CCM_CSCDR1_UART_PODF_MASK 0x7
#define CCM_CCGR1_ENET (3 << 10)
-#define CCM_CCGR2_I2C(x) (3 << (6 + 2*x))
#define CCM_CCGR4_125M_PCIE (3 << 0)
#define CCM_CCGR5_100M_SATA (3 << 4)
-#define CCM_CCGR6_USBOH3 (3 << 0)
#define CCM_CSCMR1_PERCLK_CLK_SEL_MASK 0x1f
#define CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK 0x7f
#define CCM_ANALOG_PLL_ARM_BYPASS (1 << 16)
@@ -168,10 +167,23 @@
#define HCLR4(sc, reg, bits) \
HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
+struct imxccm_gate {
+ uint8_t reg;
+ uint8_t pos;
+ uint8_t parent;
+};
+
+#include "imxccm_clocks.h"
+
struct imxccm_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ int sc_node;
+
+ struct imxccm_gate *sc_gates;
+ int sc_ngates;
+ struct clock_device sc_cd;
};
enum clocks {
@@ -227,8 +239,8 @@ unsigned int imxccm_get_ahbclk(void);
unsigned int imxccm_get_ipgclk(void);
unsigned int imxccm_get_ipg_perclk(void);
unsigned int imxccm_get_uartclk(void);
-void imxccm_enable_i2c(int x);
-void imxccm_enable_usboh3(void);
+void imxccm_enable(void *, uint32_t *, int);
+uint32_t imxccm_get_frequency(void *, uint32_t *);
void imxccm_disable_usb1_chrg_detect(void);
void imxccm_disable_usb2_chrg_detect(void);
void imxccm_enable_pll_usb1(void);
@@ -258,17 +270,27 @@ imxccm_attach(struct device *parent, struct device *self, void *aux)
KASSERT(faa->fa_nreg >= 1);
imxccm_sc = sc;
+ sc->sc_node = faa->fa_node;
sc->sc_iot = faa->fa_iot;
if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
faa->fa_reg[0].size + 0x1000, 0, &sc->sc_ioh))
panic("%s: bus_space_map failed!", __func__);
+ sc->sc_gates = imx6_gates;
+ sc->sc_ngates = nitems(imx6_gates);
+
printf(": imx6 rev 1.%d CPU freq: %d MHz",
HREAD4(sc, CCM_ANALOG_DIGPROG) & CCM_ANALOG_DIGPROG_MINOR_MASK,
imxccm_get_armclk() / 1000);
printf("\n");
+ sc->sc_cd.cd_node = faa->fa_node;
+ sc->sc_cd.cd_cookie = sc;
+ sc->sc_cd.cd_enable = imxccm_enable;
+ sc->sc_cd.cd_get_frequency = imxccm_get_frequency;
+ clock_register(&sc->sc_cd);
+
cpu_cpuspeed = imxccm_cpuspeed;
}
@@ -325,7 +347,7 @@ imxccm_get_pll3_pfd(unsigned int pfd)
}
unsigned int
-imxccm_get_armclk()
+imxccm_get_armclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
@@ -381,7 +403,6 @@ unsigned int
imxccm_get_usdhx(int x)
{
struct imxccm_softc *sc = imxccm_sc;
-
uint32_t cscmr1 = HREAD4(sc, CCM_CSCMR1);
uint32_t cscdr1 = HREAD4(sc, CCM_CSCDR1);
uint32_t podf, clkroot;
@@ -401,7 +422,7 @@ imxccm_get_usdhx(int x)
}
unsigned int
-imxccm_get_uartclk()
+imxccm_get_uartclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
@@ -412,7 +433,7 @@ imxccm_get_uartclk()
}
unsigned int
-imxccm_get_periphclk()
+imxccm_get_periphclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
@@ -446,7 +467,7 @@ imxccm_get_periphclk()
}
unsigned int
-imxccm_get_fecclk()
+imxccm_get_fecclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
uint32_t div = 0;
@@ -471,7 +492,7 @@ imxccm_get_fecclk()
}
unsigned int
-imxccm_get_ahbclk()
+imxccm_get_ahbclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
uint32_t ahb_podf;
@@ -482,7 +503,7 @@ imxccm_get_ahbclk()
}
unsigned int
-imxccm_get_ipgclk()
+imxccm_get_ipgclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
uint32_t ipg_podf;
@@ -493,7 +514,7 @@ imxccm_get_ipgclk()
}
unsigned int
-imxccm_get_ipg_perclk()
+imxccm_get_ipg_perclk(void)
{
struct imxccm_softc *sc = imxccm_sc;
uint32_t ipg_podf;
@@ -504,19 +525,62 @@ imxccm_get_ipg_perclk()
}
void
-imxccm_enable_i2c(int x)
+imxccm_enable(void *cookie, uint32_t *cells, int on)
{
- struct imxccm_softc *sc = imxccm_sc;
+ struct imxccm_softc *sc = cookie;
+ uint32_t idx = cells[0];
+ uint8_t reg, pos;
+
+ /* Dummy clock. */
+ if (idx == 0)
+ return;
- HSET4(sc, CCM_CCGR2, CCM_CCGR2_I2C(x));
+ if (idx >= sc->sc_ngates || sc->sc_gates[idx].reg == 0) {
+ printf("%s: 0x%08x\n", __func__, idx);
+ return;
+ }
+
+ reg = sc->sc_gates[idx].reg;
+ pos = sc->sc_gates[idx].pos;
+
+ if (on)
+ HSET4(sc, reg, 0x3 << (2 * pos));
+ else
+ HCLR4(sc, reg, 0x3 << (2 * pos));
}
-void
-imxccm_enable_usboh3(void)
+uint32_t
+imxccm_get_frequency(void *cookie, uint32_t *cells)
{
- struct imxccm_softc *sc = imxccm_sc;
+ struct imxccm_softc *sc = cookie;
+ uint32_t idx = cells[0];
+ uint32_t parent;
+
+ /* Dummy clock. */
+ if (idx == 0)
+ return 0;
+
+ if (idx < sc->sc_ngates && sc->sc_gates[idx].parent) {
+ parent = sc->sc_gates[idx].parent;
+ return imxccm_get_frequency(sc, &parent);
+ }
+
+ switch (idx) {
+ case IMX6_CLK_IPG:
+ return imxccm_get_ipgclk();
+ case IMX6_CLK_IPG_PER:
+ return imxccm_get_ipg_perclk();
+ case IMX6_CLK_UART_SERIAL:
+ return imxccm_get_uartclk();
+ case IMX6_CLK_USDHC1:
+ case IMX6_CLK_USDHC2:
+ case IMX6_CLK_USDHC3:
+ case IMX6_CLK_USDHC4:
+ return imxccm_get_usdhx(idx - IMX6_CLK_USDHC1 + 1);
+ }
- HSET4(sc, CCM_CCGR6, CCM_CCGR6_USBOH3);
+ printf("%s: 0x%08x\n", __func__, idx);
+ return 0;
}
void
diff --git a/sys/arch/armv7/imx/imxccm_clocks.h b/sys/arch/armv7/imx/imxccm_clocks.h
new file mode 100644
index 00000000000..1c84493711c
--- /dev/null
+++ b/sys/arch/armv7/imx/imxccm_clocks.h
@@ -0,0 +1,31 @@
+/* Public Domain */
+
+/*
+ * i.MX6Q clocks.
+ */
+
+#define IMX6_CLK_IPG 0x3e
+#define IMX6_CLK_IPG_PER 0x3f
+#define IMX6_CLK_I2C1 0x7d
+#define IMX6_CLK_I2C2 0x7e
+#define IMX6_CLK_I2C3 0x7f
+#define IMX6_CLK_UART_IPG 0xa0
+#define IMX6_CLK_UART_SERIAL 0xa1
+#define IMX6_CLK_USBOH3 0xa2
+#define IMX6_CLK_USDHC1 0xa3
+#define IMX6_CLK_USDHC2 0xa4
+#define IMX6_CLK_USDHC3 0xa5
+#define IMX6_CLK_USDHC4 0xa6
+
+struct imxccm_gate imx6_gates[] = {
+ [IMX6_CLK_I2C1] = { CCM_CCGR2, 3, IMX6_CLK_IPG_PER },
+ [IMX6_CLK_I2C2] = { CCM_CCGR2, 4, IMX6_CLK_IPG_PER },
+ [IMX6_CLK_I2C3] = { CCM_CCGR2, 5, IMX6_CLK_IPG_PER },
+ [IMX6_CLK_UART_IPG] = { CCM_CCGR5, 12, IMX6_CLK_IPG },
+ [IMX6_CLK_UART_SERIAL] = { CCM_CCGR5, 13 },
+ [IMX6_CLK_USBOH3] = { CCM_CCGR6, 0 },
+ [IMX6_CLK_USDHC1] = { CCM_CCGR6, 1 },
+ [IMX6_CLK_USDHC2] = { CCM_CCGR6, 2 },
+ [IMX6_CLK_USDHC3] = { CCM_CCGR6, 3 },
+ [IMX6_CLK_USDHC4] = { CCM_CCGR6, 4 },
+};
diff --git a/sys/arch/armv7/imx/imxccmvar.h b/sys/arch/armv7/imx/imxccmvar.h
index 86ebdaa9813..2b55a954725 100644
--- a/sys/arch/armv7/imx/imxccmvar.h
+++ b/sys/arch/armv7/imx/imxccmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxccmvar.h,v 1.2 2015/05/30 08:09:19 jsg Exp $ */
+/* $OpenBSD: imxccmvar.h,v 1.3 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -18,13 +18,8 @@
#ifndef IMXCCMVAR_H
#define IMXCCMVAR_H
-unsigned int imxccm_get_usdhx(int x);
unsigned int imxccm_get_fecclk(void);
-unsigned int imxccm_get_uartclk(void);
-unsigned int imxccm_get_ipg_perclk(void);
unsigned int imxccm_get_ahbclk(void);
-void imxccm_enable_i2c(int x);
-void imxccm_enable_usboh3(void);
void imxccm_disable_usb1_chrg_detect(void);
void imxccm_disable_usb2_chrg_detect(void);
void imxccm_enable_pll_usb1(void);
diff --git a/sys/arch/armv7/imx/imxehci.c b/sys/arch/armv7/imx/imxehci.c
index a76d477f5e6..fc5f6c9d5be 100644
--- a/sys/arch/armv7/imx/imxehci.c
+++ b/sys/arch/armv7/imx/imxehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxehci.c,v 1.18 2016/10/02 06:36:39 kettenis Exp $ */
+/* $OpenBSD: imxehci.c,v 1.19 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -35,6 +35,7 @@
#include <armv7/imx/imxccmvar.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/ofw_gpio.h>
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/ofw_regulator.h>
@@ -170,8 +171,7 @@ imxehci_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
pinctrl_byname(faa->fa_node, "default");
-
- imxccm_enable_usboh3();
+ clock_enable(faa->fa_node, NULL);
delay(1000);
/* enable usb bus power */
diff --git a/sys/arch/armv7/imx/imxesdhc.c b/sys/arch/armv7/imx/imxesdhc.c
index 6ab3fc9c9c0..6cec0554de6 100644
--- a/sys/arch/armv7/imx/imxesdhc.c
+++ b/sys/arch/armv7/imx/imxesdhc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxesdhc.c,v 1.34 2016/09/05 12:45:44 mglocker Exp $ */
+/* $OpenBSD: imxesdhc.c,v 1.35 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2009 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -31,10 +31,8 @@
#include <dev/sdmmc/sdmmcchip.h>
#include <dev/sdmmc/sdmmcvar.h>
-#include <armv7/armv7/armv7var.h>
-#include <armv7/imx/imxccmvar.h>
-
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/ofw_gpio.h>
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/ofw_regulator.h>
@@ -185,7 +183,6 @@ struct imxesdhc_softc {
uint32_t sc_vdd;
u_int sc_flags;
- int unit; /* unit id */
struct device *sdmmc; /* generic SD/MMC device */
int clockbit; /* clock control bit */
u_int clkbase; /* base clock freq. in KHz */
@@ -301,7 +298,6 @@ imxesdhc_attach(struct device *parent, struct device *self, void *aux)
if (faa->fa_nreg < 1)
return;
- sc->unit = (faa->fa_reg[0].addr & 0xc000) >> 14;
sc->sc_node = faa->fa_node;
sc->sc_dmat = faa->fa_dmat;
sc->sc_iot = faa->fa_iot;
@@ -339,7 +335,7 @@ imxesdhc_attach(struct device *parent, struct device *self, void *aux)
/*
* Determine the base clock frequency. (2.2.24)
*/
- sc->clkbase = imxccm_get_usdhx(sc->unit + 1);
+ sc->clkbase = clock_get_frequency(faa->fa_node, "per");
printf("%s: %d MHz base clock\n", DEVNAME(sc), sc->clkbase / 1000);
diff --git a/sys/arch/armv7/imx/imxiic.c b/sys/arch/armv7/imx/imxiic.c
index 951fb45c54a..8e46c1ac043 100644
--- a/sys/arch/armv7/imx/imxiic.c
+++ b/sys/arch/armv7/imx/imxiic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxiic.c,v 1.11 2016/08/06 17:18:38 kettenis Exp $ */
+/* $OpenBSD: imxiic.c,v 1.12 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
*
@@ -18,17 +18,15 @@
#include <sys/param.h>
#include <sys/device.h>
#include <sys/kernel.h>
-#include <sys/kthread.h>
-#include <sys/malloc.h>
#include <sys/systm.h>
+
#include <machine/bus.h>
#include <machine/fdt.h>
-#include <armv7/armv7/armv7var.h>
-#include <armv7/imx/imxccmvar.h>
#include <armv7/imx/imxiicvar.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/fdt.h>
@@ -170,7 +168,7 @@ imxiic_setspeed(struct imxiic_softc *sc, u_int speed)
uint32_t div;
int i;
- i2c_clk_rate = imxccm_get_ipg_perclk();
+ i2c_clk_rate = clock_get_frequency(sc->sc_node, NULL);
div = (i2c_clk_rate + speed - 1) / speed;
if (div < imxiic_clk_div[0][0])
i = 0;
@@ -324,7 +322,7 @@ imxiic_i2c_acquire_bus(void *cookie, int flags)
rw_enter(&sc->sc_buslock, RW_WRITE);
/* clock gating */
- imxccm_enable_i2c(sc->unit);
+ clock_enable(sc->sc_node, NULL);
/* set speed to 100kHz */
imxiic_setspeed(sc, 100);
diff --git a/sys/arch/armv7/imx/imxuart.c b/sys/arch/armv7/imx/imxuart.c
index ba4a857270a..e4e0b1d2cae 100644
--- a/sys/arch/armv7/imx/imxuart.c
+++ b/sys/arch/armv7/imx/imxuart.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxuart.c,v 1.12 2016/08/06 17:18:38 kettenis Exp $ */
+/* $OpenBSD: imxuart.c,v 1.13 2016/12/28 22:45:24 kettenis Exp $ */
/*
* Copyright (c) 2005 Dale Rahn <drahn@motorola.com>
*
@@ -29,23 +29,22 @@
#include <sys/select.h>
#include <sys/kernel.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
#include <dev/cons.h>
#ifdef DDB
#include <ddb/db_var.h>
#endif
-#include <machine/bus.h>
-#include <machine/fdt.h>
#include <arm/armv7/armv7var.h>
+#include <armv7/armv7/armv7_machdep.h>
#include <armv7/imx/imxuartreg.h>
#include <armv7/imx/imxuartvar.h>
-#include <armv7/armv7/armv7var.h>
-#include <armv7/armv7/armv7_machdep.h>
-#include <armv7/imx/imxccmvar.h>
-#include <armv7/imx/imxiomuxcvar.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/fdt.h>
@@ -56,6 +55,7 @@ struct imxuart_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ int sc_node;
struct soft_intrhand *sc_si;
void *sc_irq;
struct tty *sc_tty;
@@ -172,6 +172,7 @@ imxuart_attach(struct device *parent, struct device *self, void *aux)
sc->sc_irq = arm_intr_establish_fdt(faa->fa_node, IPL_TTY,
imxuart_intr, sc, sc->sc_dev.dv_xname);
+ sc->sc_node = faa->fa_node;
sc->sc_iot = faa->fa_iot;
if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
faa->fa_reg[0].size, 0, &sc->sc_ioh))
@@ -550,7 +551,7 @@ imxuartopen(dev_t dev, int flag, int mode, struct proc *p)
/* formula: clk / (rfdiv * 1600) */
bus_space_write_2(iot, ioh, IMXUART_UBMR,
- (imxccm_get_uartclk() * 1000) / 1600);
+ (clock_get_frequency(sc->sc_node, "per") * 1000) / 1600);
SET(sc->sc_ucr1, IMXUART_CR1_EN|IMXUART_CR1_RRDYEN);
SET(sc->sc_ucr2, IMXUART_CR2_TXEN|IMXUART_CR2_RXEN);