Add support for exynos5_ehci in loader

Create new driver which initializes Arndale PHY and calls ehci_init

Reviewed by:   hselasky
Submitted by:  Wojciech Macek <wma@semihalf.com>
Obtained from: Semihalf
Sponsored by:  Juniper Networks Inc.
Differential Revision: https://reviews.freebsd.org/D4192
This commit is contained in:
Zbigniew Bodek 2015-11-27 18:22:04 +00:00
parent fcf39bdcc4
commit 6a5289b068
7 changed files with 258 additions and 4 deletions

View File

@ -28,7 +28,9 @@
* 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$");
@ -50,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#endif
#include <arm/samsung/exynos/exynos5_common.h>
#include <arm/samsung/exynos/exynos5_combiner.h>

View File

@ -24,6 +24,9 @@
* SUCH DAMAGE.
*/
#ifdef USB_GLOBAL_INCLUDE_FILE
#include USB_GLOBAL_INCLUDE_FILE
#else
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -59,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include "gpio_if.h"
#include "opt_platform.h"
#endif
/* GPIO control */
#define GPIO_OUTPUT 1

View File

@ -28,7 +28,9 @@
* 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$");
@ -55,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include "gpio_if.h"
#endif
#include <arm/samsung/exynos/exynos5_combiner.h>
#include <arm/samsung/exynos/exynos5_pad.h>

View File

@ -29,6 +29,8 @@
#include <bsd_kernel.h>
#include <sys/gpio.h>
#define USB_DEBUG_VAR usb_debug
#include <dev/usb/usb_freebsd_loader.h>
#include <dev/usb/usb_endian.h>
@ -59,6 +61,8 @@
#include <dev/usb/usb_generic.h>
#include <dev/usb/quirk/usb_quirk.h>
#include <dev/usb/template/usb_template.h>
#include <dev/usb/controller/ehci.h>
#include <dev/usb/controller/ehcireg.h>
extern struct usb_process usb_process[USB_PROC_MAX];

View File

