Module Name:    src
Committed By:   marty
Date:           Mon Dec 21 00:52:51 UTC 2015

Modified Files:
        src/sys/arch/arm/samsung: exynos_i2c.c files.exynos
        src/sys/arch/evbarm/conf: EXYNOS
Added Files:
        src/sys/arch/arm/samsung: exynos_chipid.c exynos_combiner.c
            exynos_rtc.c

Log Message:
XU4 FDT checkpoint

It is rather amazing that XU4 gets as far as it does, given how much of this
code simply doesn't work.  Focusing now on getting everything converted to
FDT. Next up USB and clocks.  After that nuke everything that's not needed
and start the port in earnest.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/samsung/exynos_chipid.c \
    src/sys/arch/arm/samsung/exynos_combiner.c \
    src/sys/arch/arm/samsung/exynos_rtc.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/samsung/exynos_i2c.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/samsung/files.exynos
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/conf/EXYNOS

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/samsung/exynos_i2c.c
diff -u src/sys/arch/arm/samsung/exynos_i2c.c:1.4 src/sys/arch/arm/samsung/exynos_i2c.c:1.5
--- src/sys/arch/arm/samsung/exynos_i2c.c:1.4	Fri Dec 11 04:03:44 2015
+++ src/sys/arch/arm/samsung/exynos_i2c.c	Mon Dec 21 00:52:50 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_i2c.c,v 1.4 2015/12/11 04:03:44 marty Exp $ */
+/*	$NetBSD: exynos_i2c.c,v 1.5 2015/12/21 00:52:50 marty Exp $ */
 
 /*
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,14 +30,12 @@
  *
  */
 
-
 #include "opt_exynos.h"
 #include "opt_arm_debug.h"
 #include "exynos_iic.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.4 2015/12/11 04:03:44 marty Exp $");
-
+__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.5 2015/12/21 00:52:50 marty Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -56,342 +54,256 @@ __KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c
 #include <dev/i2c/i2cvar.h>
 #include <dev/i2c/i2c_bitbang.h>
 
+#include <dev/fdt/fdtvar.h>
 
-struct exynos_iic_dev_softc {
-	int			isc_bus;
-	bool			isc_isgpio;
-
-	bus_space_tag_t		isc_bst;
-	bus_space_handle_t	isc_bsh;
-
-	struct exynos_gpio_pinset  isc_pinset;
-	struct exynos_gpio_pindata isc_sda;
-	struct exynos_gpio_pindata isc_slc;
-	bool			isc_sda_is_output;
-
-	kmutex_t		isc_buslock;
-	struct i2c_controller 	isc_i2cbus;
+struct exynos_i2c_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	void *			sc_ih;
+	u_int			sc_port;
+
+	struct fdtbus_gpio_pin  sc_sda;
+	struct fdtbus_gpio_pin  sc_slc;
+	bool			sc_sda_is_output;
+	struct i2c_controller 	sc_ic;
+	kmutex_t		sc_lock;
+	kcondvar_t		sc_cv;
+	device_t		sc_i2cdev;
 };
 
+static u_int i2c_port;
 
-#if NEXYNOS_IIC > 0
-static int	exynos_iic_acquire_bus(void *, int);
-static void	exynos_iic_release_bus(void *, int);
-
-static int	exynos_iic_send_start(void *, int);
-static int	exynos_iic_send_stop(void *, int);
-static int	exynos_iic_initiate_xfer(void *, i2c_addr_t, int);
-static int	exynos_iic_read_byte(void *, uint8_t *, int);
-static int	exynos_iic_write_byte(void *, uint8_t , int);
-
-static bool exynos_iic_attach_i2cbus(struct exynos_iic_dev_softc *,
-	struct i2c_controller *, struct exyo_locators const *);
-#endif
-
-
-struct i2c_controller *exynos_i2cbus[EXYNOS_MAX_IIC_BUSSES];
-static int exynos_iic_match(device_t, cfdata_t, void *);
-static void exynos_iic_attach(device_t, device_t, void *);
+static int	exynos_i2c_intr(void *);
 
-struct exynos_iic_softc {
-	device_t		sc_dev;
+static int	exynos_i2c_acquire_bus(void *, int);
+static void	exynos_i2c_release_bus(void *, int);
 
-	struct exynos_iic_dev_softc sc_idevs[EXYNOS_MAX_IIC_BUSSES];
-	struct i2c_controller       sc_i2cbus[EXYNOS_MAX_IIC_BUSSES];
-} exynos_iic_sc;
+static int	exynos_i2c_send_start(void *, int);
+static int	exynos_i2c_send_stop(void *, int);
+static int	exynos_i2c_initiate_xfer(void *, i2c_addr_t, int);
+static int	exynos_i2c_read_byte(void *, uint8_t *, int);
+static int	exynos_i2c_write_byte(void *, uint8_t , int);
 
