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 <k...@freebsd.org>
  Reviewed by:  Ruslan Bukin <b...@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 <k...@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 <k...@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 <k...@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 <k...@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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to