1287371Sandrew/*
2287371Sandrew * Copyright 2015 Andrew Turner.
3287371Sandrew * All rights reserved.
4287371Sandrew *
5287371Sandrew * Redistribution and use in source and binary forms, with or without
6287371Sandrew * modification, are permitted provided that the following conditions are
7287371Sandrew * met:
8287371Sandrew *
9287371Sandrew *  1. Redistributions of source code must retain the above copyright
10287371Sandrew *     notice, this list of conditions and the following disclaimer.
11287371Sandrew *  2. Redistributions in binary form must reproduce the above copyright
12287371Sandrew *     notice, this list of conditions and the following disclaimer in the
13287371Sandrew *     documentation and/or other materials provided with the distribution.
14287371Sandrew *
15287371Sandrew * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16287371Sandrew * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17287371Sandrew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18287371Sandrew * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
19287371Sandrew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20287371Sandrew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21287371Sandrew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22287371Sandrew * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23287371Sandrew * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24287371Sandrew * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25287371Sandrew * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26287371Sandrew */
27287371Sandrew
28287371Sandrew#include <sys/cdefs.h>
29287371Sandrew__FBSDID("$FreeBSD$");
30287371Sandrew
31287371Sandrew#include <sys/param.h>
32287371Sandrew#include <sys/kernel.h>
33287371Sandrew#include <sys/bus.h>
34287371Sandrew#include <sys/module.h>
35287371Sandrew
36287371Sandrew#include <machine/bus.h>
37287371Sandrew
38287371Sandrew#include <dev/mmc/bridge.h>
39287371Sandrew
40287371Sandrew#include <dev/ofw/ofw_bus_subr.h>
41287371Sandrew
42287371Sandrew#include <dev/mmc/host/dwmmc_var.h>
43287371Sandrew
44287371Sandrewstatic device_probe_t hisi_dwmmc_probe;
45287371Sandrewstatic device_attach_t hisi_dwmmc_attach;
46287371Sandrew
47287371Sandrewstatic int
48287371Sandrewhisi_dwmmc_probe(device_t dev)
49287371Sandrew{
50287371Sandrew
51287371Sandrew	if (!ofw_bus_status_okay(dev))
52287371Sandrew		return (ENXIO);
53287371Sandrew
54287371Sandrew	if (!ofw_bus_is_compatible(dev, "hisilicon,hi6220-dw-mshc"))
55287371Sandrew		return (ENXIO);
56287371Sandrew
57287371Sandrew	device_set_desc(dev, "Synopsys DesignWare Mobile "
58287371Sandrew	    "Storage Host Controller (HiSilicon)");
59287371Sandrew
60287371Sandrew	return (BUS_PROBE_VENDOR);
61287371Sandrew}
62287371Sandrew
63287371Sandrewstatic int
64287371Sandrewhisi_dwmmc_attach(device_t dev)
65287371Sandrew{
66287371Sandrew	struct dwmmc_softc *sc;
67287371Sandrew
68287371Sandrew	sc = device_get_softc(dev);
69287371Sandrew	sc->hwtype = HWTYPE_HISILICON;
70287371Sandrew	/* TODO: Calculate this from a clock driver */
71287371Sandrew	sc->bus_hz = 24000000; /* 24MHz */
72287371Sandrew
73287371Sandrew	/*
74287371Sandrew	 * ARM64TODO: This is likely because we lack support for
75287371Sandrew	 * DMA when the controller is not cache-coherent on arm64.
76287371Sandrew	 */
77287371Sandrew	sc->use_pio = 1;
78287371Sandrew	sc->desc_count = 1;
79287371Sandrew
80287371Sandrew	return (dwmmc_attach(dev));
81287371Sandrew}
82287371Sandrew
83287371Sandrewstatic device_method_t hisi_dwmmc_methods[] = {
84287371Sandrew	/* bus interface */
85287371Sandrew	DEVMETHOD(device_probe, hisi_dwmmc_probe),
86287371Sandrew	DEVMETHOD(device_attach, hisi_dwmmc_attach),
87287371Sandrew
88287371Sandrew	DEVMETHOD_END
89287371Sandrew};
90287371Sandrew
91287371Sandrewstatic devclass_t hisi_dwmmc_devclass;
92287371Sandrew
93287371SandrewDEFINE_CLASS_1(hisi_dwmmc, hisi_dwmmc_driver, hisi_dwmmc_methods,
94287371Sandrew    sizeof(struct dwmmc_softc), dwmmc_driver);
95287371SandrewDRIVER_MODULE(hisi_dwmmc, simplebus, hisi_dwmmc_driver,
96287371Sandrew    hisi_dwmmc_devclass, 0, 0);
97