+static bool exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *,
+				     struct i2c_controller *);
 
-CFATTACH_DECL_NEW(exynos_iic, sizeof(struct exynos_iic_softc),
-    exynos_iic_match, exynos_iic_attach, NULL, NULL);
+static int exynos_i2c_match(device_t, cfdata_t, void *);
+static void exynos_i2c_attach(device_t, device_t, void *);
 
+CFATTACH_DECL_NEW(exynos_i2c, sizeof(struct exynos_i2c_softc),
+    exynos_i2c_match, exynos_i2c_attach, NULL, NULL);
 
 static int
-exynos_iic_match(device_t self, cfdata_t cf, void *aux)
+exynos_i2c_match(device_t self, cfdata_t cf, void *aux)
 {
-#ifdef DIAGNOSTIC
-	struct exyo_attach_args *exyoaa = aux;
-	struct exyo_locators *loc = &exyoaa->exyo_loc;
-#endif
-	int i;
-
-	/* no locators expected */
-	KASSERT(loc->loc_offset == 0);
-	KASSERT(loc->loc_size   == 0);
-	KASSERT(loc->loc_port   == EXYOCF_PORT_DEFAULT);
+	const char * const compatible[] = { "samsung,s3c2440-i2c", NULL };
+	struct fdt_attach_args * const faa = aux;
 
-	if (exynos_iic_sc.sc_dev != NULL)
-		return 0;
-	for (i = 0; i < EXYNOS_MAX_IIC_BUSSES; i++)
-		exynos_i2cbus[i] = NULL;
-#if NEXYNOS_IIC > 0
-	return 1;
-#else
-	return 0;
-#endif
+	return of_match_compatible(faa->faa_phandle, compatible);
 }
 
-
 static void
-exynos_iic_attach(device_t parent, device_t self, void *aux)
+exynos_i2c_attach(device_t parent, device_t self, void *aux)
 {
-#if NEXYNOS_IIC > 0
-	prop_dictionary_t dict = device_properties(self);
-        struct exynos_iic_softc * const sc =  device_private(self);
-	struct exyo_attach_args * const exyoaa = aux;
-        struct exynos_iic_dev_softc *ei2c_sc;
-	struct i2c_controller *i2c_cntr;
+        struct exynos_i2c_softc * const sc =  device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
 	struct i2cbus_attach_args iba;
-	struct exyo_locinfo const *locs;
-	struct exyo_locators const *loc;
-	bool enable;
-	char scrap[strlen("iic??_enable")];
-	int i;
-
-	locs = NULL;
-#ifdef EXYNOS4
-	if (IS_EXYNOS4_P())
-		locs = &exynos4_i2c_locinfo;
-#endif
-#ifdef EXYNOS5
-	if (IS_EXYNOS5_P())
-		locs = &exynos5_i2c_locinfo;
-#endif
-	KASSERT(locs);
+
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
 
 	sc->sc_dev  = self;
-	if (locs->nlocators == 0) {
-		aprint_error(": no i2c busses defined\n");
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr,
+			     error);
 		return;
 	}
 
-	aprint_normal("\n");
+	sc->sc_port = i2c_port++;
+	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
+	cv_init(&sc->sc_cv, device_xname(self));
+	aprint_normal(" @ 0x%08x", (uint)addr);
 
-	for (i = 0; i < locs->nlocators; i++) {
-		/* get subdriver type : either gpio or hw */
-		snprintf(scrap, sizeof(scrap), "iic%d_enable", i);
-		if (prop_dictionary_get_bool(dict, scrap, &enable)) {
-			if (!enable)
-				continue;
-			/* found an iic device */
-			ei2c_sc   = &sc->sc_idevs[i];
-			i2c_cntr = &sc->sc_i2cbus[i];
-			loc = &locs->locators[i];
-
-			ei2c_sc->isc_bus = i;
-			ei2c_sc->isc_isgpio = (loc->loc_flags > 0);
-			mutex_init(&ei2c_sc->isc_buslock, MUTEX_DEFAULT, IPL_NONE);
-
-			ei2c_sc->isc_bst  = exyoaa->exyo_core_bst;
-			if (bus_space_subregion(ei2c_sc->isc_bst,
-			    exyoaa->exyo_core_bsh,
-			    loc->loc_offset, loc->loc_size,
-			    &ei2c_sc->isc_bsh)) {
-				aprint_error_dev(self,
-				    ": failed to map registers for i2cbus%d\n",
-				    i);
-				continue;
-			}
-
-			if (!exynos_iic_attach_i2cbus(ei2c_sc, i2c_cntr, loc))
-				continue;
-
-			exynos_i2cbus[i] = i2c_cntr;
-			iba.iba_tag = i2c_cntr;
- 			(void) config_found_ia(sc->sc_dev, "i2cbus", &iba,
-					iicbus_print);
-		}
+	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
 	}
