[Midnightbsd-cvs] src [12395] trunk/sys/arm/samsung/exynos: sync with freebsd 11

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Mar 6 12:05:09 EST 2020


Revision: 12395
          http://svnweb.midnightbsd.org/src/?rev=12395
Author:   laffer1
Date:     2020-03-06 12:05:09 -0500 (Fri, 06 Mar 2020)
Log Message:
-----------
sync with freebsd 11

Modified Paths:
--------------
    trunk/sys/arm/samsung/exynos/chrome_ec.c
    trunk/sys/arm/samsung/exynos/chrome_ec.h
    trunk/sys/arm/samsung/exynos/chrome_kb.c
    trunk/sys/arm/samsung/exynos/chrome_kb.h
    trunk/sys/arm/samsung/exynos/exynos5_combiner.c
    trunk/sys/arm/samsung/exynos/exynos5_combiner.h
    trunk/sys/arm/samsung/exynos/exynos5_common.c
    trunk/sys/arm/samsung/exynos/exynos5_common.h
    trunk/sys/arm/samsung/exynos/exynos5_ehci.c
    trunk/sys/arm/samsung/exynos/exynos5_fimd.c
    trunk/sys/arm/samsung/exynos/exynos5_i2c.c
    trunk/sys/arm/samsung/exynos/exynos5_machdep.c
    trunk/sys/arm/samsung/exynos/exynos5_mct.c
    trunk/sys/arm/samsung/exynos/exynos5_mp.c
    trunk/sys/arm/samsung/exynos/exynos5_pad.c
    trunk/sys/arm/samsung/exynos/exynos5_pad.h
    trunk/sys/arm/samsung/exynos/exynos_uart.c
    trunk/sys/arm/samsung/exynos/exynos_uart.h
    trunk/sys/arm/samsung/exynos/files.exynos5
    trunk/sys/arm/samsung/exynos/std.exynos5250
    trunk/sys/arm/samsung/exynos/std.exynos5420

Added Paths:
-----------
    trunk/sys/arm/samsung/exynos/chrome_ec_spi.c
    trunk/sys/arm/samsung/exynos/exynos5_pmu.c
    trunk/sys/arm/samsung/exynos/exynos5_pmu.h
    trunk/sys/arm/samsung/exynos/exynos5_spi.c
    trunk/sys/arm/samsung/exynos/exynos5_usb_phy.c
    trunk/sys/arm/samsung/exynos/exynos5_xhci.c

Modified: trunk/sys/arm/samsung/exynos/chrome_ec.c
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_ec.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/chrome_ec.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_ec.c 266341 2014-05-17 19:37:04Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/chrome_ec.c 297793 2016-04-10 23:07:00Z pfg $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -44,13 +44,11 @@
 #include <sys/watchdog.h>
 #include <sys/gpio.h>
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
@@ -61,12 +59,11 @@
 
 #include <arm/samsung/exynos/chrome_ec.h>
 
-/* TODO: export to DTS */
-#define OUR_GPIO	177
-#define EC_GPIO		168
-
 struct ec_softc {
 	device_t	dev;
+	int		have_arbitrator;
+	pcell_t		our_gpio;
+	pcell_t		ec_gpio;
 };
 
 struct ec_softc *ec_sc;
@@ -83,17 +80,24 @@
 	device_t gpio_dev;
 	int status;
 
+	if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
+		device_printf(sc->dev, "i2c arbitrator is not configured\n");
+		return (1);
+	}
+
 	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
-        if (gpio_dev == NULL) {
+	if (gpio_dev == NULL) {
 		device_printf(sc->dev, "cant find gpio_dev\n");
 		return (1);
 	}
 
 	/* Say we want the bus */
-	GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_LOW);
+	GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_LOW);
 
+	/* TODO: insert a delay to allow EC to react. */
+
 	/* Check EC decision */
-	GPIO_PIN_GET(gpio_dev, EC_GPIO, &status);
+	GPIO_PIN_GET(gpio_dev, sc->ec_gpio, &status);
 
 	if (status == 1) {
 		/* Okay. We have bus */
@@ -109,13 +113,18 @@
 {
 	device_t gpio_dev;
 
+	if (sc->our_gpio == 0 || sc->ec_gpio == 0) {
+		device_printf(sc->dev, "i2c arbitrator is not configured\n");
+		return (1);
+	}
+
 	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
-        if (gpio_dev == NULL) {
+	if (gpio_dev == NULL) {
 		device_printf(sc->dev, "cant find gpio_dev\n");
 		return (1);
 	}
 
-	GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_HIGH);
+	GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_HIGH);
 
 	return (0);
 }
@@ -155,7 +164,7 @@
 	int i;
 
 	msg_dout = malloc(dout_len + 4, M_DEVBUF, M_NOWAIT);
-	msg_dinp = malloc(dinp_len + 4, M_DEVBUF, M_NOWAIT);
+	msg_dinp = malloc(dinp_len + 3, M_DEVBUF, M_NOWAIT);
 
 	if (ec_sc == NULL)
 		return (-1);
@@ -168,13 +177,13 @@
 
 	for (i = 0; i < dout_len; i++) {
 		msg_dout[i + 3] = dout[i];
-	};
+	}
 
 	fill_checksum(msg_dout, dout_len + 3);
 
 	struct iic_msg msgs[] = {
 		{ 0x1e, IIC_M_WR, dout_len + 4, msg_dout, },
-		{ 0x1e, IIC_M_RD, dinp_len + 4, msg_dinp, },
+		{ 0x1e, IIC_M_RD, dinp_len + 3, msg_dinp, },
 	};
 
 	ret = iicbus_transfer(sc->dev, msgs, 2);
@@ -186,8 +195,8 @@
 	}
 
 	for (i = 0; i < dinp_len; i++) {
-		dinp[i] = msg_dinp[i + 3];
-	};
+		dinp[i] = msg_dinp[i + 2];
+	}
 
 	free(msg_dout, M_DEVBUF);
 	free(msg_dinp, M_DEVBUF);
@@ -204,12 +213,34 @@
 	data_in[2] = 0x20;
 	data_in[3] = 0x10;
 
-	ec_command(EC_CMD_MKBP_STATE, data_in, 4,
+	ec_command(EC_CMD_HELLO, data_in, 4,
 	    data_out, 4);
 
 	return (0);
 }
 
+static void
+configure_i2c_arbitrator(struct ec_softc *sc)
+{
+	phandle_t arbitrator;
+
+	/* TODO: look for compatible entry instead of hard-coded path */
+	arbitrator = OF_finddevice("/i2c-arbitrator");
+	if (arbitrator > 0 &&
+	    OF_hasprop(arbitrator, "freebsd,our-gpio") &&
+	    OF_hasprop(arbitrator, "freebsd,ec-gpio")) {
+		sc->have_arbitrator = 1;
+		OF_getencprop(arbitrator, "freebsd,our-gpio",
+		    &sc->our_gpio, sizeof(sc->our_gpio));
+		OF_getencprop(arbitrator, "freebsd,ec-gpio",
+		    &sc->ec_gpio, sizeof(sc->ec_gpio));
+	} else {
+		sc->have_arbitrator = 0;
+		sc->our_gpio = 0;
+		sc->ec_gpio = 0;
+	}
+}
+
 static int
 ec_attach(device_t dev)
 {
@@ -220,6 +251,8 @@
 
 	ec_sc = sc;
 
+	configure_i2c_arbitrator(sc);
+
 	/*
 	 * Claim the bus.
 	 *
@@ -228,7 +261,7 @@
 	 *
 	 */
 
-	if (bus_claim(sc) != 0) {
+	if (sc->have_arbitrator && bus_claim(sc) != 0) {
 		return (ENXIO);
 	}
 
@@ -242,7 +275,9 @@
 
 	sc = device_get_softc(dev);
 
-	bus_release(sc);
+	if (sc->have_arbitrator) {
+		bus_release(sc);
+	}
 
 	return (0);
 }

Modified: trunk/sys/arm/samsung/exynos/chrome_ec.h
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_ec.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/chrome_ec.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_ec.h 266341 2014-05-17 19:37:04Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/chrome_ec.h 269369 2014-08-01 06:20:25Z br $
  */
 
 #define	EC_CMD_HELLO		0x01
@@ -31,6 +31,8 @@
 #define	EC_CMD_GET_VERSION	0x02
 #define	EC_CMD_MKBP_STATE	0x60
 #define	EC_CMD_VERSION0		0xdc
+#define	EC_CMD_RESEND_RESPONSE	0xdb
+#define	EC_CMD_GET_COMMS_STATUS	0x09
 
 int ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len,
     uint8_t *dinp, uint8_t dinp_len);

Added: trunk/sys/arm/samsung/exynos/chrome_ec_spi.c
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_ec_spi.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/chrome_ec_spi.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,229 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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 EXPREC OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNEC 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 BUSINEC 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.
+ */
+
+/*
+ * Samsung Chromebook Embedded Controller (EC)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/chrome_ec_spi.c 297793 2016-04-10 23:07:00Z pfg $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/gpio.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#include "spibus_if.h"
+#include "gpio_if.h"
+
+#include <arm/samsung/exynos/chrome_ec.h>
+
+struct ec_softc {
+	device_t	dev;
+	device_t	dev_gpio;
+};
+
+struct ec_softc *ec_sc;
+
+#define EC_SPI_CS	200
+
+static int
+assert_cs(struct ec_softc *sc, int enable)
+{
+	/* Get the GPIO device */
+	sc->dev_gpio = devclass_get_device(devclass_find("gpio"), 0);
+	if (sc->dev_gpio == NULL) {
+		device_printf(sc->dev, "Error: failed to get the GPIO dev\n");
+		return (1);
+	}
+
+	GPIO_PIN_SETFLAGS(sc->dev_gpio, EC_SPI_CS, GPIO_PIN_OUTPUT);
+
+	if (enable) {
+		GPIO_PIN_SET(sc->dev_gpio, EC_SPI_CS, GPIO_PIN_LOW);
+	} else {
+		GPIO_PIN_SET(sc->dev_gpio, EC_SPI_CS, GPIO_PIN_HIGH);
+	}
+
+	return (0);
+}
+
+static int
+ec_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Chromebook Embedded Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+fill_checksum(uint8_t *data_out, int len)
+{
+	int res;
+	int i;
+
+	res = 0;
+	for (i = 0; i < len; i++) {
+		res += data_out[i];
+	}
+
+	data_out[len] = (res & 0xff);
+
+	return (0);
+}
+
+int
+ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len,
+    uint8_t *dinp, uint8_t dinp_len)
+{
+	struct spi_command spi_cmd;
+	struct ec_softc *sc;
+	uint8_t *msg_dout;
+	uint8_t *msg_dinp;
+	int ret;
+	int i;
+
+	memset(&spi_cmd, 0, sizeof(spi_cmd));
+
+	msg_dout = malloc(dout_len + 4, M_DEVBUF, M_NOWAIT | M_ZERO);
+	msg_dinp = malloc(dinp_len + 4, M_DEVBUF, M_NOWAIT | M_ZERO);
+
+	spi_cmd.tx_cmd = msg_dout;
+	spi_cmd.rx_cmd = msg_dinp;
+
+	if (ec_sc == NULL)
+		return (-1);
+
+	sc = ec_sc;
+
+	msg_dout[0] = EC_CMD_VERSION0;
+	msg_dout[1] = cmd;
+	msg_dout[2] = dout_len;
+
+	for (i = 0; i < dout_len; i++) {
+		msg_dout[i + 3] = dout[i];
+	}
+
+	fill_checksum(msg_dout, dout_len + 3);
+
+	assert_cs(sc, 1);
+	spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4;
+	ret = SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd);
+
+	/* Wait 0xec */
+	for (i = 0; i < 1000; i++) {
+		DELAY(10);
+		msg_dout[0] = 0xff;
+		spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = 1;
+		SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd);
+		if (msg_dinp[0] == 0xec)
+			break;
+	}
+
+	/* Get the rest */
+	for (i = 0; i < (dout_len + 4); i++)
+		msg_dout[i] = 0xff;
+	spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4 - 1;
+	ret = SPIBUS_TRANSFER(device_get_parent(sc->dev), sc->dev, &spi_cmd);
+	assert_cs(sc, 0);
+
+	if (ret != 0) {
+		device_printf(sc->dev, "spibus_transfer returned %d\n", ret);
+		free(msg_dout, M_DEVBUF);
+		free(msg_dinp, M_DEVBUF);
+		return (-1);
+	}
+
+	for (i = 0; i < dinp_len; i++) {
+		dinp[i] = msg_dinp[i + 2];
+	}
+
+	free(msg_dout, M_DEVBUF);
+	free(msg_dinp, M_DEVBUF);
+
+	return (0);
+}
+
+static int
+ec_attach(device_t dev)
+{
+	struct ec_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	ec_sc = sc;
+
+	return (0);
+}
+
+static int
+ec_detach(device_t dev)
+{
+	struct ec_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	return (0);
+}
+
+static device_method_t ec_methods[] = {
+	DEVMETHOD(device_probe,		ec_probe),
+	DEVMETHOD(device_attach,	ec_attach),
+	DEVMETHOD(device_detach,	ec_detach),
+	{ 0, 0 }
+};
+
+static driver_t ec_driver = {
+	"chrome_ec",
+	ec_methods,
+	sizeof(struct ec_softc),
+};
+
+static devclass_t ec_devclass;
+
+DRIVER_MODULE(chrome_ec, spibus, ec_driver, ec_devclass, 0, 0);
+MODULE_VERSION(chrome_ec, 1);
+MODULE_DEPEND(chrome_ec, spibus, 1, 1, 1);


Property changes on: trunk/sys/arm/samsung/exynos/chrome_ec_spi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/arm/samsung/exynos/chrome_kb.c
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_kb.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/chrome_kb.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_kb.c 266352 2014-05-17 20:52:10Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/chrome_kb.c 356020 2019-12-22 19:06:45Z kevans $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,7 +47,6 @@
 #include <sys/mutex.h>
 #include <sys/gpio.h>
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -54,11 +53,9 @@
 
 #include <sys/ioccom.h>
 #include <sys/filio.h>
-#include <sys/tty.h>
 #include <sys/kbio.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
@@ -106,9 +103,6 @@
 #define	CKB_FLAG_POLLING	0x2
 #define	KBD_DRIVER_NAME		"ckbd"
 
