diff options
148 files changed, 3554 insertions, 1396 deletions
@@ -1458,6 +1458,9 @@ The following options need to be configured: CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the txfilltuning field in the EHCI controller on reset. + CONFIG_USB_DWC2_REG_ADDR the physical CPU address of the DWC2 + HW module registers. + - USB Device: Define the below if you wish to use the USB console. Once firmware is rebuilt from a serial console issue the diff --git a/arch/arm/cpu/arm926ejs/at91/led.c b/arch/arm/cpu/arm926ejs/at91/led.c index 46ed055..b8d5c78 100644 --- a/arch/arm/cpu/arm926ejs/at91/led.c +++ b/arch/arm/cpu/arm926ejs/at91/led.c @@ -9,6 +9,7 @@ #include <common.h> #include <asm/gpio.h> #include <asm/arch/gpio.h> +#include <status_led.h> #ifdef CONFIG_RED_LED void red_led_on(void) diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 828d10b..29b1d73 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -9,7 +9,9 @@ */ #include <common.h> +#include <dm.h> #include <errno.h> +#include <ns16550.h> #include <spl.h> #include <asm/arch/cpu.h> #include <asm/arch/hardware.h> @@ -36,6 +38,63 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_DM_GPIO +static const struct omap_gpio_platdata am33xx_gpio[] = { + { 0, AM33XX_GPIO0_BASE, METHOD_GPIO_24XX }, + { 1, AM33XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { 2, AM33XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { 3, AM33XX_GPIO3_BASE, METHOD_GPIO_24XX }, +#ifdef CONFIG_AM43XX + { 4, AM33XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { 5, AM33XX_GPIO5_BASE, METHOD_GPIO_24XX }, +#endif +}; + +U_BOOT_DEVICES(am33xx_gpios) = { + { "gpio_omap", &am33xx_gpio[0] }, + { "gpio_omap", &am33xx_gpio[1] }, + { "gpio_omap", &am33xx_gpio[2] }, + { "gpio_omap", &am33xx_gpio[3] }, +#ifdef CONFIG_AM43XX + { "gpio_omap", &am33xx_gpio[4] }, + { "gpio_omap", &am33xx_gpio[5] }, +#endif +}; + +# ifndef CONFIG_OF_CONTROL +/* + * TODO(sjg@chromium.org): When we can move SPL serial to DM, we can remove + * the CONFIGs. At the same time, we should move this to the board files. + */ +static const struct ns16550_platdata am33xx_serial[] = { + { CONFIG_SYS_NS16550_COM1, 2, CONFIG_SYS_NS16550_CLK }, +# ifdef CONFIG_SYS_NS16550_COM2 + { CONFIG_SYS_NS16550_COM2, 2, CONFIG_SYS_NS16550_CLK }, +# ifdef CONFIG_SYS_NS16550_COM3 + { CONFIG_SYS_NS16550_COM3, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM4, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM5, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM6, 2, CONFIG_SYS_NS16550_CLK }, +# endif +# endif +}; + +U_BOOT_DEVICES(am33xx_uarts) = { + { "serial_omap", &am33xx_serial[0] }, +# ifdef CONFIG_SYS_NS16550_COM2 + { "serial_omap", &am33xx_serial[1] }, +# ifdef CONFIG_SYS_NS16550_COM3 + { "serial_omap", &am33xx_serial[2] }, + { "serial_omap", &am33xx_serial[3] }, + { "serial_omap", &am33xx_serial[4] }, + { "serial_omap", &am33xx_serial[5] }, +# endif +# endif +}; +# endif + +#else + static const struct gpio_bank gpio_bank_am33xx[] = { { (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX }, { (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX }, @@ -49,6 +108,8 @@ static const struct gpio_bank gpio_bank_am33xx[] = { const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx; +#endif + #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) int cpu_mmc_init(bd_t *bis) { diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 6352422..a202b03 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -9,6 +9,7 @@ #include <common.h> #include <asm/armv7.h> +#include <asm/bootm.h> #include <asm/pl310.h> #include <asm/errno.h> #include <asm/io.h> diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 667e77f..c942fe6 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -17,13 +17,15 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <mmc.h> #include <spl.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> #include <asm/arch/mem.h> #include <asm/cache.h> #include <asm/armv7.h> -#include <asm/arch/gpio.h> +#include <asm/gpio.h> #include <asm/omap_common.h> #include <asm/arch/mmc_host_def.h> #include <i2c.h> @@ -38,6 +40,27 @@ static void omap3_setup_aux_cr(void); static void omap3_invalidate_l2_cache_secure(void); #endif +#ifdef CONFIG_DM_GPIO +static const struct omap_gpio_platdata omap34xx_gpio[] = { + { 0, OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { 1, OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { 2, OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { 3, OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { 4, OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { 5, OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, +}; + +U_BOOT_DEVICES(am33xx_gpios) = { + { "gpio_omap", &omap34xx_gpio[0] }, + { "gpio_omap", &omap34xx_gpio[1] }, + { "gpio_omap", &omap34xx_gpio[2] }, + { "gpio_omap", &omap34xx_gpio[3] }, + { "gpio_omap", &omap34xx_gpio[4] }, + { "gpio_omap", &omap34xx_gpio[5] }, +}; + +#else + static const struct gpio_bank gpio_bank_34xx[6] = { { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, @@ -49,6 +72,8 @@ static const struct gpio_bank gpio_bank_34xx[6] = { const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; +#endif + #ifdef CONFIG_SPL_BUILD /* * We use static variables because global data is not ready yet. @@ -266,7 +291,7 @@ int __weak misc_init_r(void) * Routine: wait_for_command_complete * Description: Wait for posting to finish on watchdog *****************************************************************************/ -void wait_for_command_complete(struct watchdog *wd_base) +static void wait_for_command_complete(struct watchdog *wd_base) { int pending = 1; do { diff --git a/arch/arm/cpu/armv7/omap3/emif4.c b/arch/arm/cpu/armv7/omap3/emif4.c index 6c7330a..a2aadc9 100644 --- a/arch/arm/cpu/armv7/omap3/emif4.c +++ b/arch/arm/cpu/armv7/omap3/emif4.c @@ -61,7 +61,7 @@ u32 get_sdr_cs_offset(u32 cs) * - Init the emif4 module for DDR access * - Early init routines, called from flash or SRAM. */ -void do_emif4_init(void) +static void do_emif4_init(void) { unsigned int regval; /* Set the DDR PHY parameters in PHY ctrl registers */ diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c index bef5f05..bbb65bb 100644 --- a/arch/arm/cpu/armv7/omap3/sys_info.c +++ b/arch/arm/cpu/armv7/omap3/sys_info.c @@ -16,6 +16,8 @@ #include <asm/io.h> #include <asm/arch/mem.h> /* get mem tables */ #include <asm/arch/sys_proto.h> +#include <asm/bootm.h> + #include <i2c.h> #include <linux/compiler.h> @@ -202,7 +204,7 @@ u32 __weak get_board_rev(void) /******************************************************** * get_base(); get upper addr of current execution *******************************************************/ -u32 get_base(void) +static u32 get_base(void) { u32 val; diff --git a/arch/arm/cpu/armv7/tegra20/display.c b/arch/arm/cpu/armv7/tegra20/display.c index fd77f3f..d98cec9 100644 --- a/arch/arm/cpu/armv7/tegra20/display.c +++ b/arch/arm/cpu/armv7/tegra20/display.c @@ -194,7 +194,8 @@ static void rgb_enable(struct dc_com_reg *com) writel(rgb_sel_tab[i], &com->pin_output_sel[i]); } -int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config) +static int setup_window(struct disp_ctl_win *win, + struct fdt_disp_config *config) { win->x = 0; win->y = 0; diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index b385e19..781b511 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \ sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c new file mode 100644 index 0000000..0047223 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/platdevice.h> + +#define UART_MASTER_CLK 36864000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index 712afd1..e11f4f6 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \ sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c new file mode 100644 index 0000000..6da921e --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/platdevice.h> + +#define UART_MASTER_CLK 73728000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index b385e19..781b511 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-y += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.o \ sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c new file mode 100644 index 0000000..59d054a --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/platdevice.h> + +#define UART_MASTER_CLK 80000000 + +SERIAL_DEVICE(0, 0x54006800, UART_MASTER_CLK) +SERIAL_DEVICE(1, 0x54006900, UART_MASTER_CLK) +SERIAL_DEVICE(2, 0x54006a00, UART_MASTER_CLK) +SERIAL_DEVICE(3, 0x54006b00, UART_MASTER_CLK) diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c index de20325..5933c35 100644 --- a/arch/arm/cpu/tegra-common/sys_info.c +++ b/arch/arm/cpu/tegra-common/sys_info.c @@ -8,7 +8,7 @@ #include <common.h> #include <linux/ctype.h> -void upstring(char *s) +static void upstring(char *s) { while (*s) { *s = toupper(*s); diff --git a/arch/arm/dts/am335x-bone-common.dtsi b/arch/arm/dts/am335x-bone-common.dtsi index 2f66ded..e70b4d1 100644 --- a/arch/arm/dts/am335x-bone-common.dtsi +++ b/arch/arm/dts/am335x-bone-common.dtsi @@ -10,6 +10,10 @@ model = "TI AM335x BeagleBone"; compatible = "ti,am335x-bone", "ti,am33xx"; + chosen { + stdout-path = &uart0; + }; + cpus { cpu@0 { cpu0-supply = <&dcdc2_reg>; diff --git a/arch/arm/dts/dt-bindings/gpio/gpio.h b/arch/arm/dts/dt-bindings/gpio/gpio.h deleted file mode 100644 index e6b1e0a..0000000 --- a/arch/arm/dts/dt-bindings/gpio/gpio.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This header provides constants for most GPIO bindings. - * - * Most GPIO bindings include a flags cell as part of the GPIO specifier. - * In most cases, the format of the flags cell uses the standard values - * defined in this header. - */ - -#ifndef _DT_BINDINGS_GPIO_GPIO_H -#define _DT_BINDINGS_GPIO_GPIO_H - -#define GPIO_ACTIVE_HIGH 0 -#define GPIO_ACTIVE_LOW 1 - -#endif diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c index ed826a0..09fc227 100644 --- a/arch/arm/imx-common/cpu.c +++ b/arch/arm/imx-common/cpu.c @@ -7,7 +7,9 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include <bootm.h> #include <common.h> +#include <netdev.h> #include <asm/errno.h> #include <asm/io.h> #include <asm/arch/imx-regs.h> diff --git a/arch/arm/imx-common/misc.c b/arch/arm/imx-common/misc.c index dbecf4e..12256a3 100644 --- a/arch/arm/imx-common/misc.c +++ b/arch/arm/imx-common/misc.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <asm/arch/sys_proto.h> #include <asm/errno.h> #include <asm/io.h> #include <asm/imx-common/regs-common.h> diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h index dded857..61f427d 100644 --- a/arch/arm/include/asm/arch-bcm2835/mbox.h +++ b/arch/arm/include/asm/arch-bcm2835/mbox.h @@ -119,6 +119,20 @@ struct bcm2835_mbox_tag_hdr { * }; */ +#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003 + +struct bcm2835_mbox_tag_get_mac_address { + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + } req; + struct { + u8 mac[6]; + u8 pad[2]; + } resp; + } body; +}; + #define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005 struct bcm2835_mbox_tag_get_arm_mem { diff --git a/arch/arm/include/asm/arch-mxs/sys_proto.h b/arch/arm/include/asm/arch-mxs/sys_proto.h index 09dfc90..062f3de 100644 --- a/arch/arm/include/asm/arch-mxs/sys_proto.h +++ b/arch/arm/include/asm/arch-mxs/sys_proto.h @@ -10,6 +10,8 @@ #ifndef __SYS_PROTO_H__ #define __SYS_PROTO_H__ +#include <asm/imx-common/regs-common.h> + int mxs_reset_block(struct mxs_register_32 *reg); int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 5866bf2..34bd8c5 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -64,6 +64,7 @@ void try_unlock_memory(void); u32 get_boot_type(void); void invalidate_dcache(u32); u32 wait_on_value(u32, u32, void *, u32); +void cancel_out(u32 *num, u32 *den, u32 den_limit); void sdelay(unsigned long); void make_cs1_contiguous(void); void omap_nand_switch_ecc(uint32_t, uint32_t); diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h index ff77364..783bb3c 100644 --- a/arch/arm/include/asm/arch-tegra/board.h +++ b/arch/arm/include/asm/arch-tegra/board.h @@ -24,10 +24,11 @@ void gpio_early_init(void); /* overrideable GPIO config */ * an empty stub function will be called. */ -void pinmux_init(void); /* overrideable general pinmux setup */ -void pin_mux_usb(void); /* overrideable USB pinmux setup */ -void pin_mux_spi(void); /* overrideable SPI pinmux setup */ -void pin_mux_nand(void); /* overrideable NAND pinmux setup */ -void pin_mux_display(void); /* overrideable DISPLAY pinmux setup */ +void pinmux_init(void); /* overridable general pinmux setup */ +void pin_mux_usb(void); /* overridable USB pinmux setup */ +void pin_mux_spi(void); /* overridable SPI pinmux setup */ +void pin_mux_nand(void); /* overridable NAND pinmux setup */ +void pin_mux_mmc(void); /* overridable mmc pinmux setup */ +void pin_mux_display(void); /* overridable DISPLAY pinmux setup */ #endif diff --git a/arch/arm/include/asm/arch-uniphier/platdevice.h b/arch/arm/include/asm/arch-uniphier/platdevice.h new file mode 100644 index 0000000..cdf7d13 --- /dev/null +++ b/arch/arm/include/asm/arch-uniphier/platdevice.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARCH_PLATDEVICE_H +#define ARCH_PLATDEVICE_H + +#include <dm/platdata.h> +#include <dm/platform_data/serial-uniphier.h> + +#define SERIAL_DEVICE(n, ba, clk) \ +static struct uniphier_serial_platform_data serial_device##n = { \ + .base = ba, \ + .uartclk = clk \ +}; \ +U_BOOT_DEVICE(serial##n) = { \ + .name = DRIVER_NAME, \ + .platdata = &serial_device##n \ +}; + +#endif /* ARCH_PLATDEVICE_H */ diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h index 5d25d04..839af54 100644 --- a/arch/arm/include/asm/omap_gpio.h +++ b/arch/arm/include/asm/omap_gpio.h @@ -23,6 +23,21 @@ #include <asm/arch/cpu.h> +enum gpio_method { + METHOD_GPIO_24XX = 4, +}; + +#ifdef CONFIG_DM_GPIO + +/* Information about a GPIO bank */ +struct omap_gpio_platdata { + int bank_index; + ulong base; /* address of registers in physical memory */ + enum gpio_method method; +}; + +#else + struct gpio_bank { void *base; int method; @@ -30,8 +45,6 @@ struct gpio_bank { extern const struct gpio_bank *const omap_gpio_bank; -#define METHOD_GPIO_24XX 4 - /** * Check if gpio is valid. * @@ -39,4 +52,6 @@ extern const struct gpio_bank *const omap_gpio_bank; * @return 1 if ok, 0 on error */ int gpio_is_valid(int gpio); +#endif + #endif /* _GPIO_H_ */ diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index b16694c..f97f3dd 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -45,4 +45,19 @@ void reset_timer_masked (void); ulong get_timer_masked (void); void udelay_masked (unsigned long usec); +/* calls to c from vectors.S */ +void bad_mode(void); +void do_undefined_instruction(struct pt_regs *pt_regs); +void do_software_interrupt(struct pt_regs *pt_regs); +void do_prefetch_abort(struct pt_regs *pt_regs); +void do_data_abort(struct pt_regs *pt_regs); +void do_not_used(struct pt_regs *pt_regs); +#ifdef CONFIG_ARM64 +void do_fiq(struct pt_regs *pt_regs, unsigned int esr); +void do_irq(struct pt_regs *pt_regs, unsigned int esr); +#else +void do_fiq(struct pt_regs *pt_regs); +void do_irq(struct pt_regs *pt_regswq); +#endif + #endif /* _U_BOOT_ARM_H_ */ diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 76adaf3..f606255 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -34,6 +34,7 @@ #include <onenand_uboot.h> #include <mmc.h> #include <scsi.h> +#include <status_led.h> #include <libfdt.h> #include <fdtdec.h> #include <post.h> @@ -63,25 +64,15 @@ extern void dataflash_print_info(void); ************************************************************************ * May be supplied by boards if desired */ -inline void __coloured_LED_init(void) {} -void coloured_LED_init(void) - __attribute__((weak, alias("__coloured_LED_init"))); -inline void __red_led_on(void) {} -void red_led_on(void) __attribute__((weak, alias("__red_led_on"))); -inline void __red_led_off(void) {} -void red_led_off(void) __attribute__((weak, alias("__red_led_off"))); -inline void __green_led_on(void) {} -void green_led_on(void) __attribute__((weak, alias("__green_led_on"))); -inline void __green_led_off(void) {} -void green_led_off(void) __attribute__((weak, alias("__green_led_off"))); -inline void __yellow_led_on(void) {} -void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on"))); -inline void __yellow_led_off(void) {} -void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off"))); -inline void __blue_led_on(void) {} -void blue_led_on(void) __attribute__((weak, alias("__blue_led_on"))); -inline void __blue_led_off(void) {} -void blue_led_off(void) __attribute__((weak, alias("__blue_led_off"))); +__weak void coloured_LED_init(void) {} +__weak void red_led_on(void) {} +__weak void red_led_off(void) {} +__weak void green_led_on(void) {} +__weak void green_led_off(void) {} +__weak void yellow_led_on(void) {} +__weak void yellow_led_off(void) {} +__weak void blue_led_on(void) {} +__weak void blue_led_off(void) {} /* ************************************************************************ @@ -198,27 +189,21 @@ static int arm_pci_init(void) */ typedef int (init_fnc_t) (void); -void __dram_init_banksize(void) +__weak void dram_init_banksize(void) { gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_dram[0].size = gd->ram_size; } -void dram_init_banksize(void) - __attribute__((weak, alias("__dram_init_banksize"))); -int __arch_cpu_init(void) +__weak int arch_cpu_init(void) { return 0; } -int arch_cpu_init(void) - __attribute__((weak, alias("__arch_cpu_init"))); -int __power_init_board(void) +__weak int power_init_board(void) { return 0; } -int power_init_board(void) - __attribute__((weak, alias("__power_init_board"))); /* Record the board_init_f() bootstage (after arch_cpu_init()) */ static int mark_bootstage(void) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 39fe7a1..0d19c8a 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -15,6 +15,7 @@ #include <common.h> #include <command.h> #include <image.h> +#include <vxworks.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> #include <libfdt.h> diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index f6b7c03..9019736 100644 --- a/arch/arm/lib/interrupts.c +++ b/arch/arm/lib/interrupts.c @@ -21,6 +21,7 @@ #include <common.h> #include <asm/proc-armv/ptrace.h> +#include <asm/u-boot-arm.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 329bb3a..338bab1 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -85,12 +85,25 @@ car_init_ret: /* Align global data to 16-byte boundary */ andl $0xfffffff0, %esp + /* Zero the global data since it won't happen later */ + xorl %eax, %eax + movl $GENERATED_GBL_DATA_SIZE, %ecx + movl %esp, %edi + rep stosb + /* Setup first parameter to setup_gdt */ movl %esp, %eax /* Reserve space for global descriptor table */ subl $X86_GDT_SIZE, %esp +#if defined(CONFIG_SYS_MALLOC_F_LEN) + subl $CONFIG_SYS_MALLOC_F_LEN, %esp + movl %eax, %edx + addl $GD_MALLOC_BASE, %edx + movl %esp, (%edx) +#endif + /* Align temporary global descriptor table to 16-byte boundary */ andl $0xfffffff0, %esp diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi index 4862a59..c8dc4ce 100644 --- a/arch/x86/dts/coreboot.dtsi +++ b/arch/x86/dts/coreboot.dtsi @@ -1,13 +1,14 @@ /include/ "skeleton.dtsi" / { - aliases { - console = "/serial"; + chosen { + stdout-path = "/serial"; }; serial { - compatible = "ns16550"; - reg-shift = <1>; + compatible = "coreboot-uart"; + reg = <0x3f8 0x10>; + reg-shift = <0>; io-mapped = <1>; multiplier = <1>; baudrate = <115200>; diff --git a/arch/x86/dts/link.dts b/arch/x86/dts/link.dts index 67ce52a..f2fcb39 100644 --- a/arch/x86/dts/link.dts +++ b/arch/x86/dts/link.dts @@ -12,7 +12,23 @@ silent_console = <0>; }; - gpio: gpio {}; + gpioa { + compatible = "intel,ich6-gpio"; + reg = <0 0x10>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + reg = <0x30 0x10>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + reg = <0x40 0x10>; + bank-name = "C"; + }; serial { reg = <0x3f8 8>; diff --git a/arch/x86/include/asm/arch-coreboot/gpio.h b/arch/x86/include/asm/arch-coreboot/gpio.h new file mode 100644 index 0000000..3ec1816 --- /dev/null +++ b/arch/x86/include/asm/arch-coreboot/gpio.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2014, Google Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +struct ich6_bank_platdata { + uint32_t base_addr; + const char *bank_name; +}; + +#endif /* _X86_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h index fe09f31..8bda414 100644 --- a/arch/x86/include/asm/gpio.h +++ b/arch/x86/include/asm/gpio.h @@ -6,6 +6,7 @@ #ifndef _X86_GPIO_H_ #define _X86_GPIO_H_ +#include <asm/arch/gpio.h> #include <asm-generic/gpio.h> #endif /* _X86_GPIO_H_ */ diff --git a/arch/x86/include/asm/ibmpc.h b/arch/x86/include/asm/ibmpc.h index 0f9665f..e6d183b 100644 --- a/arch/x86/include/asm/ibmpc.h +++ b/arch/x86/include/asm/ibmpc.h @@ -18,14 +18,4 @@ #define SYSCTLA 0x92 #define SLAVE_PIC 0xa0 -#if 1 -#define UART0_BASE 0x3f8 -#define UART1_BASE 0x2f8 -#else -/* FixMe: uarts swapped */ -#define UART0_BASE 0x2f8 -#define UART1_BASE 0x3f8 -#endif - - #endif diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 2f0e92f..b190283 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -282,7 +282,6 @@ void boot_zimage(void *setup_base, void *load_address) :: [kernel_entry]"a"(load_address), [boot_params] "S"(setup_base), "b"(0), "D"(0) - : "%ebp" ); } diff --git a/board/atmel/at91rm9200ek/led.c b/board/atmel/at91rm9200ek/led.c index 2298e36..6761b14 100644 --- a/board/atmel/at91rm9200ek/led.c +++ b/board/atmel/at91rm9200ek/led.c @@ -14,6 +14,7 @@ #include <asm/arch/hardware.h> #include <asm/arch/at91_pmc.h> #include <asm/arch/at91_pio.h> +#include <status_led.h> /* bit mask in PIO port B */ #define GREEN_LED (1<<0) diff --git a/board/atmel/at91sam9260ek/led.c b/board/atmel/at91sam9260ek/led.c index 56d811c..fbe15af 100644 --- a/board/atmel/at91sam9260ek/led.c +++ b/board/atmel/at91sam9260ek/led.c @@ -9,6 +9,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/gpio.h> +#include <status_led.h> void coloured_LED_init(void) { diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index f77ff48..82681b1 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -15,7 +15,6 @@ #include <netdev.h> #include <fdt_support.h> #include <sata.h> -#include <serial_mxc.h> #include <asm/arch/crm_regs.h> #include <asm/arch/sys_proto.h> #include <asm/arch/iomux.h> @@ -23,6 +22,7 @@ #include <asm/imx-common/sata.h> #include <asm/io.h> #include <asm/gpio.h> +#include <dm/platform_data/serial_mxc.h> #include "common.h" #include "../common/eeprom.h" diff --git a/board/isee/igep00x0/igep00x0.c b/board/isee/igep00x0/igep00x0.c index 3b2b1f1..7b87cc2 100644 --- a/board/isee/igep00x0/igep00x0.c +++ b/board/isee/igep00x0/igep00x0.c @@ -5,6 +5,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <ns16550.h> #include <twl4030.h> #include <netdev.h> #include <asm/gpio.h> @@ -30,6 +32,17 @@ static const u32 gpmc_lan_config[] = { }; #endif +static const struct ns16550_platdata igep_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(igep_uart) = { + "serial_omap", + &igep_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/logicpd/zoom1/zoom1.c b/board/logicpd/zoom1/zoom1.c index 461a852..9ef0026 100644 --- a/board/logicpd/zoom1/zoom1.c +++ b/board/logicpd/zoom1/zoom1.c @@ -15,6 +15,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <ns16550.h> #include <netdev.h> #include <twl4030.h> #include <asm/io.h> @@ -41,6 +43,17 @@ static const u32 gpmc_lab_enet[] = { /*CONF7- computed as params */ }; +static const struct ns16550_platdata zoom1_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(zoom1_uart) = { + "serial_omap", + &zoom1_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 03f055d..51125df 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -47,46 +47,19 @@ const struct tegra_sysinfo sysinfo = { CONFIG_TEGRA_BOARD_STRING }; -void __pinmux_init(void) -{ -} - -void pinmux_init(void) __attribute__((weak, alias("__pinmux_init"))); - -void __pin_mux_usb(void) -{ -} - -void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb"))); - -void __pin_mux_spi(void) -{ -} - -void pin_mux_spi(void) __attribute__((weak, alias("__pin_mux_spi"))); - -void __gpio_early_init_uart(void) -{ -} - -void gpio_early_init_uart(void) -__attribute__((weak, alias("__gpio_early_init_uart"))); +__weak void pinmux_init(void) {} +__weak void pin_mux_usb(void) {} +__weak void pin_mux_spi(void) {} +__weak void gpio_early_init_uart(void) {} +__weak void pin_mux_display(void) {} #if defined(CONFIG_TEGRA_NAND) -void __pin_mux_nand(void) +__weak void pin_mux_nand(void) { funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT); } - -void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand"))); #endif -void __pin_mux_display(void) -{ -} - -void pin_mux_display(void) __attribute__((weak, alias("__pin_mux_display"))); - /* * Routine: power_det_init * Description: turn off power detects @@ -204,12 +177,10 @@ int board_late_init(void) } #if defined(CONFIG_TEGRA_MMC) -void __pin_mux_mmc(void) +__weak void pin_mux_mmc(void) { } -void pin_mux_mmc(void) __attribute__((weak, alias("__pin_mux_mmc"))); - /* this is a weak define that we are overriding */ int board_mmc_init(bd_t *bd) { diff --git a/board/nvidia/common/emc.c b/board/nvidia/common/emc.c index 8124f8a..8c62f36 100644 --- a/board/nvidia/common/emc.c +++ b/board/nvidia/common/emc.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include "emc.h" #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/emc.h> diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c index 6a243f0..11472eb 100644 --- a/board/nvidia/seaboard/seaboard.c +++ b/board/nvidia/seaboard/seaboard.c @@ -8,6 +8,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/tegra.h> +#include <asm/arch-tegra/board.h> #include <asm/arch/clock.h> #include <asm/arch/funcmux.h> #include <asm/arch/gpio.h> diff --git a/board/overo/overo.c b/board/overo/overo.c index 13220c5..7506820 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -13,6 +13,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <ns16550.h> #include <netdev.h> #include <twl4030.h> #include <linux/mtd/nand.h> @@ -73,6 +75,17 @@ static const u32 gpmc_lan_config[] = { /*CONFIG7- computed as params */ }; +static const struct ns16550_platdata overo_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(overo_uart) = { + "serial_omap", + &overo_serial +}; + /* * Routine: board_init * Description: Early hardware init. diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c index 447c940..7445f53 100644 --- a/board/raspberrypi/rpi_b/rpi_b.c +++ b/board/raspberrypi/rpi_b/rpi_b.c @@ -42,6 +42,12 @@ struct msg_get_arm_mem { u32 end_tag; }; +struct msg_get_mac_address { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_get_mac_address get_mac_address; + u32 end_tag; +}; + struct msg_set_power_state { struct bcm2835_mbox_hdr hdr; struct bcm2835_mbox_tag_set_power_state set_power_state; @@ -73,6 +79,29 @@ int dram_init(void) return 0; } +int misc_init_r(void) +{ + ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16); + int ret; + + if (getenv("usbethaddr")) + return 0; + + BCM2835_MBOX_INIT_HDR(msg); + BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS); + + ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); + if (ret) { + printf("bcm2835: Could not query MAC address\n"); + /* Ignore error; not critical */ + return 0; + } + + eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac); + + return 0; +} + static int power_on_module(u32 module) { ALLOC_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1, 16); diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index e1fc123..8b4c8e9 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -28,19 +28,15 @@ DECLARE_GLOBAL_DATA_PTR; -int __exynos_early_init_f(void) +__weak int exynos_early_init_f(void) { return 0; } -int exynos_early_init_f(void) - __attribute__((weak, alias("__exynos_early_init_f"))); -int __exynos_power_init(void) +__weak int exynos_power_init(void) { return 0; } -int exynos_power_init(void) - __attribute__((weak, alias("__exynos_power_init"))); #if defined CONFIG_EXYNOS_TMU /* Boot Time Thermal Analysis for SoC temperature threshold breach */ diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c index 054e7cc..a4aed3b 100644 --- a/board/technexion/twister/twister.c +++ b/board/technexion/twister/twister.c @@ -16,6 +16,8 @@ #include <asm/omap_gpio.h> #include <asm/arch/mmc_host_def.h> #include <i2c.h> +#include <spl.h> +#include <mmc.h> #include <asm/gpio.h> #ifdef CONFIG_USB_EHCI #include <usb.h> diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 94b99bf..4c5e381 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -14,6 +14,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <ns16550.h> #ifdef CONFIG_STATUS_LED #include <status_led.h> #endif @@ -70,6 +72,17 @@ static struct { char env_setting[64]; } expansion_config; +static const struct ns16550_platdata beagle_serial = { + OMAP34XX_UART3, + 2, + V_NS16550_CLK +}; + +U_BOOT_DEVICE(beagle_uart) = { + "serial_omap", + &beagle_serial +}; + /* * Routine: board_init * Description: Early hardware init. @@ -103,22 +116,22 @@ int board_init(void) */ static int get_board_revision(void) { - int revision; - - if (!gpio_request(171, "") && - !gpio_request(172, "") && - !gpio_request(173, "")) { - - gpio_direction_input(171); - gpio_direction_input(172); - gpio_direction_input(173); - - revision = gpio_get_value(173) << 2 | - gpio_get_value(172) << 1 | - gpio_get_value(171); - } else { - printf("Error: unable to acquire board revision GPIOs\n"); - revision = -1; + static int revision = -1; + + if (revision == -1) { + if (!gpio_request(171, "rev0") && + !gpio_request(172, "rev1") && + !gpio_request(173, "rev2")) { + gpio_direction_input(171); + gpio_direction_input(172); + gpio_direction_input(173); + + revision = gpio_get_value(173) << 2 | + gpio_get_value(172) << 1 | + gpio_get_value(171); + } else { + printf("Error: unable to acquire board revision GPIOs\n"); + } } return revision; @@ -258,7 +271,7 @@ static void beagle_dvi_pup(void) case REVISION_AXBX: case REVISION_CX: case REVISION_C4: - gpio_request(170, ""); + gpio_request(170, "dvi"); gpio_direction_output(170, 0); gpio_set_value(170, 1); break; diff --git a/board/ti/beagle/led.c b/board/ti/beagle/led.c index 89b8dd3..a913a4c 100644 --- a/board/ti/beagle/led.c +++ b/board/ti/beagle/led.c @@ -27,47 +27,46 @@ void green_led_on(void) } #endif +static int get_led_gpio(led_id_t mask) +{ +#ifdef STATUS_LED_BIT + if (STATUS_LED_BIT & mask) + return BEAGLE_LED_USR0; +#endif +#ifdef STATUS_LED_BIT1 + if (STATUS_LED_BIT1 & mask) + return BEAGLE_LED_USR1; +#endif + + return 0; +} + void __led_init (led_id_t mask, int state) { - __led_set (mask, state); + int toggle_gpio; + + toggle_gpio = get_led_gpio(mask); + + if (toggle_gpio && !gpio_request(toggle_gpio, "led")) + __led_set(mask, state); } void __led_toggle (led_id_t mask) { - int state, toggle_gpio = 0; -#ifdef STATUS_LED_BIT - if (!toggle_gpio && STATUS_LED_BIT & mask) - toggle_gpio = BEAGLE_LED_USR0; -#endif -#ifdef STATUS_LED_BIT1 - if (!toggle_gpio && STATUS_LED_BIT1 & mask) - toggle_gpio = BEAGLE_LED_USR1; -#endif + int state, toggle_gpio; + + toggle_gpio = get_led_gpio(mask); if (toggle_gpio) { - if (!gpio_request(toggle_gpio, "")) { - gpio_direction_output(toggle_gpio, 0); - state = gpio_get_value(toggle_gpio); - gpio_set_value(toggle_gpio, !state); - } + state = gpio_get_value(toggle_gpio); + gpio_direction_output(toggle_gpio, !state); } } void __led_set (led_id_t mask, int state) { -#ifdef STATUS_LED_BIT - if (STATUS_LED_BIT & mask) { - if (!gpio_request(BEAGLE_LED_USR0, "")) { - gpio_direction_output(BEAGLE_LED_USR0, 0); - gpio_set_value(BEAGLE_LED_USR0, state); - } - } -#endif -#ifdef STATUS_LED_BIT1 - if (STATUS_LED_BIT1 & mask) { - if (!gpio_request(BEAGLE_LED_USR1, "")) { - gpio_direction_output(BEAGLE_LED_USR1, 0); - gpio_set_value(BEAGLE_LED_USR1, state); - } - } -#endif + int toggle_gpio; + + toggle_gpio = get_led_gpio(mask); + if (toggle_gpio) + gpio_direction_output(toggle_gpio, state); } diff --git a/board/w7o/fsboot.c b/board/w7o/fsboot.c index 25fbb55..8f4fe31 100644 --- a/board/w7o/fsboot.c +++ b/board/w7o/fsboot.c @@ -8,12 +8,11 @@ #include <common.h> #include <config.h> #include <command.h> +#include <elf.h> /* * FIXME: Add code to test image and it's header. */ -extern int valid_elf_image (unsigned long addr); - static int image_check(ulong addr) { diff --git a/common/board_f.c b/common/board_f.c index e6aa298..b5bebc9 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -128,14 +128,11 @@ int init_func_watchdog_reset(void) } #endif /* CONFIG_WATCHDOG */ -void __board_add_ram_info(int use_default) +__weak void board_add_ram_info(int use_default) { /* please define platform specific board_add_ram_info() */ } -void board_add_ram_info(int) - __attribute__ ((weak, alias("__board_add_ram_info"))); - static int init_baud_rate(void) { gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); @@ -221,7 +218,7 @@ static int show_dram_config(void) return 0; } -void __dram_init_banksize(void) +__weak void dram_init_banksize(void) { #if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE) gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; @@ -229,9 +226,6 @@ void __dram_init_banksize(void) #endif } -void dram_init_banksize(void) - __attribute__((weak, alias("__dram_init_banksize"))); - #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C) static int init_func_i2c(void) { diff --git a/common/board_r.c b/common/board_r.c index 3affb63..7c33900 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -60,7 +60,7 @@ DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; -int __board_flash_wp_on(void) +__weak int board_flash_wp_on(void) { /* * Most flashes can't be detected when write protection is enabled, @@ -70,16 +70,10 @@ int __board_flash_wp_on(void) return 0; } -int board_flash_wp_on(void) - __attribute__ ((weak, alias("__board_flash_wp_on"))); - -void __cpu_secondary_init_r(void) +__weak void cpu_secondary_init_r(void) { } -void cpu_secondary_init_r(void) - __attribute__ ((weak, alias("__cpu_secondary_init_r"))); - static int initr_secondary_cpu(void) { /* @@ -370,7 +364,7 @@ static int initr_spi(void) #ifdef CONFIG_CMD_NAND /* go init the NAND */ -int initr_nand(void) +static int initr_nand(void) { puts("NAND: "); nand_init(); @@ -380,7 +374,7 @@ int initr_nand(void) #if defined(CONFIG_CMD_ONENAND) /* go init the NAND */ -int initr_onenand(void) +static int initr_onenand(void) { puts("NAND: "); onenand_init(); @@ -389,7 +383,7 @@ int initr_onenand(void) #endif #ifdef CONFIG_GENERIC_MMC -int initr_mmc(void) +static int initr_mmc(void) { puts("MMC: "); mmc_initialize(gd->bd); @@ -398,7 +392,7 @@ int initr_mmc(void) #endif #ifdef CONFIG_HAS_DATAFLASH -int initr_dataflash(void) +static int initr_dataflash(void) { AT91F_DataflashInit(); dataflash_print_info(); diff --git a/common/cmd_elf.c b/common/cmd_elf.c index ab9c7e3..42a5296 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -14,6 +14,7 @@ */ #include <common.h> +#include <bootm.h> #include <command.h> #include <linux/ctype.h> #include <net.h> @@ -28,8 +29,7 @@ static unsigned long load_elf_image_phdr(unsigned long addr); static unsigned long load_elf_image_shdr(unsigned long addr); /* Allow ports to override the default behavior */ -__attribute__((weak)) -unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), +static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), int argc, char * const argv[]) { unsigned long ret; diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 11f4e40..65d6df4 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -12,7 +12,7 @@ #include <dm.h> #include <asm/gpio.h> -int __weak name_to_gpio(const char *name) +__weak int name_to_gpio(const char *name) { return simple_strtoul(name, NULL, 10); } @@ -25,13 +25,6 @@ enum gpio_cmd { }; #if defined(CONFIG_DM_GPIO) && !defined(gpio_status) -static const char * const gpio_function[GPIOF_COUNT] = { - "input", - "output", - "unused", - "unknown", - "func", -}; /* A few flags used by show_gpio() */ enum { @@ -40,22 +33,16 @@ enum { FLAG_SHOW_NEWLINE = 1 << 2, }; -static void show_gpio(struct udevice *dev, const char *bank_name, int offset, - int *flagsp) +static void gpio_get_description(struct udevice *dev, const char *bank_name, + int offset, int *flagsp) { - struct dm_gpio_ops *ops = gpio_get_ops(dev); - int func = GPIOF_UNKNOWN; char buf[80]; int ret; - BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); - - if (ops->get_function) { - ret = ops->get_function(dev, offset); - if (ret >= 0 && ret < ARRAY_SIZE(gpio_function)) - func = ret; - } - if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED) + ret = gpio_get_function(dev, offset, NULL); + if (ret < 0) + goto err; + if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED) return; if ((*flagsp & FLAG_SHOW_BANK) && bank_name) { if (*flagsp & FLAG_SHOW_NEWLINE) { @@ -65,20 +52,15 @@ static void show_gpio(struct udevice *dev, const char *bank_name, int offset, printf("Bank %s:\n", bank_name); *flagsp &= ~FLAG_SHOW_BANK; } - *buf = '\0'; - if (ops->get_state) { - ret = ops->get_state(dev, offset, buf, sizeof(buf)); - if (ret) { - puts("<unknown>"); - return; - } - } else { - sprintf(buf, "%s%u: %8s %d", bank_name, offset, - gpio_function[func], ops->get_value(dev, offset)); - } - puts(buf); - puts("\n"); + ret = gpio_get_status(dev, offset, buf, sizeof(buf)); + if (ret) + goto err; + + printf("%s\n", buf); + return; +err: + printf("Error %d\n", ret); } static int do_gpio_status(bool all, const char *gpio_name) @@ -101,8 +83,10 @@ static int do_gpio_status(bool all, const char *gpio_name) if (all) flags |= FLAG_SHOW_ALL; bank_name = gpio_get_bank_info(dev, &num_bits); - if (!num_bits) + if (!num_bits) { + debug("GPIO device %s has no bits\n", dev->name); continue; + } banklen = bank_name ? strlen(bank_name) : 0; if (!gpio_name || !bank_name || @@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name) p = gpio_name + banklen; if (gpio_name && *p) { offset = simple_strtoul(p, NULL, 10); - show_gpio(dev, bank_name, offset, &flags); + gpio_get_description(dev, bank_name, offset, + &flags); } else { for (offset = 0; offset < num_bits; offset++) { - show_gpio(dev, bank_name, offset, - &flags); + gpio_get_description(dev, bank_name, + offset, &flags); } } } diff --git a/common/console.c b/common/console.c index 5a2f411..4695386 100644 --- a/common/console.c +++ b/common/console.c @@ -7,6 +7,7 @@ #include <common.h> #include <stdarg.h> +#include <iomux.h> #include <malloc.h> #include <os.h> #include <serial.h> @@ -621,7 +622,7 @@ inline void dbg(const char *fmt, ...) } #else -inline void dbg(const char *fmt, ...) +static inline void dbg(const char *fmt, ...) { } #endif diff --git a/common/env_nand.c b/common/env_nand.c index 5a734a9..749605f 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -124,7 +124,7 @@ int env_init(void) * The legacy NAND code saved the environment in the first NAND device i.e., * nand_dev_desc + 0. This is also the behaviour using the new NAND code. */ -int writeenv(size_t offset, u_char *buf) +static int writeenv(size_t offset, u_char *buf) { size_t end = offset + CONFIG_ENV_RANGE; size_t amount_saved = 0; @@ -233,7 +233,7 @@ int saveenv(void) } #endif /* CMD_SAVEENV */ -int readenv(size_t offset, u_char *buf) +static int readenv(size_t offset, u_char *buf) { size_t end = offset + CONFIG_ENV_RANGE; size_t amount_loaded = 0; diff --git a/common/image-fit.c b/common/image-fit.c index 2016d1e..a272ea2 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1434,7 +1434,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p) printf("%s FDT: %s\n", p, uname); } -int fit_image_select(const void *fit, int rd_noffset, int verify) +static int fit_image_select(const void *fit, int rd_noffset, int verify) { fit_image_print(fit, rd_noffset, " "); diff --git a/common/menu.c b/common/menu.c index 94afeb2..e81c074 100644 --- a/common/menu.c +++ b/common/menu.c @@ -105,12 +105,9 @@ static inline void *menu_item_destroy(struct menu *m, return NULL; } -void __menu_display_statusline(struct menu *m) +__weak void menu_display_statusline(struct menu *m) { - return; } -void menu_display_statusline(struct menu *m) - __attribute__ ((weak, alias("__menu_display_statusline"))); /* * Display a menu so the user can make a choice of an item. First display its diff --git a/common/modem.c b/common/modem.c index be54b10..96b1064 100644 --- a/common/modem.c +++ b/common/modem.c @@ -19,7 +19,7 @@ static inline void mdm_readline(char *buf, int bufsiz) for(;;) { c = serial_getc(); - /* dbg("(%c)", c); */ + debug("(%c)", c); switch(c) { case '\r': @@ -40,7 +40,6 @@ static inline void mdm_readline(char *buf, int bufsiz) } } -extern void dbg(const char *fmt, ...); int mdm_init (void) { char env_str[16]; @@ -66,15 +65,15 @@ int mdm_init (void) serial_puts("\n"); for(;;) { mdm_readline(console_buffer, CONFIG_SYS_CBSIZE); - dbg("ini%d: [%s]", i, console_buffer); + debug("ini%d: [%s]", i, console_buffer); if ((strcmp(console_buffer, "OK") == 0) || (strcmp(console_buffer, "ERROR") == 0)) { - dbg("ini%d: cmd done", i); + debug("ini%d: cmd done", i); break; } else /* in case we are originating call ... */ if (strncmp(console_buffer, "CONNECT", 7) == 0) { - dbg("ini%d: connect", i); + debug("ini%d: connect", i); return 0; } } @@ -90,9 +89,9 @@ int mdm_init (void) for(;i > 1;) { /* if 'i' > 1 - wait for connection message from modem */ mdm_readline(console_buffer, CONFIG_SYS_CBSIZE); - dbg("ini_f: [%s]", console_buffer); + debug("ini_f: [%s]", console_buffer); if (strncmp(console_buffer, "CONNECT", 7) == 0) { - dbg("ini_f: connected"); + debug("ini_f: connected"); return 0; } } diff --git a/common/stdio.c b/common/stdio.c index 8232815..68c595d 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -39,39 +39,39 @@ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" }; #endif #ifdef CONFIG_SYS_DEVICE_NULLDEV -void nulldev_putc(struct stdio_dev *dev, const char c) +static void nulldev_putc(struct stdio_dev *dev, const char c) { /* nulldev is empty! */ } -void nulldev_puts(struct stdio_dev *dev, const char *s) +static void nulldev_puts(struct stdio_dev *dev, const char *s) { /* nulldev is empty! */ } -int nulldev_input(struct stdio_dev *dev) +static int nulldev_input(struct stdio_dev *dev) { /* nulldev is empty! */ return 0; } #endif -void stdio_serial_putc(struct stdio_dev *dev, const char c) +static void stdio_serial_putc(struct stdio_dev *dev, const char c) { serial_putc(c); } -void stdio_serial_puts(struct stdio_dev *dev, const char *s) +static void stdio_serial_puts(struct stdio_dev *dev, const char *s) { serial_puts(s); } -int stdio_serial_getc(struct stdio_dev *dev) +static int stdio_serial_getc(struct stdio_dev *dev) { return serial_getc(); } -int stdio_serial_tstc(struct stdio_dev *dev) +static int stdio_serial_tstc(struct stdio_dev *dev) { return serial_tstc(); } diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig index 38450c0..b631c41 100644 --- a/configs/am335x_boneblack_defconfig +++ b/configs/am335x_boneblack_defconfig @@ -1,4 +1,4 @@ CONFIG_SPL=y -CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT" +CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT" +S:CONFIG_ARM=y +S:CONFIG_TARGET_AM335X_EVM=y diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index e257143..5837a0a 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -1,5 +1,5 @@ CONFIG_SPL=y -CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,EMMC_BOOT,ENABLE_VBOOT" +CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT" +S:CONFIG_ARM=y +S:CONFIG_TARGET_AM335X_EVM=y CONFIG_OF_CONTROL=y diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index 53f3126..e6aba42 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -2,7 +2,10 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_UNIPHIER=y +S:CONFIG_MACH_PH1_LD4=y +CONFIG_DM=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 +CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 209466e..334ec4b 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -2,7 +2,10 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_UNIPHIER=y +S:CONFIG_MACH_PH1_PRO4=y +CONFIG_DM=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 +CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 658977b..4e8f354 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -2,7 +2,10 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_UNIPHIER=y +S:CONFIG_MACH_PH1_SLD8=y +CONFIG_DM=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 +CONFIG_DM_SERIAL=y +CONFIG_UNIPHIER_SERIAL=y S:CONFIG_SPL_NAND_DENALI=y diff --git a/disk/part.c b/disk/part.c index cfd77b0..43485c9 100644 --- a/disk/part.c +++ b/disk/part.c @@ -57,7 +57,7 @@ static const struct block_drvr block_drvr[] = { DECLARE_GLOBAL_DATA_PTR; #ifdef HAVE_BLOCK_DEVICE -block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) +static block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index 8dfcf75..0278dda 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -95,7 +95,7 @@ are provided in test/dm. To run them, try: You should see something like this: <...U-Boot banner...> - Running 22 driver model tests + Running 29 driver model tests Test: dm_test_autobind Test: dm_test_autoprobe Test: dm_test_bus_children @@ -115,7 +115,12 @@ You should see something like this: Device 'd-test': seq 3 is in use by 'b-test' Device 'a-test': seq 0 is in use by 'd-test' Test: dm_test_gpio - sandbox_gpio: sb_gpio_get_value: error: offset 4 not reserved + extra-gpios: get_value: error: gpio b5 not reserved + Test: dm_test_gpio_anon + Test: dm_test_gpio_copy + Test: dm_test_gpio_leak + extra-gpios: get_value: error: gpio b5 not reserved + Test: dm_test_gpio_requestf Test: dm_test_leak Test: dm_test_lifecycle Test: dm_test_operations @@ -123,6 +128,26 @@ You should see something like this: Test: dm_test_platdata Test: dm_test_pre_reloc Test: dm_test_remove + Test: dm_test_spi_find + Invalid chip select 0:0 (err=-19) + SF: Failed to get idcodes + Device 'name-emul': seq 0 is in use by 'name-emul' + SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB + Test: dm_test_spi_flash + 2097152 bytes written in 0 ms + SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB + SPI flash test: + 0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps + Test passed + 0 erase: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 1 check: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 2 write: 0 ticks, 65536000 KiB/s 524288.000 Mbps + 3 read: 0 ticks, 65536000 KiB/s 524288.000 Mbps + Test: dm_test_spi_xfer + SF: Detected M25P16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB Test: dm_test_uclass Test: dm_test_uclass_before_ready Failures: 0 diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index e69de29..d2799dc 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -0,0 +1,6 @@ +config DM + bool "Enable Driver Model" + depends on !SPL_BUILD + help + This config option enables Driver Model. + To use legacy drivers, say N. diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e69de29..d21302f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -0,0 +1,6 @@ +config DM_GPIO + bool "Enable Driver Model for GPIO drivers" + depends on DM + help + If you want to use driver model for GPIO drivers, say Y. + To use legacy GPIO drivers, say N. diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c index 332cfc2..0244c01 100644 --- a/drivers/gpio/bcm2835_gpio.c +++ b/drivers/gpio/bcm2835_gpio.c @@ -11,67 +11,10 @@ #include <asm/gpio.h> #include <asm/io.h> -#define GPIO_NAME_SIZE 20 - struct bcm2835_gpios { - char label[BCM2835_GPIO_COUNT][GPIO_NAME_SIZE]; struct bcm2835_gpio_regs *reg; }; -/** - * gpio_is_requested() - check if a GPIO has been requested - * - * @bank: Bank to check - * @offset: GPIO offset within bank to check - * @return true if marked as requested, false if not - */ -static inline bool gpio_is_requested(struct bcm2835_gpios *gpios, int offset) -{ - return *gpios->label[offset] != '\0'; -} - -static int check_requested(struct udevice *dev, unsigned offset, - const char *func) -{ - struct bcm2835_gpios *gpios = dev_get_priv(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - - if (!gpio_is_requested(gpios, offset)) { - printf("omap_gpio: %s: error: gpio %s%d not requested\n", - func, uc_priv->bank_name, offset); - return -EPERM; - } - - return 0; -} - -static int bcm2835_gpio_request(struct udevice *dev, unsigned offset, - const char *label) -{ - struct bcm2835_gpios *gpios = dev_get_priv(dev); - - if (gpio_is_requested(gpios, offset)) - return -EBUSY; - - strncpy(gpios->label[offset], label, GPIO_NAME_SIZE); - gpios->label[offset][GPIO_NAME_SIZE - 1] = '\0'; - - return 0; -} - -static int bcm2835_gpio_free(struct udevice *dev, unsigned offset) -{ - struct bcm2835_gpios *gpios = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; - gpios->label[offset][0] = '\0'; - - return 0; -} - static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio) { struct bcm2835_gpios *gpios = dev_get_priv(dev); @@ -142,9 +85,6 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset) { struct bcm2835_gpios *gpios = dev_get_priv(dev); - if (!gpio_is_requested(gpios, offset)) - return GPIOF_UNUSED; - /* GPIOF_FUNC is not implemented yet */ if (bcm2835_gpio_is_output(gpios, offset)) return GPIOF_OUTPUT; @@ -152,42 +92,13 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_INPUT; } -static int bcm2835_gpio_get_state(struct udevice *dev, unsigned int offset, - char *buf, int bufsize) -{ - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct bcm2835_gpios *gpios = dev_get_priv(dev); - const char *label; - bool requested; - bool is_output; - int size; - - label = gpios->label[offset]; - is_output = bcm2835_gpio_is_output(gpios, offset); - size = snprintf(buf, bufsize, "%s%d: ", - uc_priv->bank_name ? uc_priv->bank_name : "", offset); - buf += size; - bufsize -= size; - requested = gpio_is_requested(gpios, offset); - snprintf(buf, bufsize, "%s: %d [%c]%s%s", - is_output ? "out" : " in", - bcm2835_get_value(gpios, offset), - requested ? 'x' : ' ', - requested ? " " : "", - label); - - return 0; -} static const struct dm_gpio_ops gpio_bcm2835_ops = { - .request = bcm2835_gpio_request, - .free = bcm2835_gpio_free, .direction_input = bcm2835_gpio_direction_input, .direction_output = bcm2835_gpio_direction_output, .get_value = bcm2835_gpio_get_value, .set_value = bcm2835_gpio_set_value, .get_function = bcm2835_gpio_get_function, - .get_state = bcm2835_gpio_get_state, }; static int bcm2835_gpio_probe(struct udevice *dev) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index f1bbc58..45e9a5a 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -7,7 +7,9 @@ #include <common.h> #include <dm.h> #include <errno.h> +#include <malloc.h> #include <asm/gpio.h> +#include <linux/ctype.h> /** * gpio_to_device() - Convert global GPIO number to device, number @@ -43,35 +45,47 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp, int gpio_lookup_name(const char *name, struct udevice **devp, unsigned int *offsetp, unsigned int *gpiop) { - struct gpio_dev_priv *uc_priv; + struct gpio_dev_priv *uc_priv = NULL; struct udevice *dev; + ulong offset; + int numeric; int ret; if (devp) *devp = NULL; + numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { - ulong offset; int len; uc_priv = dev->uclass_priv; + if (numeric != -1) { + offset = numeric - uc_priv->gpio_base; + /* Allow GPIOs to be numbered from 0 */ + if (offset >= 0 && offset < uc_priv->gpio_count) + break; + } + len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; if (!strncasecmp(name, uc_priv->bank_name, len)) { - if (strict_strtoul(name + len, 10, &offset)) - continue; - if (devp) - *devp = dev; - if (offsetp) - *offsetp = offset; - if (gpiop) - *gpiop = uc_priv->gpio_base + offset; - return 0; + if (!strict_strtoul(name + len, 10, &offset)) + break; } } - return ret ? ret : -EINVAL; + if (!dev) + return ret ? ret : -EINVAL; + + if (devp) + *devp = dev; + if (offsetp) + *offsetp = offset; + if (gpiop) + *gpiop = uc_priv->gpio_base + offset; + + return 0; } /** @@ -79,24 +93,62 @@ int gpio_lookup_name(const char *name, struct udevice **devp, * gpio: GPIO number * label: Name for the requested GPIO * + * The label is copied and allocated so the caller does not need to keep + * the pointer around. + * * This function implements the API that's compatible with current * GPIO API used in U-Boot. The request is forwarded to particular * GPIO driver. Returns 0 on success, negative value on error. */ int gpio_request(unsigned gpio, const char *label) { + struct gpio_dev_priv *uc_priv; unsigned int offset; struct udevice *dev; + char *str; int ret; ret = gpio_to_device(gpio, &dev, &offset); if (ret) return ret; - if (!gpio_get_ops(dev)->request) - return 0; + uc_priv = dev->uclass_priv; + if (uc_priv->name[offset]) + return -EBUSY; + str = strdup(label); + if (!str) + return -ENOMEM; + if (gpio_get_ops(dev)->request) { + ret = gpio_get_ops(dev)->request(dev, offset, label); + if (ret) { + free(str); + return ret; + } + } + uc_priv->name[offset] = str; + + return 0; +} + +/** + * gpio_requestf() - [COMPAT] Request GPIO + * @gpio: GPIO number + * @fmt: Format string for the requested GPIO + * @...: Arguments for the printf() format string + * + * This function implements the API that's compatible with current + * GPIO API used in U-Boot. The request is forwarded to particular + * GPIO driver. Returns 0 on success, negative value on error. + */ +int gpio_requestf(unsigned gpio, const char *fmt, ...) +{ + va_list args; + char buf[40]; - return gpio_get_ops(dev)->request(dev, offset, label); + va_start(args, fmt); + vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + return gpio_request(gpio, buf); } /** @@ -109,6 +161,7 @@ int gpio_request(unsigned gpio, const char *label) */ int gpio_free(unsigned gpio) { + struct gpio_dev_priv *uc_priv; unsigned int offset; struct udevice *dev; int ret; @@ -117,9 +170,34 @@ int gpio_free(unsigned gpio) if (ret) return ret; - if (!gpio_get_ops(dev)->free) - return 0; - return gpio_get_ops(dev)->free(dev, offset); + uc_priv = dev->uclass_priv; + if (!uc_priv->name[offset]) + return -ENXIO; + if (gpio_get_ops(dev)->free) { + ret = gpio_get_ops(dev)->free(dev, offset); + if (ret) + return ret; + } + + free(uc_priv->name[offset]); + uc_priv->name[offset] = NULL; + + return 0; +} + +static int check_reserved(struct udevice *dev, unsigned offset, + const char *func) +{ + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + + if (!uc_priv->name[offset]) { + printf("%s: %s: error: gpio %s%d not reserved\n", + dev->name, func, + uc_priv->bank_name ? uc_priv->bank_name : "", offset); + return -EBUSY; + } + + return 0; } /** @@ -139,8 +217,9 @@ int gpio_direction_input(unsigned gpio) ret = gpio_to_device(gpio, &dev, &offset); if (ret) return ret; + ret = check_reserved(dev, offset, "dir_input"); - return gpio_get_ops(dev)->direction_input(dev, offset); + return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset); } /** @@ -161,8 +240,10 @@ int gpio_direction_output(unsigned gpio, int value) ret = gpio_to_device(gpio, &dev, &offset); if (ret) return ret; + ret = check_reserved(dev, offset, "dir_output"); - return gpio_get_ops(dev)->direction_output(dev, offset, value); + return ret ? ret : + gpio_get_ops(dev)->direction_output(dev, offset, value); } /** @@ -183,8 +264,9 @@ int gpio_get_value(unsigned gpio) ret = gpio_to_device(gpio, &dev, &offset); if (ret) return ret; + ret = check_reserved(dev, offset, "get_value"); - return gpio_get_ops(dev)->get_value(dev, offset); + return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset); } /** @@ -205,8 +287,9 @@ int gpio_set_value(unsigned gpio, int value) ret = gpio_to_device(gpio, &dev, &offset); if (ret) return ret; + ret = check_reserved(dev, offset, "set_value"); - return gpio_get_ops(dev)->set_value(dev, offset, value); + return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value); } const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) @@ -221,8 +304,94 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) return priv->bank_name; } +static const char * const gpio_function[GPIOF_COUNT] = { + "input", + "output", + "unused", + "unknown", + "func", +}; + +int get_function(struct udevice *dev, int offset, bool skip_unused, + const char **namep) +{ + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct dm_gpio_ops *ops = gpio_get_ops(dev); + + BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); + if (!device_active(dev)) + return -ENODEV; + if (offset < 0 || offset >= uc_priv->gpio_count) + return -EINVAL; + if (namep) + *namep = uc_priv->name[offset]; + if (skip_unused && !uc_priv->name[offset]) + return GPIOF_UNUSED; + if (ops->get_function) { + int ret; + + ret = ops->get_function(dev, offset); + if (ret < 0) + return ret; + if (ret >= ARRAY_SIZE(gpio_function)) + return -ENODATA; + return ret; + } + + return GPIOF_UNKNOWN; +} + +int gpio_get_function(struct udevice *dev, int offset, const char **namep) +{ + return get_function(dev, offset, true, namep); +} + +int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep) +{ + return get_function(dev, offset, false, namep); +} + +int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) +{ + struct dm_gpio_ops *ops = gpio_get_ops(dev); + struct gpio_dev_priv *priv; + char *str = buf; + int func; + int ret; + int len; + + BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); + + *buf = 0; + priv = dev->uclass_priv; + ret = gpio_get_raw_function(dev, offset, NULL); + if (ret < 0) + return ret; + func = ret; + len = snprintf(str, buffsize, "%s%d: %s", + priv->bank_name ? priv->bank_name : "", + offset, gpio_function[func]); + if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || + func == GPIOF_UNUSED) { + const char *label; + bool used; + + ret = ops->get_value(dev, offset); + if (ret < 0) + return ret; + used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED; + snprintf(str + len, buffsize - len, ": %d [%c]%s%s", + ret, + used ? 'x' : ' ', + used ? " " : "", + label ? label : ""); + } + + return 0; +} + /* We need to renumber the GPIOs when any driver is probed/removed */ -static int gpio_renumber(void) +static int gpio_renumber(struct udevice *removed_dev) { struct gpio_dev_priv *uc_priv; struct udevice *dev; @@ -237,7 +406,7 @@ static int gpio_renumber(void) /* Ensure that we have a base for each bank */ base = 0; uclass_foreach_dev(dev, uc) { - if (device_active(dev)) { + if (device_active(dev) && dev != removed_dev) { uc_priv = dev->uclass_priv; uc_priv->gpio_base = base; base += uc_priv->gpio_count; @@ -249,12 +418,27 @@ static int gpio_renumber(void) static int gpio_post_probe(struct udevice *dev) { - return gpio_renumber(); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + + uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *)); + if (!uc_priv->name) + return -ENOMEM; + + return gpio_renumber(NULL); } static int gpio_pre_remove(struct udevice *dev) { - return gpio_renumber(); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + int i; + + for (i = 0; i < uc_priv->gpio_count; i++) { + if (uc_priv->name[i]) + free(uc_priv->name[i]); + } + free(uc_priv->name); + + return gpio_renumber(dev); } UCLASS_DRIVER(gpio) = { diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c index 7d9fac7..d3381b0 100644 --- a/drivers/gpio/intel_ich6_gpio.c +++ b/drivers/gpio/intel_ich6_gpio.c @@ -27,88 +27,46 @@ */ #include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> #include <pci.h> #include <asm/gpio.h> #include <asm/io.h> +#define GPIO_PER_BANK 32 + /* Where in config space is the register that points to the GPIO registers? */ #define PCI_CFG_GPIOBASE 0x48 -#define NUM_BANKS 3 - -/* Within the I/O space, where are the registers to control the GPIOs? */ -static struct { - u8 use_sel; - u8 io_sel; - u8 lvl; -} gpio_bank[NUM_BANKS] = { - { 0x00, 0x04, 0x0c }, /* Bank 0 */ - { 0x30, 0x34, 0x38 }, /* Bank 1 */ - { 0x40, 0x44, 0x48 } /* Bank 2 */ +struct ich6_bank_priv { + /* These are I/O addresses */ + uint32_t use_sel; + uint32_t io_sel; + uint32_t lvl; }; -static pci_dev_t dev; /* handle for 0:1f:0 */ -static u32 gpiobase; /* offset into I/O space */ -static int found_it_once; /* valid GPIO device? */ -static u32 lock[NUM_BANKS]; /* "lock" for access to pins */ - -static int bad_arg(int num, int *bank, int *bitnum) -{ - int i = num / 32; - int j = num % 32; - - if (num < 0 || i > NUM_BANKS) { - debug("%s: bogus gpio num: %d\n", __func__, num); - return -1; - } - *bank = i; - *bitnum = j; - return 0; -} - -static int mark_gpio(int bank, int bitnum) -{ - if (lock[bank] & (1UL << bitnum)) { - debug("%s: %d.%d already marked\n", __func__, bank, bitnum); - return -1; - } - lock[bank] |= (1 << bitnum); - return 0; -} - -static void clear_gpio(int bank, int bitnum) -{ - lock[bank] &= ~(1 << bitnum); -} - -static int notmine(int num, int *bank, int *bitnum) -{ - if (bad_arg(num, bank, bitnum)) - return -1; - return !(lock[*bank] & (1UL << *bitnum)); -} - -static int gpio_init(void) +static int gpio_ich6_ofdata_to_platdata(struct udevice *dev) { + struct ich6_bank_platdata *plat = dev_get_platdata(dev); + pci_dev_t pci_dev; /* handle for 0:1f:0 */ u8 tmpbyte; u16 tmpword; u32 tmplong; - - /* Have we already done this? */ - if (found_it_once) - return 0; + u32 gpiobase; + int offset; /* Where should it be? */ - dev = PCI_BDF(0, 0x1f, 0); + pci_dev = PCI_BDF(0, 0x1f, 0); /* Is the device present? */ - pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword); + pci_read_config_word(pci_dev, PCI_VENDOR_ID, &tmpword); if (tmpword != PCI_VENDOR_ID_INTEL) { debug("%s: wrong VendorID\n", __func__); - return -1; + return -ENODEV; } - pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword); + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &tmpword); debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword); /* * We'd like to validate the Device ID too, but pretty much any @@ -118,37 +76,37 @@ static int gpio_init(void) */ /* I/O should already be enabled (it's a RO bit). */ - pci_read_config_word(dev, PCI_COMMAND, &tmpword); + pci_read_config_word(pci_dev, PCI_COMMAND, &tmpword); if (!(tmpword & PCI_COMMAND_IO)) { debug("%s: device IO not enabled\n", __func__); - return -1; + return -ENODEV; } /* Header Type must be normal (bits 6-0 only; see spec.) */ - pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_HEADER_TYPE, &tmpbyte); if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) { debug("%s: invalid Header type\n", __func__); - return -1; + return -ENODEV; } /* Base Class must be a bridge device */ - pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_CODE, &tmpbyte); if (tmpbyte != PCI_CLASS_CODE_BRIDGE) { debug("%s: invalid class\n", __func__); - return -1; + return -ENODEV; } /* Sub Class must be ISA */ - pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_SUB_CODE, &tmpbyte); if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) { debug("%s: invalid subclass\n", __func__); - return -1; + return -ENODEV; } /* Programming Interface must be 0x00 (no others exist) */ - pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte); + pci_read_config_byte(pci_dev, PCI_CLASS_PROG, &tmpbyte); if (tmpbyte != 0x00) { debug("%s: invalid interface type\n", __func__); - return -1; + return -ENODEV; } /* @@ -156,11 +114,11 @@ static int gpio_init(void) * that it was unused (or undocumented). Check that it looks * okay: not all ones or zeros, and mapped to I/O space (bit 0). */ - pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong); + pci_read_config_dword(pci_dev, PCI_CFG_GPIOBASE, &tmplong); if (tmplong == 0x00000000 || tmplong == 0xffffffff || !(tmplong & 0x00000001)) { debug("%s: unexpected GPIOBASE value\n", __func__); - return -1; + return -ENODEV; } /* @@ -170,105 +128,137 @@ static int gpio_init(void) * an I/O address, not a memory address, so mask that off. */ gpiobase = tmplong & 0xfffffffe; + offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); + if (offset == -1) { + debug("%s: Invalid register offset %d\n", __func__, offset); + return -EINVAL; + } + plat->base_addr = gpiobase + offset; + plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset, + "bank-name", NULL); - /* Finally. These are the droids we're looking for. */ - found_it_once = 1; return 0; } -int gpio_request(unsigned num, const char *label /* UNUSED */) +int ich6_gpio_probe(struct udevice *dev) { - u32 tmplong; - int i = 0, j = 0; + struct ich6_bank_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct ich6_bank_priv *bank = dev_get_priv(dev); + + uc_priv->gpio_count = GPIO_PER_BANK; + uc_priv->bank_name = plat->bank_name; + bank->use_sel = plat->base_addr; + bank->io_sel = plat->base_addr + 4; + bank->lvl = plat->base_addr + 8; - /* Is the hardware ready? */ - if (gpio_init()) - return -1; + return 0; +} - if (bad_arg(num, &i, &j)) - return -1; +int ich6_gpio_request(struct udevice *dev, unsigned offset, const char *label) +{ + struct ich6_bank_priv *bank = dev_get_priv(dev); + u32 tmplong; /* * Make sure that the GPIO pin we want isn't already in use for some * built-in hardware function. We have to check this for every * requested pin. */ - tmplong = inl(gpiobase + gpio_bank[i].use_sel); - if (!(tmplong & (1UL << j))) { + tmplong = inl(bank->use_sel); + if (!(tmplong & (1UL << offset))) { debug("%s: gpio %d is reserved for internal use\n", __func__, - num); - return -1; + offset); + return -EPERM; } - return mark_gpio(i, j); -} - -int gpio_free(unsigned num) -{ - int i = 0, j = 0; - - if (notmine(num, &i, &j)) - return -1; - - clear_gpio(i, j); return 0; } -int gpio_direction_input(unsigned num) +static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - - if (notmine(num, &i, &j)) - return -1; - tmplong = inl(gpiobase + gpio_bank[i].io_sel); - tmplong |= (1UL << j); - outl(gpiobase + gpio_bank[i].io_sel, tmplong); + tmplong = inl(bank->io_sel); + tmplong |= (1UL << offset); + outl(bank->io_sel, tmplong); return 0; } -int gpio_direction_output(unsigned num, int value) +static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].io_sel); - tmplong &= ~(1UL << j); - outl(gpiobase + gpio_bank[i].io_sel, tmplong); + tmplong = inl(bank->io_sel); + tmplong &= ~(1UL << offset); + outl(bank->io_sel, tmplong); return 0; } -int gpio_get_value(unsigned num) +static int ich6_gpio_get_value(struct udevice *dev, unsigned offset) + { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; int r; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].lvl); - r = (tmplong & (1UL << j)) ? 1 : 0; + tmplong = inl(bank->lvl); + r = (tmplong & (1UL << offset)) ? 1 : 0; return r; } -int gpio_set_value(unsigned num, int value) +static int ich6_gpio_set_value(struct udevice *dev, unsigned offset, + int value) { + struct ich6_bank_priv *bank = dev_get_priv(dev); u32 tmplong; - int i = 0, j = 0; - if (notmine(num, &i, &j)) - return -1; - - tmplong = inl(gpiobase + gpio_bank[i].lvl); + tmplong = inl(bank->lvl); if (value) - tmplong |= (1UL << j); + tmplong |= (1UL << offset); else - tmplong &= ~(1UL << j); - outl(gpiobase + gpio_bank[i].lvl, tmplong); + tmplong &= ~(1UL << offset); + outl(bank->lvl, tmplong); return 0; } + +static int ich6_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct ich6_bank_priv *bank = dev_get_priv(dev); + u32 mask = 1UL << offset; + + if (!(inl(bank->use_sel) & mask)) + return GPIOF_FUNC; + if (inl(bank->io_sel) & mask) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; +} + +static const struct dm_gpio_ops gpio_ich6_ops = { + .request = ich6_gpio_request, + .direction_input = ich6_gpio_direction_input, + .direction_output = ich6_gpio_direction_output, + .get_value = ich6_gpio_get_value, + .set_value = ich6_gpio_set_value, + .get_function = ich6_gpio_get_function, +}; + +static const struct udevice_id intel_ich6_gpio_ids[] = { + { .compatible = "intel,ich6-gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_ich6) = { + .name = "gpio_ich6", + .id = UCLASS_GPIO, + .of_match = intel_ich6_gpio_ids, + .ops = &gpio_ich6_ops, + .ofdata_to_platdata = gpio_ich6_ofdata_to_platdata, + .probe = ich6_gpio_probe, + .priv_auto_alloc_size = sizeof(struct ich6_bank_priv), + .platdata_auto_alloc_size = sizeof(struct ich6_bank_platdata), +}; diff --git a/drivers/gpio/kw_gpio.c b/drivers/gpio/kw_gpio.c index 4fca089..43b27e3 100644 --- a/drivers/gpio/kw_gpio.c +++ b/drivers/gpio/kw_gpio.c @@ -36,7 +36,7 @@ void __set_direction(unsigned pin, int input) u = readl(GPIO_IO_CONF(pin)); } -void __set_level(unsigned pin, int high) +static void __set_level(unsigned pin, int high) { u32 u; @@ -48,7 +48,7 @@ void __set_level(unsigned pin, int high) writel(u, GPIO_OUT(pin)); } -void __set_blinking(unsigned pin, int blink) +static void __set_blinking(unsigned pin, int blink) { u32 u; diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 3f7b7d2..8bb9e39 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -20,7 +20,6 @@ enum mxc_gpio_direction { MXC_GPIO_DIRECTION_OUT, }; -#define GPIO_NAME_SIZE 20 #define GPIO_PER_BANK 32 struct mxc_gpio_plat { @@ -28,7 +27,6 @@ struct mxc_gpio_plat { }; struct mxc_bank_info { - char label[GPIO_PER_BANK][GPIO_NAME_SIZE]; struct gpio_regs *regs; }; @@ -152,18 +150,6 @@ int gpio_direction_output(unsigned gpio, int value) #endif #ifdef CONFIG_DM_GPIO -/** - * gpio_is_requested() - check if a GPIO has been requested - * - * @bank: Bank to check - * @offset: GPIO offset within bank to check - * @return true if marked as requested, false if not - */ -static inline bool gpio_is_requested(struct mxc_bank_info *bank, int offset) -{ - return *bank->label[offset] != '\0'; -} - static int mxc_gpio_is_output(struct gpio_regs *regs, int offset) { u32 val; @@ -208,35 +194,10 @@ static int mxc_gpio_bank_get_value(struct gpio_regs *regs, int offset) return (readl(®s->gpio_psr) >> offset) & 0x01; } -static int mxc_gpio_bank_get_output_value(struct gpio_regs *regs, int offset) -{ - return (readl(®s->gpio_dr) >> offset) & 0x01; -} - -static int check_requested(struct udevice *dev, unsigned offset, - const char *func) -{ - struct mxc_bank_info *bank = dev_get_priv(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - - if (!gpio_is_requested(bank, offset)) { - printf("mxc_gpio: %s: error: gpio %s%d not requested\n", - func, uc_priv->bank_name, offset); - return -EPERM; - } - - return 0; -} - /* set GPIO pin 'gpio' as an input */ static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset) { struct mxc_bank_info *bank = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO direction as input. */ mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_IN); @@ -249,11 +210,6 @@ static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset, int value) { struct mxc_bank_info *bank = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO output value. */ mxc_gpio_bank_set_value(bank->regs, offset, value); @@ -268,11 +224,6 @@ static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset, static int mxc_gpio_get_value(struct udevice *dev, unsigned offset) { struct mxc_bank_info *bank = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; return mxc_gpio_bank_get_value(bank->regs, offset); } @@ -282,80 +233,16 @@ static int mxc_gpio_set_value(struct udevice *dev, unsigned offset, int value) { struct mxc_bank_info *bank = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; mxc_gpio_bank_set_value(bank->regs, offset, value); return 0; } -static int mxc_gpio_get_state(struct udevice *dev, unsigned int offset, - char *buf, int bufsize) -{ - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct mxc_bank_info *bank = dev_get_priv(dev); - const char *label; - bool requested; - bool is_output; - int size; - - label = bank->label[offset]; - is_output = mxc_gpio_is_output(bank->regs, offset); - size = snprintf(buf, bufsize, "%s%d: ", - uc_priv->bank_name ? uc_priv->bank_name : "", offset); - buf += size; - bufsize -= size; - requested = gpio_is_requested(bank, offset); - snprintf(buf, bufsize, "%s: %d [%c]%s%s", - is_output ? "out" : " in", - is_output ? - mxc_gpio_bank_get_output_value(bank->regs, offset) : - mxc_gpio_bank_get_value(bank->regs, offset), - requested ? 'x' : ' ', - requested ? " " : "", - label); - - return 0; -} - -static int mxc_gpio_request(struct udevice *dev, unsigned offset, - const char *label) -{ - struct mxc_bank_info *bank = dev_get_priv(dev); - - if (gpio_is_requested(bank, offset)) - return -EBUSY; - - strncpy(bank->label[offset], label, GPIO_NAME_SIZE); - bank->label[offset][GPIO_NAME_SIZE - 1] = '\0'; - - return 0; -} - -static int mxc_gpio_free(struct udevice *dev, unsigned offset) -{ - struct mxc_bank_info *bank = dev_get_priv(dev); - int ret; - - ret = check_requested(dev, offset, __func__); - if (ret) - return ret; - bank->label[offset][0] = '\0'; - - return 0; -} - static int mxc_gpio_get_function(struct udevice *dev, unsigned offset) { struct mxc_bank_info *bank = dev_get_priv(dev); - if (!gpio_is_requested(bank, offset)) - return GPIOF_UNUSED; - /* GPIOF_FUNC is not implemented yet */ if (mxc_gpio_is_output(bank->regs, offset)) return GPIOF_OUTPUT; @@ -364,14 +251,11 @@ static int mxc_gpio_get_function(struct udevice *dev, unsigned offset) } static const struct dm_gpio_ops gpio_mxc_ops = { - .request = mxc_gpio_request, - .free = mxc_gpio_free, .direction_input = mxc_gpio_direction_input, .direction_output = mxc_gpio_direction_output, .get_value = mxc_gpio_get_value, .set_value = mxc_gpio_set_value, .get_function = mxc_gpio_get_function, - .get_state = mxc_gpio_get_state, }; static const struct mxc_gpio_plat mxc_plat[] = { diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index 13dcf79..f3a7ccb 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -19,6 +19,7 @@ * Written by Juha Yrjölä <juha.yrjola@nokia.com> */ #include <common.h> +#include <dm.h> #include <asm/gpio.h> #include <asm/io.h> #include <asm/errno.h> @@ -26,10 +27,17 @@ #define OMAP_GPIO_DIR_OUT 0 #define OMAP_GPIO_DIR_IN 1 -static inline const struct gpio_bank *get_gpio_bank(int gpio) -{ - return &omap_gpio_bank[gpio >> 5]; -} +#ifdef CONFIG_DM_GPIO + +#define GPIO_PER_BANK 32 + +struct gpio_bank { + /* TODO(sjg@chromium.org): Can we use a struct here? */ + void *base; /* address of registers in physical memory */ + enum gpio_method method; +}; + +#endif static inline int get_gpio_index(int gpio) { @@ -41,15 +49,6 @@ int gpio_is_valid(int gpio) return (gpio >= 0) && (gpio < OMAP_MAX_GPIO); } -static int check_gpio(int gpio) -{ - if (!gpio_is_valid(gpio)) { - printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); - return -1; - } - return 0; -} - static void _set_gpio_direction(const struct gpio_bank *bank, int gpio, int is_input) { @@ -118,6 +117,48 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio, __raw_writel(l, reg); } +static int _get_gpio_value(const struct gpio_bank *bank, int gpio) +{ + void *reg = bank->base; + int input; + + switch (bank->method) { + case METHOD_GPIO_24XX: + input = _get_gpio_direction(bank, gpio); + switch (input) { + case OMAP_GPIO_DIR_IN: + reg += OMAP_GPIO_DATAIN; + break; + case OMAP_GPIO_DIR_OUT: + reg += OMAP_GPIO_DATAOUT; + break; + default: + return -1; + } + break; + default: + return -1; + } + + return (__raw_readl(reg) & (1 << gpio)) != 0; +} + +#ifndef CONFIG_DM_GPIO + +static inline const struct gpio_bank *get_gpio_bank(int gpio) +{ + return &omap_gpio_bank[gpio >> 5]; +} + +static int check_gpio(int gpio) +{ + if (!gpio_is_valid(gpio)) { + printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); + return -1; + } + return 0; +} + /** * Set value of the specified gpio */ @@ -139,32 +180,12 @@ int gpio_set_value(unsigned gpio, int value) int gpio_get_value(unsigned gpio) { const struct gpio_bank *bank; - void *reg; - int input; if (check_gpio(gpio) < 0) return -1; bank = get_gpio_bank(gpio); - reg = bank->base; - switch (bank->method) { - case METHOD_GPIO_24XX: - input = _get_gpio_direction(bank, get_gpio_index(gpio)); - switch (input) { - case OMAP_GPIO_DIR_IN: - reg += OMAP_GPIO_DATAIN; - break; - case OMAP_GPIO_DIR_OUT: - reg += OMAP_GPIO_DATAOUT; - break; - default: - return -1; - } - break; - default: - return -1; - } - return (__raw_readl(reg) - & (1 << get_gpio_index(gpio))) != 0; + + return _get_gpio_value(bank, get_gpio_index(gpio)); } /** @@ -220,3 +241,95 @@ int gpio_free(unsigned gpio) { return 0; } + +#else /* new driver model interface CONFIG_DM_GPIO */ + +/* set GPIO pin 'gpio' as an input */ +static int omap_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct gpio_bank *bank = dev_get_priv(dev); + + /* Configure GPIO direction as input. */ + _set_gpio_direction(bank, offset, 1); + + return 0; +} + +/* set GPIO pin 'gpio' as an output, with polarity 'value' */ +static int omap_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct gpio_bank *bank = dev_get_priv(dev); + + _set_gpio_dataout(bank, offset, value); + _set_gpio_direction(bank, offset, 0); + + return 0; +} + +/* read GPIO IN value of pin 'gpio' */ +static int omap_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct gpio_bank *bank = dev_get_priv(dev); + + return _get_gpio_value(bank, offset); +} + +/* write GPIO OUT value to pin 'gpio' */ +static int omap_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct gpio_bank *bank = dev_get_priv(dev); + + _set_gpio_dataout(bank, offset, value); + + return 0; +} + +static int omap_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct gpio_bank *bank = dev_get_priv(dev); + + /* GPIOF_FUNC is not implemented yet */ + if (_get_gpio_direction(bank->base, offset) == OMAP_GPIO_DIR_OUT) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + +static const struct dm_gpio_ops gpio_omap_ops = { + .direction_input = omap_gpio_direction_input, + .direction_output = omap_gpio_direction_output, + .get_value = omap_gpio_get_value, + .set_value = omap_gpio_set_value, + .get_function = omap_gpio_get_function, +}; + +static int omap_gpio_probe(struct udevice *dev) +{ + struct gpio_bank *bank = dev_get_priv(dev); + struct omap_gpio_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + char name[18], *str; + + sprintf(name, "GPIO%d_", plat->bank_index); + str = strdup(name); + if (!str) + return -ENOMEM; + uc_priv->bank_name = str; + uc_priv->gpio_count = GPIO_PER_BANK; + bank->base = (void *)plat->base; + bank->method = plat->method; + + return 0; +} + +U_BOOT_DRIVER(gpio_omap) = { + .name = "gpio_omap", + .id = UCLASS_GPIO, + .ops = &gpio_omap_ops, + .probe = omap_gpio_probe, + .priv_auto_alloc_size = sizeof(struct gpio_bank), +}; + +#endif /* CONFIG_DM_GPIO */ diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 13d74eb..6c41a42 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -33,8 +33,6 @@ DECLARE_GLOBAL_DATA_PTR; #define RATE_MASK(gpio) (0x1 << (gpio + 16)) #define RATE_SET(gpio) (0x1 << (gpio + 16)) -#define GPIO_NAME_SIZE 20 - /* Platform data for each bank */ struct exynos_gpio_platdata { struct s5p_gpio_bank *bank; @@ -43,7 +41,6 @@ struct exynos_gpio_platdata { /* Information about each bank at run-time */ struct exynos_bank_info { - char label[GPIO_PER_BANK][GPIO_NAME_SIZE]; struct s5p_gpio_bank *bank; }; @@ -189,61 +186,10 @@ int s5p_gpio_get_pin(unsigned gpio) /* Driver model interface */ #ifndef CONFIG_SPL_BUILD -static int exynos_gpio_get_state(struct udevice *dev, unsigned int offset, - char *buf, int bufsize) -{ - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct exynos_bank_info *state = dev_get_priv(dev); - const char *label; - bool is_output; - int size; - int cfg; - - label = state->label[offset]; - cfg = s5p_gpio_get_cfg_pin(state->bank, offset); - is_output = cfg == S5P_GPIO_OUTPUT; - size = snprintf(buf, bufsize, "%s%d: ", - uc_priv->bank_name ? uc_priv->bank_name : "", offset); - buf += size; - bufsize -= size; - if (is_output || cfg == S5P_GPIO_INPUT) { - snprintf(buf, bufsize, "%s: %d [%c]%s%s", - is_output ? "out" : " in", - s5p_gpio_get_value(state->bank, offset), - *label ? 'x' : ' ', - *label ? " " : "", - label); - } else { - snprintf(buf, bufsize, "sfpio"); - } - - return 0; -} - -static int check_reserved(struct udevice *dev, unsigned offset, - const char *func) -{ - struct exynos_bank_info *state = dev_get_priv(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - - if (!*state->label[offset]) { - printf("exynos_gpio: %s: error: gpio %s%d not reserved\n", - func, uc_priv->bank_name, offset); - return -EPERM; - } - - return 0; -} - /* set GPIO pin 'gpio' as an input */ static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset) { struct exynos_bank_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO direction as input. */ s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_INPUT); @@ -256,11 +202,6 @@ static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset, int value) { struct exynos_bank_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO output value. */ s5p_gpio_set_value(state->bank, offset, value); @@ -275,11 +216,6 @@ static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset, static int exynos_gpio_get_value(struct udevice *dev, unsigned offset) { struct exynos_bank_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; return s5p_gpio_get_value(state->bank, offset); } @@ -289,43 +225,11 @@ static int exynos_gpio_set_value(struct udevice *dev, unsigned offset, int value) { struct exynos_bank_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; s5p_gpio_set_value(state->bank, offset, value); return 0; } - -static int exynos_gpio_request(struct udevice *dev, unsigned offset, - const char *label) -{ - struct exynos_bank_info *state = dev_get_priv(dev); - - if (*state->label[offset]) - return -EBUSY; - - strncpy(state->label[offset], label, GPIO_NAME_SIZE); - state->label[offset][GPIO_NAME_SIZE - 1] = '\0'; - - return 0; -} - -static int exynos_gpio_free(struct udevice *dev, unsigned offset) -{ - struct exynos_bank_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; - state->label[offset][0] = '\0'; - - return 0; -} #endif /* nCONFIG_SPL_BUILD */ /* @@ -362,8 +266,6 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset) struct exynos_bank_info *state = dev_get_priv(dev); int cfg; - if (!*state->label[offset]) - return GPIOF_UNUSED; cfg = s5p_gpio_get_cfg_pin(state->bank, offset); if (cfg == S5P_GPIO_OUTPUT) return GPIOF_OUTPUT; @@ -374,14 +276,11 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset) } static const struct dm_gpio_ops gpio_exynos_ops = { - .request = exynos_gpio_request, - .free = exynos_gpio_free, .direction_input = exynos_gpio_direction_input, .direction_output = exynos_gpio_direction_output, .get_value = exynos_gpio_get_value, .set_value = exynos_gpio_set_value, .get_function = exynos_gpio_get_function, - .get_state = exynos_gpio_get_state, }; static int gpio_exynos_probe(struct udevice *dev) diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index 75ada5d..53c80d5 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -14,7 +14,6 @@ DECLARE_GLOBAL_DATA_PTR; /* Flags for each GPIO */ #define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */ #define GPIOF_HIGH (1 << 1) /* Currently set high */ -#define GPIOF_RESERVED (1 << 2) /* Is in use / requested */ struct gpio_state { const char *label; /* label given by requester */ @@ -54,18 +53,6 @@ static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag, return 0; } -static int check_reserved(struct udevice *dev, unsigned offset, - const char *func) -{ - if (!get_gpio_flag(dev, offset, GPIOF_RESERVED)) { - printf("sandbox_gpio: %s: error: offset %u not reserved\n", - func, offset); - return -1; - } - - return 0; -} - /* * Back-channel sandbox-internal-only access to GPIO state */ @@ -101,9 +88,6 @@ static int sb_gpio_direction_input(struct udevice *dev, unsigned offset) { debug("%s: offset:%u\n", __func__, offset); - if (check_reserved(dev, offset, __func__)) - return -1; - return sandbox_gpio_set_direction(dev, offset, 0); } @@ -113,9 +97,6 @@ static int sb_gpio_direction_output(struct udevice *dev, unsigned offset, { debug("%s: offset:%u, value = %d\n", __func__, offset, value); - if (check_reserved(dev, offset, __func__)) - return -1; - return sandbox_gpio_set_direction(dev, offset, 1) | sandbox_gpio_set_value(dev, offset, value); } @@ -125,9 +106,6 @@ static int sb_gpio_get_value(struct udevice *dev, unsigned offset) { debug("%s: offset:%u\n", __func__, offset); - if (check_reserved(dev, offset, __func__)) - return -1; - return sandbox_gpio_get_value(dev, offset); } @@ -136,9 +114,6 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) { debug("%s: offset:%u, value = %d\n", __func__, offset, value); - if (check_reserved(dev, offset, __func__)) - return -1; - if (!sandbox_gpio_get_direction(dev, offset)) { printf("sandbox_gpio: error: set_value on input gpio %u\n", offset); @@ -148,69 +123,19 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value) return sandbox_gpio_set_value(dev, offset, value); } -static int sb_gpio_request(struct udevice *dev, unsigned offset, - const char *label) +static int sb_gpio_get_function(struct udevice *dev, unsigned offset) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct gpio_state *state = dev_get_priv(dev); - - debug("%s: offset:%u, label:%s\n", __func__, offset, label); - - if (offset >= uc_priv->gpio_count) { - printf("sandbox_gpio: error: invalid gpio %u\n", offset); - return -1; - } - - if (get_gpio_flag(dev, offset, GPIOF_RESERVED)) { - printf("sandbox_gpio: error: gpio %u already reserved\n", - offset); - return -1; - } - - state[offset].label = label; - return set_gpio_flag(dev, offset, GPIOF_RESERVED, 1); -} - -static int sb_gpio_free(struct udevice *dev, unsigned offset) -{ - struct gpio_state *state = dev_get_priv(dev); - - debug("%s: offset:%u\n", __func__, offset); - - if (check_reserved(dev, offset, __func__)) - return -1; - - state[offset].label = NULL; - return set_gpio_flag(dev, offset, GPIOF_RESERVED, 0); -} - -static int sb_gpio_get_state(struct udevice *dev, unsigned int offset, - char *buf, int bufsize) -{ - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct gpio_state *state = dev_get_priv(dev); - const char *label; - - label = state[offset].label; - snprintf(buf, bufsize, "%s%d: %s: %d [%c]%s%s", - uc_priv->bank_name ? uc_priv->bank_name : "", offset, - sandbox_gpio_get_direction(dev, offset) ? "out" : " in", - sandbox_gpio_get_value(dev, offset), - get_gpio_flag(dev, offset, GPIOF_RESERVED) ? 'x' : ' ', - label ? " " : "", - label ? label : ""); - - return 0; + if (get_gpio_flag(dev, offset, GPIOF_OUTPUT)) + return GPIOF_OUTPUT; + return GPIOF_INPUT; } static const struct dm_gpio_ops gpio_sandbox_ops = { - .request = sb_gpio_request, - .free = sb_gpio_free, .direction_input = sb_gpio_direction_input, .direction_output = sb_gpio_direction_output, .get_value = sb_gpio_get_value, .set_value = sb_gpio_set_value, - .get_state = sb_gpio_get_state, + .get_function = sb_gpio_get_function, }; static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) @@ -239,6 +164,13 @@ static int gpio_sandbox_probe(struct udevice *dev) return 0; } +static int gpio_sandbox_remove(struct udevice *dev) +{ + free(dev->priv); + + return 0; +} + static const struct udevice_id sandbox_gpio_ids[] = { { .compatible = "sandbox,gpio" }, { } @@ -250,5 +182,6 @@ U_BOOT_DRIVER(gpio_sandbox) = { .of_match = sandbox_gpio_ids, .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata, .probe = gpio_sandbox_probe, + .remove = gpio_sandbox_remove, .ops = &gpio_sandbox_ops, }; diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 70663fc..88f7ef5 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -39,7 +39,6 @@ struct tegra_gpio_platdata { /* Information about each port at run-time */ struct tegra_port_info { - char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE]; struct gpio_ctlr_bank *bank; int base_gpio; /* Port number for this port (0, 1,.., n-1) */ }; @@ -132,21 +131,6 @@ static void set_level(unsigned gpio, int high) writel(u, &bank->gpio_out[GPIO_PORT(gpio)]); } -static int check_reserved(struct udevice *dev, unsigned offset, - const char *func) -{ - struct tegra_port_info *state = dev_get_priv(dev); - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - - if (!*state->label[offset]) { - printf("tegra_gpio: %s: error: gpio %s%d not reserved\n", - func, uc_priv->bank_name, offset); - return -EBUSY; - } - - return 0; -} - /* set GPIO pin 'gpio' as an output, with polarity 'value' */ int tegra_spl_gpio_direction_output(int gpio, int value) { @@ -171,59 +155,16 @@ static int tegra_gpio_request(struct udevice *dev, unsigned offset, { struct tegra_port_info *state = dev_get_priv(dev); - if (!label) - return -EINVAL; - - if (*state->label[offset]) - return -EBUSY; - - strncpy(state->label[offset], label, GPIO_NAME_SIZE); - state->label[offset][GPIO_NAME_SIZE - 1] = '\0'; - /* Configure as a GPIO */ set_config(state->base_gpio + offset, 1); return 0; } -static int tegra_gpio_free(struct udevice *dev, unsigned offset) -{ - struct tegra_port_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; - state->label[offset][0] = '\0'; - - return 0; -} - -/* read GPIO OUT value of pin 'gpio' */ -static int tegra_gpio_get_output_value(unsigned gpio) -{ - struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)]; - int val; - - debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n", - gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); - - val = readl(&bank->gpio_out[GPIO_PORT(gpio)]); - - return (val >> GPIO_BIT(gpio)) & 1; -} - - /* set GPIO pin 'gpio' as an input */ static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset) { struct tegra_port_info *state = dev_get_priv(dev); - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO direction as input. */ set_direction(state->base_gpio + offset, 0); @@ -237,11 +178,6 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset, { struct tegra_port_info *state = dev_get_priv(dev); int gpio = state->base_gpio + offset; - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; /* Configure GPIO output value. */ set_level(gpio, value); @@ -257,13 +193,8 @@ static int tegra_gpio_get_value(struct udevice *dev, unsigned offset) { struct tegra_port_info *state = dev_get_priv(dev); int gpio = state->base_gpio + offset; - int ret; int val; - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; - debug("%s: pin = %d (port %d:bit %d)\n", __func__, gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio)); @@ -277,11 +208,6 @@ static int tegra_gpio_set_value(struct udevice *dev, unsigned offset, int value) { struct tegra_port_info *state = dev_get_priv(dev); int gpio = state->base_gpio + offset; - int ret; - - ret = check_reserved(dev, offset, __func__); - if (ret) - return ret; debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n", gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value); @@ -317,8 +243,6 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset) struct tegra_port_info *state = dev_get_priv(dev); int gpio = state->base_gpio + offset; - if (!*state->label[offset]) - return GPIOF_UNUSED; if (!get_config(gpio)) return GPIOF_FUNC; else if (get_direction(gpio)) @@ -327,50 +251,13 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_INPUT; } -static int tegra_gpio_get_state(struct udevice *dev, unsigned int offset, - char *buf, int bufsize) -{ - struct gpio_dev_priv *uc_priv = dev->uclass_priv; - struct tegra_port_info *state = dev_get_priv(dev); - int gpio = state->base_gpio + offset; - const char *label; - int is_output; - int is_gpio; - int size; - - label = state->label[offset]; - is_gpio = get_config(gpio); /* GPIO, not SFPIO */ - size = snprintf(buf, bufsize, "%s%d: ", - uc_priv->bank_name ? uc_priv->bank_name : "", offset); - buf += size; - bufsize -= size; - if (is_gpio) { - is_output = get_direction(gpio); - - snprintf(buf, bufsize, "%s: %d [%c]%s%s", - is_output ? "out" : " in", - is_output ? - tegra_gpio_get_output_value(gpio) : - tegra_gpio_get_value(dev, offset), - *label ? 'x' : ' ', - *label ? " " : "", - label); - } else { - snprintf(buf, bufsize, "sfpio"); - } - - return 0; -} - static const struct dm_gpio_ops gpio_tegra_ops = { .request = tegra_gpio_request, - .free = tegra_gpio_free, .direction_input = tegra_gpio_direction_input, .direction_output = tegra_gpio_direction_output, .get_value = tegra_gpio_get_value, .set_value = tegra_gpio_set_value, .get_function = tegra_gpio_get_function, - .get_state = tegra_gpio_get_state, }; /** diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index c891ebd..e085a70 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -8,6 +8,7 @@ #include <common.h> #include <asm/io.h> #include "designware_i2c.h" +#include <i2c.h> #ifdef CONFIG_I2C_MULTI_BUS static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX]; @@ -76,16 +77,20 @@ static void set_speed(int i2c_spd) * * Set the i2c speed. */ -int i2c_set_bus_speed(int speed) +int i2c_set_bus_speed(unsigned int speed) { + int i2c_spd; + if (speed >= I2C_MAX_SPEED) - set_speed(IC_SPEED_MODE_MAX); + i2c_spd = IC_SPEED_MODE_MAX; else if (speed >= I2C_FAST_SPEED) - set_speed(IC_SPEED_MODE_FAST); + i2c_spd = IC_SPEED_MODE_FAST; else - set_speed(IC_SPEED_MODE_STANDARD); + i2c_spd = IC_SPEED_MODE_STANDARD; - return 0; + set_speed(i2c_spd); + + return i2c_spd; } /* @@ -93,7 +98,7 @@ int i2c_set_bus_speed(int speed) * * Gets the i2c speed. */ -int i2c_get_bus_speed(void) +unsigned int i2c_get_bus_speed(void) { u32 cntl; @@ -429,7 +434,7 @@ int i2c_set_bus_num(unsigned int bus) return 0; } -int i2c_get_bus_num(void) +unsigned int i2c_get_bus_num(void) { return current_bus; } diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index 257b72f..562211e 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -471,8 +471,8 @@ static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) } /* i2c write version without the register address */ -int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len, - bool end_with_repeated_start) +static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, + int len, bool end_with_repeated_start) { int rc; @@ -493,7 +493,8 @@ int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len, } /* i2c read version without the register address */ -int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len) +static int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, + int len) { int rc; diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index 7e36db0..0ef94f7 100644 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -181,7 +181,7 @@ static void kbd_wait_for_fifo_init(struct keyb *config) * @param input Input configuration * @return 1, to indicate that we have something to look at */ -int tegra_kbc_check(struct input_config *input) +static int tegra_kbc_check(struct input_config *input) { kbd_wait_for_fifo_init(&config); check_for_keys(&config); diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c index 82079d6..92f7d89 100644 --- a/drivers/mmc/bcm2835_sdhci.c +++ b/drivers/mmc/bcm2835_sdhci.c @@ -40,6 +40,7 @@ #include <malloc.h> #include <sdhci.h> #include <asm/arch/timer.h> +#include <asm/arch-bcm2835/sdhci.h> /* 400KHz is max freq for card ID etc. Use that as min */ #define MIN_FREQ 400000 diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 5b0c302..ef2cbf9 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -67,14 +67,19 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, #ifdef OMAP_HSMMC_USE_GPIO static int omap_mmc_setup_gpio_in(int gpio, const char *label) { - if (!gpio_is_valid(gpio)) - return -1; + int ret; - if (gpio_request(gpio, label) < 0) +#ifndef CONFIG_DM_GPIO + if (!gpio_is_valid(gpio)) return -1; +#endif + ret = gpio_request(gpio, label); + if (ret) + return ret; - if (gpio_direction_input(gpio) < 0) - return -1; + ret = gpio_direction_input(gpio); + if (ret) + return ret; return gpio; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 3125d13..de88e19 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -124,7 +124,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, #endif #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT 100 -int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, +static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct sdhci_host *host = mmc->priv; @@ -355,7 +355,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); } -void sdhci_set_ios(struct mmc *mmc) +static void sdhci_set_ios(struct mmc *mmc) { u32 ctrl; struct sdhci_host *host = mmc->priv; @@ -393,7 +393,7 @@ void sdhci_set_ios(struct mmc *mmc) sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } -int sdhci_init(struct mmc *mmc) +static int sdhci_init(struct mmc *mmc) { struct sdhci_host *host = mmc->priv; diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 2642fe2..2bd36b0 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -13,6 +13,7 @@ #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/mmc.h> #include <asm/arch-tegra/tegra_mmc.h> #include <mmc.h> @@ -508,7 +509,7 @@ static int tegra_mmc_core_init(struct mmc *mmc) return 0; } -int tegra_mmc_getcd(struct mmc *mmc) +static int tegra_mmc_getcd(struct mmc *mmc) { struct mmc_host *host = mmc->priv; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 9b3175d..50983b8 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -63,6 +63,12 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS]; /* FLASH chips info */ #define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_8BIT #endif +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS +#define __maybe_weak __weak +#else +#define __maybe_weak static +#endif + /* * 0xffff is an undefined value for the configuration register. When * this value is returned, the configuration register shall not be @@ -81,14 +87,12 @@ static u16 cfi_flash_config_reg(int i) int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT; #endif -static phys_addr_t __cfi_flash_bank_addr(int i) +__weak phys_addr_t cfi_flash_bank_addr(int i) { return ((phys_addr_t [])CONFIG_SYS_FLASH_BANKS_LIST)[i]; } -phys_addr_t cfi_flash_bank_addr(int i) - __attribute__((weak, alias("__cfi_flash_bank_addr"))); -static unsigned long __cfi_flash_bank_size(int i) +__weak unsigned long cfi_flash_bank_size(int i) { #ifdef CONFIG_SYS_FLASH_BANKS_SIZES return ((unsigned long [])CONFIG_SYS_FLASH_BANKS_SIZES)[i]; @@ -96,71 +100,49 @@ static unsigned long __cfi_flash_bank_size(int i) return 0; #endif } -unsigned long cfi_flash_bank_size(int i) - __attribute__((weak, alias("__cfi_flash_bank_size"))); -static void __flash_write8(u8 value, void *addr) +__maybe_weak void flash_write8(u8 value, void *addr) { __raw_writeb(value, addr); } -static void __flash_write16(u16 value, void *addr) +__maybe_weak void flash_write16(u16 value, void *addr) { __raw_writew(value, addr); } -static void __flash_write32(u32 value, void *addr) +__maybe_weak void flash_write32(u32 value, void *addr) { __raw_writel(value, addr); } -static void __flash_write64(u64 value, void *addr) +__maybe_weak void flash_write64(u64 value, void *addr) { /* No architectures currently implement __raw_writeq() */ *(volatile u64 *)addr = value; } -static u8 __flash_read8(void *addr) +__maybe_weak u8 flash_read8(void *addr) { return __raw_readb(addr); } -static u16 __flash_read16(void *addr) +__maybe_weak u16 flash_read16(void *addr) { return __raw_readw(addr); } -static u32 __flash_read32(void *addr) +__maybe_weak u32 flash_read32(void *addr) { return __raw_readl(addr); } -static u64 __flash_read64(void *addr) +__maybe_weak u64 flash_read64(void *addr) { /* No architectures currently implement __raw_readq() */ return *(volatile u64 *)addr; } -#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS -void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8"))); -void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16"))); -void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32"))); -void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64"))); -u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8"))); -u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16"))); -u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32"))); -u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64"))); -#else -#define flash_write8 __flash_write8 -#define flash_write16 __flash_write16 -#define flash_write32 __flash_write32 -#define flash_write64 __flash_write64 -#define flash_read8 __flash_read8 -#define flash_read16 __flash_read16 -#define flash_read32 __flash_read32 -#define flash_read64 __flash_read64 -#endif - /*----------------------------------------------------------------------- */ #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index db1599e..40d6705 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -75,7 +75,7 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd, #ifdef CONFIG_SPL_BUILD /* Check wait pin as dev ready indicator */ -int omap_spl_dev_ready(struct mtd_info *mtd) +static int omap_spl_dev_ready(struct mtd_info *mtd) { return gpmc_cfg->status & (1 << 8); } @@ -162,23 +162,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat, } /* - * omap_reverse_list - re-orders list elements in reverse order [internal] - * @list: pointer to start of list - * @length: length of list -*/ -void omap_reverse_list(u8 *list, unsigned int length) -{ - unsigned int i, j; - unsigned int half_length = length / 2; - u8 tmp; - for (i = 0, j = length - 1; i < half_length; i++, j--) { - tmp = list[i]; - list[i] = list[j]; - list[j] = tmp; - } -} - -/* * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write * @mtd: MTD device structure * @mode: Read/Write mode @@ -351,6 +334,23 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, #ifdef CONFIG_NAND_OMAP_ELM /* + * omap_reverse_list - re-orders list elements in reverse order [internal] + * @list: pointer to start of list + * @length: length of list +*/ +static void omap_reverse_list(u8 *list, unsigned int length) +{ + unsigned int i, j; + unsigned int half_length = length / 2; + u8 tmp; + for (i = 0, j = length - 1; i < half_length; i++, j--) { + tmp = list[i]; + list[i] = list[j]; + list[j] = tmp; + } +} + +/* * omap_correct_data_bch - Compares the ecc read from nand spare area * with ECC registers values and corrects one bit error if it has occured * diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 439f8ae..08bc1af 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -27,6 +27,7 @@ #include <net.h> #include <miiphy.h> #include <malloc.h> +#include <netdev.h> #include <linux/compiler.h> #include <asm/arch/emac_defs.h> #include <asm/io.h> diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 549d648..b572470 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -11,6 +11,7 @@ #include <common.h> #include <malloc.h> #include <net.h> +#include <netdev.h> #include <miiphy.h> #include "fec_mxc.h" @@ -179,13 +180,14 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr, return 0; } -int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr) +static int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, + int regAddr) { return fec_mdio_read(bus->priv, phyAddr, regAddr); } -int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr, - u16 data) +static int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, + int regAddr, u16 data) { return fec_mdio_write(bus->priv, phyAddr, regAddr, data); } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 1d6c14f..f1ace3c 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -575,7 +575,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, * Description: Reads the ID registers of the PHY at @addr on the * @bus, stores it in @phy_id and returns zero on success. */ -int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) +static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) { int phy_reg; @@ -785,16 +785,13 @@ int phy_startup(struct phy_device *phydev) return 0; } -static int __board_phy_config(struct phy_device *phydev) +__weak int board_phy_config(struct phy_device *phydev) { if (phydev->drv->config) return phydev->drv->config(phydev); return 0; } -int board_phy_config(struct phy_device *phydev) - __attribute__((weak, alias("__board_phy_config"))); - int phy_config(struct phy_device *phydev) { /* Invoke an optional board-specific helper */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 28859f3..60c333e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -572,7 +572,7 @@ const char * pci_class_str(u8 class) } #endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */ -int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) { /* * Check if pci device should be skipped in configuration @@ -591,19 +591,15 @@ int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) return 0; } -int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) - __attribute__((weak, alias("__pci_skip_dev"))); #ifdef CONFIG_PCI_SCAN_SHOW -int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev) +__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) { if (dev == PCI_BDF(hose->first_busno, 0, 0)) return 0; return 1; } -int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) - __attribute__((weak, alias("__pci_print_dev"))); #endif /* CONFIG_PCI_SCAN_SHOW */ int pci_hose_scan_bus(struct pci_controller *hose, int bus) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e69de29..a0b6e02 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -0,0 +1,12 @@ +config DM_SERIAL + bool "Enable Driver Model for serial drivers" + depends on DM + help + If you want to use driver model for serial drivers, say Y. + To use legacy serial drivers, say N. + +config UNIPHIER_SERIAL + bool "UniPhier on-chip UART support" + depends on ARCH_UNIPHIER && DM_SERIAL + help + Support for the on-chip UARTs on the Panasonic UniPhier platform. diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 17c56ea..2c19ebc 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -41,6 +41,8 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o +obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o +obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_USB_TTY) += usbtty.o diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 63a9ef6..8f05191 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -61,13 +61,13 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) unsigned char *addr; offset *= 1 << plat->reg_shift; - addr = plat->base + offset; + addr = map_sysmem(plat->base, 0) + offset; /* * As far as we know it doesn't make sense to support selection of * these options at run-time, so use the existing CONFIG options. */ #ifdef CONFIG_SYS_NS16550_PORT_MAPPED - outb(value, addr); + outb(value, (ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) out_le32(addr, value); #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) @@ -85,9 +85,9 @@ static int ns16550_readb(NS16550_t port, int offset) unsigned char *addr; offset *= 1 << plat->reg_shift; - addr = plat->base + offset; + addr = map_sysmem(plat->base, 0) + offset; #ifdef CONFIG_SYS_NS16550_PORT_MAPPED - return inb(addr); + return inb((ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) return in_le32(addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) @@ -253,7 +253,7 @@ static int ns16550_serial_getc(struct udevice *dev) { struct NS16550 *const com_port = dev_get_priv(dev); - if (!serial_in(&com_port->lsr) & UART_LSR_DR) + if (!(serial_in(&com_port->lsr) & UART_LSR_DR)) return -EAGAIN; return serial_in(&com_port->rbr); @@ -276,14 +276,15 @@ int ns16550_serial_probe(struct udevice *dev) { struct NS16550 *const com_port = dev_get_priv(dev); + com_port->plat = dev_get_platdata(dev); NS16550_init(com_port, -1); return 0; } +#ifdef CONFIG_OF_CONTROL int ns16550_serial_ofdata_to_platdata(struct udevice *dev) { - struct NS16550 *const com_port = dev_get_priv(dev); struct ns16550_platdata *plat = dev->platdata; fdt_addr_t addr; @@ -291,13 +292,13 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) if (addr == FDT_ADDR_T_NONE) return -EINVAL; - plat->base = (unsigned char *)addr; + plat->base = addr; plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg-shift", 1); - com_port->plat = plat; return 0; } +#endif const struct dm_serial_ops ns16550_serial_ops = { .putc = ns16550_serial_putc, diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1a75950..71f1a5c 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -11,9 +11,12 @@ #include <os.h> #include <serial.h> #include <stdio_dev.h> +#include <watchdog.h> #include <dm/lists.h> #include <dm/device-internal.h> +#include <ns16550.h> + DECLARE_GLOBAL_DATA_PTR; /* The currently-selected console serial device */ @@ -47,13 +50,22 @@ static void serial_find_console_or_panic(void) } #endif /* + * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!). + * * Failing that, get the device with sequence number 0, or in extremis * just the first serial device we can find. But we insist on having * a console (even if it is silent). */ - if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) && +#ifdef CONFIG_CONS_INDEX +#define INDEX (CONFIG_CONS_INDEX - 1) +#else +#define INDEX 0 +#endif + if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) && + uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) && (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev)) panic("No serial driver found"); +#undef INDEX } /* Called prior to relocation */ @@ -71,62 +83,74 @@ void serial_initialize(void) serial_find_console_or_panic(); } -static void serial_putc_dev(struct udevice *dev, char ch) +static void _serial_putc(struct udevice *dev, char ch) { - struct dm_serial_ops *ops = serial_get_ops(cur_dev); + struct dm_serial_ops *ops = serial_get_ops(dev); int err; do { - err = ops->putc(cur_dev, ch); + err = ops->putc(dev, ch); } while (err == -EAGAIN); if (ch == '\n') - serial_putc('\r'); + _serial_putc(dev, '\r'); } -void serial_putc(char ch) +static void _serial_puts(struct udevice *dev, const char *str) { - serial_putc_dev(cur_dev, ch); + while (*str) + _serial_putc(dev, *str++); } -void serial_setbrg(void) +static int _serial_getc(struct udevice *dev) { - struct dm_serial_ops *ops = serial_get_ops(cur_dev); + struct dm_serial_ops *ops = serial_get_ops(dev); + int err; - if (ops->setbrg) - ops->setbrg(cur_dev, gd->baudrate); -} + do { + err = ops->getc(dev); + if (err == -EAGAIN) + WATCHDOG_RESET(); + } while (err == -EAGAIN); -void serial_puts(const char *str) -{ - while (*str) - serial_putc(*str++); + return err >= 0 ? err : 0; } -int serial_tstc(void) +static int _serial_tstc(struct udevice *dev) { - struct dm_serial_ops *ops = serial_get_ops(cur_dev); + struct dm_serial_ops *ops = serial_get_ops(dev); if (ops->pending) - return ops->pending(cur_dev, true); + return ops->pending(dev, true); return 1; } -static int serial_getc_dev(struct udevice *dev) +void serial_putc(char ch) { - struct dm_serial_ops *ops = serial_get_ops(dev); - int err; - - do { - err = ops->getc(dev); - } while (err == -EAGAIN); + _serial_putc(cur_dev, ch); +} - return err >= 0 ? err : 0; +void serial_puts(const char *str) +{ + _serial_puts(cur_dev, str); } int serial_getc(void) { - return serial_getc_dev(cur_dev); + return _serial_getc(cur_dev); +} + +int serial_tstc(void) +{ + return _serial_tstc(cur_dev); +} + +void serial_setbrg(void) +{ + struct dm_serial_ops *ops = serial_get_ops(cur_dev); + + if (ops->setbrg) + ops->setbrg(cur_dev, gd->baudrate); } void serial_stdio_init(void) @@ -135,33 +159,22 @@ void serial_stdio_init(void) static void serial_stub_putc(struct stdio_dev *sdev, const char ch) { - struct udevice *dev = sdev->priv; - - serial_putc_dev(dev, ch); + _serial_putc(sdev->priv, ch); } void serial_stub_puts(struct stdio_dev *sdev, const char *str) { - while (*str) - serial_stub_putc(sdev, *str++); + _serial_puts(sdev->priv, str); } int serial_stub_getc(struct stdio_dev *sdev) { - struct udevice *dev = sdev->priv; - - return serial_getc_dev(dev); + return _serial_getc(sdev->priv); } int serial_stub_tstc(struct stdio_dev *sdev) { - struct udevice *dev = sdev->priv; - struct dm_serial_ops *ops = serial_get_ops(dev); - - if (ops->pending) - return ops->pending(dev, true); - - return 1; + return _serial_tstc(sdev->priv); } static int serial_post_probe(struct udevice *dev) diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 82fbbd9..18e41b2 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -157,7 +157,6 @@ serial_initfunc(sh_serial_initialize); serial_initfunc(arm_dcc_initialize); serial_initfunc(mxs_auart_initialize); serial_initfunc(arc_serial_initialize); -serial_initfunc(uniphier_serial_initialize); /** * serial_register() - Register serial driver with serial driver core @@ -251,33 +250,32 @@ void serial_initialize(void) arm_dcc_initialize(); mxs_auart_initialize(); arc_serial_initialize(); - uniphier_serial_initialize(); serial_assign(default_serial_console()->name); } -int serial_stub_start(struct stdio_dev *sdev) +static int serial_stub_start(struct stdio_dev *sdev) { struct serial_device *dev = sdev->priv; return dev->start(); } -int serial_stub_stop(struct stdio_dev *sdev) +static int serial_stub_stop(struct stdio_dev *sdev) { struct serial_device *dev = sdev->priv; return dev->stop(); } -void serial_stub_putc(struct stdio_dev *sdev, const char ch) +static void serial_stub_putc(struct stdio_dev *sdev, const char ch) { struct serial_device *dev = sdev->priv; dev->putc(ch); } -void serial_stub_puts(struct stdio_dev *sdev, const char *str) +static void serial_stub_puts(struct stdio_dev *sdev, const char *str) { struct serial_device *dev = sdev->priv; diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c new file mode 100644 index 0000000..5c6a76c --- /dev/null +++ b/drivers/serial/serial_coreboot.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <ns16550.h> +#include <serial.h> + +static const struct udevice_id coreboot_serial_ids[] = { + { .compatible = "coreboot-uart" }, + { } +}; + +static int coreboot_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = 1843200; + + return 0; +} +U_BOOT_DRIVER(serial_ns16550) = { + .name = "serial_coreboot", + .id = UCLASS_SERIAL, + .of_match = coreboot_serial_ids, + .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, +}; diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 9ce24f9..d6cf1d8 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -7,10 +7,10 @@ #include <common.h> #include <dm.h> #include <errno.h> -#include <serial_mxc.h> #include <watchdog.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> +#include <dm/platform_data/serial_mxc.h> #include <serial.h> #include <linux/compiler.h> diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 632da4c..799ef6a 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = { .puts = eserial##port##_puts, \ } -void -_serial_putc(const char c,const int port) +static void _serial_putc(const char c, const int port) { if (c == '\n') NS16550_putc(PORT, '\r'); @@ -128,35 +127,29 @@ _serial_putc(const char c,const int port) NS16550_putc(PORT, c); } -void -_serial_putc_raw(const char c,const int port) +static void _serial_putc_raw(const char c, const int port) { NS16550_putc(PORT, c); } -void -_serial_puts (const char *s,const int port) +static void _serial_puts(const char *s, const int port) { while (*s) { - _serial_putc (*s++,port); + _serial_putc(*s++, port); } } - -int -_serial_getc(const int port) +static int _serial_getc(const int port) { return NS16550_getc(PORT); } -int -_serial_tstc(const int port) +static int _serial_tstc(const int port) { return NS16550_tstc(PORT); } -void -_serial_setbrg (const int port) +static void _serial_setbrg(const int port) { int clock_divisor; diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c new file mode 100644 index 0000000..265fe00 --- /dev/null +++ b/drivers/serial/serial_omap.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <ns16550.h> +#include <serial.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_OF_CONTROL +static const struct udevice_id omap_serial_ids[] = { + { .compatible = "ti,omap3-uart" }, + { } +}; + +static int omap_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", -1); + plat->reg_shift = 2; + + return 0; +} +#endif + +U_BOOT_DRIVER(serial_omap_ns16550) = { + .name = "serial_omap", + .id = UCLASS_SERIAL, + .of_match = of_match_ptr(omap_serial_ids), + .ofdata_to_platdata = of_match_ptr(omap_serial_ofdata_to_platdata), + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index e6313ad..38dda91 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -17,7 +17,7 @@ #include <watchdog.h> #include <asm/io.h> #include <serial.h> -#include <serial_pl01x.h> +#include <dm/platform_data/serial_pl01x.h> #include <linux/compiler.h> #include "serial_pl01x_internal.h" diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c index c07f4c9..7afc504 100644 --- a/drivers/serial/serial_s3c24x0.c +++ b/drivers/serial/serial_s3c24x0.c @@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR; static int hwflow; #endif -void _serial_setbrg(const int dev_index) +static void _serial_setbrg(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); unsigned int reg = 0; @@ -131,7 +131,7 @@ static int serial_init_dev(const int dev_index) * otherwise. When the function is succesfull, the character read is * written into its argument c. */ -int _serial_getc(const int dev_index) +static int _serial_getc(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); @@ -181,7 +181,7 @@ void enable_putc(void) /* * Output a single byte to the serial port. */ -void _serial_putc(const char c, const int dev_index) +static void _serial_putc(const char c, const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); #ifdef CONFIG_MODEM_SUPPORT @@ -212,7 +212,7 @@ static inline void serial_putc_dev(unsigned int dev_index, const char c) /* * Test whether a character is in the RX buffer */ -int _serial_tstc(const int dev_index) +static int _serial_tstc(const int dev_index) { struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index); @@ -224,7 +224,7 @@ static inline int serial_tstc_dev(unsigned int dev_index) return _serial_tstc(dev_index); } -void _serial_puts(const char *s, const int dev_index) +static void _serial_puts(const char *s, const int dev_index) { while (*s) { _serial_putc(*s++, dev_index); diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 144a925..7c1f271 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -122,7 +122,7 @@ static void handle_error(void) sci_out(&sh_sci, SCLSR, 0x00); } -void serial_raw_putc(const char c) +static void serial_raw_putc(const char c) { while (1) { /* Tx fifo is empty */ @@ -152,7 +152,7 @@ static int sh_serial_tstc(void) } -int serial_getc_check(void) +static int serial_getc_check(void) { unsigned short status; diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index f8c9d92..9114b3e 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -2,14 +2,14 @@ * Copyright (C) 2012-2014 Panasonic Corporation * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> * - * Based on serial_ns16550.c - * (C) Copyright 2000 - * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. - * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <dm/device.h> +#include <dm/platform_data/serial-uniphier.h> #include <serial.h> #define UART_REG(x) \ @@ -48,157 +48,104 @@ struct uniphier_serial { #define UART_LSR_DR 0x01 /* Data ready */ #define UART_LSR_THRE 0x20 /* Xmit holding register empty */ -DECLARE_GLOBAL_DATA_PTR; +struct uniphier_serial_private_data { + struct uniphier_serial __iomem *membase; +}; + +#define uniphier_serial_port(dev) \ + ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase -static void uniphier_serial_init(struct uniphier_serial *port) +int uniphier_serial_setbrg(struct udevice *dev, int baudrate) { + struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); const unsigned int mode_x_div = 16; unsigned int divisor; writeb(UART_LCR_WLS_8, &port->lcr); - divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK, - mode_x_div * gd->baudrate); + divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate); writew(divisor, &port->dlr); -} -static void uniphier_serial_setbrg(struct uniphier_serial *port) -{ - uniphier_serial_init(port); + return 0; } -static int uniphier_serial_tstc(struct uniphier_serial *port) +static int uniphier_serial_getc(struct udevice *dev) { - return (readb(&port->lsr) & UART_LSR_DR) != 0; -} + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); -static int uniphier_serial_getc(struct uniphier_serial *port) -{ - while (!uniphier_serial_tstc(port)) - ; + if (!(readb(&port->lsr) & UART_LSR_DR)) + return -EAGAIN; return readb(&port->rbr); } -static void uniphier_serial_putc(struct uniphier_serial *port, const char c) +static int uniphier_serial_putc(struct udevice *dev, const char c) { - if (c == '\n') - uniphier_serial_putc(port, '\r'); + struct uniphier_serial __iomem *port = uniphier_serial_port(dev); - while (!(readb(&port->lsr) & UART_LSR_THRE)) - ; + if (!(readb(&port->lsr) & UART_LSR_THRE)) + return -EAGAIN; writeb(c, &port->thr); + + return 0; } -static struct uniphier_serial *serial_ports[4] = { -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2, -#else - NULL, -#endif -#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3 - (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3, -#else - NULL, -#endif -}; +int uniphier_serial_probe(struct udevice *dev) +{ + struct uniphier_serial_private_data *priv = dev_get_priv(dev); + struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); -/* Multi serial device functions */ -#define DECLARE_ESERIAL_FUNCTIONS(port) \ - static int eserial##port##_init(void) \ - { \ - uniphier_serial_init(serial_ports[port]); \ - return 0 ; \ - } \ - static void eserial##port##_setbrg(void) \ - { \ - uniphier_serial_setbrg(serial_ports[port]); \ - } \ - static int eserial##port##_getc(void) \ - { \ - return uniphier_serial_getc(serial_ports[port]); \ - } \ - static int eserial##port##_tstc(void) \ - { \ - return uniphier_serial_tstc(serial_ports[port]); \ - } \ - static void eserial##port##_putc(const char c) \ - { \ - uniphier_serial_putc(serial_ports[port], c); \ - } - -/* Serial device descriptor */ -#define INIT_ESERIAL_STRUCTURE(port, __name) { \ - .name = __name, \ - .start = eserial##port##_init, \ - .stop = NULL, \ - .setbrg = eserial##port##_setbrg, \ - .getc = eserial##port##_getc, \ - .tstc = eserial##port##_tstc, \ - .putc = eserial##port##_putc, \ - .puts = default_serial_puts, \ -} + priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial)); -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) -DECLARE_ESERIAL_FUNCTIONS(0); -struct serial_device uniphier_serial0_device = - INIT_ESERIAL_STRUCTURE(0, "ttyS0"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) -DECLARE_ESERIAL_FUNCTIONS(1); -struct serial_device uniphier_serial1_device = - INIT_ESERIAL_STRUCTURE(1, "ttyS1"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) -DECLARE_ESERIAL_FUNCTIONS(2); -struct serial_device uniphier_serial2_device = - INIT_ESERIAL_STRUCTURE(2, "ttyS2"); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) -DECLARE_ESERIAL_FUNCTIONS(3); -struct serial_device uniphier_serial3_device = - INIT_ESERIAL_STRUCTURE(3, "ttyS3"); -#endif + if (!priv->membase) + return -ENOMEM; -__weak struct serial_device *default_serial_console(void) + return 0; +} + +int uniphier_serial_remove(struct udevice *dev) { -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) - return &uniphier_serial0_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) - return &uniphier_serial1_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) - return &uniphier_serial2_device; -#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) - return &uniphier_serial3_device; -#else -#error "No uniphier serial ports configured." -#endif + unmap_sysmem(uniphier_serial_port(dev)); + + return 0; } -void uniphier_serial_initialize(void) +#ifdef CONFIG_OF_CONTROL +static const struct udevice_id uniphier_uart_of_match = { + { .compatible = "panasonic,uniphier-uart"}, + {}, +}; + +static int uniphier_serial_ofdata_to_platdata(struct udevice *dev) { -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) - serial_register(&uniphier_serial0_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) - serial_register(&uniphier_serial1_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) - serial_register(&uniphier_serial2_device); -#endif -#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) - serial_register(&uniphier_serial3_device); -#endif + /* + * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com) + * + * Implement conversion code from DTB to platform data + * when supporting CONFIG_OF_CONTROL on UniPhir platform. + */ } +#endif + +static const struct dm_serial_ops uniphier_serial_ops = { + .setbrg = uniphier_serial_setbrg, + .getc = uniphier_serial_getc, + .putc = uniphier_serial_putc, +}; + +U_BOOT_DRIVER(uniphier_serial) = { + .name = DRIVER_NAME, + .id = UCLASS_SERIAL, + .of_match = of_match_ptr(uniphier_uart_of_match), + .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata), + .probe = uniphier_serial_probe, + .remove = uniphier_serial_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data), + .platdata_auto_alloc_size = + sizeof(struct uniphier_serial_platform_data), + .ops = &uniphier_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e69de29..e1678e6 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -0,0 +1,6 @@ +config DM_SPI + bool "Enable Driver Model for SPI drivers" + depends on DM + help + If you want to use driver model for SPI drivers, say Y. + To use legacy SPI drivers, say N. diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 6557055..1181109 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -580,6 +580,7 @@ static const struct asix_dongle asix_dongles[] = { { 0x2001, 0x3c05, FLAG_TYPE_AX88772 }, /* ASIX 88772B */ { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC }, + { 0x0b95, 0x7e2b, FLAG_TYPE_AX88772B }, { 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */ }; diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index c4f5157..c9d2ed5 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -45,3 +45,6 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o + +# designware +obj-$(CONFIG_USB_DWC2) += dwc2.o diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c new file mode 100644 index 0000000..2a5bbf5 --- /dev/null +++ b/drivers/usb/host/dwc2.c @@ -0,0 +1,1053 @@ +/* + * Copyright (C) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> + * Copyright (C) 2014 Marek Vasut <marex@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <usb.h> +#include <malloc.h> +#include <usbroothubdes.h> +#include <asm/io.h> + +#include "dwc2.h" + +/* Use only HC channel 0. */ +#define DWC2_HC_CHANNEL 0 + +#define DWC2_STATUS_BUF_SIZE 64 +#define DWC2_DATA_BUF_SIZE (64 * 1024) + +/* We need doubleword-aligned buffers for DMA transfers */ +DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer, DWC2_DATA_BUF_SIZE, 8); +DEFINE_ALIGN_BUFFER(uint8_t, status_buffer, DWC2_STATUS_BUF_SIZE, 8); + +#define MAX_DEVICE 16 +#define MAX_ENDPOINT 16 +static int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; +static int control_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + +static int root_hub_devnum; + +static struct dwc2_core_regs *regs = + (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR; + +/* + * DWC2 IP interface + */ +static int wait_for_bit(void *reg, const uint32_t mask, bool set) +{ + unsigned int timeout = 1000000; + uint32_t val; + + while (--timeout) { + val = readl(reg); + if (!set) + val = ~val; + + if ((val & mask) == mask) + return 0; + + udelay(1); + } + + debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", + __func__, reg, mask, set); + + return -ETIMEDOUT; +} + +/* + * Initializes the FSLSPClkSel field of the HCFG register + * depending on the PHY type. + */ +static void init_fslspclksel(struct dwc2_core_regs *regs) +{ + uint32_t phyclk; + +#if (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS) + phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ; /* Full speed PHY */ +#else + /* High speed PHY running at full speed or high speed */ + phyclk = DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ; +#endif + +#ifdef CONFIG_DWC2_ULPI_FS_LS + uint32_t hwcfg2 = readl(®s->ghwcfg2); + uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >> + DWC2_HWCFG2_HS_PHY_TYPE_OFFSET; + uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >> + DWC2_HWCFG2_FS_PHY_TYPE_OFFSET; + + if (hval == 2 && fval == 1) + phyclk = DWC2_HCFG_FSLSPCLKSEL_48_MHZ; /* Full speed PHY */ +#endif + + clrsetbits_le32(®s->host_regs.hcfg, + DWC2_HCFG_FSLSPCLKSEL_MASK, + phyclk << DWC2_HCFG_FSLSPCLKSEL_OFFSET); +} + +/* + * Flush a Tx FIFO. + * + * @param regs Programming view of DWC_otg controller. + * @param num Tx FIFO to flush. + */ +static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num) +{ + int ret; + + writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET), + ®s->grstctl); + ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_TXFFLSH, 0); + if (ret) + printf("%s: Timeout!\n", __func__); + + /* Wait for 3 PHY Clocks */ + udelay(1); +} + +/* + * Flush Rx FIFO. + * + * @param regs Programming view of DWC_otg controller. + */ +static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs) +{ + int ret; + + writel(DWC2_GRSTCTL_RXFFLSH, ®s->grstctl); + ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_RXFFLSH, 0); + if (ret) + printf("%s: Timeout!\n", __func__); + + /* Wait for 3 PHY Clocks */ + udelay(1); +} + +/* + * Do core a soft reset of the core. Be careful with this because it + * resets all the internal state machines of the core. + */ +static void dwc_otg_core_reset(struct dwc2_core_regs *regs) +{ + int ret; + + /* Wait for AHB master IDLE state. */ + ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_AHBIDLE, 1); + if (ret) + printf("%s: Timeout!\n", __func__); + + /* Core Soft Reset */ + writel(DWC2_GRSTCTL_CSFTRST, ®s->grstctl); + ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_CSFTRST, 0); + if (ret) + printf("%s: Timeout!\n", __func__); + + /* + * Wait for core to come out of reset. + * NOTE: This long sleep is _very_ important, otherwise the core will + * not stay in host mode after a connector ID change! + */ + mdelay(100); +} + +/* + * This function initializes the DWC_otg controller registers for + * host mode. + * + * This function flushes the Tx and Rx FIFOs and it flushes any entries in the + * request queues. Host channels are reset to ensure that they are ready for + * performing transfers. + * + * @param regs Programming view of DWC_otg controller + * + */ +static void dwc_otg_core_host_init(struct dwc2_core_regs *regs) +{ + uint32_t nptxfifosize = 0; + uint32_t ptxfifosize = 0; + uint32_t hprt0 = 0; + int i, ret, num_channels; + + /* Restart the Phy Clock */ + writel(0, ®s->pcgcctl); + + /* Initialize Host Configuration Register */ + init_fslspclksel(regs); +#ifdef CONFIG_DWC2_DFLT_SPEED_FULL + setbits_le32(®s->host_regs.hcfg, DWC2_HCFG_FSLSSUPP); +#endif + + /* Configure data FIFO sizes */ +#ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO + if (readl(®s->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) { + /* Rx FIFO */ + writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, ®s->grxfsiz); + + /* Non-periodic Tx FIFO */ + nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE << + DWC2_FIFOSIZE_DEPTH_OFFSET; + nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE << + DWC2_FIFOSIZE_STARTADDR_OFFSET; + writel(nptxfifosize, ®s->gnptxfsiz); + + /* Periodic Tx FIFO */ + ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE << + DWC2_FIFOSIZE_DEPTH_OFFSET; + ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE + + CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) << + DWC2_FIFOSIZE_STARTADDR_OFFSET; + writel(ptxfifosize, ®s->hptxfsiz); + } +#endif + + /* Clear Host Set HNP Enable in the OTG Control Register */ + clrbits_le32(®s->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN); + + /* Make sure the FIFOs are flushed. */ + dwc_otg_flush_tx_fifo(regs, 0x10); /* All Tx FIFOs */ + dwc_otg_flush_rx_fifo(regs); + + /* Flush out any leftover queued requests. */ + num_channels = readl(®s->ghwcfg2); + num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK; + num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET; + num_channels += 1; + + for (i = 0; i < num_channels; i++) + clrsetbits_le32(®s->hc_regs[i].hcchar, + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR, + DWC2_HCCHAR_CHDIS); + + /* Halt all channels to put them into a known state. */ + for (i = 0; i < num_channels; i++) { + clrsetbits_le32(®s->hc_regs[i].hcchar, + DWC2_HCCHAR_EPDIR, + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS); + ret = wait_for_bit(®s->hc_regs[i].hcchar, + DWC2_HCCHAR_CHEN, 0); + if (ret) + printf("%s: Timeout!\n", __func__); + } + + /* Turn on the vbus power. */ + if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) { + hprt0 = readl(®s->hprt0); + hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET); + hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG); + if (!(hprt0 & DWC2_HPRT0_PRTPWR)) { + hprt0 |= DWC2_HPRT0_PRTPWR; + writel(hprt0, ®s->hprt0); + } + } +} + +/* + * This function initializes the DWC_otg controller registers and + * prepares the core for device mode or host mode operation. + * + * @param regs Programming view of the DWC_otg controller + */ +static void dwc_otg_core_init(struct dwc2_core_regs *regs) +{ + uint32_t ahbcfg = 0; + uint32_t usbcfg = 0; + uint8_t brst_sz = CONFIG_DWC2_DMA_BURST_SIZE; + + /* Common Initialization */ + usbcfg = readl(®s->gusbcfg); + + /* Program the ULPI External VBUS bit if needed */ +#ifdef CONFIG_DWC2_PHY_ULPI_EXT_VBUS + usbcfg |= DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV; +#else + usbcfg &= ~DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV; +#endif + + /* Set external TS Dline pulsing */ +#ifdef CONFIG_DWC2_TS_DLINE + usbcfg |= DWC2_GUSBCFG_TERM_SEL_DL_PULSE; +#else + usbcfg &= ~DWC2_GUSBCFG_TERM_SEL_DL_PULSE; +#endif + writel(usbcfg, ®s->gusbcfg); + + /* Reset the Controller */ + dwc_otg_core_reset(regs); + + /* + * This programming sequence needs to happen in FS mode before + * any other programming occurs + */ +#if defined(CONFIG_DWC2_DFLT_SPEED_FULL) && \ + (CONFIG_DWC2_PHY_TYPE == DWC2_PHY_TYPE_FS) + /* If FS mode with FS PHY */ + setbits_le32(®s->gusbcfg, DWC2_GUSBCFG_PHYSEL); + + /* Reset after a PHY select */ + dwc_otg_core_reset(regs); + + /* + * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. + * Also do this on HNP Dev/Host mode switches (done in dev_init + * and host_init). + */ + if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) + init_fslspclksel(regs); + +#ifdef CONFIG_DWC2_I2C_ENABLE + /* Program GUSBCFG.OtgUtmifsSel to I2C */ + setbits_le32(®s->gusbcfg, DWC2_GUSBCFG_OTGUTMIFSSEL); + + /* Program GI2CCTL.I2CEn */ + clrsetbits_le32(®s->gi2cctl, DWC2_GI2CCTL_I2CEN | + DWC2_GI2CCTL_I2CDEVADDR_MASK, + 1 << DWC2_GI2CCTL_I2CDEVADDR_OFFSET); + setbits_le32(®s->gi2cctl, DWC2_GI2CCTL_I2CEN); +#endif + +#else + /* High speed PHY. */ + + /* + * HS PHY parameters. These parameters are preserved during + * soft reset so only program the first time. Do a soft reset + * immediately after setting phyif. + */ + usbcfg &= ~(DWC2_GUSBCFG_ULPI_UTMI_SEL | DWC2_GUSBCFG_PHYIF); + usbcfg |= CONFIG_DWC2_PHY_TYPE << DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET; + + if (usbcfg & DWC2_GUSBCFG_ULPI_UTMI_SEL) { /* ULPI interface */ +#ifdef CONFIG_DWC2_PHY_ULPI_DDR + usbcfg |= DWC2_GUSBCFG_DDRSEL; +#else + usbcfg &= ~DWC2_GUSBCFG_DDRSEL; +#endif + } else { /* UTMI+ interface */ +#if (CONFIG_DWC2_UTMI_PHY_WIDTH == 16) + usbcfg |= DWC2_GUSBCFG_PHYIF; +#endif + } + + writel(usbcfg, ®s->gusbcfg); + + /* Reset after setting the PHY parameters */ + dwc_otg_core_reset(regs); +#endif + + usbcfg = readl(®s->gusbcfg); + usbcfg &= ~(DWC2_GUSBCFG_ULPI_FSLS | DWC2_GUSBCFG_ULPI_CLK_SUS_M); +#ifdef CONFIG_DWC2_ULPI_FS_LS + uint32_t hwcfg2 = readl(®s->ghwcfg2); + uint32_t hval = (ghwcfg2 & DWC2_HWCFG2_HS_PHY_TYPE_MASK) >> + DWC2_HWCFG2_HS_PHY_TYPE_OFFSET; + uint32_t fval = (ghwcfg2 & DWC2_HWCFG2_FS_PHY_TYPE_MASK) >> + DWC2_HWCFG2_FS_PHY_TYPE_OFFSET; + if (hval == 2 && fval == 1) { + usbcfg |= DWC2_GUSBCFG_ULPI_FSLS; + usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M; + } +#endif + writel(usbcfg, ®s->gusbcfg); + + /* Program the GAHBCFG Register. */ + switch (readl(®s->ghwcfg2) & DWC2_HWCFG2_ARCHITECTURE_MASK) { + case DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY: + break; + case DWC2_HWCFG2_ARCHITECTURE_EXT_DMA: + while (brst_sz > 1) { + ahbcfg |= ahbcfg + (1 << DWC2_GAHBCFG_HBURSTLEN_OFFSET); + ahbcfg &= DWC2_GAHBCFG_HBURSTLEN_MASK; + brst_sz >>= 1; + } + +#ifdef CONFIG_DWC2_DMA_ENABLE + ahbcfg |= DWC2_GAHBCFG_DMAENABLE; +#endif + break; + + case DWC2_HWCFG2_ARCHITECTURE_INT_DMA: + ahbcfg |= DWC2_GAHBCFG_HBURSTLEN_INCR4; +#ifdef CONFIG_DWC2_DMA_ENABLE + ahbcfg |= DWC2_GAHBCFG_DMAENABLE; +#endif + break; + } + + writel(ahbcfg, ®s->gahbcfg); + + /* Program the GUSBCFG register for HNP/SRP. */ + setbits_le32(®s->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP); + +#ifdef CONFIG_DWC2_IC_USB_CAP + setbits_le32(®s->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP); +#endif +} + +/* + * Prepares a host channel for transferring packets to/from a specific + * endpoint. The HCCHARn register is set up with the characteristics specified + * in _hc. Host channel interrupts that may need to be serviced while this + * transfer is in progress are enabled. + * + * @param regs Programming view of DWC_otg controller + * @param hc Information needed to initialize the host channel + */ +static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num, + uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in, + uint8_t ep_type, uint16_t max_packet) +{ + struct dwc2_hc_regs *hc_regs = ®s->hc_regs[hc_num]; + const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) | + (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) | + (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) | + (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) | + (max_packet << DWC2_HCCHAR_MPS_OFFSET); + + /* Clear old interrupt conditions for this host channel. */ + writel(0x3fff, &hc_regs->hcint); + + /* + * Program the HCCHARn register with the endpoint characteristics + * for the current transfer. + */ + writel(hcchar, &hc_regs->hcchar); + + /* Program the HCSPLIT register for SPLITs */ + writel(0, &hc_regs->hcsplt); +} + +/* + * DWC2 to USB API interface + */ +/* Direction: In ; Request: Status */ +static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer, + int txlen, struct devrequest *cmd) +{ + uint32_t hprt0 = 0; + uint32_t port_status = 0; + uint32_t port_change = 0; + int len = 0; + int stat = 0; + + switch (cmd->requesttype & ~USB_DIR_IN) { + case 0: + *(uint16_t *)buffer = cpu_to_le16(1); + len = 2; + break; + case USB_RECIP_INTERFACE: + case USB_RECIP_ENDPOINT: + *(uint16_t *)buffer = cpu_to_le16(0); + len = 2; + break; + case USB_TYPE_CLASS: + *(uint32_t *)buffer = cpu_to_le32(0); + len = 4; + break; + case USB_RECIP_OTHER | USB_TYPE_CLASS: + hprt0 = readl(®s->hprt0); + if (hprt0 & DWC2_HPRT0_PRTCONNSTS) + port_status |= USB_PORT_STAT_CONNECTION; + if (hprt0 & DWC2_HPRT0_PRTENA) + port_status |= USB_PORT_STAT_ENABLE; + if (hprt0 & DWC2_HPRT0_PRTSUSP) + port_status |= USB_PORT_STAT_SUSPEND; + if (hprt0 & DWC2_HPRT0_PRTOVRCURRACT) + port_status |= USB_PORT_STAT_OVERCURRENT; + if (hprt0 & DWC2_HPRT0_PRTRST) + port_status |= USB_PORT_STAT_RESET; + if (hprt0 & DWC2_HPRT0_PRTPWR) + port_status |= USB_PORT_STAT_POWER; + + port_status |= USB_PORT_STAT_HIGH_SPEED; + + if (hprt0 & DWC2_HPRT0_PRTENCHNG) + port_change |= USB_PORT_STAT_C_ENABLE; + if (hprt0 & DWC2_HPRT0_PRTCONNDET) + port_change |= USB_PORT_STAT_C_CONNECTION; + if (hprt0 & DWC2_HPRT0_PRTOVRCURRCHNG) + port_change |= USB_PORT_STAT_C_OVERCURRENT; + + *(uint32_t *)buffer = cpu_to_le32(port_status | + (port_change << 16)); + len = 4; + break; + default: + puts("unsupported root hub command\n"); + stat = USB_ST_STALLED; + } + + dev->act_len = min(len, txlen); + dev->status = stat; + + return stat; +} + +/* Direction: In ; Request: Descriptor */ +static int dwc_otg_submit_rh_msg_in_descriptor(struct usb_device *dev, + void *buffer, int txlen, + struct devrequest *cmd) +{ + unsigned char data[32]; + uint32_t dsc; + int len = 0; + int stat = 0; + uint16_t wValue = cpu_to_le16(cmd->value); + uint16_t wLength = cpu_to_le16(cmd->length); + + switch (cmd->requesttype & ~USB_DIR_IN) { + case 0: + switch (wValue & 0xff00) { + case 0x0100: /* device descriptor */ + len = min3(txlen, sizeof(root_hub_dev_des), wLength); + memcpy(buffer, root_hub_dev_des, len); + break; + case 0x0200: /* configuration descriptor */ + len = min3(txlen, sizeof(root_hub_config_des), wLength); + memcpy(buffer, root_hub_config_des, len); + break; + case 0x0300: /* string descriptors */ + switch (wValue & 0xff) { + case 0x00: + len = min3(txlen, sizeof(root_hub_str_index0), + wLength); + memcpy(buffer, root_hub_str_index0, len); + break; + case 0x01: + len = min3(txlen, sizeof(root_hub_str_index1), + wLength); + memcpy(buffer, root_hub_str_index1, len); + break; + } + break; + default: + stat = USB_ST_STALLED; + } + break; + + case USB_TYPE_CLASS: + /* Root port config, set 1 port and nothing else. */ + dsc = 0x00000001; + + data[0] = 9; /* min length; */ + data[1] = 0x29; + data[2] = dsc & RH_A_NDP; + data[3] = 0; + if (dsc & RH_A_PSM) + data[3] |= 0x1; + if (dsc & RH_A_NOCP) + data[3] |= 0x10; + else if (dsc & RH_A_OCPM) + data[3] |= 0x8; + + /* corresponds to data[4-7] */ + data[5] = (dsc & RH_A_POTPGT) >> 24; + data[7] = dsc & RH_B_DR; + if (data[2] < 7) { + data[8] = 0xff; + } else { + data[0] += 2; + data[8] = (dsc & RH_B_DR) >> 8; + data[9] = 0xff; + data[10] = data[9]; + } + + len = min3(txlen, data[0], wLength); + memcpy(buffer, data, len); + break; + default: + puts("unsupported root hub command\n"); + stat = USB_ST_STALLED; + } + + dev->act_len = min(len, txlen); + dev->status = stat; + + return stat; +} + +/* Direction: In ; Request: Configuration */ +static int dwc_otg_submit_rh_msg_in_configuration(struct usb_device *dev, + void *buffer, int txlen, + struct devrequest *cmd) +{ + int len = 0; + int stat = 0; + + switch (cmd->requesttype & ~USB_DIR_IN) { + case 0: + *(uint8_t *)buffer = 0x01; + len = 1; + break; + default: + puts("unsupported root hub command\n"); + stat = USB_ST_STALLED; + } + + dev->act_len = min(len, txlen); + dev->status = stat; + + return stat; +} + +/* Direction: In */ +static int dwc_otg_submit_rh_msg_in(struct usb_device *dev, + void *buffer, int txlen, + struct devrequest *cmd) +{ + switch (cmd->request) { + case USB_REQ_GET_STATUS: + return dwc_otg_submit_rh_msg_in_status(dev, buffer, + txlen, cmd); + case USB_REQ_GET_DESCRIPTOR: + return dwc_otg_submit_rh_msg_in_descriptor(dev, buffer, + txlen, cmd); + case USB_REQ_GET_CONFIGURATION: + return dwc_otg_submit_rh_msg_in_configuration(dev, buffer, + txlen, cmd); + default: + puts("unsupported root hub command\n"); + return USB_ST_STALLED; + } +} + +/* Direction: Out */ +static int dwc_otg_submit_rh_msg_out(struct usb_device *dev, + void *buffer, int txlen, + struct devrequest *cmd) +{ + int len = 0; + int stat = 0; + uint16_t bmrtype_breq = cmd->requesttype | (cmd->request << 8); + uint16_t wValue = cpu_to_le16(cmd->value); + + switch (bmrtype_breq & ~USB_DIR_IN) { + case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_ENDPOINT: + case (USB_REQ_CLEAR_FEATURE << 8) | USB_TYPE_CLASS: + break; + + case (USB_REQ_CLEAR_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS: + switch (wValue) { + case USB_PORT_FEAT_C_CONNECTION: + setbits_le32(®s->hprt0, DWC2_HPRT0_PRTCONNDET); + break; + } + break; + + case (USB_REQ_SET_FEATURE << 8) | USB_RECIP_OTHER | USB_TYPE_CLASS: + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + break; + + case USB_PORT_FEAT_RESET: + clrsetbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | + DWC2_HPRT0_PRTCONNDET | + DWC2_HPRT0_PRTENCHNG | + DWC2_HPRT0_PRTOVRCURRCHNG, + DWC2_HPRT0_PRTRST); + mdelay(50); + clrbits_le32(®s->hprt0, DWC2_HPRT0_PRTRST); + break; + + case USB_PORT_FEAT_POWER: + clrsetbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | + DWC2_HPRT0_PRTCONNDET | + DWC2_HPRT0_PRTENCHNG | + DWC2_HPRT0_PRTOVRCURRCHNG, + DWC2_HPRT0_PRTRST); + break; + + case USB_PORT_FEAT_ENABLE: + break; + } + break; + case (USB_REQ_SET_ADDRESS << 8): + root_hub_devnum = wValue; + break; + case (USB_REQ_SET_CONFIGURATION << 8): + break; + default: + puts("unsupported root hub command\n"); + stat = USB_ST_STALLED; + } + + len = min(len, txlen); + + dev->act_len = len; + dev->status = stat; + + return stat; +} + +static int dwc_otg_submit_rh_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int txlen, + struct devrequest *cmd) +{ + int stat = 0; + + if (usb_pipeint(pipe)) { + puts("Root-Hub submit IRQ: NOT implemented\n"); + return 0; + } + + if (cmd->requesttype & USB_DIR_IN) + stat = dwc_otg_submit_rh_msg_in(dev, buffer, txlen, cmd); + else + stat = dwc_otg_submit_rh_msg_out(dev, buffer, txlen, cmd); + + mdelay(1); + + return stat; +} + +/* U-Boot USB transmission interface */ +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len) +{ + int devnum = usb_pipedevice(pipe); + int ep = usb_pipeendpoint(pipe); + int max = usb_maxpacket(dev, pipe); + int done = 0; + uint32_t hctsiz, sub, tmp; + struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; + uint32_t hcint; + uint32_t xfer_len; + uint32_t num_packets; + int stop_transfer = 0; + unsigned int timeout = 1000000; + + if (devnum == root_hub_devnum) { + dev->status = 0; + return -EINVAL; + } + + if (len > DWC2_DATA_BUF_SIZE) { + printf("%s: %d is more then available buffer size (%d)\n", + __func__, len, DWC2_DATA_BUF_SIZE); + dev->status = 0; + dev->act_len = 0; + return -EINVAL; + } + + while ((done < len) && !stop_transfer) { + /* Initialize channel */ + dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, + usb_pipein(pipe), DWC2_HCCHAR_EPTYPE_BULK, max); + + xfer_len = len - done; + /* Make sure that xfer_len is a multiple of max packet size. */ + if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE) + xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1; + + if (xfer_len > 0) { + num_packets = (xfer_len + max - 1) / max; + if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) { + num_packets = CONFIG_DWC2_MAX_PACKET_COUNT; + xfer_len = num_packets * max; + } + } else { + num_packets = 1; + } + + if (usb_pipein(pipe)) + xfer_len = num_packets * max; + + writel((xfer_len << DWC2_HCTSIZ_XFERSIZE_OFFSET) | + (num_packets << DWC2_HCTSIZ_PKTCNT_OFFSET) | + (bulk_data_toggle[devnum][ep] << + DWC2_HCTSIZ_PID_OFFSET), + &hc_regs->hctsiz); + + memcpy(aligned_buffer, (char *)buffer + done, len - done); + writel((uint32_t)aligned_buffer, &hc_regs->hcdma); + + /* Set host channel enable after all other setup is complete. */ + clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK | + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS, + (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | + DWC2_HCCHAR_CHEN); + + while (1) { + hcint = readl(&hc_regs->hcint); + + if (!(hcint & DWC2_HCINT_CHHLTD)) + continue; + + if (hcint & DWC2_HCINT_XFERCOMP) { + hctsiz = readl(&hc_regs->hctsiz); + done += xfer_len; + + sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK; + sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET; + + if (usb_pipein(pipe)) { + done -= sub; + if (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK) + stop_transfer = 1; + } + + tmp = hctsiz & DWC2_HCTSIZ_PID_MASK; + tmp >>= DWC2_HCTSIZ_PID_OFFSET; + if (tmp == DWC2_HC_PID_DATA1) { + bulk_data_toggle[devnum][ep] = + DWC2_HC_PID_DATA1; + } else { + bulk_data_toggle[devnum][ep] = + DWC2_HC_PID_DATA0; + } + break; + } + + if (hcint & DWC2_HCINT_STALL) { + puts("DWC OTG: Channel halted\n"); + bulk_data_toggle[devnum][ep] = + DWC2_HC_PID_DATA0; + + stop_transfer = 1; + break; + } + + if (!--timeout) { + printf("%s: Timeout!\n", __func__); + break; + } + } + } + + if (done && usb_pipein(pipe)) + memcpy(buffer, aligned_buffer, done); + + writel(0, &hc_regs->hcintmsk); + writel(0xFFFFFFFF, &hc_regs->hcint); + + dev->status = 0; + dev->act_len = done; + + return 0; +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len, struct devrequest *setup) +{ + struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; + int done = 0; + int devnum = usb_pipedevice(pipe); + int ep = usb_pipeendpoint(pipe); + int max = usb_maxpacket(dev, pipe); + uint32_t hctsiz = 0, sub, tmp, ret; + uint32_t hcint; + const uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP | + DWC2_HCINT_CHHLTD | DWC2_HCINT_ACK; + unsigned int timeout = 1000000; + + /* For CONTROL endpoint pid should start with DATA1 */ + int status_direction; + + if (devnum == root_hub_devnum) { + dev->status = 0; + dev->speed = USB_SPEED_HIGH; + return dwc_otg_submit_rh_msg(dev, pipe, buffer, len, setup); + } + + if (len > DWC2_DATA_BUF_SIZE) { + printf("%s: %d is more then available buffer size(%d)\n", + __func__, len, DWC2_DATA_BUF_SIZE); + dev->status = 0; + dev->act_len = 0; + return -EINVAL; + } + + /* Initialize channel, OUT for setup buffer */ + dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, 0, + DWC2_HCCHAR_EPTYPE_CONTROL, max); + + /* SETUP stage */ + writel((8 << DWC2_HCTSIZ_XFERSIZE_OFFSET) | + (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) | + (DWC2_HC_PID_SETUP << DWC2_HCTSIZ_PID_OFFSET), + &hc_regs->hctsiz); + + writel((uint32_t)setup, &hc_regs->hcdma); + + /* Set host channel enable after all other setup is complete. */ + clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK | + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS, + (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN); + + ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, 1); + if (ret) + printf("%s: Timeout!\n", __func__); + + hcint = readl(&hc_regs->hcint); + + if (!(hcint & DWC2_HCINT_CHHLTD) || !(hcint & DWC2_HCINT_XFERCOMP)) { + printf("%s: Error (HCINT=%08x)\n", __func__, hcint); + dev->status = 0; + dev->act_len = 0; + return -EINVAL; + } + + /* Clear interrupts */ + writel(0, &hc_regs->hcintmsk); + writel(0xFFFFFFFF, &hc_regs->hcint); + + if (buffer) { + /* DATA stage */ + dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, + usb_pipein(pipe), + DWC2_HCCHAR_EPTYPE_CONTROL, max); + + /* TODO: check if len < 64 */ + control_data_toggle[devnum][ep] = DWC2_HC_PID_DATA1; + writel((len << DWC2_HCTSIZ_XFERSIZE_OFFSET) | + (1 << DWC2_HCTSIZ_PKTCNT_OFFSET) | + (control_data_toggle[devnum][ep] << + DWC2_HCTSIZ_PID_OFFSET), + &hc_regs->hctsiz); + + writel((uint32_t)buffer, &hc_regs->hcdma); + + /* Set host channel enable after all other setup is complete */ + clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK | + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS, + (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | + DWC2_HCCHAR_CHEN); + + while (1) { + hcint = readl(&hc_regs->hcint); + if (!(hcint & DWC2_HCINT_CHHLTD)) + continue; + + if (hcint & DWC2_HCINT_XFERCOMP) { + hctsiz = readl(&hc_regs->hctsiz); + done = len; + + sub = hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK; + sub >>= DWC2_HCTSIZ_XFERSIZE_OFFSET; + + if (usb_pipein(pipe)) + done -= sub; + } + + if (hcint & DWC2_HCINT_ACK) { + tmp = hctsiz & DWC2_HCTSIZ_PID_MASK; + tmp >>= DWC2_HCTSIZ_PID_OFFSET; + if (tmp == DWC2_HC_PID_DATA0) { + control_data_toggle[devnum][ep] = + DWC2_HC_PID_DATA0; + } else { + control_data_toggle[devnum][ep] = + DWC2_HC_PID_DATA1; + } + } + + if (hcint != hcint_comp_hlt_ack) { + printf("%s: Error (HCINT=%08x)\n", + __func__, hcint); + goto out; + } + + if (!--timeout) { + printf("%s: Timeout!\n", __func__); + goto out; + } + + break; + } + } /* End of DATA stage */ + + /* STATUS stage */ + if ((len == 0) || usb_pipeout(pipe)) + status_direction = 1; + else + status_direction = 0; + + dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, + status_direction, DWC2_HCCHAR_EPTYPE_CONTROL, max); + + writel((1 << DWC2_HCTSIZ_PKTCNT_OFFSET) | + (DWC2_HC_PID_DATA1 << DWC2_HCTSIZ_PID_OFFSET), + &hc_regs->hctsiz); + + writel((uint32_t)status_buffer, &hc_regs->hcdma); + + /* Set host channel enable after all other setup is complete. */ + clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK | + DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS, + (1 << DWC2_HCCHAR_MULTICNT_OFFSET) | DWC2_HCCHAR_CHEN); + + while (1) { + hcint = readl(&hc_regs->hcint); + if (hcint & DWC2_HCINT_CHHLTD) + break; + } + + if (hcint != hcint_comp_hlt_ack) + printf("%s: Error (HCINT=%08x)\n", __func__, hcint); + +out: + dev->act_len = done; + dev->status = 0; + + return done; +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len, int interval) +{ + printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n", + dev, pipe, buffer, len, interval); + return -ENOSYS; +} + +/* U-Boot USB control interface */ +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ + uint32_t snpsid; + int i, j; + + root_hub_devnum = 0; + + snpsid = readl(®s->gsnpsid); + printf("Core Release: %x.%03x\n", snpsid >> 12 & 0xf, snpsid & 0xfff); + + if ((snpsid & DWC2_SNPSID_DEVID_MASK) != DWC2_SNPSID_DEVID_VER_2xx) { + printf("SNPSID invalid (not DWC2 OTG device): %08x\n", snpsid); + return -ENODEV; + } + + dwc_otg_core_init(regs); + dwc_otg_core_host_init(regs); + + clrsetbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | + DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG | + DWC2_HPRT0_PRTOVRCURRCHNG, + DWC2_HPRT0_PRTRST); + mdelay(50); + clrbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET | + DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG | + DWC2_HPRT0_PRTRST); + + for (i = 0; i < MAX_DEVICE; i++) { + for (j = 0; j < MAX_ENDPOINT; j++) { + control_data_toggle[i][j] = DWC2_HC_PID_DATA1; + bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0; + } + } + + return 0; +} + +int usb_lowlevel_stop(int index) +{ + /* Put everything in reset. */ + clrsetbits_le32(®s->hprt0, DWC2_HPRT0_PRTENA | + DWC2_HPRT0_PRTCONNDET | DWC2_HPRT0_PRTENCHNG | + DWC2_HPRT0_PRTOVRCURRCHNG, + DWC2_HPRT0_PRTRST); + return 0; +} diff --git a/drivers/usb/host/dwc2.h b/drivers/usb/host/dwc2.h new file mode 100644 index 0000000..ba08fd5 --- /dev/null +++ b/drivers/usb/host/dwc2.h @@ -0,0 +1,782 @@ +/* + * Copyright (C) 2014 Marek Vasut <marex@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DWC2_H__ +#define __DWC2_H__ + +struct dwc2_hc_regs { + u32 hcchar; /* 0x00 */ + u32 hcsplt; + u32 hcint; + u32 hcintmsk; + u32 hctsiz; /* 0x10 */ + u32 hcdma; + u32 reserved; + u32 hcdmab; +}; + +struct dwc2_host_regs { + u32 hcfg; /* 0x00 */ + u32 hfir; + u32 hfnum; + u32 _pad_0x40c; + u32 hptxsts; /* 0x10 */ + u32 haint; + u32 haintmsk; + u32 hflbaddr; +}; + +struct dwc2_core_regs { + u32 gotgctl; /* 0x000 */ + u32 gotgint; + u32 gahbcfg; + u32 gusbcfg; + u32 grstctl; /* 0x010 */ + u32 gintsts; + u32 gintmsk; + u32 grxstsr; + u32 grxstsp; /* 0x020 */ + u32 grxfsiz; + u32 gnptxfsiz; + u32 gnptxsts; + u32 gi2cctl; /* 0x030 */ + u32 gpvndctl; + u32 ggpio; + u32 guid; + u32 gsnpsid; /* 0x040 */ + u32 ghwcfg1; + u32 ghwcfg2; + u32 ghwcfg3; + u32 ghwcfg4; /* 0x050 */ + u32 glpmcfg; + u32 _pad_0x58_0x9c[42]; + u32 hptxfsiz; /* 0x100 */ + u32 dptxfsiz_dieptxf[15]; + u32 _pad_0x140_0x3fc[176]; + struct dwc2_host_regs host_regs; /* 0x400 */ + u32 _pad_0x420_0x43c[8]; + u32 hprt0; /* 0x440 */ + u32 _pad_0x444_0x4fc[47]; + struct dwc2_hc_regs hc_regs[16]; /* 0x500 */ + u32 _pad_0x700_0xe00[448]; + u32 pcgcctl; /* 0xe00 */ +}; + +#define DWC2_GOTGCTL_SESREQSCS (1 << 0) +#define DWC2_GOTGCTL_SESREQSCS_OFFSET 0 +#define DWC2_GOTGCTL_SESREQ (1 << 1) +#define DWC2_GOTGCTL_SESREQ_OFFSET 1 +#define DWC2_GOTGCTL_HSTNEGSCS (1 << 8) +#define DWC2_GOTGCTL_HSTNEGSCS_OFFSET 8 +#define DWC2_GOTGCTL_HNPREQ (1 << 9) +#define DWC2_GOTGCTL_HNPREQ_OFFSET 9 +#define DWC2_GOTGCTL_HSTSETHNPEN (1 << 10) +#define DWC2_GOTGCTL_HSTSETHNPEN_OFFSET 10 +#define DWC2_GOTGCTL_DEVHNPEN (1 << 11) +#define DWC2_GOTGCTL_DEVHNPEN_OFFSET 11 +#define DWC2_GOTGCTL_CONIDSTS (1 << 16) +#define DWC2_GOTGCTL_CONIDSTS_OFFSET 16 +#define DWC2_GOTGCTL_DBNCTIME (1 << 17) +#define DWC2_GOTGCTL_DBNCTIME_OFFSET 17 +#define DWC2_GOTGCTL_ASESVLD (1 << 18) +#define DWC2_GOTGCTL_ASESVLD_OFFSET 18 +#define DWC2_GOTGCTL_BSESVLD (1 << 19) +#define DWC2_GOTGCTL_BSESVLD_OFFSET 19 +#define DWC2_GOTGCTL_OTGVER (1 << 20) +#define DWC2_GOTGCTL_OTGVER_OFFSET 20 +#define DWC2_GOTGINT_SESENDDET (1 << 2) +#define DWC2_GOTGINT_SESENDDET_OFFSET 2 +#define DWC2_GOTGINT_SESREQSUCSTSCHNG (1 << 8) +#define DWC2_GOTGINT_SESREQSUCSTSCHNG_OFFSET 8 +#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG (1 << 9) +#define DWC2_GOTGINT_HSTNEGSUCSTSCHNG_OFFSET 9 +#define DWC2_GOTGINT_RESERVER10_16_MASK (0x7F << 10) +#define DWC2_GOTGINT_RESERVER10_16_OFFSET 10 +#define DWC2_GOTGINT_HSTNEGDET (1 << 17) +#define DWC2_GOTGINT_HSTNEGDET_OFFSET 17 +#define DWC2_GOTGINT_ADEVTOUTCHNG (1 << 18) +#define DWC2_GOTGINT_ADEVTOUTCHNG_OFFSET 18 +#define DWC2_GOTGINT_DEBDONE (1 << 19) +#define DWC2_GOTGINT_DEBDONE_OFFSET 19 +#define DWC2_GAHBCFG_GLBLINTRMSK (1 << 0) +#define DWC2_GAHBCFG_GLBLINTRMSK_OFFSET 0 +#define DWC2_GAHBCFG_HBURSTLEN_SINGLE (0 << 1) +#define DWC2_GAHBCFG_HBURSTLEN_INCR (1 << 1) +#define DWC2_GAHBCFG_HBURSTLEN_INCR4 (3 << 1) +#define DWC2_GAHBCFG_HBURSTLEN_INCR8 (5 << 1) +#define DWC2_GAHBCFG_HBURSTLEN_INCR16 (7 << 1) +#define DWC2_GAHBCFG_HBURSTLEN_MASK (0xF << 1) +#define DWC2_GAHBCFG_HBURSTLEN_OFFSET 1 +#define DWC2_GAHBCFG_DMAENABLE (1 << 5) +#define DWC2_GAHBCFG_DMAENABLE_OFFSET 5 +#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL (1 << 7) +#define DWC2_GAHBCFG_NPTXFEMPLVL_TXFEMPLVL_OFFSET 7 +#define DWC2_GAHBCFG_PTXFEMPLVL (1 << 8) +#define DWC2_GAHBCFG_PTXFEMPLVL_OFFSET 8 +#define DWC2_GUSBCFG_TOUTCAL_MASK (0x7 << 0) +#define DWC2_GUSBCFG_TOUTCAL_OFFSET 0 +#define DWC2_GUSBCFG_PHYIF (1 << 3) +#define DWC2_GUSBCFG_PHYIF_OFFSET 3 +#define DWC2_GUSBCFG_ULPI_UTMI_SEL (1 << 4) +#define DWC2_GUSBCFG_ULPI_UTMI_SEL_OFFSET 4 +#define DWC2_GUSBCFG_FSINTF (1 << 5) +#define DWC2_GUSBCFG_FSINTF_OFFSET 5 +#define DWC2_GUSBCFG_PHYSEL (1 << 6) +#define DWC2_GUSBCFG_PHYSEL_OFFSET 6 +#define DWC2_GUSBCFG_DDRSEL (1 << 7) +#define DWC2_GUSBCFG_DDRSEL_OFFSET 7 +#define DWC2_GUSBCFG_SRPCAP (1 << 8) +#define DWC2_GUSBCFG_SRPCAP_OFFSET 8 +#define DWC2_GUSBCFG_HNPCAP (1 << 9) +#define DWC2_GUSBCFG_HNPCAP_OFFSET 9 +#define DWC2_GUSBCFG_USBTRDTIM_MASK (0xF << 10) +#define DWC2_GUSBCFG_USBTRDTIM_OFFSET 10 +#define DWC2_GUSBCFG_NPTXFRWNDEN (1 << 14) +#define DWC2_GUSBCFG_NPTXFRWNDEN_OFFSET 14 +#define DWC2_GUSBCFG_PHYLPWRCLKSEL (1 << 15) +#define DWC2_GUSBCFG_PHYLPWRCLKSEL_OFFSET 15 +#define DWC2_GUSBCFG_OTGUTMIFSSEL (1 << 16) +#define DWC2_GUSBCFG_OTGUTMIFSSEL_OFFSET 16 +#define DWC2_GUSBCFG_ULPI_FSLS (1 << 17) +#define DWC2_GUSBCFG_ULPI_FSLS_OFFSET 17 +#define DWC2_GUSBCFG_ULPI_AUTO_RES (1 << 18) +#define DWC2_GUSBCFG_ULPI_AUTO_RES_OFFSET 18 +#define DWC2_GUSBCFG_ULPI_CLK_SUS_M (1 << 19) +#define DWC2_GUSBCFG_ULPI_CLK_SUS_M_OFFSET 19 +#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV (1 << 20) +#define DWC2_GUSBCFG_ULPI_EXT_VBUS_DRV_OFFSET 20 +#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR (1 << 21) +#define DWC2_GUSBCFG_ULPI_INT_VBUS_INDICATOR_OFFSET 21 +#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE (1 << 22) +#define DWC2_GUSBCFG_TERM_SEL_DL_PULSE_OFFSET 22 +#define DWC2_GUSBCFG_IC_USB_CAP (1 << 26) +#define DWC2_GUSBCFG_IC_USB_CAP_OFFSET 26 +#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE (1 << 27) +#define DWC2_GUSBCFG_IC_TRAFFIC_PULL_REMOVE_OFFSET 27 +#define DWC2_GUSBCFG_TX_END_DELAY (1 << 28) +#define DWC2_GUSBCFG_TX_END_DELAY_OFFSET 28 +#define DWC2_GUSBCFG_FORCEHOSTMODE (1 << 29) +#define DWC2_GUSBCFG_FORCEHOSTMODE_OFFSET 29 +#define DWC2_GUSBCFG_FORCEDEVMODE (1 << 30) +#define DWC2_GUSBCFG_FORCEDEVMODE_OFFSET 30 +#define DWC2_GLPMCTL_LPM_CAP_EN (1 << 0) +#define DWC2_GLPMCTL_LPM_CAP_EN_OFFSET 0 +#define DWC2_GLPMCTL_APPL_RESP (1 << 1) +#define DWC2_GLPMCTL_APPL_RESP_OFFSET 1 +#define DWC2_GLPMCTL_HIRD_MASK (0xF << 2) +#define DWC2_GLPMCTL_HIRD_OFFSET 2 +#define DWC2_GLPMCTL_REM_WKUP_EN (1 << 6) +#define DWC2_GLPMCTL_REM_WKUP_EN_OFFSET 6 +#define DWC2_GLPMCTL_EN_UTMI_SLEEP (1 << 7) +#define DWC2_GLPMCTL_EN_UTMI_SLEEP_OFFSET 7 +#define DWC2_GLPMCTL_HIRD_THRES_MASK (0x1F << 8) +#define DWC2_GLPMCTL_HIRD_THRES_OFFSET 8 +#define DWC2_GLPMCTL_LPM_RESP_MASK (0x3 << 13) +#define DWC2_GLPMCTL_LPM_RESP_OFFSET 13 +#define DWC2_GLPMCTL_PRT_SLEEP_STS (1 << 15) +#define DWC2_GLPMCTL_PRT_SLEEP_STS_OFFSET 15 +#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK (1 << 16) +#define DWC2_GLPMCTL_SLEEP_STATE_RESUMEOK_OFFSET 16 +#define DWC2_GLPMCTL_LPM_CHAN_INDEX_MASK (0xF << 17) +#define DWC2_GLPMCTL_LPM_CHAN_INDEX_OFFSET 17 +#define DWC2_GLPMCTL_RETRY_COUNT_MASK (0x7 << 21) +#define DWC2_GLPMCTL_RETRY_COUNT_OFFSET 21 +#define DWC2_GLPMCTL_SEND_LPM (1 << 24) +#define DWC2_GLPMCTL_SEND_LPM_OFFSET 24 +#define DWC2_GLPMCTL_RETRY_COUNT_STS_MASK (0x7 << 25) +#define DWC2_GLPMCTL_RETRY_COUNT_STS_OFFSET 25 +#define DWC2_GLPMCTL_HSIC_CONNECT (1 << 30) +#define DWC2_GLPMCTL_HSIC_CONNECT_OFFSET 30 +#define DWC2_GLPMCTL_INV_SEL_HSIC (1 << 31) +#define DWC2_GLPMCTL_INV_SEL_HSIC_OFFSET 31 +#define DWC2_GRSTCTL_CSFTRST (1 << 0) +#define DWC2_GRSTCTL_CSFTRST_OFFSET 0 +#define DWC2_GRSTCTL_HSFTRST (1 << 1) +#define DWC2_GRSTCTL_HSFTRST_OFFSET 1 +#define DWC2_GRSTCTL_HSTFRM (1 << 2) +#define DWC2_GRSTCTL_HSTFRM_OFFSET 2 +#define DWC2_GRSTCTL_INTKNQFLSH (1 << 3) +#define DWC2_GRSTCTL_INTKNQFLSH_OFFSET 3 +#define DWC2_GRSTCTL_RXFFLSH (1 << 4) +#define DWC2_GRSTCTL_RXFFLSH_OFFSET 4 +#define DWC2_GRSTCTL_TXFFLSH (1 << 5) +#define DWC2_GRSTCTL_TXFFLSH_OFFSET 5 +#define DWC2_GRSTCTL_TXFNUM_MASK (0x1F << 6) +#define DWC2_GRSTCTL_TXFNUM_OFFSET 6 +#define DWC2_GRSTCTL_DMAREQ (1 << 30) +#define DWC2_GRSTCTL_DMAREQ_OFFSET 30 +#define DWC2_GRSTCTL_AHBIDLE (1 << 31) +#define DWC2_GRSTCTL_AHBIDLE_OFFSET 31 +#define DWC2_GINTMSK_MODEMISMATCH (1 << 1) +#define DWC2_GINTMSK_MODEMISMATCH_OFFSET 1 +#define DWC2_GINTMSK_OTGINTR (1 << 2) +#define DWC2_GINTMSK_OTGINTR_OFFSET 2 +#define DWC2_GINTMSK_SOFINTR (1 << 3) +#define DWC2_GINTMSK_SOFINTR_OFFSET 3 +#define DWC2_GINTMSK_RXSTSQLVL (1 << 4) +#define DWC2_GINTMSK_RXSTSQLVL_OFFSET 4 +#define DWC2_GINTMSK_NPTXFEMPTY (1 << 5) +#define DWC2_GINTMSK_NPTXFEMPTY_OFFSET 5 +#define DWC2_GINTMSK_GINNAKEFF (1 << 6) +#define DWC2_GINTMSK_GINNAKEFF_OFFSET 6 +#define DWC2_GINTMSK_GOUTNAKEFF (1 << 7) +#define DWC2_GINTMSK_GOUTNAKEFF_OFFSET 7 +#define DWC2_GINTMSK_I2CINTR (1 << 9) +#define DWC2_GINTMSK_I2CINTR_OFFSET 9 +#define DWC2_GINTMSK_ERLYSUSPEND (1 << 10) +#define DWC2_GINTMSK_ERLYSUSPEND_OFFSET 10 +#define DWC2_GINTMSK_USBSUSPEND (1 << 11) +#define DWC2_GINTMSK_USBSUSPEND_OFFSET 11 +#define DWC2_GINTMSK_USBRESET (1 << 12) +#define DWC2_GINTMSK_USBRESET_OFFSET 12 +#define DWC2_GINTMSK_ENUMDONE (1 << 13) +#define DWC2_GINTMSK_ENUMDONE_OFFSET 13 +#define DWC2_GINTMSK_ISOOUTDROP (1 << 14) +#define DWC2_GINTMSK_ISOOUTDROP_OFFSET 14 +#define DWC2_GINTMSK_EOPFRAME (1 << 15) +#define DWC2_GINTMSK_EOPFRAME_OFFSET 15 +#define DWC2_GINTMSK_EPMISMATCH (1 << 17) +#define DWC2_GINTMSK_EPMISMATCH_OFFSET 17 +#define DWC2_GINTMSK_INEPINTR (1 << 18) +#define DWC2_GINTMSK_INEPINTR_OFFSET 18 +#define DWC2_GINTMSK_OUTEPINTR (1 << 19) +#define DWC2_GINTMSK_OUTEPINTR_OFFSET 19 +#define DWC2_GINTMSK_INCOMPLISOIN (1 << 20) +#define DWC2_GINTMSK_INCOMPLISOIN_OFFSET 20 +#define DWC2_GINTMSK_INCOMPLISOOUT (1 << 21) +#define DWC2_GINTMSK_INCOMPLISOOUT_OFFSET 21 +#define DWC2_GINTMSK_PORTINTR (1 << 24) +#define DWC2_GINTMSK_PORTINTR_OFFSET 24 +#define DWC2_GINTMSK_HCINTR (1 << 25) +#define DWC2_GINTMSK_HCINTR_OFFSET 25 +#define DWC2_GINTMSK_PTXFEMPTY (1 << 26) +#define DWC2_GINTMSK_PTXFEMPTY_OFFSET 26 +#define DWC2_GINTMSK_LPMTRANRCVD (1 << 27) +#define DWC2_GINTMSK_LPMTRANRCVD_OFFSET 27 +#define DWC2_GINTMSK_CONIDSTSCHNG (1 << 28) +#define DWC2_GINTMSK_CONIDSTSCHNG_OFFSET 28 +#define DWC2_GINTMSK_DISCONNECT (1 << 29) +#define DWC2_GINTMSK_DISCONNECT_OFFSET 29 +#define DWC2_GINTMSK_SESSREQINTR (1 << 30) +#define DWC2_GINTMSK_SESSREQINTR_OFFSET 30 +#define DWC2_GINTMSK_WKUPINTR (1 << 31) +#define DWC2_GINTMSK_WKUPINTR_OFFSET 31 +#define DWC2_GINTSTS_CURMODE_DEVICE (0 << 0) +#define DWC2_GINTSTS_CURMODE_HOST (1 << 0) +#define DWC2_GINTSTS_CURMODE (1 << 0) +#define DWC2_GINTSTS_CURMODE_OFFSET 0 +#define DWC2_GINTSTS_MODEMISMATCH (1 << 1) +#define DWC2_GINTSTS_MODEMISMATCH_OFFSET 1 +#define DWC2_GINTSTS_OTGINTR (1 << 2) +#define DWC2_GINTSTS_OTGINTR_OFFSET 2 +#define DWC2_GINTSTS_SOFINTR (1 << 3) +#define DWC2_GINTSTS_SOFINTR_OFFSET 3 +#define DWC2_GINTSTS_RXSTSQLVL (1 << 4) +#define DWC2_GINTSTS_RXSTSQLVL_OFFSET 4 +#define DWC2_GINTSTS_NPTXFEMPTY (1 << 5) +#define DWC2_GINTSTS_NPTXFEMPTY_OFFSET 5 +#define DWC2_GINTSTS_GINNAKEFF (1 << 6) +#define DWC2_GINTSTS_GINNAKEFF_OFFSET 6 +#define DWC2_GINTSTS_GOUTNAKEFF (1 << 7) +#define DWC2_GINTSTS_GOUTNAKEFF_OFFSET 7 +#define DWC2_GINTSTS_I2CINTR (1 << 9) +#define DWC2_GINTSTS_I2CINTR_OFFSET 9 +#define DWC2_GINTSTS_ERLYSUSPEND (1 << 10) +#define DWC2_GINTSTS_ERLYSUSPEND_OFFSET 10 +#define DWC2_GINTSTS_USBSUSPEND (1 << 11) +#define DWC2_GINTSTS_USBSUSPEND_OFFSET 11 +#define DWC2_GINTSTS_USBRESET (1 << 12) +#define DWC2_GINTSTS_USBRESET_OFFSET 12 +#define DWC2_GINTSTS_ENUMDONE (1 << 13) +#define DWC2_GINTSTS_ENUMDONE_OFFSET 13 +#define DWC2_GINTSTS_ISOOUTDROP (1 << 14) +#define DWC2_GINTSTS_ISOOUTDROP_OFFSET 14 +#define DWC2_GINTSTS_EOPFRAME (1 << 15) +#define DWC2_GINTSTS_EOPFRAME_OFFSET 15 +#define DWC2_GINTSTS_INTOKENRX (1 << 16) +#define DWC2_GINTSTS_INTOKENRX_OFFSET 16 +#define DWC2_GINTSTS_EPMISMATCH (1 << 17) +#define DWC2_GINTSTS_EPMISMATCH_OFFSET 17 +#define DWC2_GINTSTS_INEPINT (1 << 18) +#define DWC2_GINTSTS_INEPINT_OFFSET 18 +#define DWC2_GINTSTS_OUTEPINTR (1 << 19) +#define DWC2_GINTSTS_OUTEPINTR_OFFSET 19 +#define DWC2_GINTSTS_INCOMPLISOIN (1 << 20) +#define DWC2_GINTSTS_INCOMPLISOIN_OFFSET 20 +#define DWC2_GINTSTS_INCOMPLISOOUT (1 << 21) +#define DWC2_GINTSTS_INCOMPLISOOUT_OFFSET 21 +#define DWC2_GINTSTS_PORTINTR (1 << 24) +#define DWC2_GINTSTS_PORTINTR_OFFSET 24 +#define DWC2_GINTSTS_HCINTR (1 << 25) +#define DWC2_GINTSTS_HCINTR_OFFSET 25 +#define DWC2_GINTSTS_PTXFEMPTY (1 << 26) +#define DWC2_GINTSTS_PTXFEMPTY_OFFSET 26 +#define DWC2_GINTSTS_LPMTRANRCVD (1 << 27) +#define DWC2_GINTSTS_LPMTRANRCVD_OFFSET 27 +#define DWC2_GINTSTS_CONIDSTSCHNG (1 << 28) +#define DWC2_GINTSTS_CONIDSTSCHNG_OFFSET 28 +#define DWC2_GINTSTS_DISCONNECT (1 << 29) +#define DWC2_GINTSTS_DISCONNECT_OFFSET 29 +#define DWC2_GINTSTS_SESSREQINTR (1 << 30) +#define DWC2_GINTSTS_SESSREQINTR_OFFSET 30 +#define DWC2_GINTSTS_WKUPINTR (1 << 31) +#define DWC2_GINTSTS_WKUPINTR_OFFSET 31 +#define DWC2_GRXSTS_EPNUM_MASK (0xF << 0) +#define DWC2_GRXSTS_EPNUM_OFFSET 0 +#define DWC2_GRXSTS_BCNT_MASK (0x7FF << 4) +#define DWC2_GRXSTS_BCNT_OFFSET 4 +#define DWC2_GRXSTS_DPID_MASK (0x3 << 15) +#define DWC2_GRXSTS_DPID_OFFSET 15 +#define DWC2_GRXSTS_PKTSTS_MASK (0xF << 17) +#define DWC2_GRXSTS_PKTSTS_OFFSET 17 +#define DWC2_GRXSTS_FN_MASK (0xF << 21) +#define DWC2_GRXSTS_FN_OFFSET 21 +#define DWC2_FIFOSIZE_STARTADDR_MASK (0xFFFF << 0) +#define DWC2_FIFOSIZE_STARTADDR_OFFSET 0 +#define DWC2_FIFOSIZE_DEPTH_MASK (0xFFFF << 16) +#define DWC2_FIFOSIZE_DEPTH_OFFSET 16 +#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_MASK (0xFFFF << 0) +#define DWC2_GNPTXSTS_NPTXFSPCAVAIL_OFFSET 0 +#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_MASK (0xFF << 16) +#define DWC2_GNPTXSTS_NPTXQSPCAVAIL_OFFSET 16 +#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE (1 << 24) +#define DWC2_GNPTXSTS_NPTXQTOP_TERMINATE_OFFSET 24 +#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_MASK (0x3 << 25) +#define DWC2_GNPTXSTS_NPTXQTOP_TOKEN_OFFSET 25 +#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_MASK (0xF << 27) +#define DWC2_GNPTXSTS_NPTXQTOP_CHNEP_OFFSET 27 +#define DWC2_DTXFSTS_TXFSPCAVAIL_MASK (0xFFFF << 0) +#define DWC2_DTXFSTS_TXFSPCAVAIL_OFFSET 0 +#define DWC2_GI2CCTL_RWDATA_MASK (0xFF << 0) +#define DWC2_GI2CCTL_RWDATA_OFFSET 0 +#define DWC2_GI2CCTL_REGADDR_MASK (0xFF << 8) +#define DWC2_GI2CCTL_REGADDR_OFFSET 8 +#define DWC2_GI2CCTL_ADDR_MASK (0x7F << 16) +#define DWC2_GI2CCTL_ADDR_OFFSET 16 +#define DWC2_GI2CCTL_I2CEN (1 << 23) +#define DWC2_GI2CCTL_I2CEN_OFFSET 23 +#define DWC2_GI2CCTL_ACK (1 << 24) +#define DWC2_GI2CCTL_ACK_OFFSET 24 +#define DWC2_GI2CCTL_I2CSUSPCTL (1 << 25) +#define DWC2_GI2CCTL_I2CSUSPCTL_OFFSET 25 +#define DWC2_GI2CCTL_I2CDEVADDR_MASK (0x3 << 26) +#define DWC2_GI2CCTL_I2CDEVADDR_OFFSET 26 +#define DWC2_GI2CCTL_RW (1 << 30) +#define DWC2_GI2CCTL_RW_OFFSET 30 +#define DWC2_GI2CCTL_BSYDNE (1 << 31) +#define DWC2_GI2CCTL_BSYDNE_OFFSET 31 +#define DWC2_HWCFG1_EP_DIR0_MASK (0x3 << 0) +#define DWC2_HWCFG1_EP_DIR0_OFFSET 0 +#define DWC2_HWCFG1_EP_DIR1_MASK (0x3 << 2) +#define DWC2_HWCFG1_EP_DIR1_OFFSET 2 +#define DWC2_HWCFG1_EP_DIR2_MASK (0x3 << 4) +#define DWC2_HWCFG1_EP_DIR2_OFFSET 4 +#define DWC2_HWCFG1_EP_DIR3_MASK (0x3 << 6) +#define DWC2_HWCFG1_EP_DIR3_OFFSET 6 +#define DWC2_HWCFG1_EP_DIR4_MASK (0x3 << 8) +#define DWC2_HWCFG1_EP_DIR4_OFFSET 8 +#define DWC2_HWCFG1_EP_DIR5_MASK (0x3 << 10) +#define DWC2_HWCFG1_EP_DIR5_OFFSET 10 +#define DWC2_HWCFG1_EP_DIR6_MASK (0x3 << 12) +#define DWC2_HWCFG1_EP_DIR6_OFFSET 12 +#define DWC2_HWCFG1_EP_DIR7_MASK (0x3 << 14) +#define DWC2_HWCFG1_EP_DIR7_OFFSET 14 +#define DWC2_HWCFG1_EP_DIR8_MASK (0x3 << 16) +#define DWC2_HWCFG1_EP_DIR8_OFFSET 16 +#define DWC2_HWCFG1_EP_DIR9_MASK (0x3 << 18) +#define DWC2_HWCFG1_EP_DIR9_OFFSET 18 +#define DWC2_HWCFG1_EP_DIR10_MASK (0x3 << 20) +#define DWC2_HWCFG1_EP_DIR10_OFFSET 20 +#define DWC2_HWCFG1_EP_DIR11_MASK (0x3 << 22) +#define DWC2_HWCFG1_EP_DIR11_OFFSET 22 +#define DWC2_HWCFG1_EP_DIR12_MASK (0x3 << 24) +#define DWC2_HWCFG1_EP_DIR12_OFFSET 24 +#define DWC2_HWCFG1_EP_DIR13_MASK (0x3 << 26) +#define DWC2_HWCFG1_EP_DIR13_OFFSET 26 +#define DWC2_HWCFG1_EP_DIR14_MASK (0x3 << 28) +#define DWC2_HWCFG1_EP_DIR14_OFFSET 28 +#define DWC2_HWCFG1_EP_DIR15_MASK (0x3 << 30) +#define DWC2_HWCFG1_EP_DIR15_OFFSET 30 +#define DWC2_HWCFG2_OP_MODE_MASK (0x7 << 0) +#define DWC2_HWCFG2_OP_MODE_OFFSET 0 +#define DWC2_HWCFG2_ARCHITECTURE_SLAVE_ONLY (0x0 << 3) +#define DWC2_HWCFG2_ARCHITECTURE_EXT_DMA (0x1 << 3) +#define DWC2_HWCFG2_ARCHITECTURE_INT_DMA (0x2 << 3) +#define DWC2_HWCFG2_ARCHITECTURE_MASK (0x3 << 3) +#define DWC2_HWCFG2_ARCHITECTURE_OFFSET 3 +#define DWC2_HWCFG2_POINT2POINT (1 << 5) +#define DWC2_HWCFG2_POINT2POINT_OFFSET 5 +#define DWC2_HWCFG2_HS_PHY_TYPE_MASK (0x3 << 6) +#define DWC2_HWCFG2_HS_PHY_TYPE_OFFSET 6 +#define DWC2_HWCFG2_FS_PHY_TYPE_MASK (0x3 << 8) +#define DWC2_HWCFG2_FS_PHY_TYPE_OFFSET 8 +#define DWC2_HWCFG2_NUM_DEV_EP_MASK (0xF << 10) +#define DWC2_HWCFG2_NUM_DEV_EP_OFFSET 10 +#define DWC2_HWCFG2_NUM_HOST_CHAN_MASK (0xF << 14) +#define DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET 14 +#define DWC2_HWCFG2_PERIO_EP_SUPPORTED (1 << 18) +#define DWC2_HWCFG2_PERIO_EP_SUPPORTED_OFFSET 18 +#define DWC2_HWCFG2_DYNAMIC_FIFO (1 << 19) +#define DWC2_HWCFG2_DYNAMIC_FIFO_OFFSET 19 +#define DWC2_HWCFG2_MULTI_PROC_INT (1 << 20) +#define DWC2_HWCFG2_MULTI_PROC_INT_OFFSET 20 +#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22) +#define DWC2_HWCFG2_NONPERIO_TX_Q_DEPTH_OFFSET 22 +#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24) +#define DWC2_HWCFG2_HOST_PERIO_TX_Q_DEPTH_OFFSET 24 +#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1F << 26) +#define DWC2_HWCFG2_DEV_TOKEN_Q_DEPTH_OFFSET 26 +#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xF << 0) +#define DWC2_HWCFG3_XFER_SIZE_CNTR_WIDTH_OFFSET 0 +#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4) +#define DWC2_HWCFG3_PACKET_SIZE_CNTR_WIDTH_OFFSET 4 +#define DWC2_HWCFG3_OTG_FUNC (1 << 7) +#define DWC2_HWCFG3_OTG_FUNC_OFFSET 7 +#define DWC2_HWCFG3_I2C (1 << 8) +#define DWC2_HWCFG3_I2C_OFFSET 8 +#define DWC2_HWCFG3_VENDOR_CTRL_IF (1 << 9) +#define DWC2_HWCFG3_VENDOR_CTRL_IF_OFFSET 9 +#define DWC2_HWCFG3_OPTIONAL_FEATURES (1 << 10) +#define DWC2_HWCFG3_OPTIONAL_FEATURES_OFFSET 10 +#define DWC2_HWCFG3_SYNCH_RESET_TYPE (1 << 11) +#define DWC2_HWCFG3_SYNCH_RESET_TYPE_OFFSET 11 +#define DWC2_HWCFG3_OTG_ENABLE_IC_USB (1 << 12) +#define DWC2_HWCFG3_OTG_ENABLE_IC_USB_OFFSET 12 +#define DWC2_HWCFG3_OTG_ENABLE_HSIC (1 << 13) +#define DWC2_HWCFG3_OTG_ENABLE_HSIC_OFFSET 13 +#define DWC2_HWCFG3_OTG_LPM_EN (1 << 15) +#define DWC2_HWCFG3_OTG_LPM_EN_OFFSET 15 +#define DWC2_HWCFG3_DFIFO_DEPTH_MASK (0xFFFF << 16) +#define DWC2_HWCFG3_DFIFO_DEPTH_OFFSET 16 +#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xF << 0) +#define DWC2_HWCFG4_NUM_DEV_PERIO_IN_EP_OFFSET 0 +#define DWC2_HWCFG4_POWER_OPTIMIZ (1 << 4) +#define DWC2_HWCFG4_POWER_OPTIMIZ_OFFSET 4 +#define DWC2_HWCFG4_MIN_AHB_FREQ_MASK (0x1FF << 5) +#define DWC2_HWCFG4_MIN_AHB_FREQ_OFFSET 5 +#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) +#define DWC2_HWCFG4_UTMI_PHY_DATA_WIDTH_OFFSET 14 +#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xF << 16) +#define DWC2_HWCFG4_NUM_DEV_MODE_CTRL_EP_OFFSET 16 +#define DWC2_HWCFG4_IDDIG_FILT_EN (1 << 20) +#define DWC2_HWCFG4_IDDIG_FILT_EN_OFFSET 20 +#define DWC2_HWCFG4_VBUS_VALID_FILT_EN (1 << 21) +#define DWC2_HWCFG4_VBUS_VALID_FILT_EN_OFFSET 21 +#define DWC2_HWCFG4_A_VALID_FILT_EN (1 << 22) +#define DWC2_HWCFG4_A_VALID_FILT_EN_OFFSET 22 +#define DWC2_HWCFG4_B_VALID_FILT_EN (1 << 23) +#define DWC2_HWCFG4_B_VALID_FILT_EN_OFFSET 23 +#define DWC2_HWCFG4_SESSION_END_FILT_EN (1 << 24) +#define DWC2_HWCFG4_SESSION_END_FILT_EN_OFFSET 24 +#define DWC2_HWCFG4_DED_FIFO_EN (1 << 25) +#define DWC2_HWCFG4_DED_FIFO_EN_OFFSET 25 +#define DWC2_HWCFG4_NUM_IN_EPS_MASK (0xF << 26) +#define DWC2_HWCFG4_NUM_IN_EPS_OFFSET 26 +#define DWC2_HWCFG4_DESC_DMA (1 << 30) +#define DWC2_HWCFG4_DESC_DMA_OFFSET 30 +#define DWC2_HWCFG4_DESC_DMA_DYN (1 << 31) +#define DWC2_HWCFG4_DESC_DMA_DYN_OFFSET 31 +#define DWC2_HCFG_FSLSPCLKSEL_30_60_MHZ 0 +#define DWC2_HCFG_FSLSPCLKSEL_48_MHZ 1 +#define DWC2_HCFG_FSLSPCLKSEL_6_MHZ 2 +#define DWC2_HCFG_FSLSPCLKSEL_MASK (0x3 << 0) +#define DWC2_HCFG_FSLSPCLKSEL_OFFSET 0 +#define DWC2_HCFG_FSLSSUPP (1 << 2) +#define DWC2_HCFG_FSLSSUPP_OFFSET 2 +#define DWC2_HCFG_DESCDMA (1 << 23) +#define DWC2_HCFG_DESCDMA_OFFSET 23 +#define DWC2_HCFG_FRLISTEN_MASK (0x3 << 24) +#define DWC2_HCFG_FRLISTEN_OFFSET 24 +#define DWC2_HCFG_PERSCHEDENA (1 << 26) +#define DWC2_HCFG_PERSCHEDENA_OFFSET 26 +#define DWC2_HCFG_PERSCHEDSTAT (1 << 27) +#define DWC2_HCFG_PERSCHEDSTAT_OFFSET 27 +#define DWC2_HFIR_FRINT_MASK (0xFFFF << 0) +#define DWC2_HFIR_FRINT_OFFSET 0 +#define DWC2_HFNUM_FRNUM_MASK (0xFFFF << 0) +#define DWC2_HFNUM_FRNUM_OFFSET 0 +#define DWC2_HFNUM_FRREM_MASK (0xFFFF << 16) +#define DWC2_HFNUM_FRREM_OFFSET 16 +#define DWC2_HPTXSTS_PTXFSPCAVAIL_MASK (0xFFFF << 0) +#define DWC2_HPTXSTS_PTXFSPCAVAIL_OFFSET 0 +#define DWC2_HPTXSTS_PTXQSPCAVAIL_MASK (0xFF << 16) +#define DWC2_HPTXSTS_PTXQSPCAVAIL_OFFSET 16 +#define DWC2_HPTXSTS_PTXQTOP_TERMINATE (1 << 24) +#define DWC2_HPTXSTS_PTXQTOP_TERMINATE_OFFSET 24 +#define DWC2_HPTXSTS_PTXQTOP_TOKEN_MASK (0x3 << 25) +#define DWC2_HPTXSTS_PTXQTOP_TOKEN_OFFSET 25 +#define DWC2_HPTXSTS_PTXQTOP_CHNUM_MASK (0xF << 27) +#define DWC2_HPTXSTS_PTXQTOP_CHNUM_OFFSET 27 +#define DWC2_HPTXSTS_PTXQTOP_ODD (1 << 31) +#define DWC2_HPTXSTS_PTXQTOP_ODD_OFFSET 31 +#define DWC2_HPRT0_PRTCONNSTS (1 << 0) +#define DWC2_HPRT0_PRTCONNSTS_OFFSET 0 +#define DWC2_HPRT0_PRTCONNDET (1 << 1) +#define DWC2_HPRT0_PRTCONNDET_OFFSET 1 +#define DWC2_HPRT0_PRTENA (1 << 2) +#define DWC2_HPRT0_PRTENA_OFFSET 2 +#define DWC2_HPRT0_PRTENCHNG (1 << 3) +#define DWC2_HPRT0_PRTENCHNG_OFFSET 3 +#define DWC2_HPRT0_PRTOVRCURRACT (1 << 4) +#define DWC2_HPRT0_PRTOVRCURRACT_OFFSET 4 +#define DWC2_HPRT0_PRTOVRCURRCHNG (1 << 5) +#define DWC2_HPRT0_PRTOVRCURRCHNG_OFFSET 5 +#define DWC2_HPRT0_PRTRES (1 << 6) +#define DWC2_HPRT0_PRTRES_OFFSET 6 +#define DWC2_HPRT0_PRTSUSP (1 << 7) +#define DWC2_HPRT0_PRTSUSP_OFFSET 7 +#define DWC2_HPRT0_PRTRST (1 << 8) +#define DWC2_HPRT0_PRTRST_OFFSET 8 +#define DWC2_HPRT0_PRTLNSTS_MASK (0x3 << 10) +#define DWC2_HPRT0_PRTLNSTS_OFFSET 10 +#define DWC2_HPRT0_PRTPWR (1 << 12) +#define DWC2_HPRT0_PRTPWR_OFFSET 12 +#define DWC2_HPRT0_PRTTSTCTL_MASK (0xF << 13) +#define DWC2_HPRT0_PRTTSTCTL_OFFSET 13 +#define DWC2_HPRT0_PRTSPD_MASK (0x3 << 17) +#define DWC2_HPRT0_PRTSPD_OFFSET 17 +#define DWC2_HAINT_CH0 (1 << 0) +#define DWC2_HAINT_CH0_OFFSET 0 +#define DWC2_HAINT_CH1 (1 << 1) +#define DWC2_HAINT_CH1_OFFSET 1 +#define DWC2_HAINT_CH2 (1 << 2) +#define DWC2_HAINT_CH2_OFFSET 2 +#define DWC2_HAINT_CH3 (1 << 3) +#define DWC2_HAINT_CH3_OFFSET 3 +#define DWC2_HAINT_CH4 (1 << 4) +#define DWC2_HAINT_CH4_OFFSET 4 +#define DWC2_HAINT_CH5 (1 << 5) +#define DWC2_HAINT_CH5_OFFSET 5 +#define DWC2_HAINT_CH6 (1 << 6) +#define DWC2_HAINT_CH6_OFFSET 6 +#define DWC2_HAINT_CH7 (1 << 7) +#define DWC2_HAINT_CH7_OFFSET 7 +#define DWC2_HAINT_CH8 (1 << 8) +#define DWC2_HAINT_CH8_OFFSET 8 +#define DWC2_HAINT_CH9 (1 << 9) +#define DWC2_HAINT_CH9_OFFSET 9 +#define DWC2_HAINT_CH10 (1 << 10) +#define DWC2_HAINT_CH10_OFFSET 10 +#define DWC2_HAINT_CH11 (1 << 11) +#define DWC2_HAINT_CH11_OFFSET 11 +#define DWC2_HAINT_CH12 (1 << 12) +#define DWC2_HAINT_CH12_OFFSET 12 +#define DWC2_HAINT_CH13 (1 << 13) +#define DWC2_HAINT_CH13_OFFSET 13 +#define DWC2_HAINT_CH14 (1 << 14) +#define DWC2_HAINT_CH14_OFFSET 14 +#define DWC2_HAINT_CH15 (1 << 15) +#define DWC2_HAINT_CH15_OFFSET 15 +#define DWC2_HAINT_CHINT_MASK 0xffff +#define DWC2_HAINT_CHINT_OFFSET 0 +#define DWC2_HAINTMSK_CH0 (1 << 0) +#define DWC2_HAINTMSK_CH0_OFFSET 0 +#define DWC2_HAINTMSK_CH1 (1 << 1) +#define DWC2_HAINTMSK_CH1_OFFSET 1 +#define DWC2_HAINTMSK_CH2 (1 << 2) +#define DWC2_HAINTMSK_CH2_OFFSET 2 +#define DWC2_HAINTMSK_CH3 (1 << 3) +#define DWC2_HAINTMSK_CH3_OFFSET 3 +#define DWC2_HAINTMSK_CH4 (1 << 4) +#define DWC2_HAINTMSK_CH4_OFFSET 4 +#define DWC2_HAINTMSK_CH5 (1 << 5) +#define DWC2_HAINTMSK_CH5_OFFSET 5 +#define DWC2_HAINTMSK_CH6 (1 << 6) +#define DWC2_HAINTMSK_CH6_OFFSET 6 +#define DWC2_HAINTMSK_CH7 (1 << 7) +#define DWC2_HAINTMSK_CH7_OFFSET 7 +#define DWC2_HAINTMSK_CH8 (1 << 8) +#define DWC2_HAINTMSK_CH8_OFFSET 8 +#define DWC2_HAINTMSK_CH9 (1 << 9) +#define DWC2_HAINTMSK_CH9_OFFSET 9 +#define DWC2_HAINTMSK_CH10 (1 << 10) +#define DWC2_HAINTMSK_CH10_OFFSET 10 +#define DWC2_HAINTMSK_CH11 (1 << 11) +#define DWC2_HAINTMSK_CH11_OFFSET 11 +#define DWC2_HAINTMSK_CH12 (1 << 12) +#define DWC2_HAINTMSK_CH12_OFFSET 12 +#define DWC2_HAINTMSK_CH13 (1 << 13) +#define DWC2_HAINTMSK_CH13_OFFSET 13 +#define DWC2_HAINTMSK_CH14 (1 << 14) +#define DWC2_HAINTMSK_CH14_OFFSET 14 +#define DWC2_HAINTMSK_CH15 (1 << 15) +#define DWC2_HAINTMSK_CH15_OFFSET 15 +#define DWC2_HAINTMSK_CHINT_MASK 0xffff +#define DWC2_HAINTMSK_CHINT_OFFSET 0 +#define DWC2_HCCHAR_MPS_MASK (0x7FF << 0) +#define DWC2_HCCHAR_MPS_OFFSET 0 +#define DWC2_HCCHAR_EPNUM_MASK (0xF << 11) +#define DWC2_HCCHAR_EPNUM_OFFSET 11 +#define DWC2_HCCHAR_EPDIR (1 << 15) +#define DWC2_HCCHAR_EPDIR_OFFSET 15 +#define DWC2_HCCHAR_LSPDDEV (1 << 17) +#define DWC2_HCCHAR_LSPDDEV_OFFSET 17 +#define DWC2_HCCHAR_EPTYPE_CONTROL 0 +#define DWC2_HCCHAR_EPTYPE_ISOC 1 +#define DWC2_HCCHAR_EPTYPE_BULK 2 +#define DWC2_HCCHAR_EPTYPE_INTR 3 +#define DWC2_HCCHAR_EPTYPE_MASK (0x3 << 18) +#define DWC2_HCCHAR_EPTYPE_OFFSET 18 +#define DWC2_HCCHAR_MULTICNT_MASK (0x3 << 20) +#define DWC2_HCCHAR_MULTICNT_OFFSET 20 +#define DWC2_HCCHAR_DEVADDR_MASK (0x7F << 22) +#define DWC2_HCCHAR_DEVADDR_OFFSET 22 +#define DWC2_HCCHAR_ODDFRM (1 << 29) +#define DWC2_HCCHAR_ODDFRM_OFFSET 29 +#define DWC2_HCCHAR_CHDIS (1 << 30) +#define DWC2_HCCHAR_CHDIS_OFFSET 30 +#define DWC2_HCCHAR_CHEN (1 << 31) +#define DWC2_HCCHAR_CHEN_OFFSET 31 +#define DWC2_HCSPLT_PRTADDR_MASK (0x7F << 0) +#define DWC2_HCSPLT_PRTADDR_OFFSET 0 +#define DWC2_HCSPLT_HUBADDR_MASK (0x7F << 7) +#define DWC2_HCSPLT_HUBADDR_OFFSET 7 +#define DWC2_HCSPLT_XACTPOS_MASK (0x3 << 14) +#define DWC2_HCSPLT_XACTPOS_OFFSET 14 +#define DWC2_HCSPLT_COMPSPLT (1 << 16) +#define DWC2_HCSPLT_COMPSPLT_OFFSET 16 +#define DWC2_HCSPLT_SPLTENA (1 << 31) +#define DWC2_HCSPLT_SPLTENA_OFFSET 31 +#define DWC2_HCINT_XFERCOMP (1 << 0) +#define DWC2_HCINT_XFERCOMP_OFFSET 0 +#define DWC2_HCINT_CHHLTD (1 << 1) +#define DWC2_HCINT_CHHLTD_OFFSET 1 +#define DWC2_HCINT_AHBERR (1 << 2) +#define DWC2_HCINT_AHBERR_OFFSET 2 +#define DWC2_HCINT_STALL (1 << 3) +#define DWC2_HCINT_STALL_OFFSET 3 +#define DWC2_HCINT_NAK (1 << 4) +#define DWC2_HCINT_NAK_OFFSET 4 +#define DWC2_HCINT_ACK (1 << 5) +#define DWC2_HCINT_ACK_OFFSET 5 +#define DWC2_HCINT_NYET (1 << 6) +#define DWC2_HCINT_NYET_OFFSET 6 +#define DWC2_HCINT_XACTERR (1 << 7) +#define DWC2_HCINT_XACTERR_OFFSET 7 +#define DWC2_HCINT_BBLERR (1 << 8) +#define DWC2_HCINT_BBLERR_OFFSET 8 +#define DWC2_HCINT_FRMOVRUN (1 << 9) +#define DWC2_HCINT_FRMOVRUN_OFFSET 9 +#define DWC2_HCINT_DATATGLERR (1 << 10) +#define DWC2_HCINT_DATATGLERR_OFFSET 10 +#define DWC2_HCINT_BNA (1 << 11) +#define DWC2_HCINT_BNA_OFFSET 11 +#define DWC2_HCINT_XCS_XACT (1 << 12) +#define DWC2_HCINT_XCS_XACT_OFFSET 12 +#define DWC2_HCINT_FRM_LIST_ROLL (1 << 13) +#define DWC2_HCINT_FRM_LIST_ROLL_OFFSET 13 +#define DWC2_HCINTMSK_XFERCOMPL (1 << 0) +#define DWC2_HCINTMSK_XFERCOMPL_OFFSET 0 +#define DWC2_HCINTMSK_CHHLTD (1 << 1) +#define DWC2_HCINTMSK_CHHLTD_OFFSET 1 +#define DWC2_HCINTMSK_AHBERR (1 << 2) +#define DWC2_HCINTMSK_AHBERR_OFFSET 2 +#define DWC2_HCINTMSK_STALL (1 << 3) +#define DWC2_HCINTMSK_STALL_OFFSET 3 +#define DWC2_HCINTMSK_NAK (1 << 4) +#define DWC2_HCINTMSK_NAK_OFFSET 4 +#define DWC2_HCINTMSK_ACK (1 << 5) +#define DWC2_HCINTMSK_ACK_OFFSET 5 +#define DWC2_HCINTMSK_NYET (1 << 6) +#define DWC2_HCINTMSK_NYET_OFFSET 6 +#define DWC2_HCINTMSK_XACTERR (1 << 7) +#define DWC2_HCINTMSK_XACTERR_OFFSET 7 +#define DWC2_HCINTMSK_BBLERR (1 << 8) +#define DWC2_HCINTMSK_BBLERR_OFFSET 8 +#define DWC2_HCINTMSK_FRMOVRUN (1 << 9) +#define DWC2_HCINTMSK_FRMOVRUN_OFFSET 9 +#define DWC2_HCINTMSK_DATATGLERR (1 << 10) +#define DWC2_HCINTMSK_DATATGLERR_OFFSET 10 +#define DWC2_HCINTMSK_BNA (1 << 11) +#define DWC2_HCINTMSK_BNA_OFFSET 11 +#define DWC2_HCINTMSK_XCS_XACT (1 << 12) +#define DWC2_HCINTMSK_XCS_XACT_OFFSET 12 +#define DWC2_HCINTMSK_FRM_LIST_ROLL (1 << 13) +#define DWC2_HCINTMSK_FRM_LIST_ROLL_OFFSET 13 +#define DWC2_HCTSIZ_XFERSIZE_MASK 0x7ffff +#define DWC2_HCTSIZ_XFERSIZE_OFFSET 0 +#define DWC2_HCTSIZ_SCHINFO_MASK 0xff +#define DWC2_HCTSIZ_SCHINFO_OFFSET 0 +#define DWC2_HCTSIZ_NTD_MASK (0xff << 8) +#define DWC2_HCTSIZ_NTD_OFFSET 8 +#define DWC2_HCTSIZ_PKTCNT_MASK (0x3ff << 19) +#define DWC2_HCTSIZ_PKTCNT_OFFSET 19 +#define DWC2_HCTSIZ_PID_MASK (0x3 << 29) +#define DWC2_HCTSIZ_PID_OFFSET 29 +#define DWC2_HCTSIZ_DOPNG (1 << 31) +#define DWC2_HCTSIZ_DOPNG_OFFSET 31 +#define DWC2_HCDMA_CTD_MASK (0xFF << 3) +#define DWC2_HCDMA_CTD_OFFSET 3 +#define DWC2_HCDMA_DMA_ADDR_MASK (0x1FFFFF << 11) +#define DWC2_HCDMA_DMA_ADDR_OFFSET 11 +#define DWC2_PCGCCTL_STOPPCLK (1 << 0) +#define DWC2_PCGCCTL_STOPPCLK_OFFSET 0 +#define DWC2_PCGCCTL_GATEHCLK (1 << 1) +#define DWC2_PCGCCTL_GATEHCLK_OFFSET 1 +#define DWC2_PCGCCTL_PWRCLMP (1 << 2) +#define DWC2_PCGCCTL_PWRCLMP_OFFSET 2 +#define DWC2_PCGCCTL_RSTPDWNMODULE (1 << 3) +#define DWC2_PCGCCTL_RSTPDWNMODULE_OFFSET 3 +#define DWC2_PCGCCTL_PHYSUSPENDED (1 << 4) +#define DWC2_PCGCCTL_PHYSUSPENDED_OFFSET 4 +#define DWC2_PCGCCTL_ENBL_SLEEP_GATING (1 << 5) +#define DWC2_PCGCCTL_ENBL_SLEEP_GATING_OFFSET 5 +#define DWC2_PCGCCTL_PHY_IN_SLEEP (1 << 6) +#define DWC2_PCGCCTL_PHY_IN_SLEEP_OFFSET 6 +#define DWC2_PCGCCTL_DEEP_SLEEP (1 << 7) +#define DWC2_PCGCCTL_DEEP_SLEEP_OFFSET 7 +#define DWC2_SNPSID_DEVID_VER_2xx (0x4f542 << 12) +#define DWC2_SNPSID_DEVID_MASK (0xfffff << 12) +#define DWC2_SNPSID_DEVID_OFFSET 12 + +/* Host controller specific */ +#define DWC2_HC_PID_DATA0 0 +#define DWC2_HC_PID_DATA2 1 +#define DWC2_HC_PID_DATA1 2 +#define DWC2_HC_PID_MDATA 3 +#define DWC2_HC_PID_SETUP 3 + +/* roothub.a masks */ +#define RH_A_NDP (0xff << 0) /* number of downstream ports */ +#define RH_A_PSM (1 << 8) /* power switching mode */ +#define RH_A_NPS (1 << 9) /* no power switching */ +#define RH_A_DT (1 << 10) /* device type (mbz) */ +#define RH_A_OCPM (1 << 11) /* over current protection mode */ +#define RH_A_NOCP (1 << 12) /* no over current protection */ +#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ + +/* roothub.b masks */ +#define RH_B_DR 0x0000ffff /* device removable flags */ +#define RH_B_PPCM 0xffff0000 /* port power control mask */ + +/* Default driver configuration */ +#define CONFIG_DWC2_DMA_ENABLE +#define CONFIG_DWC2_DMA_BURST_SIZE 32 /* DMA burst len */ +#undef CONFIG_DWC2_DFLT_SPEED_FULL /* Do not force DWC2 to FS */ +#define CONFIG_DWC2_ENABLE_DYNAMIC_FIFO /* Runtime FIFO size detect */ +#define CONFIG_DWC2_MAX_CHANNELS 16 /* Max # of EPs */ +#define CONFIG_DWC2_HOST_RX_FIFO_SIZE (516 + CONFIG_DWC2_MAX_CHANNELS) +#define CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE 0x100 /* nPeriodic TX FIFO */ +#define CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE 0x200 /* Periodic TX FIFO */ +#define CONFIG_DWC2_MAX_TRANSFER_SIZE 65535 +#define CONFIG_DWC2_MAX_PACKET_COUNT 511 + +#define DWC2_PHY_TYPE_FS 0 +#define DWC2_PHY_TYPE_UTMI 1 +#define DWC2_PHY_TYPE_ULPI 2 +#define CONFIG_DWC2_PHY_TYPE DWC2_PHY_TYPE_UTMI /* PHY type */ +#define CONFIG_DWC2_UTMI_WIDTH 8 /* UTMI bus width (8/16) */ + +#undef CONFIG_DWC2_PHY_ULPI_DDR /* ULPI PHY uses DDR mode */ +#define CONFIG_DWC2_PHY_ULPI_EXT_VBUS /* ULPI PHY controls VBUS */ +#undef CONFIG_DWC2_I2C_ENABLE /* Enable I2C */ +#undef CONFIG_DWC2_ULPI_FS_LS /* ULPI is FS/LS */ +#undef CONFIG_DWC2_TS_DLINE /* External DLine pulsing */ +#undef CONFIG_DWC2_THR_CTL /* Threshold control */ +#define CONFIG_DWC2_TX_THR_LENGTH 64 +#undef CONFIG_DWC2_IC_USB_CAP /* IC Cap */ + +#endif /* __DWC2_H__ */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6323c50..936d006 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -119,15 +119,12 @@ static struct descriptor { #define ehci_is_TDI() (0) #endif -int __ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) +__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) { return PORTSC_PSPD(reg); } -int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) - __attribute__((weak, alias("__ehci_get_port_speed"))); - -void __ehci_set_usbmode(int index) +__weak void ehci_set_usbmode(int index) { uint32_t tmp; uint32_t *reg_ptr; @@ -141,17 +138,11 @@ void __ehci_set_usbmode(int index) ehci_writel(reg_ptr, tmp); } -void ehci_set_usbmode(int index) - __attribute__((weak, alias("__ehci_set_usbmode"))); - -void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) +__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) { mdelay(50); } -void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg) - __attribute__((weak, alias("__ehci_powerup_fixup"))); - static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; @@ -1323,7 +1314,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) } /* Do not free buffers associated with QHs, they're owned by someone else */ -int +static int destroy_int_queue(struct usb_device *dev, struct int_queue *queue) { struct ehci_ctrl *ctrl = dev->controller; diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 9231927..6aa50cb 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -944,7 +944,7 @@ static void parse_putc(const char c) CURSOR_SET; } -void video_putc(struct stdio_dev *dev, const char c) +static void video_putc(struct stdio_dev *dev, const char c) { #ifdef CONFIG_CFB_CONSOLE_ANSI int i; @@ -1158,7 +1158,7 @@ void video_putc(struct stdio_dev *dev, const char c) flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE); } -void video_puts(struct stdio_dev *dev, const char *s) +static void video_puts(struct stdio_dev *dev, const char *s) { int count = strlen(s); @@ -1171,14 +1171,11 @@ void video_puts(struct stdio_dev *dev, const char *s) * video_set_lut() if they do not support 8 bpp format. * Implement weak default function instead. */ -void __video_set_lut(unsigned int index, unsigned char r, +__weak void video_set_lut(unsigned int index, unsigned char r, unsigned char g, unsigned char b) { } -void video_set_lut(unsigned int, unsigned char, unsigned char, unsigned char) - __attribute__ ((weak, alias("__video_set_lut"))); - #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) #define FILL_8BIT_332RGB(r,g,b) { \ @@ -2240,15 +2237,12 @@ static int video_init(void) * Implement a weak default function for boards that optionally * need to skip the video initialization. */ -int __board_video_skip(void) +__weak int board_video_skip(void) { /* As default, don't skip test */ return 0; } -int board_video_skip(void) - __attribute__ ((weak, alias("__board_video_skip"))); - int drv_video_init(void) { int skip_dev_init; diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index 180a3b4..be35b98 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -58,54 +58,38 @@ static void exynos_lcd_init(vidinfo_t *vid) lcd_set_flush_dcache(1); } -void __exynos_cfg_lcd_gpio(void) +__weak void exynos_cfg_lcd_gpio(void) { } -void exynos_cfg_lcd_gpio(void) - __attribute__((weak, alias("__exynos_cfg_lcd_gpio"))); -void __exynos_backlight_on(unsigned int onoff) +__weak void exynos_backlight_on(unsigned int onoff) { } -void exynos_backlight_on(unsigned int onoff) - __attribute__((weak, alias("__exynos_cfg_lcd_gpio"))); -void __exynos_reset_lcd(void) +__weak void exynos_reset_lcd(void) { } -void exynos_reset_lcd(void) - __attribute__((weak, alias("__exynos_reset_lcd"))); -void __exynos_lcd_power_on(void) +__weak void exynos_lcd_power_on(void) { } -void exynos_lcd_power_on(void) - __attribute__((weak, alias("__exynos_lcd_power_on"))); -void __exynos_cfg_ldo(void) +__weak void exynos_cfg_ldo(void) { } -void exynos_cfg_ldo(void) - __attribute__((weak, alias("__exynos_cfg_ldo"))); -void __exynos_enable_ldo(unsigned int onoff) +__weak void exynos_enable_ldo(unsigned int onoff) { } -void exynos_enable_ldo(unsigned int onoff) - __attribute__((weak, alias("__exynos_enable_ldo"))); -void __exynos_backlight_reset(void) +__weak void exynos_backlight_reset(void) { } -void exynos_backlight_reset(void) - __attribute__((weak, alias("__exynos_backlight_reset"))); -int __exynos_lcd_misc_init(vidinfo_t *vid) +__weak int exynos_lcd_misc_init(vidinfo_t *vid) { return 0; } -int exynos_lcd_misc_init(vidinfo_t *vid) - __attribute__((weak, alias("__exynos_lcd_misc_init"))); static void lcd_panel_on(vidinfo_t *vid) { diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c index 8d4e925..5873531 100644 --- a/drivers/video/ipu_common.c +++ b/drivers/video/ipu_common.c @@ -379,7 +379,7 @@ static struct clk pixel_clk[] = { /* * This function resets IPU */ -void ipu_reset(void) +static void ipu_reset(void) { u32 *reg; u32 value; diff --git a/drivers/video/ipu_disp.c b/drivers/video/ipu_disp.c index 48fee99..4faeafb 100644 --- a/drivers/video/ipu_disp.c +++ b/drivers/video/ipu_disp.c @@ -377,7 +377,7 @@ static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = { static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE; static int color_key_4rgb = 1; -void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param, +static void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param, unsigned char srm_mode_update) { u32 reg; @@ -605,17 +605,6 @@ void ipu_dc_uninit(int dc_chan) } } -int ipu_chan_is_interlaced(ipu_channel_t channel) -{ - if (channel == MEM_DC_SYNC) - return !!(__raw_readl(DC_WR_CH_CONF_1) & - DC_WR_CH_CONF_FIELD_MODE); - else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC)) - return !!(__raw_readl(DC_WR_CH_CONF_5) & - DC_WR_CH_CONF_FIELD_MODE); - return 0; -} - void ipu_dp_dc_enable(ipu_channel_t channel) { int di; @@ -782,7 +771,7 @@ void ipu_init_dc_mappings(void) ipu_dc_map_config(4, 2, 21, 0xFC); } -int ipu_pixfmt_to_map(uint32_t fmt) +static int ipu_pixfmt_to_map(uint32_t fmt) { switch (fmt) { case IPU_PIX_FMT_GENERIC: diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c index b20c19c..1fa9531 100644 --- a/drivers/video/mxc_ipuv3_fb.c +++ b/drivers/video/mxc_ipuv3_fb.c @@ -36,7 +36,7 @@ static struct fb_videomode const *gmode; static uint8_t gdisp; static uint32_t gpixfmt; -void fb_videomode_to_var(struct fb_var_screeninfo *var, +static void fb_videomode_to_var(struct fb_var_screeninfo *var, const struct fb_videomode *mode) { var->xres = mode->xres; diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 1ebb9c7..f81b51a 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -29,6 +29,9 @@ * Request a GPIO. This should be called before any of the other functions * are used on this GPIO. * + * Note: With driver model, the label is allocated so there is no need for + * the caller to preserve it. + * * @param gp GPIO number * @param label User label for this GPIO * @return 0 if ok, -1 on error @@ -80,7 +83,7 @@ int gpio_get_value(unsigned gpio); int gpio_set_value(unsigned gpio, int value); /* State of a GPIO, as reported by get_function() */ -enum { +enum gpio_func_t { GPIOF_INPUT = 0, GPIOF_OUTPUT, GPIOF_UNUSED, /* Not claimed */ @@ -93,6 +96,66 @@ enum { struct udevice; /** + * gpio_get_status() - get the current GPIO status as a string + * + * Obtain the current GPIO status as a string which can be presented to the + * user. A typical string is: + * + * "b4: in: 1 [x] sdmmc_cd" + * + * which means this is GPIO bank b, offset 4, currently set to input, current + * value 1, [x] means that it is requested and the owner is 'sdmmc_cd' + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @buf: Place to put string + * @buffsize: Size of string including \0 + */ +int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize); + +/** + * gpio_get_function() - get the current function for a GPIO pin + * + * Note this returns GPIOF_UNUSED if the GPIO is not requested. + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @namep: If non-NULL, this is set to the nane given when the GPIO + * was requested, or -1 if it has not been requested + * @return -ENODATA if the driver returned an unknown function, + * -ENODEV if the device is not active, -EINVAL if the offset is invalid. + * GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the + * function from enum gpio_func_t. + */ +int gpio_get_function(struct udevice *dev, int offset, const char **namep); + +/** + * gpio_get_raw_function() - get the current raw function for a GPIO pin + * + * Note this does not return GPIOF_UNUSED - it will always return the GPIO + * driver's view of a pin function, even if it is not correctly set up. + * + * @dev: Device to check + * @offset: Offset of device GPIO to check + * @namep: If non-NULL, this is set to the nane given when the GPIO + * was requested, or -1 if it has not been requested + * @return -ENODATA if the driver returned an unknown function, + * -ENODEV if the device is not active, -EINVAL if the offset is invalid. + * Otherwise returns the function from enum gpio_func_t. + */ +int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep); + +/** + * gpio_requestf() - request a GPIO using a format string for the owner + * + * This is a helper function for gpio_request(). It allows you to provide + * a printf()-format string for the GPIO owner. It calls gpio_request() with + * the string that is created + */ +int gpio_requestf(unsigned gpio, const char *fmt, ...) + __attribute__ ((format (__printf__, 2, 3))); + +/** * struct struct dm_gpio_ops - Driver model GPIO operations * * Refer to functions above for description. These function largely copy @@ -135,8 +198,6 @@ struct dm_gpio_ops { * @return current function - GPIOF_... */ int (*get_function)(struct udevice *dev, unsigned offset); - int (*get_state)(struct udevice *dev, unsigned offset, char *state, - int maxlen); }; /** @@ -157,11 +218,14 @@ struct dm_gpio_ops { * @gpio_base: Base GPIO number for this device. For the first active device * this will be 0; the numbering for others will follow sequentially so that * @gpio_base for device 1 will equal the number of GPIOs in device 0. + * @name: Array of pointers to the name for each GPIO in this bank. The + * value of the pointer will be NULL if the GPIO has not been claimed. */ struct gpio_dev_priv { const char *bank_name; unsigned gpio_count; unsigned gpio_base; + char **name; }; /* Access the GPIO operations for a device */ @@ -193,4 +257,6 @@ const char *gpio_get_bank_info(struct udevice *dev, int *offset_count); int gpio_lookup_name(const char *name, struct udevice **devp, unsigned int *offsetp, unsigned int *gpiop); +int name_to_gpio(const char *name); + #endif /* _ASM_GENERIC_GPIO_H_ */ diff --git a/include/bootm.h b/include/bootm.h index 694d6fc..b3d1a62 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -54,4 +54,6 @@ int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]); int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int states, bootm_headers_t *images, int boot_progress); +void arch_preboot_os(void); + #endif diff --git a/include/common.h b/include/common.h index d5020c8..bcf6c7e 100644 --- a/include/common.h +++ b/include/common.h @@ -636,13 +636,6 @@ struct stdio_dev; int serial_stub_getc(struct stdio_dev *sdev); int serial_stub_tstc(struct stdio_dev *sdev); -void _serial_setbrg (const int); -void _serial_putc (const char, const int); -void _serial_putc_raw(const char, const int); -void _serial_puts (const char *, const int); -int _serial_getc (const int); -int _serial_tstc (const int); - /* $(CPU)/speed.c */ int get_clocks (void); int get_clocks_866 (void); diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h index 200b744..4b90dc2 100644 --- a/include/configs/coreboot.h +++ b/include/configs/coreboot.h @@ -27,6 +27,11 @@ #define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_DISPLAY_BOARDINFO_LATE +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL + #define CONFIG_LMB #define CONFIG_OF_LIBFDT @@ -88,21 +93,16 @@ /*----------------------------------------------------------------------- * Serial Configuration */ -#define CONFIG_CONS_INDEX 1 +#define CONFIG_COREBOOT_SERIAL #define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE 1 -#define CONFIG_SYS_NS16550_CLK 1843200 -#define CONFIG_BAUDRATE 9600 +#define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {300, 600, 1200, 2400, 4800, \ 9600, 19200, 38400, 115200} -#define CONFIG_SYS_NS16550_COM1 UART0_BASE -#define CONFIG_SYS_NS16550_COM2 UART1_BASE #define CONFIG_SYS_NS16550_PORT_MAPPED -#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,eserial0\0" \ - "stdout=vga,eserial0,cbmem\0" \ - "stderr=vga,eserial0,cbmem\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ + "stdout=vga,serial,cbmem\0" \ + "stderr=vga,serial,cbmem\0" #define CONFIG_CONSOLE_MUX #define CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -256,7 +256,7 @@ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024) - +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE diff --git a/include/configs/ph1_ld4.h b/include/configs/ph1_ld4.h index a28d7b5..005a853 100644 --- a/include/configs/ph1_ld4.h +++ b/include/configs/ph1_ld4.h @@ -28,14 +28,10 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 36864000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 1 diff --git a/include/configs/ph1_pro4.h b/include/configs/ph1_pro4.h index b79967f..7dd6fd2 100644 --- a/include/configs/ph1_pro4.h +++ b/include/configs/ph1_pro4.h @@ -28,14 +28,10 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 73728000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 2 diff --git a/include/configs/ph1_sld8.h b/include/configs/ph1_sld8.h index 9d391f1..1062aac 100644 --- a/include/configs/ph1_sld8.h +++ b/include/configs/ph1_sld8.h @@ -28,14 +28,10 @@ * SoC UART : enable CONFIG_UNIPHIER_SERIAL * On-board UART: enable CONFIG_SYS_NS16550_SERIAL */ -#if 1 -#define CONFIG_UNIPHIER_SERIAL -#else +#if 0 #define CONFIG_SYS_NS16550_SERIAL #endif -#define CONFIG_SYS_UNIPHIER_UART_CLK 80000000 - #define CONFIG_SMC911X #define CONFIG_DDR_NUM_CH0 1 diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h index d9475e9..ca27f9a 100644 --- a/include/configs/rpi_b.h +++ b/include/configs/rpi_b.h @@ -82,6 +82,16 @@ #define CONFIG_MMC_SDHCI_IO_ACCESSORS #define CONFIG_BCM2835_SDHCI +#define CONFIG_CMD_USB +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_DWC2 +#define CONFIG_USB_DWC2_REG_ADDR 0x20980000 +#define CONFIG_USB_STORAGE +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_SMSC95XX +#define CONFIG_MISC_INIT_R +#endif + /* Console UART */ #define CONFIG_PL011_SERIAL #define CONFIG_PL011_CLOCK 3000000 @@ -129,13 +139,7 @@ /* Some things don't make sense on this HW or yet */ #undef CONFIG_CMD_FPGA -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_NFS #undef CONFIG_CMD_SAVEENV -#undef CONFIG_CMD_DHCP -#undef CONFIG_CMD_MII -#undef CONFIG_CMD_NET -#undef CONFIG_CMD_PING /* Environment */ #define ENV_DEVICE_SETTINGS \ @@ -176,7 +180,10 @@ "ramdisk_addr_r=0x02100000\0" \ #define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 0) + func(MMC, mmc, 0) \ + func(USB, usb, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) #include <config_distro_bootcmd.h> #define CONFIG_EXTRA_ENV_SETTINGS \ diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 80976e7..5ed86d9 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -19,12 +19,23 @@ #define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */ #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC +#ifndef CONFIG_SPL_BUILD +# define CONFIG_DM +# define CONFIG_CMD_DM +# define CONFIG_DM_GPIO +# define CONFIG_DM_SERIAL +# define CONFIG_OMAP_SERIAL +# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) +#endif + #include <asm/arch/omap.h> /* NS16550 Configuration */ #define CONFIG_SYS_NS16550 +#ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE (-4) +#endif #define CONFIG_SYS_NS16550_CLK 48000000 /* Network defines. */ diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h index 3b19d3d..3c634ee 100644 --- a/include/configs/ti_omap3_common.h +++ b/include/configs/ti_omap3_common.h @@ -18,6 +18,15 @@ #include <asm/arch/cpu.h> #include <asm/arch/omap3.h> +#ifndef CONFIG_SPL_BUILD +# define CONFIG_DM +# define CONFIG_CMD_DM +# define CONFIG_DM_GPIO +# define CONFIG_DM_SERIAL +# define CONFIG_OMAP_SERIAL +# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) +#endif + /* The chip has SDRC controller */ #define CONFIG_SDRC @@ -28,16 +37,20 @@ /* NS16550 Configuration */ #define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ #define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE (-4) -#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK +#ifdef CONFIG_SPL_BUILD +# define CONFIG_SYS_NS16550_SERIAL +# define CONFIG_SYS_NS16550_REG_SIZE (-4) +# define CONFIG_SYS_NS16550_CLK V_NS16550_CLK +#endif #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \ 115200} /* Select serial console configuration */ #define CONFIG_CONS_INDEX 3 +#ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 #define CONFIG_SERIAL3 3 +#endif /* Physical Memory Map */ #define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 diff --git a/include/configs/uniphier-common.h b/include/configs/uniphier-common.h index 18fe277..b18ae6d 100644 --- a/include/configs/uniphier-common.h +++ b/include/configs/uniphier-common.h @@ -33,18 +33,17 @@ are defined. Select only one of them." # define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000) #endif +#ifdef CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE #define CONFIG_SYS_NS16550_CLK 12288000 #define CONFIG_SYS_NS16550_REG_SIZE -2 +#endif #define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE #define CONFIG_SMC911X_32_BIT -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE0 0x54006800 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE1 0x54006900 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE2 0x54006a00 -#define CONFIG_SYS_UNIPHIER_SERIAL_BASE3 0x54006b00 +#define CONFIG_SYS_MALLOC_F_LEN 0x7000 /*----------------------------------------------------------------------- * MMU and Cache Setting diff --git a/include/dm/platform_data/serial-uniphier.h b/include/dm/platform_data/serial-uniphier.h new file mode 100644 index 0000000..52343e3 --- /dev/null +++ b/include/dm/platform_data/serial-uniphier.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PLAT_UNIPHIER_SERIAL_H +#define __PLAT_UNIPHIER_SERIAL_H + +#define DRIVER_NAME "uniphier-uart" + +struct uniphier_serial_platform_data { + unsigned long base; + unsigned int uartclk; +}; + +#endif /* __PLAT_UNIPHIER_SERIAL_H */ diff --git a/include/serial_mxc.h b/include/dm/platform_data/serial_mxc.h index 7d3ace2..7d3ace2 100644 --- a/include/serial_mxc.h +++ b/include/dm/platform_data/serial_mxc.h diff --git a/include/serial_pl01x.h b/include/dm/platform_data/serial_pl01x.h index 5e068f3..5e068f3 100644 --- a/include/serial_pl01x.h +++ b/include/dm/platform_data/serial_pl01x.h diff --git a/include/dm/test.h b/include/dm/test.h index 235d728..f08c05d 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -8,6 +8,7 @@ #define __DM_TEST_H #include <dm.h> +#include <malloc.h> /** * struct dm_test_cdata - configuration data for test instance @@ -120,6 +121,7 @@ struct dm_test_state { int force_fail_alloc; int skip_post_probe; struct udevice *removed; + struct mallinfo start; }; /* Test flags for each test */ @@ -178,6 +180,27 @@ int dm_check_operations(struct dm_test_state *dms, struct udevice *dev, int dm_check_devices(struct dm_test_state *dms, int num_devices); /** + * dm_leak_check_start() - Prepare to check for a memory leak + * + * Call this before allocating memory to record the amount of memory being + * used. + * + * @dms: Overall test state + */ +void dm_leak_check_start(struct dm_test_state *dms); + +/** + * dm_leak_check_end() - Check that no memory has leaked + * + * Call this after dm_leak_check_start() and after you have hopefuilly freed + * all the memory that was allocated. This function will print an error if + * it sees a different amount of total memory allocated than before. + * + * @dms: Overall test state + */int dm_leak_check_end(struct dm_test_state *dms); + + +/** * dm_test_main() - Run all the tests * * This runs all available driver model tests diff --git a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h b/include/dt-bindings/pinctrl/am33xx.h index 2fbc804..2fbc804 100644 --- a/arch/arm/dts/dt-bindings/pinctrl/am33xx.h +++ b/include/dt-bindings/pinctrl/am33xx.h diff --git a/arch/arm/dts/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h index edbd250..edbd250 100644 --- a/arch/arm/dts/dt-bindings/pinctrl/omap.h +++ b/include/dt-bindings/pinctrl/omap.h diff --git a/include/elf.h b/include/elf.h index b8ecc41..63d9341 100644 --- a/include/elf.h +++ b/include/elf.h @@ -570,4 +570,6 @@ unsigned long elf_hash(const unsigned char *name); that may still be in object files. */ #define R_PPC_TOC16 255 +int valid_elf_image(unsigned long addr); + #endif /* _ELF_H */ diff --git a/include/fdt_support.h b/include/fdt_support.h index c3d1fbc..55cef94 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -144,6 +144,8 @@ static inline u64 of_read_number(const fdt32_t *cell, int size) void of_bus_default_count_cells(void *blob, int parentoffset, int *addrc, int *sizec); +int ft_verify_fdt(void *fdt); +int arch_fixup_memory_node(void *blob); #endif /* ifdef CONFIG_OF_LIBFDT */ diff --git a/include/ide.h b/include/ide.h index c2a48e0..d5e05e9 100644 --- a/include/ide.h +++ b/include/ide.h @@ -23,6 +23,7 @@ extern ulong ide_bus_offset[]; #define LED_IDE2 0x02 #define DEVICE_LED(d) ((d & 2) | ((d & 2) == 0)) /* depends on bit positions! */ +void ide_led(uchar led, uchar status); #endif /* CONFIG_IDE_LED */ #ifdef CONFIG_SYS_64BIT_LBA diff --git a/include/linux/string.h b/include/linux/string.h index 8e44855..96348d6 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -20,6 +20,10 @@ extern __kernel_size_t strspn(const char *,const char *); */ #include <asm/string.h> +#ifndef __HAVE_ARCH_BCOPY +char *bcopy(const char *src, char *dest, int count); +#endif + #ifndef __HAVE_ARCH_STRCPY extern char * strcpy(char *,const char *); #endif @@ -89,6 +93,9 @@ extern void * memchr(const void *,int,__kernel_size_t); void *memchr_inv(const void *, int, size_t); #endif +unsigned long ustrtoul(const char *cp, char **endp, unsigned int base); +unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base); + #ifdef __cplusplus } #endif diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index 9f65ef9..075d222 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -14,6 +14,8 @@ #define __deprecated #endif +#include <linux/compat.h> + /* The USB role is defined by the connector used on the board, so long as * standards are being followed. (Developer boards sometimes won't.) */ diff --git a/include/mmc.h b/include/mmc.h index 7f5f9bc..d74a190 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -387,6 +387,7 @@ int mmc_legacy_init(int verbose); int board_mmc_init(bd_t *bis); int cpu_mmc_init(bd_t *bis); +int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); /* Set block count limit because of 16 bit register limit on some hardware*/ #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT diff --git a/include/ns16550.h b/include/ns16550.h index 5784cfd..0607379 100644 --- a/include/ns16550.h +++ b/include/ns16550.h @@ -53,7 +53,7 @@ * @clock: UART base clock speed in Hz */ struct ns16550_platdata { - unsigned char *base; + unsigned long base; int reg_shift; int clock; }; diff --git a/include/spl.h b/include/spl.h index a7e41da..cee251f 100644 --- a/include/spl.h +++ b/include/spl.h @@ -72,6 +72,8 @@ void spl_sata_load_image(void); int spl_load_image_fat(block_dev_desc_t *block_dev, int partition, const char *filename); int spl_load_image_fat_os(block_dev_desc_t *block_dev, int partition); +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image); + #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void); #endif diff --git a/include/usb.h b/include/usb.h index c355fbe..c4a288d 100644 --- a/include/usb.h +++ b/include/usb.h @@ -150,7 +150,8 @@ enum usb_init_type { defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \ defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \ defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \ - defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) + defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) || \ + defined(CONFIG_USB_DWC2) int usb_lowlevel_init(int index, enum usb_init_type init, void **controller); int usb_lowlevel_stop(int index); @@ -236,7 +236,7 @@ long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size) return lmb_add_region(_rgn, base, size); } -long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, +static long lmb_overlaps_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size) { unsigned long i; @@ -153,7 +153,7 @@ static void eth_current_changed(void) setenv("ethact", NULL); } -int eth_address_set(unsigned char *addr) +static int eth_address_set(unsigned char *addr) { return memcmp(addr, "\0\0\0\0\0\0", 6); } diff --git a/post/post.c b/post/post.c index 4af5355..4194edb 100644 --- a/post/post.c +++ b/post/post.c @@ -52,7 +52,7 @@ int post_init_f(void) * Boards with hotkey support can override this weak default function * by defining one in their board specific code. */ -int __post_hotkeys_pressed(void) +__weak int post_hotkeys_pressed(void) { #ifdef CONFIG_SYS_POST_HOTKEYS_GPIO int ret; @@ -73,9 +73,6 @@ int __post_hotkeys_pressed(void) return 0; /* No hotkeys supported */ } -int post_hotkeys_pressed(void) - __attribute__((weak, alias("__post_hotkeys_pressed"))); - void post_bootmode_init(void) { @@ -236,11 +233,9 @@ static void post_get_flags(int *test_flags) test_flags[j] |= POST_SLOWTEST; } -void __show_post_progress(unsigned int test_num, int before, int result) +__weak void show_post_progress(unsigned int test_num, int before, int result) { } -void show_post_progress(unsigned int, int, int) - __attribute__((weak, alias("__show_post_progress"))); static int post_run_single(struct post_test *test, int test_flags, int flags, unsigned int i) diff --git a/test/dm/core.c b/test/dm/core.c index b0cfb42..ff5c2a7 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -67,6 +67,34 @@ static struct driver_info driver_info_pre_reloc = { .platdata = &test_pdata_manual, }; +void dm_leak_check_start(struct dm_test_state *dms) +{ + dms->start = mallinfo(); + if (!dms->start.uordblks) + puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); +} + +int dm_leak_check_end(struct dm_test_state *dms) +{ + struct mallinfo end; + int id; + + /* Don't delete the root class, since we started with that */ + for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { + struct uclass *uc; + + uc = uclass_find(id); + if (!uc) + continue; + ut_assertok(uclass_destroy(uc)); + } + + end = mallinfo(); + ut_asserteq(dms->start.uordblks, end.uordblks); + + return 0; +} + /* Test that binding with platdata occurs correctly */ static int dm_test_autobind(struct dm_test_state *dms) { @@ -377,14 +405,11 @@ static int dm_test_leak(struct dm_test_state *dms) int i; for (i = 0; i < 2; i++) { - struct mallinfo start, end; struct udevice *dev; int ret; int id; - start = mallinfo(); - if (!start.uordblks) - puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n"); + dm_leak_check_start(dms); ut_assertok(dm_scan_platdata(false)); ut_assertok(dm_scan_fdt(gd->fdt_blob, false)); @@ -398,18 +423,7 @@ static int dm_test_leak(struct dm_test_state *dms) ut_assertok(ret); } - /* Don't delete the root class, since we started with that */ - for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) { - struct uclass *uc; - - uc = uclass_find(id); - if (!uc) - continue; - ut_assertok(uclass_destroy(uc)); - } - - end = mallinfo(); - ut_asserteq(start.uordblks, end.uordblks); + ut_assertok(dm_leak_check_end(dms)); } return 0; diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 2b2b0b5..94bd0d9 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -7,11 +7,14 @@ #include <common.h> #include <fdtdec.h> #include <dm.h> +#include <dm/root.h> #include <dm/ut.h> #include <dm/test.h> #include <dm/util.h> #include <asm/gpio.h> +DECLARE_GLOBAL_DATA_PTR; + /* Test that sandbox GPIOs work correctly */ static int dm_test_gpio(struct dm_test_state *dms) { @@ -39,52 +42,51 @@ static int dm_test_gpio(struct dm_test_state *dms) /* Get the operations for this device */ ops = gpio_get_ops(dev); - ut_assert(ops->get_state); + ut_assert(ops->get_function); /* Cannot get a value until it is reserved */ - ut_asserteq(-1, ops->get_value(dev, offset)); - + ut_asserteq(-EBUSY, gpio_get_value(gpio + 1)); /* * Now some tests that use the 'sandbox' back door. All GPIOs * should default to input, include b4 that we are using here. */ - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: in: 0 [ ]", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: input: 0 [ ]", buf); /* Change it to an output */ sandbox_gpio_set_direction(dev, offset, 1); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: out: 0 [ ]", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: output: 0 [ ]", buf); sandbox_gpio_set_value(dev, offset, 1); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: out: 1 [ ]", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: output: 1 [ ]", buf); - ut_assertok(ops->request(dev, offset, "testing")); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: out: 1 [x] testing", buf); + ut_assertok(gpio_request(gpio, "testing")); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: output: 1 [x] testing", buf); /* Change the value a bit */ ut_asserteq(1, ops->get_value(dev, offset)); ut_assertok(ops->set_value(dev, offset, 0)); ut_asserteq(0, ops->get_value(dev, offset)); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: out: 0 [x] testing", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: output: 0 [x] testing", buf); ut_assertok(ops->set_value(dev, offset, 1)); ut_asserteq(1, ops->get_value(dev, offset)); /* Make it an input */ ut_assertok(ops->direction_input(dev, offset)); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: in: 1 [x] testing", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: input: 1 [x] testing", buf); sandbox_gpio_set_value(dev, offset, 0); ut_asserteq(0, sandbox_gpio_get_value(dev, offset)); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: in: 0 [x] testing", buf); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: input: 0 [x] testing", buf); - ut_assertok(ops->free(dev, offset)); - ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf))); - ut_asserteq_str("b4: in: 0 [ ]", buf); + ut_assertok(gpio_free(gpio)); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b4: input: 0 [ ]", buf); /* Check the 'a' bank also */ ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio)); @@ -96,6 +98,18 @@ static int dm_test_gpio(struct dm_test_state *dms) ut_asserteq_str("a", name); ut_asserteq(20, offset_count); + return 0; +} +DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that sandbox anonymous GPIOs work correctly */ +static int dm_test_gpio_anon(struct dm_test_state *dms) +{ + unsigned int offset, gpio; + struct udevice *dev; + const char *name; + int offset_count; + /* And the anonymous bank */ ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio)); ut_asserteq_str(dev->name, "gpio_sandbox"); @@ -108,4 +122,57 @@ static int dm_test_gpio(struct dm_test_state *dms) return 0; } -DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +DM_TEST(dm_test_gpio_anon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that gpio_requestf() works as expected */ +static int dm_test_gpio_requestf(struct dm_test_state *dms) +{ + unsigned int offset, gpio; + struct udevice *dev; + char buf[80]; + + ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); + ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi")); + sandbox_gpio_set_direction(dev, offset, 1); + sandbox_gpio_set_value(dev, offset, 1); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf); + + return 0; +} +DM_TEST(dm_test_gpio_requestf, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that gpio_request() copies its string */ +static int dm_test_gpio_copy(struct dm_test_state *dms) +{ + unsigned int offset, gpio; + struct udevice *dev; + char buf[80], name[10]; + + ut_assertok(gpio_lookup_name("b6", &dev, &offset, &gpio)); + strcpy(name, "odd_name"); + ut_assertok(gpio_request(gpio, name)); + sandbox_gpio_set_direction(dev, offset, 1); + sandbox_gpio_set_value(dev, offset, 1); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b6: output: 1 [x] odd_name", buf); + strcpy(name, "nothing"); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b6: output: 1 [x] odd_name", buf); + + return 0; +} +DM_TEST(dm_test_gpio_copy, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we don't leak memory with GPIOs */ +static int dm_test_gpio_leak(struct dm_test_state *dms) +{ + ut_assertok(dm_test_gpio(dms)); + ut_assertok(dm_test_gpio_anon(dms)); + ut_assertok(dm_test_gpio_requestf(dms)); + ut_assertok(dm_leak_check_end(dms)); + + return 0; +} + +DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 94ce72a..90ca810 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -7,6 +7,7 @@ #include <common.h> #include <dm.h> #include <errno.h> +#include <malloc.h> #include <dm/test.h> #include <dm/root.h> #include <dm/uclass-internal.h> @@ -88,6 +89,7 @@ int dm_test_main(void) printf("Test: %s\n", test->name); ut_assertok(dm_test_init(dms)); + dms->start = mallinfo(); if (test->flags & DM_TESTF_SCAN_PDATA) ut_assertok(dm_scan_platdata(false)); if (test->flags & DM_TESTF_PROBE_TEST) |