diff options
188 files changed, 8367 insertions, 3166 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index bf60c67668..b3a45ccbac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -370,7 +370,7 @@ T: git git://git.denx.de/u-boot-sh.git F: arch/sh/ SPARC -M: Daniel Hellstrom <daniel@gaisler.com> +M: Francois Retief <fgretief@spaceteq.co.za> S: Maintained T: git git://git.denx.de/u-boot-sparc.git F: arch/sparc/ @@ -2438,6 +2438,15 @@ CBFS (Coreboot Filesystem) support - CONFIG_SYS_I2C_IHS_CH3 activate hardware channel 3 - CONFIG_SYS_I2C_IHS_SPEED_3 speed channel 3 - CONFIG_SYS_I2C_IHS_SLAVE_3 slave addr channel 3 + - activate dual channel with CONFIG_SYS_I2C_IHS_DUAL + - CONFIG_SYS_I2C_IHS_SPEED_0_1 speed channel 0_1 + - CONFIG_SYS_I2C_IHS_SLAVE_0_1 slave addr channel 0_1 + - CONFIG_SYS_I2C_IHS_SPEED_1_1 speed channel 1_1 + - CONFIG_SYS_I2C_IHS_SLAVE_1_1 slave addr channel 1_1 + - CONFIG_SYS_I2C_IHS_SPEED_2_1 speed channel 2_1 + - CONFIG_SYS_I2C_IHS_SLAVE_2_1 slave addr channel 2_1 + - CONFIG_SYS_I2C_IHS_SPEED_3_1 speed channel 3_1 + - CONFIG_SYS_I2C_IHS_SLAVE_3_1 slave addr channel 3_1 additional defines: @@ -3568,6 +3577,9 @@ FIT uImage format: CONFIG_SYS_SPL_MALLOC_START Starting address of the malloc pool used in SPL. + When this option is set the full malloc is used in SPL and + it is set up by spl_init() and before that, the simple malloc() + can be used if CONFIG_SYS_MALLOC_F is defined. CONFIG_SYS_SPL_MALLOC_SIZE The size of the malloc pool used in SPL. diff --git a/arch/arm/dts/tegra210-p2371-2180.dts b/arch/arm/dts/tegra210-p2371-2180.dts index 5d9adcff31..bf35497d83 100644 --- a/arch/arm/dts/tegra210-p2371-2180.dts +++ b/arch/arm/dts/tegra210-p2371-2180.dts @@ -21,6 +21,56 @@ reg = <0x0 0x80000000 0x0 0xc0000000>; }; + pcie-controller@0,01003000 { + status = "okay"; + + pci@1,0 { + status = "okay"; + }; + + pci@2,0 { + status = "okay"; + }; + }; + + padctl@0,7009f000 { + pinctrl-0 = <&padctl_default>; + pinctrl-names = "default"; + + padctl_default: pinmux { + xusb { + nvidia,lanes = "otg-1", "otg-2"; + nvidia,function = "xusb"; + nvidia,iddq = <0>; + }; + + usb3 { + nvidia,lanes = "pcie-5", "pcie-6"; + nvidia,function = "usb3"; + nvidia,iddq = <0>; + }; + + pcie-x1 { + nvidia,lanes = "pcie-0"; + nvidia,function = "pcie-x1"; + nvidia,iddq = <0>; + }; + + pcie-x4 { + nvidia,lanes = "pcie-1", "pcie-2", + "pcie-3", "pcie-4"; + nvidia,function = "pcie-x4"; + nvidia,iddq = <0>; + }; + + sata { + nvidia,lanes = "sata-0"; + nvidia,function = "sata"; + nvidia,iddq = <0>; + }; + }; + }; + sdhci@0,700b0000 { status = "okay"; cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>; diff --git a/arch/arm/dts/tegra210.dtsi b/arch/arm/dts/tegra210.dtsi index f3874a1141..a8c2f1994f 100644 --- a/arch/arm/dts/tegra210.dtsi +++ b/arch/arm/dts/tegra210.dtsi @@ -12,6 +12,72 @@ #address-cells = <2>; #size-cells = <2>; + pcie-controller@0,01003000 { + compatible = "nvidia,tegra210-pcie"; + device_type = "pci"; + reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ + 0x0 0x01003800 0x0 0x00000800 /* AFI registers */ + 0x0 0x02000000 0x0 0x10000000>; /* configuration space */ + reg-names = "pads", "afi", "cs"; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */ + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */ + interrupt-names = "intr", "msi"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + + bus-range = <0x00 0xff>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000 /* port 0 configuration space */ + 0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000 /* port 1 configuration space */ + 0x81000000 0 0x0 0x0 0x12000000 0 0x00010000 /* downstream I/O (64 KiB) */ + 0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000 /* non-prefetchable memory (208 MiB) */ + 0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */ + + clocks = <&tegra_car TEGRA210_CLK_PCIE>, + <&tegra_car TEGRA210_CLK_AFI>, + <&tegra_car TEGRA210_CLK_PLL_E>, + <&tegra_car TEGRA210_CLK_CML0>; + clock-names = "pex", "afi", "pll_e", "cml"; + resets = <&tegra_car 70>, + <&tegra_car 72>, + <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; + status = "disabled"; + + phys = <&padctl TEGRA_XUSB_PADCTL_PCIE>; + phy-names = "pcie"; + + pci@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>; + reg = <0x000800 0 0 0 0>; + status = "disabled"; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + nvidia,num-lanes = <4>; + }; + + pci@2,0 { + device_type = "pci"; + assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>; + reg = <0x001000 0 0 0 0>; + status = "disabled"; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + nvidia,num-lanes = <1>; + }; + }; + gic: interrupt-controller@0,50041000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; diff --git a/arch/arm/include/asm/arch-hi6220/gpio.h b/arch/arm/include/asm/arch-hi6220/gpio.h index 4fafaef5d5..29ace17ab8 100644 --- a/arch/arm/include/asm/arch-hi6220/gpio.h +++ b/arch/arm/include/asm/arch-hi6220/gpio.h @@ -21,7 +21,7 @@ struct gpio_bank { /* Information about a GPIO bank */ struct hikey_gpio_platdata { int bank_index; - unsigned int base; /* address of registers in physical memory */ + ulong base; /* address of registers in physical memory */ }; #endif /* _HI6220_GPIO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/gpu.h b/arch/arm/include/asm/arch-tegra/gpu.h index 52280f40ce..4423386f28 100644 --- a/arch/arm/include/asm/arch-tegra/gpu.h +++ b/arch/arm/include/asm/arch-tegra/gpu.h @@ -10,29 +10,23 @@ #if defined(CONFIG_TEGRA_GPU) -void config_gpu(void); -bool gpu_configured(void); +void tegra_gpu_config(void); #else /* CONFIG_TEGRA_GPU */ -static inline void config_gpu(void) +static inline void tegra_gpu_config(void) { } -static inline bool gpu_configured(void) -{ - return false; -} - #endif /* CONFIG_TEGRA_GPU */ #if defined(CONFIG_OF_LIBFDT) -int gpu_enable_node(void *blob, const char *gpupath); +int tegra_gpu_enable_node(void *blob, const char *gpupath); #else /* CONFIG_OF_LIBFDT */ -static inline int gpu_enable_node(void *blob, const char *gpupath) +static inline int tegra_gpu_enable_node(void *blob, const char *gpupath) { return 0; } diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 98431a91f8..2be6ef41ff 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -23,7 +23,7 @@ obj-y += clock.o obj-y += lowlevel_init.o obj-y += pinmux-common.o obj-y += powergate.o -obj-y += xusb-padctl.o +obj-y += xusb-padctl-dummy.o obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o obj-$(CONFIG_TEGRA_GPU) += gpu.o obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 8ecc67459a..8ba143d996 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -128,7 +128,7 @@ int board_init(void) clock_init(); clock_verify(); - config_gpu(); + tegra_gpu_config(); #ifdef CONFIG_TEGRA_SPI pin_mux_spi(); @@ -403,3 +403,23 @@ ulong board_get_usable_ram_top(ulong total_size) { return CONFIG_SYS_SDRAM_BASE + usable_ram_size_below_4g(); } + +/* + * This function is called right before the kernel is booted. "blob" is the + * device tree that will be passed to the kernel. + */ +int ft_system_setup(void *blob, bd_t *bd) +{ + const char *gpu_path = +#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210) + "/gpu@0,57000000"; +#else + NULL; +#endif + + /* Enable GPU node if GPU setup has been performed */ + if (gpu_path != NULL) + return tegra_gpu_enable_node(blob, gpu_path); + + return 0; +} diff --git a/arch/arm/mach-tegra/gpu.c b/arch/arm/mach-tegra/gpu.c index 4ea046d3e5..c7d705d8ef 100644 --- a/arch/arm/mach-tegra/gpu.c +++ b/arch/arm/mach-tegra/gpu.c @@ -25,7 +25,7 @@ static bool _configured; -void config_gpu(void) +void tegra_gpu_config(void) { struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; @@ -41,18 +41,13 @@ void config_gpu(void) _configured = true; } -bool vpr_configured(void) -{ - return _configured; -} - #if defined(CONFIG_OF_LIBFDT) -int gpu_enable_node(void *blob, const char *gpupath) +int tegra_gpu_enable_node(void *blob, const char *gpupath) { int offset; - if (vpr_configured()) { + if (_configured) { offset = fdt_path_offset(blob, gpupath); if (offset > 0) { fdt_status_okay(blob, offset); diff --git a/arch/arm/mach-tegra/tegra124/Makefile b/arch/arm/mach-tegra/tegra124/Makefile index f577f459be..c00de6151e 100644 --- a/arch/arm/mach-tegra/tegra124/Makefile +++ b/arch/arm/mach-tegra/tegra124/Makefile @@ -11,6 +11,7 @@ obj-y += clock.o obj-y += funcmux.o obj-y += pinmux.o obj-y += xusb-padctl.o +obj-y += ../xusb-padctl-common.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_NONSEC) += psci.o diff --git a/arch/arm/mach-tegra/tegra124/xusb-padctl.c b/arch/arm/mach-tegra/tegra124/xusb-padctl.c index 43af883f2c..76af924b94 100644 --- a/arch/arm/mach-tegra/tegra124/xusb-padctl.c +++ b/arch/arm/mach-tegra/tegra124/xusb-padctl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: GPL-2.0 */ @@ -8,13 +8,8 @@ #include <common.h> #include <errno.h> -#include <fdtdec.h> -#include <malloc.h> -#include <asm/io.h> - -#include <asm/arch/clock.h> -#include <asm/arch-tegra/xusb-padctl.h> +#include "../xusb-padctl-common.h" #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> @@ -83,18 +78,6 @@ static const unsigned int tegra124_pci_functions[] = { TEGRA124_FUNC_RSVD, }; -struct tegra_xusb_padctl_lane { - const char *name; - - unsigned int offset; - unsigned int shift; - unsigned int mask; - unsigned int iddq; - - const unsigned int *funcs; - unsigned int num_funcs; -}; - #define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ { \ .name = _name, \ @@ -121,74 +104,6 @@ static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), }; -struct tegra_xusb_phy_ops { - int (*prepare)(struct tegra_xusb_phy *phy); - int (*enable)(struct tegra_xusb_phy *phy); - int (*disable)(struct tegra_xusb_phy *phy); - int (*unprepare)(struct tegra_xusb_phy *phy); -}; - -struct tegra_xusb_phy { - const struct tegra_xusb_phy_ops *ops; - - struct tegra_xusb_padctl *padctl; -}; - -struct tegra_xusb_padctl_pin { - const struct tegra_xusb_padctl_lane *lane; - - unsigned int func; - int iddq; -}; - -#define MAX_GROUPS 3 -#define MAX_PINS 6 - -struct tegra_xusb_padctl_group { - const char *name; - - const char *pins[MAX_PINS]; - unsigned int num_pins; - - const char *func; - int iddq; -}; - -struct tegra_xusb_padctl_config { - const char *name; - - struct tegra_xusb_padctl_group groups[MAX_GROUPS]; - unsigned int num_groups; -}; - -struct tegra_xusb_padctl { - struct fdt_resource regs; - - unsigned int enable; - - struct tegra_xusb_phy phys[2]; - - const struct tegra_xusb_padctl_lane *lanes; - unsigned int num_lanes; - - const char *const *functions; - unsigned int num_functions; - - struct tegra_xusb_padctl_config config; -}; - -static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, - unsigned long offset) -{ - return readl(padctl->regs.start + offset); -} - -static inline void padctl_writel(struct tegra_xusb_padctl *padctl, - u32 value, unsigned long offset) -{ - writel(value, padctl->regs.start + offset); -} - static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) { u32 value; @@ -220,7 +135,7 @@ static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) u32 value; if (padctl->enable == 0) { - error("tegra-xusb-padctl: unbalanced enable/disable"); + error("unbalanced enable/disable"); return 0; } @@ -380,329 +295,27 @@ static const struct tegra_xusb_phy_ops sata_phy_ops = { .unprepare = phy_unprepare, }; -static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) { - .phys = { - [0] = { - .ops = &pcie_phy_ops, - }, - [1] = { - .ops = &sata_phy_ops, - }, +static struct tegra_xusb_phy tegra124_phys[] = { + { + .type = TEGRA_XUSB_PADCTL_PCIE, + .ops = &pcie_phy_ops, + .padctl = &padctl, + }, + { + .type = TEGRA_XUSB_PADCTL_SATA, + .ops = &sata_phy_ops, + .padctl = &padctl, }, }; -static const struct tegra_xusb_padctl_lane * -tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name) -{ - unsigned int i; - - for (i = 0; i < padctl->num_lanes; i++) - if (strcmp(name, padctl->lanes[i].name) == 0) - return &padctl->lanes[i]; - - return NULL; -} - -static int -tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_group *group, - const void *fdt, int node) -{ - unsigned int i; - int len, err; - - group->name = fdt_get_name(fdt, node, &len); - - len = fdt_count_strings(fdt, node, "nvidia,lanes"); - if (len < 0) { - error("tegra-xusb-padctl: failed to parse \"nvidia,lanes\" property"); - return -EINVAL; - } - - group->num_pins = len; - - for (i = 0; i < group->num_pins; i++) { - err = fdt_get_string_index(fdt, node, "nvidia,lanes", i, - &group->pins[i]); - if (err < 0) { - error("tegra-xusb-padctl: failed to read string from \"nvidia,lanes\" property"); - return -EINVAL; - } - } - - group->num_pins = len; - - err = fdt_get_string(fdt, node, "nvidia,function", &group->func); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse \"nvidia,func\" property"); - return -EINVAL; - } - - group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); - - return 0; -} - -static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl, - const char *name) -{ - unsigned int i; - - for (i = 0; i < padctl->num_functions; i++) - if (strcmp(name, padctl->functions[i]) == 0) - return i; - - return -ENOENT; -} - -static int -tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl, - const struct tegra_xusb_padctl_lane *lane, - const char *name) -{ - unsigned int i; - int func; - - func = tegra_xusb_padctl_find_function(padctl, name); - if (func < 0) - return func; - - for (i = 0; i < lane->num_funcs; i++) - if (lane->funcs[i] == func) - return i; - - return -ENOENT; -} - -static int -tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl, - const struct tegra_xusb_padctl_group *group) -{ - unsigned int i; - - for (i = 0; i < group->num_pins; i++) { - const struct tegra_xusb_padctl_lane *lane; - unsigned int func; - u32 value; - - lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]); - if (!lane) { - error("tegra-xusb-padctl: no lane for pin %s", - group->pins[i]); - continue; - } - - func = tegra_xusb_padctl_lane_find_function(padctl, lane, - group->func); - if (func < 0) { - error("tegra-xusb-padctl: function %s invalid for lane %s: %d", - group->func, lane->name, func); - continue; - } - - value = padctl_readl(padctl, lane->offset); - - /* set pin function */ - value &= ~(lane->mask << lane->shift); - value |= func << lane->shift; - - /* - * Set IDDQ if supported on the lane and specified in the - * configuration. - */ - if (lane->iddq > 0 && group->iddq >= 0) { - if (group->iddq != 0) - value &= ~(1 << lane->iddq); - else - value |= 1 << lane->iddq; - } - - padctl_writel(padctl, value, lane->offset); - } - - return 0; -} - -static int -tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_config *config) -{ - unsigned int i; - - for (i = 0; i < config->num_groups; i++) { - const struct tegra_xusb_padctl_group *group; - int err; - - group = &config->groups[i]; - - err = tegra_xusb_padctl_group_apply(padctl, group); - if (err < 0) { - error("tegra-xusb-padctl: failed to apply group %s: %d", - group->name, err); - continue; - } - } - - return 0; -} - -static int -tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_config *config, - const void *fdt, int node) -{ - int subnode; - - config->name = fdt_get_name(fdt, node, NULL); - - fdt_for_each_subnode(fdt, subnode, node) { - struct tegra_xusb_padctl_group *group; - int err; - - group = &config->groups[config->num_groups]; - - err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt, - subnode); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse group %s", - group->name); - return err; - } - - config->num_groups++; - } - - return 0; -} - -static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, - const void *fdt, int node) -{ - int subnode, err; - - err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); - if (err < 0) { - error("tegra-xusb-padctl: registers not found"); - return err; - } - - fdt_for_each_subnode(fdt, subnode, node) { - struct tegra_xusb_padctl_config *config = &padctl->config; - - err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt, - subnode); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse entry %s: %d", - config->name, err); - continue; - } - } - - return 0; -} - -static int process_nodes(const void *fdt, int nodes[], unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) { - enum fdt_compat_id id; - int err; - - if (!fdtdec_get_is_enabled(fdt, nodes[i])) - continue; - - id = fdtdec_lookup(fdt, nodes[i]); - switch (id) { - case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: - break; - - default: - error("tegra-xusb-padctl: unsupported compatible: %s", - fdtdec_get_compatible(id)); - continue; - } - - padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); - padctl->lanes = tegra124_lanes; - - padctl->num_functions = ARRAY_SIZE(tegra124_functions); - padctl->functions = tegra124_functions; - - err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse DT: %d", - err); - continue; - } - - /* deassert XUSB padctl reset */ - reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); - - err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); - if (err < 0) { - error("tegra-xusb-padctl: failed to apply pinmux: %d", - err); - continue; - } - - /* only a single instance is supported */ - break; - } - - return 0; -} - -struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type) -{ - struct tegra_xusb_phy *phy = NULL; - - switch (type) { - case TEGRA_XUSB_PADCTL_PCIE: - phy = &padctl->phys[0]; - phy->padctl = padctl; - break; - - case TEGRA_XUSB_PADCTL_SATA: - phy = &padctl->phys[1]; - phy->padctl = padctl; - break; - } - - return phy; -} - -int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->prepare) - return phy->ops->prepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->enable) - return phy->ops->enable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->disable) - return phy->ops->disable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->unprepare) - return phy->ops->unprepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} +static const struct tegra_xusb_padctl_soc tegra124_socdata = { + .lanes = tegra124_lanes, + .num_lanes = ARRAY_SIZE(tegra124_lanes), + .functions = tegra124_functions, + .num_functions = ARRAY_SIZE(tegra124_functions), + .phys = tegra124_phys, + .num_phys = ARRAY_SIZE(tegra124_phys), +}; void tegra_xusb_padctl_init(const void *fdt) { @@ -711,6 +324,6 @@ void tegra_xusb_padctl_init(const void *fdt) count = fdtdec_find_aliases_for_id(fdt, "padctl", COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, nodes, ARRAY_SIZE(nodes)); - if (process_nodes(fdt, nodes, count)) + if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra124_socdata)) return; } diff --git a/arch/arm/mach-tegra/tegra210/Kconfig b/arch/arm/mach-tegra/tegra210/Kconfig index b07363a4c3..055fb124d8 100644 --- a/arch/arm/mach-tegra/tegra210/Kconfig +++ b/arch/arm/mach-tegra/tegra210/Kconfig @@ -19,12 +19,12 @@ config TARGET_P2371_0000 a GPIO expansion header, and an analog audio jack. config TARGET_P2371_2180 - bool "NVIDIA Tegra210 P2371-2180 board" + bool "NVIDIA Tegra210 P2371-2180 (Jetson TX1) board" help - P2371-2180 is a P2180 CPU board married to a P2597 I/O board. The - combination contains SoC, DRAM, eMMC, SD card slot, HDMI, USB - micro-B port, Ethernet via USB3, USB3 host port, SATA, PCIe, and - two GPIO expansion headers. + P2371-2180 (Jetson TX1 developer kit) is a P2180 CPU board married + to a P2597 I/O board. The combination contains SoC, DRAM, eMMC, SD + card slot, HDMI, USB micro-B port, Ethernet via USB3, USB3 host + port, SATA, PCIe, and two GPIO expansion headers. config TARGET_P2571 bool "NVIDIA Tegra210 P2571 base board" diff --git a/arch/arm/mach-tegra/tegra210/Makefile b/arch/arm/mach-tegra/tegra210/Makefile index 1fb8d1ac74..b6012fc7ba 100644 --- a/arch/arm/mach-tegra/tegra210/Makefile +++ b/arch/arm/mach-tegra/tegra210/Makefile @@ -9,3 +9,4 @@ obj-y += clock.o obj-y += funcmux.o obj-y += pinmux.o obj-y += xusb-padctl.o +obj-y += ../xusb-padctl-common.o diff --git a/arch/arm/mach-tegra/tegra210/clock.c b/arch/arm/mach-tegra/tegra210/clock.c index 6d75d371cb..df92bdce88 100644 --- a/arch/arm/mach-tegra/tegra210/clock.c +++ b/arch/arm/mach-tegra/tegra210/clock.c @@ -8,6 +8,7 @@ /* Tegra210 Clock control functions */ #include <common.h> +#include <errno.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/sysctr.h> @@ -1030,6 +1031,59 @@ void arch_timer_init(void) debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); } +#define PLLREFE_MISC 0x4c8 +#define PLLREFE_MISC_LOCK BIT(27) +#define PLLREFE_MISC_IDDQ BIT(24) + +#define PLLREFE_BASE 0x4c4 +#define PLLREFE_BASE_BYPASS BIT(31) +#define PLLREFE_BASE_ENABLE BIT(30) +#define PLLREFE_BASE_REF_DIS BIT(29) +#define PLLREFE_BASE_KCP(kcp) (((kcp) & 0x3) << 27) +#define PLLREFE_BASE_KVCO BIT(26) +#define PLLREFE_BASE_DIVP(p) (((p) & 0x1f) << 16) +#define PLLREFE_BASE_DIVN(n) (((n) & 0xff) << 8) +#define PLLREFE_BASE_DIVM(m) (((m) & 0xff) << 0) + +static int tegra_pllref_enable(void) +{ + u32 value; + unsigned long start; + + /* + * This sequence comes from Tegra X1 TRM section "Cold Boot, with no + * Recovery Mode or Boot from USB", sub-section "PLLREFE". + */ + + value = readl(NV_PA_CLK_RST_BASE + PLLREFE_MISC); + value &= ~PLLREFE_MISC_IDDQ; + writel(value, NV_PA_CLK_RST_BASE + PLLREFE_MISC); + + udelay(5); + + value = PLLREFE_BASE_ENABLE | + PLLREFE_BASE_KCP(0) | + PLLREFE_BASE_DIVP(0) | + PLLREFE_BASE_DIVN(0x41) | + PLLREFE_BASE_DIVM(4); + writel(value, NV_PA_CLK_RST_BASE + PLLREFE_BASE); + + debug("waiting for pllrefe lock\n"); + start = get_timer(0); + while (get_timer(start) < 250) { + value = readl(NV_PA_CLK_RST_BASE + PLLREFE_MISC); + if (value & PLLREFE_MISC_LOCK) + break; + } + if (!(value & PLLREFE_MISC_LOCK)) { + debug(" timeout\n"); + return -ETIMEDOUT; + } + debug(" done\n"); + + return 0; +} + #define PLLE_SS_CNTL 0x68 #define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24) #define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) @@ -1041,100 +1095,131 @@ void arch_timer_init(void) #define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) #define PLLE_BASE 0x0e8 -#define PLLE_BASE_ENABLE (1 << 30) -#define PLLE_BASE_LOCK_OVERRIDE (1 << 29) -#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) +#define PLLE_BASE_ENABLE (1 << 31) +#define PLLE_BASE_PLDIV_CML(x) (((x) & 0x1f) << 24) #define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) #define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) #define PLLE_MISC 0x0ec #define PLLE_MISC_IDDQ_SWCTL (1 << 14) -#define PLLE_MISC_IDDQ_OVERRIDE (1 << 13) -#define PLLE_MISC_LOCK_ENABLE (1 << 9) -#define PLLE_MISC_PTS (1 << 8) -#define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4) +#define PLLE_MISC_IDDQ_OVERRIDE_VALUE (1 << 13) +#define PLLE_MISC_LOCK (1 << 11) +#define PLLE_MISC_KCP(x) (((x) & 0x3) << 6) #define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2) +#define PLLE_MISC_KVCO (1 << 0) #define PLLE_AUX 0x48c +#define PLLE_AUX_SS_SEQ_INCLUDE (1 << 31) +#define PLLE_AUX_REF_SEL_PLLREFE (1 << 28) #define PLLE_AUX_SEQ_ENABLE (1 << 24) +#define PLLE_AUX_SS_SWCTL (1 << 6) #define PLLE_AUX_ENABLE_SWCTL (1 << 4) +#define PLLE_AUX_USE_LOCKDET (1 << 3) int tegra_plle_enable(void) { - unsigned int m = 1, n = 200, cpcon = 13; u32 value; + unsigned long start; - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_LOCK_OVERRIDE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + /* PLLREF feeds PLLE */ + tegra_pllref_enable(); + + /* + * This sequence comes from Tegra X1 TRM section "Cold Boot, with no + * Recovery Mode or Boot from USB", sub-section "PLLEs". + */ + + /* 1. Select XTAL as the source */ value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX); - value |= PLLE_AUX_ENABLE_SWCTL; - value &= ~PLLE_AUX_SEQ_ENABLE; + value &= ~PLLE_AUX_REF_SEL_PLLREFE; writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); - udelay(1); - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value |= PLLE_MISC_IDDQ_SWCTL; - value &= ~PLLE_MISC_IDDQ_OVERRIDE; - value |= PLLE_MISC_LOCK_ENABLE; - value |= PLLE_MISC_PTS; - value |= PLLE_MISC_VREG_BG_CTRL(3); - value |= PLLE_MISC_VREG_CTRL(2); + value &= ~PLLE_MISC_IDDQ_OVERRIDE_VALUE; writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + /* 2. Wait 5 us */ udelay(5); - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | - PLLE_SS_CNTL_BYPASS_SS; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + /* + * 3. Program the following registers to generate a low jitter 100MHz + * clock. + */ value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_PLDIV_CML(0xf); + value &= ~PLLE_BASE_PLDIV_CML(0x1f); value &= ~PLLE_BASE_NDIV(0xff); value &= ~PLLE_BASE_MDIV(0xff); - value |= PLLE_BASE_PLDIV_CML(cpcon); - value |= PLLE_BASE_NDIV(n); - value |= PLLE_BASE_MDIV(m); + value |= PLLE_BASE_PLDIV_CML(0xe); + value |= PLLE_BASE_NDIV(0x7d); + value |= PLLE_BASE_MDIV(2); writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - udelay(1); + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value &= ~PLLE_MISC_KCP(3); + value &= ~PLLE_MISC_VREG_CTRL(3); + value &= ~PLLE_MISC_KVCO; + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); value |= PLLE_BASE_ENABLE; writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - /* wait for lock */ - udelay(300); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCINVERT; - value &= ~PLLE_SS_CNTL_SSCCENTER; - - value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f); - value &= ~PLLE_SS_CNTL_SSCINC(0xff); - value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); + /* 4. Wait for LOCK */ - value |= PLLE_SS_CNTL_SSCINCINTR(0x20); - value |= PLLE_SS_CNTL_SSCINC(0x01); - value |= PLLE_SS_CNTL_SSCMAX(0x25); + debug("waiting for plle lock\n"); + start = get_timer(0); + while (get_timer(start) < 250) { + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if (value & PLLE_MISC_LOCK) + break; + } + if (!(value & PLLE_MISC_LOCK)) { + debug(" timeout\n"); + return -ETIMEDOUT; + } + debug(" done\n"); - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + /* 5. Enable SSA */ value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCBYP; + value &= ~PLLE_SS_CNTL_SSCINC(0xff); + value |= PLLE_SS_CNTL_SSCINC(1); + value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f); + value |= PLLE_SS_CNTL_SSCINCINTR(0x23); + value &= ~PLLE_SS_CNTL_SSCMAX(0x1fff); + value |= PLLE_SS_CNTL_SSCMAX(0x21); + value &= ~PLLE_SS_CNTL_SSCINVERT; + value &= ~PLLE_SS_CNTL_SSCCENTER; value &= ~PLLE_SS_CNTL_BYPASS_SS; + value &= ~PLLE_SS_CNTL_SSCBYP; writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - udelay(1); + /* 6. Wait 300 ns */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + udelay(1); value &= ~PLLE_SS_CNTL_INTERP_RESET; writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + /* 7. Enable HW power sequencer for PLLE */ + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value &= ~PLLE_MISC_IDDQ_SWCTL; + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX); + value &= ~PLLE_AUX_SS_SWCTL; + value &= ~PLLE_AUX_ENABLE_SWCTL; + value |= PLLE_AUX_SS_SEQ_INCLUDE; + value |= PLLE_AUX_USE_LOCKDET; + writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); + + /* 8. Wait 1 us */ + udelay(1); + value |= PLLE_AUX_SEQ_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); return 0; } diff --git a/arch/arm/mach-tegra/tegra210/xusb-padctl.c b/arch/arm/mach-tegra/tegra210/xusb-padctl.c index 3c10a96aa3..9ec93e7c4c 100644 --- a/arch/arm/mach-tegra/tegra210/xusb-padctl.c +++ b/arch/arm/mach-tegra/tegra210/xusb-padctl.c @@ -8,51 +8,82 @@ #include <common.h> #include <errno.h> -#include <fdtdec.h> -#include <malloc.h> -#include <asm/io.h> +#include "../xusb-padctl-common.h" #include <asm/arch/clock.h> -#include <asm/arch-tegra/xusb-padctl.h> #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> -struct tegra_xusb_phy_ops { - int (*prepare)(struct tegra_xusb_phy *phy); - int (*enable)(struct tegra_xusb_phy *phy); - int (*disable)(struct tegra_xusb_phy *phy); - int (*unprepare)(struct tegra_xusb_phy *phy); +enum tegra210_function { + TEGRA210_FUNC_SNPS, + TEGRA210_FUNC_XUSB, + TEGRA210_FUNC_UART, + TEGRA210_FUNC_PCIE_X1, + TEGRA210_FUNC_PCIE_X4, + TEGRA210_FUNC_USB3, + TEGRA210_FUNC_SATA, + TEGRA210_FUNC_RSVD, }; -struct tegra_xusb_phy { - const struct tegra_xusb_phy_ops *ops; - - struct tegra_xusb_padctl *padctl; +static const char *const tegra210_functions[] = { + "snps", + "xusb", + "uart", + "pcie-x1", + "pcie-x4", + "usb3", + "sata", + "rsvd", }; -struct tegra_xusb_padctl { - struct fdt_resource regs; +static const unsigned int tegra210_otg_functions[] = { + TEGRA210_FUNC_SNPS, + TEGRA210_FUNC_XUSB, + TEGRA210_FUNC_UART, + TEGRA210_FUNC_RSVD, +}; - unsigned int enable; +static const unsigned int tegra210_usb_functions[] = { + TEGRA210_FUNC_SNPS, + TEGRA210_FUNC_XUSB, +}; - struct tegra_xusb_phy phys[2]; +static const unsigned int tegra210_pci_functions[] = { + TEGRA210_FUNC_PCIE_X1, + TEGRA210_FUNC_USB3, + TEGRA210_FUNC_SATA, + TEGRA210_FUNC_PCIE_X4, }; -static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, - unsigned long offset) -{ - u32 value = readl(padctl->regs.start + offset); - debug("padctl: %08lx > %08x\n", offset, value); - return value; -} +#define TEGRA210_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ + { \ + .name = _name, \ + .offset = _offset, \ + .shift = _shift, \ + .mask = _mask, \ + .iddq = _iddq, \ + .num_funcs = ARRAY_SIZE(tegra210_##_funcs##_functions), \ + .funcs = tegra210_##_funcs##_functions, \ + } -static inline void padctl_writel(struct tegra_xusb_padctl *padctl, - u32 value, unsigned long offset) -{ - debug("padctl: %08lx < %08x\n", offset, value); - writel(value, padctl->regs.start + offset); -} +static const struct tegra_xusb_padctl_lane tegra210_lanes[] = { + TEGRA210_LANE("otg-0", 0x004, 0, 0x3, 0, otg), + TEGRA210_LANE("otg-1", 0x004, 2, 0x3, 0, otg), + TEGRA210_LANE("otg-2", 0x004, 4, 0x3, 0, otg), + TEGRA210_LANE("otg-3", 0x004, 6, 0x3, 0, otg), + TEGRA210_LANE("usb2-bias", 0x004, 18, 0x3, 0, otg), + TEGRA210_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), + TEGRA210_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), + TEGRA210_LANE("pcie-0", 0x028, 12, 0x3, 1, pci), + TEGRA210_LANE("pcie-1", 0x028, 14, 0x3, 2, pci), + TEGRA210_LANE("pcie-2", 0x028, 16, 0x3, 3, pci), + TEGRA210_LANE("pcie-3", 0x028, 18, 0x3, 4, pci), + TEGRA210_LANE("pcie-4", 0x028, 20, 0x3, 5, pci), + TEGRA210_LANE("pcie-5", 0x028, 22, 0x3, 6, pci), + TEGRA210_LANE("pcie-6", 0x028, 24, 0x3, 7, pci), + TEGRA210_LANE("sata-0", 0x028, 30, 0x3, 8, pci), +}; #define XUSB_PADCTL_ELPG_PROGRAM 0x024 #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31) @@ -248,7 +279,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy) if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) break; } - + if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)) { + debug(" timeout\n"); + return -ETIMEDOUT; + } debug(" done\n"); value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); @@ -264,7 +298,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy) if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0) break; } - + if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) { + debug(" timeout\n"); + return -ETIMEDOUT; + } debug(" done\n"); value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); @@ -279,7 +316,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy) if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS) break; } - + if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)) { + debug(" timeout\n"); + return -ETIMEDOUT; + } debug(" done\n"); value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); @@ -295,7 +335,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy) if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) break; } - + if (!(value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)) { + debug(" timeout\n"); + return -ETIMEDOUT; + } debug(" done\n"); value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); @@ -310,7 +353,10 @@ static int pcie_phy_enable(struct tegra_xusb_phy *phy) if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0) break; } - + if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) { + debug(" timeout\n"); + return -ETIMEDOUT; + } debug(" done\n"); value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); @@ -358,120 +404,22 @@ static const struct tegra_xusb_phy_ops pcie_phy_ops = { .unprepare = phy_unprepare, }; -static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) { - .phys = { - [0] = { - .ops = &pcie_phy_ops, - }, +static struct tegra_xusb_phy tegra210_phys[] = { + { + .type = TEGRA_XUSB_PADCTL_PCIE, + .ops = &pcie_phy_ops, + .padctl = &padctl, }, }; -static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, - const void *fdt, int node) -{ - int err; - - err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); - if (err < 0) { - error("registers not found"); - return err; - } - - debug("regs: %pa-%pa\n", &padctl->regs.start, - &padctl->regs.end); - - return 0; -} - -static int process_nodes(const void *fdt, int nodes[], unsigned int count) -{ - unsigned int i; - int err; - - debug("> %s(fdt=%p, nodes=%p, count=%u)\n", __func__, fdt, nodes, - count); - - for (i = 0; i < count; i++) { - enum fdt_compat_id id; - - if (!fdtdec_get_is_enabled(fdt, nodes[i])) - continue; - - id = fdtdec_lookup(fdt, nodes[i]); - switch (id) { - case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: - case COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL: - break; - - default: - error("unsupported compatible: %s", - fdtdec_get_compatible(id)); - continue; - } - - err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); - if (err < 0) { - error("failed to parse DT: %d", - err); - continue; - } - - /* deassert XUSB padctl reset */ - reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); - - /* only a single instance is supported */ - break; - } - - debug("< %s()\n", __func__); - return 0; -} - -struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type) -{ - struct tegra_xusb_phy *phy = NULL; - - switch (type) { - case TEGRA_XUSB_PADCTL_PCIE: - phy = &padctl->phys[0]; - phy->padctl = padctl; - break; - } - - return phy; -} - -int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->prepare) - return phy->ops->prepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->enable) - return phy->ops->enable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->disable) - return phy->ops->disable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->unprepare) - return phy->ops->unprepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} +static const struct tegra_xusb_padctl_soc tegra210_socdata = { + .lanes = tegra210_lanes, + .num_lanes = ARRAY_SIZE(tegra210_lanes), + .functions = tegra210_functions, + .num_functions = ARRAY_SIZE(tegra210_functions), + .phys = tegra210_phys, + .num_phys = ARRAY_SIZE(tegra210_phys), +}; void tegra_xusb_padctl_init(const void *fdt) { @@ -482,13 +430,7 @@ void tegra_xusb_padctl_init(const void *fdt) count = fdtdec_find_aliases_for_id(fdt, "padctl", COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, nodes, ARRAY_SIZE(nodes)); - if (process_nodes(fdt, nodes, count)) - return; - - count = fdtdec_find_aliases_for_id(fdt, "padctl", - COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, - nodes, ARRAY_SIZE(nodes)); - if (process_nodes(fdt, nodes, count)) + if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra210_socdata)) return; debug("< %s()\n", __func__); diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c new file mode 100644 index 0000000000..18ad7bfbdc --- /dev/null +++ b/arch/arm/mach-tegra/xusb-padctl-common.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt + +#include <common.h> +#include <errno.h> + +#include "xusb-padctl-common.h" + +#include <asm/arch/clock.h> + +int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->prepare) + return phy->ops->prepare(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->enable) + return phy->ops->enable(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->disable) + return phy->ops->disable(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->unprepare) + return phy->ops->unprepare(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type) +{ + struct tegra_xusb_phy *phy; + int i; + + for (i = 0; i < padctl.socdata->num_phys; i++) { + phy = &padctl.socdata->phys[i]; + if (phy->type != type) + continue; + return phy; + } + + return NULL; +} + +static const struct tegra_xusb_padctl_lane * +tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name) +{ + unsigned int i; + + for (i = 0; i < padctl->socdata->num_lanes; i++) + if (strcmp(name, padctl->socdata->lanes[i].name) == 0) + return &padctl->socdata->lanes[i]; + + return NULL; +} + +static int +tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_group *group, + const void *fdt, int node) +{ + unsigned int i; + int len, err; + + group->name = fdt_get_name(fdt, node, &len); + + len = fdt_count_strings(fdt, node, "nvidia,lanes"); + if (len < 0) { + error("failed to parse \"nvidia,lanes\" property"); + return -EINVAL; + } + + group->num_pins = len; + + for (i = 0; i < group->num_pins; i++) { + err = fdt_get_string_index(fdt, node, "nvidia,lanes", i, + &group->pins[i]); + if (err < 0) { + error("failed to read string from \"nvidia,lanes\" property"); + return -EINVAL; + } + } + + group->num_pins = len; + + err = fdt_get_string(fdt, node, "nvidia,function", &group->func); + if (err < 0) { + error("failed to parse \"nvidia,func\" property"); + return -EINVAL; + } + + group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); + + return 0; +} + +static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl, + const char *name) +{ + unsigned int i; + + for (i = 0; i < padctl->socdata->num_functions; i++) + if (strcmp(name, padctl->socdata->functions[i]) == 0) + return i; + + return -ENOENT; +} + +static int +tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl, + const struct tegra_xusb_padctl_lane *lane, + const char *name) +{ + unsigned int i; + int func; + + func = tegra_xusb_padctl_find_function(padctl, name); + if (func < 0) + return func; + + for (i = 0; i < lane->num_funcs; i++) + if (lane->funcs[i] == func) + return i; + + return -ENOENT; +} + +static int +tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl, + const struct tegra_xusb_padctl_group *group) +{ + unsigned int i; + + for (i = 0; i < group->num_pins; i++) { + const struct tegra_xusb_padctl_lane *lane; + unsigned int func; + u32 value; + + lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]); + if (!lane) { + error("no lane for pin %s", group->pins[i]); + continue; + } + + func = tegra_xusb_padctl_lane_find_function(padctl, lane, + group->func); + if (func < 0) { + error("function %s invalid for lane %s: %d", + group->func, lane->name, func); + continue; + } + + value = padctl_readl(padctl, lane->offset); + + /* set pin function */ + value &= ~(lane->mask << lane->shift); + value |= func << lane->shift; + + /* + * Set IDDQ if supported on the lane and specified in the + * configuration. + */ + if (lane->iddq > 0 && group->iddq >= 0) { + if (group->iddq != 0) + value &= ~(1 << lane->iddq); + else + value |= 1 << lane->iddq; + } + + padctl_writel(padctl, value, lane->offset); + } + + return 0; +} + +static int +tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_config *config) +{ + unsigned int i; + + for (i = 0; i < config->num_groups; i++) { + const struct tegra_xusb_padctl_group *group; + int err; + + group = &config->groups[i]; + + err = tegra_xusb_padctl_group_apply(padctl, group); + if (err < 0) { + error("failed to apply group %s: %d", + group->name, err); + continue; + } + } + + return 0; +} + +static int +tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_config *config, + const void *fdt, int node) +{ + int subnode; + + config->name = fdt_get_name(fdt, node, NULL); + + fdt_for_each_subnode(fdt, subnode, node) { + struct tegra_xusb_padctl_group *group; + int err; + + group = &config->groups[config->num_groups]; + + err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt, + subnode); + if (err < 0) { + error("failed to parse group %s", group->name); + return err; + } + + config->num_groups++; + } + + return 0; +} + +static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, + const void *fdt, int node) +{ + int subnode, err; + + err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); + if (err < 0) { + error("registers not found"); + return err; + } + + fdt_for_each_subnode(fdt, subnode, node) { + struct tegra_xusb_padctl_config *config = &padctl->config; + + err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt, + subnode); + if (err < 0) { + error("failed to parse entry %s: %d", + config->name, err); + continue; + } + } + + return 0; +} + +struct tegra_xusb_padctl padctl; + +int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, + const struct tegra_xusb_padctl_soc *socdata) +{ + unsigned int i; + int err; + + for (i = 0; i < count; i++) { + if (!fdtdec_get_is_enabled(fdt, nodes[i])) + continue; + + padctl.socdata = socdata; + + err = tegra_xusb_padctl_parse_dt(&padctl, fdt, nodes[i]); + if (err < 0) { + error("failed to parse DT: %d", err); + continue; + } + + /* deassert XUSB padctl reset */ + reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); + + err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config); + if (err < 0) { + error("failed to apply pinmux: %d", err); + continue; + } + + /* only a single instance is supported */ + break; + } + + return 0; +} diff --git a/arch/arm/mach-tegra/xusb-padctl-common.h b/arch/arm/mach-tegra/xusb-padctl-common.h new file mode 100644 index 0000000000..f44790a650 --- /dev/null +++ b/arch/arm/mach-tegra/xusb-padctl-common.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _TEGRA_XUSB_PADCTL_COMMON_H_ +#define _TEGRA_XUSB_PADCTL_COMMON_H_ + +#include <common.h> +#include <fdtdec.h> + +#include <asm/io.h> +#include <asm/arch-tegra/xusb-padctl.h> + +struct tegra_xusb_padctl_lane { + const char *name; + + unsigned int offset; + unsigned int shift; + unsigned int mask; + unsigned int iddq; + + const unsigned int *funcs; + unsigned int num_funcs; +}; + +struct tegra_xusb_phy_ops { + int (*prepare)(struct tegra_xusb_phy *phy); + int (*enable)(struct tegra_xusb_phy *phy); + int (*disable)(struct tegra_xusb_phy *phy); + int (*unprepare)(struct tegra_xusb_phy *phy); +}; + +struct tegra_xusb_phy { + unsigned int type; + const struct tegra_xusb_phy_ops *ops; + struct tegra_xusb_padctl *padctl; +}; + +struct tegra_xusb_padctl_pin { + const struct tegra_xusb_padctl_lane *lane; + + unsigned int func; + int iddq; +}; + +#define MAX_GROUPS 5 +#define MAX_PINS 7 + +struct tegra_xusb_padctl_group { + const char *name; + + const char *pins[MAX_PINS]; + unsigned int num_pins; + + const char *func; + int iddq; +}; + +struct tegra_xusb_padctl_soc { + const struct tegra_xusb_padctl_lane *lanes; + unsigned int num_lanes; + const char *const *functions; + unsigned int num_functions; + struct tegra_xusb_phy *phys; + unsigned int num_phys; +}; + +struct tegra_xusb_padctl_config { + const char *name; + + struct tegra_xusb_padctl_group groups[MAX_GROUPS]; + unsigned int num_groups; +}; + +struct tegra_xusb_padctl { + const struct tegra_xusb_padctl_soc *socdata; + struct tegra_xusb_padctl_config config; + struct fdt_resource regs; + unsigned int enable; + +}; +extern struct tegra_xusb_padctl padctl; + +static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, + unsigned long offset) +{ + return readl(padctl->regs.start + offset); +} + +static inline void padctl_writel(struct tegra_xusb_padctl *padctl, + u32 value, unsigned long offset) +{ + writel(value, padctl->regs.start + offset); +} + +int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, + const struct tegra_xusb_padctl_soc *socdata); + +#endif diff --git a/arch/arm/mach-tegra/xusb-padctl.c b/arch/arm/mach-tegra/xusb-padctl-dummy.c index 65f8d2ea96..65f8d2ea96 100644 --- a/arch/arm/mach-tegra/xusb-padctl.c +++ b/arch/arm/mach-tegra/xusb-padctl-dummy.c diff --git a/arch/openrisc/config.mk b/arch/openrisc/config.mk index cd95f24b1f..bfdb71f0be 100644 --- a/arch/openrisc/config.mk +++ b/arch/openrisc/config.mk @@ -6,7 +6,7 @@ # ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := or32-elf- +CROSS_COMPILE := or1k-elf- endif # r10 used for global object pointer, already set in OR32 GCC but just to be diff --git a/arch/openrisc/cpu/u-boot.lds b/arch/openrisc/cpu/u-boot.lds index d9bb7b7f87..854088b880 100644 --- a/arch/openrisc/cpu/u-boot.lds +++ b/arch/openrisc/cpu/u-boot.lds @@ -1,5 +1,5 @@ #include <config.h> -OUTPUT_ARCH(or32) +OUTPUT_ARCH(or1k) __DYNAMIC = 0; MEMORY diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig index 3fb901f2a1..3ea62caada 100644 --- a/arch/powerpc/cpu/mpc83xx/Kconfig +++ b/arch/powerpc/cpu/mpc83xx/Kconfig @@ -67,6 +67,9 @@ config TARGET_TQM834X config TARGET_HRCON bool "Support hrcon" +config TARGET_STRIDER + bool "Support strider" + endchoice source "board/esd/vme8349/Kconfig" diff --git a/arch/sparc/config.mk b/arch/sparc/config.mk index d615f294fe..43faad48ce 100644 --- a/arch/sparc/config.mk +++ b/arch/sparc/config.mk @@ -1,19 +1,25 @@ # -# (C) Copyright 2007 -# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com +# (C) Copyright 2015 +# Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. # # SPDX-License-Identifier: GPL-2.0+ # ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := sparc-elf- +CROSS_COMPILE := sparc-linux- endif +# This GCC compiler is known to work: +# https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/ + gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`) CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) \ -T $(srctree)/examples/standalone/sparc.lds -PLATFORM_CPPFLAGS += -D__sparc__ +cpuflags-$(CONFIG_LEON2) := -mcpu=leon +cpuflags-$(CONFIG_LEON3) := -mcpu=leon3 + +PLATFORM_CPPFLAGS += $(cpuflags-y) PLATFORM_RELFLAGS += -fPIC diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c index 5cfbb9ed15..603364ee0b 100644 --- a/arch/sparc/cpu/leon2/serial.c +++ b/arch/sparc/cpu/leon2/serial.c @@ -1,72 +1,78 @@ /* GRLIB APBUART Serial controller driver * - * (C) Copyright 2008 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2008, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/processor.h> -#include <asm/leon.h> +#include <asm/io.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; +static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud) +{ + return (((freq*10) / (baud*8)) - 5) / 10; +} + static int leon2_serial_init(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; + LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS; LEON2_Uart_regs *regs; unsigned int tmp; - /* Init LEON2 UART - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; + regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1; #else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; + regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2; #endif - regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER; + /* Set scaler / baud rate */ + tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); + writel(tmp, ®s->UART_Scaler); /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(regs->UART_Control); + tmp = readl(®s->UART_Control) & LEON2_UART_CTRL_DBG; + tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7); + tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6); + tmp |= (LEON2_UART1_PARITY_ENABLE << 5); + tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4); + /* Receiver & transmitter enable */ + tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); + writel(tmp, ®s->UART_Control); + + gd->arch.uart = regs; + return 0; +} - regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) | - (LEON2_UART1_LOOPBACK_ENABLE << 7) | - (LEON2_UART1_FLOWCTRL_ENABLE << 6) | - (LEON2_UART1_PARITY_ENABLE << 5) | - (LEON2_UART1_ODDPAR_ENABLE << 4) | - LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); +static inline LEON2_Uart_regs *leon2_get_uart_regs(void) +{ + LEON2_Uart_regs *uart = gd->arch.uart; - return 0; + return uart; } static void leon2_serial_putc_raw(const char c) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; /* Wait for last character to go. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE)) + WATCHDOG_RESET(); /* Send data */ - regs->UART_Channel = c; + writel(c, &uart->UART_Channel); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE)) + WATCHDOG_RESET(); #endif } @@ -80,56 +86,43 @@ static void leon2_serial_putc(const char c) static int leon2_serial_getc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; /* Wait for a character to arrive. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(regs->UART_Channel); + /* Read character data */ + return readl(&uart->UART_Channel); } static int leon2_serial_tstc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; - return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR); + return readl(&uart->UART_Status) & LEON2_UART_STAT_DR; } -/* set baud rate for uart */ static void leon2_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + LEON2_Uart_regs *uart = leon2_get_uart_regs(); unsigned int scaler; - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); - if (gd->baudrate > 0) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - regs->UART_Scaler = scaler; - } + writel(scaler, &uart->UART_Scaler); } static struct serial_device leon2_serial_drv = { diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index e43097cf9b..974de76852 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -57,6 +57,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4) #error Must define number of SPARC register windows, default is 8 #endif +/* Macros to load address into a register. Uses GOT table for PIC */ +#ifdef __PIC__ + +#define SPARC_PIC_THUNK_CALL(reg) \ + sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ + call __sparc_get_pc_thunk.reg; \ + add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg; + +#define SPARC_LOAD_ADDRESS(sym, got, reg) \ + sethi %gdop_hix22(sym), %##reg; \ + xor %##reg, %gdop_lox10(sym), %##reg; \ + ld [%##got + %##reg], %##reg, %gdop(sym); + +#else + +#define SPARC_PIC_THUNK_CALL(reg) +#define SPARC_LOAD_ADDRESS(sym, got, tmp) \ + set sym, %##reg; + +#endif + #define STACK_ALIGN 8 #define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) @@ -278,7 +299,7 @@ leon2_init_mctrl: srl %g2, 30, %g2 andcc %g2, 3, %g6 bne,a leon2_init_wim - mov %g0, %asr16 ! clear err_reg + mov %g0, %asr16 ! clear err_reg leon2_init_wim: set WIM_INIT, %g3 @@ -299,7 +320,7 @@ leon2_init_stackp: cpu_init_unreloc: call cpu_init_f - nop + nop /* un relocated start address of monitor */ #define TEXT_START _text @@ -307,9 +328,10 @@ cpu_init_unreloc: /* un relocated end address of monitor */ #define DATA_END __init_end + SPARC_PIC_THUNK_CALL(l7) reloc: - set TEXT_START,%g2 - set DATA_END,%g3 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) + SPARC_LOAD_ADDRESS(DATA_END, l7, g3) set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 reloc_loop: ldd [%g2],%l0 @@ -319,7 +341,7 @@ reloc_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne reloc_loop - inc 16,%g4 + inc 16,%g4 clr %l0 clr %l1 @@ -336,8 +358,8 @@ reloc_loop: clr_bss: /* clear bss area (the relocated) */ - set __bss_start,%g2 - set __bss_end,%g3 + SPARC_LOAD_ADDRESS(__bss_start, l7, g2) + SPARC_LOAD_ADDRESS(__bss_end, l7, g3) sub %g3,%g2,%g3 add %g3,%g4,%g3 clr %g1 /* std %g0 uses g0 and g1 */ @@ -348,19 +370,19 @@ clr_bss_16: inc 16,%g4 cmp %g3,%g4 bne clr_bss_16 - nop + nop /* add offsets to GOT table */ fixup_got: - set __got_start,%g4 - set __got_end,%g3 + SPARC_LOAD_ADDRESS(__got_start, l7, g4) + SPARC_LOAD_ADDRESS(__got_end, l7, g3) /* * new got offset = (old GOT-PTR (read with ld) - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + * Destination Address (from define) */ set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - set TEXT_START, %g1 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) add %g4,%g2,%g4 sub %g4,%g1,%g4 add %g3,%g2,%g3 @@ -375,11 +397,11 @@ got_loop: inc 4,%g4 cmp %g3,%g4 bne got_loop - nop + nop prom_relocate: - set __prom_start, %g2 - set __prom_end, %g3 + SPARC_LOAD_ADDRESS(__prom_start, l7, g2) + SPARC_LOAD_ADDRESS(__prom_end, l7, g3) set CONFIG_SYS_PROM_OFFSET, %g4 prom_relocate_loop: @@ -390,7 +412,7 @@ prom_relocate_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne prom_relocate_loop - inc 16,%g4 + inc 16,%g4 /* Trap table has been moved, lets tell CPU about * the new trap table address @@ -403,19 +425,19 @@ prom_relocate_loop: nop /* Call relocated init functions */ jump: - set cpu_init_f2,%o1 + SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 add %o1,%o2,%o1 sub %o1,%g1,%o1 call %o1 - clr %o0 + clr %o0 - set board_init_f,%o1 + SPARC_LOAD_ADDRESS(board_init_f, l7, o1) set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 add %o1,%o2,%o1 sub %o1,%g1,%o1 call %o1 - clr %o0 + clr %o0 dead: ta 0 ! if call returns... nop diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile index 4f13ec3071..f4cf43cfec 100644 --- a/arch/sparc/cpu/leon3/Makefile +++ b/arch/sparc/cpu/leon3/Makefile @@ -6,4 +6,5 @@ # extra-y = start.o -obj-y = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o +obj-y = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \ + interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index a30d1f2a99..b8ac05faf1 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -1,343 +1,316 @@ -/* Gaisler AMBA Plug&Play bus scanning. Functions - * ending on _nomem is inteded to be used only during - * initialization, only registers are used (no ram). +/* GRLIB AMBA Plug&Play information scanning, relies on assembler + * routines. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ +/* #define DEBUG */ + #include <common.h> -#include <command.h> +#include <malloc.h> #include <ambapp.h> +#include <config.h> + +/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/ +struct ambapp_find_apb_info { + /* Address of APB device Plug&Play information */ + struct ambapp_pnp_apb *pnp; + /* AHB Bus index of where the APB-Master Bridge device was found */ + int ahb_bus_index; + int dec_index; +}; -#if defined(CONFIG_CMD_AMBAPP) -extern void ambapp_print_apb(apbctrl_pp_dev * apb, - ambapp_ahbdev * apbmst, int index); -extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index); -extern int ambapp_apb_print; -extern int ambapp_ahb_print; -#endif - -static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_apbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - ) -{ - int i, cnt = 0; - unsigned int apbmst_base; - ambapp_ahbdev apbmst; - apbctrl_pp_dev *apb; - - if (max_cnt == 0) - return 0; - - /* Get AMBA APB Master */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) { - return 0; - } +struct ambapp_find_ahb_info { + /* Address of AHB device Plug&Play information */ + struct ambapp_pnp_ahb *pnp; + /* AHB Bus index of where the AHB device was found */ + int ahb_bus_index; + int dec_index; +}; - /* Get APB CTRL Plug&Play info area */ - apbmst_base = apbmst.address[0] & LEON3_IO_AREA; - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); +extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus); - for (i = 0; i < LEON3_APB_SLAVES; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_apb_print && amba_vendor(apb->conf) - && amba_device(apb->conf)) { - ambapp_print_apb(apb, &apbmst, i); - } -#endif - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info into a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(apb->conf); - dev->ver = amba_ver(apb->conf); - dev->address = - (apbmst_base | - (((apb-> - bar & 0xfff00000) >> 12))) & (((apb-> - bar & - 0x0000fff0) - << 4) | - 0xfff00000); - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - apb++; - } - return cnt; -} +extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend, + int index, struct ambapp_find_apb_info *result); -unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register int index) -{ - register int i; - register ahbctrl_pp_dev *apbmst; - register apbctrl_pp_dev *apb; - register unsigned int apbmst_base; - - /* APBMST is a AHB Slave */ - apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) - return 0; - - apbmst_base = amba_membar_start(apbmst->bars[0]); - if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO) - apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base); - apbmst_base &= LEON3_IO_AREA; - - /* Find the vendor/driver device on the first APB bus */ - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); - - for (i = 0; i < LEON3_APB_SLAVES; i++) { - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) - & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000); - } - /* Get next Plug&Play entry */ - apb++; - } - return 0; -} +extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend, + int index, int type, struct ambapp_find_ahb_info *result); -/****************************** APB SLAVES ******************************/ +/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/ +struct ambapp_bus ambapp_plb; -int ambapp_apb_count(unsigned int vendor, unsigned int driver) +void ambapp_bus_init( + unsigned int ioarea, + unsigned int freq, + struct ambapp_bus *abus) { - return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES); + int i; + + ambapp_find_buses(ioarea, abus); + for (i = 0; i < 6; i++) + if (abus->ioareas[i] == 0) + break; + abus->buses = i; + abus->freq = freq; } -int ambapp_apb_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev) +/* Parse APB PnP Information */ +void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, 0, 1); + struct ambapp_pnp_apb *apb = info->pnp; + unsigned int apbbase = (unsigned int)apb & 0xfff00000; + + dev->vendor = amba_vendor(apb->id); + dev->device = amba_device(apb->id); + dev->irq = amba_irq(apb->id); + dev->ver = amba_ver(apb->id); + dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) & + (((apb->iobar & 0x0000fff0) << 4) | 0xfff00000); + dev->mask = amba_apb_mask(apb->iobar); + dev->ahb_bus_index = info->ahb_bus_index - 1; } -int ambapp_apb_next(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int index) +/* Parse AHB PnP information */ +void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, index, 1); + struct ambapp_pnp_ahb *ahb = info->pnp; + unsigned int ahbbase = (unsigned int)ahb & 0xfff00000; + int i, type; + unsigned int addr, mask, mbar; + + dev->vendor = amba_vendor(ahb->id); + dev->device = amba_device(ahb->id); + dev->irq = amba_irq(ahb->id); + dev->ver = amba_ver(ahb->id); + dev->userdef[0] = ahb->custom[0]; + dev->userdef[1] = ahb->custom[1]; + dev->userdef[2] = ahb->custom[2]; + dev->ahb_bus_index = info->ahb_bus_index - 1; + for (i = 0; i < 4; i++) { + mbar = ahb->mbar[i]; + addr = amba_membar_start(mbar); + type = amba_membar_type(mbar); + if (type == AMBA_TYPE_AHBIO) { + addr = amba_ahbio_adr(addr, ahbbase); + mask = (((unsigned int) + (amba_membar_mask((~mbar))<<8)|0xff))+1; + } else { + /* AHB memory area, absolute address */ + mask = (~((unsigned int) + (amba_membar_mask(mbar)<<20)))+1; + } + dev->address[i] = addr; + dev->mask[i] = mask; + dev->type[i] = type; + } } -int ambapp_apbs_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int max_cnt) +int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_apbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt); -} + unsigned int devid = AMBA_PNP_ID(vendor, device); + int found; + struct ambapp_find_apb_info apbdev; -enum { - AHB_SCAN_MASTER = 0, - AHB_SCAN_SLAVE = 1 -}; - -/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves - * for a certain matching Vendor and Device ID. - * - * Return number of devices found. - * - * Compact edition... - */ -static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_ahbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt, /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - int type /* Selectes what type of devices to scan. - * 0=AHB Masters - * 1=AHB Slaves - */ - ) -{ - int i, j, cnt = 0, max_pp_devs; - unsigned int addr; - ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - ahbctrl_pp_dev *ahb; - - if (max_cnt == 0) - return 0; - - if (type == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } + found = ambapp_find_apb(abus, devid, index, &apbdev); + if (found == 1) + ambapp_apb_parse(&apbdev, dev); - for (i = 0; i < max_pp_devs; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_ahb_print && amba_vendor(ahb->conf) && - amba_device(ahb->conf)) { - ambapp_print_ahb(ahb, i); - } -#endif - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(ahb->conf); - dev->ver = amba_ver(ahb->conf); - dev->userdef[0] = ahb->userdef[0]; - dev->userdef[1] = ahb->userdef[1]; - dev->userdef[2] = ahb->userdef[2]; - for (j = 0; j < 4; j++) { - addr = amba_membar_start(ahb->bars[j]); - if (amba_membar_type(ahb->bars[j]) == - AMBA_TYPE_AHBIO) - addr = - AMBA_TYPE_AHBIO_ADDR(addr); - dev->address[j] = addr; - } - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - ahb++; - } - return cnt; + return found; } -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info) +int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device) { - register unsigned int ret; - - if (!ahb) - return 0; - - switch (info) { - default: - info = 0; - case 0: - case 1: - case 2: - case 3: - /* Get Address from PnP Info */ - ret = amba_membar_start(ahb->bars[info]); - if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO) - ret = AMBA_TYPE_AHBIO_ADDR(ret); - return ret; - } - return 0; - + unsigned int devid = AMBA_PNP_ID(vendor, device); + int found; + struct ambapp_find_apb_info apbdev; + + found = ambapp_find_apb(abus, devid, 63, &apbdev); + if (found == 1) + return 64; + else + return 63 - apbdev.dec_index; } -ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register unsigned int opts, /* 1=slave, 0=master */ - register int index) +int ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev, int type) { - register ahbctrl_pp_dev *ahb; - register ahbctrl_info *info = - (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - register int i; - register int max_pp_devs; - - if (opts == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } + int found; + struct ambapp_find_ahb_info ahbdev; + unsigned int devid = AMBA_PNP_ID(vendor, device); - for (i = 0; i < max_pp_devs; i++) { - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return ahb; - } - /* Get next Plug&Play entry */ - ahb++; - } - return 0; + found = ambapp_find_ahb(abus, devid, index, type, &ahbdev); + if (found == 1) + ambapp_ahb_parse(&ahbdev, dev); + + return found; } -/****************************** AHB MASTERS ******************************/ -int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver) +int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev) { - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS, - AHB_SCAN_MASTER); + return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST); } -int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) +int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER); + return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV); } -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) +int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER); + int found; + struct ambapp_find_ahb_info ahbdev; + unsigned int devid = AMBA_PNP_ID(vendor, device); + + found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev); + if (found == 1) + return 64; + else + return 63 - ahbdev.dec_index; } -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) +int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, - AHB_SCAN_MASTER); + return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST); } -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver) +int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device) { - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES, - AHB_SCAN_SLAVE); + return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV); } -int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) +/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems + * where only one AHB Bus is available - no bridges are present. This option + * is available only to reduce the footprint. + * + * Defining this on a multi-bus GRLIB system may also work depending on the + * design. + */ + +#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS + +/* GAISLER AHB2AHB Version 1 Bridge Definitions */ +#define AHB2AHB_V1_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */ +#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100 /* Factor direction, 0=down, 1=up */ +#define AHB2AHB_V1_FLAG_MBUS 0x00c /* Master bus number mask */ +#define AHB2AHB_V1_FLAG_SBUS 0x003 /* Slave bus number mask */ + +/* Get Parent bus frequency. Note that since we go from a "child" bus + * to a parent bus, the frequency factor direction is inverted. + */ +unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE); + int dir; + unsigned char ffact; + + /* Get division/multiple factor */ + ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4; + if (ffact != 0) { + dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR; + + /* Calculate frequency by dividing or + * multiplying system frequency + */ + if (dir) + freq = freq * ffact; + else + freq = freq / ffact; + } + + return freq; } -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) +/* AHB2AHB and L2CACHE ver 2 is not supported yet. */ +unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE); + panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n"); + return -1; } +#endif -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) +/* Return the frequency of a AHB bus identified by index found + * note that this is not the AHB Bus number. + */ +unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE); + unsigned int freq = abus->freq; +#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS + unsigned int ioarea, ioarea_parent, bridge_pnp_ofs; + struct ambapp_find_ahb_info ahbinfo; + ambapp_ahbdev ahb; + int parent; + + debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index); + + while (ahb_bus_index != 0) { + debug(" BUS[0]: 0x%08x\n", abus->ioareas[0]); + debug(" BUS[1]: 0x%08x\n", abus->ioareas[1]); + debug(" BUS[2]: 0x%08x\n", abus->ioareas[2]); + debug(" BUS[3]: 0x%08x\n", abus->ioareas[3]); + debug(" BUS[4]: 0x%08x\n", abus->ioareas[4]); + debug(" BUS[5]: 0x%08x\n", abus->ioareas[5]); + + /* Get I/O area of AHB bus */ + ioarea = abus->ioareas[ahb_bus_index]; + + debug(" IOAREA: 0x%08x\n", ioarea); + + /* Get parent bus */ + parent = (ioarea & 0x7); + if (parent == 0) { + panic("%s: parent=0 indicates no parent! Stopping.\n", + __func__); + return -1; + } + parent = parent - 1; + bridge_pnp_ofs = ioarea & 0x7e0; + + debug(" PARENT: %d\n", parent); + debug(" BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs); + + /* Get AHB/AHB bridge PnP address */ + ioarea_parent = (abus->ioareas[parent] & 0xfff00000) | + AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA; + ahbinfo.pnp = (struct ambapp_pnp_ahb *) + (ioarea_parent | bridge_pnp_ofs); + + debug(" IOAREA PARENT: 0x%08x\n", ioarea_parent); + debug(" BRIDGE PNP: 0x%p\n", ahbinfo.pnp); + + /* Parse the AHB information */ + ahbinfo.ahb_bus_index = parent; + ambapp_ahb_parse(&ahbinfo, &ahb); + + debug(" BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n", + ahb.vendor, ahb.vendor, ahb.device, ahb.device); + + /* Different bridges may convert frequency differently */ + if ((ahb.vendor == VENDOR_GAISLER) && + ((ahb.device == GAISLER_AHB2AHB) || + (ahb.device == GAISLER_L2CACHE))) { + /* Get new frequency */ + if (ahb.ver > 1) + freq = gaisler_ahb2ahb_v2_freq(&ahb, freq); + else + freq = gaisler_ahb2ahb_v1_freq(&ahb, freq); + + debug(" NEW FREQ: %dHz\n", freq); + } else { + panic("%s: unsupported AMBA bridge\n", __func__); + return -1; + } + + /* Step upwards towards system top bus */ + ahb_bus_index = parent; + } +#endif + + debug("ambapp_bus_freq: %dHz\n", freq); + + return freq; } diff --git a/arch/sparc/cpu/leon3/ambapp_low.S b/arch/sparc/cpu/leon3/ambapp_low.S new file mode 100644 index 0000000000..2863586dc1 --- /dev/null +++ b/arch/sparc/cpu/leon3/ambapp_low.S @@ -0,0 +1,784 @@ +/* GRLIB AMBA Plug&Play information scanning implemented without + * using memory (stack) and one register window. The code scan + * the PnP info and inserts the AHB bridges/buses into register + * i0-i5. + * The code support + * - up to 6 AHB buses + * - multiple APB buses + * - support for AHB2AHB & L2CACHE bridges + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> + + .seg "text" + .globl _nomem_amba_init + .globl _nomem_ambapp_find_buses + .globl _nomem_find_apb + .globl _nomem_find_ahb + +/* Overview + * ======== + * + * _nomem_amba_init - Init AMBA bus and calls _nomem_ambapp_find_buses + * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and + * place them in i0-i5, see below + * _nomem_find_apb - Find one APB device identified by VENDOR:DEVICE + * ID and an index. + * _nomem_find_ahb - Find one AHB Master or Slave device identified + * by VENDOR:DEVICE ID and an index. + * init_ahb_bridges - Local function. Clears i0-i5 + * insert_ahb_bridge - Local function. Insert a new AHB bus into first + * free register in i0-i5. It also checks that the + * bus has not already been added. + * get_ahb_bridge - Local function. Get AHB bus from registers, + * return register iN, where N is defined by o0. + * + * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5 + * are populated with the AHB buses of the system. The registers are + * initialized by _nomem_ambapp_find_buses. + * + * AHB Bus result and requirements of i0-i5 + * ======================================== + * + * i0: AHB BUS0 IOAREA, no parent bus + * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address + * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address + * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address + * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address + * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address + * + * AHB BUS + * ------- + * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area). + * + * 3-bit Parent bus + * ---------------- + * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent + * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1).. + * + * Bridge Address + * -------------- + * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP + * information on the parent. Since all bridges are found in the + * PnP information they all have a PnP entry. Together with the + * parent bus number the PnP entry can be found: + * PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800 + * where N is the parent bus minus one. + * + */ + +/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5) + * + * Arguments + * none + * + * Results + * none + * + * Clobbered + * none + */ + +init_ahb_bridges: + mov %g0, %i0 + mov %g0, %i1 + mov %g0, %i2 + mov %g0, %i3 + mov %g0, %i4 + retl + mov %g0, %i5 + +/* Function returns AHB Bridge I/O AREA for specified bus. + * + * Arguments + * - o0 = bus number + * + * Results + * - o0 = I/O AREA + * + * Clobbered + * none + */ +get_ahb_bridge: + cmp %o0, 1 + be,a L1 + mov %i0, %o0 + + cmp %o0, 2 + be,a L1 + mov %i1, %o0 + + cmp %o0, 3 + be,a L1 + mov %i2, %o0 + + cmp %o0, 4 + be,a L1 + mov %i3, %o0 + + cmp %o0, 5 + be,a L1 + mov %i4, %o0 + + cmp %o0, 6 + be,a L1 + mov %i5, %o0 + + /* o0 > 6: only 6 buses supported */ + mov %g0, %o0 +L1: + retl + nop + +/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if + * not already added. It stores the bus PnP start information. + * + * Arguments + * - o0 = AHB Bridge I/O area + * + * Results + * none + * + * Clobbered + * o2, o3 + */ +insert_ahb_bridge: + /* Check that bridge hasn't already been added */ + andn %o0, 0x7ff, %o2 + andn %i0, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i1, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i2, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i3, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i4, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i5, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + + /* Insert into first free posistion */ + cmp %i0, %g0 + be,a L2 + mov %o0, %i0 + + cmp %i1, %g0 + be,a L2 + mov %o0, %i1 + + cmp %i2, %g0 + be,a L2 + mov %o0, %i2 + + cmp %i3, %g0 + be,a L2 + mov %o0, %i3 + + cmp %i4, %g0 + be,a L2 + mov %o0, %i4 + + cmp %i5, %g0 + be,a L2 + mov %o0, %i5 +L2: + retl + nop + +/* FUNCTION int _nomem_find_ahb_bus( + * unsigned int bridge, + * int vendor_device, + * int index, + * void **pconf, + * int not_used, + * int option + * ) + * + * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the + * index is decremented when a matching device is found but index is + * greater than zero. When index is zero and a matching DEVICE:VENDOR + * is found the AHB configuration address and AHB I/O area is returned. + * + * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use. + * o1,o5 Must be left untouched + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 is decremented for each matching VENDOR:DEVICE found, zero if found + * - o3 Address of the AHB PnP configuration entry (Only valid if o0=1) + * + * Clobbered + * - o3 (Clobbered when no device was found) + * - o4 (Number of Devices left to search) + * - o0 (Bus ID, PnP ID, Device) + */ +_nomem_find_ahb_bus: + + /* Get the number of Slaves/Masters. + * Only AHB Bus 0 has 64 AHB Masters/Slaves the + * other AHB buses has 16 slaves and 16 masters. + */ + add %g0, 16, %o4 /* Defaulting to 16 */ + andcc %o0, 0x7, %g0 /* 3-bit bus id */ + be,a .L_maxloops_detected + add %g0, 64, %o4 /* AHB Bus 0 has 64 AHB Masters/Slaves */ +.L_maxloops_detected: + + /* Get start address of AHB Slave or AHB Master area depending on what + * we are searching for. + */ + andn %o0, 0x7ff, %o0 /* Remove Bus ID and 5-bit AHB/AHB + * Bridge PnP Address to get I/O Area */ + set AMBA_CONF_AREA, %o3 + or %o3, %o0, %o3 /* Master area address */ + + cmp %o5, DEV_AHB_SLV + be,a .L_conf_area_calculated + or %o3, AMBA_AHB_SLAVE_CONF_AREA, %o3 /* Add 0x800 to get to slave area */ +.L_conf_area_calculated: + + /* Iterate over all AHB device and try to find matching DEVICE:VENDOR + * o1 - VENDOR|DEVICE + * o2 - Index + * o3 - Current AHB Device Configuration address + * o5 - Type (leave untouched) + * + * o4 - Number of AHB device left to process + * o0 - tmp + */ +.L_process_one_conf: + ld [%o3], %o0 + andn %o0, 0xfff, %o0 + cmp %o0, 0 /* No device if zero */ + beq .L_next_conf + cmp %o1, 0 /* If VENDOR:DEVICE==0, consider all matching */ + beq .L_process_ahb_dev_found + cmp %o0, %o1 /* Does VENDOR and DEVICE Match? */ + bne .L_next_conf + nop +.L_process_ahb_dev_found: + /* Found a Matching VENDOR:DEVICE, index must also match */ + cmp %o2, %g0 + bne .L_next_conf + dec %o2 + /* Index matches also, return happy with o3 set to AHB Conf Address */ + mov %g0, %o2 + retl + add %g0, 1, %o0 + +.L_next_conf: + subcc %o4, 1, %o4 /* One device has been processed, + * Are there more devices to process? */ + bne .L_process_one_conf + add %o3, AMBA_AHB_CONF_LENGH, %o3 /* Next Configuration entry */ + /* No Matching device found */ + retl + mov %g0, %o0 + +/* FUNCTION int _nomem_find_ahb( + * int unused, + * int vendor_device, + * int index, + * void **pconf, + * int *ahb_bus_index, + * int option, + * ) + * + * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP + * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea). + * + * Calls _nomem_find_ahb_bus for every AHB bus. + * + * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use. + * + * Arguments + * - o0 Unused + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index (Zero if found) + * - o3 Address of the AHB PnP configuration entry + * - o4 AHB Bus index the device was found on (if o0=1) + * - o5 Left untouched + * + * Clobbered + * - o0 (AHB Bridge and used by _nomem_find_ahb_bus) + * - o2 (index is decremented) + * - l2 (Current AHB Bus index) + * - g2 (return address) + */ +_nomem_find_ahb: + mov %o7, %g2 /* Save return address */ + /* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */ + clr %l2 +.L_search_next_ahb_bus: + add %l2, 1, %l2 + call get_ahb_bridge /* Get bus %l0 I/O Area */ + mov %l2, %o0 + cmp %o0, %g0 + be .L_no_device_found /* If no more AHB bus is left to be scanned, proceed */ + nop + call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ + nop + cmp %o0, %g0 /* If VENDOR:DEVICE was not found scan next AHB Bus */ + be .L_search_next_ahb_bus /* Do next bus is o0=0 (not found) */ + nop + /* The device was found, o0 is 1 */ + mov %g2, %o7 /* Restore return address */ + retl + mov %l2, %o4 /* The AHB bus index the device was found on */ + + /* No device found matching */ +.L_no_device_found: + mov %g2, %o7 /* Restore return address */ + retl + mov %g0, %o0 + + +/* FUNCTION int _nomem_find_apb_bus( + * int apbmst, + * int vendor_device, + * int index, + * void **pconf + * ) + * + * Find a APB Slave device, it puts the address of the APB PnP configuration + * in o3 (pconf). + * + * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. + * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index + * - o3 Address of the found APB device PnP configuration entry + * + * Clobbered + * - o5 PnP VENDOR:DEVICE ID + */ + +_nomem_find_apb_bus: + set AMBA_CONF_AREA, %o3 + or %o0, %o3, %o3 /* Calc start of APB device PnP info */ + add %g0, 16, %o0 /* o0, number of APB Slaves left to scan */ +.L_process_one_apb_conf: + ld [%o3], %o5 + andn %o5, 0xfff, %o5 + cmp %o5, 0 /* No device if zero */ + beq .L_process_apb_dev_not_found + cmp %o1, 0 /* If VENDOR:DEVICE == -1, consider all matching */ + beq .L_process_apb_dev_found + cmp %o1, %o5 /* Found VENDOR:DEVICE */ + bne .L_process_apb_dev_not_found + nop + +.L_process_apb_dev_found: + /* Found matching device, compare index */ + cmp %o2, %g0 + bne .L_process_apb_dev_not_found + dec %o2 + /* Matching index and VENDOR:DEVICE */ + retl + add %g0, 1, %o0 + +.L_process_apb_dev_not_found: + subcc %o0, 1, %o0 + bne .L_process_one_apb_conf + add %o3, 8, %o3 + retl + mov %g0, %o0 + +/* FUNCTION int _nomem_find_apb( + * int unused, + * int vendor_device, + * int index, + * void **pconf, + * int *ahb_bus_index + * ) + * + * Find a APB Slave device, it puts the address of the APB PnP configuration + * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea). + * + * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. + * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. + * + * i0-i7, l0, l1, o6 is not available for use. + * + * Arguments + * - o0 Unused + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index if not found + * - o3 Address of the APB PnP configuration entry + * - o4 AHB Bus index of APB Bridge/APB Device + * + * Clobbered + * - o0 (AHB Bridge) + * - o2 (index is decremented) + * - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0]) + * - l3 (Current AHB Bus index) + * - l4 (temporary storage for APB VENDOR:DEVICE) + * - o5 (AHB Slave ID) + * - o0 (clobbered by _nomem_find_ahb_bus) + * - g2 (Return address) + */ +_nomem_find_apb: + /* Scan all AHB Buses found for AHB/APB Bridges */ + mov %o7, %g2 /* Save return address */ + mov %o1, %l4 /* Save APB VENDOR:DEVICE */ + sll %o2, 4, %l2 /* APB MST index = 0 */ + add %g0, 1, %l3 /* AHB Bus index = 0 */ +.L2_search_next_ahb_bus: + call get_ahb_bridge /* Get bus %l3 I/O Area */ + mov %l3, %o0 + cmp %o0, %g0 + be .L2_no_device_found /* If no more AHB bus is left to be scanned, proceed */ + add %g0, DEV_AHB_SLV, %o5 /* Search for AHB Slave */ + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1 + call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ + and %l2, 0xf, %o2 /* Set APBMST index */ + cmp %o0, %g0 /* If no AHB/APB Bridge was not found, scan next AHB Bus */ + be .L_no_apb_bridge_found /* Do next bus */ + nop + + /* The AHB/APB Bridge was found. + * Search for the requested APB Device on the APB bus using + * find_apb_bus, it will decrement the index. + */ + ld [%o3 + AMBA_AHB_MBAR0_OFS], %o3 + sll %o3, 16, %o0 + and %o0, %o3, %o0 /* Address AND Address Mask */ + sethi %hi(0xfff00000), %o3 + and %o0, %o3, %o0 /* AHB/APB Bridge address */ + + srl %l2, 4, %o2 /* APB DEV Index */ + call _nomem_find_apb_bus + mov %l4, %o1 /* APB VENDOR:DEVICE */ + cmp %o0, %g0 + be .L_apb_dev_not_found + mov %g2, %o7 /* Restore return address */ + /* APB Device found + * o0 1 + * o2 Index is decremented to zero + * o3 APB configuration address, + * o4 APB Bridge Configuration address. + */ + mov %g0, %o2 + retl + mov %l3, %o4 + +.L_apb_dev_not_found: + /* Update APB DEV Index by saving output from find_apb_bus + * (index parameter) into bits [31..4] in L2. + */ + sll %o2, 4, %o2 + and %l2, 0xf, %l2 + or %o2, %l2, %l2 + /* Try finding the next AHB/APB Bridge on the same AHB bus + * to find more APB devices + */ + ba .L2_search_next_ahb_bus /* Find next AHB/APB bridge */ + inc %l2 + +.L_no_apb_bridge_found: + inc %l3 /* Next AHB Bus */ + ba .L2_search_next_ahb_bus /* Process next AHB bus */ + andn %l2, 0xf, %l2 /* Start at APB Bridge index 0 at every AHB Bus */ + /* No device found matching */ +.L2_no_device_found: + mov %g2, %o7 /* Restore return address */ + srl %l2, 4, %o2 /* APB DEV Index */ + retl + mov %g0, %o0 + + + +/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus) + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + * Arguments + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * + * Results + * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge + * + * Clobbered + * - o0, o2 + * + */ +_nomem_amba_scan_gaisler_ahb2ahb_bridge: + andn %o2, 0xfff, %o2 + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3 + cmp %o2, %o3 + beq .L_is_ahb2ahb_bridge + nop + + retl + add %g0, 1, %o0 + +.L_is_ahb2ahb_bridge: + /* Found a GAISLER AHB2AHB bridge */ + retl + ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ + + +/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus) + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + * Arguments + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * + * Results + * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge + * + * Clobbered + * - o0, o2 + * + */ +_nomem_amba_scan_gaisler_l2cache_bridge: + andn %o2, 0xfff, %o2 + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3 + cmp %o2, %o3 + beq .L_is_l2cache_bridge + nop + + retl + add %g0, 1, %o0 + +.L_is_l2cache_bridge: + /* Found a GAISLER l2cache bridge */ + retl + ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ + + +/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus) + * + * Constraints: + * i0-i7, l0 is used by caller + * o5-o7 may not be used. + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * - o1 Bus + * + * Results + * - o0 Number of AHB bridges found + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - o2 (Used by insert_bridge) + * - o3 (Used by insert_bridge) + * - l1 (Number of AHB Slaves left to process) + * - l2 (Current AHB slave conf address) + * - g2 (Return address) + */ +_nomem_amba_scan: + mov %o7, %g2 /* Save return address */ + set 16, %l1 + cmp %o1, 1 + be,a .L2_maxloops_detected + add %g0, 64, %l1 +.L2_maxloops_detected: + + /* Clear 3-bit parent bus from bridge to get I/O AREA, then or + * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave + * conf address. + */ + andn %o0, 0x7ff, %o0 + set (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2 + or %o0, %l2, %l2 + + /* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device + * all "bridge drivers" are called, the driver function interface: + * + * Input: + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * Return values: + * - o0 Address of new bus PnP area, returning a 1 in o2 means not found + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + */ +.L_scan_one_ahb_slave: + ld [%l2], %o2 + + cmp %o2, %g0 + beq .L_scan_next_ahb_slave + nop + + /* Call the GAISLER AHB2AHB bridge driver */ + call _nomem_amba_scan_gaisler_ahb2ahb_bridge + mov %l2, %o0 + cmp %o0, 1 + bne .L_found_bridge + ld [%l2], %o2 + + /* Call the GAISLER L2CACHE bridge driver */ + call _nomem_amba_scan_gaisler_l2cache_bridge + mov %l2, %o0 + cmp %o0, 1 + bne .L_found_bridge + ld [%l2], %o2 + + /* Insert next bridge "driver" function here */ + + + /* The PnP ID did not match a bridge - a new bus was not found ==> + * step to next AHB device */ + ba .L_scan_next_ahb_slave + nop + + /* Add Found bus */ +.L_found_bridge: + and %l2, 0x7e0, %o2 + or %o2, %o0, %o0 /* Add AHB/AHB Bridge PnP address */ + call insert_ahb_bridge /* Insert Bridge into found buses storage */ + or %o1, %o0, %o0 /* Add parent bus LSB 3-bits */ + +.L_scan_next_ahb_slave: + /* More Slaves to process? */ + subcc %l1, 1, %l1 + bne .L_scan_one_ahb_slave + add %l2, AMBA_AHB_CONF_LENGH, %l2 + + /* No more AHB devices to process */ + mov %g2, %o7 /* Restore return address */ + retl + nop + +/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea) + * + * Find AMBA AHB buses. + * + * Constraints: + * i6-i7, l7 is used by caller + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * + * Results + * - o0 Number of AHB bridges found + * - i0-i5 initialized + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - o2 (Used by insert_bridge) + * - o3 (Used by insert_bridge) + * - l0 (Current AHB Bus) + * - l1 (Used by nomem_amba_scan) + * - l2 (Used by nomem_amba_scan) + * - l3 (Used by nomem_amba_scan) + * - l4 (Used by nomem_amba_scan) + * + * - g1 (level 1 return address) + * - g2 (Used by nomem_amba_scan) + */ +_nomem_ambapp_find_buses: + mov %o7, %g1 /* Save return address */ + + /* Initialize AHB Bus storage */ + call init_ahb_bridges + nop + + /* Insert AHB Bus 0 */ + call insert_ahb_bridge + nop /* Argument already prepared by caller */ + + /* Scan AHB Bus 0 for AHB Bridges */ + call _nomem_amba_scan + add %g0, 1, %o1 + + /* Scan all AHB Buses found for more AHB Bridges */ + add %g0, 2, %l0 +.L100_search_next_ahb_bus: + call get_ahb_bridge /* Get bus %l0 I/O Area */ + mov %l0, %o0 + cmp %o0, %g0 + be .L100_return /* If no more AHB bus is left to be scanned, proceed */ + nop + call _nomem_amba_scan /* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */ + mov %l0, %o1 /* I/O AREA untouched in o0 */ + ba .L100_search_next_ahb_bus /* Do next bus */ + add %l0, 1, %l0 + +.L100_return: + mov %g1, %o7 + retl + nop + + +/* FUNCTION _nomem_amba_init(unsigned int ioarea) + * + * Find all AHB buses + * + * Constraints: + * i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * + * Results + * - o0 Number of AHB bridges found + * + * Clobbered + * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) + * - o0, o1, o2, o3 (Used as arguments) + * - o5 (return address) + * - g1 (level 1 return address) + * - g2 (level 2 return address) + */ +_nomem_amba_init: + mov %o7, %o5 /* Save return address, o5 not used */ + + /* Scan for buses, it will init i0-i5 */ + call _nomem_ambapp_find_buses + nop + + mov %o5, %o7 + retl + nop + +/* Call tree and their return address register + * + *_nomem_amba_scan (g1) + * -> init_ahb_bridges (o7) + * -> insert_ahb_bridge (o7) + * -> _nomem_amba_scan (g2) + * -> insert_ahb_bridge (o7) + * -> get_ahb_bridge (o7) + * + * + * -> _nomem_find_apb (g2) + * -> get_ahb_bridge (o7) + * -> _nomem_find_ahb_bus (o7) + * -> _nomem_find_apb_bus (o7) + * -> _nomem_find_ahb (g2) + * -> get_ahb_bridge (o7) + * -> _nomem_find_ahb_bus (o7) + * -> mem_handler.func() (o7) + * + */ diff --git a/arch/sparc/cpu/leon3/ambapp_low_c.S b/arch/sparc/cpu/leon3/ambapp_low_c.S new file mode 100644 index 0000000000..42288fac59 --- /dev/null +++ b/arch/sparc/cpu/leon3/ambapp_low_c.S @@ -0,0 +1,113 @@ +/* C-interface for AMBA PnP scanning functions implemented in + * ambapp_low.S. At the point the memory and stack can be + * used. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + + .seg "text" + .extern _nomem_ambapp_find_buses + .extern _nomem_find_apb + .extern _nomem_find_ahb + + .globl ambapp_find_buses + .globl ambapp_find_apb + .globl ambapp_find_ahb + + +/* C-interface for _nomem_ambapp_find_buses used when memory is available. + */ +ambapp_find_buses: + save %sp, -104, %sp + mov %i1, %l7 /* Save second argument */ + call _nomem_ambapp_find_buses + mov %i0, %o0 + + /* Store result */ + st %g0, [%l7+0x00] + st %i0, [%l7+0x04] + st %i1, [%l7+0x08] + st %i2, [%l7+0x0c] + st %i3, [%l7+0x10] + st %i4, [%l7+0x14] + st %i5, [%l7+0x18] + + ret + restore + +/* C-interface for _nomem_find_apb used when memory is available. + * + * void ambapp_find_apb( + * struct ambapp_bus *abus, + * unsigned int dev_vend, + * int index, + * struct ambapp_find_apb_info *result + * ); + * + */ +ambapp_find_apb: + save %sp, -104, %sp + + mov %i3, %l7 /* Save second argument */ + mov %i1, %o1 + mov %i2, %o2 + + /* Initialize buses available in system */ + ld [%i0+0x08], %i1 + ld [%i0+0x0c], %i2 + ld [%i0+0x10], %i3 + ld [%i0+0x14], %i4 + ld [%i0+0x18], %i5 + + call _nomem_find_apb + ld [%i0+0x04], %i0 + + st %o2, [%l7+0x08] /* Decremented Index */ + st %o3, [%l7] /* PnP configuration address of APB Device */ + st %o4, [%l7+0x04] /* AHB Bus Index of AHB/APB bridge and APB Device */ + mov %o0, %i0 + ret + restore + +/* C-interface for _nomem_find_ahb used when memory is available. + * + * void ambapp_find_ahb( + * struct ambapp_bus *abus, + * unsigned int dev_vend, + * int index, + * int type, + * struct ambapp_find_ahb_info *result + * ); + * + */ +ambapp_find_ahb: + save %sp, -104, %sp + + mov %i4, %l7 /* Save second argument */ + clr %o0 + mov %i1, %o1 + mov %i2, %o2 + clr %o3 + clr %o4 + mov %i3, %o5 + + /* Initialize buses available in system */ + ld [%i0+0x08], %i1 + ld [%i0+0x0c], %i2 + ld [%i0+0x10], %i3 + ld [%i0+0x14], %i4 + ld [%i0+0x18], %i5 + + call _nomem_find_ahb + ld [%i0+0x04], %i0 + + st %o2, [%l7+0x08] /* Decremented Index */ + st %o3, [%l7] /* PnP configuration address of AHB Device */ + st %o4, [%l7+0x04] /* AHB Bus Index of AHB Device */ + mov %o0, %i0 + ret + restore diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 2f41d8847b..b140da31b1 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -1,8 +1,8 @@ /* Initializes CPU and basic hardware such as memory * controllers, IRQ controller and system timer 0. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -11,9 +11,17 @@ #include <asm/asi.h> #include <asm/leon.h> #include <ambapp.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> +#include <debug_uart.h> #include <config.h> +/* Default Plug&Play I/O area */ +#ifndef CONFIG_AMBAPP_IOAREA +#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA +#endif + #define TIMER_BASE_CLK 1000000 #define US_PER_TICK (1000000 / CONFIG_SYS_HZ) @@ -22,11 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; /* reset CPU (jump to 0, without reset) */ void start(void); -/* find & initialize the memory controller */ -int init_memory_ctrl(void); - ambapp_dev_irqmp *irqmp = NULL; -ambapp_dev_mctrl memctrl; ambapp_dev_gptimer *gptimer = NULL; unsigned int gptimer_irq = 0; int leon3_snooping_avail = 0; @@ -39,64 +43,32 @@ struct { /* * Breath some life into the CPU... * - * Set up the memory map, - * initialize a bunch of registers. - * * Run from FLASH/PROM: * - until memory controller is set up, only registers available + * - memory controller has already been setup up, stack can be used * - no global variables available for writing * - constants available */ - void cpu_init_f(void) { - /* these varaiable must not be initialized */ - ambapp_dev_irqmp *irqmp; - ambapp_apbdev apbdev; - register unsigned int apbmst; - - /* find AMBA APB Master */ - apbmst = (unsigned int) - ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) { - /* - * no AHB/APB bridge, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - /* Init memory controller */ - if (init_memory_ctrl()) { - while (1) ; - } - - /**************************************************** - * From here we can use the main memory and the stack. - */ - - /* Find AMBA APB IRQMP Controller */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) { - /* no IRQ controller, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - irqmp = (ambapp_dev_irqmp *) apbdev.address; - - /* initialize the IRQMP */ - irqmp->ilevel = 0xf; /* all IRQ off */ - irqmp->iforce = 0; - irqmp->ipend = 0; - irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ - irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */ - irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */ - - /* cache */ +#ifdef CONFIG_DEBUG_UART + debug_uart_init(); +#endif } +/* Routine called from start.S, + * + * Run from FLASH/PROM: + * - memory controller has already been setup up, stack can be used + * - global variables available for read/writing + * - constants avaiable + */ void cpu_init_f2(void) { - + /* Initialize the AMBA Plug & Play bus structure, the bus + * structure represents the AMBA bus that the CPU is located at. + */ + ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); } /* @@ -105,95 +77,58 @@ void cpu_init_f2(void) int cpu_init_r(void) { ambapp_apbdev apbdev; + int index, cpu; + ambapp_dev_gptimer *timer = NULL; + unsigned int bus_freq; /* * Find AMBA APB IRQMP Controller, - * When we come so far we know there is a IRQMP available */ - ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev); - irqmp = (ambapp_dev_irqmp *) apbdev.address; - - /* timer */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) { - printf("cpu_init_r: gptimer not found!\n"); - return 1; - } - gptimer = (ambapp_dev_gptimer *) apbdev.address; - gptimer_irq = apbdev.irq; - - /* initialize prescaler common to all timers to 1MHz */ - gptimer->scalar = gptimer->scalar_reload = - (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; - - return (0); -} - -/* find & setup memory controller */ -int init_memory_ctrl() -{ - register ambapp_dev_mctrl *mctrl; - register ambapp_dev_sdctrl *sdctrl; - register ambapp_dev_ddrspa *ddrspa; - register ambapp_dev_ddr2spa *ddr2spa; - register ahbctrl_pp_dev *ahb; - register unsigned int base; - register int not_found_mctrl = -1; - - /* find ESA Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3; - not_found_mctrl = 0; + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_IRQMP, 0, &apbdev) != 1) { + panic("%s: IRQ controller not found\n", __func__); + return -1; } + irqmp = (ambapp_dev_irqmp *)apbdev.address; - /* find Gaisler Fault Tolerant Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3; - not_found_mctrl = 0; + /* initialize the IRQMP */ + irqmp->ilevel = 0xf; /* all IRQ off */ + irqmp->iforce = 0; + irqmp->ipend = 0; + irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ + for (cpu = 0; cpu < 16; cpu++) { + /* mask and clear force for all IRQs on CPU[N] */ + irqmp->cpu_mask[cpu] = 0; + irqmp->cpu_force[cpu] = 0; } - /* find SDRAM controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0); - if (base) { - sdctrl = (ambapp_dev_sdctrl *) base; - - /* config memory controller */ - sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM; - not_found_mctrl = 0; - } + /* timer */ + index = 0; + while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, + index, &apbdev) == 1) { + timer = (ambapp_dev_gptimer *)apbdev.address; + if (gptimer == NULL) { + gptimer = timer; + gptimer_irq = apbdev.irq; + } + + /* Different buses may have different frequency, the + * frequency of the bus tell in which frequency the timer + * prescaler operates. + */ + bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0); - if (ahb) { - ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1); + /* initialize prescaler common to all timers to 1MHz */ + timer->scalar = timer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; - /* Config DDR2 memory controller */ - ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1; - ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3; - not_found_mctrl = 0; + index++; } - - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0); - if (ahb) { - ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1); - - /* Config DDR memory controller */ - ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG; - not_found_mctrl = 0; + if (!gptimer) { + printf("%s: gptimer not found!\n", __func__); + return 1; } - - /* failed to find any memory controller */ - return not_found_mctrl; + return 0; } /* Uses Timer 0 to get accurate @@ -216,8 +151,8 @@ int timer_interrupt_init_cpu(void) gptimer->e[0].val = 0; gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; gptimer->e[0].ctrl = - (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); + (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | + GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); return gptimer_irq; } diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index a834aa024b..2312b58d29 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -23,6 +23,8 @@ #include <asm/leon.h> #include <ambapp.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> /* 15 normal irqs and a non maskable interrupt */ #define NR_IRQS 15 @@ -125,9 +127,8 @@ int interrupt_init_cpu(void) /* Handle Timer 0 IRQ */ void timer_interrupt_cpu(void *arg) { - gptimer->e[0].ctrl = (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | - LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); + gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | + GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); /* nothing to do here */ return; } diff --git a/arch/sparc/cpu/leon3/memcfg.c b/arch/sparc/cpu/leon3/memcfg.c new file mode 100644 index 0000000000..b9eda440e2 --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg.c @@ -0,0 +1,237 @@ +/* GRLIB Memory controller setup. The register values are used + * from the associated low level assembler routine implemented + * in memcfg_low.S. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> +#include "memcfg.h" +#include <config.h> + +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 +struct mctrl_setup esa_mctrl1_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 +struct mctrl_setup esa_mctrl2_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +struct mctrl_setup gaisler_ftmctrl1_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 +struct mctrl_setup gaisler_ftmctrl2_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 +struct mctrl_setup gaisler_sdctrl1_cfg = { + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 +struct mctrl_setup gaisler_sdctrl2_cfg = { + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 +struct ahbmctrl_setup gaisler_ddr2spa1_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0xd, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1, + }, + { 0x00000000, 0}, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 +struct ahbmctrl_setup gaisler_ddr2spa2_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0xd, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1, + }, + { 0x00000000, 0}, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 +struct ahbmctrl_setup gaisler_ddrspa1_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 +struct ahbmctrl_setup gaisler_ddrspa2_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL, + }, + } +}; +#endif +#endif + +struct grlib_mctrl_handler grlib_mctrl_handlers[] = { +/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), + _nomem_mctrl_init, (void *)&esa_mctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), + _nomem_mctrl_init, (void *)&esa_mctrl2_cfg}, +#endif +#endif + +/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), + _nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), + _nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg}, +#endif +#endif + +/* GAISLER SDRAM-only Memory controller (SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), + _nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), + _nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg}, +#endif +#endif + +/* GAISLER DDR Memory controller (DDR) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 + {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 + {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg}, +#endif +#endif + +/* GAISLER DDR2 Memory controller (DDR2) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 + {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 + {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg}, +#endif +#endif + + /* Mark end */ + MH_END +}; diff --git a/arch/sparc/cpu/leon3/memcfg.h b/arch/sparc/cpu/leon3/memcfg.h new file mode 100644 index 0000000000..a524896e5a --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg.h @@ -0,0 +1,90 @@ +/* GRLIB Memory controller setup structures + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MEMCFG_H__ +#define __MEMCFG_H__ + +/*********** Low Level Memory Controller Initalization ***********/ + +#ifndef __ASSEMBLER__ + +struct grlib_mctrl_handler; + +typedef void (*mctrl_handler_t)( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea + ); + +/* Memory Controller Handler Structure */ +struct grlib_mctrl_handler { + unsigned char type; /* 0x00. MASK: AHB MST&SLV, APB SLV */ + char index; /* 0x01. Unit number, 0, 1, 2... */ + char unused[2]; /* 0x02 */ + unsigned int ven_dev; /* 0x04. Device and Vendor */ + mctrl_handler_t func; /* 0x08. Memory Controller Handler */ + void *priv; /* 0x0c. Optional private data, ptr to + * info how to set up controller */ +}; + +extern struct grlib_mctrl_handler grlib_mctrl_handlers[]; + +#endif + +#define MH_STRUCT_SIZE (4*4) +#define MH_TYPE 0x00 +#define MH_INDEX 0x01 +#define MH_VENDOR_DEVICE 0x04 +#define MH_FUNC 0x08 +#define MH_PRIV 0x0c + +#define MH_TYPE_NONE DEV_NONE +#define MH_TYPE_AHB_MST DEV_AHB_MST +#define MH_TYPE_AHB_SLV DEV_AHB_SLV +#define MH_TYPE_APB_SLV DEV_APB_SLV + +#define MH_UNUSED {0, 0} +#define MH_END {DEV_NONE, 0, MH_UNUSED, AMBA_PNP_ID(0, 0), 0, 0} + +/*********** Low Level Memory Controller Initalization Handlers ***********/ + +#ifndef __ASSEMBLER__ +extern void _nomem_mctrl_init( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea_apbmst); + +struct mctrl_setup { + unsigned int reg_mask; /* Which registers to write */ + struct { + unsigned int mask; /* Mask used keep reg bits unchanged */ + unsigned int value; /* Value written to register */ + } regs[8]; +}; + +extern void _nomem_ahbmctrl_init( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea_apbmst); + +struct ahbmctrl_setup { + int ahb_mbar_no; /* MBAR to get register address from */ + unsigned int reg_mask; /* Which registers to write */ + struct { + unsigned int mask; /* Mask used keep reg bits unchanged */ + unsigned int value; /* Value written to register */ + } regs[8]; +}; +#endif + +/* mctrl_setup data structure defines */ +#define NREGS_OFS 0 +#define REGS_OFS 0x4 +#define REGS_SIZE 8 + +#endif diff --git a/arch/sparc/cpu/leon3/memcfg_low.S b/arch/sparc/cpu/leon3/memcfg_low.S new file mode 100644 index 0000000000..84a81a90a9 --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg_low.S @@ -0,0 +1,253 @@ +/* This is the memory initialization functions, the function + * implemented below initializes each memory controller + * found and specified by the input grlib_mctrl_handler structure. + * + * After the memory controllers have been initialized the stack + * can be used. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> +#include "memcfg.h" +#include <config.h> + + .seg "text" + .globl _nomem_memory_ctrl_init + .globl _nomem_mctrl_init, _nomem_ahbmctrl_init + .extern _nomem_find_apb + .extern _nomem_find_ahb + + +/* FUNCTION + * _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers) + * + * Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5 + * with the AHB buses on the system. + * + * For each entry in mem_handlers find the VENDOR:DEVICE and handle it + * by calling the handler function pointer. + * + * Constraints: + * i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller + * o7 is return address + * l5 reserved for this function for future use. + * + * Arguments + * - o0 Pointer to memory handler array + * + * Results + * - o0 Number of memory controllers found + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - l0 (mem handler entry address) + * - l1 (Return value, number of memory controllers found) + * - o7 (function pointer) + * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) + * - o0, o1, o2, o3, o4, o5 (Used as arguments) + * + * - g1 ( level 1 return address) + * - g2 ( level 2 return address) + */ + +_nomem_memory_ctrl_init: + /* At this point all AHB buses has been found and the I/O Areas of + * all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next, + * memory controllers are found by searching all buses for matching + * VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the + * mem_handlers array. For each match the function pointer stored in + * the mem_handler entry is called to handle the hardware setup. + */ + mov %o7, %g1 /* Save return address */ + mov %o0, %l0 + mov %g0, %l1 /* The return value */ + +.L_do_one_mem_handler: + ld [%l0 + MH_FUNC], %o7 + cmp %o7, %g0 + be .L_all_mctrl_handled + nop + + /*** Scan for memory controller ***/ + + /* Set up argments, o5 not used by _nomem_find_apb */ + ldub [%l0 + MH_TYPE], %o5 + clr %o4 + clr %o3 + ldub [%l0 + MH_INDEX], %o2 + ld [%l0 + MH_VENDOR_DEVICE], %o1 + + /* An empty config? */ + cmp %o5, DEV_NONE + beq .L_all_mctrl_next + + /* Select function (APB or AHB) */ + cmp %o5, DEV_APB_SLV + bne .L_find_ahb_memctrl + clr %o0 +.L_find_apb_memctrl: + call _nomem_find_apb /* Scan for APB slave device */ + nop + + /* o3 = iobar address + * o4 = AHB Bus index + * + * REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base" + */ + ld [%o3 + AMBA_APB_IOBAR_OFS], %o5 + srl %o5, 12, %o2 + sll %o5, 4, %o5 + and %o2, %o5, %o5 + set 0xfff00, %o2 + and %o2, %o5, %o5 + sethi %hi(0xfff00000), %o2 + and %o3, %o2, %o2 + or %o5, %o2, %o5 /* Register base address */ + + ba .L_call_one_mem_handler + nop + +.L_find_ahb_memctrl: + call _nomem_find_ahb /* Scan for AHB Slave or Master. + * o5 determine type. */ + nop + clr %o5 + + /* Call the handler function if the hardware was found + * + * o0 = mem_handler + * o1 = Configuration address + * o2 = AHB Bus index + * o3 = APB Base register (if APB Slave) + * + * Constraints: + * i0-i7, l0, l1, l5, g1, g3-g7 may no be used. + */ +.L_call_one_mem_handler: + cmp %o0, %g0 + be .L_all_mctrl_next + mov %l0, %o0 /* Mem handler pointer */ + mov %o3, %o1 /* AMBA PnP Configuration address */ + mov %o4, %o2 /* AHB Bus index */ + ld [%l0 + MH_FUNC], %o7 /* Get Function pointer */ + call %o7 + mov %o5, %o3 /* APB Register Base Address */ + + inc %l1 /* Number of Memory controllers + * handled. */ + + /* Do next entry in mem_handlers */ +.L_all_mctrl_next: + ba .L_do_one_mem_handler + add %l0, MH_STRUCT_SIZE, %l0 + +.L_all_mctrl_handled: + mov %g1, %o7 /* Restore return address */ + retl + mov %l1, %o0 + + + +/* Generic Memory controller initialization routine (APB Registers) + * + * o0 = mem_handler structure pointer + * o1 = Configuration address + * o2 = AHB Bus index + * o3 = APB Base register + * + * Clobbered + * o0-o4 + */ +_nomem_mctrl_init: + ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ + ld [%o0], %o1 /* Get Reg Mask */ + and %o1, 0xff, %o1 + add %o0, REGS_OFS, %o0 /* Point to first reg */ +.L_do_one_reg: + andcc %o1, 0x1, %g0 + beq .L_do_next_reg + ld [%o0], %o2 + ld [%o3], %o4 + and %o4, %o2, %o4 + ld [%o0 + 4], %o2 + or %o4, %o2, %o4 + st %o4, [%o3] + +.L_do_next_reg: + add %o0, REGS_SIZE, %o0 + add %o3, 4, %o3 + srl %o1, 1, %o1 + cmp %o1, 0 + bne .L_do_one_reg + nop + + /* No more registers to write */ + retl + nop + + + +/* Generic Memory controller initialization routine (AHB Registers) + * + * o0 = mem_handler structure pointer + * o1 = Configuration address of memory controller + * o2 = AHB Bus index + * + * Clobbered + * o0-o5 + */ +_nomem_ahbmctrl_init: + ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ + + /* Get index of AHB MBAR to get registers from */ + ld [%o0], %o5 + add %o0, 4, %o0 + + /* Get Address of MBAR in PnP info */ + add %o5, 4, %o5 + sll %o5, 2, %o5 + add %o5, %o1, %o5 /* Address of MBAR */ + + /* Get Address of registers from PnP information + * Address is in AHB I/O format, i.e. relative to bus + * + * ADR = (iobar & (iobar << 16) & 0xfff00000) + * IOADR = (ADR >> 12) | "APB Base" + */ + ld [%o5], %o5 + sll %o5, 16, %o4 + and %o5, %o4, %o5 + sethi %hi(0xfff00000), %o4 + and %o5, %o4, %o5 /* ADR */ + and %o4, %o1, %o4 + srl %o5, 12, %o5 + or %o5, %o4, %o3 /* IOADR in o3 */ + + ld [%o0], %o1 /* Get Reg Mask */ + and %o1, 0xff, %o1 + add %o0, REGS_OFS, %o0 /* Point to first reg */ +.L_do_one_ahbreg: + andcc %o1, 0x1, %g0 + beq .L_do_next_reg + ld [%o0], %o2 + ld [%o3], %o4 + and %o4, %o2, %o4 + ld [%o0 + 4], %o2 + or %o4, %o2, %o4 + st %o4, [%o3] + +.L_do_next_ahbreg: + add %o0, REGS_SIZE, %o0 + add %o3, 4, %o3 + srl %o1, 1, %o1 + cmp %o1, 0 + bne .L_do_one_reg + nop + + /* No more registers to write */ + retl + nop diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index b83776bc06..c391be7420 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -15,13 +15,17 @@ #include <asm/irq.h> #include <asm/leon.h> #include <ambapp.h> +#include <grlib/apbuart.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> #include <config.h> /* #define PRINT_ROM_VEC */ extern struct linux_romvec *kernel_arg_promvec; -extern ambapp_dev_apbuart *leon3_apbuart; + +DECLARE_GLOBAL_DATA_PTR; #define PROM_PGT __attribute__ ((__section__ (".prom.pgt"))) #define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) @@ -740,14 +744,14 @@ static int PROM_TEXT leon_nbputchar(int c) /* Wait for last character to go. */ while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_THE)) ; + & APBUART_STATUS_THE)); /* Send data */ SPARC_BYPASS_WRITE(&uart->data, c); /* Wait for data to be sent */ while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_TSE)) ; + & APBUART_STATUS_TSE)); return 0; } @@ -909,7 +913,7 @@ void leon_prom_init(struct leon_prom_info *pspi) pspi->avail.num_bytes = pspi->totphys.num_bytes; /* Set the pointer to the Console UART in romvec */ - pspi->reloc_funcs.leon3_apbuart = leon3_apbuart; + pspi->reloc_funcs.leon3_apbuart = gd->arch.uart; { int j = 1; diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index bca6b6548b..66b3773027 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -1,66 +1,79 @@ /* GRLIB APBUART Serial controller driver * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/processor.h> -#include <asm/leon.h> +#include <asm/io.h> #include <ambapp.h> +#include <grlib/apbuart.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; -ambapp_dev_apbuart *leon3_apbuart = NULL; +/* Select which UART that will become u-boot console */ +#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX +#define CONFIG_SYS_GRLIB_APBUART_INDEX 0 +#endif static int leon3_serial_init(void) { + ambapp_dev_apbuart *uart; ambapp_apbdev apbdev; unsigned int tmp; /* find UART */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) { + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, + CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { + panic("%s: apbuart not found!\n", __func__); + return -1; /* didn't find hardware */ + } - leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address; + /* found apbuart, let's init .. */ + uart = (ambapp_dev_apbuart *) apbdev.address; - /* found apbuart, let's init... - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ - leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER; + /* Set scaler / baud rate */ + tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + writel(tmp, &uart->scaler); - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(leon3_apbuart->ctrl); + /* Let bit 11 be unchanged (debug bit for GRMON) */ + tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG; + /* Receiver & transmitter enable */ + tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE; + writel(tmp, &uart->ctrl); - leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) | - LEON_REG_UART_CTRL_RE | - LEON_REG_UART_CTRL_TE); + gd->arch.uart = uart; + return 0; +} - return 0; - } - return -1; /* didn't find hardware */ +static inline ambapp_dev_apbuart *leon3_get_uart_regs(void) +{ + ambapp_dev_apbuart *uart = gd->arch.uart; + return uart; } static void leon3_serial_putc_raw(const char c) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) return; /* Wait for last character to go. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ; + while (!(readl(&uart->status) & APBUART_STATUS_THE)) + WATCHDOG_RESET(); /* Send data */ - leon3_apbuart->data = c; + writel(c, &uart->data); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ; + while (!(readl(&uart->status) & APBUART_STATUS_TSE)) + WATCHDOG_RESET(); #endif } @@ -74,36 +87,44 @@ static void leon3_serial_putc(const char c) static int leon3_serial_getc(void) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) return 0; /* Wait for a character to arrive. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ; + while (!(readl(&uart->status) & APBUART_STATUS_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(leon3_apbuart->data); + /* Read character data */ + return readl(&uart->data); } static int leon3_serial_tstc(void) { - if (leon3_apbuart) - return (READ_WORD(leon3_apbuart->status) & - LEON_REG_UART_STATUS_DR); - return 0; + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) + return 0; + + return readl(&uart->status) & APBUART_STATUS_DR; } /* set baud rate for uart */ static void leon3_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); unsigned int scaler; - if (leon3_apbuart && (gd->baudrate > 0)) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - leon3_apbuart->scaler = scaler; - } - return; + + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10; + + writel(scaler, &uart->scaler); } static struct serial_device leon3_serial_drv = { @@ -126,3 +147,26 @@ __weak struct serial_device *default_serial_console(void) { return &leon3_serial_drv; } + +#ifdef CONFIG_DEBUG_UART_APBUART + +#include <debug_uart.h> + +static inline void _debug_uart_init(void) +{ + ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; + uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE; +} + +static inline void _debug_uart_putc(int ch) +{ + ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; + while (!(readl(&uart->status) & APBUART_STATUS_THE)) + WATCHDOG_RESET(); + writel(ch, &uart->data); +} + +DEBUG_UART_FUNCS + +#endif diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index cf897f6877..203114970b 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -2,9 +2,6 @@ * Copyright (C) 2007, * Daniel Hellstrom, daniel@gaisler.com * - * See file CREDITS for list of people who contributed to this - * project. - * * SPDX-License-Identifier: GPL-2.0+ */ @@ -16,6 +13,12 @@ #include <asm/stack.h> #include <asm/leon.h> #include <version.h> +#include <ambapp.h> + +/* Default Plug&Play I/O area */ +#ifndef CONFIG_AMBAPP_IOAREA +#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA +#endif /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ @@ -60,6 +63,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4) #error Must define number of SPARC register windows, default is 8 #endif +/* Macros to load address into a register. Uses GOT table for PIC */ +#ifdef __PIC__ + +#define SPARC_PIC_THUNK_CALL(reg) \ + sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ + call __sparc_get_pc_thunk.reg; \ + add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg; + +#define SPARC_LOAD_ADDRESS(sym, got, reg) \ + sethi %gdop_hix22(sym), %##reg; \ + xor %##reg, %gdop_lox10(sym), %##reg; \ + ld [%##got + %##reg], %##reg, %gdop(sym); + +#else + +#define SPARC_PIC_THUNK_CALL(reg) +#define SPARC_LOAD_ADDRESS(sym, got, tmp) \ + set sym, %##reg; + +#endif + #define STACK_ALIGN 8 #define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) @@ -190,6 +214,7 @@ version_string: .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" + .extern _nomem_amba_init, _nomem_memory_ctrl_init .align 4 _hardreset: @@ -232,7 +257,7 @@ clear_window: bge clear_window save -wininit: +wiminit: set WIM_INIT, %g3 mov %g3, %wim @@ -241,9 +266,41 @@ stackp: andn %fp, 0x0f, %fp sub %fp, 64, %sp +/* Obtain the address of _GLOBAL_OFFSET_TABLE_ */ + SPARC_PIC_THUNK_CALL(l7) + +/* Scan AMBA Bus for AMBA buses using PnP information. All found + * AMBA buses I/O area will be located in i0-i5 upon return. + * The i0-i5 registers are later used by _nomem_amba_init2 + */ +ambainit: + call _nomem_amba_init + sethi %hi(CONFIG_AMBAPP_IOAREA), %o0 + +/* Scan AMBA Buses for memory controllers, then initialize the + * memory controllers. Note that before setting up the memory controller + * the stack can not be used. + */ +memory_ctrl_init: + SPARC_LOAD_ADDRESS(grlib_mctrl_handlers, l7, o0) + + call _nomem_memory_ctrl_init + nop + +/* The return valu indicate how many memory controllers where found and + * initialized, if no memory controller was initialized, we can not continue + * because from here on we expect memory to be working. + */ + cmp %o0, 0 +memory_ctrl_init_failed: + beq memory_ctrl_init_failed + nop + +/*** From now on the stack can be used. ***/ + cpu_init_unreloc: call cpu_init_f - nop + nop /* un relocated start address of monitor */ #define TEXT_START _text @@ -252,8 +309,8 @@ cpu_init_unreloc: #define DATA_END __init_end reloc: - set TEXT_START,%g2 - set DATA_END,%g3 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) + SPARC_LOAD_ADDRESS(DATA_END, l7, g3) set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 reloc_loop: ldd [%g2],%l0 @@ -263,7 +320,7 @@ reloc_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne reloc_loop - inc 16,%g4 + inc 16,%g4 clr %l0 clr %l1 @@ -280,8 +337,8 @@ reloc_loop: clr_bss: /* clear bss area (the relocated) */ - set __bss_start,%g2 - set __bss_end,%g3 + SPARC_LOAD_ADDRESS(__bss_start, l7, g2) + SPARC_LOAD_ADDRESS(__bss_end, l7, g3) sub %g3,%g2,%g3 add %g3,%g4,%g3 clr %g1 /* std %g0 uses g0 and g1 */ @@ -292,19 +349,19 @@ clr_bss_16: inc 16,%g4 cmp %g3,%g4 bne clr_bss_16 - nop + nop /* add offsets to GOT table */ fixup_got: - set __got_start,%g4 - set __got_end,%g3 + SPARC_LOAD_ADDRESS(__got_start, l7, g4) + SPARC_LOAD_ADDRESS(__got_end, l7, g3) /* * new got offset = (old GOT-PTR (read with ld) - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + * Destination Address (from define) */ set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - set TEXT_START, %g1 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) add %g4,%g2,%g4 sub %g4,%g1,%g4 add %g3,%g2,%g3 @@ -319,11 +376,11 @@ got_loop: inc 4,%g4 cmp %g3,%g4 bne got_loop - nop + nop prom_relocate: - set __prom_start, %g2 - set __prom_end, %g3 + SPARC_LOAD_ADDRESS(__prom_start, l7, g2) + SPARC_LOAD_ADDRESS(__prom_end, l7, g3) set CONFIG_SYS_PROM_OFFSET, %g4 prom_relocate_loop: @@ -334,7 +391,7 @@ prom_relocate_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne prom_relocate_loop - inc 16,%g4 + inc 16,%g4 /* Trap table has been moved, lets tell CPU about * the new trap table address @@ -361,19 +418,20 @@ snoop_detect: nop /* Call relocated init functions */ jump: - set cpu_init_f2,%o1 + SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 add %o1,%o2,%o1 sub %o1,%g1,%o1 call %o1 - clr %o0 + clr %o0 - set board_init_f,%o1 + SPARC_LOAD_ADDRESS(board_init_f, l7, o1) set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) add %o1,%o2,%o1 sub %o1,%g1,%o1 call %o1 - clr %o0 + clr %o0 dead: ta 0 ! if call returns... nop diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c index ca7d6e86f0..1be84c646b 100644 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ b/arch/sparc/cpu/leon3/usb_uhci.c @@ -690,11 +690,11 @@ void handle_usb_interrupt(void) */ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) { - unsigned char temp; ambapp_ahbdev ahbdev; /* Find GRUSB core using AMBA Plug&Play information */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) { + if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI, + CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) { printf("USB UHCI: Failed to find GRUSB controller\n"); return -1; } diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index 667e7d6d3b..0680a56758 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -15,6 +15,7 @@ /* Architecture-specific global data */ struct arch_global_data { + void *uart; }; #include <asm-generic/global_data.h> diff --git a/arch/sparc/include/asm/io.h b/arch/sparc/include/asm/io.h index f7b89c890f..a317d132be 100644 --- a/arch/sparc/include/asm/io.h +++ b/arch/sparc/include/asm/io.h @@ -1,7 +1,7 @@ /* SPARC I/O definitions * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,45 +12,57 @@ /* Nothing to sync, total store ordering (TSO)... */ #define sync() +/* + * Generic virtual read/write. + */ + +#ifndef CONFIG_SYS_HAS_NO_CACHE + /* Forces a cache miss on read/load. * On some architectures we need to bypass the cache when reading * I/O registers so that we are not reading the same status word * over and over again resulting in a hang (until an IRQ if lucky) - * */ -#ifndef CONFIG_SYS_HAS_NO_CACHE -#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)(var)) -#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var)) -#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)(var)) -#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var)) + +#define __arch_getb(a) SPARC_NOCACHE_READ_BYTE((unsigned int)(a)) +#define __arch_getw(a) SPARC_NOCACHE_READ_HWORD((unsigned int)(a)) +#define __arch_getl(a) SPARC_NOCACHE_READ((unsigned int)(a)) +#define __arch_getq(a) SPARC_NOCACHE_READ_DWORD((unsigned int)(a)) + #else -#define READ_BYTE(var) (var) -#define READ_HWORD(var) (var) -#define READ_WORD(var) (var) -#define READ_DWORD(var) (var) -#endif -/* - * Generic virtual read/write. - */ -#define __arch_getb(a) (READ_BYTE(a)) -#define __arch_getw(a) (READ_HWORD(a)) -#define __arch_getl(a) (READ_WORD(a)) -#define __arch_getq(a) (READ_DWORD(a)) +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) +#define __arch_getq(a) (*(volatile unsigned long long *)(a)) + +#endif /* CONFIG_SYS_HAS_NO_CACHE */ -#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) -#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) -#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) +#define __arch_putb(v, a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v, a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v, a) (*(volatile unsigned int *)(a) = (v)) +#define __arch_putq(v, a) (*(volatile unsigned long long *)(a) = (v)) -#define __raw_writeb(v,a) __arch_putb(v,a) -#define __raw_writew(v,a) __arch_putw(v,a) -#define __raw_writel(v,a) __arch_putl(v,a) +#define __raw_writeb(v, a) __arch_putb(v, a) +#define __raw_writew(v, a) __arch_putw(v, a) +#define __raw_writel(v, a) __arch_putl(v, a) +#define __raw_writeq(v, a) __arch_putq(v, a) #define __raw_readb(a) __arch_getb(a) #define __raw_readw(a) __arch_getw(a) #define __raw_readl(a) __arch_getl(a) #define __raw_readq(a) __arch_getq(a) +#define writeb __raw_writeb +#define writew __raw_writew +#define writel __raw_writel +#define writeq __raw_writeq + +#define readb __raw_readb +#define readw __raw_readw +#define readl __raw_readl +#define readq __raw_readq + /* * Given a physical address and a length, return a virtual address * that can be used to access the memory range with the caching diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h index 65e4561e7d..4f68fbda69 100644 --- a/arch/sparc/include/asm/winmacro.h +++ b/arch/sparc/include/asm/winmacro.h @@ -136,130 +136,3 @@ ld [reg + FW_FSR], %fsr; #endif - -#ifndef __SPARC_WINMACRO_H__ -#define __SPARC_WINMACRO_H__ - -#include <asm/asmmacro.h> -#include <asm/stack.h> - -/* Store the register window onto the 8-byte aligned area starting - * at %reg. It might be %sp, it might not, we don't care. - */ -#define RW_STORE(reg) \ - std %l0, [%reg + RW_L0]; \ - std %l2, [%reg + RW_L2]; \ - std %l4, [%reg + RW_L4]; \ - std %l6, [%reg + RW_L6]; \ - std %i0, [%reg + RW_I0]; \ - std %i2, [%reg + RW_I2]; \ - std %i4, [%reg + RW_I4]; \ - std %i6, [%reg + RW_I6]; - -/* Load a register window from the area beginning at %reg. */ -#define RW_LOAD(reg) \ - ldd [%reg + RW_L0], %l0; \ - ldd [%reg + RW_L2], %l2; \ - ldd [%reg + RW_L4], %l4; \ - ldd [%reg + RW_L6], %l6; \ - ldd [%reg + RW_I0], %i0; \ - ldd [%reg + RW_I2], %i2; \ - ldd [%reg + RW_I4], %i4; \ - ldd [%reg + RW_I6], %i6; - -/* Loading and storing struct pt_reg trap frames. */ -#define PT_LOAD_INS(base_reg) \ - ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \ - ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \ - ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \ - ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6; - -#define PT_LOAD_GLOBALS(base_reg) \ - ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \ - ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \ - ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \ - ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6; - -#define PT_LOAD_YREG(base_reg, scratch) \ - ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \ - wr %scratch, 0x0, %y; - -#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ - ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \ - ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \ - ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc; - -#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ - PT_LOAD_YREG(base_reg, scratch) \ - PT_LOAD_INS(base_reg) \ - PT_LOAD_GLOBALS(base_reg) \ - PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) - -#define PT_STORE_INS(base_reg) \ - std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \ - std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \ - std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \ - std %i6, [%base_reg + SF_REGS_SZ + PT_I6]; - -#define PT_STORE_GLOBALS(base_reg) \ - st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \ - std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \ - std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \ - std %g6, [%base_reg + SF_REGS_SZ + PT_G6]; - -#define PT_STORE_YREG(base_reg, scratch) \ - rd %y, %scratch; \ - st %scratch, [%base_reg + SF_REGS_SZ + PT_Y]; - -#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ - st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \ - st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \ - st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC]; - -#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ - PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ - PT_STORE_GLOBALS(base_reg) \ - PT_STORE_YREG(base_reg, g_scratch) \ - PT_STORE_INS(base_reg) - -/* Store the fpu register window*/ -#define FW_STORE(reg) \ - std %f0, [reg + FW_F0]; \ - std %f2, [reg + FW_F2]; \ - std %f4, [reg + FW_F4]; \ - std %f6, [reg + FW_F6]; \ - std %f8, [reg + FW_F8]; \ - std %f10, [reg + FW_F10]; \ - std %f12, [reg + FW_F12]; \ - std %f14, [reg + FW_F14]; \ - std %f16, [reg + FW_F16]; \ - std %f18, [reg + FW_F18]; \ - std %f20, [reg + FW_F20]; \ - std %f22, [reg + FW_F22]; \ - std %f24, [reg + FW_F24]; \ - std %f26, [reg + FW_F26]; \ - std %f28, [reg + FW_F28]; \ - std %f30, [reg + FW_F30]; \ - st %fsr, [reg + FW_FSR]; - -/* Load a fpu register window from the area beginning at reg. */ -#define FW_LOAD(reg) \ - ldd [reg + FW_F0], %f0; \ - ldd [reg + FW_F2], %f2; \ - ldd [reg + FW_F4], %f4; \ - ldd [reg + FW_F6], %f6; \ - ldd [reg + FW_F8], %f8; \ - ldd [reg + FW_F10], %f10; \ - ldd [reg + FW_F12], %f12; \ - ldd [reg + FW_F14], %f14; \ - ldd [reg + FW_F16], %f16; \ - ldd [reg + FW_F18], %f18; \ - ldd [reg + FW_F20], %f20; \ - ldd [reg + FW_F22], %f22; \ - ldd [reg + FW_F24], %f24; \ - ldd [reg + FW_F26], %f26; \ - ldd [reg + FW_F28], %f28; \ - ldd [reg + FW_F30], %f30; \ - ld [reg + FW_FSR], %fsr; - -#endif diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f92082d476..8914be34e6 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -420,6 +420,21 @@ config PCIE_ECAM_SIZE so a default 0x10000000 size covers all of the 256 buses which is the maximum number of PCI buses as defined by the PCI specification. +config I8259_PIC + bool + default y + help + Intel 8259 ISA compatible chipset incorporates two 8259 (master and + slave) interrupt controllers. Include this to have U-Boot set up + the interrupt correctly. + +config I8254_TIMER + bool + default y + help + Intel 8254 timer contains three counters which have fixed uses. + Include this to have U-Boot set up the timer correctly. + source "arch/x86/lib/efi/Kconfig" endmenu diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index addd26e4e6..b00ddc0cb4 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -252,7 +252,7 @@ int interrupt_init(void) /* Just in case... */ disable_interrupts(); -#ifdef CONFIG_SYS_PCAT_INTERRUPTS +#ifdef CONFIG_I8259_PIC /* Initialize the master/slave i8259 pic */ i8259_init(); #endif diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c index d2ec45a240..7a312602a0 100644 --- a/arch/x86/cpu/pci.c +++ b/arch/x86/cpu/pci.c @@ -19,51 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -static struct pci_controller x86_hose; - -int pci_early_init_hose(struct pci_controller **hosep) -{ - struct pci_controller *hose; - - hose = calloc(1, sizeof(struct pci_controller)); - if (!hose) - return -ENOMEM; - - board_pci_setup_hose(hose); - pci_setup_type1(hose); - hose->last_busno = pci_hose_scan(hose); - gd->hose = hose; - *hosep = hose; - - return 0; -} - -__weak int board_pci_pre_scan(struct pci_controller *hose) -{ - return 0; -} - -__weak int board_pci_post_scan(struct pci_controller *hose) -{ - return 0; -} - -void pci_init_board(void) -{ - struct pci_controller *hose = &x86_hose; - - /* Stop using the early hose */ - gd->hose = NULL; - - board_pci_setup_hose(hose); - pci_setup_type1(hose); - pci_register_hose(hose); - - board_pci_pre_scan(hose); - hose->last_busno = pci_hose_scan(hose); - board_pci_post_scan(hose); -} - static struct pci_controller *get_hose(void) { if (gd->hose) diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile index 1c00d1de07..3f3958aa8e 100644 --- a/arch/x86/cpu/qemu/Makefile +++ b/arch/x86/cpu/qemu/Makefile @@ -9,4 +9,3 @@ obj-y += car.o dram.o endif obj-y += qemu.o obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o -obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c deleted file mode 100644 index 2e944569b5..0000000000 --- a/arch/x86/cpu/qemu/pci.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <pci.h> -#include <pci_rom.h> -#include <asm/pci.h> -#include <asm/arch/device.h> -#include <asm/arch/qemu.h> - -DECLARE_GLOBAL_DATA_PTR; - -static bool i440fx; - -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - pci_set_region(hose->regions + 3, - 0, - 0, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - hose->region_count = 4; -} - -int board_pci_post_scan(struct pci_controller *hose) -{ - int ret = 0; - u16 device, xbcs; - int pam, i; - pci_dev_t vga; - ulong start; - - /* - * i440FX and Q35 chipset have different PAM register offset, but with - * the same bitfield layout. Here we determine the offset based on its - * PCI device ID. - */ - device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID); - i440fx = (device == PCI_DEVICE_ID_INTEL_82441); - pam = i440fx ? I440FX_PAM : Q35_PAM; - - /* - * Initialize Programmable Attribute Map (PAM) Registers - * - * Configure legacy segments C/D/E/F to system RAM - */ - for (i = 0; i < PAM_NUM; i++) - x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW); - - if (i440fx) { - /* - * Enable legacy IDE I/O ports decode - * - * Note: QEMU always decode legacy IDE I/O port on PIIX chipset. - * However Linux ata_piix driver does sanity check on these two - * registers to see whether legacy ports decode is turned on. - * This is to make Linux ata_piix driver happy. - */ - x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN); - x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN); - - /* Enable I/O APIC */ - xbcs = x86_pci_read_config16(PIIX_ISA, XBCS); - xbcs |= APIC_EN; - x86_pci_write_config16(PIIX_ISA, XBCS, xbcs); - } else { - /* Configure PCIe ECAM base address */ - x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR, - CONFIG_PCIE_ECAM_BASE | BAR_EN); - } - - /* - * QEMU emulated graphic card shows in the PCI configuration space with - * PCI vendor id and device id as an artificial pair 0x1234:0x1111. - * It is on PCI bus 0, function 0, but device number is not consistent - * for the two x86 targets it supports. For i440FX and PIIX chipset - * board, it shows as device 2, while for Q35 and ICH9 chipset board, - * it shows as device 1. - */ - vga = i440fx ? I440FX_VGA : Q35_VGA; - start = get_timer(0); - ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE); - debug("BIOS ran in %lums\n", get_timer(start)); - - return ret; -} - -#ifdef CONFIG_GENERATE_MP_TABLE -int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) -{ - u8 irq; - - if (i440fx) { - /* - * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not - * connected to I/O APIC INTPIN#16-19. Instead they are routed - * to an irq number controled by the PIRQ routing register. - */ - irq = x86_pci_read_config8(PCI_BDF(bus, dev, func), - PCI_INTERRUPT_LINE); - } else { - /* - * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7. - * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11]. - */ - irq = pirq < 8 ? pirq + 16 : pirq + 12; - } - - return irq; -} -#endif diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 7c03e0295b..84fb082077 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -6,8 +6,58 @@ #include <common.h> #include <asm/irq.h> +#include <asm/pci.h> #include <asm/post.h> #include <asm/processor.h> +#include <asm/arch/device.h> +#include <asm/arch/qemu.h> + +static bool i440fx; + +static void qemu_chipset_init(void) +{ + u16 device, xbcs; + int pam, i; + + /* + * i440FX and Q35 chipset have different PAM register offset, but with + * the same bitfield layout. Here we determine the offset based on its + * PCI device ID. + */ + device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID); + i440fx = (device == PCI_DEVICE_ID_INTEL_82441); + pam = i440fx ? I440FX_PAM : Q35_PAM; + + /* + * Initialize Programmable Attribute Map (PAM) Registers + * + * Configure legacy segments C/D/E/F to system RAM + */ + for (i = 0; i < PAM_NUM; i++) + x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW); + + if (i440fx) { + /* + * Enable legacy IDE I/O ports decode + * + * Note: QEMU always decode legacy IDE I/O port on PIIX chipset. + * However Linux ata_piix driver does sanity check on these two + * registers to see whether legacy ports decode is turned on. + * This is to make Linux ata_piix driver happy. + */ + x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN); + x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN); + + /* Enable I/O APIC */ + xbcs = x86_pci_read_config16(PIIX_ISA, XBCS); + xbcs |= APIC_EN; + x86_pci_write_config16(PIIX_ISA, XBCS, xbcs); + } else { + /* Configure PCIe ECAM base address */ + x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR, + CONFIG_PCIE_ECAM_BASE | BAR_EN); + } +} int arch_cpu_init(void) { @@ -39,7 +89,39 @@ void reset_cpu(ulong addr) x86_full_reset(); } +int arch_early_init_r(void) +{ + qemu_chipset_init(); + + return 0; +} + int arch_misc_init(void) { return pirq_init(); } + +#ifdef CONFIG_GENERATE_MP_TABLE +int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) +{ + u8 irq; + + if (i440fx) { + /* + * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not + * connected to I/O APIC INTPIN#16-19. Instead they are routed + * to an irq number controled by the PIRQ routing register. + */ + irq = x86_pci_read_config8(PCI_BDF(bus, dev, func), + PCI_INTERRUPT_LINE); + } else { + /* + * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7. + * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11]. + */ + irq = pirq < 8 ? pirq + 16 : pirq + 12; + } + + return irq; +} +#endif diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 0c02a44f63..933d189f05 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -25,12 +25,26 @@ static void unprotect_spi_flash(void) static void __maybe_unused disable_igd(void) { - u32 gc; - - gc = x86_pci_read_config32(TNC_IGD, IGD_GC); - gc &= ~GMS_MASK; - gc |= VGA_DISABLE; - x86_pci_write_config32(TNC_IGD, IGD_GC, gc); + /* + * According to Atom E6xx datasheet, setting VGA Disable (bit17) + * of Graphics Controller register (offset 0x50) prevents IGD + * (D2:F0) from reporting itself as a VGA display controller + * class in the PCI configuration space, and should also prevent + * it from responding to VGA legacy memory range and I/O addresses. + * + * However test result shows that with just VGA Disable bit set and + * a PCIe graphics card connected to one of the PCIe controllers on + * the E6xx, accessing the VGA legacy space still causes system hang. + * After a number of attempts, it turns out besides VGA Disable bit, + * the SDVO (D3:F0) device should be disabled to make it work. + * + * To simplify, use the Function Disable register (offset 0xc4) + * to disable both IGD (D2:F0) and SDVO (D3:F0) devices. Now these + * two devices will be completely disabled (invisible in the PCI + * configuration space) unless a system reset is performed. + */ + x86_pci_write_config32(TNC_IGD, IGD_FD, FUNC_DISABLE); + x86_pci_write_config32(TNC_SDVO, IGD_FD, FUNC_DISABLE); } int arch_cpu_init(void) diff --git a/arch/x86/include/asm/arch-queensbay/tnc.h b/arch/x86/include/asm/arch-queensbay/tnc.h index 23653949de..8477d92641 100644 --- a/arch/x86/include/asm/arch-queensbay/tnc.h +++ b/arch/x86/include/asm/arch-queensbay/tnc.h @@ -7,10 +7,9 @@ #ifndef _X86_ARCH_TNC_H_ #define _X86_ARCH_TNC_H_ -/* IGD Control Register */ -#define IGD_GC 0x50 -#define VGA_DISABLE 0x00020000 -#define GMS_MASK 0x00700000 +/* IGD Function Disable Register */ +#define IGD_FD 0xc4 +#define FUNC_DISABLE 0x00000001 /* Memory BAR Enable */ #define MEM_BAR_EN 0x00000001 diff --git a/arch/x86/include/asm/i8254.h b/arch/x86/include/asm/i8254.h index 4116de1f07..48e4df25b8 100644 --- a/arch/x86/include/asm/i8254.h +++ b/arch/x86/include/asm/i8254.h @@ -5,38 +5,35 @@ * SPDX-License-Identifier: GPL-2.0+ */ - /* i8254.h Intel 8254 PIT registers */ - #ifndef _ASMI386_I8254_H_ -#define _ASMI386_I8954_H_ 1 - +#define _ASMI386_I8954_H_ -#define PIT_T0 0x00 /* PIT channel 0 count/status */ -#define PIT_T1 0x01 /* PIT channel 1 count/status */ -#define PIT_T2 0x02 /* PIT channel 2 count/status */ -#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ /* PIT Command Register Bit Definitions */ -#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ -#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ -#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ -#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ -#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ -#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ -#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ -#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ -#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ -#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ -#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ -#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ -#define PIT_CMD_MODE5 0x0A /* Select mode 5 */ +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0a /* Select mode 5 */ /* The clock frequency of the i8253/i8254 PIT */ -#define PIT_TICK_RATE 1193182ul +#define PIT_TICK_RATE 1193182 -#endif +#endif /* _ASMI386_I8954_H_ */ diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index bc4033bed2..f216c23204 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h @@ -8,11 +8,9 @@ /* i8259.h i8259 PIC Registers */ #ifndef _ASMI386_I8259_H_ -#define _ASMI386_I8959_H_ 1 - +#define _ASMI386_I8959_H_ /* PIC I/O mapped registers */ - #define IRR 0x0 /* Interrupt Request Register */ #define ISR 0x0 /* In-Service Register */ #define ICW1 0x0 /* Initialization Control Word 1 */ @@ -23,7 +21,7 @@ #define ICW4 0x1 /* Initialization Control Word 4 */ #define IMR 0x1 /* Interrupt Mask Register */ -/* bits for IRR, IMR, ISR and ICW3 */ +/* IRR, IMR, ISR and ICW3 bits */ #define IR7 0x80 /* IR7 */ #define IR6 0x40 /* IR6 */ #define IR5 0x20 /* IR5 */ @@ -33,7 +31,7 @@ #define IR1 0x02 /* IR1 */ #define IR0 0x01 /* IR0 */ -/* bits for SEOI */ +/* SEOI bits */ #define SEOI_IR7 0x07 /* IR7 */ #define SEOI_IR6 0x06 /* IR6 */ #define SEOI_IR5 0x05 /* IR5 */ @@ -49,9 +47,9 @@ #define OCW2_NOP 0x40 /* NOP */ #define OCW2_SEOI 0x60 /* Specific EOI */ #define OCW2_RSET 0x80 /* Rotate/set */ -#define OCW2_REOI 0xA0 /* Rotate on non specific EOI */ -#define OCW2_PSET 0xC0 /* Priority Set Command */ -#define OCW2_RSEOI 0xE0 /* Rotate on specific EOI */ +#define OCW2_REOI 0xa0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xc0 /* Priority Set Command */ +#define OCW2_RSEOI 0xe0 /* Rotate on specific EOI */ /* ICW1 bits */ #define ICW1_SEL 0x10 /* Select ICW1 */ @@ -60,15 +58,20 @@ #define ICW1_SNGL 0x02 /* Single PIC */ #define ICW1_EICW4 0x01 /* Expect initilization ICW4 */ -/* ICW2 is the starting vector number */ - -/* ICW2 is bit-mask of present slaves for a master device, - * or the slave ID for a slave device */ +/* + * ICW2 is the starting vector number + * + * ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device + */ /* ICW4 bits */ -#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ #define ICW4_PM 0x01 /* Microprocessor Mode */ +#define ELCR1 0x4d0 +#define ELCR2 0x4d1 + int i8259_init(void); -#endif +#endif /* _ASMI386_I8959_H_ */ diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h index fcd766ba9b..95a4de023e 100644 --- a/arch/x86/include/asm/interrupt.h +++ b/arch/x86/include/asm/interrupt.h @@ -13,6 +13,8 @@ #include <asm/types.h> +#define SYS_NUM_IRQS 16 + /* Architecture defined exceptions */ enum x86_exception { EXC_DE = 0, diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index f7e968e0b0..a2945f1aff 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -25,27 +25,6 @@ struct pci_controller; void pci_setup_type1(struct pci_controller *hose); -/** - * board_pci_setup_hose() - Set up the PCI hose - * - * This is called by the common x86 PCI code to set up the PCI controller - * hose. It may be called when no memory/BSS is available so should just - * store things in 'hose' and not in BSS variables. - */ -void board_pci_setup_hose(struct pci_controller *hose); - -/** - * pci_early_init_hose() - Set up PCI host before relocation - * - * This allocates memory for, sets up and returns the PCI hose. It can be - * called before relocation. The hose will be stored in gd->hose for - * later use, but will become invalid one DRAM is available. - */ -int pci_early_init_hose(struct pci_controller **hosep); - -int board_pci_pre_scan(struct pci_controller *hose); -int board_pci_post_scan(struct pci_controller *hose); - /* * Simple PCI access routines - these work from either the early PCI hose * or the 'real' one, created after U-Boot has memory available diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 1c459d5ae3..dbf8e95c1b 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -29,7 +29,7 @@ typedef void (timer_fnc_t) (void); int register_timer_isr (timer_fnc_t *isr_func); unsigned long get_tbclk_mhz(void); void timer_set_base(uint64_t base); -int pcat_timer_init(void); +int i8254_init(void); /* cpu/.../interrupts.c */ int cpu_init_interrupts(void); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 2f82a21aff..d676e2c14f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -19,8 +19,8 @@ obj-y += lpc-uclass.o obj-y += mpspec.o obj-$(CONFIG_ENABLE_MRC_CACHE) += mrccache.o obj-y += cmd_mtrr.o -obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o -obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o +obj-$(CONFIG_I8259_PIC) += i8259.o +obj-$(CONFIG_I8254_TIMER) += i8254.o ifndef CONFIG_DM_PCI obj-$(CONFIG_PCI) += pci_type1.o endif diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index c78df94b80..5276ce6ab1 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -35,11 +35,6 @@ int fsp_init_phase_pci(void) return status ? -EPERM : 0; } -int board_pci_post_scan(struct pci_controller *hose) -{ - return fsp_init_phase_pci(); -} - void board_final_cleanup(void) { u32 status; diff --git a/arch/x86/lib/i8254.c b/arch/x86/lib/i8254.c new file mode 100644 index 0000000000..46a4245289 --- /dev/null +++ b/arch/x86/lib/i8254.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/i8254.h> + +#define TIMER1_VALUE 18 /* 15.6us */ +#define TIMER2_VALUE 0x0a8e /* 440Hz */ + +int i8254_init(void) +{ + /* + * Initialize counter 1, used to refresh request signal. + * This is required for legacy purpose as some codes like + * vgabios utilizes counter 1 to provide delay functionality. + */ + outb(PIT_CMD_CTR1 | PIT_CMD_LOW | PIT_CMD_MODE2, + PIT_BASE + PIT_COMMAND); + outb(TIMER1_VALUE, PIT_BASE + PIT_T1); + + /* + * Initialize counter 2, used to drive the speaker. + * To start a beep, set both bit0 and bit1 of port 0x61. + * To stop it, clear both bit0 and bit1 of port 0x61. + */ + outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, + PIT_BASE + PIT_COMMAND); + outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); + outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); + + return 0; +} diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/i8259.c index a9af87e4ce..b9d06140d4 100644 --- a/arch/x86/lib/pcat_interrupts.c +++ b/arch/x86/lib/i8259.c @@ -20,10 +20,6 @@ #include <asm/ibmpc.h> #include <asm/interrupt.h> -#if CONFIG_SYS_NUM_IRQS != 16 -#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined" -#endif - int i8259_init(void) { u8 i; @@ -32,10 +28,11 @@ int i8259_init(void) outb(0xff, MASTER_PIC + IMR); outb(0xff, SLAVE_PIC + IMR); - /* Master PIC */ - /* Place master PIC interrupts at INT20 */ - /* ICW3, One slave PIC is present */ - outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1); + /* + * Master PIC + * Place master PIC interrupts at INT20 + */ + outb(ICW1_SEL | ICW1_EICW4, MASTER_PIC + ICW1); outb(0x20, MASTER_PIC + ICW2); outb(IR2, MASTER_PIC + ICW3); outb(ICW4_PM, MASTER_PIC + ICW4); @@ -43,10 +40,11 @@ int i8259_init(void) for (i = 0; i < 8; i++) outb(OCW2_SEOI | i, MASTER_PIC + OCW2); - /* Slave PIC */ - /* Place slave PIC interrupts at INT28 */ - /* Slave ID */ - outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1); + /* + * Slave PIC + * Place slave PIC interrupts at INT28 + */ + outb(ICW1_SEL | ICW1_EICW4, SLAVE_PIC + ICW1); outb(0x28, SLAVE_PIC + ICW2); outb(0x02, SLAVE_PIC + ICW3); outb(ICW4_PM, SLAVE_PIC + ICW4); @@ -70,7 +68,7 @@ void mask_irq(int irq) { int imr_port; - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) @@ -85,7 +83,7 @@ void unmask_irq(int irq) { int imr_port; - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) @@ -98,7 +96,7 @@ void unmask_irq(int irq) void specific_eoi(int irq) { - if (irq >= CONFIG_SYS_NUM_IRQS) + if (irq >= SYS_NUM_IRQS) return; if (irq > 7) { @@ -114,9 +112,6 @@ void specific_eoi(int irq) outb(OCW2_SEOI | irq, MASTER_PIC + OCW2); } -#define ELCR1 0x4d0 -#define ELCR2 0x4d1 - void configure_irq_trigger(int int_num, bool is_level_triggered) { u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8); @@ -131,20 +126,4 @@ void configure_irq_trigger(int int_num, bool is_level_triggered) debug("%s: try to set interrupts 0x%x\n", __func__, int_bits); outb((u8)(int_bits & 0xff), ELCR1); outb((u8)(int_bits >> 8), ELCR2); - -#ifdef PARANOID_IRQ_TRIGGERS - /* - * Try reading back the new values. This seems like an error but is - * not - */ - if (inb(ELCR1) != (int_bits & 0xff)) { - printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n", - __func__, (int_bits & 0xff), inb(ELCR1)); - } - - if (inb(ELCR2) != (int_bits >> 8)) { - printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n", - __func__, (int_bits>>8), inb(ELCR2)); - } -#endif } diff --git a/arch/x86/lib/interrupts.c b/arch/x86/lib/interrupts.c index 146ad11fb5..dd08402665 100644 --- a/arch/x86/lib/interrupts.c +++ b/arch/x86/lib/interrupts.c @@ -39,7 +39,7 @@ struct irq_action { unsigned int count; }; -static struct irq_action irq_handlers[CONFIG_SYS_NUM_IRQS] = { {0} }; +static struct irq_action irq_handlers[SYS_NUM_IRQS] = { {0} }; static int spurious_irq_cnt; static int spurious_irq; @@ -47,7 +47,7 @@ void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) { int status; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_install_handler: bad irq number %d\n", irq); return; } @@ -75,7 +75,7 @@ void irq_free_handler(int irq) { int status; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("irq_free_handler: bad irq number %d\n", irq); return; } @@ -97,7 +97,7 @@ void do_irq(int hw_irq) { int irq = hw_irq - 0x20; - if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + if (irq < 0 || irq >= SYS_NUM_IRQS) { printf("do_irq: bad irq number %d\n", irq); return; } @@ -130,7 +130,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("Interrupt-Information:\n"); printf("Nr Routine Arg Count\n"); - for (irq = 0; irq < CONFIG_SYS_NUM_IRQS; irq++) { + for (irq = 0; irq < SYS_NUM_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { printf("%02d %08lx %08lx %d\n", irq, diff --git a/arch/x86/lib/pcat_timer.c b/arch/x86/lib/pcat_timer.c deleted file mode 100644 index 3545a5048e..0000000000 --- a/arch/x86/lib/pcat_timer.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/i8254.h> - -#define TIMER2_VALUE 0x0a8e /* 440Hz */ - -int pcat_timer_init(void) -{ - /* - * initialize 2, used to drive the speaker - * (to start a beep: write 3 to port 0x61, - * to stop it again: write 0) - */ - outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, - PIT_BASE + PIT_COMMAND); - outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); - outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); - - return 0; -} diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c index 0df1af238c..e02b918843 100644 --- a/arch/x86/lib/tsc_timer.c +++ b/arch/x86/lib/tsc_timer.c @@ -368,9 +368,9 @@ void __udelay(unsigned long usec) int timer_init(void) { -#ifdef CONFIG_SYS_PCAT_TIMER - /* Set up the PCAT timer if required */ - pcat_timer_init(); +#ifdef CONFIG_I8254_TIMER + /* Set up the i8254 timer if required */ + i8254_init(); #endif return 0; diff --git a/board/BuR/kwb/board.c b/board/BuR/kwb/board.c index 039ec207c2..ad74ff299c 100644 --- a/board/BuR/kwb/board.c +++ b/board/BuR/kwb/board.c @@ -47,10 +47,6 @@ #define RSTCTRL_FORCE_PWR_NEN 0x0404 #define RSTCTRL_CAN_STB 0x4040 -#define VXWORKS_BOOTLINE 0x80001100 -#define DEFAULT_BOOTLINE "cpsw(0,0):pme/vxWorks" -#define VXWORKS_USER "u=vxWorksFTP pw=vxWorks tn=vxtarget" - DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_SPL_BUILD) @@ -281,20 +277,15 @@ int board_late_init(void) } else { puts("ERROR: i2c_set_bus_speed failed! (scratchregister)\n"); } - /* setup vxworks bootline */ - char *vxworksbootline = (char *)VXWORKS_BOOTLINE; - sprintf(vxworksbootline, - "%s h=%s e=%s:%s g=%s %s o=0x%08x;0x%08x;0x%08x;0x%08x", - DEFAULT_BOOTLINE, - getenv("serverip"), - getenv("ipaddr"), getenv("netmask"), - getenv("gatewayip"), - VXWORKS_USER, - (unsigned int) gd->fb_base-0x20, - (u32)getenv_ulong("vx_memtop", 16, gd->fb_base-0x20), - (u32)getenv_ulong("vx_romfsbase", 16, 0), - (u32)getenv_ulong("vx_romfssize", 16, 0)); - + /* setup othbootargs for bootvx-command (vxWorks bootline) */ + char othbootargs[128]; + snprintf(othbootargs, sizeof(othbootargs), + "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", + (unsigned int) gd->fb_base-0x20, + (u32)getenv_ulong("vx_memtop", 16, gd->fb_base-0x20), + (u32)getenv_ulong("vx_romfsbase", 16, 0), + (u32)getenv_ulong("vx_romfssize", 16, 0)); + setenv("othbootargs", othbootargs); /* * reset VBAR registers to its reset location, VxWorks 6.9.3.2 does * expect that vectors are there, original u-boot moves them to _start diff --git a/board/emulation/qemu-x86/Makefile b/board/emulation/qemu-x86/Makefile index ad2bbb94a2..a855255be3 100644 --- a/board/emulation/qemu-x86/Makefile +++ b/board/emulation/qemu-x86/Makefile @@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += qemu-x86.o start.o +obj-y += start.o diff --git a/board/emulation/qemu-x86/qemu-x86.c b/board/emulation/qemu-x86/qemu-x86.c deleted file mode 100644 index fedea81abc..0000000000 --- a/board/emulation/qemu-x86/qemu-x86.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <netdev.h> - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} diff --git a/board/gdsys/405ep/dlvision-10g.c b/board/gdsys/405ep/dlvision-10g.c index 35dfbbc577..54c7eb3a12 100644 --- a/board/gdsys/405ep/dlvision-10g.c +++ b/board/gdsys/405ep/dlvision-10g.c @@ -25,17 +25,19 @@ #define LATCH2_MC2_PRESENT_N 0x0080 enum { - UNITTYPE_VIDEO_USER = 0, - UNITTYPE_MAIN_USER = 1, - UNITTYPE_VIDEO_SERVER = 2, - UNITTYPE_MAIN_SERVER = 3, + UNITTYPE_MAIN = 1<<0, + UNITTYPE_SERVER = 1<<1, + UNITTYPE_DISPLAYPORT = 1<<2, }; enum { HWVER_101 = 0, HWVER_110 = 1, - HWVER_120 = 2, - HWVER_130 = 3, + HWVER_130 = 2, + HWVER_140 = 3, + HWVER_150 = 4, + HWVER_160 = 5, + HWVER_170 = 6, }; enum { @@ -121,43 +123,48 @@ static void print_fpga_info(unsigned dev) feature_carriers = (fpga_features >> 2) & 0x0003; feature_video_channels = fpga_features & 0x0003; - switch (unit_type) { - case UNITTYPE_VIDEO_USER: - printf("Videochannel Userside"); - break; + if (unit_type & UNITTYPE_MAIN) + printf("Mainchannel "); + else + printf("Videochannel "); - case UNITTYPE_MAIN_USER: - printf("Mainchannel Userside"); - break; + if (unit_type & UNITTYPE_SERVER) + printf("Serverside "); + else + printf("Userside "); + + if (unit_type & UNITTYPE_DISPLAYPORT) + printf("DisplayPort"); + else + printf("DVI-DL"); - case UNITTYPE_VIDEO_SERVER: - printf("Videochannel Serverside"); + switch (hardware_version) { + case HWVER_101: + printf(" HW-Ver 1.01\n"); break; - case UNITTYPE_MAIN_SERVER: - printf("Mainchannel Serverside"); + case HWVER_110: + printf(" HW-Ver 1.10-1.20\n"); break; - default: - printf("UnitType %d(not supported)", unit_type); + case HWVER_130: + printf(" HW-Ver 1.30\n"); break; - } - switch (hardware_version) { - case HWVER_101: - printf(" HW-Ver 1.01\n"); + case HWVER_140: + printf(" HW-Ver 1.40-1.43\n"); break; - case HWVER_110: - printf(" HW-Ver 1.10-1.12\n"); + case HWVER_150: + printf(" HW-Ver 1.50\n"); break; - case HWVER_120: - printf(" HW-Ver 1.20\n"); + case HWVER_160: + printf(" HW-Ver 1.60-1.61\n"); break; - case HWVER_130: - printf(" HW-Ver 1.30\n"); + case HWVER_170: + printf(" HW-Ver 1.70\n"); break; default: @@ -260,7 +267,7 @@ int last_stage_init(void) if (get_mc2_present()) print_fpga_info(1); - if (((versions >> 4) & 0x000f) != UNITTYPE_MAIN_USER) + if (((versions >> 4) & 0x000f) & UNITTYPE_SERVER) return 0; if (!get_fpga_state(0) || (get_hwver() == HWVER_101)) diff --git a/board/gdsys/405ep/iocon.c b/board/gdsys/405ep/iocon.c index 3a51d864cd..7484624d13 100644 --- a/board/gdsys/405ep/iocon.c +++ b/board/gdsys/405ep/iocon.c @@ -381,7 +381,7 @@ int last_stage_init(void) ch0_rgmii2_present = !pca9698_get_value(0x20, 30); } - /* wait for FPGA done */ + /* wait for FPGA done; then reset FPGA */ for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { unsigned int ctr = 0; @@ -396,6 +396,12 @@ int last_stage_init(void) break; } } + + pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0); + udelay(10); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, + MCFPGA_RESET_N); } if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) { diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile index 49579434df..ce230455c8 100644 --- a/board/gdsys/common/Makefile +++ b/board/gdsys/common/Makefile @@ -9,7 +9,10 @@ obj-$(CONFIG_SYS_FPGA_COMMON) += fpga.o obj-$(CONFIG_CMD_IOLOOP) += cmd_ioloop.o obj-$(CONFIG_IO) += miiphybb.o obj-$(CONFIG_IO64) += miiphybb.o -obj-$(CONFIG_IOCON) += osd.o mclink.o dp501.o phy.o -obj-$(CONFIG_DLVISION_10G) += osd.o +obj-$(CONFIG_IOCON) += osd.o mclink.o dp501.o phy.o ch7301.o +obj-$(CONFIG_DLVISION_10G) += osd.o dp501.o obj-$(CONFIG_CONTROLCENTERD) += dp501.o -obj-$(CONFIG_HRCON) += osd.o mclink.o dp501.o phy.o +obj-$(CONFIG_HRCON) += osd.o mclink.o dp501.o phy.o ioep-fpga.o fanctrl.o +obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o +obj-$(CONFIG_STRIDER) += fanctrl.o +obj-$(CONFIG_STRIDER_CON) += osd.o diff --git a/board/gdsys/common/adv7611.c b/board/gdsys/common/adv7611.c new file mode 100644 index 0000000000..b728274cce --- /dev/null +++ b/board/gdsys/common/adv7611.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> + +#define ADV7611_I2C_ADDR 0x4c +#define ADV7611_RDINFO 0x2051 + +/* + * ADV7611 I2C Addresses in u-boot notation + */ +enum { + CP_I2C_ADDR = 0x22, + DPLL_I2C_ADDR = 0x26, + KSV_I2C_ADDR = 0x32, + HDMI_I2C_ADDR = 0x34, + EDID_I2C_ADDR = 0x36, + INFOFRAME_I2C_ADDR = 0x3e, + CEC_I2C_ADDR = 0x40, + IO_I2C_ADDR = ADV7611_I2C_ADDR, +}; + +/* + * Global Control Registers + */ +enum { + IO_RD_INFO_MSB = 0xea, + IO_RD_INFO_LSB = 0xeb, + IO_CEC_ADDR = 0xf4, + IO_INFOFRAME_ADDR = 0xf5, + IO_DPLL_ADDR = 0xf8, + IO_KSV_ADDR = 0xf9, + IO_EDID_ADDR = 0xfa, + IO_HDMI_ADDR = 0xfb, + IO_CP_ADDR = 0xfd, +}; + +int adv7611_i2c[] = CONFIG_SYS_ADV7611_I2C; + +int adv7611_probe(unsigned int screen) +{ + int old_bus = i2c_get_bus_num(); + unsigned int rd_info; + int res = 0; + + i2c_set_bus_num(adv7611_i2c[screen]); + + rd_info = (i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_MSB) << 8) + | i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_LSB); + + if (rd_info != ADV7611_RDINFO) { + res = -1; + goto out; + } + + /* + * set I2C addresses to default values + */ + i2c_reg_write(IO_I2C_ADDR, IO_CEC_ADDR, CEC_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_INFOFRAME_ADDR, INFOFRAME_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_DPLL_ADDR, DPLL_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_KSV_ADDR, KSV_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_EDID_ADDR, EDID_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_HDMI_ADDR, HDMI_I2C_ADDR << 1); + i2c_reg_write(IO_I2C_ADDR, IO_CP_ADDR, CP_I2C_ADDR << 1); + + /* + * do magic initialization sequence from + * "ADV7611 Register Settings Recommendations Revision 1.5" + * with most registers undocumented + */ + i2c_reg_write(CP_I2C_ADDR, 0x6c, 0x00); + i2c_reg_write(HDMI_I2C_ADDR, 0x9b, 0x03); + i2c_reg_write(HDMI_I2C_ADDR, 0x6f, 0x08); + i2c_reg_write(HDMI_I2C_ADDR, 0x85, 0x1f); + i2c_reg_write(HDMI_I2C_ADDR, 0x87, 0x70); + i2c_reg_write(HDMI_I2C_ADDR, 0x57, 0xda); + i2c_reg_write(HDMI_I2C_ADDR, 0x58, 0x01); + i2c_reg_write(HDMI_I2C_ADDR, 0x03, 0x98); + i2c_reg_write(HDMI_I2C_ADDR, 0x4c, 0x44); + + /* + * IO_REG_02, default 0xf0 + * + * INP_COLOR_SPACE (IO, Address 0x02[7:4]) + * default: 0b1111 auto + * set to : 0b0001 force RGB (range 0 to 255) input + * + * RGB_OUT (IO, Address 0x02[1]) + * default: 0 YPbPr color space output + * set to : 1 RGB color space output + */ + i2c_reg_write(IO_I2C_ADDR, 0x02, 0x12); + + /* + * IO_REG_03, default 0x00 + * + * OP_FORMAT_SEL (IO, Address 0x03[7:0]) + * default: 0x00 8-bit SDR ITU-656 mode + * set to : 0x40 24-bit 4:4:4 SDR mode + */ + i2c_reg_write(IO_I2C_ADDR, 0x03, 0x40); + + /* + * IO_REG_05, default 0x2c + * + * AVCODE_INSERT_EN (IO, Address 0x05[2]) + * default: 1 insert AV codes into data stream + * set to : 0 do not insert AV codes into data stream + */ + i2c_reg_write(IO_I2C_ADDR, 0x05, 0x28); + + /* + * IO_REG_0C, default 0x62 + * + * POWER_DOWN (IO, Address 0x0C[5]) + * default: 1 chip is powered down + * set to : 0 chip is operational + */ + i2c_reg_write(IO_I2C_ADDR, 0x0c, 0x42); + + /* + * IO_REG_15, default 0xbe + * + * TRI_SYNCS (IO, Address 0x15[3) + * TRI_LLC (IO, Address 0x15[2]) + * TRI_PIX (IO, Address 0x15[1]) + * default: 1 video output pins are tristate + * set to : 0 video output pins are active + */ + i2c_reg_write(IO_I2C_ADDR, 0x15, 0xb0); + + /* + * HDMI_REGISTER_02H, default 0xff + * + * CLOCK_TERMA_DISABLE (HDMI, Address 0x83[0]) + * default: 1 disable termination + * set to : 0 enable termination + * Future options are: + * - use the chips automatic termination control + * - set this manually on cable detect + * but at the moment this seems a safe default. + */ + i2c_reg_write(HDMI_I2C_ADDR, 0x83, 0xfe); + + /* + * HDMI_CP_CNTRL_1, default 0x01 + * + * HDMI_FRUN_EN (CP, Address 0xBA[0]) + * default: 1 Enable the free run feature in HDMI mode + * set to : 0 Disable the free run feature in HDMI mode + */ + i2c_reg_write(CP_I2C_ADDR, 0xba, 0x00); + + /* + * INT1_CONFIGURATION, default 0x20 + * + * INTRQ_DUR_SEL[1:0] (IO, Address 0x40[7:6]) + * default: 00 Interrupt signal is active for 4 Xtal periods + * set to : 11 Active until cleared + * + * INTRQ_OP_SEL[1:0] (IO, Address 0x40[1:0]) + * default: 00 Open drain + * set to : 10 Drives high when active + */ + i2c_reg_write(IO_I2C_ADDR, 0x40, 0xc2); + +out: + i2c_set_bus_num(old_bus); + + return res; +} diff --git a/board/gdsys/common/adv7611.h b/board/gdsys/common/adv7611.h new file mode 100644 index 0000000000..25a8367db6 --- /dev/null +++ b/board/gdsys/common/adv7611.h @@ -0,0 +1,13 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ADV7611_H_ +#define _ADV7611_H_ + +int adv7611_probe(unsigned int screen); + +#endif diff --git a/board/gdsys/common/ch7301.c b/board/gdsys/common/ch7301.c new file mode 100644 index 0000000000..c054e55cf7 --- /dev/null +++ b/board/gdsys/common/ch7301.c @@ -0,0 +1,64 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Chrontel CH7301C DVI Transmitter */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <i2c.h> + +#define CH7301_I2C_ADDR 0x75 + +enum { + CH7301_CM = 0x1c, /* Clock Mode Register */ + CH7301_IC = 0x1d, /* Input Clock Register */ + CH7301_GPIO = 0x1e, /* GPIO Control Register */ + CH7301_IDF = 0x1f, /* Input Data Format Register */ + CH7301_CD = 0x20, /* Connection Detect Register */ + CH7301_DC = 0x21, /* DAC Control Register */ + CH7301_HPD = 0x23, /* Hot Plug Detection Register */ + CH7301_TCTL = 0x31, /* DVI Control Input Register */ + CH7301_TPCP = 0x33, /* DVI PLL Charge Pump Ctrl Register */ + CH7301_TPD = 0x34, /* DVI PLL Divide Register */ + CH7301_TPVT = 0x35, /* DVI PLL Supply Control Register */ + CH7301_TPF = 0x36, /* DVI PLL Filter Register */ + CH7301_TCT = 0x37, /* DVI Clock Test Register */ + CH7301_TSTP = 0x48, /* Test Pattern Register */ + CH7301_PM = 0x49, /* Power Management register */ + CH7301_VID = 0x4a, /* Version ID Register */ + CH7301_DID = 0x4b, /* Device ID Register */ + CH7301_DSP = 0x56, /* DVI Sync polarity Register */ +}; + +int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C; + +int ch7301_probe(unsigned screen, bool power) +{ + u8 value; + + i2c_set_bus_num(ch7301_i2c[screen]); + if (i2c_probe(CH7301_I2C_ADDR)) + return -1; + + value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID); + if (value != 0x17) + return -1; + + if (power) { + i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08); + i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPD, 0x16); + i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPF, 0x60); + i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x09); + i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0xc0); + } else { + i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x00); + i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0x01); + } + + return 0; +} diff --git a/board/gdsys/common/ch7301.h b/board/gdsys/common/ch7301.h new file mode 100644 index 0000000000..8383719808 --- /dev/null +++ b/board/gdsys/common/ch7301.h @@ -0,0 +1,13 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CH7301_H_ +#define _CH7301_H_ + +int ch7301_probe(unsigned screen, bool power); + +#endif diff --git a/board/gdsys/common/dp501.c b/board/gdsys/common/dp501.c index 7eb15ed0ba..d35aee0879 100644 --- a/board/gdsys/common/dp501.c +++ b/board/gdsys/common/dp501.c @@ -40,11 +40,29 @@ static int dp501_detect_cable_adapter(u8 addr) static void dp501_link_training(u8 addr) { u8 val; + u8 link_bw; + u8 max_lane_cnt; + u8 lane_cnt; val = i2c_reg_read(addr, 0x51); - i2c_reg_write(addr, 0x5d, val); /* set link_bw */ + if (val >= 0x0a) + link_bw = 0x0a; + else + link_bw = 0x06; + if (link_bw != val) + printf("DP sink supports %d Mbps link rate, set to %d Mbps\n", + val * 270, link_bw * 270); + i2c_reg_write(addr, 0x5d, link_bw); /* set link_bw */ val = i2c_reg_read(addr, 0x52); - i2c_reg_write(addr, 0x5e, val); /* set lane_cnt */ + max_lane_cnt = val & 0x1f; + if (max_lane_cnt >= 4) + lane_cnt = 4; + else + lane_cnt = max_lane_cnt; + if (lane_cnt != max_lane_cnt) + printf("DP sink supports %d lanes, set to %d lanes\n", + max_lane_cnt, lane_cnt); + i2c_reg_write(addr, 0x5e, lane_cnt | (val & 0x80)); /* set lane_cnt */ val = i2c_reg_read(addr, 0x53); i2c_reg_write(addr, 0x5c, val); /* set downspread_ctl */ @@ -77,6 +95,8 @@ void dp501_powerup(u8 addr) i2c_reg_write(addr + 2, 0x24, 0x02); /* clock input single ended */ #endif + i2c_reg_write(addr + 2, 0x1a, 0x04); /* SPDIF input method TTL */ + i2c_reg_write(addr + 2, 0x00, 0x18); /* driving strength */ i2c_reg_write(addr + 2, 0x03, 0x06); /* driving strength */ i2c_reg_write(addr, 0x2c, 0x00); /* configure N value */ @@ -86,7 +106,8 @@ void dp501_powerup(u8 addr) dp501_setbits(addr, 0x78, 0x03); /* clear all interrupt */ i2c_reg_write(addr, 0x75, 0xf8); /* aux channel reset */ i2c_reg_write(addr, 0x75, 0x00); /* clear aux channel reset */ - i2c_reg_write(addr, 0x87, 0x70); /* set retry counter as 7 */ + i2c_reg_write(addr, 0x87, 0x7f); /* set retry counter as 7 + retry interval 400us */ if (dp501_detect_cable_adapter(addr)) { printf("DVI/HDMI cable adapter detected\n"); diff --git a/board/gdsys/common/fanctrl.c b/board/gdsys/common/fanctrl.c new file mode 100644 index 0000000000..44569bb1ab --- /dev/null +++ b/board/gdsys/common/fanctrl.c @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2015 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> + +enum { + FAN_CONFIG = 0x03, + FAN_TACHLIM_LSB = 0x48, + FAN_TACHLIM_MSB = 0x49, + FAN_PWM_FREQ = 0x4D, +}; + +void init_fan_controller(u8 addr) +{ + int val; + + /* set PWM Frequency to 2.5% resolution */ + i2c_reg_write(addr, FAN_PWM_FREQ, 20); + + /* set Tachometer Limit */ + i2c_reg_write(addr, FAN_TACHLIM_LSB, 0x10); + i2c_reg_write(addr, FAN_TACHLIM_MSB, 0x0a); + + /* enable Tach input */ + val = i2c_reg_read(addr, FAN_CONFIG) | 0x04; + i2c_reg_write(addr, FAN_CONFIG, val); +} diff --git a/board/gdsys/common/fanctrl.h b/board/gdsys/common/fanctrl.h new file mode 100644 index 0000000000..12bc850f85 --- /dev/null +++ b/board/gdsys/common/fanctrl.h @@ -0,0 +1,13 @@ +/* + * (C) Copyright 2015 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FANCTRL_H_ +#define _FANCTRL_H_ + +void init_fan_controller(u8 addr); + +#endif diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c new file mode 100644 index 0000000000..96f02d68ed --- /dev/null +++ b/board/gdsys/common/ioep-fpga.c @@ -0,0 +1,232 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#include <gdsys_fpga.h> + +enum { + UNITTYPE_MAIN_SERVER = 0, + UNITTYPE_MAIN_USER = 1, + UNITTYPE_VIDEO_SERVER = 2, + UNITTYPE_VIDEO_USER = 3, +}; + +enum { + UNITTYPEPCB_DVI = 0, + UNITTYPEPCB_DP_165 = 1, + UNITTYPEPCB_DP_300 = 2, + UNITTYPEPCB_HDMI = 3, +}; + +enum { + COMPRESSION_NONE = 0, + COMPRESSION_TYPE1_DELTA = 1, + COMPRESSION_TYPE1_TYPE2_DELTA = 3, +}; + +enum { + AUDIO_NONE = 0, + AUDIO_TX = 1, + AUDIO_RX = 2, + AUDIO_RXTX = 3, +}; + +enum { + SYSCLK_147456 = 0, +}; + +enum { + RAM_DDR2_32 = 0, + RAM_DDR3_32 = 1, + RAM_DDR3_48 = 2, +}; + +enum { + CARRIER_SPEED_1G = 0, + CARRIER_SPEED_2_5G = 1, +}; + +bool ioep_fpga_has_osd(unsigned int fpga) +{ + u16 fpga_features; + unsigned feature_osd; + + FPGA_GET_REG(0, fpga_features, &fpga_features); + feature_osd = fpga_features & (1<<11); + + return feature_osd; +} + +void ioep_fpga_print_info(unsigned int fpga) +{ + u16 versions; + u16 fpga_version; + u16 fpga_features; + unsigned unit_type; + unsigned unit_type_pcb_video; + unsigned feature_compression; + unsigned feature_osd; + unsigned feature_audio; + unsigned feature_sysclock; + unsigned feature_ramconfig; + unsigned feature_carrier_speed; + unsigned feature_carriers; + unsigned feature_video_channels; + + FPGA_GET_REG(fpga, versions, &versions); + FPGA_GET_REG(fpga, fpga_version, &fpga_version); + FPGA_GET_REG(fpga, fpga_features, &fpga_features); + + unit_type = (versions & 0xf000) >> 12; + unit_type_pcb_video = (versions & 0x01c0) >> 6; + feature_compression = (fpga_features & 0xe000) >> 13; + feature_osd = fpga_features & (1<<11); + feature_audio = (fpga_features & 0x0600) >> 9; + feature_sysclock = (fpga_features & 0x0180) >> 7; + feature_ramconfig = (fpga_features & 0x0060) >> 5; + feature_carrier_speed = fpga_features & (1<<4); + feature_carriers = (fpga_features & 0x000c) >> 2; + feature_video_channels = fpga_features & 0x0003; + + switch (unit_type) { + case UNITTYPE_MAIN_SERVER: + case UNITTYPE_MAIN_USER: + printf("Mainchannel"); + break; + + case UNITTYPE_VIDEO_SERVER: + case UNITTYPE_VIDEO_USER: + printf("Videochannel"); + break; + + default: + printf("UnitType %d(not supported)", unit_type); + break; + } + + switch (unit_type) { + case UNITTYPE_MAIN_SERVER: + case UNITTYPE_VIDEO_SERVER: + printf(" Server"); + if (versions & (1<<4)) + printf(" UC"); + break; + + case UNITTYPE_MAIN_USER: + case UNITTYPE_VIDEO_USER: + printf(" User"); + break; + + default: + break; + } + + if (versions & (1<<5)) + printf(" Fiber"); + else + printf(" CAT"); + + switch (unit_type_pcb_video) { + case UNITTYPEPCB_DVI: + printf(" DVI,"); + break; + + case UNITTYPEPCB_DP_165: + printf(" DP 165MPix/s,"); + break; + + case UNITTYPEPCB_DP_300: + printf(" DP 300MPix/s,"); + break; + + case UNITTYPEPCB_HDMI: + printf(" HDMI,"); + break; + } + + printf(" FPGA V %d.%02d\n features:", + fpga_version / 100, fpga_version % 100); + + + switch (feature_compression) { + case COMPRESSION_NONE: + printf(" no compression"); + break; + + case COMPRESSION_TYPE1_DELTA: + printf(" type1-deltacompression"); + break; + + case COMPRESSION_TYPE1_TYPE2_DELTA: + printf(" type1-deltacompression, type2-inlinecompression"); + break; + + default: + printf(" compression %d(not supported)", feature_compression); + break; + } + + printf(", %sosd", feature_osd ? "" : "no "); + + switch (feature_audio) { + case AUDIO_NONE: + printf(", no audio"); + break; + + case AUDIO_TX: + printf(", audio tx"); + break; + + case AUDIO_RX: + printf(", audio rx"); + break; + + case AUDIO_RXTX: + printf(", audio rx+tx"); + break; + + default: + printf(", audio %d(not supported)", feature_audio); + break; + } + + puts(",\n "); + + switch (feature_sysclock) { + case SYSCLK_147456: + printf("clock 147.456 MHz"); + break; + + default: + printf("clock %d(not supported)", feature_sysclock); + break; + } + + switch (feature_ramconfig) { + case RAM_DDR2_32: + printf(", RAM 32 bit DDR2"); + break; + + case RAM_DDR3_32: + printf(", RAM 32 bit DDR3"); + break; + + case RAM_DDR3_48: + printf(", RAM 48 bit DDR3"); + break; + + default: + printf(", RAM %d(not supported)", feature_ramconfig); + break; + } + + printf(", %d carrier(s) %s", feature_carriers, + feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s"); + + printf(", %d video channel(s)\n", feature_video_channels); +} diff --git a/board/gdsys/common/ioep-fpga.h b/board/gdsys/common/ioep-fpga.h new file mode 100644 index 0000000000..44f71399e7 --- /dev/null +++ b/board/gdsys/common/ioep-fpga.h @@ -0,0 +1,14 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _IOEP_FPGA_H_ +#define _IOEP_FPGA_H_ + +void ioep_fpga_print_info(unsigned int fpga); +bool ioep_fpga_has_osd(unsigned int fpga); + +#endif diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c index 55ecdf1012..7444bee129 100644 --- a/board/gdsys/common/osd.c +++ b/board/gdsys/common/osd.c @@ -9,11 +9,10 @@ #include <i2c.h> #include <malloc.h> +#include "ch7301.h" #include "dp501.h" #include <gdsys_fpga.h> -#define CH7301_I2C_ADDR 0x75 - #define ICS8N3QV01_I2C_ADDR 0x6E #define ICS8N3QV01_FREF 114285000 #define ICS8N3QV01_FREF_LL 114285000LL @@ -28,43 +27,53 @@ #define DP501_I2C_ADDR 0x08 #define PIXCLK_640_480_60 25180000 +#define MAX_X_CHARS 53 +#define MAX_Y_CHARS 26 + +#ifdef CONFIG_SYS_OSD_DH +#define MAX_OSD_SCREEN 8 +#define OSD_DH_BASE 4 +#else +#define MAX_OSD_SCREEN 4 +#endif + +#ifdef CONFIG_SYS_OSD_DH +#define OSD_SET_REG(screen, fld, val) \ + do { \ + if (screen >= OSD_DH_BASE) \ + FPGA_SET_REG(screen - OSD_DH_BASE, osd1.fld, val); \ + else \ + FPGA_SET_REG(screen, osd0.fld, val); \ + } while (0) +#else +#define OSD_SET_REG(screen, fld, val) \ + FPGA_SET_REG(screen, osd0.fld, val) +#endif -enum { - CH7301_CM = 0x1c, /* Clock Mode Register */ - CH7301_IC = 0x1d, /* Input Clock Register */ - CH7301_GPIO = 0x1e, /* GPIO Control Register */ - CH7301_IDF = 0x1f, /* Input Data Format Register */ - CH7301_CD = 0x20, /* Connection Detect Register */ - CH7301_DC = 0x21, /* DAC Control Register */ - CH7301_HPD = 0x23, /* Hot Plug Detection Register */ - CH7301_TCTL = 0x31, /* DVI Control Input Register */ - CH7301_TPCP = 0x33, /* DVI PLL Charge Pump Ctrl Register */ - CH7301_TPD = 0x34, /* DVI PLL Divide Register */ - CH7301_TPVT = 0x35, /* DVI PLL Supply Control Register */ - CH7301_TPF = 0x36, /* DVI PLL Filter Register */ - CH7301_TCT = 0x37, /* DVI Clock Test Register */ - CH7301_TSTP = 0x48, /* Test Pattern Register */ - CH7301_PM = 0x49, /* Power Management register */ - CH7301_VID = 0x4a, /* Version ID Register */ - CH7301_DID = 0x4b, /* Device ID Register */ - CH7301_DSP = 0x56, /* DVI Sync polarity Register */ -}; +#ifdef CONFIG_SYS_OSD_DH +#define OSD_GET_REG(screen, fld, val) \ + do { \ + if (screen >= OSD_DH_BASE) \ + FPGA_GET_REG(screen - OSD_DH_BASE, osd1.fld, val); \ + else \ + FPGA_GET_REG(screen, osd0.fld, val); \ + } while (0) +#else +#define OSD_GET_REG(screen, fld, val) \ + FPGA_GET_REG(screen, osd0.fld, val) +#endif unsigned int base_width; unsigned int base_height; size_t bufsize; u16 *buf; -unsigned int max_osd_screen = CONFIG_SYS_OSD_SCREENS - 1; +unsigned int osd_screen_mask = 0; #ifdef CONFIG_SYS_ICS8N3QV01_I2C int ics8n3qv01_i2c[] = CONFIG_SYS_ICS8N3QV01_I2C; #endif -#ifdef CONFIG_SYS_CH7301_I2C -int ch7301_i2c[] = CONFIG_SYS_CH7301_I2C; -#endif - #ifdef CONFIG_SYS_SIL1178_I2C int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C; #endif @@ -73,6 +82,9 @@ int sil1178_i2c[] = CONFIG_SYS_SIL1178_I2C; int dp501_i2c[] = CONFIG_SYS_DP501_I2C; #endif +#ifdef CONFIG_SYS_DP501_BASE +int dp501_base[] = CONFIG_SYS_DP501_BASE; +#endif #ifdef CONFIG_SYS_MPC92469AC static void mpc92469ac_calc_parameters(unsigned int fout, @@ -242,7 +254,15 @@ static int osd_write_videomem(unsigned screen, unsigned offset, for (k = 0; k < charcount; ++k) { if (offset + k >= bufsize) return -1; - FPGA_SET_REG(screen, videomem[offset + k], data[k]); +#ifdef CONFIG_SYS_OSD_DH + if (screen >= OSD_DH_BASE) + FPGA_SET_REG(screen - OSD_DH_BASE, + videomem1[offset + k], data[k]); + else + FPGA_SET_REG(screen, videomem0[offset + k], data[k]); +#else + FPGA_SET_REG(screen, videomem0[offset + k], data[k]); +#endif } return charcount; @@ -252,7 +272,12 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned screen; - for (screen = 0; screen <= max_osd_screen; ++screen) { + if (argc < 5) { + cmd_usage(cmdtp); + return 1; + } + + for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) { unsigned x; unsigned y; unsigned charcount; @@ -262,10 +287,8 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *text; int res; - if (argc < 5) { - cmd_usage(cmdtp); - return 1; - } + if (!(osd_screen_mask & (1 << screen))) + continue; x = simple_strtoul(argv[1], NULL, 16); y = simple_strtoul(argv[2], NULL, 16); @@ -280,6 +303,8 @@ static int osd_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) res = osd_write_videomem(screen, y * base_width + x, buf, len); if (res < 0) return res; + + OSD_SET_REG(screen, control, 0x0049); } return 0; @@ -292,9 +317,16 @@ int osd_probe(unsigned screen) int old_bus = i2c_get_bus_num(); bool pixclock_present = false; bool output_driver_present = false; +#ifdef CONFIG_SYS_DP501_I2C +#ifdef CONFIG_SYS_DP501_BASE + uint8_t dp501_addr = dp501_base[screen]; +#else + uint8_t dp501_addr = DP501_I2C_ADDR; +#endif +#endif - FPGA_GET_REG(0, osd.version, &version); - FPGA_GET_REG(0, osd.features, &features); + OSD_GET_REG(0, version, &version); + OSD_GET_REG(0, features, &features); base_width = ((features & 0x3f00) >> 8) + 1; base_height = (features & 0x001f) + 1; @@ -303,9 +335,15 @@ int osd_probe(unsigned screen) if (!buf) return -1; +#ifdef CONFIG_SYS_OSD_DH + printf("OSD%d-%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n", + (screen >= OSD_DH_BASE) ? (screen - OSD_DH_BASE) : screen, + (screen > 3) ? 1 : 0, version/100, version%100, base_width, + base_height); +#else printf("OSD%d: Digital-OSD version %01d.%02d, %d" "x%d characters\n", - screen, version/100, version%100, base_width, base_height); - + screen, version/100, version%100, base_width, base_height); +#endif /* setup pixclock */ #ifdef CONFIG_SYS_MPC92469AC @@ -327,19 +365,8 @@ int osd_probe(unsigned screen) /* setup output driver */ #ifdef CONFIG_SYS_CH7301_I2C - i2c_set_bus_num(ch7301_i2c[screen]); - if (!i2c_probe(CH7301_I2C_ADDR)) { - u8 value = i2c_reg_read(CH7301_I2C_ADDR, CH7301_DID); - - if (value == 0x17) { - i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPCP, 0x08); - i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPD, 0x16); - i2c_reg_write(CH7301_I2C_ADDR, CH7301_TPF, 0x60); - i2c_reg_write(CH7301_I2C_ADDR, CH7301_DC, 0x09); - i2c_reg_write(CH7301_I2C_ADDR, CH7301_PM, 0xc0); - output_driver_present = true; - } - } + if (!ch7301_probe(screen, true)) + output_driver_present = true; #endif #ifdef CONFIG_SYS_SIL1178_I2C @@ -367,8 +394,8 @@ int osd_probe(unsigned screen) #ifdef CONFIG_SYS_DP501_I2C i2c_set_bus_num(dp501_i2c[screen]); - if (!i2c_probe(DP501_I2C_ADDR)) { - dp501_powerup(DP501_I2C_ADDR); + if (!i2c_probe(dp501_addr)) { + dp501_powerup(dp501_addr); output_driver_present = true; } #endif @@ -376,14 +403,12 @@ int osd_probe(unsigned screen) if (!output_driver_present) printf(" no output driver found\n"); - FPGA_SET_REG(screen, osd.control, 0x0049); - - FPGA_SET_REG(screen, osd.xy_size, ((32 - 1) << 8) | (16 - 1)); - FPGA_SET_REG(screen, osd.x_pos, 0x007f); - FPGA_SET_REG(screen, osd.y_pos, 0x005f); + OSD_SET_REG(screen, xy_size, ((32 - 1) << 8) | (16 - 1)); + OSD_SET_REG(screen, x_pos, 0x007f); + OSD_SET_REG(screen, y_pos, 0x005f); - if (screen > max_osd_screen) - max_osd_screen = screen; + if (pixclock_present && output_driver_present) + osd_screen_mask |= 1 << screen; i2c_set_bus_num(old_bus); @@ -394,7 +419,12 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned screen; - for (screen = 0; screen <= max_osd_screen; ++screen) { + if ((argc < 4) || (strlen(argv[3]) % 4)) { + cmd_usage(cmdtp); + return 1; + } + + for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) { unsigned x; unsigned y; unsigned k; @@ -404,10 +434,8 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) unsigned count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1; - if ((argc < 4) || (strlen(argv[3]) % 4)) { - cmd_usage(cmdtp); - return 1; - } + if (!(osd_screen_mask & (1 << screen))) + continue; x = simple_strtoul(argv[1], NULL, 16); y = simple_strtoul(argv[2], NULL, 16); @@ -433,6 +461,37 @@ int osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) osd_write_videomem(screen, offset, buffer, wp - buffer); } + + OSD_SET_REG(screen, control, 0x0049); + } + + return 0; +} + +int osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned screen; + unsigned x; + unsigned y; + + if (argc < 3) { + cmd_usage(cmdtp); + return 1; + } + + x = simple_strtoul(argv[1], NULL, 16); + y = simple_strtoul(argv[2], NULL, 16); + + if (!x || (x > 64) || (x > MAX_X_CHARS) || + !y || (y > 32) || (y > MAX_Y_CHARS)) { + cmd_usage(cmdtp); + return 1; + } + + for (screen = 0; screen < MAX_OSD_SCREEN; ++screen) { + OSD_SET_REG(screen, xy_size, ((x - 1) << 8) | (y - 1)); + OSD_SET_REG(screen, x_pos, 32767 * (640 - 12 * x) / 65535); + OSD_SET_REG(screen, y_pos, 32767 * (480 - 18 * y) / 65535); } return 0; @@ -449,3 +508,10 @@ U_BOOT_CMD( "write ASCII buffer to osd memory", "pos_x pos_y color text\n" ); + +U_BOOT_CMD( + osdsize, 3, 0, osd_size, + "set OSD XY size in characters", + "size_x(max. " __stringify(MAX_X_CHARS) + ") size_y(max. " __stringify(MAX_Y_CHARS) ")\n" +); diff --git a/board/gdsys/common/osd.h b/board/gdsys/common/osd.h index 440b276a0b..5b3f14bf05 100644 --- a/board/gdsys/common/osd.h +++ b/board/gdsys/common/osd.h @@ -8,6 +8,7 @@ #ifndef _OSD_H_ #define _OSD_H_ +int ch7301_probe(unsigned screen, bool power); int osd_probe(unsigned screen); #endif diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig index 43e1663d19..9a1a3a2f28 100644 --- a/board/gdsys/mpc8308/Kconfig +++ b/board/gdsys/mpc8308/Kconfig @@ -10,3 +10,16 @@ config SYS_CONFIG_NAME default "hrcon" endif + +if TARGET_STRIDER + +config SYS_BOARD + default "mpc8308" + +config SYS_VENDOR + default "gdsys" + +config SYS_CONFIG_NAME + default "strider" + +endif diff --git a/board/gdsys/mpc8308/MAINTAINERS b/board/gdsys/mpc8308/MAINTAINERS index a7853a59df..3895b01732 100644 --- a/board/gdsys/mpc8308/MAINTAINERS +++ b/board/gdsys/mpc8308/MAINTAINERS @@ -4,3 +4,7 @@ S: Maintained F: board/gdsys/mpc8308/ F: include/configs/hrcon.h F: configs/hrcon_defconfig +F: configs/hrcon_dh_defconfig +F: include/configs/strider.h +F: configs/strider_cpu_defconfig +F: configs/strider_con_defconfig diff --git a/board/gdsys/mpc8308/Makefile b/board/gdsys/mpc8308/Makefile index b5dfdbb190..42702fb967 100644 --- a/board/gdsys/mpc8308/Makefile +++ b/board/gdsys/mpc8308/Makefile @@ -7,3 +7,4 @@ obj-y := mpc8308.o sdram.o obj-$(CONFIG_HRCON) += hrcon.o +obj-$(CONFIG_STRIDER) += strider.o diff --git a/board/gdsys/mpc8308/hrcon.c b/board/gdsys/mpc8308/hrcon.c index e4434b3b6b..880b6387de 100644 --- a/board/gdsys/mpc8308/hrcon.c +++ b/board/gdsys/mpc8308/hrcon.c @@ -22,9 +22,11 @@ #include <gdsys_fpga.h> +#include "../common/ioep-fpga.h" #include "../common/osd.h" #include "../common/mclink.h" #include "../common/phy.h" +#include "../common/fanctrl.h" #include <pca953x.h> #include <pca9698.h> @@ -36,57 +38,6 @@ DECLARE_GLOBAL_DATA_PTR; #define MAX_MUX_CHANNELS 2 enum { - UNITTYPE_MAIN_SERVER = 0, - UNITTYPE_MAIN_USER = 1, - UNITTYPE_VIDEO_SERVER = 2, - UNITTYPE_VIDEO_USER = 3, -}; - -enum { - UNITTYPEPCB_DVI = 0, - UNITTYPEPCB_DP_165 = 1, - UNITTYPEPCB_DP_300 = 2, - UNITTYPEPCB_HDMI = 3, -}; - -enum { - HWVER_100 = 0, - HWVER_110 = 1, -}; - -enum { - FPGA_HWVER_200 = 0, - FPGA_HWVER_210 = 1, -}; - -enum { - COMPRESSION_NONE = 0, - COMPRESSION_TYPE1_DELTA = 1, - COMPRESSION_TYPE1_TYPE2_DELTA = 3, -}; - -enum { - AUDIO_NONE = 0, - AUDIO_TX = 1, - AUDIO_RX = 2, - AUDIO_RXTX = 3, -}; - -enum { - SYSCLK_147456 = 0, -}; - -enum { - RAM_DDR2_32 = 0, - RAM_DDR3_32 = 1, -}; - -enum { - CARRIER_SPEED_1G = 0, - CARRIER_SPEED_2_5G = 1, -}; - -enum { MCFPGA_DONE = 1 << 0, MCFPGA_INIT_N = 1 << 1, MCFPGA_PROGRAM_N = 1 << 2, @@ -102,6 +53,11 @@ enum { unsigned int mclink_fpgacount; struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; +struct { + u8 bus; + u8 addr; +} hrcon_fans[] = CONFIG_HRCON_FANS; + int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) { int res; @@ -164,197 +120,12 @@ int checkboard(void) return 0; } -static void print_fpga_info(unsigned int fpga, bool rgmii2_present) -{ - u16 versions; - u16 fpga_version; - u16 fpga_features; - unsigned unit_type; - unsigned unit_type_pcb_video; - unsigned hardware_version; - unsigned feature_compression; - unsigned feature_osd; - unsigned feature_audio; - unsigned feature_sysclock; - unsigned feature_ramconfig; - unsigned feature_carrier_speed; - unsigned feature_carriers; - unsigned feature_video_channels; - - FPGA_GET_REG(fpga, versions, &versions); - FPGA_GET_REG(fpga, fpga_version, &fpga_version); - FPGA_GET_REG(fpga, fpga_features, &fpga_features); - - unit_type = (versions & 0xf000) >> 12; - unit_type_pcb_video = (versions & 0x01c0) >> 6; - feature_compression = (fpga_features & 0xe000) >> 13; - feature_osd = fpga_features & (1<<11); - feature_audio = (fpga_features & 0x0600) >> 9; - feature_sysclock = (fpga_features & 0x0180) >> 7; - feature_ramconfig = (fpga_features & 0x0060) >> 5; - feature_carrier_speed = fpga_features & (1<<4); - feature_carriers = (fpga_features & 0x000c) >> 2; - feature_video_channels = fpga_features & 0x0003; - - switch (unit_type) { - case UNITTYPE_MAIN_USER: - printf("Mainchannel"); - break; - - case UNITTYPE_VIDEO_USER: - printf("Videochannel"); - break; - - default: - printf("UnitType %d(not supported)", unit_type); - break; - } - - if (unit_type == UNITTYPE_MAIN_USER) { - hardware_version = - (!!pca9698_get_value(0x20, 24) << 0) - | (!!pca9698_get_value(0x20, 25) << 1) - | (!!pca9698_get_value(0x20, 26) << 2) - | (!!pca9698_get_value(0x20, 27) << 3) - | (!!pca9698_get_value(0x20, 28) << 4); - switch (hardware_version) { - case HWVER_100: - printf(" HW-Ver 1.00,"); - break; - - case HWVER_110: - printf(" HW-Ver 1.10,"); - break; - - default: - printf(" HW-Ver %d(not supported),", - hardware_version); - break; - } - if (rgmii2_present) - printf(" RGMII2,"); - } - - if (unit_type == UNITTYPE_VIDEO_USER) { - hardware_version = versions & 0x000f; - switch (hardware_version) { - case FPGA_HWVER_200: - printf(" HW-Ver 2.00,"); - break; - - case FPGA_HWVER_210: - printf(" HW-Ver 2.10,"); - break; - - default: - printf(" HW-Ver %d(not supported),", - hardware_version); - break; - } - } - - switch (unit_type_pcb_video) { - case UNITTYPEPCB_DVI: - printf(" DVI,"); - break; - - case UNITTYPEPCB_DP_165: - printf(" DP 165MPix/s,"); - break; - - case UNITTYPEPCB_DP_300: - printf(" DP 300MPix/s,"); - break; - - case UNITTYPEPCB_HDMI: - printf(" HDMI,"); - break; - } - - printf(" FPGA V %d.%02d\n features:", - fpga_version / 100, fpga_version % 100); - - - switch (feature_compression) { - case COMPRESSION_NONE: - printf(" no compression"); - break; - - case COMPRESSION_TYPE1_DELTA: - printf(" type1-deltacompression"); - break; - - case COMPRESSION_TYPE1_TYPE2_DELTA: - printf(" type1-deltacompression, type2-inlinecompression"); - break; - - default: - printf(" compression %d(not supported)", feature_compression); - break; - } - - printf(", %sosd", feature_osd ? "" : "no "); - - switch (feature_audio) { - case AUDIO_NONE: - printf(", no audio"); - break; - - case AUDIO_TX: - printf(", audio tx"); - break; - - case AUDIO_RX: - printf(", audio rx"); - break; - - case AUDIO_RXTX: - printf(", audio rx+tx"); - break; - - default: - printf(", audio %d(not supported)", feature_audio); - break; - } - - puts(",\n "); - - switch (feature_sysclock) { - case SYSCLK_147456: - printf("clock 147.456 MHz"); - break; - - default: - printf("clock %d(not supported)", feature_sysclock); - break; - } - - switch (feature_ramconfig) { - case RAM_DDR2_32: - printf(", RAM 32 bit DDR2"); - break; - - case RAM_DDR3_32: - printf(", RAM 32 bit DDR3"); - break; - - default: - printf(", RAM %d(not supported)", feature_ramconfig); - break; - } - - printf(", %d carrier(s) %s", feature_carriers, - feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s"); - - printf(", %d video channel(s)\n", feature_video_channels); -} - int last_stage_init(void) { int slaves; unsigned int k; unsigned int mux_ch; - unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 }; + unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e }; u16 fpga_features; bool hw_type_cat = pca9698_get_value(0x20, 20); bool ch0_rgmii2_present = false; @@ -363,10 +134,11 @@ int last_stage_init(void) /* Turn on Parade DP501 */ pca9698_direction_output(0x20, 10, 1); + pca9698_direction_output(0x20, 11, 1); ch0_rgmii2_present = !pca9698_get_value(0x20, 30); - /* wait for FPGA done */ + /* wait for FPGA done, then reset FPGA */ for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { unsigned int ctr = 0; @@ -381,6 +153,12 @@ int last_stage_init(void) break; } } + + pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0); + udelay(10); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, + MCFPGA_RESET_N); } if (hw_type_cat) { @@ -401,8 +179,11 @@ int last_stage_init(void) slaves = mclink_probe(); mclink_fpgacount = 0; - print_fpga_info(0, ch0_rgmii2_present); + ioep_fpga_print_info(0); osd_probe(0); +#ifdef CONFIG_SYS_OSD_DH + osd_probe(4); +#endif if (slaves <= 0) return 0; @@ -412,8 +193,11 @@ int last_stage_init(void) for (k = 1; k <= slaves; ++k) { FPGA_GET_REG(k, fpga_features, &fpga_features); - print_fpga_info(k, false); + ioep_fpga_print_info(k); osd_probe(k); +#ifdef CONFIG_SYS_OSD_DH + osd_probe(k + 4); +#endif if (hw_type_cat) { miiphy_register(bb_miiphy_buses[k].name, bb_miiphy_read, bb_miiphy_write); @@ -421,32 +205,53 @@ int last_stage_init(void) } } + for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) { + i2c_set_bus_num(hrcon_fans[k].bus); + init_fan_controller(hrcon_fans[k].addr); + } + return 0; } /* - * provide access to fpga gpios (for I2C bitbang) + * provide access to fpga gpios and controls (for I2C bitbang) * (these may look all too simple but make iocon.h much more readable) */ void fpga_gpio_set(unsigned int bus, int pin) { - FPGA_SET_REG(bus, gpio.set, pin); + FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin); } void fpga_gpio_clear(unsigned int bus, int pin) { - FPGA_SET_REG(bus, gpio.clear, pin); + FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin); } int fpga_gpio_get(unsigned int bus, int pin) { u16 val; - FPGA_GET_REG(bus, gpio.read, &val); + FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val); return val & pin; } +void fpga_control_set(unsigned int bus, int pin) +{ + u16 val; + + FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val); + FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin); +} + +void fpga_control_clear(unsigned int bus, int pin) +{ + u16 val; + + FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val); + FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin); +} + void mpc8308_init(void) { pca9698_direction_output(0x20, 4, 1); diff --git a/board/gdsys/mpc8308/strider.c b/board/gdsys/mpc8308/strider.c new file mode 100644 index 0000000000..ef5b6c03f8 --- /dev/null +++ b/board/gdsys/mpc8308/strider.c @@ -0,0 +1,479 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <hwconfig.h> +#include <i2c.h> +#include <spi.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <pci.h> +#include <mpc83xx.h> +#include <fsl_esdhc.h> +#include <asm/io.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_mpc83xx_serdes.h> + +#include "mpc8308.h" + +#include <gdsys_fpga.h> + +#include "../common/adv7611.h" +#include "../common/ch7301.h" +#include "../common/ioep-fpga.h" +#include "../common/mclink.h" +#include "../common/osd.h" +#include "../common/phy.h" +#include "../common/fanctrl.h" + +#include <pca953x.h> +#include <pca9698.h> + +#include <miiphy.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MAX_MUX_CHANNELS 2 + +enum { + MCFPGA_DONE = 1 << 0, + MCFPGA_INIT_N = 1 << 1, + MCFPGA_PROGRAM_N = 1 << 2, + MCFPGA_UPDATE_ENABLE_N = 1 << 3, + MCFPGA_RESET_N = 1 << 4, +}; + +enum { + GPIO_MDC = 1 << 14, + GPIO_MDIO = 1 << 15, +}; + +unsigned int mclink_fpgacount; +struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; + +struct { + u8 bus; + u8 addr; +} strider_fans[] = CONFIG_STRIDER_FANS; + +int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) +{ + int res; + + switch (fpga) { + case 0: + out_le16(reg, data); + break; + default: + res = mclink_send(fpga - 1, regoff, data); + if (res < 0) { + printf("mclink_send reg %02lx data %04x returned %d\n", + regoff, data, res); + return res; + } + break; + } + + return 0; +} + +int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data) +{ + int res; + + switch (fpga) { + case 0: + *data = in_le16(reg); + break; + default: + if (fpga > mclink_fpgacount) + return -EINVAL; + res = mclink_receive(fpga - 1, regoff, data); + if (res < 0) { + printf("mclink_receive reg %02lx returned %d\n", + regoff, res); + return res; + } + } + + return 0; +} + +int checkboard(void) +{ + char *s = getenv("serial#"); + bool hw_type_cat = pca9698_get_value(0x20, 18); + + puts("Board: "); + + printf("Strider %s", hw_type_cat ? "CAT" : "Fiber"); + + if (s != NULL) { + puts(", serial# "); + puts(s); + } + + puts("\n"); + + return 0; +} + +int last_stage_init(void) +{ + int slaves; + unsigned int k; + unsigned int mux_ch; + unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e }; + bool hw_type_cat = pca9698_get_value(0x20, 18); + bool ch0_sgmii2_present = false; + + /* Turn on Analog Devices ADV7611 */ + pca9698_direction_output(0x20, 8, 0); + + /* Turn on Parade DP501 */ + pca9698_direction_output(0x20, 9, 1); + + ch0_sgmii2_present = !pca9698_get_value(0x20, 37); + + /* wait for FPGA done, then reset FPGA */ + for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { + unsigned int ctr = 0; + + if (i2c_probe(mclink_controllers[k])) + continue; + + while (!(pca953x_get_val(mclink_controllers[k]) + & MCFPGA_DONE)) { + udelay(100000); + if (ctr++ > 5) { + printf("no done for mclink_controller %d\n", k); + break; + } + } + + pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0); + udelay(10); + pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, + MCFPGA_RESET_N); + } + + if (hw_type_cat) { + miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, + bb_miiphy_write); + for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { + if ((mux_ch == 1) && !ch0_sgmii2_present) + continue; + + setup_88e1514(bb_miiphy_buses[0].name, mux_ch); + } + } + + /* give slave-PLLs and Parade DP501 some time to be up and running */ + udelay(500000); + + mclink_fpgacount = CONFIG_SYS_MCLINK_MAX; + slaves = mclink_probe(); + mclink_fpgacount = 0; + + ioep_fpga_print_info(0); + + if (!adv7611_probe(0)) + printf(" Advantiv ADV7611 HDMI Receiver\n"); + +#ifdef CONFIG_STRIDER_CON + if (ioep_fpga_has_osd(0)) + osd_probe(0); +#endif + +#ifdef CONFIG_STRIDER_CPU + ch7301_probe(0, false); +#endif + + if (slaves <= 0) + return 0; + + mclink_fpgacount = slaves; + + for (k = 1; k <= slaves; ++k) { + ioep_fpga_print_info(k); +#ifdef CONFIG_STRIDER_CON + if (ioep_fpga_has_osd(k)) + osd_probe(k); +#endif +#ifdef CONFIG_STRIDER_CPU + FPGA_SET_REG(k, extended_control, 0); /* enable video in*/ + if (!adv7611_probe(k)) + printf(" Advantiv ADV7611 HDMI Receiver\n"); + ch7301_probe(k, false); +#endif + if (hw_type_cat) { + miiphy_register(bb_miiphy_buses[k].name, + bb_miiphy_read, bb_miiphy_write); + setup_88e1514(bb_miiphy_buses[k].name, 0); + } + } + + for (k = 0; k < ARRAY_SIZE(strider_fans); ++k) { + i2c_set_bus_num(strider_fans[k].bus); + init_fan_controller(strider_fans[k].addr); + } + + return 0; +} + +/* + * provide access to fpga gpios (for I2C bitbang) + * (these may look all too simple but make iocon.h much more readable) + */ +void fpga_gpio_set(unsigned int bus, int pin) +{ + FPGA_SET_REG(bus, gpio.set, pin); +} + +void fpga_gpio_clear(unsigned int bus, int pin) +{ + FPGA_SET_REG(bus, gpio.clear, pin); +} + +int fpga_gpio_get(unsigned int bus, int pin) +{ + u16 val; + + FPGA_GET_REG(bus, gpio.read, &val); + + return val & pin; +} + +void mpc8308_init(void) +{ + pca9698_direction_output(0x20, 26, 1); +} + +void mpc8308_set_fpga_reset(unsigned state) +{ + pca9698_set_value(0x20, 26, state ? 0 : 1); +} + +void mpc8308_setup_hw(void) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* + * set "startup-finished"-gpios + */ + setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12))); + setbits_be32(&immr->gpio[0].dat, 1 << (31-12)); +} + +int mpc8308_get_fpga_done(unsigned fpga) +{ + return pca9698_get_value(0x20, 20); +} + +#ifdef CONFIG_FSL_ESDHC +int board_mmc_init(bd_t *bd) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + sysconf83xx_t *sysconf = &immr->sysconf; + + /* Enable cache snooping in eSDHC system configuration register */ + out_be32(&sysconf->sdhccr, 0x02000000); + + return fsl_esdhc_mmc_init(bd); +} +#endif + +static struct pci_region pcie_regions_0[] = { + { + .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, + .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, + .size = CONFIG_SYS_PCIE1_MEM_SIZE, + .flags = PCI_REGION_MEM, + }, + { + .bus_start = CONFIG_SYS_PCIE1_IO_BASE, + .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, + .size = CONFIG_SYS_PCIE1_IO_SIZE, + .flags = PCI_REGION_IO, + }, +}; + +void pci_init_board(void) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + sysconf83xx_t *sysconf = &immr->sysconf; + law83xx_t *pcie_law = sysconf->pcielaw; + struct pci_region *pcie_reg[] = { pcie_regions_0 }; + + fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + + /* Deassert the resets in the control register */ + out_be32(&sysconf->pecr1, 0xE0008000); + udelay(2000); + + /* Configure PCI Express Local Access Windows */ + out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); + out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); + + mpc83xx_pcie_init(1, pcie_reg); +} + +ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info) +{ + info->portwidth = FLASH_CFI_16BIT; + info->chipwidth = FLASH_CFI_BY16; + info->interface = FLASH_CFI_X16; + return 1; +} + +#if defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); + fdt_fixup_dr_usb(blob, bd); + fdt_fixup_esdhc(blob, bd); + + return 0; +} +#endif + +/* + * FPGA MII bitbang implementation + */ + +struct fpga_mii { + unsigned fpga; + int mdio; +} fpga_mii[] = { + { 0, 1}, + { 1, 1}, + { 2, 1}, + { 3, 1}, +}; + +static int mii_dummy_init(struct bb_miiphy_bus *bus) +{ + return 0; +} + +static int mii_mdio_active(struct bb_miiphy_bus *bus) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (fpga_mii->mdio) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); + + return 0; +} + +static int mii_mdio_tristate(struct bb_miiphy_bus *bus) +{ + struct fpga_mii *fpga_mii = bus->priv; + + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + + return 0; +} + +static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (v) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); + + fpga_mii->mdio = v; + + return 0; +} + +static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) +{ + u16 gpio; + struct fpga_mii *fpga_mii = bus->priv; + + FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio); + + *v = ((gpio & GPIO_MDIO) != 0); + + return 0; +} + +static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) +{ + struct fpga_mii *fpga_mii = bus->priv; + + if (v) + FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC); + else + FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC); + + return 0; +} + +static int mii_delay(struct bb_miiphy_bus *bus) +{ + udelay(1); + + return 0; +} + +struct bb_miiphy_bus bb_miiphy_buses[] = { + { + .name = "board0", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[0], + }, + { + .name = "board1", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[1], + }, + { + .name = "board2", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[2], + }, + { + .name = "board3", + .init = mii_dummy_init, + .mdio_active = mii_mdio_active, + .mdio_tristate = mii_mdio_tristate, + .set_mdio = mii_set_mdio, + .get_mdio = mii_get_mdio, + .set_mdc = mii_set_mdc, + .delay = mii_delay, + .priv = &fpga_mii[3], + }, +}; + +int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / + sizeof(bb_miiphy_buses[0]); diff --git a/board/gdsys/p1022/controlcenterd.c b/board/gdsys/p1022/controlcenterd.c index 64d90dd3fd..2f98e4757f 100644 --- a/board/gdsys/p1022/controlcenterd.c +++ b/board/gdsys/p1022/controlcenterd.c @@ -57,6 +57,8 @@ struct ihs_fpga { u32 versions; /* 0x0004 */ u32 fpga_version; /* 0x0008 */ u32 fpga_features; /* 0x000c */ + u32 reserved[4]; /* 0x0010 */ + u32 control; /* 0x0020 */ }; #ifndef CONFIG_TRAILBLAZER @@ -384,6 +386,9 @@ static void hydra_initialize(void) fpga = pci_map_bar(devno, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + /* disable sideband clocks */ + writel(1, &fpga->control); + versions = readl(&fpga->versions); fpga_version = readl(&fpga->fpga_version); fpga_features = readl(&fpga->fpga_features); diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c b/board/nvidia/jetson-tk1/jetson-tk1.c index 3c21767ce4..52425a8f6d 100644 --- a/board/nvidia/jetson-tk1/jetson-tk1.c +++ b/board/nvidia/jetson-tk1/jetson-tk1.c @@ -11,7 +11,6 @@ #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> -#include <asm/arch-tegra/gpu.h> #include "pinmux-config-jetson-tk1.h" @@ -80,10 +79,3 @@ int board_eth_init(bd_t *bis) return pci_eth_init(bis); } #endif /* PCI */ - -int ft_board_setup(void *blob, bd_t *bd) -{ - gpu_enable_node(blob, "/gpu@0,57000000"); - - return 0; -} diff --git a/board/nvidia/p2371-2180/p2371-2180.c b/board/nvidia/p2371-2180/p2371-2180.c index cf2dd0b14f..57f577d85d 100644 --- a/board/nvidia/p2371-2180/p2371-2180.c +++ b/board/nvidia/p2371-2180/p2371-2180.c @@ -6,6 +6,7 @@ */ #include <common.h> +#include <netdev.h> #include <i2c.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> @@ -49,3 +50,32 @@ void pinmux_init(void) pinmux_config_drvgrp_table(p2371_2180_drvgrps, ARRAY_SIZE(p2371_2180_drvgrps)); } + +#ifdef CONFIG_PCI_TEGRA +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + uchar val; + int ret; + + /* Turn on MAX77620 LDO1 to 1.05V for PEX power */ + debug("%s: Set LDO1 for PEX power to 1.05V\n", __func__); + ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev); + if (ret) { + printf("%s: Cannot find MAX77620 I2C chip\n", __func__); + return -1; + } + /* 0xCA for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xCA; + ret = dm_i2c_write(dev, MAX77620_CNFG1_L1_REG, &val, 1); + if (ret) + printf("i2c_write 0 0x3c 0x25 failed: %d\n", ret); + + return 0; +} + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} +#endif /* PCI */ diff --git a/board/nvidia/p2571/p2571.c b/board/nvidia/p2571/p2571.c index d33e4d12b2..d80a7d0d3e 100644 --- a/board/nvidia/p2571/p2571.c +++ b/board/nvidia/p2571/p2571.c @@ -11,7 +11,6 @@ #include <asm/arch/pinmux.h> #include <asm/gpio.h> #include "max77620_init.h" -#include <asm/arch-tegra/gpu.h> #include "pinmux-config-p2571.h" void pin_mux_mmc(void) @@ -62,9 +61,3 @@ void start_cpu_fan(void) gpio_request(GPIO_PE4, "FAN_VDD"); gpio_direction_output(GPIO_PE4, 1); } - -int ft_board_setup(void *blob, bd_t *bd) -{ - gpu_enable_node(blob, "/gpu@0,57000000"); - return 0; -} diff --git a/board/nvidia/venice2/venice2.c b/board/nvidia/venice2/venice2.c index 3e2b9a7745..c56ef129d6 100644 --- a/board/nvidia/venice2/venice2.c +++ b/board/nvidia/venice2/venice2.c @@ -8,7 +8,6 @@ #include <common.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> -#include <asm/arch-tegra/gpu.h> #include "pinmux-config-venice2.h" /* @@ -28,10 +27,3 @@ void pinmux_init(void) pinmux_config_drvgrp_table(venice2_drvgrps, ARRAY_SIZE(venice2_drvgrps)); } - -int ft_board_setup(void *blob, bd_t *bd) -{ - gpu_enable_node(blob, "/gpu@0,57000000"); - - return 0; -} diff --git a/board/silica/pengwyn/board.c b/board/silica/pengwyn/board.c index 815c9a7d15..1f5a5868cb 100644 --- a/board/silica/pengwyn/board.c +++ b/board/silica/pengwyn/board.c @@ -141,12 +141,6 @@ static struct cpsw_slave_data cpsw_slaves[] = { { .slave_reg_ofs = 0x208, .sliver_reg_ofs = 0xd80, - .phy_addr = 0, - .phy_if = PHY_INTERFACE_MODE_MII, - }, - { - .slave_reg_ofs = 0x308, - .sliver_reg_ofs = 0xdc0, .phy_addr = 1, .phy_if = PHY_INTERFACE_MODE_MII, }, diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c index 28c29a2f9c..79ed02f68f 100644 --- a/board/ti/am335x/mux.c +++ b/board/ti/am335x/mux.c @@ -317,7 +317,6 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header) /* Do board-specific muxes. */ if (board_is_bone(header)) { /* Beaglebone pinmux */ - configure_module_pin_mux(i2c1_pin_mux); configure_module_pin_mux(mii1_pin_mux); configure_module_pin_mux(mmc0_pin_mux); #if defined(CONFIG_NAND) @@ -356,7 +355,6 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header) configure_module_pin_mux(mmc0_pin_mux_sk_evm); } else if (board_is_bone_lt(header)) { /* Beaglebone LT pinmux */ - configure_module_pin_mux(i2c1_pin_mux); configure_module_pin_mux(mii1_pin_mux); configure_module_pin_mux(mmc0_pin_mux); #if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT) diff --git a/common/Kconfig b/common/Kconfig index 0388a6c34d..440cb372a1 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -455,6 +455,20 @@ endmenu menu "Misc commands" +config CMD_AMBAPP + bool "ambapp" + depends on LEON3 + default y + help + Lists AMBA Plug-n-Play information. + +config SYS_AMBAPP_PRINT_ON_STARTUP + bool "Show AMBA PnP info on startup" + depends on CMD_AMBAPP + default n + help + Show AMBA Plug-n-Play information on startup. + config CMD_TIME bool "time" help diff --git a/common/Makefile b/common/Makefile index d986cde7b9..d8dc892f72 100644 --- a/common/Makefile +++ b/common/Makefile @@ -276,10 +276,15 @@ obj-y += memsize.o obj-y += stdio.o # This option is not just y/n - it can have a numeric value +ifdef CONFIG_FASTBOOT_FLASH +obj-y += image-sparse.o ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV -obj-y += aboot.o obj-y += fb_mmc.o endif +ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV +obj-y += fb_nand.o +endif +endif obj-$(CONFIG_CMD_BLOB) += cmd_blob.o diff --git a/common/aboot.c b/common/aboot.c deleted file mode 100644 index fba8e3e683..0000000000 --- a/common/aboot.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2009, Google Inc. - * All rights reserved. - * - * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. - * Portions Copyright 2014 Broadcom Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of The Linux Foundation nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * NOTE: - * Although it is very similar, this license text is not identical - * to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT! - */ - -#include <config.h> -#include <common.h> -#include <aboot.h> -#include <malloc.h> -#include <part.h> -#include <sparse_format.h> - -void write_sparse_image(block_dev_desc_t *dev_desc, - disk_partition_t *info, const char *part_name, - void *data, unsigned sz) -{ - lbaint_t blk; - lbaint_t blkcnt; - lbaint_t blks; - uint32_t bytes_written = 0; - unsigned int chunk; - unsigned int chunk_data_sz; - uint32_t *fill_buf = NULL; - uint32_t fill_val; - sparse_header_t *sparse_header; - chunk_header_t *chunk_header; - uint32_t total_blocks = 0; - int i; - - /* Read and skip over sparse image header */ - sparse_header = (sparse_header_t *) data; - - data += sparse_header->file_hdr_sz; - if (sparse_header->file_hdr_sz > sizeof(sparse_header_t)) - { - /* - * Skip the remaining bytes in a header that is longer than - * we expected. - */ - data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t)); - } - - debug("=== Sparse Image Header ===\n"); - debug("magic: 0x%x\n", sparse_header->magic); - debug("major_version: 0x%x\n", sparse_header->major_version); - debug("minor_version: 0x%x\n", sparse_header->minor_version); - debug("file_hdr_sz: %d\n", sparse_header->file_hdr_sz); - debug("chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz); - debug("blk_sz: %d\n", sparse_header->blk_sz); - debug("total_blks: %d\n", sparse_header->total_blks); - debug("total_chunks: %d\n", sparse_header->total_chunks); - - /* verify sparse_header->blk_sz is an exact multiple of info->blksz */ - if (sparse_header->blk_sz != - (sparse_header->blk_sz & ~(info->blksz - 1))) { - printf("%s: Sparse image block size issue [%u]\n", - __func__, sparse_header->blk_sz); - fastboot_fail("sparse image block size issue"); - return; - } - - puts("Flashing Sparse Image\n"); - - /* Start processing chunks */ - blk = info->start; - for (chunk=0; chunk<sparse_header->total_chunks; chunk++) - { - /* Read and skip over chunk header */ - chunk_header = (chunk_header_t *) data; - data += sizeof(chunk_header_t); - - if (chunk_header->chunk_type != CHUNK_TYPE_RAW) { - debug("=== Chunk Header ===\n"); - debug("chunk_type: 0x%x\n", chunk_header->chunk_type); - debug("chunk_data_sz: 0x%x\n", chunk_header->chunk_sz); - debug("total_size: 0x%x\n", chunk_header->total_sz); - } - - if (sparse_header->chunk_hdr_sz > sizeof(chunk_header_t)) - { - /* - * Skip the remaining bytes in a header that is longer - * than we expected. - */ - data += (sparse_header->chunk_hdr_sz - - sizeof(chunk_header_t)); - } - - chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz; - blkcnt = chunk_data_sz / info->blksz; - switch (chunk_header->chunk_type) - { - case CHUNK_TYPE_RAW: - if (chunk_header->total_sz != - (sparse_header->chunk_hdr_sz + chunk_data_sz)) - { - fastboot_fail( - "Bogus chunk size for chunk type Raw"); - return; - } - - if (blk + blkcnt > info->start + info->size) { - printf( - "%s: Request would exceed partition size!\n", - __func__); - fastboot_fail( - "Request would exceed partition size!"); - return; - } - - blks = dev_desc->block_write(dev_desc->dev, blk, blkcnt, - data); - if (blks != blkcnt) { - printf("%s: Write failed " LBAFU "\n", - __func__, blks); - fastboot_fail("flash write failure"); - return; - } - blk += blkcnt; - bytes_written += blkcnt * info->blksz; - total_blocks += chunk_header->chunk_sz; - data += chunk_data_sz; - break; - - case CHUNK_TYPE_FILL: - if (chunk_header->total_sz != - (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) - { - fastboot_fail( - "Bogus chunk size for chunk type FILL"); - return; - } - - fill_buf = (uint32_t *) - memalign(ARCH_DMA_MINALIGN, - ROUNDUP(info->blksz, - ARCH_DMA_MINALIGN)); - if (!fill_buf) - { - fastboot_fail( - "Malloc failed for: CHUNK_TYPE_FILL"); - return; - } - - fill_val = *(uint32_t *)data; - data = (char *) data + sizeof(uint32_t); - - for (i = 0; i < (info->blksz / sizeof(fill_val)); i++) - fill_buf[i] = fill_val; - - if (blk + blkcnt > info->start + info->size) { - printf( - "%s: Request would exceed partition size!\n", - __func__); - fastboot_fail( - "Request would exceed partition size!"); - return; - } - - for (i = 0; i < blkcnt; i++) { - blks = dev_desc->block_write(dev_desc->dev, - blk, 1, fill_buf); - if (blks != 1) { - printf( - "%s: Write failed, block # " LBAFU "\n", - __func__, blkcnt); - fastboot_fail("flash write failure"); - free(fill_buf); - return; - } - blk++; - } - bytes_written += blkcnt * info->blksz; - total_blocks += chunk_data_sz / sparse_header->blk_sz; - - free(fill_buf); - break; - - case CHUNK_TYPE_DONT_CARE: - blk += blkcnt; - total_blocks += chunk_header->chunk_sz; - break; - - case CHUNK_TYPE_CRC32: - if (chunk_header->total_sz != - sparse_header->chunk_hdr_sz) - { - fastboot_fail( - "Bogus chunk size for chunk type Dont Care"); - return; - } - total_blocks += chunk_header->chunk_sz; - data += chunk_data_sz; - break; - - default: - printf("%s: Unknown chunk type: %x\n", __func__, - chunk_header->chunk_type); - fastboot_fail("Unknown chunk type"); - return; - } - } - - debug("Wrote %d blocks, expected to write %d blocks\n", - total_blocks, sparse_header->total_blks); - printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name); - - if (total_blocks != sparse_header->total_blks) - fastboot_fail("sparse image write failure"); - - fastboot_okay(""); - return; -} diff --git a/common/board_f.c b/common/board_f.c index 725eb18427..04c273e2fe 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -796,7 +796,7 @@ static init_fnc_t init_sequence_f[] = { /* TODO: can we rename this to timer_init()? */ init_timebase, #endif -#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ +#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \ defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) timer_init, /* initialize timer */ #endif @@ -808,10 +808,7 @@ static init_fnc_t init_sequence_f[] = { #if defined(CONFIG_BOARD_POSTCLK_INIT) board_postclk_init, #endif -#ifdef CONFIG_SYS_FSL_CLK - get_clocks, -#endif -#ifdef CONFIG_M68K +#if defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K) get_clocks, #endif env_init, /* initialize environment */ diff --git a/common/board_r.c b/common/board_r.c index c4fd3eaf8c..c6aa7e5224 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -46,6 +46,9 @@ #include <stdio_dev.h> #include <trace.h> #include <watchdog.h> +#ifdef CONFIG_CMD_AMBAPP +#include <ambapp.h> +#endif #ifdef CONFIG_ADDR_MAP #include <asm/mmu.h> #endif @@ -559,6 +562,18 @@ static int initr_status_led(void) } #endif +#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) +extern int do_ambapp_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); + +static int initr_ambapp_print(void) +{ + puts("AMBA:\n"); + do_ambapp_print(NULL, 0, 0, NULL); + + return 0; +} +#endif + #if defined(CONFIG_CMD_SCSI) static int initr_scsi(void) { @@ -837,8 +852,7 @@ init_fnc_t init_sequence_r[] = { #if defined(CONFIG_ARM) || defined(CONFIG_AVR32) initr_enable_interrupts, #endif -#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) \ - || defined(CONFIG_M68K) +#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) || defined(CONFIG_M68K) timer_init, /* initialize timer */ #endif #if defined(CONFIG_STATUS_LED) @@ -851,6 +865,12 @@ init_fnc_t init_sequence_r[] = { #ifdef CONFIG_BOARD_LATE_INIT board_late_init, #endif +#if defined(CONFIG_CMD_AMBAPP) + ambapp_init_reloc, +#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) + initr_ambapp_print, +#endif +#endif #ifdef CONFIG_CMD_SCSI INIT_FUNC_WATCHDOG_RESET initr_scsi, diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c index 2a1995a761..4b6d1741e9 100644 --- a/common/cmd_ambapp.c +++ b/common/cmd_ambapp.c @@ -15,92 +15,375 @@ DECLARE_GLOBAL_DATA_PTR; -/* We put these variables into .data section so that they are zero - * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c) - * the first time. BSS is not garantueed to be zero since BSS - * hasn't been cleared the first times entering the CPU AMBA functions. - * - * The AMBA PnP routines call these functions if ambapp_???_print is set. - * - */ -int ambapp_apb_print __attribute__ ((section(".data"))) = 0; -int ambapp_ahb_print __attribute__ ((section(".data"))) = 0; - typedef struct { int device_id; char *name; + char *desc; } ambapp_device_name; -static ambapp_device_name gaisler_devices[] = { - {GAISLER_LEON3, "GAISLER_LEON3"}, - {GAISLER_LEON3DSU, "GAISLER_LEON3DSU"}, - {GAISLER_ETHAHB, "GAISLER_ETHAHB"}, - {GAISLER_ETHMAC, "GAISLER_ETHMAC"}, - {GAISLER_APBMST, "GAISLER_APBMST"}, - {GAISLER_AHBUART, "GAISLER_AHBUART"}, - {GAISLER_SRCTRL, "GAISLER_SRCTRL"}, - {GAISLER_SDCTRL, "GAISLER_SDCTRL"}, - {GAISLER_APBUART, "GAISLER_APBUART"}, - {GAISLER_IRQMP, "GAISLER_IRQMP"}, - {GAISLER_AHBRAM, "GAISLER_AHBRAM"}, - {GAISLER_GPTIMER, "GAISLER_GPTIMER"}, - {GAISLER_PCITRG, "GAISLER_PCITRG"}, - {GAISLER_PCISBRG, "GAISLER_PCISBRG"}, - {GAISLER_PCIFBRG, "GAISLER_PCIFBRG"}, - {GAISLER_PCITRACE, "GAISLER_PCITRACE"}, - {GAISLER_AHBTRACE, "GAISLER_AHBTRACE"}, - {GAISLER_ETHDSU, "GAISLER_ETHDSU"}, - {GAISLER_PIOPORT, "GAISLER_PIOPORT"}, - {GAISLER_AHBJTAG, "GAISLER_AHBJTAG"}, - {GAISLER_ATACTRL, "GAISLER_ATACTRL"}, - {GAISLER_VGA, "GAISLER_VGA"}, - {GAISLER_KBD, "GAISLER_KBD"}, - {GAISLER_L2TIME, "GAISLER_L2TIME"}, - {GAISLER_L2C, "GAISLER_L2C"}, - {GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"}, - {GAISLER_SPW, "GAISLER_SPW"}, - {GAISLER_SPW2, "GAISLER_SPW2"}, - {GAISLER_EHCI, "GAISLER_EHCI"}, - {GAISLER_UHCI, "GAISLER_UHCI"}, - {GAISLER_AHBSTAT, "GAISLER_AHBSTAT"}, - {GAISLER_DDR2SPA, "GAISLER_DDR2SPA"}, - {GAISLER_DDRSPA, "GAISLER_DDRSPA"}, - {0, NULL} +typedef struct { + unsigned int vendor_id; + char *name; + char *desc; + ambapp_device_name *devices; +} ambapp_vendor_devnames; + +/** Vendor GAISLER devices */ +static ambapp_device_name GAISLER_devices[] = { + {GAISLER_LEON2DSU, "LEON2DSU", "Leon2 Debug Support Unit"}, + {GAISLER_LEON3, "LEON3", "Leon3 SPARC V8 Processor"}, + {GAISLER_LEON3DSU, "LEON3DSU", "Leon3 Debug Support Unit"}, + {GAISLER_ETHAHB, "ETHAHB", "OC ethernet AHB interface"}, + {GAISLER_APBMST, "APBMST", "AHB/APB Bridge"}, + {GAISLER_AHBUART, "AHBUART", "AHB Debug UART"}, + {GAISLER_SRCTRL, "SRCTRL", "Simple SRAM Controller"}, + {GAISLER_SDCTRL, "SDCTRL", "PC133 SDRAM Controller"}, + {GAISLER_SSRCTRL, "SSRCTRL", "Synchronous SRAM Controller"}, + {GAISLER_APBUART, "APBUART", "Generic UART"}, + {GAISLER_IRQMP, "IRQMP", "Multi-processor Interrupt Ctrl."}, + {GAISLER_AHBRAM, "AHBRAM", "Single-port AHB SRAM module"}, + {GAISLER_AHBDPRAM, "AHBDPRAM", "Dual-port AHB SRAM module"}, + {GAISLER_GPTIMER, "GPTIMER", "Modular Timer Unit"}, + {GAISLER_PCITRG, "PCITRG", "Simple 32-bit PCI Target"}, + {GAISLER_PCISBRG, "PCISBRG", "Simple 32-bit PCI Bridge"}, + {GAISLER_PCIFBRG, "PCIFBRG", "Fast 32-bit PCI Bridge"}, + {GAISLER_PCITRACE, "PCITRACE", "32-bit PCI Trace Buffer"}, + {GAISLER_DMACTRL, "DMACTRL", "AMBA DMA controller"}, + {GAISLER_AHBTRACE, "AHBTRACE", "AMBA Trace Buffer"}, + {GAISLER_DSUCTRL, "DSUCTRL", "DSU/ETH controller"}, + {GAISLER_CANAHB, "CANAHB", "OC CAN AHB interface"}, + {GAISLER_GPIO, "GPIO", "General Purpose I/O port"}, + {GAISLER_AHBROM, "AHBROM", "Generic AHB ROM"}, + {GAISLER_AHBJTAG, "AHBJTAG", "JTAG Debug Link"}, + {GAISLER_ETHMAC, "ETHMAC", "GR Ethernet MAC"}, + {GAISLER_SWNODE, "SWNODE", "SpaceWire Node Interface"}, + {GAISLER_SPW, "SPW", "SpaceWire Serial Link"}, + {GAISLER_AHB2AHB, "AHB2AHB", "AHB-to-AHB Bridge"}, + {GAISLER_USBDC, "USBDC", "GR USB 2.0 Device Controller"}, + {GAISLER_USB_DCL, "USB_DCL", "USB Debug Communication Link"}, + {GAISLER_DDRMP, "DDRMP", "Multi-port DDR controller"}, + {GAISLER_ATACTRL, "ATACTRL", "ATA controller"}, + {GAISLER_DDRSP, "DDRSP", "Single-port DDR266 controller"}, + {GAISLER_EHCI, "EHCI", "USB Enhanced Host Controller"}, + {GAISLER_UHCI, "UHCI", "USB Universal Host Controller"}, + {GAISLER_I2CMST, "I2CMST", "AMBA Wrapper for OC I2C-master"}, + {GAISLER_SPW2, "SPW2", "GRSPW2 SpaceWire Serial Link"}, + {GAISLER_AHBDMA, "AHBDMA", ""}, + {GAISLER_NUHOSP3, "NUHOSP3", "Nuhorizons Spartan3 IO I/F"}, + {GAISLER_CLKGATE, "CLKGATE", "Clock gating unit"}, + {GAISLER_SPICTRL, "SPICTRL", "SPI Controller"}, + {GAISLER_DDR2SP, "DDR2SP", "Single-port DDR2 controller"}, + {GAISLER_SLINK, "SLINK", "SLINK Master"}, + {GAISLER_GRTM, "GRTM", "CCSDS Telemetry Encoder"}, + {GAISLER_GRTC, "GRTC", "CCSDS Telecommand Decoder"}, + {GAISLER_GRPW, "GRPW", "PacketWire to AMBA AHB I/F"}, + {GAISLER_GRCTM, "GRCTM", "CCSDS Time Manager"}, + {GAISLER_GRHCAN, "GRHCAN", "ESA HurriCANe CAN with DMA"}, + {GAISLER_GRFIFO, "GRFIFO", "FIFO Controller"}, + {GAISLER_GRADCDAC, "GRADCDAC", "ADC / DAC Interface"}, + {GAISLER_GRPULSE, "GRPULSE", "General Purpose I/O with Pulses"}, + {GAISLER_GRTIMER, "GRTIMER", "Timer Unit with Latches"}, + {GAISLER_AHB2PP, "AHB2PP", "AMBA AHB to Packet Parallel I/F"}, + {GAISLER_GRVERSION, "GRVERSION", "Version and Revision Register"}, + {GAISLER_APB2PW, "APB2PW", "PacketWire Transmit Interface"}, + {GAISLER_PW2APB, "PW2APB", "PacketWire Receive Interface"}, + {GAISLER_GRCAN, "GRCAN", "CAN Controller with DMA"}, + {GAISLER_I2CSLV, "I2CSLV", "I2C Slave"}, + {GAISLER_U16550, "U16550", "Simple 16550 UART"}, + {GAISLER_AHBMST_EM, "AHBMST_EM", "AMBA Master Emulator"}, + {GAISLER_AHBSLV_EM, "AHBSLV_EM", "AMBA Slave Emulator"}, + {GAISLER_GRTESTMOD, "GRTESTMOD", "Test report module"}, + {GAISLER_ASCS, "ASCS", "ASCS Master"}, + {GAISLER_IPMVBCTRL, "IPMVBCTRL", "IPM-bus/MVBC memory controller"}, + {GAISLER_SPIMCTRL, "SPIMCTRL", "SPI Memory Controller"}, + {GAISLER_L4STAT, "L4STAT", "Leon4 Statistics Module"}, + {GAISLER_LEON4, "LEON4", "Leon4 SPARC V8 Processor"}, + {GAISLER_LEON4DSU, "LEON4DSU", "Leon4 Debug Support Unit"}, + {GAISLER_PWM, "PWM", "PWM generator"}, + {GAISLER_L2CACHE, "L2CACHE", "L2-Cache Controller"}, + {GAISLER_SDCTRL64, "SDCTRL64", "64-bit PC133 SDRAM Controller"}, + {GAISLER_GR1553B, "GR1553B", "MIL-STD-1553B Interface"}, + {GAISLER_1553TST, "1553TST", "MIL-STD-1553B Test Device"}, + {GAISLER_GRIOMMU, "GRIOMMU", "I/O Memory Management Unit"}, + {GAISLER_FTAHBRAM, "FTAHBRAM", "Generic FT AHB SRAM module"}, + {GAISLER_FTSRCTRL, "FTSRCTRL", "Simple FT SRAM Controller"}, + {GAISLER_AHBSTAT, "AHBSTAT", "AHB Status Register"}, + {GAISLER_LEON3FT, "LEON3FT", "Leon3-FT SPARC V8 Processor"}, + {GAISLER_FTMCTRL, "FTMCTRL", "Memory controller with EDAC"}, + {GAISLER_FTSDCTRL, "FTSDCTRL", "FT PC133 SDRAM Controller"}, + {GAISLER_FTSRCTRL8, "FTSRCTRL8", "FT 8-bit SRAM/16-bit IO Ctrl"}, + {GAISLER_MEMSCRUB, "MEMSCRUB", "AHB Memory Scrubber"}, + {GAISLER_FTSDCTRL64, "FTSDCTRL64", "64-bit FT SDRAM Controller"}, + {GAISLER_APBPS2, "APBPS2", "PS2 interface"}, + {GAISLER_VGACTRL, "VGACTRL", "VGA controller"}, + {GAISLER_LOGAN, "LOGAN", "On chip Logic Analyzer"}, + {GAISLER_SVGACTRL, "SVGACTRL", "SVGA frame buffer"}, + {GAISLER_T1AHB, "T1AHB", "Niagara T1 PCX/AHB bridge"}, + {GAISLER_MP7WRAP, "MP7WRAP", "CoreMP7 wrapper"}, + {GAISLER_GRSYSMON, "GRSYSMON", "AMBA wrapper for System Monitor"}, + {GAISLER_GRACECTRL, "GRACECTRL", "System ACE I/F Controller"}, + {GAISLER_ATAHBSLV, "ATAHBSLV", "AMBA Test Framework AHB Slave"}, + {GAISLER_ATAHBMST, "ATAHBMST", "AMBA Test Framework AHB Master"}, + {GAISLER_ATAPBSLV, "ATAPBSLV", "AMBA Test Framework APB Slave"}, + {GAISLER_B1553BC, "B1553BC", "AMBA Wrapper for Core1553BBC"}, + {GAISLER_B1553RT, "B1553RT", "AMBA Wrapper for Core1553BRT"}, + {GAISLER_B1553BRM, "B1553BRM", "AMBA Wrapper for Core1553BRM"}, + {GAISLER_AES, "AES", "Advanced Encryption Standard"}, + {GAISLER_ECC, "ECC", "Elliptic Curve Cryptography"}, + {GAISLER_PCIF, "PCIF", "AMBA Wrapper for CorePCIF"}, + {GAISLER_CLKMOD, "CLKMOD", "CPU Clock Switching Ctrl module"}, + {GAISLER_HAPSTRAK, "HAPSTRAK", "HAPS HapsTrak I/O Port"}, + {GAISLER_TEST_1X2, "TEST_1X2", "HAPS TEST_1x2 interface"}, + {GAISLER_WILD2AHB, "WILD2AHB", "WildCard CardBus interface"}, + {GAISLER_BIO1, "BIO1", "Basic I/O board BIO1"}, + {GAISLER_AESDMA, "AESDMA", "AES 256 DMA"}, + {GAISLER_SATCAN, "SATCAN", "SatCAN controller"}, + {GAISLER_CANMUX, "CANMUX", "CAN Bus multiplexer"}, + {GAISLER_GRTMRX, "GRTMRX", "CCSDS Telemetry Receiver"}, + {GAISLER_GRTCTX, "GRTCTX", "CCSDS Telecommand Transmitter"}, + {GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"}, + {GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"}, + {GAISLER_GEFFE, "GEFFE", "Geffe Generator"}, + {GAISLER_GPREG, "GPREG", "General Purpose Register"}, + {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"}, + {GAISLER_SPWCUC, "SPWCUC", "CCSDS CUC / SpaceWire I/F"}, + {GAISLER_SPW2_DMA, "SPW2_DMA", "GRSPW Router DMA interface"}, + {GAISLER_SPWROUTER, "SPWROUTER", "GRSPW Router"}, + {0, NULL, NULL} }; -static ambapp_device_name esa_devices[] = { - {ESA_LEON2, "ESA_LEON2"}, - {ESA_MCTRL, "ESA_MCTRL"}, - {0, NULL} + +/** Vendor PENDER devices */ +static ambapp_device_name PENDER_devices[] = { + {0, NULL, NULL} }; -static ambapp_device_name opencores_devices[] = { - {OPENCORES_PCIBR, "OPENCORES_PCIBR"}, - {OPENCORES_ETHMAC, "OPENCORES_ETHMAC"}, + +/** Vendor ESA devices */ +static ambapp_device_name ESA_devices[] = { + {ESA_LEON2, "LEON2", "Leon2 SPARC V8 Processor"}, + {ESA_LEON2APB, "LEON2APB", "Leon2 Peripheral Bus"}, + {ESA_IRQ, "IRQ", "Leon2 Interrupt Controller"}, + {ESA_TIMER, "TIMER", "Leon2 Timer"}, + {ESA_UART, "UART", "Leon2 UART"}, + {ESA_CFG, "CFG", "Leon2 Configuration Register"}, + {ESA_IO, "IO", "Leon2 Input/Output"}, + {ESA_MCTRL, "MCTRL", "Leon2 Memory Controller"}, + {ESA_PCIARB, "PCIARB", "PCI Arbiter"}, + {ESA_HURRICANE, "HURRICANE", "HurriCANe/HurryAMBA CAN Ctrl"}, + {ESA_SPW_RMAP, "SPW_RMAP", "UoD/Saab SpaceWire/RMAP link"}, + {ESA_AHBUART, "AHBUART", "Leon2 AHB Debug UART"}, + {ESA_SPWA, "SPWA", "ESA/ASTRIUM SpaceWire link"}, + {ESA_BOSCHCAN, "BOSCHCAN", "SSC/BOSCH CAN Ctrl"}, + {ESA_IRQ2, "IRQ2", "Leon2 Secondary Irq Controller"}, + {ESA_AHBSTAT, "AHBSTAT", "Leon2 AHB Status Register"}, + {ESA_WPROT, "WPROT", "Leon2 Write Protection"}, + {ESA_WPROT2, "WPROT2", "Leon2 Extended Write Protection"}, + {ESA_PDEC3AMBA, "PDEC3AMBA", "ESA CCSDS PDEC3AMBA TC Decoder"}, + {ESA_PTME3AMBA, "PTME3AMBA", "ESA CCSDS PTME3AMBA TM Encoder"}, + {0, NULL, NULL} +}; + + +/** Vendor ASTRIUM devices */ +static ambapp_device_name ASTRIUM_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor OPENCHIP devices */ +static ambapp_device_name OPENCHIP_devices[] = { + {OPENCHIP_APBGPIO, "APBGPIO", "APB General Purpose IO"}, + {OPENCHIP_APBI2C, "APBI2C", "APB I2C Interface"}, + {OPENCHIP_APBSPI, "APBSPI", "APB SPI Interface"}, + {OPENCHIP_APBCHARLCD, "APBCHARLCD", "APB Character LCD"}, + {OPENCHIP_APBPWM, "APBPWM", "APB PWM"}, + {OPENCHIP_APBPS2, "APBPS2", "APB PS/2 Interface"}, + {OPENCHIP_APBMMCSD, "APBMMCSD", "APB MMC/SD Card Interface"}, + {OPENCHIP_APBNAND, "APBNAND", "APB NAND(SmartMedia) Interface"}, + {OPENCHIP_APBLPC, "APBLPC", "APB LPC Interface"}, + {OPENCHIP_APBCF, "APBCF", "APB CompactFlash (IDE)"}, + {OPENCHIP_APBSYSACE, "APBSYSACE", "APB SystemACE Interface"}, + {OPENCHIP_APB1WIRE, "APB1WIRE", "APB 1-Wire Interface"}, + {OPENCHIP_APBJTAG, "APBJTAG", "APB JTAG TAP Master"}, + {OPENCHIP_APBSUI, "APBSUI", "APB Simple User Interface"}, + {0, NULL, NULL} +}; + + +/** Vendor OPENCORES devices */ +static ambapp_device_name OPENCORES_devices[] = { + {OPENCORES_PCIBR, "PCIBR", "PCI Bridge"}, + {OPENCORES_ETHMAC, "ETHMAC", "Ethernet MAC"}, {0, NULL} }; -typedef struct { - unsigned int vendor_id; - char *name; - ambapp_device_name *devices; -} ambapp_vendor_devnames; +/** Vendor CONTRIB devices */ +static ambapp_device_name CONTRIB_devices[] = { + {CONTRIB_CORE1, "CORE1", "Contributed core 1"}, + {CONTRIB_CORE2, "CORE2", "Contributed core 2"}, + {0, NULL, NULL} +}; + + +/** Vendor EONIC devices */ +static ambapp_device_name EONIC_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor RADIONOR devices */ +static ambapp_device_name RADIONOR_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor GLEICHMANN devices */ +static ambapp_device_name GLEICHMANN_devices[] = { + {GLEICHMANN_CUSTOM, "CUSTOM", "Custom device"}, + {GLEICHMANN_GEOLCD01, "GEOLCD01", "GEOLCD01 graphics system"}, + {GLEICHMANN_DAC, "DAC", "Sigma delta DAC"}, + {GLEICHMANN_HPI, "HPI", "AHB-to-HPI bridge"}, + {GLEICHMANN_SPI, "SPI", "SPI master"}, + {GLEICHMANN_HIFC, "HIFC", "Human interface controller"}, + {GLEICHMANN_ADCDAC, "ADCDAC", "Sigma delta ADC/DAC"}, + {GLEICHMANN_SPIOC, "SPIOC", ""}, + {GLEICHMANN_AC97, "AC97", ""}, + {0, NULL, NULL} +}; + + +/** Vendor MENTA devices */ +static ambapp_device_name MENTA_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor SUN devices */ +static ambapp_device_name SUN_devices[] = { + {SUN_T1, "T1", "Niagara T1 SPARC V9 Processor"}, + {SUN_S1, "S1", "Niagara S1 SPARC V9 Processor"}, + {0, NULL, NULL} +}; + + +/** Vendor MOVIDIA devices */ +static ambapp_device_name MOVIDIA_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor ORBITA devices */ +static ambapp_device_name ORBITA_devices[] = { + {ORBITA_1553B, "1553B", "MIL-STD-1553B Controller"}, + {ORBITA_429, "429", "429 Interface"}, + {ORBITA_SPI, "SPI", "SPI Interface"}, + {ORBITA_I2C, "I2C", "I2C Interface"}, + {ORBITA_SMARTCARD, "SMARTCARD", "Smart Card Reader"}, + {ORBITA_SDCARD, "SDCARD", "SD Card Reader"}, + {ORBITA_UART16550, "UART16550", "16550 UART"}, + {ORBITA_CRYPTO, "CRYPTO", "Crypto Engine"}, + {ORBITA_SYSIF, "SYSIF", "System Interface"}, + {ORBITA_PIO, "PIO", "Programmable IO module"}, + {ORBITA_RTC, "RTC", "Real-Time Clock"}, + {ORBITA_COLORLCD, "COLORLCD", "Color LCD Controller"}, + {ORBITA_PCI, "PCI", "PCI Module"}, + {ORBITA_DSP, "DSP", "DPS Co-Processor"}, + {ORBITA_USBHOST, "USBHOST", "USB Host"}, + {ORBITA_USBDEV, "USBDEV", "USB Device"}, + {0, NULL, NULL} +}; + + +/** Vendor SYNOPSYS devices */ +static ambapp_device_name SYNOPSYS_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor NASA devices */ +static ambapp_device_name NASA_devices[] = { + {NASA_EP32, "EP32", "EP32 Forth processor"}, + {0, NULL, NULL} +}; + + +/** Vendor CAL devices */ +static ambapp_device_name CAL_devices[] = { + {CAL_DDRCTRL, "DDRCTRL", ""}, + {0, NULL, NULL} +}; + + +/** Vendor EMBEDDIT devices */ +static ambapp_device_name EMBEDDIT_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor CETON devices */ +static ambapp_device_name CETON_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor S3 devices */ +static ambapp_device_name S3_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor ACTEL devices */ +static ambapp_device_name ACTEL_devices[] = { + {ACTEL_COREMP7, "COREMP7", "CoreMP7 Processor"}, + {0, NULL, NULL} +}; + + +/** Vendor APPLECORE devices */ +static ambapp_device_name APPLECORE_devices[] = { + {APPLECORE_UTLEON3, "UTLEON3", "AppleCore uT-LEON3 Processor"}, + {APPLECORE_UTLEON3DSU, "UTLEON3DSU", "AppleCore uT-LEON3 DSU"}, + {0, NULL, NULL} +}; + + +/** Vendors and their devices */ static ambapp_vendor_devnames vendors[] = { - {VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices}, - {VENDOR_ESA, "VENDOR_ESA", esa_devices}, - {VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices}, - {0, NULL, 0} + {VENDOR_GAISLER, "GAISLER", "Gaisler Research", GAISLER_devices}, + {VENDOR_PENDER, "PENDER", "", PENDER_devices}, + {VENDOR_ESA, "ESA", "European Space Agency", ESA_devices}, + {VENDOR_ASTRIUM, "ASTRIUM", "", ASTRIUM_devices}, + {VENDOR_OPENCHIP, "OPENCHIP", "OpenChip", OPENCHIP_devices}, + {VENDOR_OPENCORES, "OPENCORES", "OpenCores", OPENCORES_devices}, + {VENDOR_CONTRIB, "CONTRIB", "Various contributions", CONTRIB_devices}, + {VENDOR_EONIC, "EONIC", "Eonic BV", EONIC_devices}, + {VENDOR_RADIONOR, "RADIONOR", "Radionor Communications", RADIONOR_devices}, + {VENDOR_GLEICHMANN, "GLEICHMANN", "Gleichmann Electronics", GLEICHMANN_devices}, + {VENDOR_MENTA, "MENTA", "Menta", MENTA_devices}, + {VENDOR_SUN, "SUN", "Sun Microsystems", SUN_devices}, + {VENDOR_MOVIDIA, "MOVIDIA", "", MOVIDIA_devices}, + {VENDOR_ORBITA, "ORBITA", "Orbita", ORBITA_devices}, + {VENDOR_SYNOPSYS, "SYNOPSYS", "Synopsys Inc.", SYNOPSYS_devices}, + {VENDOR_NASA, "NASA", "NASA", NASA_devices}, + {VENDOR_S3, "S3", "S3 Group", S3_devices}, + {VENDOR_CAL, "CAL", "", CAL_devices}, + {VENDOR_EMBEDDIT, "EMBEDDIT", "Embedd.it", EMBEDDIT_devices}, + {VENDOR_CETON, "CETON", "Ceton Corporation", CETON_devices}, + {VENDOR_ACTEL, "ACTEL", "Actel Corporation", ACTEL_devices}, + {VENDOR_APPLECORE, "APPLECORE", "AppleCore", APPLECORE_devices}, + {0, NULL, NULL, NULL} }; -static char *ambapp_get_devname(ambapp_device_name * devs, int id) +static ambapp_device_name *ambapp_get_dev(ambapp_device_name *devs, int id) { if (!devs) return NULL; while (devs->device_id > 0) { if (devs->device_id == id) - return devs->name; + return devs; devs++; } return NULL; @@ -109,10 +392,31 @@ static char *ambapp_get_devname(ambapp_device_name * devs, int id) char *ambapp_device_id2str(int vendor, int id) { ambapp_vendor_devnames *ven = &vendors[0]; + ambapp_device_name *dev; + + while (ven->vendor_id > 0) { + if (ven->vendor_id == vendor) { + dev = ambapp_get_dev(ven->devices, id); + if (!dev) + return NULL; + return dev->name; + } + ven++; + } + return NULL; +} + +char *ambapp_device_id2desc(int vendor, int id) +{ + ambapp_vendor_devnames *ven = &vendors[0]; + ambapp_device_name *dev; while (ven->vendor_id > 0) { if (ven->vendor_id == vendor) { - return ambapp_get_devname(ven->devices, id); + dev = ambapp_get_dev(ven->devices, id); + if (!dev) + return NULL; + return dev->desc; } ven++; } @@ -134,101 +438,106 @@ char *ambapp_vendor_id2str(int vendor) static char *unknown = "unknown"; +char *ambapp_type_names[4] = { + /* 0 */ "UNUSED", + /* 1 */ "apb", + /* 2 */ "ahbmem", + /* 3 */ "ahbio" +}; + /* Print one APB device */ -void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index) +void ambapp_print_apb(ambapp_apbdev *dev, int index) { char *dev_str, *ven_str; - int irq, ver, vendor, deviceid; - unsigned int address, apbmst_base, mask; - - vendor = amba_vendor(apb->conf); - deviceid = amba_device(apb->conf); - irq = amba_irq(apb->conf); - ver = amba_ver(apb->conf); - apbmst_base = apbmst->address[0] & LEON3_IO_AREA; - address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) & - (((apb->bar & 0x0000fff0) << 4) | 0xfff00000); + unsigned int freq; - mask = amba_membar_mask(apb->bar) << 8; - mask = ((~mask) & 0x000fffff) + 1; - - ven_str = ambapp_vendor_id2str(vendor); + ven_str = ambapp_vendor_id2str(dev->vendor); if (!ven_str) { ven_str = unknown; dev_str = unknown; } else { - dev_str = ambapp_device_id2str(vendor, deviceid); + dev_str = ambapp_device_id2str(dev->vendor, dev->device); if (!dev_str) dev_str = unknown; } - printf("0x%02x:0x%02x:0x%02x: %s %s\n" + /* Get Frequency of Core */ + freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index); + + printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n" " apb: 0x%08x - 0x%08x\n" " irq: %-2d (ver: %-2d)\n", - index, vendor, deviceid, ven_str, dev_str, address, - address + mask, irq, ver); + index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000, + dev->address, dev->address + (dev->mask-1), + dev->irq, dev->ver); } -void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index) +void ambapp_print_ahb(ambapp_ahbdev *dev, int index) { - char *dev_str, *ven_str; - int irq, ver, vendor, deviceid; - unsigned int addr, mask; - int j; + char *dev_str, *ven_str, *type_str; + int i; + unsigned int freq; - vendor = amba_vendor(ahb->conf); - deviceid = amba_device(ahb->conf); - irq = amba_irq(ahb->conf); - ver = amba_ver(ahb->conf); - - ven_str = ambapp_vendor_id2str(vendor); + ven_str = ambapp_vendor_id2str(dev->vendor); if (!ven_str) { ven_str = unknown; dev_str = unknown; } else { - dev_str = ambapp_device_id2str(vendor, deviceid); + dev_str = ambapp_device_id2str(dev->vendor, dev->device); if (!dev_str) dev_str = unknown; } - printf("0x%02x:0x%02x:0x%02x: %s %s\n", - index, vendor, deviceid, ven_str, dev_str); + /* Get Frequency of Core */ + freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index); + + printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n", + index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000); - for (j = 0; j < 4; j++) { - addr = amba_membar_start(ahb->bars[j]); - if (amba_membar_type(ahb->bars[j]) == 0) + for (i = 0; i < 4; i++) { + if (dev->type[i] == 0) continue; - if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO) - addr = AMBA_TYPE_AHBIO_ADDR(addr); - mask = amba_membar_mask(ahb->bars[j]) << 20; - printf(" mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1)); + type_str = ambapp_type_names[dev->type[i]]; + printf(" %-7s: 0x%08x - 0x%08x\n", type_str, dev->address[i], + dev->address[i] + (dev->mask[i]-1)); } - printf(" irq: %-2d (ver: %d)\n", irq, ver); + printf(" irq: %-2d (ver: %d)\n", dev->irq, dev->ver); } int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { + int index; + ambapp_apbdev apbdev; + ambapp_ahbdev ahbdev; /* Print AHB Masters */ - puts("--------- AHB Masters ---------\n"); - ambapp_apb_print = 0; - ambapp_ahb_print = 1; - ambapp_ahbmst_count(99, 99); /* Get vendor&device 99 = nonexistent... */ + puts("\n--------- AHB Masters ---------\n"); + index = 0; + while (ambapp_ahbmst_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) { + /* Found a AHB Master Device */ + ambapp_print_ahb(&ahbdev, index); + index++; + } /* Print AHB Slaves */ - puts("--------- AHB Slaves ---------\n"); - ambapp_ahbslv_count(99, 99); /* Get vendor&device 99 = nonexistent... */ + puts("\n--------- AHB Slaves ---------\n"); + index = 0; + while (ambapp_ahbslv_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) { + /* Found a AHB Slave Device */ + ambapp_print_ahb(&ahbdev, index); + index++; + } /* Print APB Slaves */ - puts("--------- APB Slaves ---------\n"); - ambapp_apb_print = 1; - ambapp_ahb_print = 0; - ambapp_apb_count(99, 99); /* Get vendor&device 99 = nonexistent... */ - - /* Reset, no futher printing */ - ambapp_apb_print = 0; - ambapp_ahb_print = 0; + puts("\n--------- APB Slaves ---------\n"); + index = 0; + while (ambapp_apb_find(&ambapp_plb, 0, 0, index, &apbdev) == 1) { + /* Found a APB Slave Device */ + ambapp_print_apb(&apbdev, index); + index++; + } + puts("\n"); return 0; } @@ -240,16 +549,18 @@ int ambapp_init_reloc(void) while (vend->vendor_id && vend->name) { vend->name = (char *)((unsigned int)vend->name + gd->reloc_off); - vend->devices = - (ambapp_device_name *) ((unsigned int)vend->devices + - gd->reloc_off);; + vend->desc = (char *)((unsigned int)vend->desc + gd->reloc_off); + vend->devices = (ambapp_device_name *) + ((unsigned int)vend->devices + gd->reloc_off); dev = vend->devices; vend++; if (!dev) continue; while (dev->device_id && dev->name) { dev->name = - (char *)((unsigned int)dev->name + gd->reloc_off);; + (char *)((unsigned int)dev->name + gd->reloc_off); + dev->desc = + (char *)((unsigned int)dev->desc + gd->reloc_off); dev++; } } diff --git a/common/cmd_gpt.c b/common/cmd_gpt.c index c56fe15d3b..e3c0297a1c 100644 --- a/common/cmd_gpt.c +++ b/common/cmd_gpt.c @@ -218,6 +218,23 @@ static int set_gpt_info(block_dev_desc_t *dev_desc, strcpy((char *)parts[i].uuid, p); free(val); } +#ifdef CONFIG_PARTITION_TYPE_GUID + /* guid */ + val = extract_val(tok, "type"); + if (val) { + /* 'type' is optional */ + if (extract_env(val, &p)) + p = val; + if (strlen(p) >= sizeof(parts[i].type_guid)) { + printf("Wrong type guid format for partition %d\n", + i); + errno = -4; + goto err; + } + strcpy((char *)parts[i].type_guid, p); + free(val); + } +#endif /* name */ val = extract_val(tok, "name"); if (!val) { /* name is mandatory */ diff --git a/common/fb_mmc.c b/common/fb_mmc.c index 0c48cf929f..b480e76554 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -6,32 +6,24 @@ #include <config.h> #include <common.h> +#include <errno.h> +#include <fastboot.h> #include <fb_mmc.h> +#include <image-sparse.h> #include <part.h> -#include <aboot.h> #include <sparse_format.h> #include <mmc.h> +#include <div64.h> #ifndef CONFIG_FASTBOOT_GPT_NAME #define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME #endif -/* The 64 defined bytes plus the '\0' */ -#define RESPONSE_LEN (64 + 1) - static char *response_str; -void fastboot_fail(const char *s) -{ - strncpy(response_str, "FAIL\0", 5); - strncat(response_str, s, RESPONSE_LEN - 4 - 1); -} - -void fastboot_okay(const char *s) -{ - strncpy(response_str, "OKAY\0", 5); - strncat(response_str, s, RESPONSE_LEN - 4 - 1); -} +struct fb_mmc_sparse { + block_dev_desc_t *dev_desc; +}; static int get_partition_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc, const char *name, disk_partition_t *info) @@ -55,6 +47,24 @@ static int get_partition_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc, return ret; } + +static int fb_mmc_sparse_write(struct sparse_storage *storage, + void *priv, + unsigned int offset, + unsigned int size, + char *data) +{ + struct fb_mmc_sparse *sparse = priv; + block_dev_desc_t *dev_desc = sparse->dev_desc; + int ret; + + ret = dev_desc->block_write(dev_desc->dev, offset, size, data); + if (!ret) + return -EIO; + + return ret; +} + static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, const char *part_name, void *buffer, unsigned int download_bytes) @@ -64,11 +74,11 @@ static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, /* determine number of blocks to write */ blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1)); - blkcnt = blkcnt / info->blksz; + blkcnt = lldiv(blkcnt, info->blksz); if (blkcnt > info->size) { error("too large for partition: '%s'\n", part_name); - fastboot_fail("too large for partition"); + fastboot_fail(response_str, "too large for partition"); return; } @@ -78,17 +88,18 @@ static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info, buffer); if (blks != blkcnt) { error("failed writing to device %d\n", dev_desc->dev); - fastboot_fail("failed writing to device"); + fastboot_fail(response_str, "failed writing to device"); return; } printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz, part_name); - fastboot_okay(""); + fastboot_okay(response_str, ""); } -void fb_mmc_flash_write(const char *cmd, void *download_buffer, - unsigned int download_bytes, char *response) +void fb_mmc_flash_write(const char *cmd, unsigned int session_id, + void *download_buffer, unsigned int download_bytes, + char *response) { block_dev_desc_t *dev_desc; disk_partition_t info; @@ -99,7 +110,7 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { error("invalid mmc device\n"); - fastboot_fail("invalid mmc device"); + fastboot_fail(response_str, "invalid mmc device"); return; } @@ -109,29 +120,47 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, if (is_valid_gpt_buf(dev_desc, download_buffer)) { printf("%s: invalid GPT - refusing to write to flash\n", __func__); - fastboot_fail("invalid GPT partition"); + fastboot_fail(response_str, "invalid GPT partition"); return; } if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) { printf("%s: writing GPT partitions failed\n", __func__); - fastboot_fail("writing GPT partitions failed"); + fastboot_fail(response_str, + "writing GPT partitions failed"); return; } printf("........ success\n"); - fastboot_okay(""); + fastboot_okay(response_str, ""); return; } else if (get_partition_info_efi_by_name_or_alias(dev_desc, cmd, &info)) { error("cannot find partition: '%s'\n", cmd); - fastboot_fail("cannot find partition"); + fastboot_fail(response_str, "cannot find partition"); return; } - if (is_sparse_image(download_buffer)) - write_sparse_image(dev_desc, &info, cmd, download_buffer, - download_bytes); - else + if (is_sparse_image(download_buffer)) { + struct fb_mmc_sparse sparse_priv; + sparse_storage_t sparse; + + sparse_priv.dev_desc = dev_desc; + + sparse.block_sz = info.blksz; + sparse.start = info.start; + sparse.size = info.size; + sparse.name = cmd; + sparse.write = fb_mmc_sparse_write; + + printf("Flashing sparse image at offset " LBAFU "\n", + info.start); + + store_sparse_image(&sparse, &sparse_priv, session_id, + download_buffer); + } else { write_raw_image(dev_desc, &info, cmd, download_buffer, download_bytes); + } + + fastboot_okay(response_str, ""); } void fb_mmc_erase(const char *cmd, char *response) @@ -144,7 +173,7 @@ void fb_mmc_erase(const char *cmd, char *response) if (mmc == NULL) { error("invalid mmc device"); - fastboot_fail("invalid mmc device"); + fastboot_fail(response_str, "invalid mmc device"); return; } @@ -154,14 +183,14 @@ void fb_mmc_erase(const char *cmd, char *response) dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { error("invalid mmc device"); - fastboot_fail("invalid mmc device"); + fastboot_fail(response_str, "invalid mmc device"); return; } ret = get_partition_info_efi_by_name_or_alias(dev_desc, cmd, &info); if (ret) { error("cannot find partition: '%s'", cmd); - fastboot_fail("cannot find partition"); + fastboot_fail(response_str, "cannot find partition"); return; } @@ -180,11 +209,11 @@ void fb_mmc_erase(const char *cmd, char *response) blks = dev_desc->block_erase(dev_desc->dev, blks_start, blks_size); if (blks != blks_size) { error("failed erasing from device %d", dev_desc->dev); - fastboot_fail("failed erasing from device"); + fastboot_fail(response_str, "failed erasing from device"); return; } printf("........ erased " LBAFU " bytes from '%s'\n", blks_size * info.blksz, cmd); - fastboot_okay(""); + fastboot_okay(response_str, ""); } diff --git a/common/fb_nand.c b/common/fb_nand.c new file mode 100644 index 0000000000..9ca8602a73 --- /dev/null +++ b/common/fb_nand.c @@ -0,0 +1,213 @@ +/* + * Copyright 2014 Broadcom Corporation. + * Copyright 2015 Free Electrons. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <common.h> + +#include <fastboot.h> +#include <image-sparse.h> +#include <sparse_format.h> + +#include <linux/mtd/mtd.h> +#include <jffs2/jffs2.h> +#include <nand.h> + +static char *response_str; + +struct fb_nand_sparse { + nand_info_t *nand; + struct part_info *part; +}; + +__weak int board_fastboot_erase_partition_setup(char *name) +{ + return 0; +} + +__weak int board_fastboot_write_partition_setup(char *name) +{ + return 0; +} + +static int fb_nand_lookup(const char *partname, char *response, + nand_info_t **nand, + struct part_info **part) +{ + struct mtd_device *dev; + int ret; + u8 pnum; + + ret = mtdparts_init(); + if (ret) { + error("Cannot initialize MTD partitions\n"); + fastboot_fail(response_str, "cannot init mtdparts"); + return ret; + } + + ret = find_dev_and_part(partname, &dev, &pnum, part); + if (ret) { + error("cannot find partition: '%s'", partname); + fastboot_fail(response_str, "cannot find partition"); + return ret; + } + + if (dev->id->type != MTD_DEV_TYPE_NAND) { + error("partition '%s' is not stored on a NAND device", + partname); + fastboot_fail(response_str, "not a NAND device"); + return -EINVAL; + } + + *nand = &nand_info[dev->id->num]; + + return 0; +} + +static int _fb_nand_erase(nand_info_t *nand, struct part_info *part) +{ + nand_erase_options_t opts; + int ret; + + memset(&opts, 0, sizeof(opts)); + opts.offset = part->offset; + opts.length = part->size; + opts.quiet = 1; + + printf("Erasing blocks 0x%llx to 0x%llx\n", + part->offset, part->offset + part->size); + + ret = nand_erase_opts(nand, &opts); + if (ret) + return ret; + + printf("........ erased 0x%llx bytes from '%s'\n", + part->size, part->name); + + return 0; +} + +static int _fb_nand_write(nand_info_t *nand, struct part_info *part, + void *buffer, unsigned int offset, + unsigned int length, size_t *written) +{ + int flags = WITH_WR_VERIFY; + +#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS + flags |= WITH_DROP_FFS; +#endif + + return nand_write_skip_bad(nand, offset, &length, written, + part->size - (offset - part->offset), + buffer, flags); +} + +static int fb_nand_sparse_write(struct sparse_storage *storage, + void *priv, + unsigned int offset, + unsigned int size, + char *data) +{ + struct fb_nand_sparse *sparse = priv; + size_t written; + int ret; + + ret = _fb_nand_write(sparse->nand, sparse->part, data, + offset * storage->block_sz, + size * storage->block_sz, &written); + if (ret < 0) { + printf("Failed to write sparse chunk\n"); + return ret; + } + + return written / storage->block_sz; +} + +void fb_nand_flash_write(const char *partname, unsigned int session_id, + void *download_buffer, unsigned int download_bytes, + char *response) +{ + struct part_info *part; + nand_info_t *nand = NULL; + int ret; + + /* initialize the response buffer */ + response_str = response; + + ret = fb_nand_lookup(partname, response, &nand, &part); + if (ret) { + error("invalid NAND device"); + fastboot_fail(response_str, "invalid NAND device"); + return; + } + + ret = board_fastboot_write_partition_setup(part->name); + if (ret) + return; + + if (is_sparse_image(download_buffer)) { + struct fb_nand_sparse sparse_priv; + sparse_storage_t sparse; + + sparse_priv.nand = nand; + sparse_priv.part = part; + + sparse.block_sz = nand->writesize; + sparse.start = part->offset / sparse.block_sz; + sparse.size = part->size / sparse.block_sz; + sparse.name = part->name; + sparse.write = fb_nand_sparse_write; + + ret = store_sparse_image(&sparse, &sparse_priv, session_id, + download_buffer); + } else { + printf("Flashing raw image at offset 0x%llx\n", + part->offset); + + ret = _fb_nand_write(nand, part, download_buffer, part->offset, + download_bytes, NULL); + + printf("........ wrote %u bytes to '%s'\n", + download_bytes, part->name); + } + + if (ret) { + fastboot_fail(response_str, "error writing the image"); + return; + } + + fastboot_okay(response_str, ""); +} + +void fb_nand_erase(const char *partname, char *response) +{ + struct part_info *part; + nand_info_t *nand = NULL; + int ret; + + /* initialize the response buffer */ + response_str = response; + + ret = fb_nand_lookup(partname, response, &nand, &part); + if (ret) { + error("invalid NAND device"); + fastboot_fail(response_str, "invalid NAND device"); + return; + } + + ret = board_fastboot_erase_partition_setup(part->name); + if (ret) + return; + + ret = _fb_nand_erase(nand, part); + if (ret) { + error("failed erasing from device %s", nand->name); + fastboot_fail(response_str, "failed erasing from device"); + return; + } + + fastboot_okay(response_str, ""); +} diff --git a/common/image-sparse.c b/common/image-sparse.c new file mode 100644 index 0000000000..dffe844d54 --- /dev/null +++ b/common/image-sparse.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2009, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. + * Portions Copyright 2014 Broadcom Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of The Linux Foundation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * NOTE: + * Although it is very similar, this license text is not identical + * to the "BSD-3-Clause", therefore, DO NOT MODIFY THIS LICENSE TEXT! + */ + +#include <config.h> +#include <common.h> +#include <div64.h> +#include <errno.h> +#include <image-sparse.h> +#include <malloc.h> +#include <part.h> +#include <sparse_format.h> + +#include <linux/math64.h> + +typedef struct sparse_buffer { + void *data; + u32 length; + u32 repeat; + u16 type; +} sparse_buffer_t; + +static uint32_t last_offset; + +static unsigned int sparse_get_chunk_data_size(sparse_header_t *sparse, + chunk_header_t *chunk) +{ + return chunk->total_sz - sparse->chunk_hdr_sz; +} + +static unsigned int sparse_block_size_to_storage(unsigned int size, + sparse_storage_t *storage, + sparse_header_t *sparse) +{ + return size * sparse->blk_sz / storage->block_sz; +} + +static bool sparse_chunk_has_buffer(chunk_header_t *chunk) +{ + switch (chunk->chunk_type) { + case CHUNK_TYPE_RAW: + case CHUNK_TYPE_FILL: + return true; + + default: + return false; + } +} + +static sparse_header_t *sparse_parse_header(void **data) +{ + /* Read and skip over sparse image header */ + sparse_header_t *sparse_header = (sparse_header_t *) *data; + + *data += sparse_header->file_hdr_sz; + + debug("=== Sparse Image Header ===\n"); + debug("magic: 0x%x\n", sparse_header->magic); + debug("major_version: 0x%x\n", sparse_header->major_version); + debug("minor_version: 0x%x\n", sparse_header->minor_version); + debug("file_hdr_sz: %d\n", sparse_header->file_hdr_sz); + debug("chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz); + debug("blk_sz: %d\n", sparse_header->blk_sz); + debug("total_blks: %d\n", sparse_header->total_blks); + debug("total_chunks: %d\n", sparse_header->total_chunks); + + return sparse_header; +} + +static int sparse_parse_fill_chunk(sparse_header_t *sparse, + chunk_header_t *chunk) +{ + unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk); + + if (chunk_data_sz != sizeof(uint32_t)) + return -EINVAL; + + return 0; +} + +static int sparse_parse_raw_chunk(sparse_header_t *sparse, + chunk_header_t *chunk) +{ + unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk); + + /* Check if the data size is a multiple of the main block size */ + if (chunk_data_sz % sparse->blk_sz) + return -EINVAL; + + /* Check that the chunk size is consistent */ + if ((chunk_data_sz / sparse->blk_sz) != chunk->chunk_sz) + return -EINVAL; + + return 0; +} + +static chunk_header_t *sparse_parse_chunk(sparse_header_t *sparse, + void **image) +{ + chunk_header_t *chunk = (chunk_header_t *) *image; + int ret; + + debug("=== Chunk Header ===\n"); + debug("chunk_type: 0x%x\n", chunk->chunk_type); + debug("chunk_data_sz: 0x%x\n", chunk->chunk_sz); + debug("total_size: 0x%x\n", chunk->total_sz); + + switch (chunk->chunk_type) { + case CHUNK_TYPE_RAW: + ret = sparse_parse_raw_chunk(sparse, chunk); + if (ret) + return NULL; + break; + + case CHUNK_TYPE_FILL: + ret = sparse_parse_fill_chunk(sparse, chunk); + if (ret) + return NULL; + break; + + case CHUNK_TYPE_DONT_CARE: + case CHUNK_TYPE_CRC32: + debug("Ignoring chunk\n"); + break; + + default: + printf("%s: Unknown chunk type: %x\n", __func__, + chunk->chunk_type); + return NULL; + } + + *image += sparse->chunk_hdr_sz; + + return chunk; +} + +static int sparse_get_fill_buffer(sparse_header_t *sparse, + chunk_header_t *chunk, + sparse_buffer_t *buffer, + unsigned int blk_sz, + void *data) +{ + int i; + + buffer->type = CHUNK_TYPE_FILL; + + /* + * We create a buffer of one block, and ask it to be + * repeated as many times as needed. + */ + buffer->length = blk_sz; + buffer->repeat = (chunk->chunk_sz * sparse->blk_sz) / blk_sz; + + buffer->data = memalign(ARCH_DMA_MINALIGN, + ROUNDUP(blk_sz, + ARCH_DMA_MINALIGN)); + if (!buffer->data) + return -ENOMEM; + + for (i = 0; i < (buffer->length / sizeof(uint32_t)); i++) + ((uint32_t *)buffer->data)[i] = *(uint32_t *)(data); + + return 0; +} + +static int sparse_get_raw_buffer(sparse_header_t *sparse, + chunk_header_t *chunk, + sparse_buffer_t *buffer, + unsigned int blk_sz, + void *data) +{ + unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk); + + buffer->type = CHUNK_TYPE_RAW; + buffer->length = chunk_data_sz; + buffer->data = data; + buffer->repeat = 1; + + return 0; +} + +static sparse_buffer_t *sparse_get_data_buffer(sparse_header_t *sparse, + chunk_header_t *chunk, + unsigned int blk_sz, + void **image) +{ + unsigned int chunk_data_sz = sparse_get_chunk_data_size(sparse, chunk); + sparse_buffer_t *buffer; + void *data = *image; + int ret; + + *image += chunk_data_sz; + + if (!sparse_chunk_has_buffer(chunk)) + return NULL; + + buffer = calloc(sizeof(sparse_buffer_t), 1); + if (!buffer) + return NULL; + + switch (chunk->chunk_type) { + case CHUNK_TYPE_RAW: + ret = sparse_get_raw_buffer(sparse, chunk, buffer, blk_sz, + data); + if (ret) + return NULL; + break; + + case CHUNK_TYPE_FILL: + ret = sparse_get_fill_buffer(sparse, chunk, buffer, blk_sz, + data); + if (ret) + return NULL; + break; + + default: + return NULL; + } + + debug("=== Buffer ===\n"); + debug("length: 0x%x\n", buffer->length); + debug("repeat: 0x%x\n", buffer->repeat); + debug("type: 0x%x\n", buffer->type); + debug("data: 0x%p\n", buffer->data); + + return buffer; +} + +static void sparse_put_data_buffer(sparse_buffer_t *buffer) +{ + if (buffer->type == CHUNK_TYPE_FILL) + free(buffer->data); + + free(buffer); +} + +int store_sparse_image(sparse_storage_t *storage, void *storage_priv, + unsigned int session_id, void *data) +{ + unsigned int chunk, offset; + sparse_header_t *sparse_header; + chunk_header_t *chunk_header; + sparse_buffer_t *buffer; + uint32_t start; + uint32_t total_blocks = 0; + uint32_t skipped = 0; + int i; + + debug("=== Storage ===\n"); + debug("name: %s\n", storage->name); + debug("block_size: 0x%x\n", storage->block_sz); + debug("start: 0x%x\n", storage->start); + debug("size: 0x%x\n", storage->size); + debug("write: 0x%p\n", storage->write); + debug("priv: 0x%p\n", storage_priv); + + sparse_header = sparse_parse_header(&data); + if (!sparse_header) { + printf("sparse header issue\n"); + return -EINVAL; + } + + /* + * Verify that the sparse block size is a multiple of our + * storage backend block size + */ + div_u64_rem(sparse_header->blk_sz, storage->block_sz, &offset); + if (offset) { + printf("%s: Sparse image block size issue [%u]\n", + __func__, sparse_header->blk_sz); + return -EINVAL; + } + + /* + * If it's a new flashing session, start at the beginning of + * the partition. If not, then simply resume where we were. + */ + if (session_id > 0) + start = last_offset; + else + start = storage->start; + + printf("Flashing sparse image on partition %s at offset 0x%x (ID: %d)\n", + storage->name, start * storage->block_sz, session_id); + + /* Start processing chunks */ + for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) { + uint32_t blkcnt; + + chunk_header = sparse_parse_chunk(sparse_header, &data); + if (!chunk_header) { + printf("Unknown chunk type"); + return -EINVAL; + } + + /* + * If we have a DONT_CARE type, just skip the blocks + * and go on parsing the rest of the chunks + */ + if (chunk_header->chunk_type == CHUNK_TYPE_DONT_CARE) { + skipped += sparse_block_size_to_storage(chunk_header->chunk_sz, + storage, + sparse_header); + continue; + } + + /* Retrieve the buffer we're going to write */ + buffer = sparse_get_data_buffer(sparse_header, chunk_header, + storage->block_sz, &data); + if (!buffer) + continue; + + blkcnt = (buffer->length / storage->block_sz) * buffer->repeat; + + if ((start + total_blocks + blkcnt) > + (storage->start + storage->size)) { + printf("%s: Request would exceed partition size!\n", + __func__); + return -EINVAL; + } + + for (i = 0; i < buffer->repeat; i++) { + unsigned long buffer_blk_cnt; + int ret; + + buffer_blk_cnt = buffer->length / storage->block_sz; + + ret = storage->write(storage, storage_priv, + start + total_blocks, + buffer_blk_cnt, + buffer->data); + if (ret < 0) { + printf("%s: Write %d failed %d\n", + __func__, i, ret); + return ret; + } + + total_blocks += ret; + } + + sparse_put_data_buffer(buffer); + } + + debug("Wrote %d blocks, skipped %d, expected to write %d blocks\n", + total_blocks, skipped, + sparse_block_size_to_storage(sparse_header->total_blks, + storage, sparse_header)); + printf("........ wrote %d blocks to '%s'\n", total_blocks, + storage->name); + + if ((total_blocks + skipped) != + sparse_block_size_to_storage(sparse_header->total_blks, + storage, sparse_header)) { + printf("sparse image write failure\n"); + return -EIO; + } + + last_offset = start + total_blocks; + + return 0; +} diff --git a/common/init/board_init.c b/common/init/board_init.c index e74b63b8a8..1c6126d8ce 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -50,8 +50,7 @@ ulong board_init_f_mem(ulong top) #endif arch_setup_gd(gd_ptr); -#if defined(CONFIG_SYS_MALLOC_F) && \ - (!defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYS_SPL_MALLOC_START)) +#if defined(CONFIG_SYS_MALLOC_F) top -= CONFIG_SYS_MALLOC_F_LEN; gd->malloc_base = top; #endif diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 34bf4eabec..390803aa9c 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -4,6 +4,7 @@ CONFIG_MACH_SUN5I=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_EMR1=0 CONFIG_MMC0_CD_PIN="PG0" +CONFIG_USB0_VBUS_DET="PG1" CONFIG_USB1_VBUS_PIN="PG11" CONFIG_AXP_GPIO=y # CONFIG_VIDEO_HDMI is not set @@ -11,6 +12,8 @@ CONFIG_VIDEO_VGA_VIA_LCD=y CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_MUSB_GADGET=y CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index efe2317138..bb9c42a800 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -14,3 +14,8 @@ CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12)" # CONFIG_CMD_FPGA is not set CONFIG_ETH_DESIGNWARE=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB0_ID_DET="PH19" +CONFIG_USB0_VBUS_DET="PH22" +CONFIG_USB0_VBUS_PIN="PH17" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_MUSB_GADGET=y diff --git a/configs/bct-brettl2_defconfig b/configs/bct-brettl2_defconfig index 9e6f1ee82c..efcfe4da48 100644 --- a/configs/bct-brettl2_defconfig +++ b/configs/bct-brettl2_defconfig @@ -2,4 +2,3 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BCT_BRETTL2=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y diff --git a/configs/bf526-ezbrd_defconfig b/configs/bf526-ezbrd_defconfig index c8dab57190..624484c96d 100644 --- a/configs/bf526-ezbrd_defconfig +++ b/configs/bf526-ezbrd_defconfig @@ -3,4 +3,3 @@ CONFIG_TARGET_BF526_EZBRD=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPI_FLASH=y -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y diff --git a/configs/bf527-ezkit-v2_defconfig b/configs/bf527-ezkit-v2_defconfig index 74f352edc3..ad290881d8 100644 --- a/configs/bf527-ezkit-v2_defconfig +++ b/configs/bf527-ezkit-v2_defconfig @@ -3,5 +3,4 @@ CONFIG_TARGET_BF527_EZKIT=y CONFIG_SYS_EXTRA_OPTIONS="BF527_EZKIT_REV_2_1" # CONFIG_CMD_SETEXPR is not set CONFIG_SPI_FLASH=y -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y CONFIG_LIB_RAND=y diff --git a/configs/bf527-ezkit_defconfig b/configs/bf527-ezkit_defconfig index 0cc81cc44c..8752267695 100644 --- a/configs/bf527-ezkit_defconfig +++ b/configs/bf527-ezkit_defconfig @@ -3,5 +3,4 @@ CONFIG_TARGET_BF527_EZKIT=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPI_FLASH=y -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y CONFIG_NET_TFTP_VARS=n diff --git a/configs/bf537-stamp_defconfig b/configs/bf537-stamp_defconfig index 294d0d9d5f..a60c1b75c2 100644 --- a/configs/bf537-stamp_defconfig +++ b/configs/bf537-stamp_defconfig @@ -3,4 +3,3 @@ CONFIG_TARGET_BF537_STAMP=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPI_FLASH=y -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y diff --git a/configs/bf538f-ezkit_defconfig b/configs/bf538f-ezkit_defconfig index 668f9cb85d..0edaae523b 100644 --- a/configs/bf538f-ezkit_defconfig +++ b/configs/bf538f-ezkit_defconfig @@ -1,6 +1,5 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BF538F_EZKIT=y # CONFIG_CMD_SETEXPR is not set -CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y # CONFIG_REGEX is not set CONFIG_LIB_RAND=y diff --git a/configs/grsim_defconfig b/configs/grsim_defconfig index f0fa23f810..d2f709f834 100644 --- a/configs/grsim_defconfig +++ b/configs/grsim_defconfig @@ -11,4 +11,10 @@ CONFIG_SYS_TEXT_BASE=0x00000000 # CONFIG_CMD_MEMORY is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_APBUART=y +CONFIG_DEBUG_UART_BASE=0x80000100 +CONFIG_DEBUG_UART_CLOCK=40000000 diff --git a/configs/hrcon_dh_defconfig b/configs/hrcon_dh_defconfig new file mode 100644 index 0000000000..a059dd9f8d --- /dev/null +++ b/configs/hrcon_dh_defconfig @@ -0,0 +1,5 @@ +CONFIG_SYS_EXTRA_OPTIONS="HRCON_DH" + +CONFIG_PPC=y +CONFIG_MPC83xx=y +CONFIG_TARGET_HRCON=y diff --git a/configs/kwb_defconfig b/configs/kwb_defconfig index f82fcf31e8..0bbe0a723d 100644 --- a/configs/kwb_defconfig +++ b/configs/kwb_defconfig @@ -3,6 +3,9 @@ CONFIG_TARGET_KWB=y CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1" CONFIG_SYS_PROMPT="U-Boot (BuR V2.0)# " +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_GO is not set # CONFIG_CMD_IMI is not set # CONFIG_CMD_IMLS is not set # CONFIG_CMD_XIMG is not set diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig index f4cc86250d..366ccc4c57 100644 --- a/configs/qemu-x86_defconfig +++ b/configs/qemu-x86_defconfig @@ -15,9 +15,12 @@ CONFIG_CMD_BOOTSTAGE=y CONFIG_OF_CONTROL=y CONFIG_CPU=y CONFIG_SPI_FLASH=y -CONFIG_NETDEVICES=y +CONFIG_DM_ETH=y CONFIG_E1000=y +CONFIG_DM_PCI=y CONFIG_DM_RTC=y +CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_111=y diff --git a/configs/strider_con_defconfig b/configs/strider_con_defconfig new file mode 100644 index 0000000000..74ef69e855 --- /dev/null +++ b/configs/strider_con_defconfig @@ -0,0 +1,7 @@ +CONFIG_SYS_EXTRA_OPTIONS="STRIDER_CON" +CONFIG_PPC=y +CONFIG_MPC83xx=y +CONFIG_TARGET_STRIDER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_STOP_STR=" " +# CONFIG_CMD_SETEXPR is not set diff --git a/configs/strider_cpu_defconfig b/configs/strider_cpu_defconfig new file mode 100644 index 0000000000..fc0a8233b3 --- /dev/null +++ b/configs/strider_cpu_defconfig @@ -0,0 +1,7 @@ +CONFIG_SYS_EXTRA_OPTIONS="STRIDER_CPU" +CONFIG_PPC=y +CONFIG_MPC83xx=y +CONFIG_TARGET_STRIDER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_STOP_STR=" " +# CONFIG_CMD_SETEXPR is not set diff --git a/disk/part.c b/disk/part.c index e57a252d94..909712e501 100644 --- a/disk/part.c +++ b/disk/part.c @@ -392,6 +392,9 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part, /* The common case is no UUID support */ info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif switch (dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION @@ -532,6 +535,9 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif return 0; } @@ -639,6 +645,9 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif ret = 0; goto cleanup; diff --git a/disk/part_efi.c b/disk/part_efi.c index 15627f29e8..ea9c615ee5 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -223,6 +223,10 @@ void print_part_efi(block_dev_desc_t * dev_desc) uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\ttype:\t%s\n", uuid); +#ifdef CONFIG_PARTITION_TYPE_GUID + if (!uuid_guid_get_str(uuid_bin, uuid)) + printf("\ttype:\t%s\n", uuid); +#endif uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b; uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); printf("\tguid:\t%s\n", uuid); @@ -283,6 +287,10 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, UUID_STR_FORMAT_GUID); #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b, + info->type_guid, UUID_STR_FORMAT_GUID); +#endif debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, info->start, info->size, info->name); @@ -419,6 +427,10 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, char *str_uuid; unsigned char *bin_uuid; #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + char *str_type_guid; + unsigned char *bin_type_guid; +#endif for (i = 0; i < parts; i++) { /* partition starting lba */ @@ -445,9 +457,26 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, else gpt_e[i].ending_lba = cpu_to_le64(offset - 1); +#ifdef CONFIG_PARTITION_TYPE_GUID + str_type_guid = partitions[i].type_guid; + bin_type_guid = gpt_e[i].partition_type_guid.b; + if (strlen(str_type_guid)) { + if (uuid_str_to_bin(str_type_guid, bin_type_guid, + UUID_STR_FORMAT_GUID)) { + printf("Partition no. %d: invalid type guid: %s\n", + i, str_type_guid); + return -1; + } + } else { + /* default partition type GUID */ + memcpy(bin_type_guid, + &PARTITION_BASIC_DATA_GUID, 16); + } +#else /* partition type GUID */ memcpy(gpt_e[i].partition_type_guid.b, &PARTITION_BASIC_DATA_GUID, 16); +#endif #ifdef CONFIG_PARTITION_UUIDS str_uuid = partitions[i].uuid; diff --git a/doc/README.gpt b/doc/README.gpt index 59fdeebfe8..35902ce0c8 100644 --- a/doc/README.gpt +++ b/doc/README.gpt @@ -31,7 +31,8 @@ More often UUID is displayed as 32 hexadecimal digits, in 5 groups, separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 digits and 4 hyphens) -For instance, GUID of Linux data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 +For instance, GUID of Basic data partition: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 +and GUID of Linux filesystem data: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 Historically there are 5 methods to generate this number. The oldest one is combining machine's MAC address and timer (epoch) value. @@ -170,6 +171,43 @@ To restore GUID partition table one needs to: 2. From u-boot prompt type: gpt write mmc 0 $partitions +Partition type GUID: +==================== + +For created partition, the used partition type GUID is +PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7). + +If you define 'CONFIG_PARTITION_TYPE_GUID', a optionnal parameter 'type' +can specify a other partition type guid: + + "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...; + name=kernel,size=60MiB,uuid=..., + type=0FC63DAF-8483-4772-8E79-3D69D8477DE4;" + +Some strings can be also used at the place of known GUID : + "system" = PARTITION_SYSTEM_GUID + (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) + "mbr" = LEGACY_MBR_PARTITION_GUID + (024DEE41-33E7-11D3-9D69-0008C781F39F) + "msft" = PARTITION_MSFT_RESERVED_GUID + (E3C9E316-0B5C-4DB8-817D-F92DF00215AE) + "data" = PARTITION_BASIC_DATA_GUID + (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7) + "linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID + (0FC63DAF-8483-4772-8E79-3D69D8477DE4) + "raid" = PARTITION_LINUX_RAID_GUID + (A19D880F-05FC-4D3B-A006-743F0F84911E) + "swap" = PARTITION_LINUX_SWAP_GUID + (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F) + "lvm" = PARTITION_LINUX_LVM_GUID + (E6D6D379-F507-44C2-A23C-238F2A3DF928) + + "partitions=uuid_disk=...;name=u-boot,size=60MiB,uuid=...; + name=kernel,size=60MiB,uuid=...,type=linux;" + +They are also used to display the type of partition in "part list" command. + + Useful info: ============ diff --git a/doc/git-mailrc b/doc/git-mailrc index 6fe78a1d08..1b26e232d2 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -106,7 +106,7 @@ alias ppc4xx uboot, stroese alias sandbox sjg alias sb sandbox -alias sparc uboot, Daniel Hellstrom <daniel@gaisler.com> +alias sparc uboot, Francois Retief <fgretief@spaceteq.co.za> alias superh uboot, iwamatsu alias sh superh diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 82c68439f8..1ad638ea05 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -485,36 +485,6 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) #endif } - -#ifdef CONFIG_AHCI_SETFEATURES_XFER -static void ahci_set_feature(u8 port) -{ - struct ahci_ioports *pp = &(probe_ent->port[port]); - void __iomem *port_mmio = pp->port_mmio; - u32 cmd_fis_len = 5; /* five dwords */ - u8 fis[20]; - - /* set feature */ - memset(fis, 0, sizeof(fis)); - fis[0] = 0x27; - fis[1] = 1 << 7; - fis[2] = ATA_CMD_SET_FEATURES; - fis[3] = SETFEATURES_XFER; - fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01; - - memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis)); - ahci_fill_cmd_slot(pp, cmd_fis_len); - ahci_dcache_flush_sata_cmd(pp); - writel(1, port_mmio + PORT_CMD_ISSUE); - readl(port_mmio + PORT_CMD_ISSUE); - - if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, - WAIT_MS_DATAIO, 0x1)) { - printf("set feature error on port %d!\n", port); - } -} -#endif - static int wait_spinup(void __iomem *port_mmio) { ulong start; @@ -956,9 +926,6 @@ void scsi_low_level_init(int busdevfunc) printf("Can not start port %d\n", i); continue; } -#ifdef CONFIG_AHCI_SETFEATURES_XFER - ahci_set_feature((u8) i); -#endif } } } @@ -1002,9 +969,6 @@ int ahci_init(void __iomem *base) printf("Can not start port %d\n", i); continue; } -#ifdef CONFIG_AHCI_SETFEATURES_XFER - ahci_set_feature((u8) i); -#endif } } err_out: diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7371cd4a87..c8c863765b 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -88,8 +88,10 @@ static int pca953x_reg_write(uint8_t chip, uint addr, uint mask, uint data) if (i2c_read(chip, addr << 1, 1, (u8*)&valw, 2)) return -1; + valw = le16_to_cpu(valw); valw &= ~mask; valw |= data; + valw = cpu_to_le16(valw); return i2c_write(chip, addr << 1, 1, (u8*)&valw, 2); } @@ -107,7 +109,7 @@ static int pca953x_reg_read(uint8_t chip, uint addr, uint *data) } else { if (i2c_read(chip, addr << 1, 1, (u8*)&valw, 2)) return -1; - *data = (int)valw; + *data = (uint)le16_to_cpu(valw); } return 0; } diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c index 19fbe596f4..b05c15f8cb 100644 --- a/drivers/i2c/ihs_i2c.c +++ b/drivers/i2c/ihs_i2c.c @@ -11,6 +11,32 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SYS_I2C_IHS_DUAL +#define I2C_SET_REG(fld, val) \ + do { \ + if (I2C_ADAP_HWNR & 0x10) \ + FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \ + else \ + FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \ + } while (0) +#else +#define I2C_SET_REG(fld, val) \ + FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val) +#endif + +#ifdef CONFIG_SYS_I2C_IHS_DUAL +#define I2C_GET_REG(fld, val) \ + do { \ + if (I2C_ADAP_HWNR & 0x10) \ + FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \ + else \ + FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \ + } while (0) +#else +#define I2C_GET_REG(fld, val) \ + FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val) +#endif + enum { I2CINT_ERROR_EV = 1 << 13, I2CINT_TRANSMIT_EV = 1 << 14, @@ -29,14 +55,14 @@ static int wait_for_int(bool read) u16 val; unsigned int ctr = 0; - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); while (!(val & (I2CINT_ERROR_EV | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) { udelay(10); if (ctr++ > 5000) { return 1; } - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); } return (val & I2CINT_ERROR_EV) ? 1 : 0; @@ -47,30 +73,30 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read, { u16 val; - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, I2CINT_ERROR_EV + I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV); - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); if (!read && len) { val = buffer[0]; if (len > 1) val |= buffer[1] << 8; - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox_ext, val); + I2C_SET_REG(write_mailbox_ext, val); } - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox, - I2CMB_NATIVE - | (read ? 0 : I2CMB_WRITE) - | (chip << 1) - | ((len > 1) ? I2CMB_2BYTE : 0) - | (is_last ? 0 : I2CMB_HOLD_BUS)); + I2C_SET_REG(write_mailbox, + I2CMB_NATIVE + | (read ? 0 : I2CMB_WRITE) + | (chip << 1) + | ((len > 1) ? I2CMB_2BYTE : 0) + | (is_last ? 0 : I2CMB_HOLD_BUS)); if (wait_for_int(read)) return 1; if (read) { - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.read_mailbox_ext, &val); + I2C_GET_REG(read_mailbox_ext, &val); buffer[0] = val & 0xff; if (len > 1) buffer[1] = val >> 8; @@ -109,7 +135,7 @@ static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, uint addr, if (len <= 0) return 1; - if (ihs_i2c_address(chip, addr, alen, !read)) + if (ihs_i2c_address(chip, addr, alen, len)) return 1; while (len) { @@ -163,7 +189,7 @@ static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, } static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap, - unsigned int speed) + unsigned int speed) { if (speed != adap->speed) return 1; @@ -179,6 +205,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_0, CONFIG_SYS_I2C_IHS_SLAVE_0, 0) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_0_1, + CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH1 U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe, @@ -186,6 +219,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_1, CONFIG_SYS_I2C_IHS_SLAVE_1, 1) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_1_1, + CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH2 U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe, @@ -193,6 +233,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_2, CONFIG_SYS_I2C_IHS_SLAVE_2, 2) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_2_1, + CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH3 U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe, @@ -200,4 +247,11 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_3, CONFIG_SYS_I2C_IHS_SLAVE_3, 3) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_3_1, + CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19) +#endif #endif diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index db9b4026b3..05bf4d476d 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -448,28 +448,84 @@ static int soft_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, /* * Register soft i2c adapters */ -U_BOOT_I2C_ADAP_COMPLETE(soft0, soft_i2c_init, soft_i2c_probe, +U_BOOT_I2C_ADAP_COMPLETE(soft00, soft_i2c_init, soft_i2c_probe, soft_i2c_read, soft_i2c_write, NULL, CONFIG_SYS_I2C_SOFT_SPEED, CONFIG_SYS_I2C_SOFT_SLAVE, 0) #if defined(I2C_SOFT_DECLARATIONS2) -U_BOOT_I2C_ADAP_COMPLETE(soft1, soft_i2c_init, soft_i2c_probe, +U_BOOT_I2C_ADAP_COMPLETE(soft01, soft_i2c_init, soft_i2c_probe, soft_i2c_read, soft_i2c_write, NULL, CONFIG_SYS_I2C_SOFT_SPEED_2, CONFIG_SYS_I2C_SOFT_SLAVE_2, 1) #endif #if defined(I2C_SOFT_DECLARATIONS3) -U_BOOT_I2C_ADAP_COMPLETE(soft2, soft_i2c_init, soft_i2c_probe, +U_BOOT_I2C_ADAP_COMPLETE(soft02, soft_i2c_init, soft_i2c_probe, soft_i2c_read, soft_i2c_write, NULL, CONFIG_SYS_I2C_SOFT_SPEED_3, CONFIG_SYS_I2C_SOFT_SLAVE_3, 2) #endif #if defined(I2C_SOFT_DECLARATIONS4) -U_BOOT_I2C_ADAP_COMPLETE(soft3, soft_i2c_init, soft_i2c_probe, +U_BOOT_I2C_ADAP_COMPLETE(soft03, soft_i2c_init, soft_i2c_probe, soft_i2c_read, soft_i2c_write, NULL, CONFIG_SYS_I2C_SOFT_SPEED_4, CONFIG_SYS_I2C_SOFT_SLAVE_4, 3) #endif +#if defined(I2C_SOFT_DECLARATIONS5) +U_BOOT_I2C_ADAP_COMPLETE(soft04, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_5, + CONFIG_SYS_I2C_SOFT_SLAVE_5, + 4) +#endif +#if defined(I2C_SOFT_DECLARATIONS6) +U_BOOT_I2C_ADAP_COMPLETE(soft05, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_6, + CONFIG_SYS_I2C_SOFT_SLAVE_6, + 5) +#endif +#if defined(I2C_SOFT_DECLARATIONS7) +U_BOOT_I2C_ADAP_COMPLETE(soft06, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_7, + CONFIG_SYS_I2C_SOFT_SLAVE_7, + 6) +#endif +#if defined(I2C_SOFT_DECLARATIONS8) +U_BOOT_I2C_ADAP_COMPLETE(soft07, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_8, + CONFIG_SYS_I2C_SOFT_SLAVE_8, + 7) +#endif +#if defined(I2C_SOFT_DECLARATIONS9) +U_BOOT_I2C_ADAP_COMPLETE(soft08, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_9, + CONFIG_SYS_I2C_SOFT_SLAVE_9, + 8) +#endif +#if defined(I2C_SOFT_DECLARATIONS10) +U_BOOT_I2C_ADAP_COMPLETE(soft09, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_10, + CONFIG_SYS_I2C_SOFT_SLAVE_10, + 9) +#endif +#if defined(I2C_SOFT_DECLARATIONS11) +U_BOOT_I2C_ADAP_COMPLETE(soft10, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_11, + CONFIG_SYS_I2C_SOFT_SLAVE_11, + 10) +#endif +#if defined(I2C_SOFT_DECLARATIONS12) +U_BOOT_I2C_ADAP_COMPLETE(soft11, soft_i2c_init, soft_i2c_probe, + soft_i2c_read, soft_i2c_write, NULL, + CONFIG_SYS_I2C_SOFT_SPEED_12, + CONFIG_SYS_I2C_SOFT_SLAVE_12, + 11) +#endif diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 26d34ae5cc..4375abc940 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -40,7 +40,7 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, desc->flags = desc0; desc->cnt = desc1; desc->addr = desc2; - desc->next_addr = (unsigned int)desc + sizeof(struct dwmci_idmac); + desc->next_addr = (ulong)desc + sizeof(struct dwmci_idmac); } static void dwmci_prepare_data(struct dwmci_host *host, @@ -58,7 +58,7 @@ static void dwmci_prepare_data(struct dwmci_host *host, dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET); data_start = (ulong)cur_idmac; - dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac); + dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac); do { flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ; @@ -70,7 +70,7 @@ static void dwmci_prepare_data(struct dwmci_host *host, cnt = data->blocksize * 8; dwmci_set_idma_desc(cur_idmac, flags, cnt, - (u32)bounce_buffer + (i * PAGE_SIZE)); + (ulong)bounce_buffer + (i * PAGE_SIZE)); if (blk_cnt <= 8) break; diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c index 731458c18c..b0d063c698 100644 --- a/drivers/mmc/hi6220_dw_mmc.c +++ b/drivers/mmc/hi6220_dw_mmc.c @@ -48,7 +48,7 @@ int hi6220_dwmci_add_port(int index, u32 regbase, int bus_width) return -ENOMEM; } - host->ioaddr = (void *)regbase; + host->ioaddr = (void *)(ulong)regbase; host->buswidth = bus_width; host->bus_hz = MMC0_DEFAULT_FREQ; diff --git a/drivers/mtd/mtd_uboot.c b/drivers/mtd/mtd_uboot.c index c517b9c65d..21386951ef 100644 --- a/drivers/mtd/mtd_uboot.c +++ b/drivers/mtd/mtd_uboot.c @@ -37,7 +37,7 @@ static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size, return 0; #else - puts("offset is not a number\n"); + puts("mtdparts support missing.\n"); return -1; #endif } diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index d8324645b2..384224d75a 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -268,9 +268,12 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) return -1; } - if (flash->flash_is_locked(flash, offset, len) > 0) { - printf("offset 0x%x is protected and cannot be erased\n", offset); - return -EINVAL; + if (flash->flash_is_locked) { + if (flash->flash_is_locked(flash, offset, len) > 0) { + printf("offset 0x%x is protected and cannot be erased\n", + offset); + return -EINVAL; + } } cmd[0] = flash->erase_cmd; @@ -315,9 +318,12 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, page_size = flash->page_size; - if (flash->flash_is_locked(flash, offset, len) > 0) { - printf("offset 0x%x is protected and cannot be written\n", offset); - return -EINVAL; + if (flash->flash_is_locked) { + if (flash->flash_is_locked(flash, offset, len) > 0) { + printf("offset 0x%x is protected and cannot be written\n", + offset); + return -EINVAL; + } } cmd[0] = flash->write_cmd; diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 9bc8a8d1aa..0624eb8cac 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -20,7 +20,7 @@ #include <ambapp.h> #include <asm/leon.h> -#include "greth.h" +#include <grlib/greth.h> /* Default to 3s timeout on autonegotiation */ #ifndef GRETH_PHY_TIMEOUT_MS @@ -34,6 +34,13 @@ #define GRETH_PHY_ADR_DEFAULT 0 #endif +/* Let board select which GRETH to use as network interface, set + * this to zero if only one GRETH is available. + */ +#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX +#define CONFIG_SYS_GRLIB_GRETH_INDEX 0 +#endif + /* ByPass Cache when reading regs */ #define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr) /* Write-through cache ==> no bypassing needed on writes */ @@ -593,8 +600,12 @@ int greth_initialize(bd_t * bis) debug("Scanning for GRETH\n"); - /* Find Device & IRQ via AMBA Plug&Play information */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) { + /* Find Device & IRQ via AMBA Plug&Play information, + * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple + * GRETHs in system. + */ + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC, + CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) { return -1; /* GRETH not found */ } diff --git a/drivers/net/phy/natsemi.c b/drivers/net/phy/natsemi.c index ea9fe833ed..d2e4c3c487 100644 --- a/drivers/net/phy/natsemi.c +++ b/drivers/net/phy/natsemi.c @@ -53,7 +53,7 @@ static struct phy_driver DP83630_driver = { /* NatSemi DP83865 */ -static int dp83865_config(struct phy_device *phydev) +static int dp838xx_config(struct phy_device *phydev) { phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); genphy_config_aneg(phydev); @@ -105,15 +105,56 @@ static struct phy_driver DP83865_driver = { .uid = 0x20005c70, .mask = 0xfffffff0, .features = PHY_GBIT_FEATURES, - .config = &dp83865_config, + .config = &dp838xx_config, .startup = &dp83865_startup, .shutdown = &genphy_shutdown, }; +/* NatSemi DP83848 */ +static int dp83848_parse_status(struct phy_device *phydev) +{ + int mii_reg; + + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); + + if(mii_reg & (BMSR_100FULL | BMSR_100HALF)) { + phydev->speed = SPEED_100; + } else { + phydev->speed = SPEED_10; + } + + if (mii_reg & (BMSR_10FULL | BMSR_100FULL)) { + phydev->duplex = DUPLEX_FULL; + } else { + phydev->duplex = DUPLEX_HALF; + } + + return 0; +} + +static int dp83848_startup(struct phy_device *phydev) +{ + genphy_update_link(phydev); + dp83848_parse_status(phydev); + + return 0; +} + +static struct phy_driver DP83848_driver = { + .name = "NatSemi DP83848", + .uid = 0x20005c90, + .mask = 0x2000ff90, + .features = PHY_BASIC_FEATURES, + .config = &dp838xx_config, + .startup = &dp83848_startup, + .shutdown = &genphy_shutdown, +}; + int phy_natsemi_init(void) { phy_register(&DP83630_driver); phy_register(&DP83865_driver); + phy_register(&DP83848_driver); return 0; } diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 9175d2cae8..5637a0d083 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -327,13 +327,13 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) for (i = 0; i < RX_BUF; i++) { priv->rx_bd[i].status = 0xF0000000; priv->rx_bd[i].addr = - ((u32)(priv->rxbuffers) + + ((ulong)(priv->rxbuffers) + (i * PKTSIZE_ALIGN)); } /* WRAP bit to last BD */ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; /* Write RxBDs to IP */ - writel((u32)priv->rx_bd, ®s->rxqbase); + writel((ulong)priv->rx_bd, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); @@ -396,22 +396,22 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; /* setup BD */ - writel((u32)priv->tx_bd, ®s->txqbase); + writel((ulong)priv->tx_bd, ®s->txqbase); /* Setup Tx BD */ memset(priv->tx_bd, 0, sizeof(struct emac_bd)); - priv->tx_bd->addr = (u32)ptr; + priv->tx_bd->addr = (ulong)ptr; priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | ZYNQ_GEM_TXBUF_LAST_MASK | ZYNQ_GEM_TXBUF_WRAP_MASK; - addr = (u32) ptr; + addr = (ulong) ptr; addr &= ~(ARCH_DMA_MINALIGN - 1); size = roundup(len, ARCH_DMA_MINALIGN); flush_dcache_range(addr, addr + size); - addr = (u32)priv->rxbuffers; + addr = (ulong)priv->rxbuffers; addr &= ~(ARCH_DMA_MINALIGN - 1); size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN); flush_dcache_range(addr, addr + size); @@ -451,7 +451,7 @@ static int zynq_gem_recv(struct eth_device *dev) u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; addr &= ~(ARCH_DMA_MINALIGN - 1); - net_process_received_packet((u8 *)addr, frame_len); + net_process_received_packet((u8 *)(ulong)addr, frame_len); if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) priv->rx_first_buf = priv->rxbd_current; @@ -530,7 +530,7 @@ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr, /* Initialize the bd spaces for tx and rx bd's */ priv->tx_bd = (struct emac_bd *)bd_space; - priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE); + priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE); priv->phyaddr = phy_addr; priv->emio = emio; diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c index 07f1726748..a64792f988 100644 --- a/drivers/pci/pci_common.c +++ b/drivers/pci/pci_common.c @@ -231,7 +231,7 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose, * if PCI_REGION_MEM is set we do a two pass search with preference * on matches that don't have PCI_REGION_SYS_MEMORY set */ - if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { + if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) { ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, PCI_REGION_SYS_MEMORY, &phys_addr); if (!ret) @@ -298,7 +298,7 @@ pci_addr_t pci_hose_phys_to_bus(struct pci_controller *hose, * if PCI_REGION_MEM is set we do a two pass search with preference * on matches that don't have PCI_REGION_SYS_MEMORY set */ - if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { + if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) { ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, PCI_REGION_SYS_MEMORY, &bus_addr); if (!ret) diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index ebb959f1f3..690896f9f5 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -166,6 +166,9 @@ DECLARE_GLOBAL_DATA_PTR; #define RP_VEND_XP 0x00000F00 #define RP_VEND_XP_DL_UP (1 << 30) +#define RP_VEND_CTL2 0x00000FA8 +#define RP_VEND_CTL2_PCA_ENABLE (1 << 7) + #define RP_PRIV_MISC 0x00000FE0 #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) @@ -194,6 +197,7 @@ struct tegra_pcie_soc { bool has_pex_bias_ctrl; bool has_cml_clk; bool has_gen2; + bool force_pca_enable; }; struct tegra_pcie { @@ -383,6 +387,7 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, break; case COMPAT_NVIDIA_TEGRA124_PCIE: + case COMPAT_NVIDIA_TEGRA210_PCIE: switch (lanes) { case 0x0000104: debug("4x1, 1x1 configuration\n"); @@ -406,9 +411,34 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, static int tegra_pcie_parse_dt_ranges(const void *fdt, int node, struct tegra_pcie *pcie) { + int parent, na_parent, na_pcie, ns_pcie; const u32 *ptr, *end; int len; + parent = fdt_parent_offset(fdt, node); + if (parent < 0) { + error("Can't find PCI parent node\n"); + return -FDT_ERR_NOTFOUND; + } + + na_parent = fdt_address_cells(fdt, parent); + if (na_parent < 1) { + error("bad #address-cells for PCIE parent\n"); + return -FDT_ERR_NOTFOUND; + } + + na_pcie = fdt_address_cells(fdt, node); + if (na_pcie < 1) { + error("bad #address-cells for PCIE\n"); + return -FDT_ERR_NOTFOUND; + } + + ns_pcie = fdt_size_cells(fdt, node); + if (ns_pcie < 1) { + error("bad #size-cells for PCIE\n"); + return -FDT_ERR_NOTFOUND; + } + ptr = fdt_getprop(fdt, node, "ranges", &len); if (!ptr) { error("missing \"ranges\" property"); @@ -437,11 +467,13 @@ static int tegra_pcie_parse_dt_ranges(const void *fdt, int node, } if (res) { - res->start = fdt32_to_cpu(ptr[3]); - res->end = res->start + fdt32_to_cpu(ptr[5]); + int start_low = na_pcie + (na_parent - 1); + int size_low = na_pcie + na_parent + (ns_pcie - 1); + res->start = fdt32_to_cpu(ptr[start_low]); + res->end = res->start + fdt32_to_cpu(ptr[size_low]); } - ptr += 3 + 1 + 2; + ptr += na_pcie + na_parent + ns_pcie; } debug("PCI regions:\n"); @@ -587,8 +619,6 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) return err; } - tegra_pcie_board_init(); - err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, PERIPH_ID_PCIE); if (err < 0) { @@ -860,6 +890,7 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port) static void tegra_pcie_port_enable(struct tegra_pcie_port *port) { + const struct tegra_pcie_soc *soc = port->pcie->soc; unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); unsigned long value; @@ -875,6 +906,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port) afi_writel(port->pcie, value, ctrl); tegra_pcie_port_reset(port); + + if (soc->force_pca_enable) { + value = rp_readl(port, RP_VEND_CTL2); + value |= RP_VEND_CTL2_PCA_ENABLE; + rp_writel(port, value, RP_VEND_CTL2); + } } static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port) @@ -972,6 +1009,7 @@ static const struct tegra_pcie_soc tegra20_pcie_soc = { .has_pex_bias_ctrl = false, .has_cml_clk = false, .has_gen2 = false, + .force_pca_enable = false, }; static const struct tegra_pcie_soc tegra30_pcie_soc = { @@ -982,6 +1020,7 @@ static const struct tegra_pcie_soc tegra30_pcie_soc = { .has_pex_bias_ctrl = true, .has_cml_clk = true, .has_gen2 = false, + .force_pca_enable = false, }; static const struct tegra_pcie_soc tegra124_pcie_soc = { @@ -992,11 +1031,31 @@ static const struct tegra_pcie_soc tegra124_pcie_soc = { .has_pex_bias_ctrl = true, .has_cml_clk = true, .has_gen2 = true, + .force_pca_enable = false, +}; + +static const struct tegra_pcie_soc tegra210_pcie_soc = { + .num_ports = 2, + .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, + .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, + .has_pex_clkreq_en = true, + .has_pex_bias_ctrl = true, + .has_cml_clk = true, + .has_gen2 = true, + .force_pca_enable = true, }; static int process_nodes(const void *fdt, int nodes[], unsigned int count) { unsigned int i; + uint64_t dram_end; + uint32_t pci_dram_size; + + /* Clip PCI-accessible DRAM to 32-bits */ + dram_end = ((uint64_t)NV_PA_SDRAM_BASE) + gd->ram_size; + if (dram_end > 0x100000000) + dram_end = 0x100000000; + pci_dram_size = dram_end - NV_PA_SDRAM_BASE; for (i = 0; i < count; i++) { const struct tegra_pcie_soc *soc; @@ -1021,6 +1080,10 @@ static int process_nodes(const void *fdt, int nodes[], unsigned int count) soc = &tegra124_pcie_soc; break; + case COMPAT_NVIDIA_TEGRA210_PCIE: + soc = &tegra210_pcie_soc; + break; + default: error("unsupported compatible: %s", fdtdec_get_compatible(id)); @@ -1069,7 +1132,7 @@ static int process_nodes(const void *fdt, int nodes[], unsigned int count) pcie->hose.last_busno = 0; pci_set_region(&pcie->hose.regions[0], NV_PA_SDRAM_BASE, - NV_PA_SDRAM_BASE, gd->ram_size, + NV_PA_SDRAM_BASE, pci_dram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); pci_set_region(&pcie->hose.regions[1], pcie->io.start, @@ -1115,6 +1178,14 @@ void pci_init_board(void) const void *fdt = gd->fdt_blob; int count, nodes[1]; + tegra_pcie_board_init(); + + count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", + COMPAT_NVIDIA_TEGRA210_PCIE, + nodes, ARRAY_SIZE(nodes)); + if (process_nodes(fdt, nodes, count)) + return; + count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", COMPAT_NVIDIA_TEGRA124_PCIE, nodes, ARRAY_SIZE(nodes)); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d462244a04..eba96f4a80 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -98,6 +98,14 @@ config DEBUG_UART_ZYNQ will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running. +config DEBUG_UART_APBUART + depends on LEON3 + bool "Gaisler APBUART" + help + Select this to enable a debug UART using the serial_leon3 driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + endchoice config DEBUG_UART_BASE diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7d7a9d0809..a0dbd8b640 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -123,6 +123,13 @@ config TEGRA20_SLINK be used to access the SPI NOR flash on platforms embedding this nVidia Tegra20/Tegra30 IP cores. +config TEGRA210_QSPI + bool "nVidia Tegra210 QSPI driver" + help + Enable the Tegra Quad-SPI (QSPI) driver for T210. This driver + be used to access SPI chips on platforms embedding this + NVIDIA Tegra210 IP core. + config XILINX_SPI bool "Xilinx SPI driver" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 637fea8544..3eca7456d6 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_SH_QSPI) += sh_qspi.o obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o +obj-$(CONFIG_TEGRA210_QSPI) += tegra210_qspi.o obj-$(CONFIG_TI_QSPI) += ti_qspi.o obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c new file mode 100644 index 0000000000..6bbbe93839 --- /dev/null +++ b/drivers/spi/tegra210_qspi.c @@ -0,0 +1,417 @@ +/* + * NVIDIA Tegra210 QSPI controller driver + * + * (C) Copyright 2015 NVIDIA Corporation <www.nvidia.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch-tegra/clk_rst.h> +#include <spi.h> +#include <fdtdec.h> +#include "tegra_spi.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* COMMAND1 */ +#define QSPI_CMD1_GO BIT(31) +#define QSPI_CMD1_M_S BIT(30) +#define QSPI_CMD1_MODE_MASK GENMASK(1,0) +#define QSPI_CMD1_MODE_SHIFT 28 +#define QSPI_CMD1_CS_SEL_MASK GENMASK(1,0) +#define QSPI_CMD1_CS_SEL_SHIFT 26 +#define QSPI_CMD1_CS_POL_INACTIVE0 BIT(22) +#define QSPI_CMD1_CS_SW_HW BIT(21) +#define QSPI_CMD1_CS_SW_VAL BIT(20) +#define QSPI_CMD1_IDLE_SDA_MASK GENMASK(1,0) +#define QSPI_CMD1_IDLE_SDA_SHIFT 18 +#define QSPI_CMD1_BIDIR BIT(17) +#define QSPI_CMD1_LSBI_FE BIT(16) +#define QSPI_CMD1_LSBY_FE BIT(15) +#define QSPI_CMD1_BOTH_EN_BIT BIT(14) +#define QSPI_CMD1_BOTH_EN_BYTE BIT(13) +#define QSPI_CMD1_RX_EN BIT(12) +#define QSPI_CMD1_TX_EN BIT(11) +#define QSPI_CMD1_PACKED BIT(5) +#define QSPI_CMD1_BITLEN_MASK GENMASK(4,0) +#define QSPI_CMD1_BITLEN_SHIFT 0 + +/* COMMAND2 */ +#define QSPI_CMD2_TX_CLK_TAP_DELAY BIT(6) +#define QSPI_CMD2_TX_CLK_TAP_DELAY_MASK GENMASK(11,6) +#define QSPI_CMD2_RX_CLK_TAP_DELAY BIT(0) +#define QSPI_CMD2_RX_CLK_TAP_DELAY_MASK GENMASK(5,0) + +/* TRANSFER STATUS */ +#define QSPI_XFER_STS_RDY BIT(30) + +/* FIFO STATUS */ +#define QSPI_FIFO_STS_CS_INACTIVE BIT(31) +#define QSPI_FIFO_STS_FRAME_END BIT(30) +#define QSPI_FIFO_STS_RX_FIFO_FLUSH BIT(15) +#define QSPI_FIFO_STS_TX_FIFO_FLUSH BIT(14) +#define QSPI_FIFO_STS_ERR BIT(8) +#define QSPI_FIFO_STS_TX_FIFO_OVF BIT(7) +#define QSPI_FIFO_STS_TX_FIFO_UNR BIT(6) +#define QSPI_FIFO_STS_RX_FIFO_OVF BIT(5) +#define QSPI_FIFO_STS_RX_FIFO_UNR BIT(4) +#define QSPI_FIFO_STS_TX_FIFO_FULL BIT(3) +#define QSPI_FIFO_STS_TX_FIFO_EMPTY BIT(2) +#define QSPI_FIFO_STS_RX_FIFO_FULL BIT(1) +#define QSPI_FIFO_STS_RX_FIFO_EMPTY BIT(0) + +#define QSPI_TIMEOUT 1000 + +struct qspi_regs { + u32 command1; /* 000:QSPI_COMMAND1 register */ + u32 command2; /* 004:QSPI_COMMAND2 register */ + u32 timing1; /* 008:QSPI_CS_TIM1 register */ + u32 timing2; /* 00c:QSPI_CS_TIM2 register */ + u32 xfer_status;/* 010:QSPI_TRANS_STATUS register */ + u32 fifo_status;/* 014:QSPI_FIFO_STATUS register */ + u32 tx_data; /* 018:QSPI_TX_DATA register */ + u32 rx_data; /* 01c:QSPI_RX_DATA register */ + u32 dma_ctl; /* 020:QSPI_DMA_CTL register */ + u32 dma_blk; /* 024:QSPI_DMA_BLK register */ + u32 rsvd[56]; /* 028-107 reserved */ + u32 tx_fifo; /* 108:QSPI_FIFO1 register */ + u32 rsvd2[31]; /* 10c-187 reserved */ + u32 rx_fifo; /* 188:QSPI_FIFO2 register */ + u32 spare_ctl; /* 18c:QSPI_SPARE_CTRL register */ +}; + +struct tegra210_qspi_priv { + struct qspi_regs *regs; + unsigned int freq; + unsigned int mode; + int periph_id; + int valid; + int last_transaction_us; +}; + +static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct tegra_spi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + + plat->base = dev_get_addr(bus); + plat->periph_id = clock_decode_periph_id(blob, node); + + if (plat->periph_id == PERIPH_ID_NONE) { + debug("%s: could not decode periph id %d\n", __func__, + plat->periph_id); + return -FDT_ERR_NOTFOUND; + } + + /* Use 500KHz as a suitable default */ + plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + 500000); + plat->deactivate_delay_us = fdtdec_get_int(blob, node, + "spi-deactivate-delay", 0); + debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n", + __func__, plat->base, plat->periph_id, plat->frequency, + plat->deactivate_delay_us); + + return 0; +} + +static int tegra210_qspi_probe(struct udevice *bus) +{ + struct tegra_spi_platdata *plat = dev_get_platdata(bus); + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + + priv->regs = (struct qspi_regs *)plat->base; + + priv->last_transaction_us = timer_get_us(); + priv->freq = plat->frequency; + priv->periph_id = plat->periph_id; + + return 0; +} + +static int tegra210_qspi_claim_bus(struct udevice *bus) +{ + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + struct qspi_regs *regs = priv->regs; + + /* Change SPI clock to correct frequency, PLLP_OUT0 source */ + clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); + + debug("%s: FIFO STATUS = %08x\n", __func__, readl(®s->fifo_status)); + + /* Set master mode and sw controlled CS */ + setbits_le32(®s->command1, QSPI_CMD1_M_S | QSPI_CMD1_CS_SW_HW | + (priv->mode << QSPI_CMD1_MODE_SHIFT)); + debug("%s: COMMAND1 = %08x\n", __func__, readl(®s->command1)); + + return 0; +} + +/** + * Activate the CS by driving it LOW + * + * @param slave Pointer to spi_slave to which controller has to + * communicate with + */ +static void spi_cs_activate(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct tegra_spi_platdata *pdata = dev_get_platdata(bus); + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + + /* If it's too soon to do another transaction, wait */ + if (pdata->deactivate_delay_us && + priv->last_transaction_us) { + ulong delay_us; /* The delay completed so far */ + delay_us = timer_get_us() - priv->last_transaction_us; + if (delay_us < pdata->deactivate_delay_us) + udelay(pdata->deactivate_delay_us - delay_us); + } + + clrbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL); +} + +/** + * Deactivate the CS by driving it HIGH + * + * @param slave Pointer to spi_slave to which controller has to + * communicate with + */ +static void spi_cs_deactivate(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct tegra_spi_platdata *pdata = dev_get_platdata(bus); + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + + setbits_le32(&priv->regs->command1, QSPI_CMD1_CS_SW_VAL); + + /* Remember time of this transaction so we can honour the bus delay */ + if (pdata->deactivate_delay_us) + priv->last_transaction_us = timer_get_us(); + + debug("Deactivate CS, bus '%s'\n", bus->name); +} + +static int tegra210_qspi_xfer(struct udevice *dev, unsigned int bitlen, + const void *data_out, void *data_in, + unsigned long flags) +{ + struct udevice *bus = dev->parent; + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + struct qspi_regs *regs = priv->regs; + u32 reg, tmpdout, tmpdin = 0; + const u8 *dout = data_out; + u8 *din = data_in; + int num_bytes, tm, ret; + + debug("%s: slave %u:%u dout %p din %p bitlen %u\n", + __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen); + if (bitlen % 8) + return -1; + num_bytes = bitlen / 8; + + ret = 0; + + /* clear all error status bits */ + reg = readl(®s->fifo_status); + writel(reg, ®s->fifo_status); + + /* flush RX/TX FIFOs */ + setbits_le32(®s->fifo_status, + (QSPI_FIFO_STS_RX_FIFO_FLUSH | + QSPI_FIFO_STS_TX_FIFO_FLUSH)); + + tm = QSPI_TIMEOUT; + while ((tm && readl(®s->fifo_status) & + (QSPI_FIFO_STS_RX_FIFO_FLUSH | + QSPI_FIFO_STS_TX_FIFO_FLUSH))) { + tm--; + udelay(1); + } + + if (!tm) { + printf("%s: timeout during QSPI FIFO flush!\n", + __func__); + return -1; + } + + /* + * Notes: + * 1. don't set LSBY_FE, so no need to swap bytes from/to TX/RX FIFOs; + * 2. don't set RX_EN and TX_EN yet. + * (SW needs to make sure that while programming the blk_size, + * tx_en and rx_en bits must be zero) + * [TODO] I (Yen Lin) have problems when both RX/TX EN bits are set + * i.e., both dout and din are not NULL. + */ + clrsetbits_le32(®s->command1, + (QSPI_CMD1_LSBI_FE | QSPI_CMD1_LSBY_FE | + QSPI_CMD1_RX_EN | QSPI_CMD1_TX_EN), + (spi_chip_select(dev) << QSPI_CMD1_CS_SEL_SHIFT)); + + /* set xfer size to 1 block (32 bits) */ + writel(0, ®s->dma_blk); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(dev); + + /* handle data in 32-bit chunks */ + while (num_bytes > 0) { + int bytes; + + tmpdout = 0; + bytes = (num_bytes > 4) ? 4 : num_bytes; + + if (dout != NULL) { + memcpy((void *)&tmpdout, (void *)dout, bytes); + dout += bytes; + num_bytes -= bytes; + writel(tmpdout, ®s->tx_fifo); + setbits_le32(®s->command1, QSPI_CMD1_TX_EN); + } + + if (din != NULL) + setbits_le32(®s->command1, QSPI_CMD1_RX_EN); + + /* clear ready bit */ + setbits_le32(®s->xfer_status, QSPI_XFER_STS_RDY); + + clrsetbits_le32(®s->command1, + QSPI_CMD1_BITLEN_MASK << QSPI_CMD1_BITLEN_SHIFT, + (bytes * 8 - 1) << QSPI_CMD1_BITLEN_SHIFT); + + /* Need to stabilize other reg bits before GO bit set. + * As per the TRM: + * "For successful operation at various freq combinations, + * a minimum of 4-5 spi_clk cycle delay might be required + * before enabling the PIO or DMA bits. The worst case delay + * calculation can be done considering slowest qspi_clk as + * 1MHz. Based on that 1us delay should be enough before + * enabling PIO or DMA." Padded another 1us for safety. + */ + udelay(2); + setbits_le32(®s->command1, QSPI_CMD1_GO); + udelay(1); + + /* + * Wait for SPI transmit FIFO to empty, or to time out. + * The RX FIFO status will be read and cleared last + */ + for (tm = 0; tm < QSPI_TIMEOUT; ++tm) { + u32 fifo_status, xfer_status; + + xfer_status = readl(®s->xfer_status); + if (!(xfer_status & QSPI_XFER_STS_RDY)) + continue; + + fifo_status = readl(®s->fifo_status); + if (fifo_status & QSPI_FIFO_STS_ERR) { + debug("%s: got a fifo error: ", __func__); + if (fifo_status & QSPI_FIFO_STS_TX_FIFO_OVF) + debug("tx FIFO overflow "); + if (fifo_status & QSPI_FIFO_STS_TX_FIFO_UNR) + debug("tx FIFO underrun "); + if (fifo_status & QSPI_FIFO_STS_RX_FIFO_OVF) + debug("rx FIFO overflow "); + if (fifo_status & QSPI_FIFO_STS_RX_FIFO_UNR) + debug("rx FIFO underrun "); + if (fifo_status & QSPI_FIFO_STS_TX_FIFO_FULL) + debug("tx FIFO full "); + if (fifo_status & QSPI_FIFO_STS_TX_FIFO_EMPTY) + debug("tx FIFO empty "); + if (fifo_status & QSPI_FIFO_STS_RX_FIFO_FULL) + debug("rx FIFO full "); + if (fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY) + debug("rx FIFO empty "); + debug("\n"); + break; + } + + if (!(fifo_status & QSPI_FIFO_STS_RX_FIFO_EMPTY)) { + tmpdin = readl(®s->rx_fifo); + if (din != NULL) { + memcpy(din, &tmpdin, bytes); + din += bytes; + num_bytes -= bytes; + } + } + break; + } + + if (tm >= QSPI_TIMEOUT) + ret = tm; + + /* clear ACK RDY, etc. bits */ + writel(readl(®s->fifo_status), ®s->fifo_status); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(dev); + + debug("%s: transfer ended. Value=%08x, fifo_status = %08x\n", + __func__, tmpdin, readl(®s->fifo_status)); + + if (ret) { + printf("%s: timeout during SPI transfer, tm %d\n", + __func__, ret); + return -1; + } + + return ret; +} + +static int tegra210_qspi_set_speed(struct udevice *bus, uint speed) +{ + struct tegra_spi_platdata *plat = bus->platdata; + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + + if (speed > plat->frequency) + speed = plat->frequency; + priv->freq = speed; + debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq); + + return 0; +} + +static int tegra210_qspi_set_mode(struct udevice *bus, uint mode) +{ + struct tegra210_qspi_priv *priv = dev_get_priv(bus); + + priv->mode = mode; + debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode); + + return 0; +} + +static const struct dm_spi_ops tegra210_qspi_ops = { + .claim_bus = tegra210_qspi_claim_bus, + .xfer = tegra210_qspi_xfer, + .set_speed = tegra210_qspi_set_speed, + .set_mode = tegra210_qspi_set_mode, + /* + * cs_info is not needed, since we require all chip selects to be + * in the device tree explicitly + */ +}; + +static const struct udevice_id tegra210_qspi_ids[] = { + { .compatible = "nvidia,tegra210-qspi" }, + { } +}; + +U_BOOT_DRIVER(tegra210_qspi) = { + .name = "tegra210-qspi", + .id = UCLASS_SPI, + .of_match = tegra210_qspi_ids, + .ops = &tegra210_qspi_ops, + .ofdata_to_platdata = tegra210_qspi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata), + .priv_auto_alloc_size = sizeof(struct tegra210_qspi_priv), + .per_child_auto_alloc_size = sizeof(struct spi_slave), + .probe = tegra210_qspi_probe, +}; diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index 202e48285f..3099bf4fd4 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -680,7 +680,8 @@ static int smsc95xx_send_common(struct ueth_data *dev, void *packet, int length) ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg, PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)); - debug("** %s(), len %d, buf %#x\n", __func__, length, (int)msg); + debug("** %s(), len %d, buf %#x\n", __func__, length, + (unsigned int)(ulong)msg); if (length > PKTSIZE) return -ENOSPC; @@ -701,8 +702,8 @@ static int smsc95xx_send_common(struct ueth_data *dev, void *packet, int length) &actual_len, USB_BULK_SEND_TIMEOUT); debug("Tx: len = %u, actual = %u, err = %d\n", - length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b), - actual_len, err); + (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)), + (unsigned int)actual_len, err); return err; } @@ -784,7 +785,7 @@ static int smsc95xx_recv(struct eth_device *eth) /* Adjust for next iteration */ actual_len -= sizeof(packet_len) + packet_len; buf_ptr += sizeof(packet_len) + packet_len; - cur_buf_align = (int)buf_ptr - (int)recv_buf; + cur_buf_align = (ulong)buf_ptr - (ulong)recv_buf; if (cur_buf_align & 0x03) { int align = 4 - (cur_buf_align & 0x03); diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index ece48e668c..20b6c18b9c 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -13,6 +13,7 @@ #include <config.h> #include <common.h> #include <errno.h> +#include <fastboot.h> #include <malloc.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -23,6 +24,9 @@ #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV #include <fb_mmc.h> #endif +#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV +#include <fb_nand.h> +#endif #define FASTBOOT_VERSION "0.4" @@ -34,9 +38,6 @@ #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE (0x0040) -/* The 64 defined bytes plus \0 */ -#define RESPONSE_LEN (64 + 1) - #define EP_BUFFER_SIZE 4096 struct f_fastboot { @@ -53,6 +54,7 @@ static inline struct f_fastboot *func_to_fastboot(struct usb_function *f) } static struct f_fastboot *fastboot_func; +static unsigned int fastboot_flash_session_id; static unsigned int download_size; static unsigned int download_bytes; static bool is_high_speed; @@ -125,6 +127,19 @@ static struct usb_gadget_strings *fastboot_strings[] = { static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); static int strcmp_l1(const char *s1, const char *s2); + +void fastboot_fail(char *response, const char *reason) +{ + strncpy(response, "FAIL\0", 5); + strncat(response, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); +} + +void fastboot_okay(char *response, const char *reason) +{ + strncpy(response, "OKAY\0", 5); + strncat(response, reason, FASTBOOT_RESPONSE_LEN - 4 - 1); +} + static void fastboot_complete(struct usb_ep *ep, struct usb_request *req) { int status = req->status; @@ -358,7 +373,7 @@ static int strcmp_l1(const char *s1, const char *s2) static void cb_getvar(struct usb_ep *ep, struct usb_request *req) { char *cmd = req->buf; - char response[RESPONSE_LEN]; + char response[FASTBOOT_RESPONSE_LEN]; const char *s; size_t chars_left; @@ -382,6 +397,15 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req) sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE); strncat(response, str_num, chars_left); + + /* + * This also indicates the start of a new flashing + * "session", in which we could have 1-N buffers to + * write to a partition. + * + * Reset our session counter. + */ + fastboot_flash_session_id = 0; } else if (!strcmp_l1("serialno", cmd)) { s = getenv("serial#"); if (s) @@ -415,7 +439,7 @@ static unsigned int rx_bytes_expected(unsigned int maxpacket) #define BYTES_PER_DOT 0x20000 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) { - char response[RESPONSE_LEN]; + char response[FASTBOOT_RESPONSE_LEN]; unsigned int transfer_size = download_size - download_bytes; const unsigned char *buffer = req->buf; unsigned int buffer_size = req->actual; @@ -472,7 +496,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) static void cb_download(struct usb_ep *ep, struct usb_request *req) { char *cmd = req->buf; - char response[RESPONSE_LEN]; + char response[FASTBOOT_RESPONSE_LEN]; unsigned int max; strsep(&cmd, ":"); @@ -533,7 +557,7 @@ static void cb_continue(struct usb_ep *ep, struct usb_request *req) static void cb_flash(struct usb_ep *ep, struct usb_request *req) { char *cmd = req->buf; - char response[RESPONSE_LEN]; + char response[FASTBOOT_RESPONSE_LEN]; strsep(&cmd, ":"); if (!cmd) { @@ -544,9 +568,16 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req) strcpy(response, "FAILno flash device defined"); #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV - fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR, + fb_mmc_flash_write(cmd, fastboot_flash_session_id, + (void *)CONFIG_FASTBOOT_BUF_ADDR, download_bytes, response); #endif +#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV + fb_nand_flash_write(cmd, fastboot_flash_session_id, + (void *)CONFIG_FASTBOOT_BUF_ADDR, + download_bytes, response); +#endif + fastboot_flash_session_id++; fastboot_tx_write_str(response); } #endif @@ -577,7 +608,7 @@ static void cb_oem(struct usb_ep *ep, struct usb_request *req) static void cb_erase(struct usb_ep *ep, struct usb_request *req) { char *cmd = req->buf; - char response[RESPONSE_LEN]; + char response[FASTBOOT_RESPONSE_LEN]; strsep(&cmd, ":"); if (!cmd) { @@ -591,6 +622,9 @@ static void cb_erase(struct usb_ep *ep, struct usb_request *req) #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV fb_mmc_erase(cmd, response); #endif +#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV + fb_nand_erase(cmd, response); +#endif fastboot_tx_write_str(response); } #endif diff --git a/include/ambapp.h b/include/ambapp.h index 405637d8cd..d79fcedb41 100644 --- a/include/ambapp.h +++ b/include/ambapp.h @@ -3,8 +3,8 @@ * the APB bus, also freely available in GRLIB at * www.gaisler.com. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2009, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,366 +12,214 @@ #ifndef __AMBAPP_H__ #define __AMBAPP_H__ -/* Default location of Plug&Play info - * normally 0xfffff000 for AHB masters - * and 0xfffff800 for AHB slaves. - * Normally no need to change this. - */ -#define LEON3_IO_AREA 0xfff00000 -#define LEON3_CONF_AREA 0xff000 -#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11) - -/* Max devices this software will support */ -#define LEON3_AHB_MASTERS 16 -#define LEON3_AHB_SLAVES 16 -/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */ -#define LEON3_APB_SLAVES 16 /* Total number of APB slaves per APB bus */ - -/* Vendor codes */ -#define VENDOR_GAISLER 1 -#define VENDOR_PENDER 2 -#define VENDOR_ESA 4 -#define VENDOR_ASTRIUM 6 -#define VENDOR_OPENCHIP 7 -#define VENDOR_OPENCORES 8 -#define VENDOR_CONTRIB 9 -#define VENDOR_EONIC 11 -#define VENDOR_RADIONOR 15 -#define VENDOR_GLEICHMANN 16 -#define VENDOR_MENTA 17 -#define VENDOR_SUN 19 -#define VENDOR_EMBEDDIT 234 -#define VENDOR_CAL 202 - -/* Gaisler Research device id's */ -#define GAISLER_LEON3 0x003 -#define GAISLER_LEON3DSU 0x004 -#define GAISLER_ETHAHB 0x005 -#define GAISLER_APBMST 0x006 -#define GAISLER_AHBUART 0x007 -#define GAISLER_SRCTRL 0x008 -#define GAISLER_SDCTRL 0x009 -#define GAISLER_APBUART 0x00C -#define GAISLER_IRQMP 0x00D -#define GAISLER_AHBRAM 0x00E -#define GAISLER_GPTIMER 0x011 -#define GAISLER_PCITRG 0x012 -#define GAISLER_PCISBRG 0x013 -#define GAISLER_PCIFBRG 0x014 -#define GAISLER_PCITRACE 0x015 -#define GAISLER_PCIDMA 0x016 -#define GAISLER_AHBTRACE 0x017 -#define GAISLER_ETHDSU 0x018 -#define GAISLER_PIOPORT 0x01A -#define GAISLER_AHBJTAG 0x01c -#define GAISLER_SPW 0x01f -#define GAISLER_ATACTRL 0x024 -#define GAISLER_VGA 0x061 -#define GAISLER_KBD 0X060 -#define GAISLER_ETHMAC 0x01D -#define GAISLER_DDRSPA 0x025 -#define GAISLER_EHCI 0x026 -#define GAISLER_UHCI 0x027 -#define GAISLER_SPW2 0x029 -#define GAISLER_DDR2SPA 0x02E -#define GAISLER_AHBSTAT 0x052 -#define GAISLER_FTMCTRL 0x054 - -#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */ -#define GAISLER_L2C 0xffe /* internal device: leon2compat */ -#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */ - -/* European Space Agency device id's */ -#define ESA_LEON2 0x2 -#define ESA_MCTRL 0xF - -/* Opencores device id's */ -#define OPENCORES_PCIBR 0x4 -#define OPENCORES_ETHMAC 0x5 - -/* Vendor codes */ - -/* - * - * Macros for manipulating Configuration registers - * - */ - -#define amba_vendor(x) (((x) >> 24) & 0xff) - -#define amba_device(x) (((x) >> 12) & 0xfff) - -#define amba_membar_start(mbar) \ - (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) - -#define amba_iobar_start(base, iobar) \ - ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) ) - -#define amba_irq(conf) ((conf) & 0xf) - -#define amba_ver(conf) (((conf)>>5) & 0x1f) - -#define amba_membar_type(mbar) ((mbar) & 0xf) - -#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff) - -#define AMBA_TYPE_APBIO 0x1 -#define AMBA_TYPE_MEM 0x2 -#define AMBA_TYPE_AHBIO 0x3 - -#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12)) +#include <ambapp_ids.h> #ifndef __ASSEMBLER__ +/* Structures used to access Plug&Play information directly */ +struct ambapp_pnp_ahb { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int custom[3]; + const unsigned int mbar[4]; /* MASK, ADDRESS, TYPE, + * CACHABLE/PREFETCHABLE */ +}; + +struct ambapp_pnp_apb { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int iobar; /* MASK, ADDRESS, TYPE, + * CACHABLE/PREFETCHABLE */ +}; -#ifdef CONFIG_CMD_AMBAPP - -/* AMBA Plug&Play relocation & initialization */ -int ambapp_init_reloc(void); - -/* AMBA Plug&Play Name of Vendors and devices */ - -/* Return name of device */ -char *ambapp_device_id2str(int vendor, int id); - -/* Return name of vendor */ -char *ambapp_vendor_id2str(int vendor); -#endif - -/* - * Types and structure used for AMBA Plug & Play bus scanning - */ - -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int userdef[3]; - unsigned int bars[4]; -} ahbctrl_pp_dev; - -/* Prototypes for scanning AMBA Plug&Play bus for AMBA - * i) AHB Masters - * ii) AHB Slaves - * iii) APB Slaves (APB MST is a AHB Slave) +/* AMBA Plug&Play AHB Masters & Slaves information locations + * Max devices is 64 supported by HW, however often only 16 + * are used. */ - -typedef struct { +struct ambapp_pnp_info { + struct ambapp_pnp_ahb masters[64]; + struct ambapp_pnp_ahb slaves[63]; + const unsigned int unused[4]; + const unsigned int systemid[4]; +}; + +/* Describes a AMBA PnP bus */ +struct ambapp_bus { + int buses; /* Number of buses */ + unsigned int ioareas[6]; /* PnP I/O AREAs of AHB buses */ + unsigned int freq; /* Frequency of bus0 [Hz] */ +}; + +/* Processor Local AMBA bus */ +extern struct ambapp_bus ambapp_plb; + +/* Get Bus frequency of a certain AMBA bus */ +extern unsigned int ambapp_bus_freq( + struct ambapp_bus *abus, + int ahb_bus_index + ); + +/* AMBA PnP information of a APB Device */ +typedef struct { + unsigned int vendor; + unsigned int device; unsigned char irq; unsigned char ver; unsigned int address; + unsigned int mask; + int ahb_bus_index; } ambapp_apbdev; +/* AMBA PnP information of a AHB Device */ typedef struct { + unsigned int vendor; + unsigned int device; unsigned char irq; unsigned char ver; unsigned int userdef[3]; unsigned int address[4]; + unsigned int mask[4]; + int type[4]; + int ahb_bus_index; } ambapp_ahbdev; -/* AMBA Plug&Play AHB Masters & Slaves information locations - * Max devices is 64 supported by HW, however often only 8 - * are used. - */ -typedef struct { - ahbctrl_pp_dev masters[64]; - ahbctrl_pp_dev slaves[64]; -} ahbctrl_info; +/* Scan AMBA Bus for AHB Bridges */ +extern void ambapp_bus_init( + unsigned int ioarea, + unsigned int freq, + struct ambapp_bus *abus); -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int bar; -} apbctrl_pp_dev; - -/* All functions return the number of found devices - * 0 = no devices found +/* Find APB Slave device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. */ +extern int ambapp_apb_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_apbdev *dev + ); + +/* Find AHB Master device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. + */ +extern int ambapp_ahbmst_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_ahbdev *dev + ); + +/* Find AHB Slave device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. + */ +extern int ambapp_ahbslv_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_ahbdev *dev + ); + +/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device); -/****************************** APB SLAVES ******************************/ -int ambapp_apb_count(unsigned int vendor, unsigned int driver); - -int ambapp_apb_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev); - -int ambapp_apb_next(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int index); - -int ambapp_apbs_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int max_cnt); - -/****************************** AHB MASTERS ******************************/ -int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver); - -int ambapp_ahbmst_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev); - -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device); -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device); -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver); +#ifdef CONFIG_CMD_AMBAPP -int ambapp_ahbslv_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev); +/* AMBA Plug&Play relocation & initialization */ +int ambapp_init_reloc(void); -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +/* AMBA Plug&Play Name of Vendors and devices */ -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +/* Return name of device */ +char *ambapp_device_id2str(int vendor, int id); -/*************************** AHB/APB only regs functions ************************* - * During start up, no memory is available we can use the simplified functions - * to get to the memory controller. - * - * Functions uses no stack/memory, only registers. - */ -unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register int index); +/* Return name of vendor */ +char *ambapp_vendor_id2str(int vendor); -ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register unsigned int opts, /* scan for AHB 1=slave, 0=masters */ - register int index); +/* Return description of a device */ +char *ambapp_device_id2desc(int vendor, int id); -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info); +#endif -/*************************** AMBA Plug&Play device register MAPS *****************/ +#endif /* defined(__ASSEMBLER__) */ -/* - * The following defines the bits in the LEON UART Status Registers. - */ +#define AMBA_DEFAULT_IOAREA 0xfff00000 +#define AMBA_CONF_AREA 0xff000 +#define AMBA_AHB_SLAVE_CONF_AREA 0x800 -#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */ -#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ -#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ -#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */ -#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */ -#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */ -#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */ -#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */ - -/* - * The following defines the bits in the LEON UART Ctrl Registers. - */ +#define DEV_NONE 0 +#define DEV_AHB_MST 1 +#define DEV_AHB_SLV 2 +#define DEV_APB_SLV 3 -#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */ -#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */ -#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ -#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */ -#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */ -#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */ -#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */ -#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */ -#define LEON_REG_UART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */ - -#define LEON3_GPTIMER_EN 1 -#define LEON3_GPTIMER_RL 2 -#define LEON3_GPTIMER_LD 4 -#define LEON3_GPTIMER_IRQEN 8 - -/* - * The following defines the bits in the LEON PS/2 Status Registers. - */ - -#define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */ -#define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */ -#define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */ -#define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */ +#define AMBA_TYPE_APBIO 0x1 +#define AMBA_TYPE_MEM 0x2 +#define AMBA_TYPE_AHBIO 0x3 -/* - * The following defines the bits in the LEON PS/2 Ctrl Registers. +/* ID layout for APB and AHB devices */ +#define AMBA_PNP_ID(vendor, device) (((vendor)<<24) | ((device)<<12)) + +/* APB Slave PnP layout definitions */ +#define AMBA_APB_ID_OFS (0*4) +#define AMBA_APB_IOBAR_OFS (1*4) +#define AMBA_APB_CONF_LENGH (2*4) + +/* AHB Master/Slave layout PnP definitions */ +#define AMBA_AHB_ID_OFS (0*4) +#define AMBA_AHB_CUSTOM0_OFS (1*4) +#define AMBA_AHB_CUSTOM1_OFS (2*4) +#define AMBA_AHB_CUSTOM2_OFS (3*4) +#define AMBA_AHB_MBAR0_OFS (4*4) +#define AMBA_AHB_MBAR1_OFS (5*4) +#define AMBA_AHB_MBAR2_OFS (6*4) +#define AMBA_AHB_MBAR3_OFS (7*4) +#define AMBA_AHB_CONF_LENGH (8*4) + +/* Macros for extracting information from AMBA PnP information + * registers. */ -#define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */ -#define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */ -#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */ -#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */ - -typedef struct { - volatile unsigned int ilevel; - volatile unsigned int ipend; - volatile unsigned int iforce; - volatile unsigned int iclear; - volatile unsigned int mstatus; - volatile unsigned int notused[11]; - volatile unsigned int cpu_mask[16]; - volatile unsigned int cpu_force[16]; -} ambapp_dev_irqmp; - -typedef struct { - volatile unsigned int data; - volatile unsigned int status; - volatile unsigned int ctrl; - volatile unsigned int scaler; -} ambapp_dev_apbuart; +#define amba_vendor(x) (((x) >> 24) & 0xff) -typedef struct { - volatile unsigned int val; - volatile unsigned int rld; - volatile unsigned int ctrl; - volatile unsigned int unused; -} ambapp_dev_gptimer_element; - -#define LEON3_GPTIMER_CTRL_EN 0x1 /* Timer enable */ -#define LEON3_GPTIMER_CTRL_RS 0x2 /* Timer reStart */ -#define LEON3_GPTIMER_CTRL_LD 0x4 /* Timer reLoad */ -#define LEON3_GPTIMER_CTRL_IE 0x8 /* interrupt enable */ -#define LEON3_GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */ -#define LEON3_GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */ +#define amba_device(x) (((x) >> 12) & 0xfff) -typedef struct { - volatile unsigned int scalar; - volatile unsigned int scalar_reload; - volatile unsigned int config; - volatile unsigned int unused; - volatile ambapp_dev_gptimer_element e[8]; -} ambapp_dev_gptimer; +#define amba_irq(conf) ((conf) & 0x1f) -typedef struct { - volatile unsigned int iodata; - volatile unsigned int ioout; - volatile unsigned int iodir; - volatile unsigned int irqmask; - volatile unsigned int irqpol; - volatile unsigned int irqedge; -} ambapp_dev_ioport; - -typedef struct { - volatile unsigned int write; - volatile unsigned int dummy; - volatile unsigned int txcolor; - volatile unsigned int bgcolor; -} ambapp_dev_textvga; +#define amba_ver(conf) (((conf)>>5) & 0x1f) -typedef struct { - volatile unsigned int data; - volatile unsigned int status; - volatile unsigned int ctrl; -} ambapp_dev_apbps2; +#define amba_iobar_start(base, iobar) \ + ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4))) -typedef struct { - unsigned int mcfg1, mcfg2, mcfg3; -} ambapp_dev_mctrl; +#define amba_membar_start(mbar) \ + (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) -typedef struct { - unsigned int sdcfg; -} ambapp_dev_sdctrl; +#define amba_membar_type(mbar) ((mbar) & 0xf) -typedef struct { - unsigned int cfg1; - unsigned int cfg2; - unsigned int cfg3; -} ambapp_dev_ddr2spa; +#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff) -typedef struct { - unsigned int ctrl; - unsigned int cfg; -} ambapp_dev_ddrspa; +#define amba_ahbio_adr(addr, base_ioarea) \ + ((unsigned int)(base_ioarea) | ((addr) >> 12)) -#endif +#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1) #endif diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h new file mode 100644 index 0000000000..1eae34e554 --- /dev/null +++ b/include/ambapp_ids.h @@ -0,0 +1,250 @@ +/* AMBA Plug & Play Bus Vendor and Device IDs. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#ifndef __AMBAPP_IDS_H__ +#define __AMBAPP_IDS_H__ + +/* Vendor ID defines */ +#define VENDOR_GAISLER 0x01 +#define VENDOR_PENDER 0x02 +#define VENDOR_ESA 0x04 +#define VENDOR_ASTRIUM 0x06 +#define VENDOR_OPENCHIP 0x07 +#define VENDOR_OPENCORES 0x08 +#define VENDOR_CONTRIB 0x09 +#define VENDOR_EONIC 0x0b +#define VENDOR_RADIONOR 0x0f +#define VENDOR_GLEICHMANN 0x10 +#define VENDOR_MENTA 0x11 +#define VENDOR_SUN 0x13 +#define VENDOR_MOVIDIA 0x14 +#define VENDOR_ORBITA 0x17 +#define VENDOR_SYNOPSYS 0x21 +#define VENDOR_NASA 0x22 +#define VENDOR_S3 0x31 +#define VENDOR_CAL 0xca +#define VENDOR_EMBEDDIT 0xea +#define VENDOR_CETON 0xcb +#define VENDOR_ACTEL 0xac +#define VENDOR_APPLECORE 0xae + +/* Aeroflex Gaisler device ID defines */ +#define GAISLER_LEON2DSU 0x002 +#define GAISLER_LEON3 0x003 +#define GAISLER_LEON3DSU 0x004 +#define GAISLER_ETHAHB 0x005 +#define GAISLER_APBMST 0x006 +#define GAISLER_AHBUART 0x007 +#define GAISLER_SRCTRL 0x008 +#define GAISLER_SDCTRL 0x009 +#define GAISLER_SSRCTRL 0x00a +#define GAISLER_APBUART 0x00c +#define GAISLER_IRQMP 0x00d +#define GAISLER_AHBRAM 0x00e +#define GAISLER_AHBDPRAM 0x00f +#define GAISLER_GPTIMER 0x011 +#define GAISLER_PCITRG 0x012 +#define GAISLER_PCISBRG 0x013 +#define GAISLER_PCIFBRG 0x014 +#define GAISLER_PCITRACE 0x015 +#define GAISLER_DMACTRL 0x016 +#define GAISLER_AHBTRACE 0x017 +#define GAISLER_DSUCTRL 0x018 +#define GAISLER_CANAHB 0x019 +#define GAISLER_GPIO 0x01a +#define GAISLER_AHBROM 0x01b +#define GAISLER_AHBJTAG 0x01c +#define GAISLER_ETHMAC 0x01d +#define GAISLER_SWNODE 0x01e +#define GAISLER_SPW 0x01f +#define GAISLER_AHB2AHB 0x020 +#define GAISLER_USBDC 0x021 +#define GAISLER_USB_DCL 0x022 +#define GAISLER_DDRMP 0x023 +#define GAISLER_ATACTRL 0x024 +#define GAISLER_DDRSP 0x025 +#define GAISLER_EHCI 0x026 +#define GAISLER_UHCI 0x027 +#define GAISLER_I2CMST 0x028 +#define GAISLER_SPW2 0x029 +#define GAISLER_AHBDMA 0x02a +#define GAISLER_NUHOSP3 0x02b +#define GAISLER_CLKGATE 0x02c +#define GAISLER_SPICTRL 0x02d +#define GAISLER_DDR2SP 0x02e +#define GAISLER_SLINK 0x02f +#define GAISLER_GRTM 0x030 +#define GAISLER_GRTC 0x031 +#define GAISLER_GRPW 0x032 +#define GAISLER_GRCTM 0x033 +#define GAISLER_GRHCAN 0x034 +#define GAISLER_GRFIFO 0x035 +#define GAISLER_GRADCDAC 0x036 +#define GAISLER_GRPULSE 0x037 +#define GAISLER_GRTIMER 0x038 +#define GAISLER_AHB2PP 0x039 +#define GAISLER_GRVERSION 0x03a +#define GAISLER_APB2PW 0x03b +#define GAISLER_PW2APB 0x03c +#define GAISLER_GRCAN 0x03d +#define GAISLER_I2CSLV 0x03e +#define GAISLER_U16550 0x03f +#define GAISLER_AHBMST_EM 0x040 +#define GAISLER_AHBSLV_EM 0x041 +#define GAISLER_GRTESTMOD 0x042 +#define GAISLER_ASCS 0x043 +#define GAISLER_IPMVBCTRL 0x044 +#define GAISLER_SPIMCTRL 0x045 +#define GAISLER_L4STAT 0x047 +#define GAISLER_LEON4 0x048 +#define GAISLER_LEON4DSU 0x049 +#define GAISLER_PWM 0x04a +#define GAISLER_L2CACHE 0x04b +#define GAISLER_SDCTRL64 0x04c +#define GAISLER_GR1553B 0x04d +#define GAISLER_1553TST 0x04e +#define GAISLER_GRIOMMU 0x04f +#define GAISLER_FTAHBRAM 0x050 +#define GAISLER_FTSRCTRL 0x051 +#define GAISLER_AHBSTAT 0x052 +#define GAISLER_LEON3FT 0x053 +#define GAISLER_FTMCTRL 0x054 +#define GAISLER_FTSDCTRL 0x055 +#define GAISLER_FTSRCTRL8 0x056 +#define GAISLER_MEMSCRUB 0x057 +#define GAISLER_FTSDCTRL64 0x058 +#define GAISLER_APBPS2 0x060 +#define GAISLER_VGACTRL 0x061 +#define GAISLER_LOGAN 0x062 +#define GAISLER_SVGACTRL 0x063 +#define GAISLER_T1AHB 0x064 +#define GAISLER_MP7WRAP 0x065 +#define GAISLER_GRSYSMON 0x066 +#define GAISLER_GRACECTRL 0x067 +#define GAISLER_ATAHBSLV 0x068 +#define GAISLER_ATAHBMST 0x069 +#define GAISLER_ATAPBSLV 0x06a +#define GAISLER_B1553BC 0x070 +#define GAISLER_B1553RT 0x071 +#define GAISLER_B1553BRM 0x072 +#define GAISLER_AES 0x073 +#define GAISLER_ECC 0x074 +#define GAISLER_PCIF 0x075 +#define GAISLER_CLKMOD 0x076 +#define GAISLER_HAPSTRAK 0x077 +#define GAISLER_TEST_1X2 0x078 +#define GAISLER_WILD2AHB 0x079 +#define GAISLER_BIO1 0x07a +#define GAISLER_AESDMA 0x07b +#define GAISLER_SATCAN 0x080 +#define GAISLER_CANMUX 0x081 +#define GAISLER_GRTMRX 0x082 +#define GAISLER_GRTCTX 0x083 +#define GAISLER_GRTMDESC 0x084 +#define GAISLER_GRTMVC 0x085 +#define GAISLER_GEFFE 0x086 +#define GAISLER_GPREG 0x087 +#define GAISLER_GRTMPAHB 0x088 +#define GAISLER_SPWCUC 0x089 +#define GAISLER_SPW2_DMA 0x08a +#define GAISLER_SPWROUTER 0x08b + +/* European Space Agency device ID defines */ +#define ESA_LEON2 0x002 +#define ESA_LEON2APB 0x003 +#define ESA_IRQ 0x005 +#define ESA_TIMER 0x006 +#define ESA_UART 0x007 +#define ESA_CFG 0x008 +#define ESA_IO 0x009 +#define ESA_MCTRL 0x00f +#define ESA_PCIARB 0x010 +#define ESA_HURRICANE 0x011 +#define ESA_SPW_RMAP 0x012 +#define ESA_AHBUART 0x013 +#define ESA_SPWA 0x014 +#define ESA_BOSCHCAN 0x015 +#define ESA_IRQ2 0x016 +#define ESA_AHBSTAT 0x017 +#define ESA_WPROT 0x018 +#define ESA_WPROT2 0x019 +#define ESA_PDEC3AMBA 0x020 +#define ESA_PTME3AMBA 0x021 + +/* OpenChip device ID defines */ +#define OPENCHIP_APBGPIO 0x001 +#define OPENCHIP_APBI2C 0x002 +#define OPENCHIP_APBSPI 0x003 +#define OPENCHIP_APBCHARLCD 0x004 +#define OPENCHIP_APBPWM 0x005 +#define OPENCHIP_APBPS2 0x006 +#define OPENCHIP_APBMMCSD 0x007 +#define OPENCHIP_APBNAND 0x008 +#define OPENCHIP_APBLPC 0x009 +#define OPENCHIP_APBCF 0x00a +#define OPENCHIP_APBSYSACE 0x00b +#define OPENCHIP_APB1WIRE 0x00c +#define OPENCHIP_APBJTAG 0x00d +#define OPENCHIP_APBSUI 0x00e + +/* Various contributions device ID defines */ +#define CONTRIB_CORE1 0x001 +#define CONTRIB_CORE2 0x002 + +/* Gleichmann Electronics device ID defines */ +#define GLEICHMANN_CUSTOM 0x001 +#define GLEICHMANN_GEOLCD01 0x002 +#define GLEICHMANN_DAC 0x003 +#define GLEICHMANN_HPI 0x004 +#define GLEICHMANN_SPI 0x005 +#define GLEICHMANN_HIFC 0x006 +#define GLEICHMANN_ADCDAC 0x007 +#define GLEICHMANN_SPIOC 0x008 +#define GLEICHMANN_AC97 0x009 + +/* Sun Microsystems device ID defines */ +#define SUN_T1 0x001 +#define SUN_S1 0x011 + +/* Orbita device ID defines */ +#define ORBITA_1553B 0x001 +#define ORBITA_429 0x002 +#define ORBITA_SPI 0x003 +#define ORBITA_I2C 0x004 +#define ORBITA_SMARTCARD 0x064 +#define ORBITA_SDCARD 0x065 +#define ORBITA_UART16550 0x066 +#define ORBITA_CRYPTO 0x067 +#define ORBITA_SYSIF 0x068 +#define ORBITA_PIO 0x069 +#define ORBITA_RTC 0x0c8 +#define ORBITA_COLORLCD 0x12c +#define ORBITA_PCI 0x190 +#define ORBITA_DSP 0x1f4 +#define ORBITA_USBHOST 0x258 +#define ORBITA_USBDEV 0x2bc + +/* NASA device ID defines */ +#define NASA_EP32 0x001 + +/* CAL device ID defines */ +#define CAL_DDRCTRL 0x188 + +/* Actel Corporation device ID defines */ +#define ACTEL_COREMP7 0x001 + +/* AppleCore device ID defines */ +#define APPLECORE_UTLEON3 0x001 +#define APPLECORE_UTLEON3DSU 0x002 + +/* Opencores device id's */ +#define OPENCORES_PCIBR 0x4 +#define OPENCORES_ETHMAC 0x5 + +#endif diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index 8832552f31..424721b7e7 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -13,7 +13,6 @@ * Alphabetical list of all possible commands. */ -#define CONFIG_CMD_AMBAPP /* AMBA Plug & Play Bus print utility */ #define CONFIG_CMD_ASKENV /* ask for env variable */ #define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */ #define CONFIG_CMD_BMP /* BMP support */ diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index d93e3e7619..b02abd389e 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -177,11 +177,22 @@ "fdt ram 0x80f80000 0x80000;" \ "ramdisk ram 0x81000000 0x4000000\0" +#define CONFIG_DFU_SF +#define DFU_ALT_INFO_QSPI \ + "dfu_alt_info_qspi=" \ + "u-boot.bin raw 0x0 0x080000;" \ + "u-boot.backup raw 0x080000 0x080000;" \ + "u-boot-spl-os raw 0x100000 0x010000;" \ + "u-boot-env raw 0x110000 0x010000;" \ + "u-boot-env.backup raw 0x120000 0x010000;" \ + "kernel raw 0x130000 0x800000\0" + #define DFUARGS \ "dfu_bufsiz=0x10000\0" \ DFU_ALT_INFO_MMC \ DFU_ALT_INFO_EMMC \ - DFU_ALT_INFO_RAM + DFU_ALT_INFO_RAM \ + DFU_ALT_INFO_QSPI #else #define DFUARGS #endif diff --git a/include/configs/bayleybay.h b/include/configs/bayleybay.h index 1ba2998d54..b102c689e2 100644 --- a/include/configs/bayleybay.h +++ b/include/configs/bayleybay.h @@ -16,7 +16,6 @@ #define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_ARCH_MISC_INIT -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \ diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 7f91ffffa5..54a2905c1d 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -20,19 +20,6 @@ #define CONFIG_SMSC_LPC47M -#define CONFIG_PCI_MEM_BUS 0x40000000 -#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS -#define CONFIG_PCI_MEM_SIZE 0x80000000 - -#define CONFIG_PCI_PREF_BUS 0xc0000000 -#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS -#define CONFIG_PCI_PREF_SIZE 0x20000000 - -#define CONFIG_PCI_IO_BUS 0x2000 -#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS -#define CONFIG_PCI_IO_SIZE 0xe000 - -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \ diff --git a/include/configs/dlvision-10g.h b/include/configs/dlvision-10g.h index 0b804ebdd7..b614f190bf 100644 --- a/include/configs/dlvision-10g.h +++ b/include/configs/dlvision-10g.h @@ -67,7 +67,7 @@ #undef CONFIG_CMD_DHCP #undef CONFIG_CMD_DIAG #undef CONFIG_CMD_EEPROM -#undef CONFIG_CMD_I2C +#define CONFIG_CMD_I2C #undef CONFIG_CMD_IRQ /* @@ -105,17 +105,22 @@ #define CONFIG_SYS_I2C_PPC4XX_SLAVE_0 0x7F #define CONFIG_SYS_I2C_IHS +#define CONFIG_SYS_I2C_IHS_DUAL #define CONFIG_SYS_I2C_IHS_CH0 #define CONFIG_SYS_I2C_IHS_SPEED_0 50000 #define CONFIG_SYS_I2C_IHS_SLAVE_0 0x7F +#define CONFIG_SYS_I2C_IHS_SPEED_0_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_0_1 0x7F #define CONFIG_SYS_I2C_IHS_CH1 #define CONFIG_SYS_I2C_IHS_SPEED_1 50000 #define CONFIG_SYS_I2C_IHS_SLAVE_1 0x7F +#define CONFIG_SYS_I2C_IHS_SPEED_1_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_1_1 0x7F -#define CONFIG_SYS_SPD_BUS_NUM 2 +#define CONFIG_SYS_SPD_BUS_NUM 4 /* Temp sensor/hwmon/dtt */ -#define CONFIG_SYS_DTT_BUS_NUM 2 +#define CONFIG_SYS_DTT_BUS_NUM 4 #define CONFIG_DTT_LM63 1 /* National LM63 */ #define CONFIG_DTT_SENSORS { 0x4c, 0x4e, 0x18 } /* Sensor addresses */ #define CONFIG_DTT_PWM_LOOKUPTABLE \ @@ -123,8 +128,9 @@ { 54, 27 }, { 56, 31 }, { 58, 36 }, { 60, 40 } } #define CONFIG_DTT_TACH_LIMIT 0xa10 -#define CONFIG_SYS_ICS8N3QV01_I2C {0, 1} -#define CONFIG_SYS_SIL1178_I2C {0, 1} +#define CONFIG_SYS_ICS8N3QV01_I2C {1, 3} +#define CONFIG_SYS_SIL1178_I2C {0, 2} +#define CONFIG_SYS_DP501_I2C {0, 2} /* EBC peripherals */ @@ -327,5 +333,7 @@ */ #define CONFIG_SYS_MPC92469AC #define CONFIG_SYS_OSD_SCREENS CONFIG_SYS_FPGA_COUNT +#define CONFIG_SYS_DP501_DIFFERENTIAL +#define CONFIG_SYS_DP501_VCAPCTRL0 0x01 /* DDR mode 0, DE for H/VSYNC */ #endif /* __CONFIG_H */ diff --git a/include/configs/galileo.h b/include/configs/galileo.h index ba6c8f172b..eb16a5eaca 100644 --- a/include/configs/galileo.h +++ b/include/configs/galileo.h @@ -21,7 +21,6 @@ /* ns16550 UART is memory-mapped in Quark SoC */ #undef CONFIG_SYS_NS16550_PORT_MAPPED -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 782746e4e0..5bbf1aaae8 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -60,7 +60,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -311,40 +310,38 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x10f800ff | (1<<11)) #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 #else -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82205260 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82205260 #endif -#define CONFIG_SYS_GRLIB_MEMCFG3 0x0809a000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x0809a000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x10f800ff | (1<<11)) +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x10f800ff | (1<<11)) #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 #else -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82205260 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82205260 #endif -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x0809a000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x0809a000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000" diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 5c466f2929..b55ca77a87 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -54,7 +54,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -288,30 +287,31 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x10f800ff | (1<<11)) -#define CONFIG_SYS_GRLIB_MEMCFG2 0x00000000 -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x10f800ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x00000000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_DDR_CFG 0xa900830a - -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x00000000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00000000 + +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x00000000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00000000 + +/* DDR controller */ +#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 +#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL 0xa900830a + +/* no DDR2 Controller */ +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60" diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index e01578cbb2..d086b694c2 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -41,7 +41,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -251,32 +250,30 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00136000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00136000 +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00136000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500" diff --git a/include/configs/grsim.h b/include/configs/grsim.h index f54919eaae..e1f7dc3bf6 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -19,9 +19,13 @@ * * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1. * - * TSIM command - * tsim-leon3 -sdram 0 -ram 32000 -rom 8192 -mmu + * TSIM command: + * $ tsim-leon3 -sdram 32768 -ram 4096 -rom 2048 -mmu -cas * + * In the evaluation version of TSIM, the -sdram/-ram/-rom arguments are + * hard-coded to these values and need not be specified. (see below) + * + * Get TSIM from http://www.gaisler.com/index.php/downloads/simulators */ #define CONFIG_GRSIM 0 /* ... not running on GRSIM */ @@ -47,7 +51,6 @@ /* * Supported commands */ -#define CONFIG_CMD_AMBAPP /* AMBA Plyg&Play information */ #define CONFIG_CMD_DIAG #define CONFIG_CMD_FPGA_LOADMK #define CONFIG_CMD_IRQ @@ -184,18 +187,18 @@ /* * Memory map */ -#define CONFIG_SYS_SDRAM_BASE 0x40000000 -#define CONFIG_SYS_SDRAM_SIZE 0x02000000 -#define CONFIG_SYS_SDRAM_END (CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_SDRAM_SIZE) +#define CONFIG_SYS_SDRAM_BASE 0x60000000 +#define CONFIG_SYS_SDRAM_SIZE 0x02000000 /* 32MiB SDRAM */ +#define CONFIG_SYS_SDRAM_END (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE) -/* no SRAM available */ -#undef CONFIG_SYS_SRAM_BASE -#undef CONFIG_SYS_SRAM_SIZE +#define CONFIG_SYS_SRAM_BASE 0x40000000 +#define CONFIG_SYS_SRAM_SIZE 0x00400000 /* 4MiB SRAM */ +#define CONFIG_SYS_SRAM_END (CONFIG_SYS_SRAM_BASE + CONFIG_SYS_SRAM_SIZE) /* Always Run U-Boot from SDRAM */ -#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE -#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE -#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END +#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE +#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_RAM_END - GENERATED_GBL_DATA_SIZE) @@ -224,6 +227,7 @@ /* make un relocated address from relocated address */ #define UN_RELOC(address) (address-(CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE)) +#ifdef CONFIG_CMD_NET /* * Ethernet configuration */ @@ -235,6 +239,8 @@ /* #define CONFIG_GRETH_10MBIT 1 */ #define CONFIG_PHY_ADDR 0x00 +#endif /* CONFIG_CMD_NET */ + /* * Miscellaneous configurable options */ @@ -255,37 +261,65 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 + #define CONFIG_SYS_GRLIB_MEMCFG1 (0x000000ff | (1<<11)) + +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + +/* LEON2 MCTRL configuration */ +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x000000ff | (1<<11)) #if CONFIG_GRSIM /* GRSIM configuration */ -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 #else /* TSIM configuration */ -#define CONFIG_SYS_GRLIB_MEMCFG2 0x00001820 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x81805220 #endif -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00136000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00136000 +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00136000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" #define CONFIG_IDENT_STRING "Gaisler GRSIM" +/* TSIM command: + * $ ./tsim-leon3 -mmu -cas + * + * This TSIM evaluation version will expire 2015-04-02 + * + * + * TSIM/LEON3 SPARC simulator, version 2.0.35 (evaluation version) + * + * Copyright (C) 2014, Aeroflex Gaisler - all rights reserved. + * This software may only be used with a valid license. + * For latest updates, go to http://www.gaisler.com/ + * Comments or bug-reports to support@gaisler.com + * + * serial port A on stdin/stdout + * allocated 4096 K SRAM memory, in 1 bank + * allocated 32 M SDRAM memory, in 1 bank + * allocated 2048 K ROM memory + * icache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total) + * dcache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total) + * tsim> leon + * 0x80000000 Memory configuration register 1 0x000002ff + * 0x80000004 Memory configuration register 2 0x81805220 + * 0x80000008 Memory configuration register 3 0x00000000 + */ + #endif /* __CONFIG_H */ diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index bd2eaa9fda..83fd7fae50 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -264,8 +264,6 @@ #define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 /*** LEON2 UART 1 ***/ -#define CONFIG_SYS_LEON2_UART1_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) /* UART1 Define to 1 or 0 */ #define LEON2_UART1_LOOPBACK_ENABLE 0 @@ -275,9 +273,6 @@ /*** LEON2 UART 2 ***/ -#define CONFIG_SYS_LEON2_UART2_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* UART2 Define to 1 or 0 */ #define LEON2_UART2_LOOPBACK_ENABLE 0 #define LEON2_UART2_FLOWCTRL_ENABLE 0 diff --git a/include/configs/hrcon.h b/include/configs/hrcon.h index 3cb279a912..84d0928a67 100644 --- a/include/configs/hrcon.h +++ b/include/configs/hrcon.h @@ -20,7 +20,11 @@ #define CONFIG_SYS_TEXT_BASE 0xFE000000 +#ifdef CONFIG_HRCON_DH +#define CONFIG_IDENT_STRING " hrcon dh 0.01" +#else #define CONFIG_IDENT_STRING " hrcon 0.01" +#endif #define CONFIG_BOARD_EARLY_INIT_F @@ -343,6 +347,22 @@ #define CONFIG_SYS_I2C_IHS_SPEED_3 50000 #define CONFIG_SYS_I2C_IHS_SLAVE_3 0x7F +#ifdef CONFIG_HRCON_DH +#define CONFIG_SYS_I2C_IHS_DUAL +#define CONFIG_SYS_I2C_IHS_CH0_1 +#define CONFIG_SYS_I2C_IHS_SPEED_0_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_0_1 0x7F +#define CONFIG_SYS_I2C_IHS_CH1_1 +#define CONFIG_SYS_I2C_IHS_SPEED_1_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_1_1 0x7F +#define CONFIG_SYS_I2C_IHS_CH2_1 +#define CONFIG_SYS_I2C_IHS_SPEED_2_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_2_1 0x7F +#define CONFIG_SYS_I2C_IHS_CH3_1 +#define CONFIG_SYS_I2C_IHS_SPEED_3_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_3_1 0x7F +#endif + /* * Software (bit-bang) I2C driver configuration */ @@ -358,34 +378,85 @@ #define I2C_SOFT_DECLARATIONS4 #define CONFIG_SYS_I2C_SOFT_SPEED_4 50000 #define CONFIG_SYS_I2C_SOFT_SLAVE_4 0x7F +#define I2C_SOFT_DECLARATIONS5 +#define CONFIG_SYS_I2C_SOFT_SPEED_5 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_5 0x7F +#define I2C_SOFT_DECLARATIONS6 +#define CONFIG_SYS_I2C_SOFT_SPEED_6 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_6 0x7F +#define I2C_SOFT_DECLARATIONS7 +#define CONFIG_SYS_I2C_SOFT_SPEED_7 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_7 0x7F +#define I2C_SOFT_DECLARATIONS8 +#define CONFIG_SYS_I2C_SOFT_SPEED_8 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_8 0x7F + +#ifdef CONFIG_HRCON_DH +#define I2C_SOFT_DECLARATIONS9 +#define CONFIG_SYS_I2C_SOFT_SPEED_9 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_9 0x7F +#define I2C_SOFT_DECLARATIONS10 +#define CONFIG_SYS_I2C_SOFT_SPEED_10 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_10 0x7F +#define I2C_SOFT_DECLARATIONS11 +#define CONFIG_SYS_I2C_SOFT_SPEED_11 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_11 0x7F +#define I2C_SOFT_DECLARATIONS12 +#define CONFIG_SYS_I2C_SOFT_SPEED_12 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_12 0x7F +#endif -#define CONFIG_SYS_ICS8N3QV01_I2C {5, 6, 7, 8} -#define CONFIG_SYS_CH7301_I2C {5, 6, 7, 8} +#ifdef CONFIG_HRCON_DH +#define CONFIG_SYS_ICS8N3QV01_I2C {13, 14, 15, 16, 17, 18, 19, 20} +#define CONFIG_SYS_DP501_I2C {1, 3, 5, 7, 2, 4, 6, 8} +#define CONFIG_HRCON_FANS { {10, 0x4c}, {11, 0x4c}, \ + {12, 0x4c} } +#else +#define CONFIG_SYS_ICS8N3QV01_I2C {9, 10, 11, 12} #define CONFIG_SYS_DP501_I2C {1, 2, 3, 4} +#define CONFIG_HRCON_FANS { {6, 0x4c}, {7, 0x4c}, \ + {8, 0x4c} } +#endif #ifndef __ASSEMBLY__ void fpga_gpio_set(unsigned int bus, int pin); void fpga_gpio_clear(unsigned int bus, int pin); int fpga_gpio_get(unsigned int bus, int pin); +void fpga_control_set(unsigned int bus, int pin); +void fpga_control_clear(unsigned int bus, int pin); #endif +#define I2C_SDA_GPIO ((I2C_ADAP_HWNR > 3) ? 0x0040 : 0x0200) +#define I2C_SCL_GPIO ((I2C_ADAP_HWNR > 3) ? 0x0020 : 0x0100) +#define I2C_FPGA_IDX (I2C_ADAP_HWNR % 4) + +#ifdef CONFIG_HRCON_DH +#define I2C_ACTIVE \ + do { \ + if (I2C_ADAP_HWNR > 7) \ + fpga_control_set(I2C_FPGA_IDX, 0x0004); \ + else \ + fpga_control_clear(I2C_FPGA_IDX, 0x0004); \ + } while (0) +#else #define I2C_ACTIVE { } +#endif #define I2C_TRISTATE { } #define I2C_READ \ - (fpga_gpio_get(I2C_ADAP_HWNR, 0x0040) ? 1 : 0) + (fpga_gpio_get(I2C_FPGA_IDX, I2C_SDA_GPIO) ? 1 : 0) #define I2C_SDA(bit) \ do { \ if (bit) \ - fpga_gpio_set(I2C_ADAP_HWNR, 0x0040); \ + fpga_gpio_set(I2C_FPGA_IDX, I2C_SDA_GPIO); \ else \ - fpga_gpio_clear(I2C_ADAP_HWNR, 0x0040); \ + fpga_gpio_clear(I2C_FPGA_IDX, I2C_SDA_GPIO); \ } while (0) #define I2C_SCL(bit) \ do { \ if (bit) \ - fpga_gpio_set(I2C_ADAP_HWNR, 0x0020); \ + fpga_gpio_set(I2C_FPGA_IDX, I2C_SCL_GPIO); \ else \ - fpga_gpio_clear(I2C_ADAP_HWNR, 0x0020); \ + fpga_gpio_clear(I2C_FPGA_IDX, I2C_SCL_GPIO); \ } while (0) #define I2C_DELAY udelay(25) /* 1/4 I2C clock duration */ @@ -402,6 +473,10 @@ int fpga_gpio_get(unsigned int bus, int pin); #define CONFIG_SYS_DP501_DIFFERENTIAL #define CONFIG_SYS_DP501_VCAPCTRL0 0x01 /* DDR mode 0, DE for H/VSYNC */ +#ifdef CONFIG_HRCON_DH +#define CONFIG_SYS_OSD_DH +#endif + /* * General PCI * Addresses are mapped 1-1. diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h index e87a01047d..f63957ab92 100644 --- a/include/configs/jetson-tk1.h +++ b/include/configs/jetson-tk1.h @@ -78,6 +78,4 @@ #define CONFIG_ARMV7_SECURE_BASE 0xfff00000 #define CONFIG_ARMV7_SECURE_RESERVE_SIZE 0x00100000 -#define CONFIG_OF_BOARD_SETUP - #endif /* __CONFIG_H */ diff --git a/include/configs/kwb.h b/include/configs/kwb.h index 96f2e9d39b..45253b8118 100644 --- a/include/configs/kwb.h +++ b/include/configs/kwb.h @@ -57,6 +57,8 @@ #ifndef CONFIG_SPL_BUILD #define CONFIG_EXTRA_ENV_SETTINGS \ BUR_COMMON_ENV \ +"bootaddr=0x80001100\0" \ +"bootdev=cpsw(0,0)\0" \ "vx_romfsbase=0x800E0000\0" \ "vx_romfssize=0x20000\0" \ "vx_memtop=0x8FBEF000\0" \ @@ -66,7 +68,7 @@ BUR_COMMON_ENV \ "logoaddr=0x82000000\0" \ "defaultARlen=0x8000\0" \ "loaddefaultAR=mmc read ${loadaddr} 800 ${defaultARlen}\0" \ -"defaultAR=run loadromfs; run loaddefaultAR; go ${loadaddr}\0" \ +"defaultAR=run loadromfs; run loaddefaultAR; bootvx ${loadaddr}\0" \ "logo0=fatload mmc 0:1 ${logoaddr} SYSTEM/ADDON/Bootlogo/Bootlogo.bmp.gz && " \ "bmp display ${logoaddr} 0 0\0" \ "logo1=fatload mmc 0:1 ${logoaddr} SYSTEM/BASE/Bootlogo/Bootlogo.bmp.gz && " \ @@ -74,11 +76,11 @@ BUR_COMMON_ENV \ "mmcboot=echo booting AR from eMMC-flash ...; "\ "run logo0 || run logo1; " \ "run loadromfs; " \ - "fatload mmc 0:1 ${loadaddr} arimg && go ${loadaddr}; " \ + "fatload mmc 0:1 ${loadaddr} arimg && bootvx ${loadaddr}; " \ "run defaultAR;\0" \ "netboot=echo booting AR from network ...; " \ "run loadromfs; " \ - "tftp ${loadaddr} arimg && go ${loadaddr}; " \ + "tftp ${loadaddr} arimg && bootvx ${loadaddr}; " \ "puts 'networkboot failed!';\0" \ "netscript=echo running script from network (tftp) ...; " \ "tftp 0x80000000 netscript.img && source; " \ diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 53d86a2778..a20552e74e 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -19,7 +19,6 @@ #define CONFIG_SMSC_LPC47M -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_RTL8169 #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ diff --git a/include/configs/omap3_logic.h b/include/configs/omap3_logic.h index ecd5615859..7b60f29bd2 100644 --- a/include/configs/omap3_logic.h +++ b/include/configs/omap3_logic.h @@ -272,13 +272,4 @@ #endif /* (CONFIG_CMD_NET) */ -/* - * BOOTP fields - */ - -#define CONFIG_BOOTP_SUBNETMASK 0x00000001 -#define CONFIG_BOOTP_GATEWAY 0x00000002 -#define CONFIG_BOOTP_HOSTNAME 0x00000004 -#define CONFIG_BOOTP_BOOTPATH 0x00000010 - #endif /* __CONFIG_H */ diff --git a/include/configs/p2371-2180.h b/include/configs/p2371-2180.h index 3bdf1961a3..94f8085ceb 100644 --- a/include/configs/p2371-2180.h +++ b/include/configs/p2371-2180.h @@ -53,6 +53,16 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX +/* PCI host support */ +#define CONFIG_PCI +#define CONFIG_PCI_TEGRA +#define CONFIG_PCI_PNP +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PCI_ENUM + +/* PCI networking support */ +#define CONFIG_RTL8169 + /* General networking support */ #define CONFIG_CMD_DHCP diff --git a/include/configs/p2571.h b/include/configs/p2571.h index c65d3e5fcb..a5de411121 100644 --- a/include/configs/p2571.h +++ b/include/configs/p2571.h @@ -60,6 +60,4 @@ #include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" -#define CONFIG_OF_BOARD_SETUP - #endif /* _P2571_H */ diff --git a/include/configs/pengwyn.h b/include/configs/pengwyn.h index ccb5dd3c03..d68cdede86 100644 --- a/include/configs/pengwyn.h +++ b/include/configs/pengwyn.h @@ -127,35 +127,58 @@ #define CONFIG_CMD_NAND #define CONFIG_NAND_OMAP_GPMC #define CONFIG_NAND_OMAP_ELM + +/* NAND Configuration. */ #define CONFIG_SYS_NAND_5_ADDR_CYCLE #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ CONFIG_SYS_NAND_PAGE_SIZE) -#define CONFIG_SYS_NAND_PAGE_SIZE 2048 -#define CONFIG_SYS_NAND_OOBSIZE 64 -#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) +#define CONFIG_SYS_NAND_PAGE_SIZE 4096 +#define CONFIG_SYS_NAND_OOBSIZE 224 +#define CONFIG_SYS_NAND_ONFI_DETECTION +#define CONFIG_SYS_NAND_BLOCK_SIZE (128*4096) #define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS -#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ - 10, 11, 12, 13, 14, 15, 16, 17, \ - 18, 19, 20, 21, 22, 23, 24, 25, \ - 26, 27, 28, 29, 30, 31, 32, 33, \ - 34, 35, 36, 37, 38, 39, 40, 41, \ - 42, 43, 44, 45, 46, 47, 48, 49, \ - 50, 51, 52, 53, 54, 55, 56, 57, } +#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\ + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\ + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\ + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,\ + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\ + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,\ + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,\ + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,\ + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,\ + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,\ + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,\ + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209} + #define CONFIG_SYS_NAND_ECCSIZE 512 -#define CONFIG_SYS_NAND_ECCBYTES 14 -#define CONFIG_SYS_NAND_ONFI_DETECTION -#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW +#define CONFIG_SYS_NAND_ECCBYTES 26 +#define CONFIG_SYS_NAND_ECCSTEPS 8 +#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \ + CONFIG_SYS_NAND_ECCSTEPS) +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH16_CODE_HW +/* END NAND Configuration. */ + #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE -#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 +/* #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000 */ +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x200000 + + + +#define CONFIG_CMD_MTDPARTS + +#define CONFIG_CMD_ASKENV /* monitor functions : ask for env variable */ +#define CONFIG_VERSION_VARIABLE /* monitor functions : u-boot version */ +#define CONFIG_CMD_DIAG /* monitor functions : Diagnostics */ #define MTDIDS_DEFAULT "nand0=omap2-nand.0" -#define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:128k(SPL)," \ - "128k(SPL.backup1)," \ - "128k(SPL.backup2)," \ - "128k(SPL.backup3),1792k(u-boot)," \ - "128k(u-boot-spl-os)," \ - "128k(u-boot-env),5m(kernel),-(rootfs)" +/* Size must be a multiple of Nand erase size (524288 b) */ +#define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:512k(SPL)," \ + "512k(SPL.backup1)," \ + "512k(SPL.backup2)," \ + "512k(SPL.backup3),1536k(u-boot)," \ + "512k(u-boot-spl-os)," \ + "512k(u-boot-env),5m(kernel),-(rootfs)" #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_OFFSET 0x260000 /* environment starts here */ #define CONFIG_SYS_ENV_SECT_SIZE (128 << 10) /* 128 KiB */ @@ -198,11 +221,15 @@ #undef CONFIG_SPL_ETH_SUPPORT #endif +/* CPSW ethernet */ +#define CONFIG_NET_MULTI + /* Network */ #define CONFIG_CMD_MII #define CONFIG_PHYLIB #define CONFIG_PHY_RESET 1 #define CONFIG_PHY_NATSEMI +#define CONFIG_PHY_REALTEK /* CPSW support */ #define CONFIG_SPL_ETH_SUPPORT diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h index 1b544c119e..ecb385c0b3 100644 --- a/include/configs/qemu-x86.h +++ b/include/configs/qemu-x86.h @@ -15,18 +15,7 @@ #define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_ARCH_MISC_INIT - -#define CONFIG_PCI_MEM_BUS 0xc0000000 -#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS -#define CONFIG_PCI_MEM_SIZE 0x10000000 - -#define CONFIG_PCI_PREF_BUS 0xd0000000 -#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS -#define CONFIG_PCI_PREF_SIZE 0x10000000 - -#define CONFIG_PCI_IO_BUS 0x2000 -#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS -#define CONFIG_PCI_IO_SIZE 0xe000 +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_PCI_PNP diff --git a/include/configs/som-6896.h b/include/configs/som-6896.h index 300e9dfc39..43a9623f04 100644 --- a/include/configs/som-6896.h +++ b/include/configs/som-6896.h @@ -20,7 +20,6 @@ #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_AHCI} -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define VIDEO_IO_OFFSET 0 diff --git a/include/configs/strider.h b/include/configs/strider.h new file mode 100644 index 0000000000..fb7b7f9551 --- /dev/null +++ b/include/configs/strider.h @@ -0,0 +1,651 @@ +/* + * (C) Copyright 2014 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_E300 1 /* E300 family */ +#define CONFIG_MPC83xx 1 /* MPC83xx family */ +#define CONFIG_MPC830x 1 /* MPC830x family */ +#define CONFIG_MPC8308 1 /* MPC8308 CPU specific */ +#define CONFIG_STRIDER 1 /* STRIDER board specific */ + +#define CONFIG_SYS_TEXT_BASE 0xFE000000 + +#ifdef CONFIG_STRIDER_CPU +#define CONFIG_IDENT_STRING " strider cpu 0.01" +#else +#define CONFIG_IDENT_STRING " strider con 0.01" +#endif + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_LAST_STAGE_INIT + +/* new uImage format support */ +#define CONFIG_FIT 1 +#define CONFIG_FIT_VERBOSE 1 + +#define CONFIG_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR CONFIG_SYS_MPC83xx_ESDHC_ADDR +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 + +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_DOS_PARTITION +#define CONFIG_CMD_EXT2 + +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_ALT_MEMTEST + +#define CONFIG_CMD_FPGAD +#define CONFIG_CMD_IOLOOP + +/* + * System Clock Setup + */ +#define CONFIG_83XX_CLKIN 33333333 /* in Hz */ +#define CONFIG_SYS_CLK_FREQ CONFIG_83XX_CLKIN + +/* + * Hardware Reset Configuration Word + * if CLKIN is 66.66MHz, then + * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz + * We choose the A type silicon as default, so the core is 400Mhz. + */ +#define CONFIG_SYS_HRCW_LOW (\ + HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\ + HRCWL_DDR_TO_SCB_CLK_2X1 |\ + HRCWL_SVCOD_DIV_2 |\ + HRCWL_CSB_TO_CLKIN_4X1 |\ + HRCWL_CORE_TO_CSB_3X1) +/* + * There are neither HRCWH_PCI_HOST nor HRCWH_PCI1_ARBITER_ENABLE bits + * in 8308's HRCWH according to the manual, but original Freescale's + * code has them and I've expirienced some problems using the board + * with BDI3000 attached when I've tried to set these bits to zero + * (UART doesn't work after the 'reset run' command). + */ +#define CONFIG_SYS_HRCW_HIGH (\ + HRCWH_PCI_HOST |\ + HRCWH_PCI1_ARBITER_ENABLE |\ + HRCWH_CORE_ENABLE |\ + HRCWH_FROM_0XFFF00100 |\ + HRCWH_BOOTSEQ_DISABLE |\ + HRCWH_SW_WATCHDOG_DISABLE |\ + HRCWH_ROM_LOC_LOCAL_16BIT |\ + HRCWH_RL_EXT_LEGACY |\ + HRCWH_TSEC1M_IN_MII |\ + HRCWH_TSEC2M_IN_RGMII |\ + HRCWH_BIG_ENDIAN) + +/* + * System IO Config + */ +#define CONFIG_SYS_SICRH (\ + SICRH_ESDHC_A_SD |\ + SICRH_ESDHC_B_SD |\ + SICRH_ESDHC_C_SD |\ + SICRH_GPIO_A_GPIO |\ + SICRH_GPIO_B_GPIO |\ + SICRH_IEEE1588_A_GPIO |\ + SICRH_USB |\ + SICRH_GTM_GPIO |\ + SICRH_IEEE1588_B_GPIO |\ + SICRH_ETSEC2_GPIO |\ + SICRH_GPIOSEL_1 |\ + SICRH_TMROBI_V3P3 |\ + SICRH_TSOBI1_V2P5 |\ + SICRH_TSOBI2_V2P5) /* 0x0037f103 */ +#define CONFIG_SYS_SICRL (\ + SICRL_SPI_PF0 |\ + SICRL_UART_PF0 |\ + SICRL_IRQ_PF0 |\ + SICRL_I2C2_PF0 |\ + SICRL_ETSEC1_TX_CLK) /* 0x00000000 */ + +/* + * IMMR new address + */ +#define CONFIG_SYS_IMMR 0xE0000000 + +/* + * SERDES + */ +#define CONFIG_FSL_SERDES +#define CONFIG_FSL_SERDES1 0xe3000 + +/* + * Arbiter Setup + */ +#define CONFIG_SYS_ACR_PIPE_DEP 3 /* Arbiter pipeline depth is 4 */ +#define CONFIG_SYS_ACR_RPTCNT 3 /* Arbiter repeat count is 4 */ +#define CONFIG_SYS_SPCR_TSECEP 3 /* eTSEC emergency priority is highest */ + +/* + * DDR Setup + */ +#define CONFIG_SYS_DDR_BASE 0x00000000 /* DDR is system memory */ +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_BASE +#define CONFIG_SYS_DDR_SDRAM_BASE CONFIG_SYS_DDR_BASE +#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05 +#define CONFIG_SYS_DDRCDR_VALUE (DDRCDR_EN \ + | DDRCDR_PZ_LOZ \ + | DDRCDR_NZ_LOZ \ + | DDRCDR_ODT \ + | DDRCDR_Q_DRN) + /* 0x7b880001 */ +/* + * Manually set up DDR parameters + * consist of one chip NT5TU64M16HG from NANYA + */ + +#define CONFIG_SYS_DDR_SIZE 128 /* MB */ + +#define CONFIG_SYS_DDR_CS0_BNDS 0x00000007 +#define CONFIG_SYS_DDR_CS0_CONFIG (CSCONFIG_EN \ + | CSCONFIG_ODT_RD_NEVER \ + | CSCONFIG_ODT_WR_ONLY_CURRENT \ + | CSCONFIG_BANK_BIT_3 \ + | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10) + /* 0x80010102 */ +#define CONFIG_SYS_DDR_TIMING_3 0 +#define CONFIG_SYS_DDR_TIMING_0 ((0 << TIMING_CFG0_RWT_SHIFT) \ + | (0 << TIMING_CFG0_WRT_SHIFT) \ + | (0 << TIMING_CFG0_RRT_SHIFT) \ + | (0 << TIMING_CFG0_WWT_SHIFT) \ + | (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) \ + | (6 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) \ + | (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) \ + | (2 << TIMING_CFG0_MRS_CYC_SHIFT)) + /* 0x00260802 */ +#define CONFIG_SYS_DDR_TIMING_1 ((2 << TIMING_CFG1_PRETOACT_SHIFT) \ + | (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \ + | (2 << TIMING_CFG1_ACTTORW_SHIFT) \ + | (7 << TIMING_CFG1_CASLAT_SHIFT) \ + | (9 << TIMING_CFG1_REFREC_SHIFT) \ + | (2 << TIMING_CFG1_WRREC_SHIFT) \ + | (2 << TIMING_CFG1_ACTTOACT_SHIFT) \ + | (2 << TIMING_CFG1_WRTORD_SHIFT)) + /* 0x26279222 */ +#define CONFIG_SYS_DDR_TIMING_2 ((0 << TIMING_CFG2_ADD_LAT_SHIFT) \ + | (4 << TIMING_CFG2_CPO_SHIFT) \ + | (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \ + | (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \ + | (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \ + | (3 << TIMING_CFG2_CKE_PLS_SHIFT) \ + | (5 << TIMING_CFG2_FOUR_ACT_SHIFT)) + /* 0x021848c5 */ +#define CONFIG_SYS_DDR_INTERVAL ((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \ + | (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT)) + /* 0x08240100 */ +#define CONFIG_SYS_DDR_SDRAM_CFG (SDRAM_CFG_SREN \ + | SDRAM_CFG_SDRAM_TYPE_DDR2 \ + | SDRAM_CFG_DBW_16) + /* 0x43100000 */ + +#define CONFIG_SYS_DDR_SDRAM_CFG2 0x00401000 /* 1 posted refresh */ +#define CONFIG_SYS_DDR_MODE ((0x0440 << SDRAM_MODE_ESD_SHIFT) \ + | (0x0242 << SDRAM_MODE_SD_SHIFT)) + /* ODT 150ohm CL=4, AL=0 on SDRAM */ +#define CONFIG_SYS_DDR_MODE2 0x00000000 + +/* + * Memory test + */ +#define CONFIG_SYS_MEMTEST_START 0x00001000 /* memtest region */ +#define CONFIG_SYS_MEMTEST_END 0x07f00000 + +/* + * The reserved memory + */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */ + +#define CONFIG_SYS_MONITOR_LEN (384 * 1024) /* Reserve 384 kB for Mon */ +#define CONFIG_SYS_MALLOC_LEN (512 * 1024) /* Reserved for malloc */ + +/* + * Initial RAM Base Address Setup + */ +#define CONFIG_SYS_INIT_RAM_LOCK 1 +#define CONFIG_SYS_INIT_RAM_ADDR 0xE6000000 /* Initial RAM address */ +#define CONFIG_SYS_INIT_RAM_SIZE 0x1000 /* Size of used area in RAM */ +#define CONFIG_SYS_GBL_DATA_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) + +/* + * Local Bus Configuration & Clock Setup + */ +#define CONFIG_SYS_LCRR_DBYP LCRR_DBYP +#define CONFIG_SYS_LCRR_CLKDIV LCRR_CLKDIV_2 +#define CONFIG_SYS_LBC_LBCR 0x00040000 + +/* + * FLASH on the Local Bus + */ +#if 1 +#define CONFIG_SYS_FLASH_CFI /* use the Common Flash Interface */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT +#define CONFIG_FLASH_CFI_LEGACY +#define CONFIG_SYS_FLASH_LEGACY_512Kx16 +#else +#define CONFIG_SYS_NO_FLASH +#endif + +#define CONFIG_SYS_FLASH_BASE 0xFE000000 /* FLASH base address */ +#define CONFIG_SYS_FLASH_SIZE 8 /* FLASH size is up to 8M */ +#define CONFIG_SYS_FLASH_PROTECTION 1 /* Use h/w Flash protection. */ + +/* Window base at flash base */ +#define CONFIG_SYS_LBLAWBAR0_PRELIM CONFIG_SYS_FLASH_BASE +#define CONFIG_SYS_LBLAWAR0_PRELIM (LBLAWAR_EN | LBLAWAR_8MB) + +#define CONFIG_SYS_BR0_PRELIM (CONFIG_SYS_FLASH_BASE \ + | BR_PS_16 /* 16 bit port */ \ + | BR_MS_GPCM /* MSEL = GPCM */ \ + | BR_V) /* valid */ +#define CONFIG_SYS_OR0_PRELIM (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) \ + | OR_UPM_XAM \ + | OR_GPCM_CSNT \ + | OR_GPCM_ACS_DIV2 \ + | OR_GPCM_XACS \ + | OR_GPCM_SCY_15 \ + | OR_GPCM_TRLX_SET \ + | OR_GPCM_EHTR_SET) + +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 135 + +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +/* + * FPGA + */ +#define CONFIG_SYS_FPGA0_BASE 0xE0600000 +#define CONFIG_SYS_FPGA0_SIZE 1 /* FPGA size is 1M */ + +/* Window base at FPGA base */ +#define CONFIG_SYS_LBLAWBAR1_PRELIM CONFIG_SYS_FPGA0_BASE +#define CONFIG_SYS_LBLAWAR1_PRELIM (LBLAWAR_EN | LBLAWAR_1MB) + +#define CONFIG_SYS_BR1_PRELIM (CONFIG_SYS_FPGA0_BASE \ + | BR_PS_16 /* 16 bit port */ \ + | BR_MS_GPCM /* MSEL = GPCM */ \ + | BR_V) /* valid */ +#define CONFIG_SYS_OR1_PRELIM (MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \ + | OR_UPM_XAM \ + | OR_GPCM_CSNT \ + | OR_GPCM_ACS_DIV2 \ + | OR_GPCM_XACS \ + | OR_GPCM_SCY_15 \ + | OR_GPCM_TRLX_SET \ + | OR_GPCM_EHTR_SET) + +#define CONFIG_SYS_FPGA_BASE(k) CONFIG_SYS_FPGA0_BASE +#define CONFIG_SYS_FPGA_DONE(k) 0x0010 + +#define CONFIG_SYS_FPGA_COUNT 1 + +#define CONFIG_SYS_MCLINK_MAX 3 + +#define CONFIG_SYS_FPGA_PTR \ + { (struct ihs_fpga *)CONFIG_SYS_FPGA0_BASE, NULL, NULL, NULL } + +#define CONFIG_SYS_FPGA_NO_RFL_HI + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 2 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_bus_freq(0) + +#define CONFIG_SYS_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} + +#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x4500) +#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x4600) + +/* Use the HUSH parser */ +#define CONFIG_SYS_HUSH_PARSER + +/* Pass open firmware flat tree */ +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_STDOUT_VIA_ALIAS 1 + +/* I2C */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_FSL +#define CONFIG_SYS_FSL_I2C_SPEED 400000 +#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F +#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000 + +#define CONFIG_PCA953X /* NXP PCA9554 */ +#define CONFIG_PCA9698 /* NXP PCA9698 */ + +#define CONFIG_SYS_I2C_IHS +#define CONFIG_SYS_I2C_IHS_CH0 +#define CONFIG_SYS_I2C_IHS_SPEED_0 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_0 0x7F +#define CONFIG_SYS_I2C_IHS_CH1 +#define CONFIG_SYS_I2C_IHS_SPEED_1 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_1 0x7F +#define CONFIG_SYS_I2C_IHS_CH2 +#define CONFIG_SYS_I2C_IHS_SPEED_2 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_2 0x7F +#define CONFIG_SYS_I2C_IHS_CH3 +#define CONFIG_SYS_I2C_IHS_SPEED_3 50000 +#define CONFIG_SYS_I2C_IHS_SLAVE_3 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#define CONFIG_SYS_I2C_SOFT +#define CONFIG_SOFT_I2C_READ_REPEATED_START +#define CONFIG_SYS_I2C_SOFT_SPEED 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE 0x7F +#define I2C_SOFT_DECLARATIONS2 +#define CONFIG_SYS_I2C_SOFT_SPEED_2 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_2 0x7F +#define I2C_SOFT_DECLARATIONS3 +#define CONFIG_SYS_I2C_SOFT_SPEED_3 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_3 0x7F +#define I2C_SOFT_DECLARATIONS4 +#define CONFIG_SYS_I2C_SOFT_SPEED_4 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_4 0x7F +#ifdef CONFIG_STRIDER_CON +#define I2C_SOFT_DECLARATIONS5 +#define CONFIG_SYS_I2C_SOFT_SPEED_5 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_5 0x7F +#define I2C_SOFT_DECLARATIONS6 +#define CONFIG_SYS_I2C_SOFT_SPEED_6 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_6 0x7F +#define I2C_SOFT_DECLARATIONS7 +#define CONFIG_SYS_I2C_SOFT_SPEED_7 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_7 0x7F +#define I2C_SOFT_DECLARATIONS8 +#define CONFIG_SYS_I2C_SOFT_SPEED_8 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE_8 0x7F +#endif + +#ifdef CONFIG_STRIDER_CON +#define CONFIG_SYS_ICS8N3QV01_I2C {5, 6, 7, 8} +#define CONFIG_SYS_CH7301_I2C {5, 6, 7, 8} +#define CONFIG_SYS_ADV7611_I2C {5, 6, 7, 8} +#define CONFIG_SYS_DP501_I2C {1, 2, 3, 4} +#define CONFIG_STRIDER_FANS { {10, 0x4c}, {11, 0x4c}, \ + {12, 0x4c} } +#else +#define CONFIG_SYS_CH7301_I2C {1, 2, 3, 4} +#define CONFIG_SYS_ADV7611_I2C {1, 2, 3, 4} +#define CONFIG_SYS_DP501_I2C {1, 2, 3, 4} +#define CONFIG_STRIDER_FANS { {2, 0x18}, {3, 0x18}, \ + {4, 0x18} } +#endif + +#ifndef __ASSEMBLY__ +void fpga_gpio_set(unsigned int bus, int pin); +void fpga_gpio_clear(unsigned int bus, int pin); +int fpga_gpio_get(unsigned int bus, int pin); +#endif + +#ifdef CONFIG_STRIDER_CON +#define I2C_SDA_GPIO ((I2C_ADAP_HWNR > 3) ? 0x0200 : 0x0040) +#define I2C_SCL_GPIO ((I2C_ADAP_HWNR > 3) ? 0x0100 : 0x0020) +#define I2C_FPGA_IDX ((I2C_ADAP_HWNR > 3) ? \ + (I2C_ADAP_HWNR - 4) : I2C_ADAP_HWNR) +#else +#define I2C_SDA_GPIO 0x0040 +#define I2C_SCL_GPIO 0x0020 +#define I2C_FPGA_IDX I2C_ADAP_HWNR +#endif +#define I2C_ACTIVE { } +#define I2C_TRISTATE { } +#define I2C_READ \ + (fpga_gpio_get(I2C_FPGA_IDX, I2C_SDA_GPIO) ? 1 : 0) +#define I2C_SDA(bit) \ + do { \ + if (bit) \ + fpga_gpio_set(I2C_FPGA_IDX, I2C_SDA_GPIO); \ + else \ + fpga_gpio_clear(I2C_FPGA_IDX, I2C_SDA_GPIO); \ + } while (0) +#define I2C_SCL(bit) \ + do { \ + if (bit) \ + fpga_gpio_set(I2C_FPGA_IDX, I2C_SCL_GPIO); \ + else \ + fpga_gpio_clear(I2C_FPGA_IDX, I2C_SCL_GPIO); \ + } while (0) +#define I2C_DELAY udelay(25) /* 1/4 I2C clock duration */ + +/* + * Software (bit-bang) MII driver configuration + */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +#define CONFIG_BITBANGMII_MULTI + +/* + * OSD Setup + */ +#define CONFIG_SYS_OSD_SCREENS 1 +#define CONFIG_SYS_DP501_DIFFERENTIAL +#define CONFIG_SYS_DP501_VCAPCTRL0 0x01 /* DDR mode 0, DE for H/VSYNC */ + +/* + * General PCI + * Addresses are mapped 1-1. + */ +#define CONFIG_SYS_PCIE1_BASE 0xA0000000 +#define CONFIG_SYS_PCIE1_MEM_BASE 0xA0000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS 0xA0000000 +#define CONFIG_SYS_PCIE1_MEM_SIZE 0x10000000 +#define CONFIG_SYS_PCIE1_CFG_BASE 0xB0000000 +#define CONFIG_SYS_PCIE1_CFG_SIZE 0x01000000 +#define CONFIG_SYS_PCIE1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCIE1_IO_PHYS 0xB1000000 +#define CONFIG_SYS_PCIE1_IO_SIZE 0x00800000 + +/* enable PCIE clock */ +#define CONFIG_SYS_SCCR_PCIEXP1CM 1 + +#define CONFIG_PCI +#define CONFIG_PCI_INDIRECT_BRIDGE +#define CONFIG_PCIE + +#define CONFIG_PCI_PNP /* do pci plug-and-play */ + +#define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ +#define CONFIG_83XX_GENERIC_PCIE_REGISTER_HOSES 1 + +/* + * TSEC + */ +#define CONFIG_TSEC_ENET /* TSEC ethernet support */ +#define CONFIG_SYS_TSEC1_OFFSET 0x24000 +#define CONFIG_SYS_TSEC1 (CONFIG_SYS_IMMR+CONFIG_SYS_TSEC1_OFFSET) + +/* + * TSEC ethernet configuration + */ +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_TSEC1 +#define CONFIG_TSEC1_NAME "eTSEC0" +#define TSEC1_PHY_ADDR 1 +#define TSEC1_PHYIDX 0 +#define TSEC1_FLAGS 0 + +/* Options are: eTSEC[0-1] */ +#define CONFIG_ETHPRIME "eTSEC0" + +/* + * Environment + */ +#if 1 +#define CONFIG_ENV_IS_IN_FLASH 1 +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + \ + CONFIG_SYS_MONITOR_LEN) +#define CONFIG_ENV_SECT_SIZE 0x10000 /* 64K(one sector) for env */ +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE +#else +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x2000 /* 8KB */ +#endif + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/* + * Command line configuration. + */ +#define CONFIG_CMD_I2C +#define CONFIG_CMD_MII +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PING + +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_AUTO_COMPLETE /* add autocompletion support */ + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_LOAD_ADDR 0x2000000 /* default load address */ +#define CONFIG_SYS_HZ 1000 /* decrementer freq: 1ms ticks */ + +#undef CONFIG_ZERO_BOOTDELAY_CHECK /* ignore keypress on bootdelay==0 */ + +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ + +#define CONFIG_SYS_CONSOLE_INFO_QUIET + +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +/* + * For booting Linux, the board info and command line data + * have to be in the first 256 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_SYS_BOOTMAPSZ (256 << 20) /* Initial Memory map for Linux */ + +/* + * Core HID Setup + */ +#define CONFIG_SYS_HID0_INIT 0x000000000 +#define CONFIG_SYS_HID0_FINAL (HID0_ENABLE_MACHINE_CHECK | \ + HID0_ENABLE_INSTRUCTION_CACHE | \ + HID0_ENABLE_DYNAMIC_POWER_MANAGMENT) +#define CONFIG_SYS_HID2 HID2_HBE + +/* + * MMU Setup + */ + +/* DDR: cache cacheable */ +#define CONFIG_SYS_IBAT0L (CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | \ + BATL_MEMCOHERENCE) +#define CONFIG_SYS_IBAT0U (CONFIG_SYS_SDRAM_BASE | BATU_BL_128M | \ + BATU_VS | BATU_VP) +#define CONFIG_SYS_DBAT0L CONFIG_SYS_IBAT0L +#define CONFIG_SYS_DBAT0U CONFIG_SYS_IBAT0U + +/* IMMRBAR, PCI IO and FPGA: cache-inhibit and guarded */ +#define CONFIG_SYS_IBAT1L (CONFIG_SYS_IMMR | BATL_PP_RW | \ + BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) +#define CONFIG_SYS_IBAT1U (CONFIG_SYS_IMMR | BATU_BL_8M | BATU_VS | \ + BATU_VP) +#define CONFIG_SYS_DBAT1L CONFIG_SYS_IBAT1L +#define CONFIG_SYS_DBAT1U CONFIG_SYS_IBAT1U + +/* FLASH: icache cacheable, but dcache-inhibit and guarded */ +#define CONFIG_SYS_IBAT2L (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \ + BATL_MEMCOHERENCE) +#define CONFIG_SYS_IBAT2U (CONFIG_SYS_FLASH_BASE | BATU_BL_8M | \ + BATU_VS | BATU_VP) +#define CONFIG_SYS_DBAT2L (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \ + BATL_CACHEINHIBIT | \ + BATL_GUARDEDSTORAGE) +#define CONFIG_SYS_DBAT2U CONFIG_SYS_IBAT2U + +/* Stack in dcache: cacheable, no memory coherence */ +#define CONFIG_SYS_IBAT3L (CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW) +#define CONFIG_SYS_IBAT3U (CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \ + BATU_VS | BATU_VP) +#define CONFIG_SYS_DBAT3L CONFIG_SYS_IBAT3L +#define CONFIG_SYS_DBAT3U CONFIG_SYS_IBAT3U + +/* + * Environment Configuration + */ + +#define CONFIG_ENV_OVERWRITE + +#if defined(CONFIG_TSEC_ENET) +#define CONFIG_HAS_ETH0 +#endif + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_LOADADDR 800000 /* default location for tftp and bootm */ + +#define CONFIG_BOOTDELAY 5 /* -1 disables auto-boot */ + +#define CONFIG_HOSTNAME hrcon +#define CONFIG_ROOTPATH "/opt/nfsroot" +#define CONFIG_BOOTFILE "uImage" + +#define CONFIG_PREBOOT /* enable preboot variable */ + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "netdev=eth0\0" \ + "consoledev=ttyS1\0" \ + "u-boot=u-boot.bin\0" \ + "kernel_addr=1000000\0" \ + "fdt_addr=C00000\0" \ + "fdtfile=hrcon.dtb\0" \ + "load=tftp ${loadaddr} ${u-boot}\0" \ + "update=protect off " __stringify(CONFIG_SYS_MONITOR_BASE) \ + " +${filesize};era " __stringify(CONFIG_SYS_MONITOR_BASE)\ + " +${filesize};cp.b ${fileaddr} " \ + __stringify(CONFIG_SYS_MONITOR_BASE) " ${filesize}\0" \ + "upd=run load update\0" \ + +#define CONFIG_NFSBOOTCOMMAND \ + "setenv bootargs root=/dev/nfs rw " \ + "nfsroot=$serverip:$rootpath " \ + "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "tftp ${kernel_addr} $bootfile;" \ + "tftp ${fdt_addr} $fdtfile;" \ + "bootm ${kernel_addr} - ${fdt_addr}" + +#define CONFIG_MMCBOOTCOMMAND \ + "setenv bootargs root=/dev/mmcblk0p3 rw rootwait " \ + "console=$consoledev,$baudrate $othbootargs;" \ + "ext2load mmc 0:2 ${kernel_addr} $bootfile;" \ + "ext2load mmc 0:2 ${fdt_addr} $fdtfile;" \ + "bootm ${kernel_addr} - ${fdt_addr}" + +#define CONFIG_BOOTCOMMAND CONFIG_MMCBOOTCOMMAND + + +#endif /* __CONFIG_H */ diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index a005e6a2ac..32cc39bbe3 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -143,4 +143,6 @@ #define CONFIG_FAT_WRITE #endif +#define CONFIG_OF_SYSTEM_SETUP + #endif /* _TEGRA_COMMON_H_ */ diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index 32bb805f78..7810dd6c30 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -67,11 +67,6 @@ "rootfstype=${mmcrootfstype}\0" /* - * Default to a quick boot delay. - */ -#define CONFIG_BOOTDELAY 1 - -/* * DDR information. If the CONFIG_NR_DRAM_BANKS is not defined, * we say (for simplicity) that we have 1 bank, always, even when * we have more. We always start at 0x80000000, and we place the @@ -288,4 +283,6 @@ #define NETARGS "" #endif +#include <config_distro_defaults.h> + #endif /* __CONFIG_TI_ARMV7_COMMON_H__ */ diff --git a/include/configs/venice2.h b/include/configs/venice2.h index 0fc8cf7674..a374cd9488 100644 --- a/include/configs/venice2.h +++ b/include/configs/venice2.h @@ -60,6 +60,4 @@ #include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" -#define CONFIG_OF_BOARD_SETUP - #endif /* __CONFIG_H */ diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index 2be885079e..b0aa875f5e 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -35,7 +35,6 @@ #define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS #define CONFIG_PCI_IO_SIZE 0xefff -#define CONFIG_SYS_EARLY_PCI_INIT #define CONFIG_PCI_PNP #define CONFIG_BIOSEMU diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index faadab83ce..ab9fa0b082 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -155,9 +155,6 @@ */ #define CONFIG_SYS_X86_TSC_TIMER -#define CONFIG_SYS_PCAT_INTERRUPTS -#define CONFIG_SYS_PCAT_TIMER -#define CONFIG_SYS_NUM_IRQS 16 #define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE diff --git a/include/fastboot.h b/include/fastboot.h new file mode 100644 index 0000000000..db826d20bf --- /dev/null +++ b/include/fastboot.h @@ -0,0 +1,22 @@ +/* + * (C) Copyright 2008 - 2009 + * Windriver, <www.windriver.com> + * Tom Rix <Tom.Rix@windriver.com> + * + * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> + * + * Copyright 2014 Linaro, Ltd. + * Rob Herring <robh@kernel.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _FASTBOOT_H_ +#define _FASTBOOT_H_ + +/* The 64 defined bytes plus \0 */ +#define FASTBOOT_RESPONSE_LEN (64 + 1) + +void fastboot_fail(char *response, const char *reason); +void fastboot_okay(char *response, const char *reason); + +#endif /* _FASTBOOT_H_ */ diff --git a/include/fb_mmc.h b/include/fb_mmc.h index 402ba9b1b4..978a1395a1 100644 --- a/include/fb_mmc.h +++ b/include/fb_mmc.h @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ -void fb_mmc_flash_write(const char *cmd, void *download_buffer, - unsigned int download_bytes, char *response); +void fb_mmc_flash_write(const char *cmd, unsigned int session_id, + void *download_buffer, unsigned int download_bytes, + char *response); void fb_mmc_erase(const char *cmd, char *response); diff --git a/include/fb_nand.h b/include/fb_nand.h new file mode 100644 index 0000000000..80ddef5656 --- /dev/null +++ b/include/fb_nand.h @@ -0,0 +1,11 @@ +/* + * Copyright 2014 Broadcom Corporation. + * Copyright 2015 Free Electrons. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +void fb_nand_flash_write(const char *cmd, unsigned int session_id, + void *download_buffer, unsigned int download_bytes, + char *response); +void fb_nand_erase(const char *cmd, char *response); diff --git a/include/fdtdec.h b/include/fdtdec.h index 0e36664dca..3a6ff1f8ac 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -130,6 +130,7 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */ COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */ COMPAT_NVIDIA_TEGRA124_PCIE, /* Tegra 124 PCIe controller */ + COMPAT_NVIDIA_TEGRA210_PCIE, /* Tegra 210 PCIe controller */ COMPAT_NVIDIA_TEGRA30_PCIE, /* Tegra 30 PCIe controller */ COMPAT_NVIDIA_TEGRA20_PCIE, /* Tegra 20 PCIe controller */ COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h index 8a5efe732a..3b8762df66 100644 --- a/include/gdsys_fpga.h +++ b/include/gdsys_fpga.h @@ -143,7 +143,7 @@ struct ihs_fpga { u16 reserved_2[2]; /* 0x001c */ struct ihs_io_ep ep; /* 0x0020 */ u16 reserved_3[9]; /* 0x002e */ - struct ihs_i2c i2c; /* 0x0040 */ + struct ihs_i2c i2c0; /* 0x0040 */ u16 reserved_4[10]; /* 0x004c */ u16 mc_int; /* 0x0060 */ u16 mc_int_en; /* 0x0062 */ @@ -157,9 +157,9 @@ struct ihs_fpga { u16 mc_rx_data; /* 0x0072 */ u16 reserved_5[69]; /* 0x0074 */ u16 reflection_high; /* 0x00fe */ - struct ihs_osd osd; /* 0x0100 */ + struct ihs_osd osd0; /* 0x0100 */ u16 reserved_6[889]; /* 0x010e */ - u16 videomem[31736]; /* 0x0800 */ + u16 videomem0[2048]; /* 0x0800 */ }; #endif @@ -171,13 +171,15 @@ struct ihs_fpga { u16 fpga_features; /* 0x0006 */ u16 reserved_0[1]; /* 0x0008 */ u16 top_interrupt; /* 0x000a */ - u16 reserved_1[4]; /* 0x000c */ + u16 reserved_1[2]; /* 0x000c */ + u16 control; /* 0x0010 */ + u16 extended_control; /* 0x0012 */ struct ihs_gpio gpio; /* 0x0014 */ u16 mpc3w_control; /* 0x001a */ u16 reserved_2[2]; /* 0x001c */ struct ihs_io_ep ep; /* 0x0020 */ u16 reserved_3[9]; /* 0x002e */ - struct ihs_i2c i2c; /* 0x0040 */ + struct ihs_i2c i2c0; /* 0x0040 */ u16 reserved_4[10]; /* 0x004c */ u16 mc_int; /* 0x0060 */ u16 mc_int_en; /* 0x0062 */ @@ -191,9 +193,82 @@ struct ihs_fpga { u16 mc_rx_data; /* 0x0072 */ u16 reserved_5[69]; /* 0x0074 */ u16 reflection_high; /* 0x00fe */ - struct ihs_osd osd; /* 0x0100 */ + struct ihs_osd osd0; /* 0x0100 */ +#ifdef CONFIG_SYS_OSD_DH + u16 reserved_6[57]; /* 0x010e */ + struct ihs_osd osd1; /* 0x0180 */ + u16 reserved_7[9]; /* 0x018e */ + struct ihs_i2c i2c1; /* 0x01a0 */ + u16 reserved_8[1834]; /* 0x01ac */ + u16 videomem0[2048]; /* 0x1000 */ + u16 videomem1[2048]; /* 0x2000 */ +#else + u16 reserved_6[889]; /* 0x010e */ + u16 videomem0[2048]; /* 0x0800 */ +#endif +}; +#endif + +#ifdef CONFIG_STRIDER_CPU +struct ihs_fpga { + u16 reflection_low; /* 0x0000 */ + u16 versions; /* 0x0002 */ + u16 fpga_version; /* 0x0004 */ + u16 fpga_features; /* 0x0006 */ + u16 reserved_0[1]; /* 0x0008 */ + u16 top_interrupt; /* 0x000a */ + u16 reserved_1[3]; /* 0x000c */ + u16 extended_control; /* 0x0012 */ + struct ihs_gpio gpio; /* 0x0014 */ + u16 mpc3w_control; /* 0x001a */ + u16 reserved_2[2]; /* 0x001c */ + struct ihs_io_ep ep; /* 0x0020 */ + u16 reserved_3[9]; /* 0x002e */ + u16 mc_int; /* 0x0040 */ + u16 mc_int_en; /* 0x0042 */ + u16 mc_status; /* 0x0044 */ + u16 mc_control; /* 0x0046 */ + u16 mc_tx_data; /* 0x0048 */ + u16 mc_tx_address; /* 0x004a */ + u16 mc_tx_cmd; /* 0x004c */ + u16 mc_res; /* 0x004e */ + u16 mc_rx_cmd_status; /* 0x0050 */ + u16 mc_rx_data; /* 0x0052 */ + u16 reserved_4[62]; /* 0x0054 */ + struct ihs_i2c i2c0; /* 0x00d0 */ +}; +#endif + +#ifdef CONFIG_STRIDER_CON +struct ihs_fpga { + u16 reflection_low; /* 0x0000 */ + u16 versions; /* 0x0002 */ + u16 fpga_version; /* 0x0004 */ + u16 fpga_features; /* 0x0006 */ + u16 reserved_0[1]; /* 0x0008 */ + u16 top_interrupt; /* 0x000a */ + u16 reserved_1[4]; /* 0x000c */ + struct ihs_gpio gpio; /* 0x0014 */ + u16 mpc3w_control; /* 0x001a */ + u16 reserved_2[2]; /* 0x001c */ + struct ihs_io_ep ep; /* 0x0020 */ + u16 reserved_3[9]; /* 0x002e */ + struct ihs_i2c i2c0; /* 0x0040 */ + u16 reserved_4[10]; /* 0x004c */ + u16 mc_int; /* 0x0060 */ + u16 mc_int_en; /* 0x0062 */ + u16 mc_status; /* 0x0064 */ + u16 mc_control; /* 0x0066 */ + u16 mc_tx_data; /* 0x0068 */ + u16 mc_tx_address; /* 0x006a */ + u16 mc_tx_cmd; /* 0x006c */ + u16 mc_res; /* 0x006e */ + u16 mc_rx_cmd_status; /* 0x0070 */ + u16 mc_rx_data; /* 0x0072 */ + u16 reserved_5[70]; /* 0x0074 */ + struct ihs_osd osd0; /* 0x0100 */ u16 reserved_6[889]; /* 0x010e */ - u16 videomem[31736]; /* 0x0800 */ + u16 videomem0[2048]; /* 0x0800 */ }; #endif @@ -208,11 +283,13 @@ struct ihs_fpga { u16 reserved_1[29]; /* 0x001e */ u16 mpc3w_control; /* 0x0058 */ u16 reserved_2[3]; /* 0x005a */ - struct ihs_i2c i2c; /* 0x0060 */ - u16 reserved_3[205]; /* 0x0066 */ - struct ihs_osd osd; /* 0x0200 */ - u16 reserved_4[761]; /* 0x020e */ - u16 videomem[31736]; /* 0x0800 */ + struct ihs_i2c i2c0; /* 0x0060 */ + u16 reserved_3[2]; /* 0x006c */ + struct ihs_i2c i2c1; /* 0x0070 */ + u16 reserved_4[194]; /* 0x007c */ + struct ihs_osd osd0; /* 0x0200 */ + u16 reserved_5[761]; /* 0x020e */ + u16 videomem0[2048]; /* 0x0800 */ }; #endif diff --git a/include/grlib/apbuart.h b/include/grlib/apbuart.h new file mode 100644 index 0000000000..1e1eb9a77c --- /dev/null +++ b/include/grlib/apbuart.h @@ -0,0 +1,47 @@ +/* GRLIB APBUART definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_APBUART_H__ +#define __GRLIB_APBUART_H__ + +/* APBUART Register map */ +typedef struct { + volatile unsigned int data; + volatile unsigned int status; + volatile unsigned int ctrl; + volatile unsigned int scaler; +} ambapp_dev_apbuart; + +/* + * The following defines the bits in the LEON UART Status Registers. + */ + +#define APBUART_STATUS_DR 0x00000001 /* Data Ready */ +#define APBUART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ +#define APBUART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ +#define APBUART_STATUS_BR 0x00000008 /* Break Error */ +#define APBUART_STATUS_OE 0x00000010 /* RX Overrun Error */ +#define APBUART_STATUS_PE 0x00000020 /* RX Parity Error */ +#define APBUART_STATUS_FE 0x00000040 /* RX Framing Error */ +#define APBUART_STATUS_ERR 0x00000078 /* Error Mask */ + +/* + * The following defines the bits in the LEON UART Ctrl Registers. + */ + +#define APBUART_CTRL_RE 0x00000001 /* Receiver enable */ +#define APBUART_CTRL_TE 0x00000002 /* Transmitter enable */ +#define APBUART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ +#define APBUART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */ +#define APBUART_CTRL_PS 0x00000010 /* Parity select */ +#define APBUART_CTRL_PE 0x00000020 /* Parity enable */ +#define APBUART_CTRL_FL 0x00000040 /* Flow control enable */ +#define APBUART_CTRL_LB 0x00000080 /* Loop Back enable */ +#define APBUART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */ + +#endif diff --git a/include/grlib/gptimer.h b/include/grlib/gptimer.h new file mode 100644 index 0000000000..8b2b1651b0 --- /dev/null +++ b/include/grlib/gptimer.h @@ -0,0 +1,34 @@ +/* GRLIB GPTIMER (General Purpose Timer) definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_GPTIMER_H__ +#define __GRLIB_GPTIMER_H__ + +typedef struct { + volatile unsigned int val; + volatile unsigned int rld; + volatile unsigned int ctrl; + volatile unsigned int unused; +} ambapp_dev_gptimer_element; + +#define GPTIMER_CTRL_EN 0x1 /* Timer enable */ +#define GPTIMER_CTRL_RS 0x2 /* Timer reStart */ +#define GPTIMER_CTRL_LD 0x4 /* Timer reLoad */ +#define GPTIMER_CTRL_IE 0x8 /* interrupt enable */ +#define GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */ +#define GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */ + +typedef struct { + volatile unsigned int scalar; + volatile unsigned int scalar_reload; + volatile unsigned int config; + volatile unsigned int unused; + volatile ambapp_dev_gptimer_element e[8]; +} ambapp_dev_gptimer; + +#endif diff --git a/include/grlib/greth.h b/include/grlib/greth.h new file mode 100644 index 0000000000..89c1e49387 --- /dev/null +++ b/include/grlib/greth.h @@ -0,0 +1,87 @@ +/* Gaisler.com GRETH 10/100/1000 Ethernet MAC definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_GRETH_H__ +#define __GRLIB_GRETH_H__ + +#define GRETH_FD 0x10 +#define GRETH_RESET 0x40 +#define GRETH_MII_BUSY 0x8 +#define GRETH_MII_NVALID 0x10 + +/* MII registers */ +#define GRETH_MII_EXTADV_1000FD 0x00000200 +#define GRETH_MII_EXTADV_1000HD 0x00000100 +#define GRETH_MII_EXTPRT_1000FD 0x00000800 +#define GRETH_MII_EXTPRT_1000HD 0x00000400 + +#define GRETH_MII_100T4 0x00000200 +#define GRETH_MII_100TXFD 0x00000100 +#define GRETH_MII_100TXHD 0x00000080 +#define GRETH_MII_10FD 0x00000040 +#define GRETH_MII_10HD 0x00000020 + +#define GRETH_BD_EN 0x800 +#define GRETH_BD_WR 0x1000 +#define GRETH_BD_IE 0x2000 +#define GRETH_BD_LEN 0x7FF + +#define GRETH_TXEN 0x1 +#define GRETH_INT_TX 0x8 +#define GRETH_TXI 0x4 +#define GRETH_TXBD_STATUS 0x0001C000 +#define GRETH_TXBD_MORE 0x20000 +#define GRETH_TXBD_IPCS 0x40000 +#define GRETH_TXBD_TCPCS 0x80000 +#define GRETH_TXBD_UDPCS 0x100000 +#define GRETH_TXBD_ERR_LC 0x10000 +#define GRETH_TXBD_ERR_UE 0x4000 +#define GRETH_TXBD_ERR_AL 0x8000 +#define GRETH_TXBD_NUM 128 +#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1) +#define GRETH_TX_BUF_SIZE 2048 + +#define GRETH_INT_RX 0x4 +#define GRETH_RXEN 0x2 +#define GRETH_RXI 0x8 +#define GRETH_RXBD_STATUS 0xFFFFC000 +#define GRETH_RXBD_ERR_AE 0x4000 +#define GRETH_RXBD_ERR_FT 0x8000 +#define GRETH_RXBD_ERR_CRC 0x10000 +#define GRETH_RXBD_ERR_OE 0x20000 +#define GRETH_RXBD_ERR_LE 0x40000 +#define GRETH_RXBD_IP_DEC 0x80000 +#define GRETH_RXBD_IP_CSERR 0x100000 +#define GRETH_RXBD_UDP_DEC 0x200000 +#define GRETH_RXBD_UDP_CSERR 0x400000 +#define GRETH_RXBD_TCP_DEC 0x800000 +#define GRETH_RXBD_TCP_CSERR 0x1000000 + +#define GRETH_RXBD_NUM 128 +#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1) +#define GRETH_RX_BUF_SIZE 2048 + +/* Ethernet configuration registers */ +typedef struct _greth_regs { + volatile unsigned int control; + volatile unsigned int status; + volatile unsigned int esa_msb; + volatile unsigned int esa_lsb; + volatile unsigned int mdio; + volatile unsigned int tx_desc_p; + volatile unsigned int rx_desc_p; + volatile unsigned int edcl_ip; +} greth_regs; + +/* Ethernet buffer descriptor */ +typedef struct _greth_bd { + volatile unsigned int stat; + unsigned int addr; /* Buffer address not changed by HW */ +} greth_bd; + +#endif diff --git a/include/grlib/irqmp.h b/include/grlib/irqmp.h new file mode 100644 index 0000000000..0354d5c21c --- /dev/null +++ b/include/grlib/irqmp.h @@ -0,0 +1,23 @@ +/* GRLIB IRQMP (IRQ Multi-processor controller) definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_IRQMP_H__ +#define __GRLIB_IRQMP_H__ + +typedef struct { + volatile unsigned int ilevel; + volatile unsigned int ipend; + volatile unsigned int iforce; + volatile unsigned int iclear; + volatile unsigned int mstatus; + volatile unsigned int notused[11]; + volatile unsigned int cpu_mask[16]; + volatile unsigned int cpu_force[16]; +} ambapp_dev_irqmp; + +#endif diff --git a/include/aboot.h b/include/image-sparse.h index 30e4d36df8..0382f5bd26 100644 --- a/include/aboot.h +++ b/include/image-sparse.h @@ -9,8 +9,16 @@ #define ROUNDUP(x, y) (((x) + ((y) - 1)) & ~((y) - 1)) -void fastboot_fail(const char *s); -void fastboot_okay(const char *s); +typedef struct sparse_storage { + unsigned int block_sz; + unsigned int start; + unsigned int size; + const char *name; + + int (*write)(struct sparse_storage *storage, void *priv, + unsigned int offset, unsigned int size, + char *data); +} sparse_storage_t; static inline int is_sparse_image(void *buf) { @@ -23,6 +31,5 @@ static inline int is_sparse_image(void *buf) return 0; } -void write_sparse_image(block_dev_desc_t *dev_desc, - disk_partition_t *info, const char *part_name, - void *data, unsigned sz); +int store_sparse_image(sparse_storage_t *storage, void *storage_priv, + unsigned int session_id, void *data); diff --git a/include/linux/mtd/concat.h b/include/linux/mtd/concat.h index 195a4a5426..a374ca98e8 100644 --- a/include/linux/mtd/concat.h +++ b/include/linux/mtd/concat.h @@ -1,9 +1,10 @@ /* * MTD device concatenation layer definitions * - * (C) 2002 Robert Kaiser <rkaiser@sysgo.de> + * Copyright © 2002 Robert Kaiser <rkaiser@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ * - * This code is GPL */ #ifndef MTD_CONCAT_H diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h index ba29d53ec6..a3cfe6bdd9 100644 --- a/include/linux/mtd/doc2000.h +++ b/include/linux/mtd/doc2000.h @@ -1,12 +1,13 @@ /* * Linux driver for Disk-On-Chip devices * - * Copyright (C) 1999 Machine Vision Holdings, Inc. - * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org> - * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com> - * Copyright (C) 2002-2003 SnapGear Inc + * Copyright © 1999 Machine Vision Holdings, Inc. + * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> + * Copyright © 2002-2003 Greg Ungerer <gerg@snapgear.com> + * Copyright © 2002-2003 SnapGear Inc + * + * SPDX-License-Identifier: GPL-2.0+ * - * Released under GPL */ #ifndef __MTD_DOC2000_H__ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index c2cd3df1fa..9da77ec144 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -1,7 +1,7 @@ /* * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al. * - * Released under GPL + * SPDX-License-Identifier: GPL-2.0+ * */ diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h index 090da50542..02ba9f7e63 100644 --- a/include/linux/mtd/nand_ecc.h +++ b/include/linux/mtd/nand_ecc.h @@ -1,11 +1,11 @@ /* * drivers/mtd/nand_ecc.h * - * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com> + * David Woodhouse <dwmw2@infradead.org> + * Thomas Gleixner <tglx@linutronix.de> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0 * * This file is the header for the ECC algorithm. */ diff --git a/include/part.h b/include/part.h index 8ea9b3049a..8b5ac12e2b 100644 --- a/include/part.h +++ b/include/part.h @@ -93,6 +93,9 @@ typedef struct disk_partition { #ifdef CONFIG_PARTITION_UUIDS char uuid[37]; /* filesystem UUID as string, if exists */ #endif +#ifdef CONFIG_PARTITION_TYPE_GUID + char type_guid[37]; /* type GUID as string, if exists */ +#endif } disk_partition_t; /* Misc _get_dev functions */ diff --git a/include/part_efi.h b/include/part_efi.h index 3012b91ade..c8fc8738f9 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -43,6 +43,9 @@ #define PARTITION_BASIC_DATA_GUID \ EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \ 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7) +#define PARTITION_LINUX_FILE_SYSTEM_DATA_GUID \ + EFI_GUID(0x0FC63DAF, 0x8483, 0x4772, \ + 0x8E, 0x79, 0x3D, 0x69, 0xD8, 0x47, 0x7D, 0xE4) #define PARTITION_LINUX_RAID_GUID \ EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \ 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e) diff --git a/include/spi_flash.h b/include/spi_flash.h index 0ae0062d12..f25b3e7819 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -237,7 +237,7 @@ static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, static inline int spi_flash_protect(struct spi_flash *flash, u32 ofs, u32 len, bool prot) { - if (!flash->flash_lock) + if (!flash->flash_lock || !flash->flash_unlock) return -EOPNOTSUPP; if (prot) diff --git a/include/uuid.h b/include/uuid.h index 93027c1b28..c3f423fab4 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -36,6 +36,10 @@ enum { int uuid_str_valid(const char *uuid); int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format); void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format); +#ifdef CONFIG_PARTITION_TYPE_GUID +int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin); +int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str); +#endif void gen_rand_uuid(unsigned char *uuid_bin); void gen_rand_uuid_str(char *uuid_str, int str_format); #endif diff --git a/lib/fdtdec.c b/lib/fdtdec.c index c1b517706d..f1849bcd37 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -36,6 +36,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"), COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"), COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"), + COMPAT(NVIDIA_TEGRA210_PCIE, "nvidia,tegra210-pcie"), COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"), COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"), COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"), diff --git a/lib/uuid.c b/lib/uuid.c index f6b4423551..c8584edcb8 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -80,10 +80,65 @@ int uuid_str_valid(const char *uuid) return 1; } +#ifdef CONFIG_PARTITION_TYPE_GUID +static const struct { + const char *string; + efi_guid_t guid; +} list_guid[] = { + {"system", PARTITION_SYSTEM_GUID}, + {"mbr", LEGACY_MBR_PARTITION_GUID}, + {"msft", PARTITION_MSFT_RESERVED_GUID}, + {"data", PARTITION_BASIC_DATA_GUID}, + {"linux", PARTITION_LINUX_FILE_SYSTEM_DATA_GUID}, + {"raid", PARTITION_LINUX_RAID_GUID}, + {"swap", PARTITION_LINUX_SWAP_GUID}, + {"lvm", PARTITION_LINUX_LVM_GUID} +}; + +/* + * uuid_guid_get_bin() - this function get GUID bin for string + * + * @param guid_str - pointer to partition type string + * @param guid_bin - pointer to allocated array for big endian output [16B] + */ +int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(list_guid); i++) { + if (!strcmp(list_guid[i].string, guid_str)) { + memcpy(guid_bin, &list_guid[i].guid, 16); + return 0; + } + } + return -ENODEV; +} + +/* + * uuid_guid_get_str() - this function get string for GUID. + * + * @param guid_bin - pointer to string with partition type guid [16B] + * @param guid_str - pointer to allocated partition type string [7B] + */ +int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str) +{ + int i; + + *guid_str = 0; + for (i = 0; i < ARRAY_SIZE(list_guid); i++) { + if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) { + strcpy(guid_str, list_guid[i].string); + return 0; + } + } + return -ENODEV; +} +#endif + /* * uuid_str_to_bin() - convert string UUID or GUID to big endian binary data. * - * @param uuid_str - pointer to UUID or GUID string [37B] + * @param uuid_str - pointer to UUID or GUID string [37B] or GUID shorcut * @param uuid_bin - pointer to allocated array for big endian output [16B] * @str_format - UUID string format: 0 - UUID; 1 - GUID */ @@ -93,8 +148,13 @@ int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format) uint32_t tmp32; uint64_t tmp64; - if (!uuid_str_valid(uuid_str)) + if (!uuid_str_valid(uuid_str)) { +#ifdef CONFIG_PARTITION_TYPE_GUID + if (!uuid_guid_get_bin(uuid_str, uuid_bin)) + return 0; +#endif return -EINVAL; + } if (str_format == UUID_STR_FORMAT_STD) { tmp32 = cpu_to_be32(simple_strtoul(uuid_str, NULL, 16)); diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index dd235b9d7a..8f690eb70c 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -56,6 +56,7 @@ libs-y += common/init/ libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/ libs-y += drivers/ +libs-y += dts/ libs-y += fs/ libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/ libs-$(CONFIG_SPL_POST_MEM_SUPPORT) += post/drivers/ diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 368a20e2cc..4707dfd18e 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -62,7 +62,7 @@ my %commit_author_hash; my %commit_signer_hash; my @penguin_chief = (); -push(@penguin_chief, "Tom Rini:trini\@ti.com"); +push(@penguin_chief, "Tom Rini:trini\@konsulko.com"); my @penguin_chief_names = (); foreach my $chief (@penguin_chief) { |