-#endif
-}
 
+	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM,
+	    FDT_INTR_MPSAFE, exynos_i2c_intr, sc);
+	if (sc->sc_ih == NULL) {
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
+		return;
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
+
+	if (!exynos_i2c_attach_i2cbus(sc, &sc->sc_ic))
+		return;
+
+	sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
+
+}
 
-#if NEXYNOS_IIC > 0
 static bool
-exynos_iic_attach_i2cbus(struct exynos_iic_dev_softc *ei2c_sc,
-	struct i2c_controller *i2c_cntr, struct exyo_locators const *loc)
+exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *i2c_sc,
+			 struct i2c_controller *i2c_cntr)
 {
-	struct exynos_gpio_pinset *pinset;
-
-	/* reserve our pins */
-	pinset = &ei2c_sc->isc_pinset;
-	strcpy(pinset->pinset_bank, loc->loc_gpio_bus);
-	pinset->pinset_mask = __BIT(loc->loc_sda) | __BIT(loc->loc_slc);
-	pinset->pinset_func = loc->loc_func;
-
-	i2c_cntr->ic_cookie = ei2c_sc;
-	i2c_cntr->ic_acquire_bus = exynos_iic_acquire_bus;
-	i2c_cntr->ic_release_bus = exynos_iic_release_bus;
-	i2c_cntr->ic_send_start  = exynos_iic_send_start;
-	i2c_cntr->ic_send_stop   = exynos_iic_send_stop;
-	i2c_cntr->ic_initiate_xfer = exynos_iic_initiate_xfer;
-	i2c_cntr->ic_read_byte   = exynos_iic_read_byte;
-	i2c_cntr->ic_write_byte  = exynos_iic_write_byte;
+	i2c_cntr->ic_cookie = i2c_sc;
+	i2c_cntr->ic_acquire_bus = exynos_i2c_acquire_bus;
+	i2c_cntr->ic_release_bus = exynos_i2c_release_bus;
+	i2c_cntr->ic_send_start  = exynos_i2c_send_start;
+	i2c_cntr->ic_send_stop   = exynos_i2c_send_stop;
+	i2c_cntr->ic_initiate_xfer = exynos_i2c_initiate_xfer;
+	i2c_cntr->ic_read_byte   = exynos_i2c_read_byte;
+	i2c_cntr->ic_write_byte  = exynos_i2c_write_byte;
 
-	/*MJF: FIX ME IN REWRITE */
+	/*MJF: FIX ME needs gpio pins */
 //	exynos_gpio_pinset_acquire(pinset);
-	if (ei2c_sc->isc_isgpio) {
-		/* get sda and slc pins */
-#if 0
-		exynos_gpio_pinset_to_pindata(pinset,
-			loc->loc_sda, &ei2c_sc->isc_sda);
-		exynos_gpio_pinset_to_pindata(pinset,
-			loc->loc_slc, &ei2c_sc->isc_slc);
-		ei2c_sc->isc_sda_is_output = false;
-		exynos_gpio_pindata_ctl(&ei2c_sc->isc_sda, GPIO_PIN_INPUT);
-		exynos_gpio_pindata_ctl(&ei2c_sc->isc_slc, GPIO_PIN_OUTPUT);
-#endif
-		return 1;
-	} else {
-		/* TBD: attach hardware driver */
-		aprint_normal("i2cbus%d: would attach native i2c driver\n",
-		    ei2c_sc->isc_bus);
-		return 0;
-	}
+	return 1;
 }
 
-
-#define EXYNOS_IIC_BB_SDA	__BIT(1)
-#define EXYNOS_IIC_BB_SCL	__BIT(2)
-#define EXYNOS_IIC_BB_SDA_OUT	__BIT(3)
-#define EXYNOS_IIC_BB_SDA_IN	0
+#define EXYNOS_I2C_BB_SDA	__BIT(1)
+#define EXYNOS_I2C_BB_SCL	__BIT(2)
+#define EXYNOS_I2C_BB_SDA_OUT	__BIT(3)
+#define EXYNOS_I2C_BB_SDA_IN	0
 
 static void
-exynos_iic_bb_set_bits(void *cookie, uint32_t bits)
+exynos_i2c_bb_set_bits(void *cookie, uint32_t bits)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
+	struct exynos_i2c_softc *i2c_sc = cookie;
 	int sda, slc;
 
