From owner-svn-src-all@FreeBSD.ORG Tue Mar 31 11:50:49 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 188E0193; Tue, 31 Mar 2015 11:50:49 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0096967E; Tue, 31 Mar 2015 11:50:49 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2VBomoR045478; Tue, 31 Mar 2015 11:50:48 GMT (envelope-from ganbold@FreeBSD.org) Received: (from ganbold@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2VBolGm044903; Tue, 31 Mar 2015 11:50:47 GMT (envelope-from ganbold@FreeBSD.org) Message-Id: <201503311150.t2VBolGm044903@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ganbold set sender to ganbold@FreeBSD.org using -f From: Ganbold Tsagaankhuu Date: Tue, 31 Mar 2015 11:50:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280905 - in head/sys: arm/amlogic arm/amlogic/aml8726 arm/arm conf dev/mmc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Mar 2015 11:50:49 -0000 Author: ganbold Date: Tue Mar 31 11:50:46 2015 New Revision: 280905 URL: https://svnweb.freebsd.org/changeset/base/280905 Log: Add necessary changes to support various Amlogic SoC devices specially aml8726-m6 and aml8726-m8b SoC based devices. aml8726-m6 SoC exist in devices such as Visson ATV-102. Hardkernel ODROID-C1 board has aml8726-m8b SoC. The following support is included: Basic machdep code SMP Interrupt controller Clock control driver (aka gate) Pinctrl Timer Real time clock UART GPIO I2C SD controller SDXC controller USB Watchdog Random number generator PLL / Clock frequency measurement Frame buffer Submitted by: John Wehle Approved by: stas (mentor) Added: head/sys/arm/amlogic/ head/sys/arm/amlogic/aml8726/ head/sys/arm/amlogic/aml8726/aml8726_ccm.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_ccm.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_clkmsr.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_clkmsr.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_fb.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_fb.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_gpio.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_i2c.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_identsoc.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_l2cache.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_machdep.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_machdep.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_mmc.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_mmc.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_mp.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_pic.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_pinctrl.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_pinctrl.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_rng.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_rtc.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_soc.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_timer.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_uart.h (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_uart_console.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_usb_phy-m6.c (contents, props changed) head/sys/arm/amlogic/aml8726/aml8726_wdt.c (contents, props changed) head/sys/arm/amlogic/aml8726/files.aml8726 (contents, props changed) head/sys/arm/amlogic/aml8726/files.smp (contents, props changed) head/sys/arm/amlogic/aml8726/std.aml8726 (contents, props changed) head/sys/arm/amlogic/aml8726/std.odroidc1 (contents, props changed) head/sys/arm/amlogic/aml8726/std.vsatv102-m6 (contents, props changed) head/sys/arm/amlogic/aml8726/uart_dev_aml8726.c (contents, props changed) Modified: head/sys/arm/arm/gic.c head/sys/conf/options.arm head/sys/dev/mmc/mmc.c Added: head/sys/arm/amlogic/aml8726/aml8726_ccm.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/amlogic/aml8726/aml8726_ccm.c Tue Mar 31 11:50:46 2015 (r280905) @@ -0,0 +1,231 @@ +/*- + * Copyright 2015 John Wehle + * 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. + */ + +/* + * Amlogic aml8726 clock control module driver. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + + +struct aml8726_ccm_softc { + device_t dev; + struct aml8726_ccm_function *soc; + struct resource *res[1]; + struct mtx mtx; +}; + +static struct resource_spec aml8726_ccm_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +#define AML_CCM_LOCK(sc) mtx_lock(&(sc)->mtx) +#define AML_CCM_UNLOCK(sc) mtx_unlock(&(sc)->mtx) +#define AML_CCM_LOCK_INIT(sc) \ + mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ + "ccm", MTX_DEF) +#define AML_CCM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); + +#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) +#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) + +static int +aml8726_ccm_configure_gates(struct aml8726_ccm_softc *sc) +{ + struct aml8726_ccm_function *f; + struct aml8726_ccm_gate *g; + char *function_name; + char *functions; + phandle_t node; + ssize_t len; + uint32_t value; + + node = ofw_bus_get_node(sc->dev); + + len = OF_getprop_alloc(node, "functions", sizeof(char), + (void **)&functions); + + if (len < 0) { + device_printf(sc->dev, "missing functions attribute in FDT\n"); + return (ENXIO); + } + + function_name = functions; + + while (len) { + for (f = sc->soc; f->name != NULL; f++) + if (strncmp(f->name, function_name, len) == 0) + break; + + if (f->name == NULL) { + /* display message prior to queuing up next string */ + device_printf(sc->dev, + "unknown function attribute %.*s in FDT\n", + len, function_name); + } + + /* queue up next string */ + while (*function_name && len) { + function_name++; + len--; + } + if (len) { + function_name++; + len--; + } + + if (f->name == NULL) + continue; + + AML_CCM_LOCK(sc); + + /* + * Enable the clock gates necessary for the function. + * + * In some cases a clock may be shared across functions + * (meaning don't disable a clock without ensuring that + * it's not required by someone else). + */ + for (g = f->gates; g->bits != 0x00000000; g++) { + value = CSR_READ_4(sc, g->addr); + value |= g->bits; + CSR_WRITE_4(sc, g->addr, value); + } + + AML_CCM_UNLOCK(sc); + } + + free(functions, M_OFWPROP); + + return (0); +} + +static int +aml8726_ccm_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-ccm")) + return (ENXIO); + + device_set_desc(dev, "Amlogic aml8726 ccm"); + + return (BUS_PROBE_DEFAULT); +} + +static int +aml8726_ccm_attach(device_t dev) +{ + struct aml8726_ccm_softc *sc = device_get_softc(dev); + + sc->dev = dev; + + switch (aml8726_soc_hw_rev) { + case AML_SOC_HW_REV_M3: + sc->soc = aml8726_m3_ccm; + break; + case AML_SOC_HW_REV_M6: + sc->soc = aml8726_m6_ccm; + break; + case AML_SOC_HW_REV_M8: + sc->soc = aml8726_m8_ccm; + break; + case AML_SOC_HW_REV_M8B: + sc->soc = aml8726_m8b_ccm; + break; + default: + device_printf(dev, "unsupported SoC\n"); + return (ENXIO); + /* NOTREACHED */ + break; + } + + if (bus_alloc_resources(dev, aml8726_ccm_spec, sc->res)) { + device_printf(dev, "can not allocate resources for device\n"); + return (ENXIO); + } + + AML_CCM_LOCK_INIT(sc); + + return (aml8726_ccm_configure_gates(sc)); +} + +static int +aml8726_ccm_detach(device_t dev) +{ + struct aml8726_ccm_softc *sc = device_get_softc(dev); + + AML_CCM_LOCK_DESTROY(sc); + + bus_release_resources(dev, aml8726_ccm_spec, sc->res); + + return (0); +} + +static device_method_t aml8726_ccm_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, aml8726_ccm_probe), + DEVMETHOD(device_attach, aml8726_ccm_attach), + DEVMETHOD(device_detach, aml8726_ccm_detach), + + DEVMETHOD_END +}; + +static driver_t aml8726_ccm_driver = { + "ccm", + aml8726_ccm_methods, + sizeof(struct aml8726_ccm_softc), +}; + +static devclass_t aml8726_ccm_devclass; + +EARLY_DRIVER_MODULE(ccm, simplebus, aml8726_ccm_driver, + aml8726_ccm_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE); Added: head/sys/arm/amlogic/aml8726/aml8726_ccm.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/amlogic/aml8726/aml8726_ccm.h Tue Mar 31 11:50:46 2015 (r280905) @@ -0,0 +1,325 @@ +/*- + * Copyright 2015 John Wehle + * 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 _ARM_AMLOGIC_AML8726_CCM_H +#define _ARM_AMLOGIC_AML8726_CCM_H + + +struct aml8726_ccm_gate { + uint32_t addr; + uint32_t bits; +}; + +struct aml8726_ccm_function { + const char *name; + struct aml8726_ccm_gate *gates; +}; + + +/* + * aml8726-m3 + */ + +static struct aml8726_ccm_gate aml8726_m3_ethernet[] = { + { 4, 0x00000008 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_i2c[] = { + { 0, 0x00000200 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_rng[] = { + { 0, 0x00001000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_sdio[] = { + { 0, 0x00020000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_sdxc[] = { + { 0, 0x00004000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_uart_a[] = { + { 0, 0x00002000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_uart_b[] = { + { 4, 0x00010000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_uart_c[] = { + { 8, 0x00008000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_usb_a[] = { + { 4, 0x00200000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m3_usb_b[] = { + { 4, 0x00400000 }, + { 0, 0x00000000 } +}; + +struct aml8726_ccm_function aml8726_m3_ccm[] = { + { "ethernet", aml8726_m3_ethernet }, + { "i2c", aml8726_m3_i2c }, + { "rng", aml8726_m3_rng }, + { "sdio", aml8726_m3_sdio }, + { "sdxc", aml8726_m3_sdxc }, + { "uart-a", aml8726_m3_uart_a }, + { "uart-b", aml8726_m3_uart_b }, + { "uart-c", aml8726_m3_uart_c }, + { "usb-a", aml8726_m3_usb_a }, + { "usb-b", aml8726_m3_usb_b }, + { NULL } +}; + + +/* + * aml8726-m6 + */ + +static struct aml8726_ccm_gate aml8726_m6_ethernet[] = { + { 4, 0x00000008 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_i2c[] = { + { 0, 0x00000200 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_rng[] = { + { 0, 0x00001000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_sdio[] = { + { 0, 0x00020000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_sdxc[] = { + { 0, 0x00004000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_uart_a[] = { + { 0, 0x00002000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_uart_b[] = { + { 4, 0x00010000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_uart_c[] = { + { 8, 0x00008000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_usb_a[] = { + { 4, 0x00200000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m6_usb_b[] = { + { 4, 0x00400000 }, + { 0, 0x00000000 } +}; + +struct aml8726_ccm_function aml8726_m6_ccm[] = { + { "ethernet", aml8726_m6_ethernet }, + { "i2c", aml8726_m6_i2c }, + { "rng", aml8726_m6_rng }, + { "sdio", aml8726_m6_sdio }, + { "sdxc", aml8726_m6_sdxc }, + { "uart-a", aml8726_m6_uart_a }, + { "uart-b", aml8726_m6_uart_b }, + { "uart-c", aml8726_m6_uart_c }, + { "usb-a", aml8726_m6_usb_a }, + { "usb-b", aml8726_m6_usb_b }, + { NULL } +}; + + +/* + * aml8726-m8 + */ + +static struct aml8726_ccm_gate aml8726_m8_ethernet[] = { + { 4, 0x00000008 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_i2c[] = { + { 0, 0x00000200 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_rng[] = { + { 0, 0x00001000 }, + { 16, 0x00200000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_sdio[] = { + { 0, 0x00020000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_sdxc[] = { + { 0, 0x00004000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_uart_a[] = { + { 0, 0x00002000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_uart_b[] = { + { 4, 0x00010000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_uart_c[] = { + { 8, 0x00008000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_usb_a[] = { + { 4, 0x00200000 }, + { 4, 0x04000000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8_usb_b[] = { + { 4, 0x00400000 }, + { 4, 0x04000000 }, + { 0, 0x00000000 } +}; + +struct aml8726_ccm_function aml8726_m8_ccm[] = { + { "ethernet", aml8726_m8_ethernet }, + { "i2c", aml8726_m8_i2c }, + { "rng", aml8726_m8_rng }, + { "sdio", aml8726_m8_sdio }, + { "sdxc", aml8726_m8_sdxc }, + { "uart-a", aml8726_m8_uart_a }, + { "uart-b", aml8726_m8_uart_b }, + { "uart-c", aml8726_m8_uart_c }, + { "usb-a", aml8726_m8_usb_a }, + { "usb-b", aml8726_m8_usb_b }, + { NULL } +}; + + +/* + * aml8726-m8b + */ + +static struct aml8726_ccm_gate aml8726_m8b_ethernet[] = { + { 4, 0x00000008 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_i2c[] = { + { 0, 0x00000200 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_rng[] = { + { 0, 0x00001000 }, + { 16, 0x00200000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_sdio[] = { + { 0, 0x00020000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_sdxc[] = { + { 0, 0x00004000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_uart_a[] = { + { 0, 0x00002000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_uart_b[] = { + { 4, 0x00010000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_uart_c[] = { + { 8, 0x00008000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_usb_a[] = { + { 4, 0x00200000 }, + { 4, 0x04000000 }, + { 0, 0x00000000 } +}; + +static struct aml8726_ccm_gate aml8726_m8b_usb_b[] = { + { 4, 0x00400000 }, + { 4, 0x04000000 }, + { 0, 0x00000000 } +}; + +struct aml8726_ccm_function aml8726_m8b_ccm[] = { + { "ethernet", aml8726_m8b_ethernet }, + { "i2c", aml8726_m8b_i2c }, + { "rng", aml8726_m8b_rng }, + { "sdio", aml8726_m8b_sdio }, + { "sdxc", aml8726_m8b_sdxc }, + { "uart-a", aml8726_m8b_uart_a }, + { "uart-b", aml8726_m8b_uart_b }, + { "uart-c", aml8726_m8b_uart_c }, + { "usb-a", aml8726_m8b_usb_a }, + { "usb-b", aml8726_m8b_usb_b }, + { NULL } +}; + +#endif /* _ARM_AMLOGIC_AML8726_CCM_H */ Added: head/sys/arm/amlogic/aml8726/aml8726_clkmsr.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/amlogic/aml8726/aml8726_clkmsr.c Tue Mar 31 11:50:46 2015 (r280905) @@ -0,0 +1,271 @@ +/*- + * Copyright 2014-2015 John Wehle + * 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. + * + */ + +/* + * Amlogic aml8726 clock measurement driver. + * + * This allows various clock rates to be determine at runtime. + * The measurements are done once and are not expected to change + * (i.e. FDT fixup provides clk81 as bus-frequency to the MMC + * and UART drivers which use the value when programming the + * hardware). + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + + +static struct aml8726_clkmsr_clk { + const char * name; + uint32_t mux; +} aml8726_clkmsr_clks[] = { + { "clk81", 7 }, +}; + +#define AML_CLKMSR_CLK81 0 + +#define AML_CLKMSR_NCLKS (sizeof(aml8726_clkmsr_clks) \ + / sizeof(aml8726_clkmsr_clks[0])) + +struct aml8726_clkmsr_softc { + device_t dev; + struct resource * res[1]; +}; + +static struct resource_spec aml8726_clkmsr_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +/* + * Duration can range from 1uS to 65535 uS and should be chosen + * based on the expected frequency result so to maximize resolution + * and avoid overflowing the 16 bit result counter. + */ +#define AML_CLKMSR_DURATION 32 + +#define AML_CLKMSR_DUTY_REG 0 +#define AML_CLKMSR_0_REG 4 +#define AML_CLKMSR_0_BUSY (1U << 31) +#define AML_CLKMSR_0_MUX_MASK (0x3f << 20) +#define AML_CLKMSR_0_MUX_SHIFT 20 +#define AML_CLKMSR_0_MUX_EN (1 << 19) +#define AML_CLKMSR_0_MEASURE (1 << 16) +#define AML_CLKMSR_0_DURATION_MASK 0xffff +#define AML_CLKMSR_0_DURATION_SHIFT 0 +#define AML_CLKMSR_1_REG 8 +#define AML_CLKMSR_2_REG 12 +#define AML_CLKMSR_2_RESULT_MASK 0xffff +#define AML_CLKMSR_2_RESULT_SHIFT 0 + +#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) +#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) +#define CSR_BARRIER(sc, reg) bus_barrier((sc)->res[0], reg, 4, \ + (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)) + +static int +aml8726_clkmsr_clock_frequency(struct aml8726_clkmsr_softc *sc, unsigned clock) +{ + uint32_t value; + + if (clock >= AML_CLKMSR_NCLKS) + return (0); + + /* + * Locking is not used as this is only expected to be called from + * FDT fixup (which occurs prior to driver initialization) or attach. + */ + + CSR_WRITE_4(sc, AML_CLKMSR_0_REG, 0); + + CSR_BARRIER(sc, AML_CLKMSR_0_REG); + + value = (aml8726_clkmsr_clks[clock].mux << AML_CLKMSR_0_MUX_SHIFT) + | ((AML_CLKMSR_DURATION - 1) << AML_CLKMSR_0_DURATION_SHIFT) + | AML_CLKMSR_0_MUX_EN + | AML_CLKMSR_0_MEASURE; + CSR_WRITE_4(sc, AML_CLKMSR_0_REG, value); + + CSR_BARRIER(sc, AML_CLKMSR_0_REG); + + while ((CSR_READ_4(sc, AML_CLKMSR_0_REG) & AML_CLKMSR_0_BUSY) != 0) + cpu_spinwait(); + + value &= ~AML_CLKMSR_0_MEASURE; + CSR_WRITE_4(sc, AML_CLKMSR_0_REG, value); + + CSR_BARRIER(sc, AML_CLKMSR_0_REG); + + value = (((CSR_READ_4(sc, AML_CLKMSR_2_REG) & AML_CLKMSR_2_RESULT_MASK) + >> AML_CLKMSR_2_RESULT_SHIFT) + AML_CLKMSR_DURATION / 2) / + AML_CLKMSR_DURATION; + + return value; +} + +static int +aml8726_clkmsr_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-clkmsr")) + return (ENXIO); + + device_set_desc(dev, "Amlogic aml8726 clkmsr"); + + return (BUS_PROBE_DEFAULT); +} + +static int +aml8726_clkmsr_attach(device_t dev) +{ + struct aml8726_clkmsr_softc *sc = device_get_softc(dev); + int freq; + + sc->dev = dev; + + if (bus_alloc_resources(dev, aml8726_clkmsr_spec, sc->res)) { + device_printf(dev, "can not allocate resources for device\n"); + return (ENXIO); + } + + freq = aml8726_clkmsr_clock_frequency(sc, AML_CLKMSR_CLK81); + device_printf(sc->dev, "bus clock %u MHz\n", freq); + + return (0); +} + +static int +aml8726_clkmsr_detach(device_t dev) +{ + struct aml8726_clkmsr_softc *sc = device_get_softc(dev); + + bus_release_resources(dev, aml8726_clkmsr_spec, sc->res); + + return (0); +} + + +static device_method_t aml8726_clkmsr_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, aml8726_clkmsr_probe), + DEVMETHOD(device_attach, aml8726_clkmsr_attach), + DEVMETHOD(device_detach, aml8726_clkmsr_detach), + + DEVMETHOD_END +}; + +static driver_t aml8726_clkmsr_driver = { + "clkmsr", + aml8726_clkmsr_methods, + sizeof(struct aml8726_clkmsr_softc), +}; + +static devclass_t aml8726_clkmsr_devclass; + +DRIVER_MODULE(clkmsr, simplebus, aml8726_clkmsr_driver, + aml8726_clkmsr_devclass, 0, 0); + +int +aml8726_clkmsr_bus_frequency() +{ + struct resource mem; + struct aml8726_clkmsr_softc sc; + phandle_t node; + u_long pbase, psize; + u_long start, size; + int freq; + + /* + * Try to access the clkmsr node directly i.e. through /aliases/. + */ + + if ((node = OF_finddevice("clkmsr")) != 0) + if (fdt_is_compatible_strict(node, "amlogic,aml8726-clkmsr")) + goto moveon; + + /* + * Find the node the long way. + */ + if ((node = OF_finddevice("/soc")) == 0) + return (0); + + if ((node = fdt_find_compatible(node, + "amlogic,aml8726-clkmsr", 1)) == 0) + return (0); + +moveon: + if (fdt_get_range(OF_parent(node), 0, &pbase, &psize) != 0 + || fdt_regsize(node, &start, &size) != 0) + return (0); + + start += pbase; + + memset(&mem, 0, sizeof(mem)); + + mem.r_bustag = fdtbus_bs_tag; + + if (bus_space_map(mem.r_bustag, start, size, 0, &mem.r_bushandle) != 0) + return (0); + + /* + * Build an incomplete (however sufficient for the purpose + * of calling aml8726_clkmsr_clock_frequency) softc. + */ + + memset(&sc, 0, sizeof(sc)); + + sc.res[0] = &mem; + + freq = aml8726_clkmsr_clock_frequency(&sc, AML_CLKMSR_CLK81) * 1000000; + + bus_space_unmap(mem.r_bustag, mem.r_bushandle, size); + + return (freq); +} Added: head/sys/arm/amlogic/aml8726/aml8726_clkmsr.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/amlogic/aml8726/aml8726_clkmsr.h Tue Mar 31 11:50:46 2015 (r280905) @@ -0,0 +1,34 @@ +/*- + * Copyright 2014 John Wehle + * 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 _ARM_AMLOGIC_AML8726_CLKMSR_H +#define _ARM_AMLOGIC_AML8726_CLKMSR_H + +int aml8726_clkmsr_bus_frequency(void); + +#endif /* _ARM_AMLOGIC_AML8726_CLKMSR_H */ Added: head/sys/arm/amlogic/aml8726/aml8726_fb.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/amlogic/aml8726/aml8726_fb.c Tue Mar 31 11:50:46 2015 (r280905) @@ -0,0 +1,468 @@ +/*- + * Copyright 2013-2014 John Wehle + * 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. + */ + +/* + * Amlogic aml8726 frame buffer driver. + * + * The current implementation has limited flexibility. + * For example only progressive scan is supported when + * using HDMI and the resolution / frame rate is not + * negotiated. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "fb_if.h" + + +enum aml8726_fb_output { + aml8726_unknown_fb_output, + aml8726_cvbs_fb_output, + aml8726_hdmi_fb_output, + aml8726_lcd_fb_output +}; + +struct aml8726_fb_clk { + uint32_t freq; + uint32_t video_pre; + uint32_t video_post; + uint32_t video_x; + uint32_t hdmi_tx; + uint32_t encp; + uint32_t enci; + uint32_t enct; + uint32_t encl; + uint32_t vdac0; + uint32_t vdac1; +}; + +struct aml8726_fb_softc { + device_t dev; + struct resource *res[4]; + struct mtx mtx; + void *ih_cookie; + struct fb_info info; + enum aml8726_fb_output output; + struct aml8726_fb_clk clk; +}; + +static struct resource_spec aml8726_fb_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* CANVAS */ + { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* VIU */ + { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* VPP */ + { SYS_RES_IRQ, 1, RF_ACTIVE }, /* INT_VIU_VSYNC */ + { -1, 0 } +}; + +#define AML_FB_LOCK(sc) mtx_lock(&(sc)->mtx) +#define AML_FB_UNLOCK(sc) mtx_unlock(&(sc)->mtx) +#define AML_FB_LOCK_INIT(sc) \ + mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ + "fb", MTX_DEF) +#define AML_FB_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); + +#define CAV_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) +#define CAV_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) +#define CAV_BARRIER(sc, reg) bus_barrier((sc)->res[0], reg, 4, \ + (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)) + +#define VIU_WRITE_4(sc, reg, val) bus_write_4((sc)->res[1], reg, (val)) +#define VIU_READ_4(sc, reg) bus_read_4((sc)->res[1], reg) + +#define VPP_WRITE_4(sc, reg, val) bus_write_4((sc)->res[2], reg, (val)) +#define VPP_READ_4(sc, reg) bus_read_4((sc)->res[2], reg) + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***