-/* TODO: take interrupt from DTS */
-#define	KB_GPIO_INT		146
-
 struct ckb_softc {
 	keyboard_t sc_kbd;
 	keymap_t sc_keymap;
@@ -131,8 +125,11 @@
 	int			flag;
 	int			rows;
 	int			cols;
+	int			gpio;
 	device_t		dev;
+	device_t		gpio_dev;
 	struct thread		*sc_poll_thread;
+	uint16_t		*keymap;
 
 	uint8_t			*scan_local;
 	uint8_t			*scan;
@@ -199,7 +196,7 @@
 ckb_intr(keyboard_t *kbd, void *arg)
 {
 
-        return (0);
+	return (0);
 }
 
 /* lock the access to the keyboard, not used */
@@ -207,7 +204,7 @@
 ckb_lock(keyboard_t *kbd, int lock)
 {
 
-        return (1);
+	return (1);
 }
 
 /* clear the internal state of the keyboard */
@@ -258,12 +255,12 @@
 
 	if (sc->sc_flags & CKB_FLAG_POLLING) {
 		return (1);
-	};
+	}
 
 	for (i = 0; i < sc->cols; i++)
 		if (sc->scan_local[i] != sc->scan[i]) {
 			return (1);
-		};
+		}
 
 	if (sc->sc_repeating)
 		return (1);
@@ -309,20 +306,33 @@
 	return (0);
 }
 
-int scantokey(int i, int j);
-
-int
-scantokey(int i, int j)
+static uint16_t
+keymap_read(struct ckb_softc *sc, int col, int row)
 {
-	int k;
 
-	for (k = 0; k < KEYMAP_LEN; k++)
-		if ((keymap[k].col == i) && (keymap[k].row == j))
-			return (keymap[k].key);
+	KASSERT(sc->keymap != NULL, ("keymap_read: no keymap"));
+	if (col >= 0 && col < sc->cols &&
+	    row >= 0 && row < sc->rows) {
+		return sc->keymap[row * sc->cols + col];
+	}
 
 	return (0);
 }
 
+static int
+keymap_write(struct ckb_softc *sc, int col, int row, uint16_t key)
+{
+
+	KASSERT(sc->keymap != NULL, ("keymap_write: no keymap"));
+	if (col >= 0 && col < sc->cols &&
+	    row >= 0 && row < sc->rows) {
+		sc->keymap[row * sc->cols + col] = key;
+		return (0);
+	}
+
+	return (-1);
+}
+
 /* read char from the keyboard */
 static uint32_t
 ckb_read_char_locked(keyboard_t *kbd, int wait)
@@ -332,6 +342,7 @@
 	uint16_t key;
 	int oldbit;
 	int newbit;
+	int status;
 
 	sc = kbd->kb_data;
 
@@ -345,11 +356,25 @@
 		callout_reset(&sc->sc_repeat_callout, hz / 10,
                     ckb_repeat, sc);
 		return (sc->sc_repeat_key);
-	};
+	}
 
 	if (sc->sc_flags & CKB_FLAG_POLLING) {
-		/* TODO */
-	};
+		for (;;) {
+			GPIO_PIN_GET(sc->gpio_dev, sc->gpio, &status);
+			if (status == 0) {
+				if (ec_command(EC_CMD_MKBP_STATE, sc->scan,
+					sc->cols,
+				    sc->scan, sc->cols)) {
+					return (NOKEY);
+				}
+				break;
+			}
+			if (!wait) {
+				return (NOKEY);
+			}
+			DELAY(1000);
+		}
+	}
 
 	for (i = 0; i < sc->cols; i++) {
 		for (j = 0; j < sc->rows; j++) {
@@ -359,10 +384,10 @@
 			if (oldbit == newbit)
 				continue;
 
-			key = scantokey(i,j);
+			key = keymap_read(sc, i, j);
 			if (key == 0) {
 				continue;
-			};
+			}
 
 			if (newbit > 0) {
 				/* key pressed */
@@ -638,9 +663,7 @@
 	.clear_state = &ckb_clear_state,
 	.get_state = &ckb_get_state,
 	.set_state = &ckb_set_state,
-	.get_fkeystr = &genkbd_get_fkeystr,
 	.poll = &ckb_poll,
-	.diag = &genkbd_diag,
 };
 
 static int
@@ -652,29 +675,111 @@
 
 KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure);
 
+/* 
+ * Parses 'keymap' into sc->keymap.
+ * Requires sc->cols and sc->rows to be set.
+ */
 static int
+parse_keymap(struct ckb_softc *sc, pcell_t *keymap, size_t len)
+{
+	int i;
+
+	sc->keymap = malloc(sc->cols * sc->rows * sizeof(sc->keymap[0]),
+	    M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (sc->keymap == NULL) {
+		return (ENOMEM);
+	}
+
+	for (i = 0; i < len; i++) {
+		/* 
+		 * Return value is ignored, we just write whatever fits into
+		 * specified number of rows and columns and silently ignore
+		 * everything else.
+		 * Keymap entries follow this format: 0xRRCCKKKK
+		 * RR - row number, CC - column number, KKKK - key code
+		 */
+		keymap_write(sc, (keymap[i] >> 16) & 0xff,
+		    (keymap[i] >> 24) & 0xff,
+		    keymap[i] & 0xffff);
+	}
+
+	return (0);
+}
+
+/* Allocates a new array for keymap and returns it in 'keymap'. */
+static int
+read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len)
+{
+
+	if ((*len = OF_getproplen(node, prop)) <= 0) {
+		return (ENXIO);
+	}
+	if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) {
+		return (ENOMEM);
+	}
+	if (OF_getencprop(node, prop, *keymap, *len) != *len) {
+		return (ENXIO);
+	}
+	return (0);
+}
+
+static int
 parse_dts(struct ckb_softc *sc)
 {
 	phandle_t node;
 	pcell_t dts_value;
-	int len;
+	pcell_t *keymap;
+	int len, ret;
+	const char *keymap_prop = NULL;
 
 	if ((node = ofw_bus_get_node(sc->dev)) == -1)
 		return (ENXIO);
 
-	if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0)
+	if ((len = OF_getproplen(node, "google,key-rows")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "keypad,num-rows", &dts_value, len);
-	sc->rows = fdt32_to_cpu(dts_value);
+	OF_getencprop(node, "google,key-rows", &dts_value, len);
+	sc->rows = dts_value;
 
-	if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0)
+	if ((len = OF_getproplen(node, "google,key-columns")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "keypad,num-columns", &dts_value, len);
-	sc->cols = fdt32_to_cpu(dts_value);
+	OF_getencprop(node, "google,key-columns", &dts_value, len);
+	sc->cols = dts_value;
 
-	if ((sc->rows == 0) || (sc->cols == 0))
+	if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0)
 		return (ENXIO);
+	OF_getencprop(node, "freebsd,intr-gpio", &dts_value, len);
+	sc->gpio = dts_value;
 
+	if (OF_hasprop(node, "freebsd,keymap")) {
+		keymap_prop = "freebsd,keymap";
+		device_printf(sc->dev, "using FreeBSD-specific keymap from FDT\n");
+	} else if (OF_hasprop(node, "linux,keymap")) {
+		keymap_prop = "linux,keymap";
+		device_printf(sc->dev, "using Linux keymap from FDT\n");
+	} else {
+		device_printf(sc->dev, "using built-in keymap\n");
+	}
+
+	if (keymap_prop != NULL) {
+		if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) {
+			device_printf(sc->dev,
+			     "failed to read keymap from FDT: %d\n", ret);
+			return (ret);
+		}
+		ret = parse_keymap(sc, keymap, len);
+		free(keymap, M_DEVBUF);
+		if (ret) {
+			return (ret);
+		}
+	} else {
+		if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) {
+			return (ret);
+		}
+	}
+
+	if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0))
+		return (ENXIO);
+
 	return (0);
 }
 
@@ -707,17 +812,23 @@
 	sc = device_get_softc(dev);
 
 	sc->dev = dev;
+	sc->keymap = NULL;
 
 	if ((error = parse_dts(sc)) != 0)
 		return error;
 
+	sc->gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (sc->gpio_dev == NULL) {
+		device_printf(sc->dev, "Can't find gpio device.\n");
+		return (ENXIO);
+	}
+
 #if 0
 	device_printf(sc->dev, "Keyboard matrix [%dx%d]\n",
 	    sc->cols, sc->rows);
 #endif
 
-	/* TODO: take interrupt from DTS */
-	pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc);
+	pad_setup_intr(sc->gpio, ckb_ec_intr, sc);
 
 	kbd = &sc->sc_kbd;
 	rid = 0;
@@ -728,7 +839,7 @@
 	for (i = 0; i < sc->cols; i++) {
 		sc->scan_local[i] = 0;
 		sc->scan[i] = 0;
-	};
+	}
 
 	kbd_init_struct(kbd, KBD_DRIVER_NAME, KB_OTHER,
 	    device_get_unit(dev), 0, 0, 0);
@@ -753,7 +864,7 @@
 
 	if (kbd_register(kbd) < 0) {
 		return (ENXIO);
-	};
+	}
 	KBD_CONFIG_DONE(kbd);
 
 	return (0);
@@ -766,7 +877,8 @@
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-	if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb")) {
+	if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb") ||
+	    ofw_bus_is_compatible(dev, "google,mkbp-keyb")) {
 		device_set_desc(dev, "Chrome EC Keyboard");
 		return (BUS_PROBE_DEFAULT);
 	}
@@ -774,9 +886,24 @@
 	return (ENXIO);
 }
 
+static int
+chrome_kb_detach(device_t dev)
+{
+	struct ckb_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->keymap != NULL) {
+		free(sc->keymap, M_DEVBUF);
+	}
+
+	return 0;
+}
+
 static device_method_t chrome_kb_methods[] = {
 	DEVMETHOD(device_probe,		chrome_kb_probe),
 	DEVMETHOD(device_attach,	chrome_kb_attach),
+	DEVMETHOD(device_detach,	chrome_kb_detach),
 	{ 0, 0 }
 };
 

Modified: trunk/sys/arm/samsung/exynos/chrome_kb.h
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_kb.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/chrome_kb.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -24,100 +24,96 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_kb.h 266341 2014-05-17 19:37:04Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/chrome_kb.h 266872 2014-05-30 06:45:50Z br $
  */
 
+#include <dev/ofw/openfirm.h>
+
 void ckb_ec_intr(void *);
 
-struct key {
-	uint8_t row;
-	uint8_t col;
-	uint8_t key;
-};
-
 #define	KEYMAP_LEN	75
 
-struct key keymap[KEYMAP_LEN] = {
-	{ 0x00, 0x01, 0x7d }, /* lmeta */
-	{ 0x00, 0x02, 0x3b }, /* F1 */
-	{ 0x00, 0x03, 0x30 }, /* B */
-	{ 0x00, 0x04, 0x44 }, /* F10 */
-	{ 0x00, 0x06, 0x31 }, /* N */
-	{ 0x00, 0x08, 0x0d }, /* = */
-	{ 0x00, 0x0a, 0x64 }, /* ralt */
+pcell_t default_keymap[KEYMAP_LEN] = {
+	0x0001007d, /* lmeta */
+	0x0002003b, /* F1 */
+	0x00030030, /* B */
+	0x00040044, /* F10 */
+	0x00060031, /* N */
+	0x0008000d, /* = */
+	0x000a0064, /* ralt */
 
-	{ 0x01, 0x01, 0x01 }, /* escape */
-	{ 0x01, 0x02, 0x3e }, /* F4 */
-	{ 0x01, 0x03, 0x22 }, /* G */
-	{ 0x01, 0x04, 0x41 }, /* F7 */
-	{ 0x01, 0x06, 0x23 }, /* H */
-	{ 0x01, 0x08, 0x28 }, /* ' */
-	{ 0x01, 0x09, 0x43 }, /* F9 */
-	{ 0x01, 0x0b, 0x0e }, /* backspace */
+	0x01010001, /* escape */
+	0x0102003e, /* F4 */
+	0x01030022, /* G */
+	0x01040041, /* F7 */
+	0x01060023, /* H */
+	0x01080028, /* ' */
+	0x01090043, /* F9 */
+	0x010b000e, /* backspace */
 
-	{ 0x02, 0x00, 0x1d }, /* lctrl */
-	{ 0x02, 0x01, 0x0f }, /* tab */
-	{ 0x02, 0x02, 0x3d }, /* F3 */
-	{ 0x02, 0x03, 0x14 }, /* t */
-	{ 0x02, 0x04, 0x40 }, /* F6 */
-	{ 0x02, 0x05, 0x1b }, /* ] */
-	{ 0x02, 0x06, 0x15 }, /* y */
-	{ 0x02, 0x07, 0x56 }, /* 102nd */
-	{ 0x02, 0x08, 0x1a }, /* [ */
-	{ 0x02, 0x09, 0x42 }, /* F8 */
+	0x0200001d, /* lctrl */
+	0x0201000f, /* tab */
+	0x0202003d, /* F3 */
+	0x02030014, /* t */
+	0x02040040, /* F6 */
+	0x0205001b, /* ] */
+	0x02060015, /* y */
+	0x02070056, /* 102nd */
+	0x0208001a, /* [ */
+	0x02090042, /* F8 */
 
-	{ 0x03, 0x01, 0x29 }, /* grave */
-	{ 0x03, 0x02, 0x3c }, /* F2 */
-	{ 0x03, 0x03, 0x06 }, /* 5 */
-	{ 0x03, 0x04, 0x3f }, /* F5 */
-	{ 0x03, 0x06, 0x07 }, /* 6 */
-	{ 0x03, 0x08, 0x0c }, /* - */
-	{ 0x03, 0x0b, 0x2b }, /* \ */
+	0x03010029, /* grave */
+	0x0302003c, /* F2 */
+	0x03030006, /* 5 */
+	0x0304003f, /* F5 */
+	0x03060007, /* 6 */
+	0x0308000c, /* - */
+	0x030b002b, /* \ */
 
-	{ 0x04, 0x00, 0x61 }, /* rctrl */
-	{ 0x04, 0x01, 0x1e }, /* a */
-	{ 0x04, 0x02, 0x20 }, /* d */
-	{ 0x04, 0x03, 0x21 }, /* f */
-	{ 0x04, 0x04, 0x1f }, /* s */
-	{ 0x04, 0x05, 0x25 }, /* k */
-	{ 0x04, 0x06, 0x24 }, /* j */
-	{ 0x04, 0x08, 0x27 }, /* ; */
-	{ 0x04, 0x09, 0x26 }, /* l */
-	{ 0x04, 0x0a, 0x2b }, /* \ */
-	{ 0x04, 0x0b, 0x1c }, /* enter */
+	0x04000061, /* rctrl */
+	0x0401001e, /* a */
+	0x04020020, /* d */
+	0x04030021, /* f */
+	0x0404001f, /* s */
+	0x04050025, /* k */
+	0x04060024, /* j */
+	0x04080027, /* ; */
+	0x04090026, /* l */
+	0x040a002b, /* \ */
+	0x040b001c, /* enter */
 
-	{ 0x05, 0x01, 0x2c }, /* z */
-	{ 0x05, 0x02, 0x2e }, /* c */
-	{ 0x05, 0x03, 0x2f }, /* v */
-	{ 0x05, 0x04, 0x2d }, /* x */
-	{ 0x05, 0x05, 0x33 }, /* , */
-	{ 0x05, 0x06, 0x32 }, /* m */
-	{ 0x05, 0x07, 0x2a }, /* lsh */
-	{ 0x05, 0x08, 0x35 }, /* / */
-	{ 0x05, 0x09, 0x34 }, /* . */
-	{ 0x05, 0x0B, 0x39 }, /* space */
+	0x0501002c, /* z */
+	0x0502002e, /* c */
+	0x0503002f, /* v */
+	0x0504002d, /* x */
+	0x05050033, /* , */
+	0x05060032, /* m */
+	0x0507002a, /* lsh */
+	0x05080035, /* / */
+	0x05090034, /* . */
+	0x050B0039, /* space */
 
-	{ 0x06, 0x01, 0x02 }, /* 1 */
-	{ 0x06, 0x02, 0x04 }, /* 3 */
-	{ 0x06, 0x03, 0x05 }, /* 4 */
-	{ 0x06, 0x04, 0x03 }, /* 2 */
-	{ 0x06, 0x05, 0x09 }, /* 8 */
-	{ 0x06, 0x06, 0x08 }, /* 7 */
-	{ 0x06, 0x08, 0x0b }, /* 0 */
-	{ 0x06, 0x09, 0x0a }, /* 9 */
-	{ 0x06, 0x0a, 0x38 }, /* lalt */
-	{ 0x06, 0x0b, 0x64 }, /* down */
-	{ 0x06, 0x0c, 0x62 }, /* right */
+	0x06010002, /* 1 */
+	0x06020004, /* 3 */
+	0x06030005, /* 4 */
+	0x06040003, /* 2 */
+	0x06050009, /* 8 */
+	0x06060008, /* 7 */
+	0x0608000b, /* 0 */
+	0x0609000a, /* 9 */
+	0x060a0038, /* lalt */
+	0x060b0064, /* down */
+	0x060c0062, /* right */
 
-	{ 0x07, 0x01, 0x10 }, /* q */
-	{ 0x07, 0x02, 0x12 }, /* e */
-	{ 0x07, 0x03, 0x13 }, /* r */
-	{ 0x07, 0x04, 0x11 }, /* w */
-	{ 0x07, 0x05, 0x17 }, /* i */
-	{ 0x07, 0x06, 0x16 }, /* u */
-	{ 0x07, 0x07, 0x36 }, /* rsh */
-	{ 0x07, 0x08, 0x19 }, /* p */
-	{ 0x07, 0x09, 0x18 }, /* o */
-	{ 0x07, 0x0b, 0x5F }, /* up */
-	{ 0x07, 0x0c, 0x61 }, /* left */
+	0x07010010, /* q */
+	0x07020012, /* e */
+	0x07030013, /* r */
+	0x07040011, /* w */
+	0x07050017, /* i */
+	0x07060016, /* u */
+	0x07070036, /* rsh */
+	0x07080019, /* p */
+	0x07090018, /* o */
+	0x070b005F, /* up */
+	0x070c0061, /* left */
 };

Modified: trunk/sys/arm/samsung/exynos/exynos5_combiner.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_combiner.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_combiner.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -29,9 +29,11 @@
  * Samsung Exynos 5 Interrupt Combiner
  * Chapter 7, Exynos 5 Dual User's Manual Public Rev 1.00
  */
-
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_combiner.c 266341 2014-05-17 19:37:04Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_combiner.c 351675 2019-09-02 00:29:16Z emaste $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -44,21 +46,19 @@
 #include <sys/timetc.h>
 #include <sys/watchdog.h>
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
+#endif
 
 #include <arm/samsung/exynos/exynos5_common.h>
 #include <arm/samsung/exynos/exynos5_combiner.h>
 
 #define NGRP		32
-#define ITABLE_LEN	24
 
 #define	IESR(n)	(0x10 * n + 0x0)	/* Interrupt enable set */
 #define	IECR(n)	(0x10 * n + 0x4)	/* Interrupt enable clear */
@@ -119,7 +119,7 @@
 	char *source_name;
 };
 