-	sda = (bits & EXYNOS_IIC_BB_SDA) ? true : false;
-	slc = (bits & EXYNOS_IIC_BB_SCL) ? true : false;
+	sda = (bits & EXYNOS_I2C_BB_SDA) ? true : false;
+	slc = (bits & EXYNOS_I2C_BB_SCL) ? true : false;
 
-	if (i2c_sc->isc_sda_is_output)
-		exynos_gpio_pindata_write(&i2c_sc->isc_sda, sda);
-	exynos_gpio_pindata_write(&i2c_sc->isc_slc, slc);
+	if (i2c_sc->sc_sda_is_output)
+		fdtbus_gpio_write(&i2c_sc->sc_sda, sda);
+	fdtbus_gpio_write(&i2c_sc->sc_slc, slc);
 }
 
 static uint32_t
-exynos_iic_bb_read_bits(void *cookie)
+exynos_i2c_bb_read_bits(void *cookie)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
+	struct exynos_i2c_softc *i2c_sc = cookie;
 	int sda, slc;
 
 	sda = 0;
-	if (!i2c_sc->isc_sda_is_output)
-		sda = exynos_gpio_pindata_read(&i2c_sc->isc_sda);
-	slc = exynos_gpio_pindata_read(&i2c_sc->isc_slc);
+	if (!i2c_sc->sc_sda_is_output)
+		sda = fdtbus_gpio_read(&i2c_sc->sc_sda);
+	slc = fdtbus_gpio_read(&i2c_sc->sc_slc);
 
-	return (sda ? EXYNOS_IIC_BB_SDA : 0) | (slc ? EXYNOS_IIC_BB_SCL : 0);
+	return (sda ? EXYNOS_I2C_BB_SDA : 0) | (slc ? EXYNOS_I2C_BB_SCL : 0);
 }
 
-
 static void
-exynos_iic_bb_set_dir(void *cookie, uint32_t bits)
+exynos_i2c_bb_set_dir(void *cookie, uint32_t bits)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
+	struct exynos_i2c_softc *i2c_sc = cookie;
 	int flags;
 
 	flags = GPIO_PIN_INPUT | GPIO_PIN_TRISTATE;
-	i2c_sc->isc_sda_is_output = ((bits & EXYNOS_IIC_BB_SDA_OUT) != 0);
-	if (i2c_sc->isc_sda_is_output)
+	i2c_sc->sc_sda_is_output = ((bits & EXYNOS_I2C_BB_SDA_OUT) != 0);
+	if (i2c_sc->sc_sda_is_output)
 		flags = GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE;
 
-	exynos_gpio_pindata_ctl(&i2c_sc->isc_sda, flags);
+	/* MJF: This is wrong but fdtbus has no ctrl operation */
+	fdtbus_gpio_write(&i2c_sc->sc_sda, flags);
 }
 
-
-static const struct i2c_bitbang_ops exynos_iic_bbops = {
-	exynos_iic_bb_set_bits,
-	exynos_iic_bb_set_dir,
-	exynos_iic_bb_read_bits,
+static const struct i2c_bitbang_ops exynos_i2c_bbops = {
+	exynos_i2c_bb_set_bits,
+	exynos_i2c_bb_set_dir,
+	exynos_i2c_bb_read_bits,
 	{
-		EXYNOS_IIC_BB_SDA,
-		EXYNOS_IIC_BB_SCL,
-		EXYNOS_IIC_BB_SDA_OUT,
-		EXYNOS_IIC_BB_SDA_IN,
+		EXYNOS_I2C_BB_SDA,
+		EXYNOS_I2C_BB_SCL,
+		EXYNOS_I2C_BB_SDA_OUT,
+		EXYNOS_I2C_BB_SDA_IN,
 	}
 };
 
+static int
+exynos_i2c_intr(void *priv)
+{
+	struct exynos_i2c_softc * const sc = priv;
+
+//	const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
+//	if (istatus == 0)
+//		return 0;
+//	I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus);
+
+	mutex_enter(&sc->sc_lock);
+	cv_broadcast(&sc->sc_cv);
+	mutex_exit(&sc->sc_lock);
+
+	return 1;
+}
 
 static int
-exynos_iic_acquire_bus(void *cookie, int flags)
+exynos_i2c_acquire_bus(void *cookie, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
+	struct exynos_i2c_softc *i2c_sc = cookie;
 
 	/* XXX what to do in polling case? could another cpu help */
 	if (flags & I2C_F_POLL)
 		return 0;
-	mutex_enter(&i2c_sc->isc_buslock);
+	mutex_enter(&i2c_sc->sc_lock);
 	return 0;
 }
 
 static void
-exynos_iic_release_bus(void *cookie, int flags)
+exynos_i2c_release_bus(void *cookie, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
+	struct exynos_i2c_softc *i2c_sc = cookie;
 
 	/* XXX what to do in polling case? could another cpu help */
 	if (flags & I2C_F_POLL)
 		return;
-	mutex_exit(&i2c_sc->isc_buslock);
+	mutex_exit(&i2c_sc->sc_lock);
 }
 
 static int
-exynos_iic_send_start(void *cookie, int flags)
+exynos_i2c_send_start(void *cookie, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
-
-	if (i2c_sc->isc_isgpio)
-		return i2c_bitbang_send_start(cookie, flags, &exynos_iic_bbops);
-	panic("%s: not implemented for non gpio case\n", __func__);
-	return EINVAL;
+	return i2c_bitbang_send_start(cookie, flags, &exynos_i2c_bbops);
 }
 
 static int
-exynos_iic_send_stop(void *cookie, int flags)
+exynos_i2c_send_stop(void *cookie, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
-
-	if (i2c_sc->isc_isgpio)
-		return i2c_bitbang_send_stop(cookie, flags, &exynos_iic_bbops);
-	panic("%s: not implemented for non gpio case\n", __func__);
-	return EINVAL;
+	return i2c_bitbang_send_stop(cookie, flags, &exynos_i2c_bbops);
 }
 
 static int
-exynos_iic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
+exynos_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
-
-	if (i2c_sc->isc_isgpio)
-		return i2c_bitbang_initiate_xfer(cookie, addr, flags,
-							&exynos_iic_bbops);
-	panic("%s: not implemented for non gpio case\n", __func__);
-	return EINVAL;
+	return i2c_bitbang_initiate_xfer(cookie, addr, flags,
+					 &exynos_i2c_bbops);
 }
 
 static int
