Merge git://git.denx.de/u-boot-dm
Fix a trivial conflict over adding <dm.h> Conflicts: arch/arm/cpu/armv7/omap3/board.c Signed-off-by: Tom Rini <trini@ti.com>
This commit is contained in:
commit
84a6df09c7
@ -9,7 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ns16550.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
#include <asm/arch/cpu.h>
|
#include <asm/arch/cpu.h>
|
||||||
#include <asm/arch/hardware.h>
|
#include <asm/arch/hardware.h>
|
||||||
@ -36,6 +38,63 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
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[] = {
|
static const struct gpio_bank gpio_bank_am33xx[] = {
|
||||||
{ (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
|
{ (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX },
|
||||||
{ (void *)AM33XX_GPIO1_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;
|
const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
|
#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
|
||||||
int cpu_mmc_init(bd_t *bis)
|
int cpu_mmc_init(bd_t *bis)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <mmc.h>
|
#include <mmc.h>
|
||||||
#include <spl.h>
|
#include <spl.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -24,7 +25,7 @@
|
|||||||
#include <asm/arch/mem.h>
|
#include <asm/arch/mem.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/armv7.h>
|
#include <asm/armv7.h>
|
||||||
#include <asm/arch/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/omap_common.h>
|
#include <asm/omap_common.h>
|
||||||
#include <asm/arch/mmc_host_def.h>
|
#include <asm/arch/mmc_host_def.h>
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
@ -39,6 +40,27 @@ static void omap3_setup_aux_cr(void);
|
|||||||
static void omap3_invalidate_l2_cache_secure(void);
|
static void omap3_invalidate_l2_cache_secure(void);
|
||||||
#endif
|
#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] = {
|
static const struct gpio_bank gpio_bank_34xx[6] = {
|
||||||
{ (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
|
{ (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX },
|
||||||
{ (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
|
{ (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX },
|
||||||
@ -50,6 +72,8 @@ static const struct gpio_bank gpio_bank_34xx[6] = {
|
|||||||
|
|
||||||
const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
|
const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifdef CONFIG_SPL_BUILD
|
||||||
/*
|
/*
|
||||||
* We use static variables because global data is not ready yet.
|
* We use static variables because global data is not ready yet.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
||||||
|
obj-y += platdevice.o
|
||||||
obj-y += boot-mode.o
|
obj-y += boot-mode.o
|
||||||
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.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
|
sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
|
||||||
|
15
arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c
Normal file
15
arch/arm/cpu/armv7/uniphier/ph1-ld4/platdevice.c
Normal file
@ -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)
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
||||||
|
obj-y += platdevice.o
|
||||||
obj-y += boot-mode.o
|
obj-y += boot-mode.o
|
||||||
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \
|
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o sbc_init.o \
|
||||||
sg_init.o pll_init.o clkrst_init.o pinctrl.o
|
sg_init.o pll_init.o clkrst_init.o pinctrl.o
|
||||||
|
15
arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c
Normal file
15
arch/arm/cpu/armv7/uniphier/ph1-pro4/platdevice.c
Normal file
@ -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)
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
|
||||||
|
obj-y += platdevice.o
|
||||||
obj-y += boot-mode.o
|
obj-y += boot-mode.o
|
||||||
obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o bcu_init.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
|
sbc_init.o sg_init.o pll_init.o clkrst_init.o pinctrl.o
|
||||||
|
15
arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c
Normal file
15
arch/arm/cpu/armv7/uniphier/ph1-sld8/platdevice.c
Normal file
@ -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)
|
@ -10,6 +10,10 @@
|
|||||||
model = "TI AM335x BeagleBone";
|
model = "TI AM335x BeagleBone";
|
||||||
compatible = "ti,am335x-bone", "ti,am33xx";
|
compatible = "ti,am335x-bone", "ti,am33xx";
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = &uart0;
|
||||||
|
};
|
||||||
|
|
||||||
cpus {
|
cpus {
|
||||||
cpu@0 {
|
cpu@0 {
|
||||||
cpu0-supply = <&dcdc2_reg>;
|
cpu0-supply = <&dcdc2_reg>;
|
||||||
|
@ -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
|
|
24
arch/arm/include/asm/arch-uniphier/platdevice.h
Normal file
24
arch/arm/include/asm/arch-uniphier/platdevice.h
Normal file
@ -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 */
|
@ -23,6 +23,21 @@
|
|||||||
|
|
||||||
#include <asm/arch/cpu.h>
|
#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 {
|
struct gpio_bank {
|
||||||
void *base;
|
void *base;
|
||||||
int method;
|
int method;
|
||||||
@ -30,8 +45,6 @@ struct gpio_bank {
|
|||||||
|
|
||||||
extern const struct gpio_bank *const omap_gpio_bank;
|
extern const struct gpio_bank *const omap_gpio_bank;
|
||||||
|
|
||||||
#define METHOD_GPIO_24XX 4
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if gpio is valid.
|
* 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
|
* @return 1 if ok, 0 on error
|
||||||
*/
|
*/
|
||||||
int gpio_is_valid(int gpio);
|
int gpio_is_valid(int gpio);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _GPIO_H_ */
|
#endif /* _GPIO_H_ */
|
||||||
|
@ -85,12 +85,25 @@ car_init_ret:
|
|||||||
/* Align global data to 16-byte boundary */
|
/* Align global data to 16-byte boundary */
|
||||||
andl $0xfffffff0, %esp
|
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 */
|
/* Setup first parameter to setup_gdt */
|
||||||
movl %esp, %eax
|
movl %esp, %eax
|
||||||
|
|
||||||
/* Reserve space for global descriptor table */
|
/* Reserve space for global descriptor table */
|
||||||
subl $X86_GDT_SIZE, %esp
|
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 */
|
/* Align temporary global descriptor table to 16-byte boundary */
|
||||||
andl $0xfffffff0, %esp
|
andl $0xfffffff0, %esp
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
/include/ "skeleton.dtsi"
|
/include/ "skeleton.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
chosen {
|
||||||
console = "/serial";
|
stdout-path = "/serial";
|
||||||
};
|
};
|
||||||
|
|
||||||
serial {
|
serial {
|
||||||
compatible = "ns16550";
|
compatible = "coreboot-uart";
|
||||||
reg-shift = <1>;
|
reg = <0x3f8 0x10>;
|
||||||
|
reg-shift = <0>;
|
||||||
io-mapped = <1>;
|
io-mapped = <1>;
|
||||||
multiplier = <1>;
|
multiplier = <1>;
|
||||||
baudrate = <115200>;
|
baudrate = <115200>;
|
||||||
|
@ -12,7 +12,23 @@
|
|||||||
silent_console = <0>;
|
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 {
|
serial {
|
||||||
reg = <0x3f8 8>;
|
reg = <0x3f8 8>;
|
||||||
|
15
arch/x86/include/asm/arch-coreboot/gpio.h
Normal file
15
arch/x86/include/asm/arch-coreboot/gpio.h
Normal file
@ -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_ */
|
@ -6,6 +6,7 @@
|
|||||||
#ifndef _X86_GPIO_H_
|
#ifndef _X86_GPIO_H_
|
||||||
#define _X86_GPIO_H_
|
#define _X86_GPIO_H_
|
||||||
|
|
||||||
|
#include <asm/arch/gpio.h>
|
||||||
#include <asm-generic/gpio.h>
|
#include <asm-generic/gpio.h>
|
||||||
|
|
||||||
#endif /* _X86_GPIO_H_ */
|
#endif /* _X86_GPIO_H_ */
|
||||||
|
@ -18,14 +18,4 @@
|
|||||||
#define SYSCTLA 0x92
|
#define SYSCTLA 0x92
|
||||||
#define SLAVE_PIC 0xa0
|
#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
|
#endif
|
||||||
|
@ -282,7 +282,6 @@ void boot_zimage(void *setup_base, void *load_address)
|
|||||||
:: [kernel_entry]"a"(load_address),
|
:: [kernel_entry]"a"(load_address),
|
||||||
[boot_params] "S"(setup_base),
|
[boot_params] "S"(setup_base),
|
||||||
"b"(0), "D"(0)
|
"b"(0), "D"(0)
|
||||||
: "%ebp"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <netdev.h>
|
#include <netdev.h>
|
||||||
#include <fdt_support.h>
|
#include <fdt_support.h>
|
||||||
#include <sata.h>
|
#include <sata.h>
|
||||||
#include <serial_mxc.h>
|
|
||||||
#include <asm/arch/crm_regs.h>
|
#include <asm/arch/crm_regs.h>
|
||||||
#include <asm/arch/sys_proto.h>
|
#include <asm/arch/sys_proto.h>
|
||||||
#include <asm/arch/iomux.h>
|
#include <asm/arch/iomux.h>
|
||||||
@ -23,6 +22,7 @@
|
|||||||
#include <asm/imx-common/sata.h>
|
#include <asm/imx-common/sata.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
|
#include <dm/platform_data/serial_mxc.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "../common/eeprom.h"
|
#include "../common/eeprom.h"
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <ns16550.h>
|
||||||
#include <twl4030.h>
|
#include <twl4030.h>
|
||||||
#include <netdev.h>
|
#include <netdev.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
@ -30,6 +32,17 @@ static const u32 gpmc_lan_config[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
* Routine: board_init
|
||||||
* Description: Early hardware init.
|
* Description: Early hardware init.
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <ns16550.h>
|
||||||
#include <netdev.h>
|
#include <netdev.h>
|
||||||
#include <twl4030.h>
|
#include <twl4030.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@ -41,6 +43,17 @@ static const u32 gpmc_lab_enet[] = {
|
|||||||
/*CONF7- computed as params */
|
/*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
|
* Routine: board_init
|
||||||
* Description: Early hardware init.
|
* Description: Early hardware init.
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <ns16550.h>
|
||||||
#include <netdev.h>
|
#include <netdev.h>
|
||||||
#include <twl4030.h>
|
#include <twl4030.h>
|
||||||
#include <linux/mtd/nand.h>
|
#include <linux/mtd/nand.h>
|
||||||
@ -73,6 +75,17 @@ static const u32 gpmc_lan_config[] = {
|
|||||||
/*CONFIG7- computed as params */
|
/*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
|
* Routine: board_init
|
||||||
* Description: Early hardware init.
|
* Description: Early hardware init.
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <ns16550.h>
|
||||||
#ifdef CONFIG_STATUS_LED
|
#ifdef CONFIG_STATUS_LED
|
||||||
#include <status_led.h>
|
#include <status_led.h>
|
||||||
#endif
|
#endif
|
||||||
@ -70,6 +72,17 @@ static struct {
|
|||||||
char env_setting[64];
|
char env_setting[64];
|
||||||
} expansion_config;
|
} 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
|
* Routine: board_init
|
||||||
* Description: Early hardware init.
|
* Description: Early hardware init.
|
||||||
@ -103,22 +116,22 @@ int board_init(void)
|
|||||||
*/
|
*/
|
||||||
static int get_board_revision(void)
|
static int get_board_revision(void)
|
||||||
{
|
{
|
||||||
int revision;
|
static int revision = -1;
|
||||||
|
|
||||||
if (!gpio_request(171, "") &&
|
if (revision == -1) {
|
||||||
!gpio_request(172, "") &&
|
if (!gpio_request(171, "rev0") &&
|
||||||
!gpio_request(173, "")) {
|
!gpio_request(172, "rev1") &&
|
||||||
|
!gpio_request(173, "rev2")) {
|
||||||
|
gpio_direction_input(171);
|
||||||
|
gpio_direction_input(172);
|
||||||
|
gpio_direction_input(173);
|
||||||
|
|
||||||
gpio_direction_input(171);
|
revision = gpio_get_value(173) << 2 |
|
||||||
gpio_direction_input(172);
|
gpio_get_value(172) << 1 |
|
||||||
gpio_direction_input(173);
|
gpio_get_value(171);
|
||||||
|
} else {
|
||||||
revision = gpio_get_value(173) << 2 |
|
printf("Error: unable to acquire board revision GPIOs\n");
|
||||||
gpio_get_value(172) << 1 |
|
}
|
||||||
gpio_get_value(171);
|
|
||||||
} else {
|
|
||||||
printf("Error: unable to acquire board revision GPIOs\n");
|
|
||||||
revision = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return revision;
|
return revision;
|
||||||
@ -258,7 +271,7 @@ static void beagle_dvi_pup(void)
|
|||||||
case REVISION_AXBX:
|
case REVISION_AXBX:
|
||||||
case REVISION_CX:
|
case REVISION_CX:
|
||||||
case REVISION_C4:
|
case REVISION_C4:
|
||||||
gpio_request(170, "");
|
gpio_request(170, "dvi");
|
||||||
gpio_direction_output(170, 0);
|
gpio_direction_output(170, 0);
|
||||||
gpio_set_value(170, 1);
|
gpio_set_value(170, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -27,47 +27,46 @@ void green_led_on(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
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)
|
void __led_toggle (led_id_t mask)
|
||||||
{
|
{
|
||||||
int state, toggle_gpio = 0;
|
int state, toggle_gpio;
|
||||||
#ifdef STATUS_LED_BIT
|
|
||||||
if (!toggle_gpio && STATUS_LED_BIT & mask)
|
toggle_gpio = get_led_gpio(mask);
|
||||||
toggle_gpio = BEAGLE_LED_USR0;
|
|
||||||
#endif
|
|
||||||
#ifdef STATUS_LED_BIT1
|
|
||||||
if (!toggle_gpio && STATUS_LED_BIT1 & mask)
|
|
||||||
toggle_gpio = BEAGLE_LED_USR1;
|
|
||||||
#endif
|
|
||||||
if (toggle_gpio) {
|
if (toggle_gpio) {
|
||||||
if (!gpio_request(toggle_gpio, "")) {
|
state = gpio_get_value(toggle_gpio);
|
||||||
gpio_direction_output(toggle_gpio, 0);
|
gpio_direction_output(toggle_gpio, !state);
|
||||||
state = gpio_get_value(toggle_gpio);
|
|
||||||
gpio_set_value(toggle_gpio, !state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __led_set (led_id_t mask, int state)
|
void __led_set (led_id_t mask, int state)
|
||||||
{
|
{
|
||||||
#ifdef STATUS_LED_BIT
|
int toggle_gpio;
|
||||||
if (STATUS_LED_BIT & mask) {
|
|
||||||
if (!gpio_request(BEAGLE_LED_USR0, "")) {
|
toggle_gpio = get_led_gpio(mask);
|
||||||
gpio_direction_output(BEAGLE_LED_USR0, 0);
|
if (toggle_gpio)
|
||||||
gpio_set_value(BEAGLE_LED_USR0, state);
|
gpio_direction_output(toggle_gpio, 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
|
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,6 @@ enum gpio_cmd {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
|
#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() */
|
/* A few flags used by show_gpio() */
|
||||||
enum {
|
enum {
|
||||||
@ -40,22 +33,16 @@ enum {
|
|||||||
FLAG_SHOW_NEWLINE = 1 << 2,
|
FLAG_SHOW_NEWLINE = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void show_gpio(struct udevice *dev, const char *bank_name, int offset,
|
static void gpio_get_description(struct udevice *dev, const char *bank_name,
|
||||||
int *flagsp)
|
int offset, int *flagsp)
|
||||||
{
|
{
|
||||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
|
||||||
int func = GPIOF_UNKNOWN;
|
|
||||||
char buf[80];
|
char buf[80];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
|
ret = gpio_get_function(dev, offset, NULL);
|
||||||
|
if (ret < 0)
|
||||||
if (ops->get_function) {
|
goto err;
|
||||||
ret = ops->get_function(dev, offset);
|
if (!(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
|
||||||
if (ret >= 0 && ret < ARRAY_SIZE(gpio_function))
|
|
||||||
func = ret;
|
|
||||||
}
|
|
||||||
if (!(*flagsp & FLAG_SHOW_ALL) && func == GPIOF_UNUSED)
|
|
||||||
return;
|
return;
|
||||||
if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
|
if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
|
||||||
if (*flagsp & FLAG_SHOW_NEWLINE) {
|
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);
|
printf("Bank %s:\n", bank_name);
|
||||||
*flagsp &= ~FLAG_SHOW_BANK;
|
*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);
|
ret = gpio_get_status(dev, offset, buf, sizeof(buf));
|
||||||
puts("\n");
|
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)
|
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)
|
if (all)
|
||||||
flags |= FLAG_SHOW_ALL;
|
flags |= FLAG_SHOW_ALL;
|
||||||
bank_name = gpio_get_bank_info(dev, &num_bits);
|
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;
|
continue;
|
||||||
|
}
|
||||||
banklen = bank_name ? strlen(bank_name) : 0;
|
banklen = bank_name ? strlen(bank_name) : 0;
|
||||||
|
|
||||||
if (!gpio_name || !bank_name ||
|
if (!gpio_name || !bank_name ||
|
||||||
@ -113,11 +97,12 @@ static int do_gpio_status(bool all, const char *gpio_name)
|
|||||||
p = gpio_name + banklen;
|
p = gpio_name + banklen;
|
||||||
if (gpio_name && *p) {
|
if (gpio_name && *p) {
|
||||||
offset = simple_strtoul(p, NULL, 10);
|
offset = simple_strtoul(p, NULL, 10);
|
||||||
show_gpio(dev, bank_name, offset, &flags);
|
gpio_get_description(dev, bank_name, offset,
|
||||||
|
&flags);
|
||||||
} else {
|
} else {
|
||||||
for (offset = 0; offset < num_bits; offset++) {
|
for (offset = 0; offset < num_bits; offset++) {
|
||||||
show_gpio(dev, bank_name, offset,
|
gpio_get_description(dev, bank_name,
|
||||||
&flags);
|
offset, &flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
CONFIG_SPL=y
|
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_ARM=y
|
||||||
+S:CONFIG_TARGET_AM335X_EVM=y
|
+S:CONFIG_TARGET_AM335X_EVM=y
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
CONFIG_SPL=y
|
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_ARM=y
|
||||||
+S:CONFIG_TARGET_AM335X_EVM=y
|
+S:CONFIG_TARGET_AM335X_EVM=y
|
||||||
CONFIG_OF_CONTROL=y
|
CONFIG_OF_CONTROL=y
|
||||||
|
@ -2,7 +2,10 @@ CONFIG_SPL=y
|
|||||||
+S:CONFIG_ARM=y
|
+S:CONFIG_ARM=y
|
||||||
+S:CONFIG_ARCH_UNIPHIER=y
|
+S:CONFIG_ARCH_UNIPHIER=y
|
||||||
+S:CONFIG_MACH_PH1_LD4=y
|
+S:CONFIG_MACH_PH1_LD4=y
|
||||||
|
CONFIG_DM=y
|
||||||
CONFIG_NAND_DENALI=y
|
CONFIG_NAND_DENALI=y
|
||||||
CONFIG_SYS_NAND_DENALI_64BIT=y
|
CONFIG_SYS_NAND_DENALI_64BIT=y
|
||||||
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
||||||
|
CONFIG_DM_SERIAL=y
|
||||||
|
CONFIG_UNIPHIER_SERIAL=y
|
||||||
S:CONFIG_SPL_NAND_DENALI=y
|
S:CONFIG_SPL_NAND_DENALI=y
|
||||||
|
@ -2,7 +2,10 @@ CONFIG_SPL=y
|
|||||||
+S:CONFIG_ARM=y
|
+S:CONFIG_ARM=y
|
||||||
+S:CONFIG_ARCH_UNIPHIER=y
|
+S:CONFIG_ARCH_UNIPHIER=y
|
||||||
+S:CONFIG_MACH_PH1_PRO4=y
|
+S:CONFIG_MACH_PH1_PRO4=y
|
||||||
|
CONFIG_DM=y
|
||||||
CONFIG_NAND_DENALI=y
|
CONFIG_NAND_DENALI=y
|
||||||
CONFIG_SYS_NAND_DENALI_64BIT=y
|
CONFIG_SYS_NAND_DENALI_64BIT=y
|
||||||
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
||||||
|
CONFIG_DM_SERIAL=y
|
||||||
|
CONFIG_UNIPHIER_SERIAL=y
|
||||||
S:CONFIG_SPL_NAND_DENALI=y
|
S:CONFIG_SPL_NAND_DENALI=y
|
||||||
|
@ -2,7 +2,10 @@ CONFIG_SPL=y
|
|||||||
+S:CONFIG_ARM=y
|
+S:CONFIG_ARM=y
|
||||||
+S:CONFIG_ARCH_UNIPHIER=y
|
+S:CONFIG_ARCH_UNIPHIER=y
|
||||||
+S:CONFIG_MACH_PH1_SLD8=y
|
+S:CONFIG_MACH_PH1_SLD8=y
|
||||||
|
CONFIG_DM=y
|
||||||
CONFIG_NAND_DENALI=y
|
CONFIG_NAND_DENALI=y
|
||||||
CONFIG_SYS_NAND_DENALI_64BIT=y
|
CONFIG_SYS_NAND_DENALI_64BIT=y
|
||||||
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
|
||||||
|
CONFIG_DM_SERIAL=y
|
||||||
|
CONFIG_UNIPHIER_SERIAL=y
|
||||||
S:CONFIG_SPL_NAND_DENALI=y
|
S:CONFIG_SPL_NAND_DENALI=y
|
||||||
|
@ -95,7 +95,7 @@ are provided in test/dm. To run them, try:
|
|||||||
You should see something like this:
|
You should see something like this:
|
||||||
|
|
||||||
<...U-Boot banner...>
|
<...U-Boot banner...>
|
||||||
Running 22 driver model tests
|
Running 29 driver model tests
|
||||||
Test: dm_test_autobind
|
Test: dm_test_autobind
|
||||||
Test: dm_test_autoprobe
|
Test: dm_test_autoprobe
|
||||||
Test: dm_test_bus_children
|
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 'd-test': seq 3 is in use by 'b-test'
|
||||||
Device 'a-test': seq 0 is in use by 'd-test'
|
Device 'a-test': seq 0 is in use by 'd-test'
|
||||||
Test: dm_test_gpio
|
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_leak
|
||||||
Test: dm_test_lifecycle
|
Test: dm_test_lifecycle
|
||||||
Test: dm_test_operations
|
Test: dm_test_operations
|
||||||
@ -123,6 +128,26 @@ You should see something like this:
|
|||||||
Test: dm_test_platdata
|
Test: dm_test_platdata
|
||||||
Test: dm_test_pre_reloc
|
Test: dm_test_pre_reloc
|
||||||
Test: dm_test_remove
|
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
|
||||||
Test: dm_test_uclass_before_ready
|
Test: dm_test_uclass_before_ready
|
||||||
Failures: 0
|
Failures: 0
|
||||||
|
@ -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.
|
@ -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.
|
@ -11,67 +11,10 @@
|
|||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#define GPIO_NAME_SIZE 20
|
|
||||||
|
|
||||||
struct bcm2835_gpios {
|
struct bcm2835_gpios {
|
||||||
char label[BCM2835_GPIO_COUNT][GPIO_NAME_SIZE];
|
|
||||||
struct bcm2835_gpio_regs *reg;
|
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)
|
static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio)
|
||||||
{
|
{
|
||||||
struct bcm2835_gpios *gpios = dev_get_priv(dev);
|
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);
|
struct bcm2835_gpios *gpios = dev_get_priv(dev);
|
||||||
|
|
||||||
if (!gpio_is_requested(gpios, offset))
|
|
||||||
return GPIOF_UNUSED;
|
|
||||||
|
|
||||||
/* GPIOF_FUNC is not implemented yet */
|
/* GPIOF_FUNC is not implemented yet */
|
||||||
if (bcm2835_gpio_is_output(gpios, offset))
|
if (bcm2835_gpio_is_output(gpios, offset))
|
||||||
return GPIOF_OUTPUT;
|
return GPIOF_OUTPUT;
|
||||||
@ -152,42 +92,13 @@ static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset)
|
|||||||
return GPIOF_INPUT;
|
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 = {
|
static const struct dm_gpio_ops gpio_bcm2835_ops = {
|
||||||
.request = bcm2835_gpio_request,
|
|
||||||
.free = bcm2835_gpio_free,
|
|
||||||
.direction_input = bcm2835_gpio_direction_input,
|
.direction_input = bcm2835_gpio_direction_input,
|
||||||
.direction_output = bcm2835_gpio_direction_output,
|
.direction_output = bcm2835_gpio_direction_output,
|
||||||
.get_value = bcm2835_gpio_get_value,
|
.get_value = bcm2835_gpio_get_value,
|
||||||
.set_value = bcm2835_gpio_set_value,
|
.set_value = bcm2835_gpio_set_value,
|
||||||
.get_function = bcm2835_gpio_get_function,
|
.get_function = bcm2835_gpio_get_function,
|
||||||
.get_state = bcm2835_gpio_get_state,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bcm2835_gpio_probe(struct udevice *dev)
|
static int bcm2835_gpio_probe(struct udevice *dev)
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpio_to_device() - Convert global GPIO number to device, number
|
* 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,
|
int gpio_lookup_name(const char *name, struct udevice **devp,
|
||||||
unsigned int *offsetp, unsigned int *gpiop)
|
unsigned int *offsetp, unsigned int *gpiop)
|
||||||
{
|
{
|
||||||
struct gpio_dev_priv *uc_priv;
|
struct gpio_dev_priv *uc_priv = NULL;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
ulong offset;
|
||||||
|
int numeric;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (devp)
|
if (devp)
|
||||||
*devp = NULL;
|
*devp = NULL;
|
||||||
|
numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
|
||||||
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
|
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
|
||||||
dev;
|
dev;
|
||||||
ret = uclass_next_device(&dev)) {
|
ret = uclass_next_device(&dev)) {
|
||||||
ulong offset;
|
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
uc_priv = dev->uclass_priv;
|
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;
|
len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
|
||||||
|
|
||||||
if (!strncasecmp(name, uc_priv->bank_name, len)) {
|
if (!strncasecmp(name, uc_priv->bank_name, len)) {
|
||||||
if (strict_strtoul(name + len, 10, &offset))
|
if (!strict_strtoul(name + len, 10, &offset))
|
||||||
continue;
|
break;
|
||||||
if (devp)
|
|
||||||
*devp = dev;
|
|
||||||
if (offsetp)
|
|
||||||
*offsetp = offset;
|
|
||||||
if (gpiop)
|
|
||||||
*gpiop = uc_priv->gpio_base + offset;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
* gpio: GPIO number
|
||||||
* label: Name for the requested GPIO
|
* 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
|
* This function implements the API that's compatible with current
|
||||||
* GPIO API used in U-Boot. The request is forwarded to particular
|
* GPIO API used in U-Boot. The request is forwarded to particular
|
||||||
* GPIO driver. Returns 0 on success, negative value on error.
|
* GPIO driver. Returns 0 on success, negative value on error.
|
||||||
*/
|
*/
|
||||||
int gpio_request(unsigned gpio, const char *label)
|
int gpio_request(unsigned gpio, const char *label)
|
||||||
{
|
{
|
||||||
|
struct gpio_dev_priv *uc_priv;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
char *str;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = gpio_to_device(gpio, &dev, &offset);
|
ret = gpio_to_device(gpio, &dev, &offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!gpio_get_ops(dev)->request)
|
uc_priv = dev->uclass_priv;
|
||||||
return 0;
|
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 gpio_get_ops(dev)->request(dev, offset, label);
|
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];
|
||||||
|
|
||||||
|
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)
|
int gpio_free(unsigned gpio)
|
||||||
{
|
{
|
||||||
|
struct gpio_dev_priv *uc_priv;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
int ret;
|
int ret;
|
||||||
@ -117,9 +170,34 @@ int gpio_free(unsigned gpio)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!gpio_get_ops(dev)->free)
|
uc_priv = dev->uclass_priv;
|
||||||
return 0;
|
if (!uc_priv->name[offset])
|
||||||
return gpio_get_ops(dev)->free(dev, 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);
|
ret = gpio_to_device(gpio, &dev, &offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = gpio_to_device(gpio, &dev, &offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = gpio_to_device(gpio, &dev, &offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = gpio_to_device(gpio, &dev, &offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
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;
|
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 */
|
/* 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 gpio_dev_priv *uc_priv;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
@ -237,7 +406,7 @@ static int gpio_renumber(void)
|
|||||||
/* Ensure that we have a base for each bank */
|
/* Ensure that we have a base for each bank */
|
||||||
base = 0;
|
base = 0;
|
||||||
uclass_foreach_dev(dev, uc) {
|
uclass_foreach_dev(dev, uc) {
|
||||||
if (device_active(dev)) {
|
if (device_active(dev) && dev != removed_dev) {
|
||||||
uc_priv = dev->uclass_priv;
|
uc_priv = dev->uclass_priv;
|
||||||
uc_priv->gpio_base = base;
|
uc_priv->gpio_base = base;
|
||||||
base += uc_priv->gpio_count;
|
base += uc_priv->gpio_count;
|
||||||
@ -249,12 +418,27 @@ static int gpio_renumber(void)
|
|||||||
|
|
||||||
static int gpio_post_probe(struct udevice *dev)
|
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)
|
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) = {
|
UCLASS_DRIVER(gpio) = {
|
||||||
|
@ -27,88 +27,46 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#define GPIO_PER_BANK 32
|
||||||
|
|
||||||
/* Where in config space is the register that points to the GPIO registers? */
|
/* Where in config space is the register that points to the GPIO registers? */
|
||||||
#define PCI_CFG_GPIOBASE 0x48
|
#define PCI_CFG_GPIOBASE 0x48
|
||||||
|
|
||||||
#define NUM_BANKS 3
|
struct ich6_bank_priv {
|
||||||
|
/* These are I/O addresses */
|
||||||
/* Within the I/O space, where are the registers to control the GPIOs? */
|
uint32_t use_sel;
|
||||||
static struct {
|
uint32_t io_sel;
|
||||||
u8 use_sel;
|
uint32_t lvl;
|
||||||
u8 io_sel;
|
|
||||||
u8 lvl;
|
|
||||||
} gpio_bank[NUM_BANKS] = {
|
|
||||||
{ 0x00, 0x04, 0x0c }, /* Bank 0 */
|
|
||||||
{ 0x30, 0x34, 0x38 }, /* Bank 1 */
|
|
||||||
{ 0x40, 0x44, 0x48 } /* Bank 2 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static pci_dev_t dev; /* handle for 0:1f:0 */
|
static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
struct ich6_bank_platdata *plat = dev_get_platdata(dev);
|
||||||
|
pci_dev_t pci_dev; /* handle for 0:1f:0 */
|
||||||
u8 tmpbyte;
|
u8 tmpbyte;
|
||||||
u16 tmpword;
|
u16 tmpword;
|
||||||
u32 tmplong;
|
u32 tmplong;
|
||||||
|
u32 gpiobase;
|
||||||
/* Have we already done this? */
|
int offset;
|
||||||
if (found_it_once)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Where should it be? */
|
/* Where should it be? */
|
||||||
dev = PCI_BDF(0, 0x1f, 0);
|
pci_dev = PCI_BDF(0, 0x1f, 0);
|
||||||
|
|
||||||
/* Is the device present? */
|
/* 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) {
|
if (tmpword != PCI_VENDOR_ID_INTEL) {
|
||||||
debug("%s: wrong VendorID\n", __func__);
|
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);
|
debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
|
||||||
/*
|
/*
|
||||||
* We'd like to validate the Device ID too, but pretty much any
|
* 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). */
|
/* 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)) {
|
if (!(tmpword & PCI_COMMAND_IO)) {
|
||||||
debug("%s: device IO not enabled\n", __func__);
|
debug("%s: device IO not enabled\n", __func__);
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header Type must be normal (bits 6-0 only; see spec.) */
|
/* 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) {
|
if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
|
||||||
debug("%s: invalid Header type\n", __func__);
|
debug("%s: invalid Header type\n", __func__);
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Base Class must be a bridge device */
|
/* 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) {
|
if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
|
||||||
debug("%s: invalid class\n", __func__);
|
debug("%s: invalid class\n", __func__);
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
/* Sub Class must be ISA */
|
/* 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) {
|
if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
|
||||||
debug("%s: invalid subclass\n", __func__);
|
debug("%s: invalid subclass\n", __func__);
|
||||||
return -1;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Programming Interface must be 0x00 (no others exist) */
|
/* 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) {
|
if (tmpbyte != 0x00) {
|
||||||
debug("%s: invalid interface type\n", __func__);
|
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
|
* that it was unused (or undocumented). Check that it looks
|
||||||
* okay: not all ones or zeros, and mapped to I/O space (bit 0).
|
* 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 ||
|
if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
|
||||||
!(tmplong & 0x00000001)) {
|
!(tmplong & 0x00000001)) {
|
||||||
debug("%s: unexpected GPIOBASE value\n", __func__);
|
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.
|
* an I/O address, not a memory address, so mask that off.
|
||||||
*/
|
*/
|
||||||
gpiobase = tmplong & 0xfffffffe;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpio_request(unsigned num, const char *label /* UNUSED */)
|
int ich6_gpio_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ich6_gpio_request(struct udevice *dev, unsigned offset, const char *label)
|
||||||
|
{
|
||||||
|
struct ich6_bank_priv *bank = dev_get_priv(dev);
|
||||||
u32 tmplong;
|
u32 tmplong;
|
||||||
int i = 0, j = 0;
|
|
||||||
|
|
||||||
/* Is the hardware ready? */
|
|
||||||
if (gpio_init())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (bad_arg(num, &i, &j))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure that the GPIO pin we want isn't already in use for some
|
* 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
|
* built-in hardware function. We have to check this for every
|
||||||
* requested pin.
|
* requested pin.
|
||||||
*/
|
*/
|
||||||
tmplong = inl(gpiobase + gpio_bank[i].use_sel);
|
tmplong = inl(bank->use_sel);
|
||||||
if (!(tmplong & (1UL << j))) {
|
if (!(tmplong & (1UL << offset))) {
|
||||||
debug("%s: gpio %d is reserved for internal use\n", __func__,
|
debug("%s: gpio %d is reserved for internal use\n", __func__,
|
||||||
num);
|
offset);
|
||||||
return -1;
|
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;
|
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;
|
u32 tmplong;
|
||||||
int i = 0, j = 0;
|
|
||||||
|
|
||||||
if (notmine(num, &i, &j))
|
tmplong = inl(bank->io_sel);
|
||||||
return -1;
|
tmplong |= (1UL << offset);
|
||||||
|
outl(bank->io_sel, tmplong);
|
||||||
tmplong = inl(gpiobase + gpio_bank[i].io_sel);
|
|
||||||
tmplong |= (1UL << j);
|
|
||||||
outl(gpiobase + gpio_bank[i].io_sel, tmplong);
|
|
||||||
return 0;
|
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;
|
u32 tmplong;
|
||||||
int i = 0, j = 0;
|
|
||||||
|
|
||||||
if (notmine(num, &i, &j))
|
tmplong = inl(bank->io_sel);
|
||||||
return -1;
|
tmplong &= ~(1UL << offset);
|
||||||
|
outl(bank->io_sel, tmplong);
|
||||||
tmplong = inl(gpiobase + gpio_bank[i].io_sel);
|
|
||||||
tmplong &= ~(1UL << j);
|
|
||||||
outl(gpiobase + gpio_bank[i].io_sel, tmplong);
|
|
||||||
return 0;
|
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;
|
u32 tmplong;
|
||||||
int i = 0, j = 0;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (notmine(num, &i, &j))
|
tmplong = inl(bank->lvl);
|
||||||
return -1;
|
r = (tmplong & (1UL << offset)) ? 1 : 0;
|
||||||
|
|
||||||
tmplong = inl(gpiobase + gpio_bank[i].lvl);
|
|
||||||
r = (tmplong & (1UL << j)) ? 1 : 0;
|
|
||||||
return r;
|
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;
|
u32 tmplong;
|
||||||
int i = 0, j = 0;
|
|
||||||
|
|
||||||
if (notmine(num, &i, &j))
|
tmplong = inl(bank->lvl);
|
||||||
return -1;
|
|
||||||
|
|
||||||
tmplong = inl(gpiobase + gpio_bank[i].lvl);
|
|
||||||
if (value)
|
if (value)
|
||||||
tmplong |= (1UL << j);
|
tmplong |= (1UL << offset);
|
||||||
else
|
else
|
||||||
tmplong &= ~(1UL << j);
|
tmplong &= ~(1UL << offset);
|
||||||
outl(gpiobase + gpio_bank[i].lvl, tmplong);
|
outl(bank->lvl, tmplong);
|
||||||
return 0;
|
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),
|
||||||
|
};
|
||||||
|
@ -20,7 +20,6 @@ enum mxc_gpio_direction {
|
|||||||
MXC_GPIO_DIRECTION_OUT,
|
MXC_GPIO_DIRECTION_OUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GPIO_NAME_SIZE 20
|
|
||||||
#define GPIO_PER_BANK 32
|
#define GPIO_PER_BANK 32
|
||||||
|
|
||||||
struct mxc_gpio_plat {
|
struct mxc_gpio_plat {
|
||||||
@ -28,7 +27,6 @@ struct mxc_gpio_plat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mxc_bank_info {
|
struct mxc_bank_info {
|
||||||
char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
|
|
||||||
struct gpio_regs *regs;
|
struct gpio_regs *regs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -152,18 +150,6 @@ int gpio_direction_output(unsigned gpio, int value)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DM_GPIO
|
#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)
|
static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
|
||||||
{
|
{
|
||||||
u32 val;
|
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;
|
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 */
|
/* set GPIO pin 'gpio' as an input */
|
||||||
static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset)
|
static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct mxc_bank_info *bank = dev_get_priv(dev);
|
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. */
|
/* Configure GPIO direction as input. */
|
||||||
mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_IN);
|
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)
|
int value)
|
||||||
{
|
{
|
||||||
struct mxc_bank_info *bank = dev_get_priv(dev);
|
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. */
|
/* Configure GPIO output value. */
|
||||||
mxc_gpio_bank_set_value(bank->regs, offset, 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)
|
static int mxc_gpio_get_value(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct mxc_bank_info *bank = dev_get_priv(dev);
|
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);
|
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)
|
int value)
|
||||||
{
|
{
|
||||||
struct mxc_bank_info *bank = dev_get_priv(dev);
|
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);
|
mxc_gpio_bank_set_value(bank->regs, offset, value);
|
||||||
|
|
||||||
return 0;
|
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)
|
static int mxc_gpio_get_function(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct mxc_bank_info *bank = dev_get_priv(dev);
|
struct mxc_bank_info *bank = dev_get_priv(dev);
|
||||||
|
|
||||||
if (!gpio_is_requested(bank, offset))
|
|
||||||
return GPIOF_UNUSED;
|
|
||||||
|
|
||||||
/* GPIOF_FUNC is not implemented yet */
|
/* GPIOF_FUNC is not implemented yet */
|
||||||
if (mxc_gpio_is_output(bank->regs, offset))
|
if (mxc_gpio_is_output(bank->regs, offset))
|
||||||
return GPIOF_OUTPUT;
|
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 = {
|
static const struct dm_gpio_ops gpio_mxc_ops = {
|
||||||
.request = mxc_gpio_request,
|
|
||||||
.free = mxc_gpio_free,
|
|
||||||
.direction_input = mxc_gpio_direction_input,
|
.direction_input = mxc_gpio_direction_input,
|
||||||
.direction_output = mxc_gpio_direction_output,
|
.direction_output = mxc_gpio_direction_output,
|
||||||
.get_value = mxc_gpio_get_value,
|
.get_value = mxc_gpio_get_value,
|
||||||
.set_value = mxc_gpio_set_value,
|
.set_value = mxc_gpio_set_value,
|
||||||
.get_function = mxc_gpio_get_function,
|
.get_function = mxc_gpio_get_function,
|
||||||
.get_state = mxc_gpio_get_state,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mxc_gpio_plat mxc_plat[] = {
|
static const struct mxc_gpio_plat mxc_plat[] = {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
* Written by Juha Yrjölä <juha.yrjola@nokia.com>
|
* Written by Juha Yrjölä <juha.yrjola@nokia.com>
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
@ -26,10 +27,17 @@
|
|||||||
#define OMAP_GPIO_DIR_OUT 0
|
#define OMAP_GPIO_DIR_OUT 0
|
||||||
#define OMAP_GPIO_DIR_IN 1
|
#define OMAP_GPIO_DIR_IN 1
|
||||||
|
|
||||||
static inline const struct gpio_bank *get_gpio_bank(int gpio)
|
#ifdef CONFIG_DM_GPIO
|
||||||
{
|
|
||||||
return &omap_gpio_bank[gpio >> 5];
|
#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)
|
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);
|
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,
|
static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
|
||||||
int is_input)
|
int is_input)
|
||||||
{
|
{
|
||||||
@ -118,6 +117,48 @@ static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
|
|||||||
__raw_writel(l, reg);
|
__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
|
* Set value of the specified gpio
|
||||||
*/
|
*/
|
||||||
@ -139,32 +180,12 @@ int gpio_set_value(unsigned gpio, int value)
|
|||||||
int gpio_get_value(unsigned gpio)
|
int gpio_get_value(unsigned gpio)
|
||||||
{
|
{
|
||||||
const struct gpio_bank *bank;
|
const struct gpio_bank *bank;
|
||||||
void *reg;
|
|
||||||
int input;
|
|
||||||
|
|
||||||
if (check_gpio(gpio) < 0)
|
if (check_gpio(gpio) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
bank = get_gpio_bank(gpio);
|
bank = get_gpio_bank(gpio);
|
||||||
reg = bank->base;
|
|
||||||
switch (bank->method) {
|
return _get_gpio_value(bank, get_gpio_index(gpio));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,3 +241,95 @@ int gpio_free(unsigned gpio)
|
|||||||
{
|
{
|
||||||
return 0;
|
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 */
|
||||||
|
@ -33,8 +33,6 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
#define RATE_MASK(gpio) (0x1 << (gpio + 16))
|
#define RATE_MASK(gpio) (0x1 << (gpio + 16))
|
||||||
#define RATE_SET(gpio) (0x1 << (gpio + 16))
|
#define RATE_SET(gpio) (0x1 << (gpio + 16))
|
||||||
|
|
||||||
#define GPIO_NAME_SIZE 20
|
|
||||||
|
|
||||||
/* Platform data for each bank */
|
/* Platform data for each bank */
|
||||||
struct exynos_gpio_platdata {
|
struct exynos_gpio_platdata {
|
||||||
struct s5p_gpio_bank *bank;
|
struct s5p_gpio_bank *bank;
|
||||||
@ -43,7 +41,6 @@ struct exynos_gpio_platdata {
|
|||||||
|
|
||||||
/* Information about each bank at run-time */
|
/* Information about each bank at run-time */
|
||||||
struct exynos_bank_info {
|
struct exynos_bank_info {
|
||||||
char label[GPIO_PER_BANK][GPIO_NAME_SIZE];
|
|
||||||
struct s5p_gpio_bank *bank;
|
struct s5p_gpio_bank *bank;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -189,61 +186,10 @@ int s5p_gpio_get_pin(unsigned gpio)
|
|||||||
|
|
||||||
/* Driver model interface */
|
/* Driver model interface */
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#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 */
|
/* set GPIO pin 'gpio' as an input */
|
||||||
static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset)
|
static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct exynos_bank_info *state = dev_get_priv(dev);
|
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. */
|
/* Configure GPIO direction as input. */
|
||||||
s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_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)
|
int value)
|
||||||
{
|
{
|
||||||
struct exynos_bank_info *state = dev_get_priv(dev);
|
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. */
|
/* Configure GPIO output value. */
|
||||||
s5p_gpio_set_value(state->bank, offset, 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)
|
static int exynos_gpio_get_value(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct exynos_bank_info *state = dev_get_priv(dev);
|
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);
|
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)
|
int value)
|
||||||
{
|
{
|
||||||
struct exynos_bank_info *state = dev_get_priv(dev);
|
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);
|
s5p_gpio_set_value(state->bank, offset, value);
|
||||||
|
|
||||||
return 0;
|
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 */
|
#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);
|
struct exynos_bank_info *state = dev_get_priv(dev);
|
||||||
int cfg;
|
int cfg;
|
||||||
|
|
||||||
if (!*state->label[offset])
|
|
||||||
return GPIOF_UNUSED;
|
|
||||||
cfg = s5p_gpio_get_cfg_pin(state->bank, offset);
|
cfg = s5p_gpio_get_cfg_pin(state->bank, offset);
|
||||||
if (cfg == S5P_GPIO_OUTPUT)
|
if (cfg == S5P_GPIO_OUTPUT)
|
||||||
return GPIOF_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 = {
|
static const struct dm_gpio_ops gpio_exynos_ops = {
|
||||||
.request = exynos_gpio_request,
|
|
||||||
.free = exynos_gpio_free,
|
|
||||||
.direction_input = exynos_gpio_direction_input,
|
.direction_input = exynos_gpio_direction_input,
|
||||||
.direction_output = exynos_gpio_direction_output,
|
.direction_output = exynos_gpio_direction_output,
|
||||||
.get_value = exynos_gpio_get_value,
|
.get_value = exynos_gpio_get_value,
|
||||||
.set_value = exynos_gpio_set_value,
|
.set_value = exynos_gpio_set_value,
|
||||||
.get_function = exynos_gpio_get_function,
|
.get_function = exynos_gpio_get_function,
|
||||||
.get_state = exynos_gpio_get_state,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gpio_exynos_probe(struct udevice *dev)
|
static int gpio_exynos_probe(struct udevice *dev)
|
||||||
|
@ -14,7 +14,6 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
/* Flags for each GPIO */
|
/* Flags for each GPIO */
|
||||||
#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
|
#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
|
||||||
#define GPIOF_HIGH (1 << 1) /* Currently set high */
|
#define GPIOF_HIGH (1 << 1) /* Currently set high */
|
||||||
#define GPIOF_RESERVED (1 << 2) /* Is in use / requested */
|
|
||||||
|
|
||||||
struct gpio_state {
|
struct gpio_state {
|
||||||
const char *label; /* label given by requester */
|
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;
|
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
|
* 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);
|
debug("%s: offset:%u\n", __func__, offset);
|
||||||
|
|
||||||
if (check_reserved(dev, offset, __func__))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return sandbox_gpio_set_direction(dev, offset, 0);
|
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);
|
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) |
|
return sandbox_gpio_set_direction(dev, offset, 1) |
|
||||||
sandbox_gpio_set_value(dev, offset, value);
|
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);
|
debug("%s: offset:%u\n", __func__, offset);
|
||||||
|
|
||||||
if (check_reserved(dev, offset, __func__))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return sandbox_gpio_get_value(dev, offset);
|
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);
|
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)) {
|
if (!sandbox_gpio_get_direction(dev, offset)) {
|
||||||
printf("sandbox_gpio: error: set_value on input gpio %u\n",
|
printf("sandbox_gpio: error: set_value on input gpio %u\n",
|
||||||
offset);
|
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);
|
return sandbox_gpio_set_value(dev, offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sb_gpio_request(struct udevice *dev, unsigned offset,
|
static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
|
||||||
const char *label)
|
|
||||||
{
|
{
|
||||||
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
|
if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
|
||||||
struct gpio_state *state = dev_get_priv(dev);
|
return GPIOF_OUTPUT;
|
||||||
|
return GPIOF_INPUT;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dm_gpio_ops gpio_sandbox_ops = {
|
static const struct dm_gpio_ops gpio_sandbox_ops = {
|
||||||
.request = sb_gpio_request,
|
|
||||||
.free = sb_gpio_free,
|
|
||||||
.direction_input = sb_gpio_direction_input,
|
.direction_input = sb_gpio_direction_input,
|
||||||
.direction_output = sb_gpio_direction_output,
|
.direction_output = sb_gpio_direction_output,
|
||||||
.get_value = sb_gpio_get_value,
|
.get_value = sb_gpio_get_value,
|
||||||
.set_value = sb_gpio_set_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)
|
static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
|
||||||
@ -239,6 +164,13 @@ static int gpio_sandbox_probe(struct udevice *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gpio_sandbox_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
free(dev->priv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct udevice_id sandbox_gpio_ids[] = {
|
static const struct udevice_id sandbox_gpio_ids[] = {
|
||||||
{ .compatible = "sandbox,gpio" },
|
{ .compatible = "sandbox,gpio" },
|
||||||
{ }
|
{ }
|
||||||
@ -250,5 +182,6 @@ U_BOOT_DRIVER(gpio_sandbox) = {
|
|||||||
.of_match = sandbox_gpio_ids,
|
.of_match = sandbox_gpio_ids,
|
||||||
.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
|
.ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
|
||||||
.probe = gpio_sandbox_probe,
|
.probe = gpio_sandbox_probe,
|
||||||
|
.remove = gpio_sandbox_remove,
|
||||||
.ops = &gpio_sandbox_ops,
|
.ops = &gpio_sandbox_ops,
|
||||||
};
|
};
|
||||||
|
@ -39,7 +39,6 @@ struct tegra_gpio_platdata {
|
|||||||
|
|
||||||
/* Information about each port at run-time */
|
/* Information about each port at run-time */
|
||||||
struct tegra_port_info {
|
struct tegra_port_info {
|
||||||
char label[TEGRA_GPIOS_PER_PORT][GPIO_NAME_SIZE];
|
|
||||||
struct gpio_ctlr_bank *bank;
|
struct gpio_ctlr_bank *bank;
|
||||||
int base_gpio; /* Port number for this port (0, 1,.., n-1) */
|
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)]);
|
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' */
|
/* set GPIO pin 'gpio' as an output, with polarity 'value' */
|
||||||
int tegra_spl_gpio_direction_output(int gpio, int 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);
|
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 */
|
/* Configure as a GPIO */
|
||||||
set_config(state->base_gpio + offset, 1);
|
set_config(state->base_gpio + offset, 1);
|
||||||
|
|
||||||
return 0;
|
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 */
|
/* set GPIO pin 'gpio' as an input */
|
||||||
static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
|
static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
|
||||||
{
|
{
|
||||||
struct tegra_port_info *state = dev_get_priv(dev);
|
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. */
|
/* Configure GPIO direction as input. */
|
||||||
set_direction(state->base_gpio + offset, 0);
|
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);
|
struct tegra_port_info *state = dev_get_priv(dev);
|
||||||
int gpio = state->base_gpio + offset;
|
int gpio = state->base_gpio + offset;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = check_reserved(dev, offset, __func__);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Configure GPIO output value. */
|
/* Configure GPIO output value. */
|
||||||
set_level(gpio, 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);
|
struct tegra_port_info *state = dev_get_priv(dev);
|
||||||
int gpio = state->base_gpio + offset;
|
int gpio = state->base_gpio + offset;
|
||||||
int ret;
|
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
ret = check_reserved(dev, offset, __func__);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
debug("%s: pin = %d (port %d:bit %d)\n", __func__,
|
debug("%s: pin = %d (port %d:bit %d)\n", __func__,
|
||||||
gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
|
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);
|
struct tegra_port_info *state = dev_get_priv(dev);
|
||||||
int gpio = state->base_gpio + offset;
|
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",
|
debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
|
||||||
gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
|
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);
|
struct tegra_port_info *state = dev_get_priv(dev);
|
||||||
int gpio = state->base_gpio + offset;
|
int gpio = state->base_gpio + offset;
|
||||||
|
|
||||||
if (!*state->label[offset])
|
|
||||||
return GPIOF_UNUSED;
|
|
||||||
if (!get_config(gpio))
|
if (!get_config(gpio))
|
||||||
return GPIOF_FUNC;
|
return GPIOF_FUNC;
|
||||||
else if (get_direction(gpio))
|
else if (get_direction(gpio))
|
||||||
@ -327,50 +251,13 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
|
|||||||
return GPIOF_INPUT;
|
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 = {
|
static const struct dm_gpio_ops gpio_tegra_ops = {
|
||||||
.request = tegra_gpio_request,
|
.request = tegra_gpio_request,
|
||||||
.free = tegra_gpio_free,
|
|
||||||
.direction_input = tegra_gpio_direction_input,
|
.direction_input = tegra_gpio_direction_input,
|
||||||
.direction_output = tegra_gpio_direction_output,
|
.direction_output = tegra_gpio_direction_output,
|
||||||
.get_value = tegra_gpio_get_value,
|
.get_value = tegra_gpio_get_value,
|
||||||
.set_value = tegra_gpio_set_value,
|
.set_value = tegra_gpio_set_value,
|
||||||
.get_function = tegra_gpio_get_function,
|
.get_function = tegra_gpio_get_function,
|
||||||
.get_state = tegra_gpio_get_state,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,14 +67,19 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
|
|||||||
#ifdef OMAP_HSMMC_USE_GPIO
|
#ifdef OMAP_HSMMC_USE_GPIO
|
||||||
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
|
static int omap_mmc_setup_gpio_in(int gpio, const char *label)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_GPIO
|
||||||
if (!gpio_is_valid(gpio))
|
if (!gpio_is_valid(gpio))
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
|
ret = gpio_request(gpio, label);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (gpio_request(gpio, label) < 0)
|
ret = gpio_direction_input(gpio);
|
||||||
return -1;
|
if (ret)
|
||||||
|
return ret;
|
||||||
if (gpio_direction_input(gpio) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return gpio;
|
return gpio;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
@ -41,6 +41,8 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o
|
|||||||
obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
|
obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
|
||||||
obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
|
obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
|
||||||
obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.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
|
ifndef CONFIG_SPL_BUILD
|
||||||
obj-$(CONFIG_USB_TTY) += usbtty.o
|
obj-$(CONFIG_USB_TTY) += usbtty.o
|
||||||
|
@ -61,13 +61,13 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
|
|||||||
unsigned char *addr;
|
unsigned char *addr;
|
||||||
|
|
||||||
offset *= 1 << plat->reg_shift;
|
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
|
* 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.
|
* these options at run-time, so use the existing CONFIG options.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||||
outb(value, addr);
|
outb(value, (ulong)addr);
|
||||||
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
|
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
|
||||||
out_le32(addr, value);
|
out_le32(addr, value);
|
||||||
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
|
#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;
|
unsigned char *addr;
|
||||||
|
|
||||||
offset *= 1 << plat->reg_shift;
|
offset *= 1 << plat->reg_shift;
|
||||||
addr = plat->base + offset;
|
addr = map_sysmem(plat->base, 0) + offset;
|
||||||
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
|
||||||
return inb(addr);
|
return inb((ulong)addr);
|
||||||
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
|
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
|
||||||
return in_le32(addr);
|
return in_le32(addr);
|
||||||
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
|
#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);
|
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 -EAGAIN;
|
||||||
|
|
||||||
return serial_in(&com_port->rbr);
|
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);
|
struct NS16550 *const com_port = dev_get_priv(dev);
|
||||||
|
|
||||||
|
com_port->plat = dev_get_platdata(dev);
|
||||||
NS16550_init(com_port, -1);
|
NS16550_init(com_port, -1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF_CONTROL
|
||||||
int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
|
int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct NS16550 *const com_port = dev_get_priv(dev);
|
|
||||||
struct ns16550_platdata *plat = dev->platdata;
|
struct ns16550_platdata *plat = dev->platdata;
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
|
|
||||||
@ -291,13 +292,13 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
|
|||||||
if (addr == FDT_ADDR_T_NONE)
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
plat->base = (unsigned char *)addr;
|
plat->base = addr;
|
||||||
plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
|
plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
|
||||||
"reg-shift", 1);
|
"reg-shift", 1);
|
||||||
com_port->plat = plat;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const struct dm_serial_ops ns16550_serial_ops = {
|
const struct dm_serial_ops ns16550_serial_ops = {
|
||||||
.putc = ns16550_serial_putc,
|
.putc = ns16550_serial_putc,
|
||||||
|
@ -11,9 +11,12 @@
|
|||||||
#include <os.h>
|
#include <os.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <stdio_dev.h>
|
#include <stdio_dev.h>
|
||||||
|
#include <watchdog.h>
|
||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
#include <dm/device-internal.h>
|
#include <dm/device-internal.h>
|
||||||
|
|
||||||
|
#include <ns16550.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/* The currently-selected console serial device */
|
/* The currently-selected console serial device */
|
||||||
@ -47,13 +50,22 @@ static void serial_find_console_or_panic(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* 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
|
* just the first serial device we can find. But we insist on having
|
||||||
* a console (even if it is silent).
|
* 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))
|
(uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
|
||||||
panic("No serial driver found");
|
panic("No serial driver found");
|
||||||
|
#undef INDEX
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called prior to relocation */
|
/* Called prior to relocation */
|
||||||
@ -71,21 +83,66 @@ void serial_initialize(void)
|
|||||||
serial_find_console_or_panic();
|
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;
|
int err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = ops->putc(cur_dev, ch);
|
err = ops->putc(dev, ch);
|
||||||
} while (err == -EAGAIN);
|
} while (err == -EAGAIN);
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
serial_putc('\r');
|
_serial_putc(dev, '\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _serial_puts(struct udevice *dev, const char *str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
_serial_putc(dev, *str++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _serial_getc(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct dm_serial_ops *ops = serial_get_ops(dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = ops->getc(dev);
|
||||||
|
if (err == -EAGAIN)
|
||||||
|
WATCHDOG_RESET();
|
||||||
|
} while (err == -EAGAIN);
|
||||||
|
|
||||||
|
return err >= 0 ? err : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _serial_tstc(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct dm_serial_ops *ops = serial_get_ops(dev);
|
||||||
|
|
||||||
|
if (ops->pending)
|
||||||
|
return ops->pending(dev, true);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_putc(char ch)
|
void serial_putc(char ch)
|
||||||
{
|
{
|
||||||
serial_putc_dev(cur_dev, ch);
|
_serial_putc(cur_dev, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_puts(const char *str)
|
||||||
|
{
|
||||||
|
_serial_puts(cur_dev, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_getc(void)
|
||||||
|
{
|
||||||
|
return _serial_getc(cur_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_tstc(void)
|
||||||
|
{
|
||||||
|
return _serial_tstc(cur_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_setbrg(void)
|
void serial_setbrg(void)
|
||||||
@ -96,72 +153,28 @@ void serial_setbrg(void)
|
|||||||
ops->setbrg(cur_dev, gd->baudrate);
|
ops->setbrg(cur_dev, gd->baudrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_puts(const char *str)
|
|
||||||
{
|
|
||||||
while (*str)
|
|
||||||
serial_putc(*str++);
|
|
||||||
}
|
|
||||||
|
|
||||||
int serial_tstc(void)
|
|
||||||
{
|
|
||||||
struct dm_serial_ops *ops = serial_get_ops(cur_dev);
|
|
||||||
|
|
||||||
if (ops->pending)
|
|
||||||
return ops->pending(cur_dev, true);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int serial_getc_dev(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct dm_serial_ops *ops = serial_get_ops(dev);
|
|
||||||
int err;
|
|
||||||
|
|
||||||
do {
|
|
||||||
err = ops->getc(dev);
|
|
||||||
} while (err == -EAGAIN);
|
|
||||||
|
|
||||||
return err >= 0 ? err : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int serial_getc(void)
|
|
||||||
{
|
|
||||||
return serial_getc_dev(cur_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void serial_stdio_init(void)
|
void serial_stdio_init(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
|
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
|
||||||
{
|
{
|
||||||
struct udevice *dev = sdev->priv;
|
_serial_putc(sdev->priv, ch);
|
||||||
|
|
||||||
serial_putc_dev(dev, ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
|
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
|
||||||
{
|
{
|
||||||
while (*str)
|
_serial_puts(sdev->priv, str);
|
||||||
serial_stub_putc(sdev, *str++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_stub_getc(struct stdio_dev *sdev)
|
int serial_stub_getc(struct stdio_dev *sdev)
|
||||||
{
|
{
|
||||||
struct udevice *dev = sdev->priv;
|
return _serial_getc(sdev->priv);
|
||||||
|
|
||||||
return serial_getc_dev(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_stub_tstc(struct stdio_dev *sdev)
|
int serial_stub_tstc(struct stdio_dev *sdev)
|
||||||
{
|
{
|
||||||
struct udevice *dev = sdev->priv;
|
return _serial_tstc(sdev->priv);
|
||||||
struct dm_serial_ops *ops = serial_get_ops(dev);
|
|
||||||
|
|
||||||
if (ops->pending)
|
|
||||||
return ops->pending(dev, true);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serial_post_probe(struct udevice *dev)
|
static int serial_post_probe(struct udevice *dev)
|
||||||
|
@ -157,7 +157,6 @@ serial_initfunc(sh_serial_initialize);
|
|||||||
serial_initfunc(arm_dcc_initialize);
|
serial_initfunc(arm_dcc_initialize);
|
||||||
serial_initfunc(mxs_auart_initialize);
|
serial_initfunc(mxs_auart_initialize);
|
||||||
serial_initfunc(arc_serial_initialize);
|
serial_initfunc(arc_serial_initialize);
|
||||||
serial_initfunc(uniphier_serial_initialize);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* serial_register() - Register serial driver with serial driver core
|
* serial_register() - Register serial driver with serial driver core
|
||||||
@ -251,7 +250,6 @@ void serial_initialize(void)
|
|||||||
arm_dcc_initialize();
|
arm_dcc_initialize();
|
||||||
mxs_auart_initialize();
|
mxs_auart_initialize();
|
||||||
arc_serial_initialize();
|
arc_serial_initialize();
|
||||||
uniphier_serial_initialize();
|
|
||||||
|
|
||||||
serial_assign(default_serial_console()->name);
|
serial_assign(default_serial_console()->name);
|
||||||
}
|
}
|
||||||
|
38
drivers/serial/serial_coreboot.c
Normal file
38
drivers/serial/serial_coreboot.c
Normal file
@ -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,
|
||||||
|
};
|
@ -7,10 +7,10 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <serial_mxc.h>
|
|
||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
#include <asm/arch/imx-regs.h>
|
#include <asm/arch/imx-regs.h>
|
||||||
#include <asm/arch/clock.h>
|
#include <asm/arch/clock.h>
|
||||||
|
#include <dm/platform_data/serial_mxc.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = {
|
|||||||
.puts = eserial##port##_puts, \
|
.puts = eserial##port##_puts, \
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void _serial_putc(const char c, const int port)
|
||||||
_serial_putc(const char c,const int port)
|
|
||||||
{
|
{
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
NS16550_putc(PORT, '\r');
|
NS16550_putc(PORT, '\r');
|
||||||
@ -128,35 +127,29 @@ _serial_putc(const char c,const int port)
|
|||||||
NS16550_putc(PORT, c);
|
NS16550_putc(PORT, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void _serial_putc_raw(const char c, const int port)
|
||||||
_serial_putc_raw(const char c,const int port)
|
|
||||||
{
|
{
|
||||||
NS16550_putc(PORT, c);
|
NS16550_putc(PORT, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void _serial_puts(const char *s, const int port)
|
||||||
_serial_puts (const char *s,const int port)
|
|
||||||
{
|
{
|
||||||
while (*s) {
|
while (*s) {
|
||||||
_serial_putc (*s++,port);
|
_serial_putc(*s++, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _serial_getc(const int port)
|
||||||
int
|
|
||||||
_serial_getc(const int port)
|
|
||||||
{
|
{
|
||||||
return NS16550_getc(PORT);
|
return NS16550_getc(PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int _serial_tstc(const int port)
|
||||||
_serial_tstc(const int port)
|
|
||||||
{
|
{
|
||||||
return NS16550_tstc(PORT);
|
return NS16550_tstc(PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void _serial_setbrg(const int port)
|
||||||
_serial_setbrg (const int port)
|
|
||||||
{
|
{
|
||||||
int clock_divisor;
|
int clock_divisor;
|
||||||
|
|
||||||
|
47
drivers/serial/serial_omap.c
Normal file
47
drivers/serial/serial_omap.c
Normal file
@ -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,
|
||||||
|
};
|
@ -17,7 +17,7 @@
|
|||||||
#include <watchdog.h>
|
#include <watchdog.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <serial_pl01x.h>
|
#include <dm/platform_data/serial_pl01x.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include "serial_pl01x_internal.h"
|
#include "serial_pl01x_internal.h"
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
static int hwflow;
|
static int hwflow;
|
||||||
#endif
|
#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);
|
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
|
||||||
unsigned int reg = 0;
|
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
|
* otherwise. When the function is succesfull, the character read is
|
||||||
* written into its argument c.
|
* 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);
|
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.
|
* 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);
|
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
|
||||||
#ifdef CONFIG_MODEM_SUPPORT
|
#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
|
* 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);
|
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);
|
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) {
|
while (*s) {
|
||||||
_serial_putc(*s++, dev_index);
|
_serial_putc(*s++, dev_index);
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
* Copyright (C) 2012-2014 Panasonic Corporation
|
* Copyright (C) 2012-2014 Panasonic Corporation
|
||||||
* Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
|
* 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+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#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>
|
#include <serial.h>
|
||||||
|
|
||||||
#define UART_REG(x) \
|
#define UART_REG(x) \
|
||||||
@ -48,157 +48,104 @@ struct uniphier_serial {
|
|||||||
#define UART_LSR_DR 0x01 /* Data ready */
|
#define UART_LSR_DR 0x01 /* Data ready */
|
||||||
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
|
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
struct uniphier_serial_private_data {
|
||||||
|
struct uniphier_serial __iomem *membase;
|
||||||
|
};
|
||||||
|
|
||||||
static void uniphier_serial_init(struct uniphier_serial *port)
|
#define uniphier_serial_port(dev) \
|
||||||
|
((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
|
||||||
|
|
||||||
|
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;
|
const unsigned int mode_x_div = 16;
|
||||||
unsigned int divisor;
|
unsigned int divisor;
|
||||||
|
|
||||||
writeb(UART_LCR_WLS_8, &port->lcr);
|
writeb(UART_LCR_WLS_8, &port->lcr);
|
||||||
|
|
||||||
divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK,
|
divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate);
|
||||||
mode_x_div * gd->baudrate);
|
|
||||||
|
|
||||||
writew(divisor, &port->dlr);
|
writew(divisor, &port->dlr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uniphier_serial_setbrg(struct uniphier_serial *port)
|
static int uniphier_serial_getc(struct udevice *dev)
|
||||||
{
|
{
|
||||||
uniphier_serial_init(port);
|
struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
|
||||||
}
|
|
||||||
|
|
||||||
static int uniphier_serial_tstc(struct uniphier_serial *port)
|
if (!(readb(&port->lsr) & UART_LSR_DR))
|
||||||
{
|
return -EAGAIN;
|
||||||
return (readb(&port->lsr) & UART_LSR_DR) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int uniphier_serial_getc(struct uniphier_serial *port)
|
|
||||||
{
|
|
||||||
while (!uniphier_serial_tstc(port))
|
|
||||||
;
|
|
||||||
|
|
||||||
return readb(&port->rbr);
|
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')
|
struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
|
||||||
uniphier_serial_putc(port, '\r');
|
|
||||||
|
|
||||||
while (!(readb(&port->lsr) & UART_LSR_THRE))
|
if (!(readb(&port->lsr) & UART_LSR_THRE))
|
||||||
;
|
return -EAGAIN;
|
||||||
|
|
||||||
writeb(c, &port->thr);
|
writeb(c, &port->thr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct uniphier_serial *serial_ports[4] = {
|
int uniphier_serial_probe(struct udevice *dev)
|
||||||
#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0
|
{
|
||||||
(struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0,
|
struct uniphier_serial_private_data *priv = dev_get_priv(dev);
|
||||||
#else
|
struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
|
||||||
NULL,
|
|
||||||
#endif
|
priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial));
|
||||||
#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1
|
|
||||||
(struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1,
|
if (!priv->membase)
|
||||||
#else
|
return -ENOMEM;
|
||||||
NULL,
|
|
||||||
#endif
|
return 0;
|
||||||
#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2
|
}
|
||||||
(struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2,
|
|
||||||
#else
|
int uniphier_serial_remove(struct udevice *dev)
|
||||||
NULL,
|
{
|
||||||
#endif
|
unmap_sysmem(uniphier_serial_port(dev));
|
||||||
#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3
|
|
||||||
(struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3,
|
return 0;
|
||||||
#else
|
}
|
||||||
NULL,
|
|
||||||
#endif
|
#ifdef CONFIG_OF_CONTROL
|
||||||
|
static const struct udevice_id uniphier_uart_of_match = {
|
||||||
|
{ .compatible = "panasonic,uniphier-uart"},
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Multi serial device functions */
|
static int uniphier_serial_ofdata_to_platdata(struct udevice *dev)
|
||||||
#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, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
__weak struct serial_device *default_serial_console(void)
|
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
|
/*
|
||||||
return &uniphier_serial0_device;
|
* TODO: Masahiro Yamada (yamada.m@jp.panasonic.com)
|
||||||
#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
|
*
|
||||||
return &uniphier_serial1_device;
|
* Implement conversion code from DTB to platform data
|
||||||
#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
|
* when supporting CONFIG_OF_CONTROL on UniPhir platform.
|
||||||
return &uniphier_serial2_device;
|
*/
|
||||||
#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
|
|
||||||
return &uniphier_serial3_device;
|
|
||||||
#else
|
|
||||||
#error "No uniphier serial ports configured."
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void uniphier_serial_initialize(void)
|
static const struct dm_serial_ops uniphier_serial_ops = {
|
||||||
{
|
.setbrg = uniphier_serial_setbrg,
|
||||||
#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
|
.getc = uniphier_serial_getc,
|
||||||
serial_register(&uniphier_serial0_device);
|
.putc = uniphier_serial_putc,
|
||||||
#endif
|
};
|
||||||
#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
|
|
||||||
serial_register(&uniphier_serial1_device);
|
U_BOOT_DRIVER(uniphier_serial) = {
|
||||||
#endif
|
.name = DRIVER_NAME,
|
||||||
#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
|
.id = UCLASS_SERIAL,
|
||||||
serial_register(&uniphier_serial2_device);
|
.of_match = of_match_ptr(uniphier_uart_of_match),
|
||||||
#endif
|
.ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata),
|
||||||
#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
|
.probe = uniphier_serial_probe,
|
||||||
serial_register(&uniphier_serial3_device);
|
.remove = uniphier_serial_remove,
|
||||||
#endif
|
.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,
|
||||||
|
};
|
||||||
|
@ -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.
|
@ -29,6 +29,9 @@
|
|||||||
* Request a GPIO. This should be called before any of the other functions
|
* Request a GPIO. This should be called before any of the other functions
|
||||||
* are used on this GPIO.
|
* 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 gp GPIO number
|
||||||
* @param label User label for this GPIO
|
* @param label User label for this GPIO
|
||||||
* @return 0 if ok, -1 on error
|
* @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);
|
int gpio_set_value(unsigned gpio, int value);
|
||||||
|
|
||||||
/* State of a GPIO, as reported by get_function() */
|
/* State of a GPIO, as reported by get_function() */
|
||||||
enum {
|
enum gpio_func_t {
|
||||||
GPIOF_INPUT = 0,
|
GPIOF_INPUT = 0,
|
||||||
GPIOF_OUTPUT,
|
GPIOF_OUTPUT,
|
||||||
GPIOF_UNUSED, /* Not claimed */
|
GPIOF_UNUSED, /* Not claimed */
|
||||||
@ -92,6 +95,66 @@ enum {
|
|||||||
|
|
||||||
struct udevice;
|
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
|
* struct struct dm_gpio_ops - Driver model GPIO operations
|
||||||
*
|
*
|
||||||
@ -135,8 +198,6 @@ struct dm_gpio_ops {
|
|||||||
* @return current function - GPIOF_...
|
* @return current function - GPIOF_...
|
||||||
*/
|
*/
|
||||||
int (*get_function)(struct udevice *dev, unsigned offset);
|
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
|
* @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
|
* 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.
|
* @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 {
|
struct gpio_dev_priv {
|
||||||
const char *bank_name;
|
const char *bank_name;
|
||||||
unsigned gpio_count;
|
unsigned gpio_count;
|
||||||
unsigned gpio_base;
|
unsigned gpio_base;
|
||||||
|
char **name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Access the GPIO operations for a device */
|
/* Access the GPIO operations for a device */
|
||||||
|
@ -636,13 +636,6 @@ struct stdio_dev;
|
|||||||
int serial_stub_getc(struct stdio_dev *sdev);
|
int serial_stub_getc(struct stdio_dev *sdev);
|
||||||
int serial_stub_tstc(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 */
|
/* $(CPU)/speed.c */
|
||||||
int get_clocks (void);
|
int get_clocks (void);
|
||||||
int get_clocks_866 (void);
|
int get_clocks_866 (void);
|
||||||
|
@ -27,6 +27,11 @@
|
|||||||
#define CONFIG_SYS_EARLY_PCI_INIT
|
#define CONFIG_SYS_EARLY_PCI_INIT
|
||||||
#define CONFIG_DISPLAY_BOARDINFO_LATE
|
#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_LMB
|
||||||
#define CONFIG_OF_LIBFDT
|
#define CONFIG_OF_LIBFDT
|
||||||
|
|
||||||
@ -88,21 +93,16 @@
|
|||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
* Serial Configuration
|
* Serial Configuration
|
||||||
*/
|
*/
|
||||||
#define CONFIG_CONS_INDEX 1
|
#define CONFIG_COREBOOT_SERIAL
|
||||||
#define CONFIG_SYS_NS16550
|
#define CONFIG_SYS_NS16550
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#define CONFIG_BAUDRATE 115200
|
||||||
#define CONFIG_SYS_NS16550_REG_SIZE 1
|
|
||||||
#define CONFIG_SYS_NS16550_CLK 1843200
|
|
||||||
#define CONFIG_BAUDRATE 9600
|
|
||||||
#define CONFIG_SYS_BAUDRATE_TABLE {300, 600, 1200, 2400, 4800, \
|
#define CONFIG_SYS_BAUDRATE_TABLE {300, 600, 1200, 2400, 4800, \
|
||||||
9600, 19200, 38400, 115200}
|
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_SYS_NS16550_PORT_MAPPED
|
||||||
|
|
||||||
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,eserial0\0" \
|
#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
|
||||||
"stdout=vga,eserial0,cbmem\0" \
|
"stdout=vga,serial,cbmem\0" \
|
||||||
"stderr=vga,eserial0,cbmem\0"
|
"stderr=vga,serial,cbmem\0"
|
||||||
|
|
||||||
#define CONFIG_CONSOLE_MUX
|
#define CONFIG_CONSOLE_MUX
|
||||||
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
|
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
|
||||||
@ -256,7 +256,7 @@
|
|||||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||||
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
|
#define CONFIG_SYS_MONITOR_LEN (256 * 1024)
|
||||||
#define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024)
|
#define CONFIG_SYS_MALLOC_LEN (0x20000 + 128 * 1024)
|
||||||
|
#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
|
||||||
|
|
||||||
/* allow to overwrite serial and ethaddr */
|
/* allow to overwrite serial and ethaddr */
|
||||||
#define CONFIG_ENV_OVERWRITE
|
#define CONFIG_ENV_OVERWRITE
|
||||||
|
@ -28,14 +28,10 @@
|
|||||||
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
||||||
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
||||||
*/
|
*/
|
||||||
#if 1
|
#if 0
|
||||||
#define CONFIG_UNIPHIER_SERIAL
|
|
||||||
#else
|
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#define CONFIG_SYS_NS16550_SERIAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_SYS_UNIPHIER_UART_CLK 36864000
|
|
||||||
|
|
||||||
#define CONFIG_SMC911X
|
#define CONFIG_SMC911X
|
||||||
|
|
||||||
#define CONFIG_DDR_NUM_CH0 1
|
#define CONFIG_DDR_NUM_CH0 1
|
||||||
|
@ -28,14 +28,10 @@
|
|||||||
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
||||||
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
||||||
*/
|
*/
|
||||||
#if 1
|
#if 0
|
||||||
#define CONFIG_UNIPHIER_SERIAL
|
|
||||||
#else
|
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#define CONFIG_SYS_NS16550_SERIAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_SYS_UNIPHIER_UART_CLK 73728000
|
|
||||||
|
|
||||||
#define CONFIG_SMC911X
|
#define CONFIG_SMC911X
|
||||||
|
|
||||||
#define CONFIG_DDR_NUM_CH0 2
|
#define CONFIG_DDR_NUM_CH0 2
|
||||||
|
@ -28,14 +28,10 @@
|
|||||||
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
* SoC UART : enable CONFIG_UNIPHIER_SERIAL
|
||||||
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
* On-board UART: enable CONFIG_SYS_NS16550_SERIAL
|
||||||
*/
|
*/
|
||||||
#if 1
|
#if 0
|
||||||
#define CONFIG_UNIPHIER_SERIAL
|
|
||||||
#else
|
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#define CONFIG_SYS_NS16550_SERIAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_SYS_UNIPHIER_UART_CLK 80000000
|
|
||||||
|
|
||||||
#define CONFIG_SMC911X
|
#define CONFIG_SMC911X
|
||||||
|
|
||||||
#define CONFIG_DDR_NUM_CH0 1
|
#define CONFIG_DDR_NUM_CH0 1
|
||||||
|
@ -19,12 +19,23 @@
|
|||||||
#define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */
|
#define CONFIG_SYS_TIMERBASE 0x48040000 /* Use Timer2 */
|
||||||
#define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC
|
#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>
|
#include <asm/arch/omap.h>
|
||||||
|
|
||||||
/* NS16550 Configuration */
|
/* NS16550 Configuration */
|
||||||
#define CONFIG_SYS_NS16550
|
#define CONFIG_SYS_NS16550
|
||||||
|
#ifdef CONFIG_SPL_BUILD
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#define CONFIG_SYS_NS16550_SERIAL
|
||||||
#define CONFIG_SYS_NS16550_REG_SIZE (-4)
|
#define CONFIG_SYS_NS16550_REG_SIZE (-4)
|
||||||
|
#endif
|
||||||
#define CONFIG_SYS_NS16550_CLK 48000000
|
#define CONFIG_SYS_NS16550_CLK 48000000
|
||||||
|
|
||||||
/* Network defines. */
|
/* Network defines. */
|
||||||
|
@ -18,6 +18,15 @@
|
|||||||
#include <asm/arch/cpu.h>
|
#include <asm/arch/cpu.h>
|
||||||
#include <asm/arch/omap3.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 */
|
/* The chip has SDRC controller */
|
||||||
#define CONFIG_SDRC
|
#define CONFIG_SDRC
|
||||||
|
|
||||||
@ -28,16 +37,20 @@
|
|||||||
/* NS16550 Configuration */
|
/* NS16550 Configuration */
|
||||||
#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
|
#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
|
||||||
#define CONFIG_SYS_NS16550
|
#define CONFIG_SYS_NS16550
|
||||||
#define CONFIG_SYS_NS16550_SERIAL
|
#ifdef CONFIG_SPL_BUILD
|
||||||
#define CONFIG_SYS_NS16550_REG_SIZE (-4)
|
# define CONFIG_SYS_NS16550_SERIAL
|
||||||
#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
|
# 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, \
|
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \
|
||||||
115200}
|
115200}
|
||||||
|
|
||||||
/* Select serial console configuration */
|
/* Select serial console configuration */
|
||||||
#define CONFIG_CONS_INDEX 3
|
#define CONFIG_CONS_INDEX 3
|
||||||
|
#ifdef CONFIG_SPL_BUILD
|
||||||
#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
|
#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
|
||||||
#define CONFIG_SERIAL3 3
|
#define CONFIG_SERIAL3 3
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Physical Memory Map */
|
/* Physical Memory Map */
|
||||||
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
|
||||||
|
@ -33,18 +33,17 @@ are defined. Select only one of them."
|
|||||||
# define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000)
|
# define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYS_NS16550_SERIAL
|
||||||
#define CONFIG_SYS_NS16550
|
#define CONFIG_SYS_NS16550
|
||||||
#define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE
|
#define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE
|
||||||
#define CONFIG_SYS_NS16550_CLK 12288000
|
#define CONFIG_SYS_NS16550_CLK 12288000
|
||||||
#define CONFIG_SYS_NS16550_REG_SIZE -2
|
#define CONFIG_SYS_NS16550_REG_SIZE -2
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE
|
#define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE
|
||||||
#define CONFIG_SMC911X_32_BIT
|
#define CONFIG_SMC911X_32_BIT
|
||||||
|
|
||||||
#define CONFIG_SYS_UNIPHIER_SERIAL_BASE0 0x54006800
|
#define CONFIG_SYS_MALLOC_F_LEN 0x7000
|
||||||
#define CONFIG_SYS_UNIPHIER_SERIAL_BASE1 0x54006900
|
|
||||||
#define CONFIG_SYS_UNIPHIER_SERIAL_BASE2 0x54006a00
|
|
||||||
#define CONFIG_SYS_UNIPHIER_SERIAL_BASE3 0x54006b00
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
* MMU and Cache Setting
|
* MMU and Cache Setting
|
||||||
|
18
include/dm/platform_data/serial-uniphier.h
Normal file
18
include/dm/platform_data/serial-uniphier.h
Normal file
@ -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 */
|
@ -8,6 +8,7 @@
|
|||||||
#define __DM_TEST_H
|
#define __DM_TEST_H
|
||||||
|
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct dm_test_cdata - configuration data for test instance
|
* struct dm_test_cdata - configuration data for test instance
|
||||||
@ -120,6 +121,7 @@ struct dm_test_state {
|
|||||||
int force_fail_alloc;
|
int force_fail_alloc;
|
||||||
int skip_post_probe;
|
int skip_post_probe;
|
||||||
struct udevice *removed;
|
struct udevice *removed;
|
||||||
|
struct mallinfo start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Test flags for each test */
|
/* Test flags for each test */
|
||||||
@ -177,6 +179,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);
|
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
|
* dm_test_main() - Run all the tests
|
||||||
*
|
*
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
* @clock: UART base clock speed in Hz
|
* @clock: UART base clock speed in Hz
|
||||||
*/
|
*/
|
||||||
struct ns16550_platdata {
|
struct ns16550_platdata {
|
||||||
unsigned char *base;
|
unsigned long base;
|
||||||
int reg_shift;
|
int reg_shift;
|
||||||
int clock;
|
int clock;
|
||||||
};
|
};
|
||||||
|
@ -67,6 +67,34 @@ static struct driver_info driver_info_pre_reloc = {
|
|||||||
.platdata = &test_pdata_manual,
|
.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 */
|
/* Test that binding with platdata occurs correctly */
|
||||||
static int dm_test_autobind(struct dm_test_state *dms)
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
struct mallinfo start, end;
|
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
int ret;
|
int ret;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
start = mallinfo();
|
dm_leak_check_start(dms);
|
||||||
if (!start.uordblks)
|
|
||||||
puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
|
|
||||||
|
|
||||||
ut_assertok(dm_scan_platdata(false));
|
ut_assertok(dm_scan_platdata(false));
|
||||||
ut_assertok(dm_scan_fdt(gd->fdt_blob, 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);
|
ut_assertok(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't delete the root class, since we started with that */
|
ut_assertok(dm_leak_check_end(dms));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
111
test/dm/gpio.c
111
test/dm/gpio.c
@ -7,11 +7,14 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <dm/root.h>
|
||||||
#include <dm/ut.h>
|
#include <dm/ut.h>
|
||||||
#include <dm/test.h>
|
#include <dm/test.h>
|
||||||
#include <dm/util.h>
|
#include <dm/util.h>
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
/* Test that sandbox GPIOs work correctly */
|
/* Test that sandbox GPIOs work correctly */
|
||||||
static int dm_test_gpio(struct dm_test_state *dms)
|
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 */
|
/* Get the operations for this device */
|
||||||
ops = gpio_get_ops(dev);
|
ops = gpio_get_ops(dev);
|
||||||
ut_assert(ops->get_state);
|
ut_assert(ops->get_function);
|
||||||
|
|
||||||
/* Cannot get a value until it is reserved */
|
/* 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
|
* Now some tests that use the 'sandbox' back door. All GPIOs
|
||||||
* should default to input, include b4 that we are using here.
|
* should default to input, include b4 that we are using here.
|
||||||
*/
|
*/
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: in: 0 [ ]", buf);
|
ut_asserteq_str("b4: input: 0 [ ]", buf);
|
||||||
|
|
||||||
/* Change it to an output */
|
/* Change it to an output */
|
||||||
sandbox_gpio_set_direction(dev, offset, 1);
|
sandbox_gpio_set_direction(dev, offset, 1);
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: out: 0 [ ]", buf);
|
ut_asserteq_str("b4: output: 0 [ ]", buf);
|
||||||
|
|
||||||
sandbox_gpio_set_value(dev, offset, 1);
|
sandbox_gpio_set_value(dev, offset, 1);
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: out: 1 [ ]", buf);
|
ut_asserteq_str("b4: output: 1 [ ]", buf);
|
||||||
|
|
||||||
ut_assertok(ops->request(dev, offset, "testing"));
|
ut_assertok(gpio_request(gpio, "testing"));
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: out: 1 [x] testing", buf);
|
ut_asserteq_str("b4: output: 1 [x] testing", buf);
|
||||||
|
|
||||||
/* Change the value a bit */
|
/* Change the value a bit */
|
||||||
ut_asserteq(1, ops->get_value(dev, offset));
|
ut_asserteq(1, ops->get_value(dev, offset));
|
||||||
ut_assertok(ops->set_value(dev, offset, 0));
|
ut_assertok(ops->set_value(dev, offset, 0));
|
||||||
ut_asserteq(0, ops->get_value(dev, offset));
|
ut_asserteq(0, ops->get_value(dev, offset));
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: out: 0 [x] testing", buf);
|
ut_asserteq_str("b4: output: 0 [x] testing", buf);
|
||||||
ut_assertok(ops->set_value(dev, offset, 1));
|
ut_assertok(ops->set_value(dev, offset, 1));
|
||||||
ut_asserteq(1, ops->get_value(dev, offset));
|
ut_asserteq(1, ops->get_value(dev, offset));
|
||||||
|
|
||||||
/* Make it an input */
|
/* Make it an input */
|
||||||
ut_assertok(ops->direction_input(dev, offset));
|
ut_assertok(ops->direction_input(dev, offset));
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: in: 1 [x] testing", buf);
|
ut_asserteq_str("b4: input: 1 [x] testing", buf);
|
||||||
sandbox_gpio_set_value(dev, offset, 0);
|
sandbox_gpio_set_value(dev, offset, 0);
|
||||||
ut_asserteq(0, sandbox_gpio_get_value(dev, offset));
|
ut_asserteq(0, sandbox_gpio_get_value(dev, offset));
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: in: 0 [x] testing", buf);
|
ut_asserteq_str("b4: input: 0 [x] testing", buf);
|
||||||
|
|
||||||
ut_assertok(ops->free(dev, offset));
|
ut_assertok(gpio_free(gpio));
|
||||||
ut_assertok(ops->get_state(dev, offset, buf, sizeof(buf)));
|
ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
|
||||||
ut_asserteq_str("b4: in: 0 [ ]", buf);
|
ut_asserteq_str("b4: input: 0 [ ]", buf);
|
||||||
|
|
||||||
/* Check the 'a' bank also */
|
/* Check the 'a' bank also */
|
||||||
ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio));
|
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_str("a", name);
|
||||||
ut_asserteq(20, offset_count);
|
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 */
|
/* And the anonymous bank */
|
||||||
ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
|
ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
|
||||||
ut_asserteq_str(dev->name, "gpio_sandbox");
|
ut_asserteq_str(dev->name, "gpio_sandbox");
|
||||||
@ -108,4 +122,57 @@ static int dm_test_gpio(struct dm_test_state *dms)
|
|||||||
|
|
||||||
return 0;
|
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);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <dm/test.h>
|
#include <dm/test.h>
|
||||||
#include <dm/root.h>
|
#include <dm/root.h>
|
||||||
#include <dm/uclass-internal.h>
|
#include <dm/uclass-internal.h>
|
||||||
@ -88,6 +89,7 @@ int dm_test_main(void)
|
|||||||
printf("Test: %s\n", test->name);
|
printf("Test: %s\n", test->name);
|
||||||
ut_assertok(dm_test_init(dms));
|
ut_assertok(dm_test_init(dms));
|
||||||
|
|
||||||
|
dms->start = mallinfo();
|
||||||
if (test->flags & DM_TESTF_SCAN_PDATA)
|
if (test->flags & DM_TESTF_SCAN_PDATA)
|
||||||
ut_assertok(dm_scan_platdata(false));
|
ut_assertok(dm_scan_platdata(false));
|
||||||
if (test->flags & DM_TESTF_PROBE_TEST)
|
if (test->flags & DM_TESTF_PROBE_TEST)
|
||||||
|
Loading…
Reference in New Issue
Block a user