1190207Srpaulo/*-
298524Sfenner * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
398524Sfenner * All rights reserved.
498524Sfenner *
598524Sfenner * Redistribution and use in source and binary forms, with or without
698524Sfenner * modification, are permitted provided that the following conditions
798524Sfenner * are met:
898524Sfenner * 1. Redistributions of source code must retain the above copyright
998524Sfenner *    notice, this list of conditions and the following disclaimer.
1098524Sfenner * 2. Redistributions in binary form must reproduce the above copyright
1198524Sfenner *    notice, this list of conditions and the following disclaimer in the
1298524Sfenner *    documentation and/or other materials provided with the distribution.
1398524Sfenner *
1498524Sfenner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1598524Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1698524Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1798524Sfenner * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1898524Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1998524Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2098524Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2198524Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2298524Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2398524Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2498524Sfenner * SUCH DAMAGE.
2598524Sfenner */
2698524Sfenner
2798524Sfenner/*
2898524Sfenner * Vybrid Family Direct Memory Access Multiplexer (DMAMUX)
2998524Sfenner * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013
3098524Sfenner */
3198524Sfenner
3298524Sfenner#include <sys/cdefs.h>
3398524Sfenner__FBSDID("$FreeBSD$");
34127668Sbms
3598524Sfenner#include <sys/param.h>
3698524Sfenner#include <sys/systm.h>
37127668Sbms#include <sys/bus.h>
3898524Sfenner#include <sys/kernel.h>
3998524Sfenner#include <sys/module.h>
4098524Sfenner#include <sys/malloc.h>
41127668Sbms#include <sys/rman.h>
4298524Sfenner#include <sys/timeet.h>
4398524Sfenner#include <sys/timetc.h>
4498524Sfenner#include <sys/watchdog.h>
4598524Sfenner
4698524Sfenner#include <dev/fdt/fdt_common.h>
4798524Sfenner#include <dev/ofw/openfirm.h>
4898524Sfenner#include <dev/ofw/ofw_bus.h>
4998524Sfenner#include <dev/ofw/ofw_bus_subr.h>
5098524Sfenner
5198524Sfenner#include <machine/bus.h>
5298524Sfenner#include <machine/fdt.h>
5398524Sfenner#include <machine/cpu.h>
5498524Sfenner#include <machine/intr.h>
5598524Sfenner
5698524Sfenner#include <arm/freescale/vybrid/vf_common.h>
5798524Sfenner#include <arm/freescale/vybrid/vf_dmamux.h>
5898524Sfenner
5998524Sfenner#define	DMAMUX_CHCFG(n)		(0x1 * n)	/* Channels 0-15 Cfg Reg */
60127668Sbms#define	CHCFG_ENBL		(1 << 7)	/* Channel Enable */
6198524Sfenner#define	CHCFG_TRIG		(1 << 6)	/* Channel Trigger Enable */
6298524Sfenner#define	CHCFG_SOURCE_MASK	0x3f		/* Channel Source (Slot) */
63127668Sbms#define	CHCFG_SOURCE_SHIFT	0
64127668Sbms
65127668Sbmsstruct dmamux_softc {
66127668Sbms	struct resource		*res[4];
6798524Sfenner	bus_space_tag_t		bst[4];
6898524Sfenner	bus_space_handle_t	bsh[4];
6998524Sfenner};
7098524Sfenner
7198524Sfennerstruct dmamux_softc *dmamux_sc;
72127668Sbms
73127668Sbmsstatic struct resource_spec dmamux_spec[] = {
74127668Sbms	{ SYS_RES_MEMORY,	0,	RF_ACTIVE }, /* DMAMUX0 */
7598524Sfenner	{ SYS_RES_MEMORY,	1,	RF_ACTIVE }, /* DMAMUX1 */
7698524Sfenner	{ SYS_RES_MEMORY,	2,	RF_ACTIVE }, /* DMAMUX2 */
7798524Sfenner	{ SYS_RES_MEMORY,	3,	RF_ACTIVE }, /* DMAMUX3 */
78127668Sbms	{ -1, 0 }
79127668Sbms};
8098524Sfenner
8198524Sfennerstatic int
8298524Sfennerdmamux_probe(device_t dev)
8398524Sfenner{
8498524Sfenner
85127668Sbms	if (!ofw_bus_status_okay(dev))
8698524Sfenner		return (ENXIO);
8798524Sfenner
8898524Sfenner	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux"))
8998524Sfenner		return (ENXIO);
90127668Sbms
91127668Sbms	device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer");
92127668Sbms	return (BUS_PROBE_DEFAULT);
9398524Sfenner}
9498524Sfenner
9598524Sfennerint
9698524Sfennerdmamux_configure(int mux, int source, int channel, int enable)
9798524Sfenner{
9898524Sfenner	struct dmamux_softc *sc;
9998524Sfenner	int reg;
10098524Sfenner
10198524Sfenner	sc = dmamux_sc;
10298524Sfenner
10398524Sfenner	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0);
104127668Sbms
105127668Sbms	reg = 0;
106127668Sbms	if (enable)
107127668Sbms		reg |= (CHCFG_ENBL);
108127668Sbms
10998524Sfenner	reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT);
11098524Sfenner	reg |= (source << CHCFG_SOURCE_SHIFT);
11198524Sfenner
11298524Sfenner	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg);
11398524Sfenner
114127668Sbms	return (0);
11598524Sfenner}
11698524Sfenner
11798524Sfennerstatic int
11898524Sfennerdmamux_attach(device_t dev)
11998524Sfenner{
120127668Sbms	struct dmamux_softc *sc;
12198524Sfenner	int i;
12298524Sfenner
12398524Sfenner	sc = device_get_softc(dev);
12498524Sfenner
125127668Sbms	if (bus_alloc_resources(dev, dmamux_spec, sc->res)) {
12698524Sfenner		device_printf(dev, "could not allocate resources\n");
12798524Sfenner		return (ENXIO);
12898524Sfenner	}
12998524Sfenner
13098524Sfenner	/* Memory interface */
131127668Sbms	for (i = 0; i < 4; i++) {
13298524Sfenner		sc->bst[i] = rman_get_bustag(sc->res[i]);
13398524Sfenner		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
13498524Sfenner	}
13598524Sfenner
136127668Sbms	dmamux_sc = sc;
137127668Sbms
13898524Sfenner	return (0);
13998524Sfenner}
14098524Sfenner
14198524Sfennerstatic device_method_t dmamux_methods[] = {
142127668Sbms	DEVMETHOD(device_probe,		dmamux_probe),
143127668Sbms	DEVMETHOD(device_attach,	dmamux_attach),
144127668Sbms	{ 0, 0 }
14598524Sfenner};
14698524Sfenner
147127668Sbmsstatic driver_t dmamux_driver = {
148127668Sbms	"dmamux",
149127668Sbms	dmamux_methods,
150127668Sbms	sizeof(struct dmamux_softc),
15198524Sfenner};
152127668Sbms
15398524Sfennerstatic devclass_t dmamux_devclass;
15498524Sfenner
15598524SfennerDRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0);
15698524Sfenner