-exynos_iic_read_byte(void *cookie, uint8_t *bytep, int flags)
+exynos_i2c_read_byte(void *cookie, uint8_t *bytep, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
-
-	if (i2c_sc->isc_isgpio)
-		return i2c_bitbang_read_byte(cookie, bytep, flags,
-							&exynos_iic_bbops);
-	panic("%s: not implemented for non gpio case\n", __func__);
-	return EINVAL;
+	return i2c_bitbang_read_byte(cookie, bytep, flags,
+				     &exynos_i2c_bbops);
 }
 
 static int
-exynos_iic_write_byte(void *cookie, uint8_t byte, int flags)
+exynos_i2c_write_byte(void *cookie, uint8_t byte, int flags)
 {
-	struct exynos_iic_dev_softc *i2c_sc = cookie;
-
-	if (i2c_sc->isc_isgpio)
-		return i2c_bitbang_write_byte(cookie, byte, flags,
-							&exynos_iic_bbops);
-	panic("%s: not implemented for non gpio case\n", __func__);
-	return EINVAL;
+	return i2c_bitbang_write_byte(cookie, byte, flags,
+				      &exynos_i2c_bbops);
 }
-
-#endif /* NEXYNOS_IIC > 0 */
-

Index: src/sys/arch/arm/samsung/files.exynos
diff -u src/sys/arch/arm/samsung/files.exynos:1.14 src/sys/arch/arm/samsung/files.exynos:1.15
--- src/sys/arch/arm/samsung/files.exynos:1.14	Sat Dec 19 21:42:31 2015
+++ src/sys/arch/arm/samsung/files.exynos	Mon Dec 21 00:52:50 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.exynos,v 1.14 2015/12/19 21:42:31 marty Exp $
+#	$NetBSD: files.exynos,v 1.15 2015/12/21 00:52:50 marty Exp $
 #
 # Configuration info for Samsung Exynos SoC ARM Peripherals
 #
@@ -56,9 +56,24 @@ file	arch/arm/samsung/exynos_io.c	exyo_i
 file	arch/arm/samsung/exynos4_loc.c	exyo_io & exynos4
 file	arch/arm/samsung/exynos5_loc.c	exyo_io & exynos5
 
+# Interrupt combiner
+device  exyointr
+attach  exyointr at fdt with exynos_intr
+file	arch/arm/samsung/exynos_combiner.c	exynos_intr
+
+# CHIP ID register
+device	chipid : fdtbus
+attach	chipid at fdt with exynos_chipid
+file	arch/arm/samsung/exynos_chipid.c	exynos_chipid
+
+# real time clock
+device  exyortc : ftdbus
+attach  exyortc at fdt with exynos_rtc
+file    arch/arm/samsung/exynos_rtc.c		exynos_rtc
+
 # Multi Core timer