-static struct combiner_entry interrupt_table[ITABLE_LEN] = {
+static struct combiner_entry interrupt_table[] = {
 	{ 63, 1, "EINT[15]" },
 	{ 63, 0, "EINT[14]" },
 	{ 62, 1, "EINT[13]" },
@@ -144,8 +144,116 @@
 	{ 55, 4, "MCT_G1" },
 	{ 55, 3, "MCT_G0" },
 	{ 55, 0, "EINT[0]" },
+	{ 54, 7, "CPU_nCNTVIRQ[1]" },
+	{ 54, 6, "CPU_nCTIIRQ[1]" },
+	{ 54, 5, "CPU_nCNTPSIRQ[1]" },
+	{ 54, 4, "CPU_nPMUIRQ[1]" },
+	{ 54, 3, "CPU_nCNTPNSIRQ[1]" },
+	{ 54, 2, "CPU_PARITYFAILSCU[1]" },
+	{ 54, 1, "CPU_nCNTHPIRQ[1]" },
+	{ 54, 0, "PARITYFAIL[1]" },
+	{ 53, 1, "CPU_nIRQ[1]" },
+	{ 52, 0, "CPU_nIRQ[0]" },
+	{ 51, 7, "CPU_nRAMERRIRQ" },
+	{ 51, 6, "CPU_nAXIERRIRQ" },
+	{ 51, 4, "INT_COMB_ISP_GIC" },
+	{ 51, 3, "INT_COMB_IOP_GIC" },
+	{ 51, 2, "CCI_nERRORIRQ" },
+	{ 51, 1, "INT_COMB_ARMISP_GIC" },
+	{ 51, 0, "INT_COMB_ARMIOP_GIC" },
+	{ 50, 7, "DISP1[3]" },
+	{ 50, 6, "DISP1[2]" },
+	{ 50, 5, "DISP1[1]" },
+	{ 50, 4, "DISP1[0]" },
+	{ 49, 3, "SSCM_PULSE_IRQ_C2CIF[1]" },
+	{ 49, 2, "SSCM_PULSE_IRQ_C2CIF[0]" },
+	{ 49, 1, "SSCM_IRQ_C2CIF[1]" },
+	{ 49, 0, "SSCM_IRQ_C2CIF[0]" },
+	{ 48, 3, "PEREV_M1_CDREX" },
+	{ 48, 2, "PEREV_M0_CDREX" },
+	{ 48, 1, "PEREV_A1_CDREX" },
+	{ 48, 0, "PEREV_A0_CDREX" },
+	{ 47, 3, "MDMA0_ABORT" },
+	/* 46 is fully reserved */
+	{ 45, 1, "MDMA1_ABORT" },
+	/* 44 is fully reserved */
+	{ 43, 7, "SYSMMU_DRCISP[1]" },
+	{ 43, 6, "SYSMMU_DRCISP[0]" },
+	{ 43, 1, "SYSMMU_ODC[1]" },
+	{ 43, 0, "SYSMMU_ODC[0]" },
+	{ 42, 7, "SYSMMU_ISP[1]" },
+	{ 42, 6, "SYSMMU_ISP[0]" },
+	{ 42, 5, "SYSMMU_DIS0[1]" },
+	{ 42, 4, "SYSMMU_DIS0[0]" },
+	{ 42, 3, "DP1" },
+	{ 41, 5, "SYSMMU_DIS1[1]" },
+	{ 41, 4, "SYSMMU_DIS1[0]" },
+	{ 40, 6, "SYSMMU_MFCL[1]" },
+	{ 40, 5, "SYSMMU_MFCL[0]" },
+	{ 39, 5, "SYSMMU_TV_M0[1]" },
+	{ 39, 4, "SYSMMU_TV_M0[0]" },
+	{ 39, 3, "SYSMMU_MDMA1[1]" },
+	{ 39, 2, "SYSMMU_MDMA1[0]" },
+	{ 39, 1, "SYSMMU_MDMA0[1]" },
+	{ 39, 0, "SYSMMU_MDMA0[0]" },
+	{ 38, 7, "SYSMMU_SSS[1]" },
+	{ 38, 6, "SYSMMU_SSS[0]" },
+	{ 38, 5, "SYSMMU_RTIC[1]" },
+	{ 38, 4, "SYSMMU_RTIC[0]" },
+	{ 38, 3, "SYSMMU_MFCR[1]" },
+	{ 38, 2, "SYSMMU_MFCR[0]" },
+	{ 38, 1, "SYSMMU_ARM[1]" },
+	{ 38, 0, "SYSMMU_ARM[0]" },
+	{ 37, 7, "SYSMMU_3DNR[1]" },
+	{ 37, 6, "SYSMMU_3DNR[0]" },
+	{ 37, 5, "SYSMMU_MCUISP[1]" },
+	{ 37, 4, "SYSMMU_MCUISP[0]" },
+	{ 37, 3, "SYSMMU_SCALERCISP[1]" },
+	{ 37, 2, "SYSMMU_SCALERCISP[0]" },
+	{ 37, 1, "SYSMMU_FDISP[1]" },
+	{ 37, 0, "SYSMMU_FDISP[0]" },
+	{ 36, 7, "MCUIOP_CTIIRQ" },
+	{ 36, 6, "MCUIOP_PMUIRQ" },
+	{ 36, 5, "MCUISP_CTIIRQ" },
+	{ 36, 4, "MCUISP_PMUIRQ" },
+	{ 36, 3, "SYSMMU_JPEGX[1]" },
+	{ 36, 2, "SYSMMU_JPEGX[0]" },
+	{ 36, 1, "SYSMMU_ROTATOR[1]" },
+	{ 36, 0, "SYSMMU_ROTATOR[0]" },
+	{ 35, 7, "SYSMMU_SCALERPISP[1]" },
+	{ 35, 6, "SYSMMU_SCALERPISP[0]" },
+	{ 35, 5, "SYSMMU_FIMC_LITE0[1]" },
+	{ 35, 4, "SYSMMU_FIMC_LITE0[0]" },
+	{ 35, 3, "SYSMMU_DISP1_M0[1]" },
+	{ 35, 2, "SYSMMU_DISP1_M0[0]" },
+	{ 35, 1, "SYSMMU_FIMC_LITE2[1]" },
+	{ 35, 0, "SYSMMU_FIMC_LITE2[0]" },
+	{ 34, 7, "SYSMMU_GSCL3[1]" },
+	{ 34, 6, "SYSMMU_GSCL3[0]" },
+	{ 34, 5, "SYSMMU_GSCL2[1]" },
+	{ 34, 4, "SYSMMU_GSCL2[0]" },
+	{ 34, 3, "SYSMMU_GSCL1[1]" },
+	{ 34, 2, "SYSMMU_GSCL1[0]" },
+	{ 34, 1, "SYSMMU_GSCL0[1]" },
+	{ 34, 0, "SYSMMU_GSCL0[0]" },
+	{ 33, 7, "CPU_nCNTVIRQ[0]" },
+	{ 33, 6, "CPU_nCNTPSIRQ[0]" },
+	{ 33, 5, "CPU_nCNTPSNIRQ[0]" },
+	{ 33, 4, "CPU_nCNTHPIRQ[0]" },
+	{ 33, 3, "CPU_nCTIIRQ[0]" },
+	{ 33, 2, "CPU_nPMUIRQ[0]" },
+	{ 33, 1, "CPU_PARITYFAILSCU[0]" },
+	{ 33, 0, "CPU_PARITYFAIL0" },
+	{ 32, 7, "TZASC_XR1BXW" },
+	{ 32, 6, "TZASC_XR1BXR" },
+	{ 32, 5, "TZASC_XLBXW" },
+	{ 32, 4, "TZASC_XLBXR" },
+	{ 32, 3, "TZASC_DRBXW" },
+	{ 32, 2, "TZASC_DRBXR" },
+	{ 32, 1, "TZASC_CBXW" },
+	{ 32, 0, "TZASC_CBXR" },
 
-	/* TODO: add groups 54-32 */
+	{ -1, -1, NULL },
 };
 
 struct combined_intr {
@@ -207,13 +315,13 @@
 	sc = combiner_sc;
 
 	if (sc == NULL) {
-		device_printf(sc->dev, "Error: combiner is not attached\n");
+		printf("%s: error: combiner is not attached\n", __func__);
 		return;
 	}
 
 	entry = NULL;
 
-	for (i = 0; i < ITABLE_LEN; i++) {
+	for (i = 0; i < NGRP && interrupt_table[i].bit != -1; i++) {
 		if (strcmp(interrupt_table[i].source_name, source_name) == 0) {
 			entry = &interrupt_table[i];
 		}
@@ -247,6 +355,9 @@
 combiner_probe(device_t dev)
 {
 
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
 	if (!ofw_bus_is_compatible(dev, "exynos,combiner"))
 		return (ENXIO);
 

Modified: trunk/sys/arm/samsung/exynos/exynos5_combiner.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_combiner.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_combiner.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_combiner.h 266341 2014-05-17 19:37:04Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_combiner.h 263936 2014-03-30 15:22:36Z br $
  */
 
 void combiner_setup_intr(char *source_name, void (*ih)(void *), void *ih_user);

Modified: trunk/sys/arm/samsung/exynos/exynos5_common.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_common.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_common.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_common.c 266277 2014-05-17 00:53:12Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_common.c 314506 2017-03-01 19:55:04Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -50,10 +50,7 @@
 	while (1);
 }
 
-struct fdt_fixup_entry fdt_fixup_table[] = {
-	{ NULL, NULL }
-};
-
+#ifndef INTRNG
 static int
 fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
     int *pol)
@@ -72,3 +69,4 @@
 	&fdt_pic_decode_ic,
 	NULL
 };
+#endif

Modified: trunk/sys/arm/samsung/exynos/exynos5_common.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_common.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_common.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_common.h 266332 2014-05-17 17:54:38Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_common.h 263426 2014-03-20 17:07:14Z br $
  */
 
 #define	READ4(_sc, _reg)	\

Modified: trunk/sys/arm/samsung/exynos/exynos5_ehci.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_ehci.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_ehci.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -1,6 +1,6 @@
 /* $MidnightBSD$ */
 /*-
- * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,8 +25,11 @@
  * SUCH DAMAGE.
  */
 
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_ehci.c 278278 2015-02-05 20:03:02Z hselasky $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_ehci.c 346524 2019-04-22 04:56:41Z ian $");
 
 #include "opt_bus.h"
 
@@ -51,14 +54,16 @@
 #include <dev/usb/controller/ehci.h>
 #include <dev/usb/controller/ehcireg.h>
 
-#include <dev/fdt/fdt_common.h>
-
 #include <machine/bus.h>
 #include <machine/resource.h>
 
+#include <arm/samsung/exynos/exynos5_common.h>
+#include <arm/samsung/exynos/exynos5_pmu.h>
+
 #include "gpio_if.h"
 
 #include "opt_platform.h"
+#endif
 
 /* GPIO control */
 #define	GPIO_OUTPUT	1
@@ -65,11 +70,6 @@
 #define	GPIO_INPUT	0
 #define	PIN_USB		161
 
-/* PWR control */
-#define	EXYNOS5_PWR_USBHOST_PHY		0x708
-#define	PHY_POWER_ON			1
-#define	PHY_POWER_OFF			0
-
 /* SYSREG */
 #define	EXYNOS5_SYSREG_USB2_PHY	0x0
 #define	USB2_MODE_HOST		0x1
@@ -92,12 +92,10 @@
 struct exynos_ehci_softc {
 	device_t		dev;
 	ehci_softc_t		base;
-	struct resource		*res[5];
+	struct resource		*res[4];
 	bus_space_tag_t		host_bst;
-	bus_space_tag_t		pwr_bst;
 	bus_space_tag_t		sysreg_bst;
 	bus_space_handle_t	host_bsh;
-	bus_space_handle_t	pwr_bsh;
 	bus_space_handle_t	sysreg_bsh;
 
 };
@@ -106,7 +104,6 @@
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
 	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
-	{ SYS_RES_MEMORY,	3,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
 	{ -1, 0 }
 };
@@ -130,13 +127,13 @@
 static driver_t ehci_driver = {
 	"ehci",
 	ehci_methods,
-	sizeof(ehci_softc_t)
+	sizeof(struct exynos_ehci_softc)
 };
 
 static devclass_t ehci_devclass;
 
-DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
-MODULE_DEPEND(ehci, usb, 1, 1, 1);
+DRIVER_MODULE(exynos_ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(exynos_ehci, usb, 1, 1, 1);
 
 /*
  * Public methods
@@ -181,9 +178,41 @@
 }
 
 static int
+reset_hsic_hub(struct exynos_ehci_softc *esc, phandle_t hub)
+{
+	device_t gpio_dev;
+	pcell_t pin;
+
+	/* TODO: check that hub is compatible with "smsc,usb3503" */
+	if (!OF_hasprop(hub, "freebsd,reset-gpio")) {
+		return (1);
+	}
+
+	if (OF_getencprop(hub, "freebsd,reset-gpio", &pin, sizeof(pin)) < 0) {
+		device_printf(esc->dev,
+		    "failed to decode reset GPIO pin number for HSIC hub\n");
+		return (1);
+	}
+
+	/* Get the GPIO device, we need this to give power to USB */
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (gpio_dev == NULL) {
+		device_printf(esc->dev, "Cant find gpio device\n");
+		return (1);
+	}
+
+	GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_LOW);
+	DELAY(100);
+	GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_HIGH);
+
+	return (0);
+}
+
+static int
 phy_init(struct exynos_ehci_softc *esc)
 {
 	int reg;
+	phandle_t hub;
 
 	gpio_ctrl(esc, GPIO_INPUT, 1);
 
@@ -192,8 +221,7 @@
 	    EXYNOS5_SYSREG_USB2_PHY, USB2_MODE_HOST);
 
 	/* Power ON phy */
