diff --git a/dde_linux/Makefile b/dde_linux/Makefile index 73803755c..c9a24b257 100644 --- a/dde_linux/Makefile +++ b/dde_linux/Makefile @@ -31,7 +31,8 @@ CONTENT += include/linux/usbdevice_fs.h include/asm-generic/ioctl.h # USB host-controller driver CONTENT_USB_HOST := ehci.h ehci-hcd.c ehci-hub.c ehci-dbg.c ehci-mem.c \ - ehci-omap.c ehci-q.c ehci-pci.c ehci-sched.c ehci-sysfs.c + ehci-omap.c ehci-q.c ehci-pci.c ehci-s5p.c ehci-sched.c \ + ehci-sysfs.c CONTENT_USB_HOST += ohci.h ohci-hcd.c ohci-hub.c ohci-dbg.c ohci-mem.c \ ohci-q.c ohci-pci.c ehci-lpm.c CONTENT_USB_HOST += uhci-hcd.h uhci-hcd.c uhci-debug.c uhci-q.c uhci-hub.c \ @@ -61,6 +62,10 @@ CONTENT_NET = usbnet.c smsc95xx.c smsc95xx.h CONTENT += $(addprefix drivers/net/usb/,$(CONTENT_NET)) CONTENT += include/linux/usb/usbnet.h +# Arndale +CONTENT_ARNDALE = ehci.h usb-phy.h +CONTENT += $(addprefix arch/arm/plat-samsung/include/plat/,$(CONTENT_ARNDALE)) + # # # Utility to check if a tool is installed diff --git a/dde_linux/src/drivers/usb/arm/platform/lx_emul.h b/dde_linux/src/drivers/usb/arm/platform/lx_emul.h index 3871df394..f3d17c63c 100644 --- a/dde_linux/src/drivers/usb/arm/platform/lx_emul.h +++ b/dde_linux/src/drivers/usb/arm/platform/lx_emul.h @@ -84,7 +84,10 @@ struct platform_driver { const struct platform_device_id *id_table; }; +struct resource *platform_get_resource(struct platform_device *, unsigned, unsigned); struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); + +int platform_get_irq(struct platform_device *, unsigned int); int platform_get_irq_byname(struct platform_device *, const char *); int platform_driver_register(struct platform_driver *); @@ -134,4 +137,24 @@ struct regulator *regulator_get(struct device *dev, const char *id); int omap_usbhs_enable(struct device *dev); void omap_usbhs_disable(struct device *dev); + +/**************** + ** linux/pm.h ** + ****************/ + +struct dev_pm_ops { + int (*suspend)(struct device *dev); + int (*resume)(struct device *dev); +}; + + +/***************** + ** linux/clk.h ** + *****************/ + +struct clk *clk_get(struct device *, const char *); +int clk_enable(struct clk *); +void clk_disable(struct clk *); +void clk_put(struct clk *); + #endif /* _ARM__PLATFORM__LX_EMUL_H_ */ diff --git a/dde_linux/src/drivers/usb/arm/platform/platform_arndale/platform.cc b/dde_linux/src/drivers/usb/arm/platform/platform_arndale/platform.cc new file mode 100644 index 000000000..17f29e609 --- /dev/null +++ b/dde_linux/src/drivers/usb/arm/platform/platform_arndale/platform.cc @@ -0,0 +1,162 @@ +/* + * \brief EHCI for Arndale initializaion code + * \author Sebastian Sumpf + * \date 2013-02-20 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode */ +#include +#include + +/* Emulation */ +#include +#include + +/* Linux */ +#include + +using namespace Genode; + +enum { + EHCI_BASE = 0x12110000, + GPIO_BASE = 0x11400000, + EHCI_IRQ = 103, +}; + +static resource _ehci[] = +{ + { EHCI_BASE, EHCI_BASE + 0xfff, "ehci", IORESOURCE_MEM }, + { EHCI_IRQ, EHCI_IRQ, "ehci-irq", IORESOURCE_IRQ }, +}; + +static struct s5p_ehci_platdata _ehci_data; + + +/** + * EHCI controller + */ +struct Ehci : Genode::Mmio +{ + Ehci(addr_t const mmio_base) : Mmio(mmio_base) + { + write(0); + + /* reset */ + write(1); + + while(read()) + msleep(1); + } + + struct Cmd : Register<0x10, 32> + { + struct Reset : Bitfield<1, 1> { }; + }; +}; + + +/** + * Gpio handling + */ +struct Gpio_bank { + unsigned con; + unsigned dat; +}; + + +static inline +unsigned con_mask(unsigned val) { return 0xf << ((val) << 2); } + + +static inline +unsigned con_sfr(unsigned x, unsigned v) { return (v) << ((x) << 2); } + + +static void gpio_cfg_pin(Gpio_bank *bank, int gpio, int cfg) +{ + unsigned int value; + + value = readl(&bank->con); + value &= ~con_mask(gpio); + value |= con_sfr(gpio, cfg); + writel(value, &bank->con); +} + + +static void gpio_direction_output(Gpio_bank *bank, int gpio, int en) +{ + unsigned int value; + enum { GPIO_OUTPUT = 0x1 }; + + gpio_cfg_pin(bank, gpio, GPIO_OUTPUT); + + value = readl(&bank->dat); + value &= ~(0x1 << gpio); + if (en) + value |= 0x1 << gpio; + writel(value, &bank->dat); +} + + +static void arndale_ehci_init() +{ + enum Gpio_offset { D1 = 0x180, X3 = 0xc60 }; + + /* reset hub via GPIO */ + Io_mem_connection io_gpio(GPIO_BASE, 0x1000); + addr_t gpio_base = (addr_t)env()->rm_session()->attach(io_gpio.dataspace()); + + Gpio_bank *d1 = reinterpret_cast(gpio_base + D1); + Gpio_bank *x3 = reinterpret_cast(gpio_base + X3); + + /* hub reset */ + gpio_direction_output(x3, 5, 0); + /* hub connect */ + gpio_direction_output(d1, 7, 0); + + gpio_direction_output(x3, 5, 1); + gpio_direction_output(d1, 7, 1); + + env()->rm_session()->detach(gpio_base); + + /* reset ehci controller */ + Io_mem_connection io_ehci(EHCI_BASE, 0x1000); + addr_t ehci_base = (addr_t)env()->rm_session()->attach(io_ehci.dataspace()); + + Ehci ehci(ehci_base); + env()->rm_session()->detach(ehci_base); +} + + +extern "C" void module_ehci_hcd_init(); + +void platform_hcd_init(Services *services) +{ + /* register EHCI controller */ + module_ehci_hcd_init(); + + /* setup controller */ + arndale_ehci_init(); + + /* setup EHCI-controller platform device */ + platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0); + pdev->name = "s5p-ehci"; + pdev->id = 0; + pdev->num_resources = 2; + pdev->resource = _ehci; + pdev->dev.platform_data = &_ehci_data; + + /*needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */ + static u64 dma_mask = ~(u64)0; + pdev->dev.dma_mask = &dma_mask; + pdev->dev.coherent_dma_mask = ~0; + + platform_device_register(pdev); +} diff --git a/dde_linux/src/drivers/usb/arm/platform/platform_device.c b/dde_linux/src/drivers/usb/arm/platform/platform_device.c index e7a716d7c..23deb503a 100644 --- a/dde_linux/src/drivers/usb/arm/platform/platform_device.c +++ b/dde_linux/src/drivers/usb/arm/platform/platform_device.c @@ -52,6 +52,20 @@ int platform_driver_register(struct platform_driver *drv) return driver_register(&drv->driver); } +struct resource *platform_get_resource(struct platform_device *dev, + unsigned int type, unsigned int num) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) { + struct resource *r = &dev->resource[i]; + + if ((type & r->flags) && num-- == 0) + return r; + } + + return NULL; +} struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, @@ -77,6 +91,12 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name) } +int platform_get_irq(struct platform_device *dev, unsigned int num) +{ + struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, 0); + return r ? r->start : -1; +} + int platform_device_register(struct platform_device *pdev) { pdev->dev.bus = &platform_bus_type; diff --git a/dde_linux/src/drivers/usb/arm/platform/platform.cc b/dde_linux/src/drivers/usb/arm/platform/platform_panda/platform.cc similarity index 100% rename from dde_linux/src/drivers/usb/arm/platform/platform.cc rename to dde_linux/src/drivers/usb/arm/platform/platform_panda/platform.cc diff --git a/dde_linux/src/drivers/usb/dummies.c b/dde_linux/src/drivers/usb/dummies.c index eedad38f3..5c9cf0315 100644 --- a/dde_linux/src/drivers/usb/dummies.c +++ b/dde_linux/src/drivers/usb/dummies.c @@ -383,6 +383,7 @@ void class_destroy(struct class *cls) { TRACE; } *****************************/ void *platform_get_drvdata(const struct platform_device *pdev) { TRACE; return NULL; } +void platform_set_drvdata(struct platform_device *pdev, void *data) { TRACE; } /******************** @@ -878,3 +879,19 @@ __wsum csum_partial(const void *buff, int len, __wsum wsum) { TRACE; return 0; } __sum16 csum_fold(__wsum sum) { TRACE; return 0; } +/***************** + ** linux/clk.h ** + *****************/ + +struct clk { }; + +struct clk *clk_get(struct device *dev, const char *id) +{ + static struct clk _c; + TRACE; + return &_c; +} + +int clk_enable(struct clk *clk) { TRACE; return 0; } +void clk_disable(struct clk *clk) { TRACE; } +void clk_put(struct clk *clk) { TRACE; } diff --git a/dde_linux/src/drivers/usb/lx_emul.h b/dde_linux/src/drivers/usb/lx_emul.h index d57d3653a..c27611878 100644 --- a/dde_linux/src/drivers/usb/lx_emul.h +++ b/dde_linux/src/drivers/usb/lx_emul.h @@ -39,8 +39,8 @@ extern "C" { #if VERBOSE_LX_EMUL #define DEBUG_COMPLETION 0 #define DEBUG_DMA 0 -#define DEBUG_DRIVER 0 -#define DEBUG_IRQ 0 +#define DEBUG_DRIVER 1 +#define DEBUG_IRQ 1 #define DEBUG_KREF 0 #define DEBUG_PCI 0 #define DEBUG_SKB 0 @@ -675,6 +675,7 @@ int isprint(int); #define __devinit #define __devinitconst #define __devexit +#define __devexit_p(x) x #define __exit #define __exit_p(x) x @@ -1292,6 +1293,8 @@ struct device_driver { const char *mod_name; int (*probe) (struct device *dev); int (*remove) (struct device *dev); + + const struct dev_pm_ops *pm; }; struct kobj_uevent_env; @@ -1434,6 +1437,7 @@ void class_destroy(struct class *cls); struct platform_device; void *platform_get_drvdata(const struct platform_device *pdev); +void platform_set_drvdata(struct platform_device *pdev, void *data); /********************* diff --git a/dde_linux/src/drivers/usb/target.mk b/dde_linux/src/drivers/usb/target.mk index ae833ebf3..fb45099ac 100644 --- a/dde_linux/src/drivers/usb/target.mk +++ b/dde_linux/src/drivers/usb/target.mk @@ -81,13 +81,22 @@ SRC_CC += pci_driver.cc else ifeq ($(filter-out $(SPECS),platform_panda),) CC_OPT += -DCONFIG_USB_EHCI_HCD_OMAP -DCONFIG_USB_EHCI_TT_NEWSCHED -DVERBOSE_DEBUG INC_DIR += $(PRG_DIR)/arm -INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-omap/include SRC_C += platform_device.c usbnet.c smsc95xx.c SRC_CC += platform.cc mem.cc vpath %.c $(PRG_DIR)/arm/platform vpath %.cc $(PRG_DIR)/arm/platform +vpath %.cc $(PRG_DIR)/arm/platform/platform_panda vpath %.c $(CONTRIB_DIR)/drivers/net/usb +else ifeq ($(filter-out $(SPECS),platform_arndale),) +CC_OPT += -DCONFIG_USB_EHCI_S5P -DCONFIG_USB_EHCI_TT_NEWSCHED +INC_DIR += $(PRG_DIR)/arm +INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-samsung/include +SRC_C += platform_device.c +SRC_CC += platform.cc +vpath %.c $(PRG_DIR)/arm/platform +vpath %.cc $(PRG_DIR)/arm/platform/platform_arndale + # # Unsupported #