-device	mct { } : bus_space_generic
-attach	mct at exyo with exyo_mct
+device	mct : ftdbus
+attach	mct at fdt with exyo_mct
 file	arch/arm/samsung/mct.c		exyo_mct
 
 # Watchdog
@@ -93,8 +108,8 @@ attach	ehci at exyousb with ehci_exyousb
 file	arch/arm/samsung/exynos_usb.c		exyo_usb
 
 # I2C support, bitbanging trough GPIO
-device	exyoiic: i2cbus, i2c_bitbang
-attach	exyoiic at exyo with exynos_iic
+device	exyoi2c: i2cbus, i2c_bitbang
+attach	exyoi2c at fdt with exynos_i2c
 file	arch/arm/samsung/exynos_i2c.c		exynos_iic | exyo_io needs-flag
 
 file	arch/arm/samsung/exynos5422_dma.c

Index: src/sys/arch/evbarm/conf/EXYNOS
diff -u src/sys/arch/evbarm/conf/EXYNOS:1.3 src/sys/arch/evbarm/conf/EXYNOS:1.4
--- src/sys/arch/evbarm/conf/EXYNOS:1.3	Sat Dec 19 21:42:31 2015
+++ src/sys/arch/evbarm/conf/EXYNOS	Mon Dec 21 00:52:51 2015
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: EXYNOS,v 1.3 2015/12/19 21:42:31 marty Exp $
+#	$NetBSD: EXYNOS,v 1.4 2015/12/21 00:52:51 marty Exp $
 #
 #	ODROID-XU -- ODROID-XU4 Exynos5422 based kernel
 #
@@ -210,6 +210,7 @@ fdt*		at simplebus?
 fregulator*	at fdt?
 
 #interrupt controller
+exyointr0	at fdt?
 gic*		at fdt?
 
 # Exynos SoC
@@ -225,6 +226,15 @@ sscom*		at fdt?				# UART ?
 # Exynos Watchdog Timer
 exyowdt0 	at fdt?				# watchdog
 
+# Exynos chip id
+chipid0		at fdt?
+
+# Exynos RTC
+exyortc0 	at fdt?
+
+# Exynos Multi Core timer (MCT)
+mct0	       at fdt?
+
 # GPIO
 exyopctl0	at fdt?
 exyopctl1	at fdt?
@@ -241,8 +251,11 @@ usb*		at ohci?
 usb*		at ehci?
 
 # I2C devices
-exyoiic0	at exyo0
-iic*		at exyoiic?
+exyoi2c0	at fdt?
+exyoi2c1	at fdt?
+exyoi2c2	at fdt?
+exyoi2c3	at fdt?
+#i2c*		at exyoi2c?
 
 # MISSING SUPPORT
 # eMMC

Added files:

