Date: Sat, 19 Nov 2016 17:46:19 +0000 (UTC) From: Ruslan Bukin <br@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r308857 - in head: bin/dd sys/mips/conf sys/mips/ingenic Message-ID: <201611191746.uAJHkJQ8095246@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: br Date: Sat Nov 19 17:46:18 2016 New Revision: 308857 URL: https://svnweb.freebsd.org/changeset/base/308857 Log: Bring in support for Ingenic XBurst JZ4780 and X1000 systems on chips. Imgtec CI20 and Ingenic CANNA boards supported. Submitted by: Alexander Kabaev <kan@FreeBSD.org> Reviewed by: Ruslan Bukin <br@FreeBSD.org> Sponsored by: DARPA, AFRL Added: head/sys/mips/conf/CANNA (contents, props changed) head/sys/mips/conf/CI20 (contents, props changed) head/sys/mips/conf/JZ4780 (contents, props changed) head/sys/mips/conf/JZ4780.hints (contents, props changed) head/sys/mips/conf/X1000 (contents, props changed) head/sys/mips/conf/X1000.hints (contents, props changed) head/sys/mips/ingenic/ head/sys/mips/ingenic/files.jz4780 (contents, props changed) head/sys/mips/ingenic/files.x1000 (contents, props changed) head/sys/mips/ingenic/jz4780_clk.h (contents, props changed) head/sys/mips/ingenic/jz4780_clk_gen.c (contents, props changed) head/sys/mips/ingenic/jz4780_clk_otg.c (contents, props changed) head/sys/mips/ingenic/jz4780_clk_pll.c (contents, props changed) head/sys/mips/ingenic/jz4780_clock.c (contents, props changed) head/sys/mips/ingenic/jz4780_clock.h (contents, props changed) head/sys/mips/ingenic/jz4780_cpuregs.h (contents, props changed) head/sys/mips/ingenic/jz4780_dme.c (contents, props changed) head/sys/mips/ingenic/jz4780_dwc_fdt.c (contents, props changed) head/sys/mips/ingenic/jz4780_efuse.c (contents, props changed) head/sys/mips/ingenic/jz4780_ehci.c (contents, props changed) head/sys/mips/ingenic/jz4780_gpio.c (contents, props changed) head/sys/mips/ingenic/jz4780_gpio_if.m (contents, props changed) head/sys/mips/ingenic/jz4780_intr.c (contents, props changed) head/sys/mips/ingenic/jz4780_machdep.c (contents, props changed) head/sys/mips/ingenic/jz4780_mmc.c (contents, props changed) head/sys/mips/ingenic/jz4780_mp.c (contents, props changed) head/sys/mips/ingenic/jz4780_mpboot.S (contents, props changed) head/sys/mips/ingenic/jz4780_nand.c (contents, props changed) head/sys/mips/ingenic/jz4780_nemc.c (contents, props changed) head/sys/mips/ingenic/jz4780_ohci.c (contents, props changed) head/sys/mips/ingenic/jz4780_pinctrl.c (contents, props changed) head/sys/mips/ingenic/jz4780_pinctrl.h (contents, props changed) head/sys/mips/ingenic/jz4780_regs.h (contents, props changed) head/sys/mips/ingenic/jz4780_timer.c (contents, props changed) head/sys/mips/ingenic/jz4780_uart.c (contents, props changed) Modified: head/bin/dd/dd.c Modified: head/bin/dd/dd.c ============================================================================== --- head/bin/dd/dd.c Sat Nov 19 17:13:12 2016 (r308856) +++ head/bin/dd/dd.c Sat Nov 19 17:46:18 2016 (r308857) @@ -48,13 +48,10 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/stat.h> #include <sys/conf.h> -#include <sys/capsicum.h> #include <sys/disklabel.h> #include <sys/filio.h> -#include <sys/mtio.h> #include <assert.h> -#include <capsicum_helpers.h> #include <ctype.h> #include <err.h> #include <errno.h> @@ -95,10 +92,6 @@ main(int argc __unused, char *argv[]) jcl(argv); setup(); - caph_cache_catpages(); - if (cap_enter() == -1 && errno != ENOSYS) - err(1, "unable to enter capability mode"); - (void)signal(SIGINFO, siginfo_handler); (void)signal(SIGINT, terminate); @@ -132,8 +125,6 @@ static void setup(void) { u_int cnt; - cap_rights_t rights; - unsigned long cmds[] = { FIODTYPE, MTIOCTOP }; if (in.name == NULL) { in.name = "stdin"; @@ -142,20 +133,13 @@ setup(void) in.fd = open(in.name, O_RDONLY, 0); if (in.fd == -1) err(1, "%s", in.name); - if (caph_limit_stdin() == -1) - err(1, "unable to limit capability rights"); } getfdtype(&in); - cap_rights_init(&rights, CAP_READ, CAP_SEEK); - if (cap_rights_limit(in.fd, &rights) == -1 && errno != ENOSYS) - err(1, "unable to limit capability rights"); - if (files_cnt > 1 && !(in.flags & ISTAPE)) errx(1, "files is not supported for non-tape devices"); - cap_rights_set(&rights, CAP_WRITE, CAP_FTRUNCATE, CAP_IOCTL); if (out.name == NULL) { /* No way to check for read access here. */ out.fd = STDOUT_FILENO; @@ -172,27 +156,13 @@ setup(void) if (out.fd == -1) { out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE); out.flags |= NOREAD; - cap_rights_clear(&rights, CAP_READ); } if (out.fd == -1) err(1, "%s", out.name); - if (caph_limit_stdout() == -1) - err(1, "unable to limit capability rights"); } getfdtype(&out); - if (cap_rights_limit(out.fd, &rights) == -1 && errno != ENOSYS) - err(1, "unable to limit capability rights"); - if (cap_ioctls_limit(out.fd, cmds, nitems(cmds)) == -1 && - errno != ENOSYS) - err(1, "unable to limit capability rights"); - - if (in.fd != STDERR_FILENO && out.fd != STDERR_FILENO) { - if (caph_limit_stderr() == -1) - err(1, "unable to limit capability rights"); - } - /* * Allocate space for the input and output buffers. If not doing * record oriented I/O, only need a single buffer. Added: head/sys/mips/conf/CANNA ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/CANNA Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,29 @@ +# CANNA -- Kernel config for Ingenic CANNA board +# +# $FreeBSD$ + +include "X1000" +ident CANNA + +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=ingenic/canna.dts + +#options KTR +#options KTR_CPUMASK=0x3 +#options KTR_MASK=(KTR_GEN) +#options KTR_COMPILE=(KTR_GEN) +#options KTR_VERBOSE + +# Uncomment for NFS root +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=dme0 +#options BOOTP_COMPAT +options ROOTDEVNAME=\"ufs:mmcsd0s3\" + +makeoptions TRAMPLOADADDR=0x88000000 + +#options VERBOSE_SYSINIT +options PRINTF_BUFR_SIZE=256 Added: head/sys/mips/conf/CI20 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/CI20 Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,31 @@ +# CI20 -- Kernel config for Creator CI20 board +# +# $FreeBSD$ + +include "JZ4780" +ident CI20 + +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=ingenic/ci20.dts + +#options KTR +#options KTR_CPUMASK=0x3 +#options KTR_MASK=(KTR_GEN) +#options KTR_COMPILE=(KTR_GEN) +#options KTR_VERBOSE + +# Uncomment for NFS root +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=dme0 +#options BOOTP_COMPAT + +options ROOTDEVNAME=\"ufs:mmcsd0\" + +makeoptions TRAMPLOADADDR=0x88000000 + +#options VERBOSE_SYSINIT +device dme +options PRINTF_BUFR_SIZE=256 Added: head/sys/mips/conf/JZ4780 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/JZ4780 Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,92 @@ +# JZ4780 -- Kernel config for Ingenic JZ47XX boards +# +# $FreeBSD$ + +ident JZ4780 +machine mips mipsel +cpu CPU_XBURST +cpu CPU_MIPS4KC + +makeoptions KERNLOADADDR=0x80020000 +makeoptions ARCH_FLAGS="-EL -march=mips32r2" + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +files "../ingenic/files.jz4780" +hints "JZ4780.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options INTRNG # Borrow interrupt code from ARM +options MIPS_NIRQ=264 # 8 cpuintc + 64 intc + 6 * 23 gpio + +options DDB +options KDB +options BREAK_TO_DEBUGGER + +options COMPAT_FREEBSD10 + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCL #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCL +options NFSLOCKD #Network Lock Manager +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +#options ROOTDEVNAME=\"ufs:ada0\" + +options GEOM_LABEL # Provides labelization +options GEOM_PART_GPT # GUID Partition Tables. +#options GEOM_RAID # Soft RAID functionality. + +# Debugging for use in -current +#options DEADLKRES #Enable the deadlock resolver +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +# Make an SMP-capable kernel by default +# options SMP # Symmetric MultiProcessor Kernel + +device loop +device ether +#device le +device miibus +device bpf +device md +device uart +device random + +device fdt_pinctrl + +device clk +device regulator +device ext_resources + +device gpio + +device scbus +device da + +device mmc +device mmcsd + +# USB support +options USB_DEBUG # enable debug msgs +options USB_HOST_ALIGN=128 # L2 cache line size +device ohci # OHCI PCI->USB interface +device ehci # EHCI PCI->USB interface (USB 2.0) +device dwcotg # DesignWare HS OTG controller +device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +device uhid # "Human Interface Devices" +#device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ums # Mouse Added: head/sys/mips/conf/JZ4780.hints ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/JZ4780.hints Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,2 @@ +# $FreeBSD$ +# device.hints Added: head/sys/mips/conf/X1000 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/X1000 Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,89 @@ +# X1000 -- Kernel config for Ingenic X1000 boards +# +# $FreeBSD$ + +ident X1000 +machine mips mipsel +cpu CPU_XBURST +cpu CPU_MIPS4KC + +makeoptions KERNLOADADDR=0x80020000 +makeoptions ARCH_FLAGS="-EL -march=mips32r2" + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" + +files "../ingenic/files.x1000" +hints "X1000.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options INTRNG # Borrow interrupt code from ARM +options MIPS_NIRQ=264 # 8 cpuintc + 64 intc + 6 * 23 gpio + +options DDB +options KDB +options BREAK_TO_DEBUGGER + +options COMPAT_FREEBSD10 + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCL #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCL +options NFSLOCKD #Network Lock Manager +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +#options ROOTDEVNAME=\"ufs:ada0\" + +options GEOM_LABEL # Provides labelization +options GEOM_PART_GPT # GUID Partition Tables. +#options GEOM_RAID # Soft RAID functionality. + +# Debugging for use in -current +#options DEADLKRES #Enable the deadlock resolver +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +device loop +device ether +#device le +device miibus +device bpf +device md +device uart +device random + +device fdt_pinctrl + +device clk +device regulator +device ext_resources + +device gpio + +device scbus +device da + +device mmc +device mmcsd + +# USB support +#options USB_DEBUG # enable debug msgs +#options USB_HOST_ALIGN=128 # L2 cache line size +#device ohci # OHCI PCI->USB interface +#device ehci # EHCI PCI->USB interface (USB 2.0) +#device dwcotg # DesignWare HS OTG controller +#device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +#device uhid # "Human Interface Devices" +#device ulpt # Printer +#device umass # Disks/Mass storage - Requires scbus and da +#device ums # Mouse Added: head/sys/mips/conf/X1000.hints ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/conf/X1000.hints Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,2 @@ +# $FreeBSD$ +# device.hints Added: head/sys/mips/ingenic/files.jz4780 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/files.jz4780 Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,26 @@ +# $FreeBSD$ + +mips/ingenic/jz4780_dwc_fdt.c optional dwcotg +mips/ingenic/jz4780_ehci.c optional ehci +mips/ingenic/jz4780_mmc.c optional mmc +mips/ingenic/jz4780_ohci.c optional ohci +mips/ingenic/jz4780_uart.c optional uart + +mips/ingenic/jz4780_clock.c standard +mips/ingenic/jz4780_clk_gen.c standard +mips/ingenic/jz4780_clk_otg.c standard +mips/ingenic/jz4780_clk_pll.c standard +mips/ingenic/jz4780_efuse.c standard +mips/ingenic/jz4780_intr.c standard +mips/ingenic/jz4780_gpio.c standard +mips/ingenic/jz4780_machdep.c standard +mips/ingenic/jz4780_nemc.c standard +mips/ingenic/jz4780_pinctrl.c standard +mips/ingenic/jz4780_timer.c standard + +# SMP +mips/ingenic/jz4780_mp.c optional smp +mips/ingenic/jz4780_mpboot.S optional smp + +# Custom interface between pinctrl and gpio +mips/ingenic/jz4780_gpio_if.m standard Added: head/sys/mips/ingenic/files.x1000 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/files.x1000 Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,17 @@ +# $FreeBSD$ + +mips/ingenic/jz4780_mmc.c optional mmc +mips/ingenic/jz4780_uart.c optional uart + +mips/ingenic/jz4780_clock.c standard +mips/ingenic/jz4780_clk_gen.c standard +mips/ingenic/jz4780_clk_otg.c standard +mips/ingenic/jz4780_clk_pll.c standard +mips/ingenic/jz4780_intr.c standard +mips/ingenic/jz4780_gpio.c standard +mips/ingenic/jz4780_machdep.c standard +mips/ingenic/jz4780_pinctrl.c standard +mips/ingenic/jz4780_timer.c standard + +# Custom interface between pinctrl and gpio +mips/ingenic/jz4780_gpio_if.m standard Added: head/sys/mips/ingenic/jz4780_clk.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/jz4780_clk.h Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,93 @@ +/*- + * Copyright 2015 Alexander Kabaev <kan@FreeBSD.org> + * All rights reserved. + * + * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +#ifndef _MIPS_INGENIC_JZ4780_CLK_H +#define _MIPS_INGENIC_JZ4780_CLK_H + +#include <dev/extres/clk/clk.h> +#include <dev/extres/clk/clk_gate.h> + +/* Convenience bitfiled manipulation macros */ +#define REG_MSK(field) (((1u << field ## _WIDTH) - 1) << field ##_SHIFT) +#define REG_VAL(field, val) ((val) << field ##_SHIFT) +#define REG_CLR(reg, field) ((reg) & ~REG_MSK(field)) +#define REG_GET(reg, field) (((reg) & REG_MSK(field)) >> field ##_SHIFT) +#define REG_SET(reg, field, val) (REG_CLR(reg, field) | REG_VAL(field, val)) + +/* Common clock macros */ +#define CLK_LOCK(_sc) mtx_lock((_sc)->clk_mtx) +#define CLK_UNLOCK(_sc) mtx_unlock((_sc)->clk_mtx) + +#define CLK_WR_4(_sc, off, val) bus_write_4((_sc)->clk_res, (off), (val)) +#define CLK_RD_4(_sc, off) bus_read_4((_sc)->clk_res, (off)) + +struct jz4780_clk_mux_descr { + uint16_t mux_reg; + uint16_t mux_shift: 5; + uint16_t mux_bits: 5; + uint16_t mux_map: 4; /* Map into mux space */ +}; + +struct jz4780_clk_div_descr { + uint16_t div_reg; + uint16_t div_shift: 5; + uint16_t div_bits: 5; + uint16_t div_lg: 5; + int div_ce_bit: 6; /* -1, if CE bit is not present */ + int div_st_bit: 6; /* Can be negative */ + int div_busy_bit: 6; /* Can be negative */ +}; + +struct jz4780_clk_descr { + uint16_t clk_id: 6; + uint16_t clk_type: 3; + int clk_gate_bit: 7; /* Can be negative */ + struct jz4780_clk_mux_descr clk_mux; + struct jz4780_clk_div_descr clk_div; + const char *clk_name; + const char *clk_pnames[4]; +}; + +/* clk_type bits */ +#define CLK_MASK_GATE 0x01 +#define CLK_MASK_DIV 0x02 +#define CLK_MASK_MUX 0x04 + +extern int jz4780_clk_gen_register(struct clkdom *clkdom, + const struct jz4780_clk_descr *descr, struct mtx *dev_mtx, + struct resource *mem_res); + +extern int jz4780_clk_pll_register(struct clkdom *clkdom, + struct clknode_init_def *clkdef, struct mtx *dev_mtx, + struct resource *mem_res, uint32_t mem_reg); + +extern int jz4780_clk_otg_register(struct clkdom *clkdom, + struct clknode_init_def *clkdef, struct mtx *dev_mtx, + struct resource *mem_res); + +#endif /* _MIPS_INGENIC_JZ4780_CLK_PLL_H */ Added: head/sys/mips/ingenic/jz4780_clk_gen.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/jz4780_clk_gen.c Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,317 @@ +/*- + * Copyright 2015 Alexander Kabaev <kan@FreeBSD.org> + * All rights reserved. + * + * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. + */ + +/* + * Ingenic JZ4780 generic CGU clock driver. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/bus.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/resource.h> + +#include <machine/bus.h> + +#include <mips/ingenic/jz4780_clk.h> +#include <mips/ingenic/jz4780_regs.h> + +/* JZ4780 generic mux and div clocks implementation */ +static int jz4780_clk_gen_init(struct clknode *clk, device_t dev); +static int jz4780_clk_gen_recalc_freq(struct clknode *clk, uint64_t *freq); +static int jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, + uint64_t *fout, int flags, int *stop); +static int jz4780_clk_gen_set_gate(struct clknode *clk, bool enable); +static int jz4780_clk_gen_set_mux(struct clknode *clk, int src); + +struct jz4780_clk_gen_sc { + struct mtx *clk_mtx; + struct resource *clk_res; + int clk_reg; + const struct jz4780_clk_descr *clk_descr; +}; + +/* + * JZ4780 clock PLL clock methods + */ +static clknode_method_t jz4780_clk_gen_methods[] = { + CLKNODEMETHOD(clknode_init, jz4780_clk_gen_init), + CLKNODEMETHOD(clknode_set_gate, jz4780_clk_gen_set_gate), + CLKNODEMETHOD(clknode_recalc_freq, jz4780_clk_gen_recalc_freq), + CLKNODEMETHOD(clknode_set_freq, jz4780_clk_gen_set_freq), + CLKNODEMETHOD(clknode_set_mux, jz4780_clk_gen_set_mux), + + CLKNODEMETHOD_END +}; +DEFINE_CLASS_1(jz4780_clk_pll, jz4780_clk_gen_class, jz4780_clk_gen_methods, + sizeof(struct jz4780_clk_gen_sc), clknode_class); + +static inline unsigned +mux_to_reg(unsigned src, unsigned map) +{ + unsigned ret, bit; + + bit = (1u << 3); + for (ret = 0; bit; ret++, bit >>= 1) { + if (map & bit) { + if (src-- == 0) + return (ret); + } + } + panic("mux_to_reg"); +} + +static inline unsigned +reg_to_mux(unsigned reg, unsigned map) +{ + unsigned ret, bit; + + bit = (1u << 3); + for (ret = 0; reg; reg--, bit >>= 1) + if (map & bit) + ret++; + return (ret); +} + +static int +jz4780_clk_gen_init(struct clknode *clk, device_t dev) +{ + struct jz4780_clk_gen_sc *sc; + uint32_t reg, msk, parent_idx; + + sc = clknode_get_softc(clk); + CLK_LOCK(sc); + /* Figure our parent out */ + if (sc->clk_descr->clk_type & CLK_MASK_MUX) { + msk = (1u << sc->clk_descr->clk_mux.mux_bits) - 1; + reg = CLK_RD_4(sc, sc->clk_descr->clk_mux.mux_reg); + reg = (reg >> sc->clk_descr->clk_mux.mux_shift) & msk; + parent_idx = reg_to_mux(reg, sc->clk_descr->clk_mux.mux_map); + } else + parent_idx = 0; + CLK_UNLOCK(sc); + + clknode_init_parent_idx(clk, parent_idx); + return (0); +} + +static int +jz4780_clk_gen_recalc_freq(struct clknode *clk, uint64_t *freq) +{ + struct jz4780_clk_gen_sc *sc; + uint32_t reg; + + sc = clknode_get_softc(clk); + + /* Calculate divisor frequency */ + if (sc->clk_descr->clk_type & CLK_MASK_DIV) { + uint32_t msk; + + msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; + reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); + reg = (reg >> sc->clk_descr->clk_div.div_shift) & msk; + reg = (reg + 1) << sc->clk_descr->clk_div.div_lg; + *freq /= reg; + } + return (0); +} + +#define DIV_TIMEOUT 100 + +static int +jz4780_clk_gen_set_freq(struct clknode *clk, uint64_t fin, + uint64_t *fout, int flags, int *stop) +{ + struct jz4780_clk_gen_sc *sc; + uint64_t _fout; + uint32_t divider, div_reg, div_msk, reg; + int rv; + + sc = clknode_get_softc(clk); + + divider = fin / *fout; + + /* Adjust for divider multiplier */ + div_reg = divider >> sc->clk_descr->clk_div.div_lg; + divider = div_reg << sc->clk_descr->clk_div.div_lg; + + _fout = fin / divider; + + /* Rounding */ + if ((flags & CLK_SET_ROUND_UP) && (*fout < _fout)) + div_reg--; + else if ((flags & CLK_SET_ROUND_DOWN) && (*fout > _fout)) + div_reg++; + if (div_reg == 0) + div_reg = 1; + + div_msk = (1u << sc->clk_descr->clk_div.div_bits) - 1; + + *stop = 1; + if (div_reg > div_msk + 1) { + *stop = 0; + div_reg = div_msk; + } + + divider = (div_reg << sc->clk_descr->clk_div.div_lg); + div_reg--; + + if ((flags & CLK_SET_DRYRUN) != 0) { + if (*stop != 0 && *fout != fin / divider && + (flags & (CLK_SET_ROUND_UP | CLK_SET_ROUND_DOWN)) == 0) + return (ERANGE); + *fout = fin / divider; + return (0); + } + + CLK_LOCK(sc); + /* Apply the new divider value */ + reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); + reg &= ~(div_msk << sc->clk_descr->clk_div.div_shift); + reg |= (div_reg << sc->clk_descr->clk_div.div_shift); + /* Set the change enable bit, it present */ + if (sc->clk_descr->clk_div.div_ce_bit >= 0) + reg |= (1u << sc->clk_descr->clk_div.div_ce_bit); + /* Clear stop bit, it present */ + if (sc->clk_descr->clk_div.div_st_bit >= 0) + reg &= ~(1u << sc->clk_descr->clk_div.div_st_bit); + /* Initiate the change */ + CLK_WR_4(sc, sc->clk_descr->clk_div.div_reg, reg); + + /* Wait for busy bit to clear indicating the change is complete */ + rv = 0; + if (sc->clk_descr->clk_div.div_busy_bit >= 0) { + int i; + + for (i = 0; i < DIV_TIMEOUT; i++) { + reg = CLK_RD_4(sc, sc->clk_descr->clk_div.div_reg); + if (!(reg & (1u << sc->clk_descr->clk_div.div_busy_bit))) + break; + DELAY(1000); + } + if (i == DIV_TIMEOUT) + rv = ETIMEDOUT; + } + CLK_UNLOCK(sc); + + *fout = fin / divider; + return (rv); +} + +static int +jz4780_clk_gen_set_mux(struct clknode *clk, int src) +{ + struct jz4780_clk_gen_sc *sc; + uint32_t reg, msk; + + sc = clknode_get_softc(clk); + + /* Only mux nodes are capable of being reparented */ + if (!(sc->clk_descr->clk_type & CLK_MASK_MUX)) + return (src ? EINVAL : 0); + + msk = (1u << sc->clk_descr->clk_mux.mux_bits) - 1; + src = mux_to_reg(src & msk, sc->clk_descr->clk_mux.mux_map); + + CLK_LOCK(sc); + reg = CLK_RD_4(sc, sc->clk_descr->clk_mux.mux_reg); + reg &= ~(msk << sc->clk_descr->clk_mux.mux_shift); + reg |= (src << sc->clk_descr->clk_mux.mux_shift); + CLK_WR_4(sc, sc->clk_descr->clk_mux.mux_reg, reg); + CLK_UNLOCK(sc); + + return (0); +} + +static int +jz4780_clk_gen_set_gate(struct clknode *clk, bool enable) +{ + struct jz4780_clk_gen_sc *sc; + uint32_t off, reg, bit; + + sc = clknode_get_softc(clk); + + /* Check is clock can be gated */ + if (sc->clk_descr->clk_gate_bit < 0) + return 0; + + bit = sc->clk_descr->clk_gate_bit; + if (bit < 32) { + off = JZ_CLKGR0; + } else { + off = JZ_CLKGR1; + bit -= 32; + } + + CLK_LOCK(sc); + reg = CLK_RD_4(sc, off); + if (enable) + reg &= ~(1u << bit); + else + reg |= (1u << bit); + CLK_WR_4(sc, off, reg); + CLK_UNLOCK(sc); + + return (0); +} + + +int jz4780_clk_gen_register(struct clkdom *clkdom, + const struct jz4780_clk_descr *descr, struct mtx *dev_mtx, + struct resource *mem_res) +{ + struct clknode_init_def clkdef; + struct clknode *clk; + struct jz4780_clk_gen_sc *sc; + + clkdef.id = descr->clk_id; + clkdef.name = __DECONST(char *, descr->clk_name); + /* Silly const games to work around API deficiency */ + clkdef.parent_names = (const char **)(uintptr_t)&descr->clk_pnames[0]; + clkdef.flags = CLK_NODE_STATIC_STRINGS; + if (descr->clk_type & CLK_MASK_MUX) + clkdef.parent_cnt = __bitcount16(descr->clk_mux.mux_map); + else + clkdef.parent_cnt = 1; + + clk = clknode_create(clkdom, &jz4780_clk_gen_class, &clkdef); + if (clk == NULL) + return (1); + + sc = clknode_get_softc(clk); + sc->clk_mtx = dev_mtx; + sc->clk_res = mem_res; + sc->clk_descr = descr; + clknode_register(clkdom, clk); + + return (0); +} Added: head/sys/mips/ingenic/jz4780_clk_otg.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/jz4780_clk_otg.c Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,167 @@ +/*- + * Copyright 2015 Alexander Kabaev <kan@FreeBSD.org> + * All rights reserved. + * + * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. + */ + +/* + * Ingenic JZ4780 OTG PHY clock driver. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/bus.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/resource.h> + +#include <machine/bus.h> + +#include <mips/ingenic/jz4780_clk.h> +#include <mips/ingenic/jz4780_regs.h> + +/* JZ4780 OTG PHY clock */ +static int jz4780_clk_otg_init(struct clknode *clk, device_t dev); +static int jz4780_clk_otg_recalc_freq(struct clknode *clk, uint64_t *freq); +static int jz4780_clk_otg_set_freq(struct clknode *clk, uint64_t fin, + uint64_t *fout, int flags, int *stop); + +struct jz4780_clk_otg_sc { + struct mtx *clk_mtx; + struct resource *clk_res; +}; + +/* + * JZ4780 OTG PHY clock methods + */ +static clknode_method_t jz4780_clk_otg_methods[] = { + CLKNODEMETHOD(clknode_init, jz4780_clk_otg_init), + CLKNODEMETHOD(clknode_recalc_freq, jz4780_clk_otg_recalc_freq), + CLKNODEMETHOD(clknode_set_freq, jz4780_clk_otg_set_freq), + + CLKNODEMETHOD_END +}; +DEFINE_CLASS_1(jz4780_clk_pll, jz4780_clk_otg_class, jz4780_clk_otg_methods, + sizeof(struct jz4780_clk_otg_sc), clknode_class); + +static int +jz4780_clk_otg_init(struct clknode *clk, device_t dev) +{ + struct jz4780_clk_otg_sc *sc; + uint32_t reg; + + sc = clknode_get_softc(clk); + CLK_LOCK(sc); + /* Force the use fo the core clock */ + reg = CLK_RD_4(sc, JZ_USBPCR1); + reg &= ~PCR_REFCLK_M; + reg |= PCR_REFCLK_CORE; + CLK_WR_4(sc, JZ_USBPCR1, reg); + CLK_UNLOCK(sc); + + clknode_init_parent_idx(clk, 0); + return (0); +} + +static const struct { + uint32_t div_val; + uint32_t freq; +} otg_div_table[] = { + { PCR_CLK_12, 12000000 }, + { PCR_CLK_192, 19200000 }, + { PCR_CLK_24, 24000000 }, + { PCR_CLK_48, 48000000 } +}; + +static int +jz4780_clk_otg_recalc_freq(struct clknode *clk, uint64_t *freq) +{ + struct jz4780_clk_otg_sc *sc; + uint32_t reg; + int i; + + sc = clknode_get_softc(clk); + reg = CLK_RD_4(sc, JZ_USBPCR1); + reg &= PCR_CLK_M; + + for (i = 0; i < nitems(otg_div_table); i++) + if (otg_div_table[i].div_val == reg) + *freq = otg_div_table[i].freq; + return (0); +} + +static int +jz4780_clk_otg_set_freq(struct clknode *clk, uint64_t fin, + uint64_t *fout, int flags, int *stop) +{ + struct jz4780_clk_otg_sc *sc; + uint32_t reg; + int i; + + sc = clknode_get_softc(clk); + + for (i = 0; i < nitems(otg_div_table) - 1; i++) { + if (*fout < (otg_div_table[i].freq + otg_div_table[i + 1].freq) / 2) + break; + } + + *fout = otg_div_table[i].freq; + + *stop = 1; + if (flags & CLK_SET_DRYRUN) + return (0); + + CLK_LOCK(sc); + reg = CLK_RD_4(sc, JZ_USBPCR1); + /* Set the calculated values */ + reg &= ~PCR_CLK_M; + reg |= otg_div_table[i].div_val; + /* Initiate the change */ + CLK_WR_4(sc, JZ_USBPCR1, reg); + CLK_UNLOCK(sc); + + return (0); +} + +int jz4780_clk_otg_register(struct clkdom *clkdom, + struct clknode_init_def *clkdef, struct mtx *dev_mtx, + struct resource *mem_res) +{ + struct clknode *clk; + struct jz4780_clk_otg_sc *sc; + + clk = clknode_create(clkdom, &jz4780_clk_otg_class, clkdef); + if (clk == NULL) + return (1); + + sc = clknode_get_softc(clk); + sc->clk_mtx = dev_mtx; + sc->clk_res = mem_res; + clknode_register(clkdom, clk); + return (0); +} Added: head/sys/mips/ingenic/jz4780_clk_pll.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/mips/ingenic/jz4780_clk_pll.c Sat Nov 19 17:46:18 2016 (r308857) @@ -0,0 +1,234 @@ +/*- + * Copyright 2015 Alexander Kabaev <kan@FreeBSD.org> + * All rights reserved. + * + * 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 THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611191746.uAJHkJQ8095246>