@ -35,6 +35,10 @@ static device_t usb_pci_root;
*------------------------------------------------------------------------*/
struct mtx Giant;
int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev,
int type, int *rid, unsigned int flags);
int (*ofw_bus_status_ok_cb)(device_t dev);
int (*ofw_bus_is_compatible_cb)(device_t dev, char *name);
static void
mtx_system_init(void *arg)
@ -43,6 +47,146 @@ mtx_system_init(void *arg)
}
SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
struct resource *
bus_alloc_resource_any(device_t dev, int type, int *rid, unsigned int flags)
{
struct resource *res;
int ret = EINVAL;
res = malloc(sizeof(*res), XXX, XXX);
if (res == NULL)
return (NULL);
res->__r_i = malloc(sizeof(struct resource_i), XXX, XXX);
if (res->__r_i == NULL) {
free(res, XXX);
return (NULL);
}
if (bus_alloc_resource_any_cb != NULL)
ret = (*bus_alloc_resource_any_cb)(res, dev, type, rid, flags);
if (ret == 0)
return (res);
free(res->__r_i, XXX);
free(res, XXX);
return (NULL);
}
int
bus_alloc_resources(device_t dev, struct resource_spec *rs,
struct resource **res)
{
int i;
for (i = 0; rs[i].type != -1; i++)
res[i] = NULL;
for (i = 0; rs[i].type != -1; i++) {
res[i] = bus_alloc_resource_any(dev,
rs[i].type, &rs[i].rid, rs[i].flags);
if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
bus_release_resources(dev, rs, res);
return (ENXIO);
}
}
return (0);
}
void
bus_release_resources(device_t dev, const struct resource_spec *rs,
struct resource **res)
{
int i;
for (i = 0; rs[i].type != -1; i++)
if (res[i] != NULL) {
bus_release_resource(
dev, rs[i].type, rs[i].rid, res[i]);
res[i] = NULL;
}
}
int
bus_setup_intr(device_t dev, struct resource *r, int flags,
driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
{
dev->dev_irq_filter = filter;
dev->dev_irq_fn = handler;
dev->dev_irq_arg = arg;
return (0);
}
int
bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
{
dev->dev_irq_filter = NULL;
dev->dev_irq_fn = NULL;
dev->dev_irq_arg = NULL;
return (0);
}
int
bus_release_resource(device_t dev, int type, int rid, struct resource *r)
{
/* Resource releasing is not supported */
return (EINVAL);
}
int
bus_generic_attach(device_t dev)
{
device_t child;
TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
device_probe_and_attach(child);
}
return (0);
}
bus_space_tag_t
rman_get_bustag(struct resource *r)
{
return (r->r_bustag);
}
bus_space_handle_t
rman_get_bushandle(struct resource *r)
{
return (r->r_bushandle);
}
u_long
rman_get_size(struct resource *r)
{
return (r->__r_i->r_end - r->__r_i->r_start + 1);
}
int
ofw_bus_status_okay(device_t dev)
{
if (ofw_bus_status_ok_cb == NULL)
return (0);
return ((*ofw_bus_status_ok_cb)(dev));
}
int
ofw_bus_is_compatible(device_t dev, char *name)
{
if (ofw_bus_is_compatible_cb == NULL)
return (0);
return ((*ofw_bus_is_compatible_cb)(dev, name));
}
void
mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
{
@ -873,7 +1017,7 @@ devclass_find(const char *classname)
const struct module_data *mod;
TAILQ_FOREACH(mod, &module_head, entry) {
if (devclass_equal(mod->mod_name, classname))
if (devclass_equal(mod->driver->name, classname))
return (mod->devclass_pp[0]);
}
return (NULL);

View File

@ -109,6 +109,7 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs), \
#define WITNESS_WARN(...)
#define cold 0
#define BUS_PROBE_GENERIC 0
#define BUS_PROBE_DEFAULT (-20)
#define CALLOUT_RETURNUNLOCKED 0x1
#undef ffs
#define ffs(x) __builtin_ffs(x)
@ -138,6 +139,10 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs), \
(((usb_handle_request_t *)(device_get_method(dev, "usb_handle_request")))(dev,## __VA_ARGS__))
#define USB_TAKE_CONTROLLER(dev, ...) \
(((usb_take_controller_t *)(device_get_method(dev, "usb_take_controller")))(dev,## __VA_ARGS__))
#define GPIO_PIN_SET(dev, ...) \
(((gpio_pin_set_t *)(device_get_method(dev, "gpio_pin_set")))(dev,## __VA_ARGS__))
#define GPIO_PIN_SETFLAGS(dev, ...) \
(((gpio_pin_setflags_t *)(device_get_method(dev, "gpio_pin_setflags")))(dev,## __VA_ARGS__))
enum {
SI_SUB_DUMMY = 0x0000000,
@ -302,6 +307,8 @@ typedef int device_resume_t (device_t dev);
typedef int device_shutdown_t (device_t dev);
typedef int device_probe_t (device_t dev);
typedef int device_suspend_t (device_t dev);
typedef int gpio_pin_set_t (device_t dev, uint32_t, unsigned int);
typedef int gpio_pin_setflags_t (device_t dev, uint32_t, uint32_t);
typedef int bus_child_location_str_t (device_t parent, device_t child, char *buf, size_t buflen);
typedef int bus_child_pnpinfo_str_t (device_t parent, device_t child, char *buf, size_t buflen);
@ -498,4 +505,78 @@ struct selinfo {
extern const void *sysinit_data[];
extern const void *sysuninit_data[];
/* Resources */
enum intr_type {
INTR_TYPE_TTY = 1,
INTR_TYPE_BIO = 2,
INTR_TYPE_NET = 4,
INTR_TYPE_CAM = 8,
INTR_TYPE_MISC = 16,
INTR_TYPE_CLK = 32,
INTR_TYPE_AV = 64,
INTR_EXCL = 256, /* exclusive interrupt */
INTR_MPSAFE = 512, /* this interrupt is SMP safe */
INTR_ENTROPY = 1024, /* this interrupt provides entropy */
INTR_MD1 = 4096, /* flag reserved for MD use */
INTR_MD2 = 8192, /* flag reserved for MD use */
INTR_MD3 = 16384, /* flag reserved for MD use */
INTR_MD4 = 32768 /* flag reserved for MD use */
};
struct resource_i {
u_long r_start; /* index of the first entry in this resource */
u_long r_end; /* index of the last entry (inclusive) */
};
struct resource {
struct resource_i *__r_i;
bus_space_tag_t r_bustag; /* bus_space tag */
bus_space_handle_t r_bushandle; /* bus_space handle */
};
struct resource_spec {
int type;
int rid;
int flags;
};
#define SYS_RES_IRQ 1 /* interrupt lines */
#define SYS_RES_DRQ 2 /* isa dma lines */
#define SYS_RES_MEMORY 3 /* i/o memory */
#define SYS_RES_IOPORT 4 /* i/o ports */
#define RF_ALLOCATED 0x0001 /* resource has been reserved */
#define RF_ACTIVE 0x0002 /* resource allocation has been activated */
#define RF_SHAREABLE 0x0004 /* resource permits contemporaneous sharing */
#define RF_SPARE1 0x0008
#define RF_SPARE2 0x0010
#define RF_FIRSTSHARE 0x0020 /* first in sharing list */
#define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */
#define RF_OPTIONAL 0x0080 /* for bus_alloc_resources() */
int bus_alloc_resources(device_t, struct resource_spec *, struct resource **);
int bus_release_resource(device_t, int, int, struct resource *);
void bus_release_resources(device_t, const struct resource_spec *,
struct resource **);
struct resource *bus_alloc_resource_any(device_t, int, int *, unsigned int);
int bus_generic_attach(device_t);
bus_space_tag_t rman_get_bustag(struct resource *);
bus_space_handle_t rman_get_bushandle(struct resource *);
u_long rman_get_size(struct resource *);
int bus_setup_intr(device_t, struct resource *, int, driver_filter_t,
driver_intr_t, void *, void **);
int bus_teardown_intr(device_t, struct resource *, void *);
int ofw_bus_status_okay(device_t);
int ofw_bus_is_compatible(device_t, char *);
extern int (*bus_alloc_resource_any_cb)(struct resource *res, device_t dev,
int type, int *rid, unsigned int flags);
extern int (*ofw_bus_status_ok_cb)(device_t dev);
extern int (*ofw_bus_is_compatible_cb)(device_t dev, char *name);
#ifndef strlcpy
#define strlcpy(d,s,n) snprintf((d),(n),"%s",(s))
#endif
#endif /* _BSD_KERNEL_H_ */

View File

@ -34,6 +34,12 @@
USBCOREDIR:= ${.PARSEDIR}
S=${USBCOREDIR}/../..
MACHDEP_DIRS=
.if defined(HAVE_EXYNOS_EHCI)
MACHDEP_DIRS+= ${S}/arm/samsung/exynos
.endif
.PATH: \
${USBCOREDIR} \
${USBCOREDIR}/storage \
@ -41,7 +47,8 @@ S=${USBCOREDIR}/../..
${S}/dev/usb/controller \
${S}/dev/usb/serial \
${S}/dev/usb/storage \
${S}/dev/usb/template
${S}/dev/usb/template \
${MACHDEP_DIRS}
.undef S
USB_POOL_SIZE?= 131072
@ -91,6 +98,14 @@ CFLAGS += -DUSB_PCI_PROBE_LIST="\"ehci\""
KSRCS+= ehci.c
.endif
.if defined(HAVE_EXYNOS_EHCI)
CFLAGS += -DUSB_PCI_PROBE_LIST="\"combiner\", \"pad\", \"ehci\""
KSRCS+= ehci.c
KSRCS+= exynos5_combiner.c
KSRCS+= exynos5_pad.c
KSRCS+= exynos5_ehci.c
.endif
.if defined(HAVE_OHCI)
CFLAGS += -DUSB_PCI_PROBE_LIST="\"ohci\""
KSRCS+= ohci.c