diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-12-28 22:45:25 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-12-28 22:45:25 +0000 |
commit | 60c8277d806b8bfdab967ba11febbd0842c58cd7 (patch) | |
tree | b7fef91069ad15a3927292b82e583e66d3dab72c /sys | |
parent | e986b7b3f586db0e5ae350705054bf6fafa704de (diff) |
Use the generic clock framework.
ok jsg@, patrick@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/armv7/imx/imxccm.c | 104 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxccm_clocks.h | 31 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxccmvar.h | 7 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxehci.c | 6 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxesdhc.c | 10 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxiic.c | 12 | ||||
-rw-r--r-- | sys/arch/armv7/imx/imxuart.c | 17 |
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); |