-	bus_space_write_4(esc->pwr_bst, esc->pwr_bsh,
-	    EXYNOS5_PWR_USBHOST_PHY, PHY_POWER_ON);
+	usb2_phy_power_on();
 
 	reg = bus_space_read_4(esc->host_bst, esc->host_bsh, 0x0);
 	reg &= ~(HOST_CTRL_CLK_MASK |
@@ -213,6 +241,10 @@
 	reg &= ~(HOST_CTRL_RESET_LINK);
 	bus_space_write_4(esc->host_bst, esc->host_bsh, 0x0, reg);
 
+	if ((hub = OF_finddevice("/hsichub")) != 0) {
+		reset_hsic_hub(esc, hub);
+	}
+
 	gpio_ctrl(esc, GPIO_OUTPUT, 1);
 
 	return (0);
@@ -248,13 +280,9 @@
 	esc->host_bst = rman_get_bustag(esc->res[1]);
 	esc->host_bsh = rman_get_bushandle(esc->res[1]);
 
-	/* PWR registers */
-	esc->pwr_bst = rman_get_bustag(esc->res[2]);
-	esc->pwr_bsh = rman_get_bushandle(esc->res[2]);
-
 	/* SYSREG */
-	esc->sysreg_bst = rman_get_bustag(esc->res[3]);
-	esc->sysreg_bsh = rman_get_bushandle(esc->res[3]);
+	esc->sysreg_bst = rman_get_bustag(esc->res[2]);
+	esc->sysreg_bsh = rman_get_bushandle(esc->res[2]);
 
 	/* get all DMA memory */
 	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
@@ -273,7 +301,7 @@
 	phy_init(esc);
 
 	/* Setup interrupt handler */
-	err = bus_setup_intr(dev, esc->res[4], INTR_TYPE_BIO | INTR_MPSAFE,
+	err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
 	    NULL, (driver_intr_t *)ehci_interrupt, sc,
 	    &sc->sc_intr_hdl);
 	if (err) {
@@ -286,7 +314,7 @@
 	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
 	if (!sc->sc_bus.bdev) {
 		device_printf(dev, "Could not add USB device\n");
-		err = bus_teardown_intr(dev, esc->res[4],
+		err = bus_teardown_intr(dev, esc->res[3],
 		    sc->sc_intr_hdl);
 		if (err)
 			device_printf(dev, "Could not tear down irq,"
@@ -307,7 +335,7 @@
 		device_delete_child(dev, sc->sc_bus.bdev);
 		sc->sc_bus.bdev = NULL;
 
-		err = bus_teardown_intr(dev, esc->res[4],
+		err = bus_teardown_intr(dev, esc->res[3],
 		    sc->sc_intr_hdl);
 		if (err)
 			device_printf(dev, "Could not tear down irq,"
@@ -346,8 +374,8 @@
 		bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
 		    EHCI_USBINTR, 0);
 
-	if (esc->res[4] && sc->sc_intr_hdl) {
-		err = bus_teardown_intr(dev, esc->res[4],
+	if (esc->res[3] && sc->sc_intr_hdl) {
+		err = bus_teardown_intr(dev, esc->res[3],
 		    sc->sc_intr_hdl);
 		if (err) {
 			device_printf(dev, "Could not tear down irq,"

Modified: trunk/sys/arm/samsung/exynos/exynos5_fimd.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_fimd.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_fimd.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_fimd.c 266358 2014-05-17 21:26:33Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_fimd.c 269702 2014-08-08 06:29:30Z nwhitehorn $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,8 +51,8 @@
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 #include <vm/vm_kern.h>
+#include <vm/pmap.h>
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -65,7 +65,6 @@
 #include "gpio_if.h"
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
@@ -214,37 +213,37 @@
 	/* panel size */
 	if ((len = OF_getproplen(node, "panel-size")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "panel-size", &dts_value, len);
-	panel->width = fdt32_to_cpu(dts_value[0]);
-	panel->height = fdt32_to_cpu(dts_value[1]);
+	OF_getencprop(node, "panel-size", dts_value, len);
+	panel->width = dts_value[0];
+	panel->height = dts_value[1];
 
 	/* hsync */
 	if ((len = OF_getproplen(node, "panel-hsync")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "panel-hsync", &dts_value, len);
-	panel->h_back_porch = fdt32_to_cpu(dts_value[0]);
-	panel->h_pulse_width = fdt32_to_cpu(dts_value[1]);
-	panel->h_front_porch = fdt32_to_cpu(dts_value[2]);
+	OF_getencprop(node, "panel-hsync", dts_value, len);
+	panel->h_back_porch = dts_value[0];
+	panel->h_pulse_width = dts_value[1];
+	panel->h_front_porch = dts_value[2];
 
 	/* vsync */
 	if ((len = OF_getproplen(node, "panel-vsync")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "panel-vsync", &dts_value, len);
-	panel->v_back_porch = fdt32_to_cpu(dts_value[0]);
-	panel->v_pulse_width = fdt32_to_cpu(dts_value[1]);
-	panel->v_front_porch = fdt32_to_cpu(dts_value[2]);
+	OF_getencprop(node, "panel-vsync", dts_value, len);
+	panel->v_back_porch = dts_value[0];
+	panel->v_pulse_width = dts_value[1];
+	panel->v_front_porch = dts_value[2];
 
 	/* clk divider */
 	if ((len = OF_getproplen(node, "panel-clk-div")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "panel-clk-div", &dts_value, len);
-	panel->clk_div = fdt32_to_cpu(dts_value[0]);
+	OF_getencprop(node, "panel-clk-div", dts_value, len);
+	panel->clk_div = dts_value[0];
 
 	/* backlight pin */
 	if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0)
 		return (ENXIO);
-	OF_getprop(node, "panel-backlight-pin", &dts_value, len);
-	panel->backlight_pin = fdt32_to_cpu(dts_value[0]);
+	OF_getencprop(node, "panel-backlight-pin", dts_value, len);
+	panel->backlight_pin = dts_value[0];
 
 	return (0);
 }

Modified: trunk/sys/arm/samsung/exynos/exynos5_i2c.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_i2c.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_i2c.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_i2c.c 289666 2015-10-20 21:20:34Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_i2c.c 297793 2016-04-10 23:07:00Z pfg $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,13 +48,11 @@
 
 #include "iicbus_if.h"
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
@@ -295,7 +293,7 @@
 
 		mtx_unlock(&sc->mutex);
 		return (IIC_ENOACK);
-	};
+	}
 
 	mtx_unlock(&sc->mutex);
 	return (IIC_NOERR);
@@ -373,6 +371,13 @@
 	mtx_lock(&sc->mutex);
 
 	/* dummy read */
+	clear_ipend(sc);
+	error = wait_for_iif(sc);
+	if (error) {
+		DPRINTF("cant i2c read: iif error\n");
+		mtx_unlock(&sc->mutex);
+		return (error);
+	}
 	READ1(sc, I2CDS);
 
 	DPRINTF("Read ");
@@ -383,7 +388,7 @@
 			reg = READ1(sc, I2CCON);
 			reg &= ~(ACKGEN);
 			WRITE1(sc, I2CCON, reg);
-		};
+		}
 
 		clear_ipend(sc);
 
@@ -440,7 +445,7 @@
 			DPRINTF("cant i2c write: no ack\n");
 			mtx_unlock(&sc->mutex);
 			return (IIC_ENOACK);
-		};
+		}
 
 		(*sent)++;
 	}

Modified: trunk/sys/arm/samsung/exynos/exynos5_machdep.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_machdep.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_machdep.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -29,67 +29,57 @@
 #include "opt_platform.h"
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_machdep.c 266275 2014-05-16 23:49:40Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_machdep.c 331722 2018-03-29 02:50:57Z eadler $");
 
-#define	_ARM32_BUS_DMA_PRIVATE
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/devmap.h>
 
 #include <vm/vm.h>
 
 #include <machine/armreg.h>
 #include <machine/bus.h>
-#include <machine/devmap.h>
 #include <machine/machdep.h>
+#include <machine/platform.h> 
 
-#include <dev/fdt/fdt_common.h>
-
 vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
 {
 
-	return (arm_devmap_lastaddr());
+	return (devmap_lastaddr());
 }
 
 void
-initarm_early_init(void)
+platform_probe_and_attach(void)
 {
 
 }
 
 void
-initarm_gpio_init(void)
+platform_gpio_init(void)
 {
 
 }
 
 void
-initarm_late_init(void)
+platform_late_init(void)
 {
 
 }
 
 int
-initarm_devmap_init(void)
+platform_devmap_init(void)
 {
 
+	/* CHIP ID */
+	devmap_add_entry(0x10000000, 0x100000);
+
 	/* UART */
-	arm_devmap_add_entry(0x12C00000, 0x100000);
+	devmap_add_entry(0x12C00000, 0x100000);
 
-	return (0);
-}
+	/* DWMMC */
+	devmap_add_entry(0x12200000, 0x100000);
 
-struct arm32_dma_range *
-bus_dma_get_range(void)
-{
-
-	return (NULL);
-}
-
-int
-bus_dma_get_range_nb(void)
-{
-
 	return (0);
 }

Modified: trunk/sys/arm/samsung/exynos/exynos5_mct.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_mct.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_mct.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_mct.c 266332 2014-05-17 17:54:38Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_mct.c 269703 2014-08-08 06:30:17Z nwhitehorn $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,13 +46,11 @@
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
-#include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 
 #define	MCT_CTRL_START		(1 << 8)
 #define	MCT_CTRL		(0x240)

Modified: trunk/sys/arm/samsung/exynos/exynos5_mp.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_mp.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_mp.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -1,6 +1,6 @@
 /* $MidnightBSD$ */
 /*-
- * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_mp.c 266203 2014-05-16 00:14:50Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_mp.c 331722 2018-03-29 02:50:57Z eadler $");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -34,17 +34,41 @@
 #include <sys/mutex.h>
 #include <sys/smp.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/cpu.h>
 #include <machine/smp.h>
 #include <machine/fdt.h>
 #include <machine/intr.h>
 
-#define	EXYNOS_SYSRAM			0x02020000
+#define	EXYNOS_CHIPID		0x10000000
 
-void
-platform_mp_init_secondary(void)
+#define	EXYNOS5250_SOC_ID	0x43520000
+#define	EXYNOS5420_SOC_ID	0xE5420000
+#define	EXYNOS5_SOC_ID_MASK	0xFFFFF000
+
+#define	EXYNOS_SYSRAM		0x02020000
+#define	EXYNOS5420_SYSRAM_NS	(EXYNOS_SYSRAM + 0x53000 + 0x1c)
+
+#define	EXYNOS_PMU_BASE		0x10040000
+#define	CORE_CONFIG(n)		(0x2000 + (0x80 * (n)))
+#define	CORE_STATUS(n)		(CORE_CONFIG(n) + 0x4)
+#define	CORE_PWR_EN		0x3
+
+static int
+exynos_get_soc_id(void)
 {
+	bus_addr_t chipid;
+	int reg;
 
-	gic_init_secondary();
+	if (bus_space_map(fdtbus_bs_tag, EXYNOS_CHIPID,
+		0x1000, 0, &chipid) != 0)
+		panic("Couldn't map chipid\n");
+	reg = bus_space_read_4(fdtbus_bs_tag, chipid, 0x0);
+	bus_space_unmap(fdtbus_bs_tag, chipid, 0x1000);
+
+	return (reg & EXYNOS5_SOC_ID_MASK);
 }
 
 void
@@ -51,40 +75,58 @@
 platform_mp_setmaxid(void)
 {
 
-	mp_maxid = 1;
-}
+	if (exynos_get_soc_id() == EXYNOS5420_SOC_ID)
+		mp_ncpus = 4;
+	else
+		mp_ncpus = 2;
 
-int
-platform_mp_probe(void)
-{
-
-	mp_ncpus = 2;
-	return (1);
+	mp_maxid = mp_ncpus - 1;
 }
 
 void
 platform_mp_start_ap(void)
 {
-	bus_addr_t sysram;
-	int err;
+	bus_addr_t sysram, pmu;
+	int err, i, j;
+	int status;
+	int reg;
 
-	err = bus_space_map(fdtbus_bs_tag, EXYNOS_SYSRAM, 0x100, 0, &sysram);
+	err = bus_space_map(fdtbus_bs_tag, EXYNOS_PMU_BASE, 0x20000, 0, &pmu);
 	if (err != 0)
+		panic("Couldn't map pmu\n");
+
+	if (exynos_get_soc_id() == EXYNOS5420_SOC_ID)
+		reg = EXYNOS5420_SYSRAM_NS;
+	else
+		reg = EXYNOS_SYSRAM;
+
+	err = bus_space_map(fdtbus_bs_tag, reg, 0x100, 0, &sysram);
+	if (err != 0)
 		panic("Couldn't map sysram\n");
 
+	/* Give power to CPUs */
+	for (i = 1; i < mp_ncpus; i++) {
+		bus_space_write_4(fdtbus_bs_tag, pmu, CORE_CONFIG(i),
+		    CORE_PWR_EN);
+
+		for (j = 10; j >= 0; j--) {
+			status = bus_space_read_4(fdtbus_bs_tag, pmu,
+			    CORE_STATUS(i));
+			if ((status & CORE_PWR_EN) == CORE_PWR_EN)
+				break;
+			DELAY(10);
+			if (j == 0)
+				printf("Can't power on CPU%d\n", i);
+		}
+	}
+
 	bus_space_write_4(fdtbus_bs_tag, sysram, 0x0,
 	    pmap_kextract((vm_offset_t)mpentry));
 
-	cpu_idcache_wbinv_all();
-	cpu_l2cache_wbinv_all();
+	dcache_wbinv_poc_all();
 
-	armv7_sev();
+	dsb();
+	sev();
 	bus_space_unmap(fdtbus_bs_tag, sysram, 0x100);
+	bus_space_unmap(fdtbus_bs_tag, pmu, 0x20000);
 }
-
-void
-platform_ipi_send(cpuset_t cpus, u_int ipi)
-{
-
-	pic_ipi_send(cpus, ipi);
-}

Modified: trunk/sys/arm/samsung/exynos/exynos5_pad.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pad.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_pad.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -29,9 +29,11 @@
  * Samsung Exynos 5 Pad Control
  * Chapter 4, Exynos 5 Dual User's Manual Public Rev 1.00
  */
-
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_pad.c 278786 2015-02-14 21:16:19Z loos $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_pad.c 351675 2019-09-02 00:29:16Z emaste $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,17 +48,17 @@
 #include <sys/mutex.h>
 #include <sys/gpio.h>
 
-#include <dev/fdt/fdt_common.h>
+#include <dev/gpio/gpiobusvar.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
 
 #include "gpio_if.h"
+#endif
 
 #include <arm/samsung/exynos/exynos5_combiner.h>
 #include <arm/samsung/exynos/exynos5_pad.h>
@@ -66,11 +68,14 @@
 
 #define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
 
-#define	NPORTS	4
-#define	NGRP	40
-#define	NGPIO	253
-#define	NINTS	16
+#define	MAX_PORTS	5
+#define	MAX_NGPIO	253
 
+#define	N_EXT_INTS	16
+
+#define	EXYNOS5250	1
+#define	EXYNOS5420	2
+
 #define	PIN_IN	0
 #define	PIN_OUT	1
 
@@ -82,6 +87,7 @@
 /*
  * GPIO interface
  */
+static device_t pad_get_bus(device_t);
 static int pad_pin_max(device_t, int *);
 static int pad_pin_getcaps(device_t, uint32_t, uint32_t *);
 static int pad_pin_getname(device_t, uint32_t, char *);
@@ -91,20 +97,37 @@
 static int pad_pin_get(device_t, uint32_t, unsigned int *);
 static int pad_pin_toggle(device_t, uint32_t pin);
 
+struct gpio_bank {
+	char		*name;
+	uint32_t	port;
+	uint32_t	con;
+	uint32_t	ngpio;
+	uint32_t	ext_con;
+	uint32_t	ext_flt_con;
+	uint32_t	mask;
+	uint32_t	pend;
+};
+
 struct pad_softc {
-	struct resource		*res[NPORTS+4];
-	bus_space_tag_t		bst[NPORTS];
-	bus_space_handle_t	bsh[NPORTS];
+	struct resource		*res[MAX_PORTS * 2];
+	bus_space_tag_t		bst[MAX_PORTS];
+	bus_space_handle_t	bsh[MAX_PORTS];
 	struct mtx		sc_mtx;
 	int			gpio_npins;
-	struct gpio_pin		gpio_pins[NGPIO];
-	void			*gpio_ih[NPORTS+4];
+	struct gpio_pin		gpio_pins[MAX_NGPIO];
+	void			*gpio_ih[MAX_PORTS];
 	device_t		dev;
+	device_t		busdev;
+	int			model;
+	struct resource_spec	*pad_spec;
+	struct gpio_bank	*gpio_map;
+	struct interrupt_entry	*interrupt_table;
+	int			nports;
 };
 
 struct pad_softc *gpio_sc;
 
-static struct resource_spec pad_spec[] = {
+static struct resource_spec pad_spec_5250[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
 	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
@@ -116,6 +139,26 @@
 	{ -1, 0 }
 };
 
+static struct resource_spec pad_spec_5420[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	3,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	4,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		4,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"samsung,exynos5420-padctrl",	EXYNOS5420},
+	{"samsung,exynos5250-padctrl",	EXYNOS5250},
+	{NULL, 0}
+};
+
 struct pad_intr {
 	uint32_t	enabled;
 	void		(*ih) (void *);
@@ -122,7 +165,7 @@
 	void		*ih_user;
 };
 
-static struct pad_intr intr_map[NGPIO];
+static struct pad_intr intr_map[MAX_NGPIO];
 
 struct interrupt_entry {
 	int gpio_number;
@@ -129,7 +172,7 @@
 	char *combiner_source_name;
 };
 
-struct interrupt_entry interrupt_table[NINTS] = {
+struct interrupt_entry interrupt_table_5250[N_EXT_INTS] = {
 	{ 147, "EINT[15]" },
 	{ 146, "EINT[14]" },
 	{ 145, "EINT[13]" },
@@ -148,16 +191,23 @@
 	{ 132, "EINT[0]" },
 };
 
-struct gpio_bank {
-	char		*name;
-	uint32_t	port;
-	uint32_t	con;
-	uint32_t	ngpio;
-	uint32_t	ext_int_grp;
-	uint32_t	ext_con;
-	uint32_t	ext_flt_con;
-	uint32_t	mask;
-	uint32_t	pend;
+struct interrupt_entry interrupt_table_5420[N_EXT_INTS] = {
+	{ 23, "EINT[15]" },
+	{ 22, "EINT[14]" },
+	{ 21, "EINT[13]" },
+	{ 20, "EINT[12]" },
+	{ 19, "EINT[11]" },
+	{ 18, "EINT[10]" },
+	{ 17, "EINT[9]" },
+	{ 16, "EINT[8]" },
+	{ 15, "EINT[7]" },
+	{ 14, "EINT[6]" },
+	{ 13, "EINT[5]" },
+	{ 12, "EINT[4]" },
+	{ 11, "EINT[3]" },
+	{ 10, "EINT[2]" },
+	{  9, "EINT[1]" },
+	{  8, "EINT[0]" },
 };
 
 /*
@@ -164,57 +214,110 @@
  * 253 multi-functional input/output ports
  */
 
-static struct gpio_bank gpio_map[] = {
+static struct gpio_bank gpio_map_5250[] = {
 	/* first 132 gpio */
-	{ "gpa0", 0, 0x000, 8,  1, 0x700, 0x800, 0x900, 0xA00 },
-	{ "gpa1", 0, 0x020, 6,  2, 0x704, 0x808, 0x904, 0xA04 },
-	{ "gpa2", 0, 0x040, 8,  3, 0x708, 0x810, 0x908, 0xA08 },
-	{ "gpb0", 0, 0x060, 5,  4, 0x70C, 0x818, 0x90C, 0xA0C },
-	{ "gpb1", 0, 0x080, 5,  5, 0x710, 0x820, 0x910, 0xA10 },
-	{ "gpb2", 0, 0x0A0, 4,  6, 0x714, 0x828, 0x914, 0xA14 },
-	{ "gpb3", 0, 0x0C0, 4,  7, 0x718, 0x830, 0x918, 0xA18 },
-	{ "gpc0", 0, 0x0E0, 7,  8, 0x71C, 0x838, 0x91C, 0xA1C },
-	{ "gpc1", 0, 0x100, 4,  9, 0x720, 0x840, 0x920, 0xA20 },
-	{ "gpc2", 0, 0x120, 7, 10, 0x724, 0x848, 0x924, 0xA24 },
-	{ "gpc3", 0, 0x140, 7, 11, 0x728, 0x850, 0x928, 0xA28 },
-	{ "gpd0", 0, 0x160, 4, 12, 0x72C, 0x858, 0x92C, 0xA2C },
-	{ "gpd1", 0, 0x180, 8, 13, 0x730, 0x860, 0x930, 0xA30 },
-	{ "gpy0", 0, 0x1A0, 6,  0,     0,     0,     0,     0 },
-	{ "gpy1", 0, 0x1C0, 4,  0,     0,     0,     0,     0 },
-	{ "gpy2", 0, 0x1E0, 6,  0,     0,     0,     0,     0 },
-	{ "gpy3", 0, 0x200, 8,  0,     0,     0,     0,     0 },
-	{ "gpy4", 0, 0x220, 8,  0,     0,     0,     0,     0 },
-	{ "gpy5", 0, 0x240, 8,  0,     0,     0,     0,     0 },
-	{ "gpy6", 0, 0x260, 8,  0,     0,     0,     0,     0 },
-	{ "gpc4", 0, 0x2E0, 7, 30, 0x734, 0x868, 0x934, 0xA34 },
+	{ "gpa0", 0, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpa1", 0, 0x020, 6, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpa2", 0, 0x040, 8, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpb0", 0, 0x060, 5, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpb1", 0, 0x080, 5, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpb2", 0, 0x0A0, 4, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpb3", 0, 0x0C0, 4, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gpc0", 0, 0x0E0, 7, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gpc1", 0, 0x100, 4, 0x720, 0x840, 0x920, 0xA20 },
+	{ "gpc2", 0, 0x120, 7, 0x724, 0x848, 0x924, 0xA24 },
+	{ "gpc3", 0, 0x140, 7, 0x728, 0x850, 0x928, 0xA28 },
+	{ "gpd0", 0, 0x160, 4, 0x72C, 0x858, 0x92C, 0xA2C },
+	{ "gpd1", 0, 0x180, 8, 0x730, 0x860, 0x930, 0xA30 },
+	{ "gpy0", 0, 0x1A0, 6,     0,     0,     0,     0 },
+	{ "gpy1", 0, 0x1C0, 4,     0,     0,     0,     0 },
+	{ "gpy2", 0, 0x1E0, 6,     0,     0,     0,     0 },
+	{ "gpy3", 0, 0x200, 8,     0,     0,     0,     0 },
+	{ "gpy4", 0, 0x220, 8,     0,     0,     0,     0 },
+	{ "gpy5", 0, 0x240, 8,     0,     0,     0,     0 },
+	{ "gpy6", 0, 0x260, 8,     0,     0,     0,     0 },
+	{ "gpc4", 0, 0x2E0, 7, 0x734, 0x868, 0x934, 0xA34 },
 
 	/* next 32 */
-	{ "gpx0", 0, 0xC00, 8, 40, 0xE00, 0xE80, 0xF00, 0xF40 },
-	{ "gpx1", 0, 0xC20, 8, 41, 0xE04, 0xE88, 0xF04, 0xF44 },
-	{ "gpx2", 0, 0xC40, 8, 42, 0xE08, 0xE90, 0xF08, 0xF48 },
-	{ "gpx3", 0, 0xC60, 8, 43, 0xE0C, 0xE98, 0xF0C, 0xF4C },
+	{ "gpx0", 0, 0xC00, 8, 0xE00, 0xE80, 0xF00, 0xF40 },
+	{ "gpx1", 0, 0xC20, 8, 0xE04, 0xE88, 0xF04, 0xF44 },
+	{ "gpx2", 0, 0xC40, 8, 0xE08, 0xE90, 0xF08, 0xF48 },
+	{ "gpx3", 0, 0xC60, 8, 0xE0C, 0xE98, 0xF0C, 0xF4C },
 
-	{ "gpe0", 1, 0x000, 8, 14, 0x700, 0x800, 0x900, 0xA00 },
-	{ "gpe1", 1, 0x020, 2, 15, 0x704, 0x808, 0x904, 0xA04 },
-	{ "gpf0", 1, 0x040, 4, 16, 0x708, 0x810, 0x908, 0xA08 },
-	{ "gpf1", 1, 0x060, 4, 17, 0x70C, 0x818, 0x90C, 0xA0C },
-	{ "gpg0", 1, 0x080, 8, 18, 0x710, 0x820, 0x910, 0xA10 },
-	{ "gpg1", 1, 0x0A0, 8, 19, 0x714, 0x828, 0x914, 0xA14 },
-	{ "gpg2", 1, 0x0C0, 2, 20, 0x718, 0x830, 0x918, 0xA18 },
-	{ "gph0", 1, 0x0E0, 4, 21, 0x71C, 0x838, 0x91C, 0xA1C },
-	{ "gph1", 1, 0x100, 8, 22, 0x720, 0x840, 0x920, 0xA20 },
+	{ "gpe0", 1, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpe1", 1, 0x020, 2, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpf0", 1, 0x040, 4, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpf1", 1, 0x060, 4, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpg0", 1, 0x080, 8, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpg1", 1, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpg2", 1, 0x0C0, 2, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gph0", 1, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gph1", 1, 0x100, 8, 0x720, 0x840, 0x920, 0xA20 },
 
-	{ "gpv0", 2, 0x000, 8, 60, 0x700, 0x800, 0x900, 0xA00 },
-	{ "gpv1", 2, 0x020, 8, 61, 0x704, 0x808, 0x904, 0xA04 },
-	{ "gpv2", 2, 0x060, 8, 62, 0x708, 0x810, 0x908, 0xA08 },
-	{ "gpv3", 2, 0x080, 8, 63, 0x70C, 0x818, 0x90C, 0xA0C },
-	{ "gpv4", 2, 0x0C0, 2, 64, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpv0", 2, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpv1", 2, 0x020, 8, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpv2", 2, 0x060, 8, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpv3", 2, 0x080, 8, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpv4", 2, 0x0C0, 2, 0x710, 0x820, 0x910, 0xA10 },
 
-	{ "gpz",  3, 0x000, 7, 50, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpz",  3, 0x000, 7, 0x700, 0x800, 0x900, 0xA00 },
+
+	{ NULL, -1, -1, -1, -1, -1, -1, -1 },
 };
 
+static struct gpio_bank gpio_map_5420[] = {
+	/* First 40 */
+	{ "gpy7", 0, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpx0", 0, 0xC00, 8, 0x704, 0xE80, 0xF00, 0xF40 },
+	{ "gpx1", 0, 0xC20, 8, 0x708, 0xE88, 0xF04, 0xF44 },
+	{ "gpx2", 0, 0xC40, 8, 0x70C, 0xE90, 0xF08, 0xF48 },
+	{ "gpx3", 0, 0xC60, 8, 0x710, 0xE98, 0xF0C, 0xF4C },
+
+	/* Next 85 */
+	{ "gpc0", 1, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpc1", 1, 0x020, 8, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpc2", 1, 0x040, 7, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpc3", 1, 0x060, 4, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpc4", 1, 0x080, 2, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpd1", 1, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpy0", 1, 0x0C0, 6, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gpy1", 1, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gpy2", 1, 0x100, 6, 0x720, 0x840, 0x920, 0xA20 },
+	{ "gpy3", 1, 0x120, 8, 0x724, 0x848, 0x924, 0xA24 },
+	{ "gpy4", 1, 0x140, 8, 0x728, 0x850, 0x928, 0xA28 },
+	{ "gpy5", 1, 0x160, 8, 0x72C, 0x858, 0x92C, 0xA2C },
+	{ "gpy6", 1, 0x180, 8, 0x730, 0x860, 0x930, 0xA30 },
+
+	/* Next 46 */
+	{ "gpe0", 2, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpe1", 2, 0x020, 2, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpf0", 2, 0x040, 6, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpf1", 2, 0x060, 8, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpg0", 2, 0x080, 8, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpg1", 2, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpg2", 2, 0x0C0, 2, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gpj4", 2, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C },
+
+	/* Next 54 */
+	{ "gpa0", 3, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpa1", 3, 0x020, 6, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpa2", 3, 0x040, 8, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpb0", 3, 0x060, 5, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpb1", 3, 0x080, 5, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpb2", 3, 0x0A0, 4, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpb3", 3, 0x0C0, 8, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gpb4", 3, 0x0E0, 2, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gph0", 3, 0x100, 8, 0x720, 0x840, 0x920, 0xA20 },
+
+	/* Last 7 */
+	{ "gpz",  4, 0x000, 7, 0x700, 0x800, 0x900, 0xA00 },
+
+	{ NULL, -1, -1, -1, -1, -1, -1, -1 },
+};
+
 static int
-get_bank(int gpio_number, struct gpio_bank *bank, int *pin_shift)
+get_bank(struct pad_softc *sc, int gpio_number,
+    struct gpio_bank *bank, int *pin_shift)
 {
 	int ngpio;
 	int i;
@@ -221,17 +324,17 @@
 	int n;
 
 	n = 0;
-	for (i = 0; i < NGRP; i++) {
-		ngpio = gpio_map[i].ngpio;
+	for (i = 0; sc->gpio_map[i].ngpio != -1; i++) {
+		ngpio = sc->gpio_map[i].ngpio;
 
-		if ((n + ngpio) >= gpio_number) {
-			*bank = gpio_map[i];
+		if ((n + ngpio) > gpio_number) {
+			*bank = sc->gpio_map[i];
 			*pin_shift = (gpio_number - n);
 			return (0);
-		};
+		}
 
 		n += ngpio;
-	};
+	}
 
 	return (-1);
 }
@@ -261,16 +364,16 @@
 	sc = arg;
 
 	n = 0;
-	for (i = 0; i < NGRP; i++) {
+	for (i = 0; sc->gpio_map[i].ngpio != -1; i++) {
 		found = 0;
-		ngpio = gpio_map[i].ngpio;
+		ngpio = sc->gpio_map[i].ngpio;
 
-		if (gpio_map[i].pend == 0) {
+		if (sc->gpio_map[i].pend == 0) {
 			n += ngpio;
 			continue;
 		}
 
-		reg = READ4(sc, gpio_map[i].port, gpio_map[i].pend);
+		reg = READ4(sc, sc->gpio_map[i].port, sc->gpio_map[i].pend);
 
 		for (j = 0; j < ngpio; j++) {
 			if (reg & (1 << j)) {
@@ -287,7 +390,7 @@
 
 		if (found) {
 			/* ACK */
-			WRITE4(sc, gpio_map[i].port, gpio_map[i].pend, reg);
+			WRITE4(sc, sc->gpio_map[i].port, sc->gpio_map[i].pend, reg);
 		}
 
 		n += ngpio;
@@ -308,17 +411,17 @@
 	sc = gpio_sc;
 
 	if (sc == NULL) {
-		device_printf(sc->dev, "Error: pad is not attached\n");
+		printf("%s: Error: pad is not attached\n", __func__);
 		return (-1);
 	}
 
-	if (get_bank(gpio_number, &bank, &pin_shift) != 0)
+	if (get_bank(sc, gpio_number, &bank, &pin_shift) != 0)
 		return (-1);
 
 	entry = NULL;
-	for (i = 0; i < NINTS; i++)
-		if (interrupt_table[i].gpio_number == gpio_number)
-			entry = &interrupt_table[i];
+	for (i = 0; i < N_EXT_INTS; i++)
+		if (sc->interrupt_table[i].gpio_number == gpio_number)
+			entry = &(sc->interrupt_table[i]);
 
 	if (entry == NULL) {
 		device_printf(sc->dev, "Cant find interrupt source for %d\n",
@@ -375,11 +478,12 @@
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-	if (!ofw_bus_is_compatible(dev, "exynos,pad"))
-		return (ENXIO);
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "Exynos Pad Control");
+		return (BUS_PROBE_DEFAULT);
+	}
 
-	device_set_desc(dev, "Exynos Pad Control");
-	return (BUS_PROBE_DEFAULT);
+	return (ENXIO);
 }
 
 static int
@@ -392,40 +496,60 @@
 	int i;
 
 	sc = device_get_softc(dev);
+
 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
 
-	if (bus_alloc_resources(dev, pad_spec, sc->res)) {
+	sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+	switch (sc->model) {
+	case EXYNOS5250:
+		sc->pad_spec = pad_spec_5250;
+		sc->gpio_map = gpio_map_5250;
+		sc->interrupt_table = interrupt_table_5250;
+		sc->gpio_npins = 253;
+		sc->nports = 4;
+		break;
+	case EXYNOS5420:
+		sc->pad_spec = pad_spec_5420;
+		sc->gpio_map = gpio_map_5420;
+		sc->interrupt_table = interrupt_table_5420;
+		sc->gpio_npins = 232;
+		sc->nports = 5;
+		break;
+	default:
+		goto fail;
+	}
+
+	if (bus_alloc_resources(dev, sc->pad_spec, sc->res)) {
 		device_printf(dev, "could not allocate resources\n");
-		return (ENXIO);
+		goto fail;
 	}
 
 	/* Memory interface */
 
-	for (i = 0; i < NPORTS; i++) {
+	for (i = 0; i < sc->nports; i++) {
 		sc->bst[i] = rman_get_bustag(sc->res[i]);
 		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
-	};
+	}
 
 	sc->dev = dev;
-	sc->gpio_npins = NGPIO;
 
 	gpio_sc = sc;
 
-	for (i = 0; i < NPORTS; i++) {
-		if ((bus_setup_intr(dev, sc->res[NPORTS + i],
+	for (i = 0; i < sc->nports; i++) {
+		if ((bus_setup_intr(dev, sc->res[sc->nports + i],
 			    INTR_TYPE_BIO | INTR_MPSAFE, port_intr,
 			    NULL, sc, &sc->gpio_ih[i]))) {
 			device_printf(dev,
 			    "ERROR: Unable to register interrupt handler\n");
-			return (ENXIO);
+			goto fail;
 		}
-	};
+	}
 
 	for (i = 0; i < sc->gpio_npins; i++) {
 		sc->gpio_pins[i].gp_pin = i;
 		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
 
-		if (get_bank(i, &bank, &pin_shift) != 0)
+		if (get_bank(sc, i, &bank, &pin_shift) != 0)
 			continue;
 
 		pin_shift *= 4;
@@ -441,18 +565,42 @@
 		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
 		    "pad%d.%d", device_get_unit(dev), i);
 	}
+	sc->busdev = gpiobus_attach_bus(dev);
+	if (sc->busdev == NULL)
+		goto fail;
 
-	device_add_child(dev, "gpioc", -1);
-	device_add_child(dev, "gpiobus", -1);
+	return (0);
 
-	return (bus_generic_attach(dev));
+fail:
+	for (i = 0; i < sc->nports; i++) {
+		if (sc->gpio_ih[i])
+			bus_teardown_intr(dev, sc->res[sc->nports + i],
+			    sc->gpio_ih[i]);
+	}
+	bus_release_resources(dev, sc->pad_spec, sc->res);
+	mtx_destroy(&sc->sc_mtx);
+
+	return (ENXIO);
 }
 
+static device_t
+pad_get_bus(device_t dev)
+{
+	struct pad_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	return (sc->busdev);
+}
+
 static int
 pad_pin_max(device_t dev, int *maxpin)
 {
+	struct pad_softc *sc;
 
-	*maxpin = NGPIO - 1;
+	sc = device_get_softc(dev);
+
+	*maxpin = sc->gpio_npins - 1;
 	return (0);
 }
 
@@ -539,7 +687,7 @@
 	if (i >= sc->gpio_npins)
 		return (EINVAL);
 
-	if (get_bank(pin, &bank, &pin_shift) != 0)
+	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
 		return (EINVAL);
 
 	GPIO_LOCK(sc);
@@ -570,7 +718,7 @@
 	if (i >= sc->gpio_npins)
 		return (EINVAL);
 
-	if (get_bank(pin, &bank, &pin_shift) != 0)
+	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
 		return (EINVAL);
 
 	GPIO_LOCK(sc);
@@ -602,7 +750,7 @@
 	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
 		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
 
-		if (get_bank(pin->gp_pin, &bank, &pin_shift) != 0)
+		if (get_bank(sc, pin->gp_pin, &bank, &pin_shift) != 0)
 			return;
 
 		pin_shift *= 4;
@@ -667,7 +815,7 @@
 	if (i >= sc->gpio_npins)
 		return (EINVAL);
 
-	if (get_bank(pin, &bank, &pin_shift) != 0)
+	if (get_bank(sc, pin, &bank, &pin_shift) != 0)
 		return (EINVAL);
 
 	GPIO_LOCK(sc);
@@ -686,6 +834,7 @@
 	DEVMETHOD(device_attach,	pad_attach),
 
 	/* GPIO protocol */
+	DEVMETHOD(gpio_get_bus,		pad_get_bus),
 	DEVMETHOD(gpio_pin_max,		pad_pin_max),
 	DEVMETHOD(gpio_pin_getname,	pad_pin_getname),
 	DEVMETHOD(gpio_pin_getcaps,	pad_pin_getcaps),

Modified: trunk/sys/arm/samsung/exynos/exynos5_pad.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pad.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos5_pad.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_pad.h 266341 2014-05-17 19:37:04Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_pad.h 263936 2014-03-30 15:22:36Z br $
  */
 
 int pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user);

Added: trunk/sys/arm/samsung/exynos/exynos5_pmu.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pmu.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_pmu.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,180 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Exynos 5 Power Management Unit (PMU)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_pmu.c 269703 2014-08-08 06:30:17Z nwhitehorn $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+#include <arm/samsung/exynos/exynos5_pmu.h>
+
+#define	EXYNOS5250	1
+#define	EXYNOS5420	2
+
+/* PWR control */
+#define	EXYNOS5_PWR_USBHOST_PHY		0x708
+#define	EXYNOS5_USBDRD_PHY_CTRL		0x704
+#define	EXYNOS5420_USBDRD1_PHY_CTRL	0x708
+
+#define	PHY_POWER_ON			1
+#define	PHY_POWER_OFF			0
+
+struct pmu_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+	int			model;
+};
+
+struct pmu_softc *pmu_sc;
+
+static struct ofw_compat_data compat_data[] = {
+	{"samsung,exynos5420-pmu",	EXYNOS5420},
+	{"samsung,exynos5250-pmu",	EXYNOS5250},
+	{NULL, 0}
+};
+
+static struct resource_spec pmu_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+pmu_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "Samsung Exynos 5 Power Management Unit");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+int
+usb2_phy_power_on(void)
+{
+	struct pmu_softc *sc;
+
+	sc = pmu_sc;
+	if (sc == NULL)
+		return (-1);
+
+	/* EHCI */
+	WRITE4(sc, EXYNOS5_PWR_USBHOST_PHY, PHY_POWER_ON);
+
+	return (0);
+}
+
+int
+usbdrd_phy_power_on(void)
+{
+	struct pmu_softc *sc;
+
+	sc = pmu_sc;
+	if (sc == NULL)
+		return (-1);
+
+	/*
+	 * First XHCI controller (left-side USB port on chromebook2)
+	 */
+	WRITE4(sc, EXYNOS5_USBDRD_PHY_CTRL, PHY_POWER_ON);
+
+	/*
+	 * Second XHCI controller (right-side USB port on chrombook2)
+	 * Only available on 5420.
+	 */
+	if (sc->model == EXYNOS5420)
+		WRITE4(sc, EXYNOS5420_USBDRD1_PHY_CTRL, PHY_POWER_ON);
+
+	return (0);
+}
+
+static int
+pmu_attach(device_t dev)
+{
+	struct pmu_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	sc->model = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+
+	if (bus_alloc_resources(dev, pmu_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	pmu_sc = sc;
+
+	return (0);
+}
+
+static device_method_t pmu_methods[] = {
+	DEVMETHOD(device_probe,		pmu_probe),
+	DEVMETHOD(device_attach,	pmu_attach),
+	{ 0, 0 }
+};
+
+static driver_t pmu_driver = {
+	"pmu",
+	pmu_methods,
+	sizeof(struct pmu_softc),
+};
+
+static devclass_t pmu_devclass;
+
+DRIVER_MODULE(pmu, simplebus, pmu_driver, pmu_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_pmu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_pmu.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pmu.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_pmu.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,31 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/11/sys/arm/samsung/exynos/exynos5_pmu.h 269369 2014-08-01 06:20:25Z br $
+ */
+
+int usb2_phy_power_on(void);
+int usbdrd_phy_power_on(void);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_pmu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_spi.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_spi.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_spi.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,237 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Exynos 5 Serial Peripheral Interface (SPI)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_spi.c 331506 2018-03-24 23:23:31Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#include "spibus_if.h"
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+
+#define	CH_CFG		0x00		/* SPI configuration */
+#define	 SW_RST		(1 << 5)	/* Reset */
+#define	 RX_CH_ON	(1 << 1)	/* SPI Rx Channel On */
+#define	 TX_CH_ON	(1 << 0)	/* SPI Tx Channel On */
+#define	MODE_CFG	0x08		/* FIFO control */
+#define	CS_REG		0x0C		/* slave selection control */
+#define	 NSSOUT		(1 << 0)
+#define	SPI_INT_EN	0x10		/* interrupt enable */
+#define	SPI_STATUS	0x14		/* SPI status */
+#define	 TX_FIFO_LVL_S	6
+#define	 TX_FIFO_LVL_M	0x1ff
+#define	 RX_FIFO_LVL_S	15
+#define	 RX_FIFO_LVL_M	0x1ff
+#define	SPI_TX_DATA	0x18		/* Tx data */
+#define	SPI_RX_DATA	0x1C		/* Rx data */
+#define	PACKET_CNT_REG	0x20		/* packet count */
+#define	PENDING_CLR_REG	0x24		/* interrupt pending clear */
+#define	SWAP_CFG	0x28		/* swap configuration */
+#define	FB_CLK_SEL	0x2C		/* feedback clock selection */
+#define	 FB_CLK_180	0x2		/* 180 degree phase lagging */
+
+struct spi_softc {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+};
+
+struct spi_softc *spi_sc;
+
+static struct resource_spec spi_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+spi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "samsung,exynos5-spi"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Exynos 5 Serial Peripheral Interface (SPI)");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+spi_attach(device_t dev)
+{
+	struct spi_softc *sc;
+	int reg;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, spi_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	spi_sc = sc;
+
+	WRITE4(sc, FB_CLK_SEL, FB_CLK_180);
+
+	reg = READ4(sc, CH_CFG);
+	reg |= (RX_CH_ON | TX_CH_ON);
+	WRITE4(sc, CH_CFG, reg);
+
+	device_add_child(dev, "spibus", 0);
+	return (bus_generic_attach(dev));
+}
+
+static int
+spi_txrx(struct spi_softc *sc, uint8_t *out_buf,
+    uint8_t *in_buf, int bufsz, int cs)
+{
+	uint32_t reg;
+	uint32_t i;
+
+	if (bufsz == 0) {
+		/* Nothing to transfer */
+		return (0);
+	}
+
+	/* Reset registers */
+	reg = READ4(sc, CH_CFG);
+	reg |= SW_RST;
+	WRITE4(sc, CH_CFG, reg);
+	reg &= ~SW_RST;
+	WRITE4(sc, CH_CFG, reg);
+
+	/* Assert CS */
+	reg = READ4(sc, CS_REG);
+	reg &= ~NSSOUT;
+	WRITE4(sc, CS_REG, reg);
+
+	for (i = 0; i < bufsz; i++) {
+
+		/* TODO: Implement FIFO operation */
+
+		/* Wait all the data shifted out */
+		while (READ4(sc, SPI_STATUS) & \
+		    (TX_FIFO_LVL_M << TX_FIFO_LVL_S))
+			continue;
+
+		WRITE1(sc, SPI_TX_DATA, out_buf[i]);
+
+		/* Wait until no data available */
+		while ((READ4(sc, SPI_STATUS) & \
+			(RX_FIFO_LVL_M << RX_FIFO_LVL_S)) == 0)
+			continue;
+
+		in_buf[i] = READ1(sc, SPI_RX_DATA);
+	}
+
+	/* Deassert CS */
+	reg = READ4(sc, CS_REG);
+	reg |= NSSOUT;
+	WRITE4(sc, CS_REG, reg);
+
+	return (0);
+}
+
+static int
+spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
+{
+	struct spi_softc *sc;
+	uint32_t cs;
+
+	sc = device_get_softc(dev);
+
+	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
+	    ("%s: TX/RX command sizes should be equal", __func__));
+	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
+	    ("%s: TX/RX data sizes should be equal", __func__));
+
+	/* get the proper chip select */
+	spibus_get_cs(child, &cs);
+
+	cs &= ~SPIBUS_CS_HIGH;
+
+	/* Command */
+	spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs);
+
+	/* Data */
+	spi_txrx(sc, cmd->tx_data, cmd->rx_data, cmd->tx_data_sz, cs);
+
+	return (0);
+}
+
+static device_method_t spi_methods[] = {
+	DEVMETHOD(device_probe,		spi_probe),
+	DEVMETHOD(device_attach,	spi_attach),
+
+	/* SPI interface */
+	DEVMETHOD(spibus_transfer,	spi_transfer),
+
+	{ 0, 0 }
+};
+
+static driver_t spi_driver = {
+	"spi",
+	spi_methods,
+	sizeof(struct spi_softc),
+};
+
+static devclass_t spi_devclass;
+
+DRIVER_MODULE(spi, simplebus, spi_driver, spi_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_spi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_usb_phy.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_usb_phy.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_usb_phy.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,272 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * DWC3 USB 3.0 DRD (dual role device) PHY
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_usb_phy.c 299069 2016-05-04 15:48:59Z pfg $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/gpio.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+#include <arm/samsung/exynos/exynos5_pmu.h>
+
+#include "gpio_if.h"
+
+#define	USB_DRD_LINKSYSTEM			0x04
+#define	 LINKSYSTEM_FLADJ_MASK			(0x3f << 1)
+#define	 LINKSYSTEM_FLADJ(x)			((x) << 1)
+#define	 LINKSYSTEM_XHCI_VERSION_CTRL		(1 << 27)
+#define	USB_DRD_PHYUTMI				0x08
+#define	 PHYUTMI_OTGDISABLE			(1 << 6)
+#define	 PHYUTMI_FORCESUSPEND			(1 << 1)
+#define	 PHYUTMI_FORCESLEEP			(1 << 0)
+#define	USB_DRD_PHYPIPE				0x0c
+#define	USB_DRD_PHYCLKRST			0x10
+#define	 PHYCLKRST_PORTRESET			(1 << 1)
+#define	 PHYCLKRST_COMMONONN			(1 << 0)
+#define	 PHYCLKRST_EN_UTMISUSPEND		(1 << 31)
+#define	 PHYCLKRST_SSC_REFCLKSEL_MASK		(0xff << 23)
+#define	 PHYCLKRST_SSC_REFCLKSEL(x)		((x) << 23)
+#define	 PHYCLKRST_SSC_RANGE_MASK		(0x03 << 21)
+#define	 PHYCLKRST_SSC_RANGE(x)			((x) << 21)
+#define	 PHYCLKRST_SSC_EN			(1 << 20)
+#define	 PHYCLKRST_REF_SSP_EN			(1 << 19)
+#define	 PHYCLKRST_REF_CLKDIV2			(1 << 18)
+#define	 PHYCLKRST_MPLL_MLTPR_MASK		(0x7f << 11)
+#define	 PHYCLKRST_MPLL_MLTPR_100MHZ		(0x19 << 11)
+#define	 PHYCLKRST_MPLL_MLTPR_50M		(0x32 << 11)
+#define	 PHYCLKRST_MPLL_MLTPR_24MHZ		(0x68 << 11)
+#define	 PHYCLKRST_MPLL_MLTPR_20MHZ		(0x7d << 11)
+#define	 PHYCLKRST_MPLL_MLTPR_19200KHZ		(0x02 << 11)
+#define	 PHYCLKRST_FSEL_UTMI_MASK		(0x7 << 5)
+#define	 PHYCLKRST_FSEL_PIPE_MASK		(0x7 << 8)
+#define	 PHYCLKRST_FSEL(x)			((x) << 5)
+#define	 PHYCLKRST_FSEL_9MHZ6			0x0
+#define	 PHYCLKRST_FSEL_10MHZ			0x1
+#define	 PHYCLKRST_FSEL_12MHZ			0x2
+#define	 PHYCLKRST_FSEL_19MHZ2			0x3
+#define	 PHYCLKRST_FSEL_20MHZ			0x4
+#define	 PHYCLKRST_FSEL_24MHZ			0x5
+#define	 PHYCLKRST_FSEL_50MHZ			0x7
+#define	 PHYCLKRST_RETENABLEN			(1 << 4)
+#define	 PHYCLKRST_REFCLKSEL_MASK		(0x03 << 2)
+#define	 PHYCLKRST_REFCLKSEL_PAD_REFCLK		(0x2 << 2)
+#define	 PHYCLKRST_REFCLKSEL_EXT_REFCLK		(0x3 << 2)
+#define	USB_DRD_PHYREG0				0x14
+#define	USB_DRD_PHYREG1				0x18
+#define	USB_DRD_PHYPARAM0			0x1c
+#define	 PHYPARAM0_REF_USE_PAD			(1 << 31)
+#define	 PHYPARAM0_REF_LOSLEVEL_MASK		(0x1f << 26)
+#define	 PHYPARAM0_REF_LOSLEVEL			(0x9 << 26)
+#define	USB_DRD_PHYPARAM1			0x20
+#define	 PHYPARAM1_PCS_TXDEEMPH_MASK		(0x1f << 0)
+#define	 PHYPARAM1_PCS_TXDEEMPH			(0x1c)
+#define	USB_DRD_PHYTERM				0x24
+#define	USB_DRD_PHYTEST				0x28
+#define	 PHYTEST_POWERDOWN_SSP			(1 << 3)
+#define	 PHYTEST_POWERDOWN_HSP			(1 << 2)
+#define	USB_DRD_PHYADP				0x2c
+#define	USB_DRD_PHYUTMICLKSEL			0x30
+#define	 PHYUTMICLKSEL_UTMI_CLKSEL		(1 << 2)
+#define	USB_DRD_PHYRESUME			0x34
+#define	USB_DRD_LINKPORT			0x44
+
+struct usb_phy_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+};
+
+static struct resource_spec usb_phy_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+usb_phy_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "samsung,exynos5420-usbdrd-phy"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Samsung Exynos 5 USB PHY");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+vbus_on(struct usb_phy_softc *sc)
+{
+	pcell_t dts_value[3];
+	device_t gpio_dev;
+	phandle_t node;
+	pcell_t pin;
+	int len;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (-1);
+
+	/* Power pin */
+	if ((len = OF_getproplen(node, "vbus-supply")) <= 0)
+		return (-1);
+	OF_getencprop(node, "vbus-supply", dts_value, len);
+	pin = dts_value[0];
+
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (gpio_dev == NULL) {
+		device_printf(sc->dev, "can't find gpio_dev\n");
+		return (1);
+	}
+
+	GPIO_PIN_SETFLAGS(gpio_dev, pin, GPIO_PIN_OUTPUT);
+	GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_HIGH);
+
+	return (0);
+}
+
+static int
+usb3_phy_init(struct usb_phy_softc *sc)
+{
+	int reg;
+
+	/* Reset USB 3.0 PHY */
+	WRITE4(sc, USB_DRD_PHYREG0, 0);
+
+	reg = READ4(sc, USB_DRD_PHYPARAM0);
+	/* PHY CLK src */
+	reg &= ~(PHYPARAM0_REF_USE_PAD);
+	reg &= ~(PHYPARAM0_REF_LOSLEVEL_MASK);
+	reg |= (PHYPARAM0_REF_LOSLEVEL);
+	WRITE4(sc, USB_DRD_PHYPARAM0, reg);
+	WRITE4(sc, USB_DRD_PHYRESUME, 0);
+
+	reg = (LINKSYSTEM_XHCI_VERSION_CTRL |
+	    LINKSYSTEM_FLADJ(0x20));
+	WRITE4(sc, USB_DRD_LINKSYSTEM, reg);
+
+	reg = READ4(sc, USB_DRD_PHYPARAM1);
+	reg &= ~(PHYPARAM1_PCS_TXDEEMPH_MASK);
+	reg |= (PHYPARAM1_PCS_TXDEEMPH);
+	WRITE4(sc, USB_DRD_PHYPARAM1, reg);
+
+	reg = READ4(sc, USB_DRD_PHYUTMICLKSEL);
+	reg |= (PHYUTMICLKSEL_UTMI_CLKSEL);
+	WRITE4(sc, USB_DRD_PHYUTMICLKSEL, reg);
+
+	reg = READ4(sc, USB_DRD_PHYTEST);
+	reg &= ~(PHYTEST_POWERDOWN_HSP);
+	reg &= ~(PHYTEST_POWERDOWN_SSP);
+	WRITE4(sc, USB_DRD_PHYTEST, reg);
+
+	WRITE4(sc, USB_DRD_PHYUTMI, PHYUTMI_OTGDISABLE);
+
+	/* Clock */
+	reg = (PHYCLKRST_REFCLKSEL_EXT_REFCLK);
+	reg |= (PHYCLKRST_FSEL(PHYCLKRST_FSEL_24MHZ));
+	reg |= (PHYCLKRST_MPLL_MLTPR_24MHZ);
+	reg |= (PHYCLKRST_SSC_REFCLKSEL(0x88));
+	reg |= (PHYCLKRST_RETENABLEN |
+	    PHYCLKRST_REF_SSP_EN | /* Super speed */
+	    PHYCLKRST_SSC_EN | /* Spread spectrum */
+	    PHYCLKRST_COMMONONN |
+	    PHYCLKRST_PORTRESET);
+
+	WRITE4(sc, USB_DRD_PHYCLKRST, reg);
+	DELAY(50000);
+	reg &= ~PHYCLKRST_PORTRESET;
+	WRITE4(sc, USB_DRD_PHYCLKRST, reg);
+
+	return (0);
+}
+
+static int
+usb_phy_attach(device_t dev)
+{
+	struct usb_phy_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, usb_phy_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	vbus_on(sc);
+
+	usbdrd_phy_power_on();
+
+	DELAY(100);
+
+	usb3_phy_init(sc);
+
+	return (0);
+}
+
+static device_method_t usb_phy_methods[] = {
+	DEVMETHOD(device_probe,		usb_phy_probe),
+	DEVMETHOD(device_attach,	usb_phy_attach),
+	{ 0, 0 }
+};
+
+static driver_t usb_phy_driver = {
+	"usb_phy",
+	usb_phy_methods,
+	sizeof(struct usb_phy_softc),
+};
+
+static devclass_t usb_phy_devclass;
+
+DRIVER_MODULE(usb_phy, simplebus, usb_phy_driver, usb_phy_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_usb_phy.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_xhci.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_xhci.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_xhci.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -0,0 +1,314 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos5_xhci.c 308401 2016-11-07 08:36:06Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/xhci.h>
+#include <dev/usb/controller/xhcireg.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+
+#include "opt_platform.h"
+
+#define	GSNPSID				0x20
+#define	 GSNPSID_MASK			0xffff0000
+#define	 REVISION_MASK			0xffff
+#define	GCTL				0x10
+#define	 GCTL_PWRDNSCALE(n)		((n) << 19)
+#define	 GCTL_U2RSTECN			(1 << 16)
+#define	 GCTL_CLK_BUS			(0)
+#define	 GCTL_CLK_PIPE			(1)
+#define	 GCTL_CLK_PIPEHALF		(2)
+#define	 GCTL_CLK_M			(3)
+#define	 GCTL_CLK_S			(6)
+#define	 GCTL_PRTCAP(n)			(((n) & (3 << 12)) >> 12)
+#define	 GCTL_PRTCAPDIR(n)		((n) << 12)
+#define	 GCTL_PRTCAP_HOST		1
+#define	 GCTL_PRTCAP_DEVICE		2
+#define	 GCTL_PRTCAP_OTG		3
+#define	 GCTL_CORESOFTRESET		(1 << 11)
+#define	 GCTL_SCALEDOWN_MASK		3
+#define	 GCTL_SCALEDOWN_SHIFT		4
+#define	 GCTL_DISSCRAMBLE		(1 << 3)
+#define	 GCTL_DSBLCLKGTNG		(1 << 0)
+#define	GHWPARAMS1			0x3c
+#define	 GHWPARAMS1_EN_PWROPT(n)	(((n) & (3 << 24)) >> 24)
+#define	 GHWPARAMS1_EN_PWROPT_NO	0
+#define	 GHWPARAMS1_EN_PWROPT_CLK	1
+#define	GUSB2PHYCFG(n)			(0x100 + (n * 0x04))
+#define	 GUSB2PHYCFG_PHYSOFTRST		(1 << 31)
+#define	 GUSB2PHYCFG_SUSPHY		(1 << 6)
+#define	GUSB3PIPECTL(n)			(0x1c0 + (n * 0x04))
+#define	 GUSB3PIPECTL_PHYSOFTRST	(1 << 31)
+#define	 GUSB3PIPECTL_SUSPHY		(1 << 17)
+
+/* Forward declarations */
+static device_attach_t exynos_xhci_attach;
+static device_detach_t exynos_xhci_detach;
+static device_probe_t exynos_xhci_probe;
+
+struct exynos_xhci_softc {
+	device_t		dev;
+	struct xhci_softc	base;
+	struct resource		*res[3];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct resource_spec exynos_xhci_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static device_method_t xhci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, exynos_xhci_probe),
+	DEVMETHOD(device_attach, exynos_xhci_attach),
+	DEVMETHOD(device_detach, exynos_xhci_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	DEVMETHOD_END
+};
+
+/* kobj_class definition */
+static driver_t xhci_driver = {
+	"xhci",
+	xhci_methods,
+	sizeof(struct xhci_softc)
+};
+
+static devclass_t xhci_devclass;
+
+DRIVER_MODULE(xhci, simplebus, xhci_driver, xhci_devclass, 0, 0);
+MODULE_DEPEND(xhci, usb, 1, 1, 1);
+
+/*
+ * Public methods
+ */
+static int
+exynos_xhci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "samsung,exynos5250-dwusb3") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Exynos USB 3.0 controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+dwc3_init(struct exynos_xhci_softc *esc)
+{
+	int hwparams1;
+	int rev;
+	int reg;
+
+	rev = READ4(esc, GSNPSID);
+	if ((rev & GSNPSID_MASK) != 0x55330000) {
+		printf("It is not DWC3 controller\n");
+		return (-1);
+	}
+
+	/* Reset controller */
+	WRITE4(esc, GCTL, GCTL_CORESOFTRESET);
+	WRITE4(esc, GUSB3PIPECTL(0), GUSB3PIPECTL_PHYSOFTRST);
+	WRITE4(esc, GUSB2PHYCFG(0), GUSB2PHYCFG_PHYSOFTRST);
+
+	DELAY(100000);
+
+	reg = READ4(esc, GUSB3PIPECTL(0));
+	reg &= ~(GUSB3PIPECTL_PHYSOFTRST);
+	WRITE4(esc, GUSB3PIPECTL(0), reg);
+
+	reg = READ4(esc, GUSB2PHYCFG(0));
+	reg &= ~(GUSB2PHYCFG_PHYSOFTRST);
+	WRITE4(esc, GUSB2PHYCFG(0), reg);
+
+	reg = READ4(esc, GCTL);
+	reg &= ~GCTL_CORESOFTRESET;
+	WRITE4(esc, GCTL, reg);
+
+	hwparams1 = READ4(esc, GHWPARAMS1);
+
+	reg = READ4(esc, GCTL);
+	reg &= ~(GCTL_SCALEDOWN_MASK << GCTL_SCALEDOWN_SHIFT);
+	reg &= ~(GCTL_DISSCRAMBLE);
+
+	if (GHWPARAMS1_EN_PWROPT(hwparams1) == \
+	    GHWPARAMS1_EN_PWROPT_CLK)
+		reg &= ~(GCTL_DSBLCLKGTNG);
+
+	if ((rev & REVISION_MASK) < 0x190a)
+		reg |= (GCTL_U2RSTECN);
+	WRITE4(esc, GCTL, reg);
+
+	/* Set host mode */
+	reg = READ4(esc, GCTL);
+	reg &= ~(GCTL_PRTCAPDIR(GCTL_PRTCAP_OTG));
+	reg |= GCTL_PRTCAPDIR(GCTL_PRTCAP_HOST);
+	WRITE4(esc, GCTL, reg);
+
+	return (0);
+}
+
+static int
+exynos_xhci_attach(device_t dev)
+{
+	struct exynos_xhci_softc *esc = device_get_softc(dev);
+	bus_space_handle_t bsh;
+	int err;
+
+	esc->dev = dev;
+
+	if (bus_alloc_resources(dev, exynos_xhci_spec, esc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* XHCI registers */
+	esc->base.sc_io_tag = rman_get_bustag(esc->res[0]);
+	bsh = rman_get_bushandle(esc->res[0]);
+	esc->base.sc_io_size = rman_get_size(esc->res[0]);
+
+	/* DWC3 ctrl registers */
+	esc->bst = rman_get_bustag(esc->res[1]);
+	esc->bsh = rman_get_bushandle(esc->res[1]);
+
+	/*
+	 * Set handle to USB related registers subregion used by
+	 * generic XHCI driver.
+	 */
+	err = bus_space_subregion(esc->base.sc_io_tag, bsh, 0x0,
+	    esc->base.sc_io_size, &esc->base.sc_io_hdl);
+	if (err != 0) {
+		device_printf(dev, "Subregion failed\n");
+		bus_release_resources(dev, exynos_xhci_spec, esc->res);
+		return (ENXIO);
+	}
+
+	if (xhci_init(&esc->base, dev, 0)) {
+		device_printf(dev, "Could not initialize softc\n");
+		bus_release_resources(dev, exynos_xhci_spec, esc->res);
+		return (ENXIO);
+	}
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, esc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (driver_intr_t *)xhci_interrupt, &esc->base,
+	    &esc->base.sc_intr_hdl);
+	if (err) {
+		device_printf(dev, "Could not setup irq, %d\n", err);
+		esc->base.sc_intr_hdl = NULL;
+		goto error;
+	}
+
+	/* Add USB device */
+	esc->base.sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (esc->base.sc_bus.bdev == NULL) {
+		device_printf(dev, "Could not add USB device\n");
+		goto error;
+	}
+	device_set_ivars(esc->base.sc_bus.bdev, &esc->base.sc_bus);
+	strlcpy(esc->base.sc_vendor, "Samsung", sizeof(esc->base.sc_vendor));
+
+	dwc3_init(esc);
+
+	err = xhci_halt_controller(&esc->base);
+	if (err == 0) {
+		device_printf(dev, "Starting controller\n");
+		err = xhci_start_controller(&esc->base);
+	}
+	if (err == 0) {
+		device_printf(dev, "Controller started\n");
+		err = device_probe_and_attach(esc->base.sc_bus.bdev);
+	}
+	if (err != 0)
+		goto error;
+	return (0);
+
+error:
+	exynos_xhci_detach(dev);
+	return (ENXIO);
+}
+
+static int
+exynos_xhci_detach(device_t dev)
+{
+	struct exynos_xhci_softc *esc = device_get_softc(dev);
+	int err;
+
+	/* During module unload there are lots of children leftover */
+	device_delete_children(dev);
+
+	xhci_halt_controller(&esc->base);
+	
+	if (esc->res[2] && esc->base.sc_intr_hdl) {
+		err = bus_teardown_intr(dev, esc->res[2],
+		    esc->base.sc_intr_hdl);
+		if (err) {
+			device_printf(dev, "Could not tear down IRQ,"
+			    " %d\n", err);
+			return (err);
+		}
+	}
+
+	bus_release_resources(dev, exynos_xhci_spec, esc->res);
+
+	xhci_uninit(&esc->base);
+	
+	return (0);
+}


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_xhci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/arm/samsung/exynos/exynos_uart.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos_uart.c	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos_uart.c	2020-03-06 17:05:09 UTC (rev 12395)
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos_uart.c 283327 2015-05-23 20:54:25Z ian $");
+__FBSDID("$FreeBSD: stable/11/sys/arm/samsung/exynos/exynos_uart.c 356020 2019-12-22 19:06:45Z kevans $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,7 +35,6 @@
 #include <sys/bus.h>
 #include <sys/conf.h>
 #include <sys/cons.h>
-#include <sys/tty.h>
 #include <sys/rman.h>
 #include <machine/bus.h>
 #include <machine/intr.h>
@@ -381,6 +380,7 @@
 	.uc_ops = &uart_exynos4210_ops,
 	.uc_range = 8,
 	.uc_rclk = 0,
+	.uc_rshift = 0
 };
 
 static struct ofw_compat_data compat_data[] = {

Modified: trunk/sys/arm/samsung/exynos/exynos_uart.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos_uart.h	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/exynos_uart.h	2020-03-06 17:05:09 UTC (rev 12395)
@@ -32,7 +32,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/10/sys/arm/samsung/exynos/exynos_uart.h 283322 2015-05-23 19:50:14Z ian $
+ * $FreeBSD: stable/11/sys/arm/samsung/exynos/exynos_uart.h 266944 2014-06-01 08:34:45Z br $
  */
 
 /* s3c2410-specific registers */

Modified: trunk/sys/arm/samsung/exynos/files.exynos5
===================================================================
--- trunk/sys/arm/samsung/exynos/files.exynos5	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/files.exynos5	2020-03-06 17:05:09 UTC (rev 12395)
@@ -1,18 +1,7 @@
-# $FreeBSD: stable/10/sys/arm/samsung/exynos/files.exynos5 283322 2015-05-23 19:50:14Z ian $
+# $FreeBSD: stable/11/sys/arm/samsung/exynos/files.exynos5 291135 2015-11-21 16:23:56Z andrew $
 
 kern/kern_clocksource.c				standard
 
-arm/arm/bus_space_generic.c			standard
-arm/arm/bus_space_asm_generic.S			standard
-arm/arm/cpufunc_asm_armv5.S			standard
-arm/arm/cpufunc_asm_arm10.S			standard
-arm/arm/cpufunc_asm_arm11.S			standard
-arm/arm/cpufunc_asm_armv7.S			standard
-
-arm/arm/bus_space_base.c			standard
-arm/arm/gic.c					standard
-arm/arm/generic_timer.c				standard
-
 arm/samsung/exynos/exynos5_mct.c		standard
 arm/samsung/exynos/exynos5_mp.c			optional	smp
 arm/samsung/exynos/exynos5_common.c		standard
@@ -21,11 +10,16 @@
 arm/samsung/exynos/exynos5_pad.c		optional	gpio
 arm/samsung/exynos/exynos_uart.c		optional	uart
 arm/samsung/exynos/exynos5_ehci.c		optional	ehci
+arm/samsung/exynos/exynos5_xhci.c		optional	xhci
 arm/samsung/exynos/exynos5_fimd.c		optional	vt
 arm/samsung/exynos/exynos5_i2c.c		optional	iicbus
+arm/samsung/exynos/exynos5_usb_phy.c		standard
+arm/samsung/exynos/exynos5_pmu.c		standard
+arm/samsung/exynos/exynos5_spi.c		optional	exynos_spi
 
 # chromebook drivers
-arm/samsung/exynos/chrome_ec.c			optional	chrome_ec
+arm/samsung/exynos/chrome_ec.c			optional	chrome_ec_i2c
+arm/samsung/exynos/chrome_ec_spi.c		optional	chrome_ec_spi
 arm/samsung/exynos/chrome_kb.c			optional	chrome_kb
 
-#dev/sdhci/sdhci_fdt.c				optional	sdhci
+dev/mmc/host/dwmmc.c				optional	dwmmc

Modified: trunk/sys/arm/samsung/exynos/std.exynos5250
===================================================================
--- trunk/sys/arm/samsung/exynos/std.exynos5250	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/std.exynos5250	2020-03-06 17:05:09 UTC (rev 12395)
@@ -1,21 +1,9 @@
-# $FreeBSD: stable/10/sys/arm/samsung/exynos/std.exynos5250 278601 2015-02-11 22:47:48Z ian $
+# $FreeBSD: stable/11/sys/arm/samsung/exynos/std.exynos5250 327658 2018-01-07 00:04:13Z ian $
 
-makeoption	ARM_LITTLE_ENDIAN
-
 cpu		CPU_CORTEXA
 machine		arm armv6
-makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoptions	CONF_CFLAGS="-march=armv7a"
 
-options		PHYSADDR=0x40000000
-
-makeoptions	KERNPHYSADDR=0x40f00000
-options		KERNPHYSADDR=0x40f00000
-
-makeoptions	KERNVIRTADDR=0xc0f00000
-options		KERNVIRTADDR=0xc0f00000
-
-options		ARM_L2_PIPT
-
 options		IPI_IRQ_START=0
 options		IPI_IRQ_END=15
 

Modified: trunk/sys/arm/samsung/exynos/std.exynos5420
===================================================================
--- trunk/sys/arm/samsung/exynos/std.exynos5420	2020-03-06 16:44:57 UTC (rev 12394)
+++ trunk/sys/arm/samsung/exynos/std.exynos5420	2020-03-06 17:05:09 UTC (rev 12395)
@@ -1,21 +1,9 @@
-# $FreeBSD: stable/10/sys/arm/samsung/exynos/std.exynos5420 278601 2015-02-11 22:47:48Z ian $
+# $FreeBSD: stable/11/sys/arm/samsung/exynos/std.exynos5420 327658 2018-01-07 00:04:13Z ian $
 
-makeoption	ARM_LITTLE_ENDIAN
-
 cpu		CPU_CORTEXA
 machine		arm armv6
-makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoptions	CONF_CFLAGS="-march=armv7a"
 
-options		PHYSADDR=0x20000000
-
-makeoptions	KERNPHYSADDR=0x20f00000
-options		KERNPHYSADDR=0x20f00000
-
-makeoptions	KERNVIRTADDR=0xc0f00000
-options		KERNVIRTADDR=0xc0f00000
-
-options		ARM_L2_PIPT
-
 options		IPI_IRQ_START=0
 options		IPI_IRQ_END=15
 



More information about the Midnightbsd-cvs mailing list