Index: src/sys/arch/arm/samsung/exynos_chipid.c
diff -u /dev/null src/sys/arch/arm/samsung/exynos_chipid.c:1.1
--- /dev/null	Mon Dec 21 00:52:51 2015
+++ src/sys/arch/arm/samsung/exynos_chipid.c	Mon Dec 21 00:52:50 2015
@@ -0,0 +1,105 @@
+/*	$NetBSD: exynos_chipid.c,v 1.1 2015/12/21 00:52:50 marty Exp $ */
+
+/*-
+* Copyright (c) 2015 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Marty Fouts
+*
+* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "opt_exynos.h"
+#include "opt_arm_debug.h"
+#include "gpio.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: exynos_chipid.c,v 1.1 2015/12/21 00:52:50 marty Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/gpio.h>
+
+#include <dev/gpio/gpiovar.h>
+
+#include <arm/samsung/exynos_reg.h>
+#include <arm/samsung/exynos_io.h>
+#include <arm/samsung/exynos_intr.h>
+
+#include <dev/fdt/fdtvar.h>
+
+struct exynos_chipid_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+
+};
+
+static int exynos_chipid_match(device_t, cfdata_t, void *);
+static void exynos_chipid_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(exynos_chipid, sizeof(struct exynos_chipid_softc),
+	exynos_chipid_match, exynos_chipid_attach, NULL, NULL);
+
+static int
+exynos_chipid_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = { "samsung,exynos4210-chipid",
+					    NULL };
+	struct fdt_attach_args * const faa = aux;
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+exynos_chipid_attach(device_t parent, device_t self, void *aux)
+{
+	struct exynos_chipid_softc * const sc
+		= kmem_zalloc(sizeof(*sc), KM_SLEEP);
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	sc->sc_dev = self;
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d",
+			     (uint64_t)addr, error);
+		return;
+	}
+
+	aprint_normal(" @ 0x%08x: CHIPID -  NOT IMPLEMENTED", (uint)addr);
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+}
Index: src/sys/arch/arm/samsung/exynos_combiner.c
diff -u /dev/null src/sys/arch/arm/samsung/exynos_combiner.c:1.1
--- /dev/null	Mon Dec 21 00:52:51 2015
+++ src/sys/arch/arm/samsung/exynos_combiner.c	Mon Dec 21 00:52:50 2015
@@ -0,0 +1,217 @@
+/*	$NetBSD: exynos_combiner.c,v 1.1 2015/12/21 00:52:50 marty Exp $ */
+
+/*-
+* Copyright (c) 2015 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Marty Fouts
+*
+* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "opt_exynos.h"
+#include "opt_arm_debug.h"
+#include "gpio.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.1 2015/12/21 00:52:50 marty Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+
+#include <arm/cortex/gic_intr.h>
+
+#include <arm/samsung/exynos_reg.h>
+#include <arm/samsung/exynos_io.h>
+#include <arm/samsung/exynos_intr.h>
+
+#include <dev/fdt/fdtvar.h>
+
+struct exynos_combiner_softc {
+	device_t		sc_dev;
+	int			sc_phandle;
+
+};
+
+static int exynos_combiner_match(device_t, cfdata_t, void *);
+static void exynos_combiner_attach(device_t, device_t, void *);
+
+static void *	exynos_combiner_establish(device_t, int, u_int, int, int,
+		    int (*)(void *), void *);
+static void	exynos_combiner_disestablish(device_t, void *);
+static bool	exynos_combiner_intrstr(device_t, int, u_int, char *, size_t);
+
+struct fdtbus_interrupt_controller_func exynos_combiner_funcs = {
+	.establish = exynos_combiner_establish,
+	.disestablish = exynos_combiner_disestablish,
+	.intrstr = exynos_combiner_intrstr
+};
+
+CFATTACH_DECL_NEW(exynos_intr, sizeof(struct exynos_combiner_softc),
+	exynos_combiner_match, exynos_combiner_attach, NULL, NULL);
+
+static int
+exynos_combiner_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = { "samsung,exynos4210-combiner",
+					    NULL };
+	struct fdt_attach_args * const faa = aux;
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+exynos_combiner_attach(device_t parent, device_t self, void *aux)
+{
+	struct exynos_combiner_softc * const sc
+		= kmem_zalloc(sizeof(*sc), KM_SLEEP);
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	sc->sc_dev = self;
+	sc->sc_phandle = faa->faa_phandle;
+	error = fdtbus_register_interrupt_controller(self, faa->faa_phandle,
+	    &exynos_combiner_funcs);
+	if (error) {
+		aprint_error(": couldn't register with fdtbus: %d\n", error);
+		return;
+	}
+
+
+	aprint_normal(" @ 0x%08x: interrupt combiner,  NOT IMPLEMENTED",
+		      (uint)addr);
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+}
+
+
+static void *
+exynos_combiner_establish(device_t dev, int phandle, u_int index, int ipl,
+			  int flags,
+			  int (*func)(void *), void *arg)
+{
+	struct exynos_combiner_softc * const sc = device_private(dev);
+	int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
+	u_int *interrupts;
+	int interrupt_cells, len;
+
+	if (of_getprop_uint32(sc->sc_phandle, "#interrupt-cells",
+	    &interrupt_cells)) {
+		return NULL;
+	}
+
+	len = OF_getproplen(phandle, "interrupts");
+	if (len <= 0)
+		return NULL;
+
+	const u_int clen = interrupt_cells * 4;
+	const u_int nintr = len / interrupt_cells;
+
+	if (index >= nintr)
+		return NULL;
+
+	interrupts = kmem_alloc(len, KM_SLEEP);
+
+	if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
+		kmem_free(interrupts, len);
+		return NULL;
+	}
+
+	/* 1st cell is the interrupt type; */
+	/* 2nd cell is the interrupt number */
+	/* 3rd cell is flags */
+
+	const u_int type = be32toh(interrupts[index * clen + 0]);
+	const u_int intr = be32toh(interrupts[index * clen + 1]);
+	const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
+	const u_int trig = be32toh(interrupts[index * clen + 2]) & 0xf;
+	const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL;
+
+	kmem_free(interrupts, len);
+
+	return intr_establish(irq, ipl, level | iflags, func, arg);
+}
+
+static void
+exynos_combiner_disestablish(device_t dev, void *ih)
+{
+	intr_disestablish(ih);
+}
+
+static bool
+exynos_combiner_intrstr(device_t dev, int phandle, u_int index, char *buf,
+    size_t buflen)
+{
+	struct exynos_combiner_softc * const sc = device_private(dev);
+	u_int *interrupts;
+	int interrupt_cells, len;
+
+	if (of_getprop_uint32(sc->sc_phandle, "#interrupt-cells",
+	    &interrupt_cells)) {
+		return false;
+	}
+
+	len = OF_getproplen(phandle, "interrupts");
+	if (len <= 0) {
+		return false;
+	}
+
+	const u_int clen = interrupt_cells * 4;
+	const u_int nintr = len / interrupt_cells;
+
+	if (index >= nintr) {
+		return false;
+	}
+
+	interrupts = kmem_alloc(len, KM_SLEEP);
+
+	if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
+		kmem_free(interrupts, len);
+		return false;
+	}
+
+	/* 1st cell is the interrupt type; */
+	/* 2nd cell is the interrupt number */
+	/* 3rd cell is flags */
+
+	const u_int type = be32toh(interrupts[index * clen + 0]);
+	const u_int intr = be32toh(interrupts[index * clen + 1]);
+	const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
+
+	kmem_free(interrupts, len);
+
+	snprintf(buf, buflen, "LIC irq %d", irq);
+
+	return true;
+}
Index: src/sys/arch/arm/samsung/exynos_rtc.c
diff -u /dev/null src/sys/arch/arm/samsung/exynos_rtc.c:1.1
--- /dev/null	Mon Dec 21 00:52:51 2015
+++ src/sys/arch/arm/samsung/exynos_rtc.c	Mon Dec 21 00:52:50 2015
@@ -0,0 +1,151 @@
+/*	$NetBSD: exynos_rtc.c,v 1.1 2015/12/21 00:52:50 marty Exp $ */
+
+/*-
+* Copyright (c) 2015 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Marty Fouts
+*
+* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 "opt_exynos.h"
+#include "opt_arm_debug.h"
+#include "gpio.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: exynos_rtc.c,v 1.1 2015/12/21 00:52:50 marty Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kmem.h>
+
+#include <dev/clock_subr.h>
+
+#include <arm/samsung/exynos_reg.h>
+#include <arm/samsung/exynos_io.h>
+#include <arm/samsung/exynos_intr.h>
+
+#include <dev/fdt/fdtvar.h>
+
+struct exynos_rtc_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+
+	struct todr_chip_handle sc_todr;
+};
+
+static int exynos_rtc_match(device_t, cfdata_t, void *);
+static void exynos_rtc_attach(device_t, device_t, void *);
+
+static int	exynos_rtc_gettime(todr_chip_handle_t, struct timeval *);
+static int	exynos_rtc_settime(todr_chip_handle_t, struct timeval *);
+
+CFATTACH_DECL_NEW(exynos_rtc, sizeof(struct exynos_rtc_softc),
+	exynos_rtc_match, exynos_rtc_attach, NULL, NULL);
+
+#define RTC_READ(sc, reg)	\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define RTC_WRITE(sc, reg, val)	\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static int
+exynos_rtc_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = { "samsung,s3c6410-rtc",
+					    NULL };
+	struct fdt_attach_args * const faa = aux;
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+exynos_rtc_attach(device_t parent, device_t self, void *aux)
+{
+	struct exynos_rtc_softc * const sc
+		= kmem_zalloc(sizeof(*sc), KM_SLEEP);
+	struct fdt_attach_args * const faa = aux;
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	aprint_normal(" @ 0x%08x", (uint)addr);
+	sc->sc_dev = self;
+	sc->sc_bst = faa->faa_bst;
+	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d",
+			     (uint64_t)addr, error);
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": RTC\n");
+
+	sc->sc_todr.todr_gettime = exynos_rtc_gettime;
+	sc->sc_todr.todr_settime = exynos_rtc_settime;
+	sc->sc_todr.cookie = sc;
+	todr_attach(&sc->sc_todr);
+
+}
+
+static int
+exynos_rtc_gettime(todr_chip_handle_t tch, struct timeval *tv)
+{
+	struct exynos_rtc_softc * const sc = tch->cookie;
+
+	tv->tv_sec = RTC_READ(sc, EXYNOS5_RTC_OFFSET);
+	tv->tv_usec = 0;
+
+	return 0;
+}
+
+static int
+exynos_rtc_settime(todr_chip_handle_t tch, struct timeval *tv)
+{
+	struct exynos_rtc_softc * const sc = tch->cookie;
+	int retry = 500;
+
+	while (--retry > 0) {
+		if (!RTC_READ(sc, EXYNOS5_RTC_OFFSET))
+			break;
+		delay(1);
+	}
+	if (retry == 0) {
+		device_printf(sc->sc_dev, "RTC write failed (BUSY)\n");
+		return ETIMEDOUT;
+	}
+
+	RTC_WRITE(sc, EXYNOS5_RTC_OFFSET, tv->tv_sec);
+
+	return 0;
+}

Reply via email to