From: Tom Rini Date: Wed, 13 Jan 2016 23:27:40 +0000 (-0500) Subject: Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze X-Git-Tag: KARO-TXSD-2017-03-15~2319 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=20d08f59fa7cdde0da1eb7aca7915c91dbdeaf51;hp=fc82edd8440721aadf3bfc784f29a513ad7680be;p=karo-tx-uboot.git Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze --- diff --git a/arch/arm/dts/am4372.dtsi b/arch/arm/dts/am4372.dtsi index 3fffe1eec3..c95d1d3b35 100644 --- a/arch/arm/dts/am4372.dtsi +++ b/arch/arm/dts/am4372.dtsi @@ -25,6 +25,7 @@ serial0 = &uart0; ethernet0 = &cpsw_emac0; ethernet1 = &cpsw_emac1; + spi0 = &qspi; }; cpus { @@ -908,7 +909,9 @@ qspi: qspi@47900000 { compatible = "ti,am4372-qspi"; - reg = <0x47900000 0x100>; + reg = <0x47900000 0x100>, + <0x30000000 0x4000000>; + reg-names = "qspi_base", "qspi_mmap"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "qspi"; diff --git a/arch/arm/dts/am437x-sk-evm.dts b/arch/arm/dts/am437x-sk-evm.dts index 3f9d808091..89feaf3eb7 100644 --- a/arch/arm/dts/am437x-sk-evm.dts +++ b/arch/arm/dts/am437x-sk-evm.dts @@ -567,7 +567,7 @@ spi-max-frequency = <48000000>; m25p80@0 { - compatible = "mx66l51235l"; + compatible = "mx66l51235l","spi-flash"; spi-max-frequency = <48000000>; reg = <0>; spi-cpol; diff --git a/arch/arm/dts/dra7-evm.dts b/arch/arm/dts/dra7-evm.dts index e4daa991e9..797d411d6f 100644 --- a/arch/arm/dts/dra7-evm.dts +++ b/arch/arm/dts/dra7-evm.dts @@ -487,7 +487,7 @@ spi-max-frequency = <48000000>; m25p80@0 { - compatible = "s25fl256s1"; + compatible = "s25fl256s1","spi-flash"; spi-max-frequency = <48000000>; reg = <0>; spi-tx-bus-width = <1>; diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi index feb3708dc6..e7fecf7656 100644 --- a/arch/arm/dts/dra7.dtsi +++ b/arch/arm/dts/dra7.dtsi @@ -41,6 +41,7 @@ ethernet1 = &cpsw_emac1; d_can0 = &dcan1; d_can1 = &dcan2; + spi0 = &qspi; }; timer { @@ -1113,8 +1114,11 @@ qspi: qspi@4b300000 { compatible = "ti,dra7xxx-qspi"; - reg = <0x4b300000 0x100>; - reg-names = "qspi_base"; + reg = <0x4b300000 0x100>, + <0x5c000000 0x4000000>, + <0x4a002558 0x4>; + reg-names = "qspi_base", "qspi_mmap", + "qspi_ctrlmod"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "qspi"; diff --git a/arch/arm/dts/dra72-evm.dts b/arch/arm/dts/dra72-evm.dts index efb544c6bb..a62550f0e0 100644 --- a/arch/arm/dts/dra72-evm.dts +++ b/arch/arm/dts/dra72-evm.dts @@ -604,7 +604,7 @@ spi-max-frequency = <48000000>; m25p80@0 { - compatible = "s25fl256s1"; + compatible = "s25fl256s1","spi-flash"; spi-max-frequency = <48000000>; reg = <0>; spi-tx-bus-width = <1>; diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index b703c3c1f2..1cc4a96bf4 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -11,7 +11,6 @@ else obj-$(CONFIG_ROCKCHIP_RK3288) += board.o endif obj-y += rk_timer.o -obj-y += rk_early_print.o obj-$(CONFIG_$(SPL_)ROCKCHIP_COMMON) += common.o obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/ obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/ diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c index 3a1491cab3..801548109b 100644 --- a/arch/arm/mach-rockchip/rk3036-board-spl.c +++ b/arch/arm/mach-rockchip/rk3036-board-spl.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -34,7 +35,7 @@ void board_init_f(ulong dummy) GPIO1C2_MASK << GPIO1C2_SHIFT, GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT | GPIO1C2_UART2_SIN << GPIO1C2_SHIFT); - rk_uart_init((void *)DEBUG_UART_BASE); + debug_uart_init(); #endif rockchip_timer_init(); sdram_init(); @@ -53,3 +54,9 @@ void board_init_r(gd_t *id, ulong dest_addr) while (1) ; } + +void hang(void) +{ + while (1) + ; +} diff --git a/arch/arm/mach-rockchip/rk_early_print.c b/arch/arm/mach-rockchip/rk_early_print.c deleted file mode 100644 index a1c14b0210..0000000000 --- a/arch/arm/mach-rockchip/rk_early_print.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * (C) Copyright 2015 Rockchip Electronics Co., Ltd - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -static struct rk_uart *uart_ptr; - -static void uart_wrtie_byte(char byte) -{ - writel(byte, &uart_ptr->rbr); - while (!(readl(&uart_ptr->lsr) & 0x40)) - ; -} - -void print(char *s) -{ - while (*s) { - if (*s == '\n') - uart_wrtie_byte('\r'); - uart_wrtie_byte(*s); - s++; - } -} - -void print_hex(unsigned int n) -{ - int i; - int temp; - - uart_wrtie_byte('0'); - uart_wrtie_byte('x'); - - for (i = 8; i > 0; i--) { - temp = (n >> (i - 1) * 4) & 0x0f; - if (temp < 10) - uart_wrtie_byte((char)(temp + '0')); - else - uart_wrtie_byte((char)(temp - 10 + 'a')); - } - uart_wrtie_byte('\n'); - uart_wrtie_byte('\r'); -} - -/* - * TODO: since rk3036 only 4K sram to use in SPL, for saving space, - * we implement uart driver this way, we should convert this to use - * ns16550 driver in future, which support DEBUG_UART in the standard way - */ -void rk_uart_init(void *base) -{ - uart_ptr = (struct rk_uart *)base; - writel(0x83, &uart_ptr->lcr); - writel(0x0d, &uart_ptr->rbr); - writel(0x03, &uart_ptr->lcr); - - /* fifo enable, sfe is shadow register of FCR[0] */ - writel(0x01, &uart_ptr->sfe); -} diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index fbfb204e6e..48a387c957 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -3,6 +3,7 @@ if TEGRA config TEGRA_COMMON bool "Tegra common options" select DM + select DM_ETH select DM_GPIO select DM_I2C select DM_KEYBOARD diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index 9e6ac3a0ff..03256be403 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -70,8 +70,17 @@ config CMD_PINMON config CMD_DDRPHY_DUMP bool "Enable dump command of DDR PHY parameters" + depends on ARCH_UNIPHIER_PH1_LD4 || ARCH_UNIPHIER_PH1_PRO4 || \ + ARCH_UNIPHIER_PH1_SLD8 help The command "ddrphy" shows the resulting parameters of DDR PHY training; it is useful for the evaluation of DDR PHY training. +config CMD_DDRMPHY_DUMP + bool "Enable dump command of DDR Multi PHY parameters" + depends on ARCH_UNIPHIER_PROXSTREAM2 || ARCH_UNIPHIER_PH1_LD6B + help + The command "ddrmphy" shows the resulting parameters of DDR Multi PHY + training; it is useful for the evaluation of DDR Multi PHY training. + endif diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile index 5b19f93ea9..ea3ae5425e 100644 --- a/arch/arm/mach-uniphier/Makefile +++ b/arch/arm/mach-uniphier/Makefile @@ -24,8 +24,6 @@ obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o obj-y += reset.o obj-y += cache_uniphier.o -obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o -obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o obj-y += pinctrl/ clk/ diff --git a/arch/arm/mach-uniphier/include/mach/arm-mpcore.h b/arch/arm/mach-uniphier/arm-mpcore.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/arm-mpcore.h rename to arch/arm/mach-uniphier/arm-mpcore.h diff --git a/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c b/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c index e9d3761fde..f82c7d1f8e 100644 --- a/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c +++ b/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "bcu-regs.h" #define ch(x) ((x) >= 32 ? 0 : (x) < 0 ? 0x11111111 : 0x11111111 << (x)) diff --git a/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c b/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c index cb6f862721..75ccd155b0 100644 --- a/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c +++ b/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "bcu-regs.h" #define ch(x) ((x) >= 32 ? 0 : (x) < 0 ? 0x11111111 : 0x11111111 << (x)) diff --git a/arch/arm/mach-uniphier/include/mach/bcu-regs.h b/arch/arm/mach-uniphier/bcu/bcu-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/bcu-regs.h rename to arch/arm/mach-uniphier/bcu/bcu-regs.h diff --git a/arch/arm/mach-uniphier/board_common.c b/arch/arm/mach-uniphier/board_common.c index 198004b59b..020ffcae1d 100644 --- a/arch/arm/mach-uniphier/board_common.c +++ b/arch/arm/mach-uniphier/board_common.c @@ -5,7 +5,8 @@ */ #include -#include + +#include "micro-support-card.h" int board_init(void) { diff --git a/arch/arm/mach-uniphier/board_early_init_f.c b/arch/arm/mach-uniphier/board_early_init_f.c index 5e0d246ce4..824da25ac7 100644 --- a/arch/arm/mach-uniphier/board_early_init_f.c +++ b/arch/arm/mach-uniphier/board_early_init_f.c @@ -4,9 +4,9 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include -#include -#include +#include "init.h" +#include "micro-support-card.h" +#include "soc-info.h" int board_early_init_f(void) { diff --git a/arch/arm/mach-uniphier/board_early_init_r.c b/arch/arm/mach-uniphier/board_early_init_r.c index 28c7f82228..b26da3633f 100644 --- a/arch/arm/mach-uniphier/board_early_init_r.c +++ b/arch/arm/mach-uniphier/board_early_init_r.c @@ -5,7 +5,8 @@ */ #include -#include + +#include "micro-support-card.h" int board_early_init_r(void) { diff --git a/arch/arm/mach-uniphier/boards.c b/arch/arm/mach-uniphier/boards.c index d075a11ca2..f12415022b 100644 --- a/arch/arm/mach-uniphier/boards.c +++ b/arch/arm/mach-uniphier/boards.c @@ -7,7 +7,8 @@ #include #include #include -#include + +#include "init.h" DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/mach-uniphier/boot-mode/Makefile b/arch/arm/mach-uniphier/boot-mode/Makefile index 0797d6e615..be0de8f9a9 100644 --- a/arch/arm/mach-uniphier/boot-mode/Makefile +++ b/arch/arm/mach-uniphier/boot-mode/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += boot-mode-ph1-ld4.o obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += boot-mode-ph1-pro5.o obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += boot-mode-proxstream2.o obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += boot-mode-proxstream2.o + +obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o diff --git a/arch/arm/mach-uniphier/include/mach/boot-device.h b/arch/arm/mach-uniphier/boot-mode/boot-device.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/boot-device.h rename to arch/arm/mach-uniphier/boot-mode/boot-device.h diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c index f974d9f08d..8334373f08 100644 --- a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c @@ -7,9 +7,9 @@ #include #include #include -#include -#include -#include + +#include "../sg-regs.h" +#include "boot-device.h" struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"}, diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-pro5.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-pro5.c index c68cb59fc0..0ec6a08879 100644 --- a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-pro5.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-pro5.c @@ -7,9 +7,9 @@ #include #include #include -#include -#include -#include + +#include "../sg-regs.h" +#include "boot-device.h" static struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 5)"}, diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c index c943e12db1..b0f3f9a805 100644 --- a/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c @@ -7,9 +7,9 @@ #include #include #include -#include -#include -#include + +#include "../sg-regs.h" +#include "boot-device.h" static struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, "Reserved"}, diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c index 10a47c6fcc..de12953585 100644 --- a/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c @@ -7,10 +7,9 @@ #include #include #include -#include -#include -#include -#include + +#include "../sg-regs.h" +#include "boot-device.h" static struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"}, diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode.c index c6cafa7919..0c5749badb 100644 --- a/arch/arm/mach-uniphier/boot-mode/boot-mode.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode.c @@ -6,10 +6,10 @@ #include #include -#include -#include -#include -#include + +#include "../sbc/sbc-regs.h" +#include "../soc-info.h" +#include "boot-device.h" u32 spl_boot_device(void) { diff --git a/arch/arm/mach-uniphier/cmd_pinmon.c b/arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c similarity index 93% rename from arch/arm/mach-uniphier/cmd_pinmon.c rename to arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c index b15ee9dd60..3ff756b7dd 100644 --- a/arch/arm/mach-uniphier/cmd_pinmon.c +++ b/arch/arm/mach-uniphier/boot-mode/cmd_pinmon.c @@ -5,9 +5,10 @@ */ #include -#include -#include -#include + +#include "../sbc/sbc-regs.h" +#include "../soc-info.h" +#include "boot-device.h" static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/arch/arm/mach-uniphier/cache_uniphier.c b/arch/arm/mach-uniphier/cache_uniphier.c index bf85ad6fd9..b4ca8b6934 100644 --- a/arch/arm/mach-uniphier/cache_uniphier.c +++ b/arch/arm/mach-uniphier/cache_uniphier.c @@ -7,7 +7,8 @@ #include #include #include -#include + +#include "ssc-regs.h" #ifdef CONFIG_UNIPHIER_L2CACHE_ON static void uniphier_cache_maint_all(u32 operation) diff --git a/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c b/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c index 8b95fbb008..4de9bfb102 100644 --- a/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c +++ b/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" void ph1_ld4_clk_init(void) { diff --git a/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c b/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c index 2e1b20a423..3df017edd2 100644 --- a/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c +++ b/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" void ph1_pro4_clk_init(void) { diff --git a/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c b/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c index f78edbbe3f..039da737d0 100644 --- a/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c +++ b/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" void ph1_pro5_clk_init(void) { diff --git a/arch/arm/mach-uniphier/clk/clk-proxstream2.c b/arch/arm/mach-uniphier/clk/clk-proxstream2.c index b494021ecf..a528f048f7 100644 --- a/arch/arm/mach-uniphier/clk/clk-proxstream2.c +++ b/arch/arm/mach-uniphier/clk/clk-proxstream2.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" void proxstream2_clk_init(void) { diff --git a/arch/arm/mach-uniphier/cmd_ddrmphy.c b/arch/arm/mach-uniphier/cmd_ddrmphy.c new file mode 100644 index 0000000000..c18f099f2c --- /dev/null +++ b/arch/arm/mach-uniphier/cmd_ddrmphy.c @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#include "../init.h" +#include "ddrmphy-regs.h" + +/* Select either decimal or hexadecimal */ +#if 1 +#define PRINTF_FORMAT "%2d" +#else +#define PRINTF_FORMAT "%02x" +#endif +/* field separator */ +#define FS " " + +static void __iomem *get_phy_base(int ch) +{ + return (void __iomem *)(0x5b830000 + ch * 0x00200000); +} + +static int get_nr_ch(void) +{ + const struct uniphier_board_data *bd = uniphier_get_board_param(); + + return bd->dram_ch2_width ? 3 : 2; +} + +static int get_nr_datx8(int ch) +{ + unsigned int width; + + const struct uniphier_board_data *bd = uniphier_get_board_param(); + + switch (ch) { + case 0: + width = bd->dram_ch0_width; + break; + case 1: + width = bd->dram_ch1_width; + break; + default: + width = bd->dram_ch2_width; + break; + } + + return width / 8; +} + +static void print_bdl(void __iomem *reg, int n) +{ + u32 val = readl(reg); + int i; + + for (i = 0; i < n; i++) + printf(FS PRINTF_FORMAT, (val >> i * 8) & 0x1f); +} + +static void dump_loop(void (*callback)(void __iomem *)) +{ + int ch, dx, nr_ch, nr_dx; + void __iomem *dx_base; + + nr_ch = get_nr_ch(); + + for (ch = 0; ch < nr_ch; ch++) { + dx_base = get_phy_base(ch) + DMPHY_DX_BASE; + nr_dx = get_nr_datx8(ch); + + for (dx = 0; dx < nr_dx; dx++) { + printf("CH%dDX%d:", ch, dx); + (*callback)(dx_base); + dx_base += DMPHY_DX_STRIDE; + printf("\n"); + } + } +} + +static void zq_dump(void) +{ + int ch, zq, nr_ch, nr_zq, i; + void __iomem *zq_base; + u32 dr, pr; + + printf("\n--- Impedance Data ---\n"); + printf(" ZPD ZPU OPD OPU ZDV ODV\n"); + + nr_ch = get_nr_ch(); + + for (ch = 0; ch < nr_ch; ch++) { + zq_base = get_phy_base(ch) + DMPHY_ZQ_BASE; + nr_zq = 3; + + for (zq = 0; zq < nr_zq; zq++) { + printf("CH%dZQ%d:", ch, zq); + + dr = readl(zq_base + DMPHY_ZQ_DR); + for (i = 0; i < 4; i++) { + printf(FS PRINTF_FORMAT, dr & 0x7f); + dr >>= 7; + } + + pr = readl(zq_base + DMPHY_ZQ_PR); + for (i = 0; i < 2; i++) { + printf(FS PRINTF_FORMAT, pr & 0xf); + pr >>= 4; + } + + zq_base += DMPHY_ZQ_STRIDE; + printf("\n"); + } + } +} + +static void __wbdl_dump(void __iomem *dx_base) +{ + print_bdl(dx_base + DMPHY_DX_BDLR0, 4); + print_bdl(dx_base + DMPHY_DX_BDLR1, 4); + print_bdl(dx_base + DMPHY_DX_BDLR2, 2); + + printf(FS "(+" PRINTF_FORMAT ")", + readl(dx_base + DMPHY_DX_LCDLR1) & 0xff); +} + +static void wbdl_dump(void) +{ + printf("\n--- Write Bit Delay Line ---\n"); + printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n"); + + dump_loop(&__wbdl_dump); +} + +static void __rbdl_dump(void __iomem *dx_base) +{ + print_bdl(dx_base + DMPHY_DX_BDLR3, 4); + print_bdl(dx_base + DMPHY_DX_BDLR4, 4); + print_bdl(dx_base + DMPHY_DX_BDLR5, 1); + + printf(FS "(+" PRINTF_FORMAT ")", + (readl(dx_base + DMPHY_DX_LCDLR1) >> 8) & 0xff); + + printf(FS "(+" PRINTF_FORMAT ")", + (readl(dx_base + DMPHY_DX_LCDLR1) >> 16) & 0xff); +} + +static void rbdl_dump(void) +{ + printf("\n--- Read Bit Delay Line ---\n"); + printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD) (RDQSND)\n"); + + dump_loop(&__rbdl_dump); +} + +static void __wld_dump(void __iomem *dx_base) +{ + int rank; + u32 lcdlr0 = readl(dx_base + DMPHY_DX_LCDLR0); + u32 gtr = readl(dx_base + DMPHY_DX_GTR); + + for (rank = 0; rank < 4; rank++) { + u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */ + u32 wlsl = (gtr >> (12 + 2 * rank)) & 0x3; /* System Latency */ + + printf(FS PRINTF_FORMAT "%sT", wld, + wlsl == 0 ? "-1" : wlsl == 1 ? "+0" : "+1"); + } +} + +static void wld_dump(void) +{ + printf("\n--- Write Leveling Delay ---\n"); + printf(" Rank0 Rank1 Rank2 Rank3\n"); + + dump_loop(&__wld_dump); +} + +static void __dqsgd_dump(void __iomem *dx_base) +{ + int rank; + u32 lcdlr2 = readl(dx_base + DMPHY_DX_LCDLR2); + u32 gtr = readl(dx_base + DMPHY_DX_GTR); + + for (rank = 0; rank < 4; rank++) { + u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */ + u32 dgsl = (gtr >> (3 * rank)) & 0x7; /* System Latency */ + + printf(FS PRINTF_FORMAT "+%dT", dqsgd, dgsl); + } +} + +static void dqsgd_dump(void) +{ + printf("\n--- DQS Gating Delay ---\n"); + printf(" Rank0 Rank1 Rank2 Rank3\n"); + + dump_loop(&__dqsgd_dump); +} + +static void __mdl_dump(void __iomem *dx_base) +{ + int i; + u32 mdl = readl(dx_base + DMPHY_DX_MDLR); + + for (i = 0; i < 3; i++) + printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff); +} + +static void mdl_dump(void) +{ + printf("\n--- Master Delay Line ---\n"); + printf(" IPRD TPRD MDLD\n"); + + dump_loop(&__mdl_dump); +} + +#define REG_DUMP(x) \ + { int ofst = DMPHY_ ## x; void __iomem *reg = phy_base + ofst; \ + printf("%3d: %-10s: %p : %08x\n", \ + ofst >> DMPHY_SHIFT, #x, reg, readl(reg)); } + +#define DX_REG_DUMP(dx, x) \ + { int ofst = DMPHY_DX_BASE + DMPHY_DX_STRIDE * (dx) + \ + DMPHY_DX_## x; \ + void __iomem *reg = phy_base + ofst; \ + printf("%3d: DX%d%-7s: %p : %08x\n", \ + ofst >> DMPHY_SHIFT, (dx), #x, reg, readl(reg)); } + +static void reg_dump(void) +{ + int ch, dx, nr_ch, nr_dx; + void __iomem *phy_base; + + printf("\n--- DDR PHY registers ---\n"); + + nr_ch = get_nr_ch(); + + for (ch = 0; ch < nr_ch; ch++) { + phy_base = get_phy_base(ch); + nr_dx = get_nr_datx8(ch); + + printf("== Ch%d ==\n", ch); + printf(" No: Name : Address : Data\n"); + + REG_DUMP(RIDR); + REG_DUMP(PIR); + REG_DUMP(PGCR0); + REG_DUMP(PGCR1); + REG_DUMP(PGCR2); + REG_DUMP(PGCR3); + REG_DUMP(PGSR0); + REG_DUMP(PGSR1); + REG_DUMP(PLLCR); + REG_DUMP(PTR0); + REG_DUMP(PTR1); + REG_DUMP(PTR2); + REG_DUMP(PTR3); + REG_DUMP(PTR4); + REG_DUMP(ACMDLR); + REG_DUMP(ACBDLR0); + REG_DUMP(DXCCR); + REG_DUMP(DSGCR); + REG_DUMP(DCR); + REG_DUMP(DTPR0); + REG_DUMP(DTPR1); + REG_DUMP(DTPR2); + REG_DUMP(DTPR3); + REG_DUMP(MR0); + REG_DUMP(MR1); + REG_DUMP(MR2); + REG_DUMP(MR3); + + for (dx = 0; dx < nr_dx; dx++) { + DX_REG_DUMP(dx, GCR0); + DX_REG_DUMP(dx, GCR1); + DX_REG_DUMP(dx, GCR2); + DX_REG_DUMP(dx, GCR3); + DX_REG_DUMP(dx, GTR); + } + } +} + +static int do_ddrm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *cmd = argv[1]; + + if (argc == 1) + cmd = "all"; + + if (!strcmp(cmd, "zq") || !strcmp(cmd, "all")) + zq_dump(); + + if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all")) + wbdl_dump(); + + if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all")) + rbdl_dump(); + + if (!strcmp(cmd, "wld") || !strcmp(cmd, "all")) + wld_dump(); + + if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all")) + dqsgd_dump(); + + if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all")) + mdl_dump(); + + if (!strcmp(cmd, "reg") || !strcmp(cmd, "all")) + reg_dump(); + + return 0; +} + +U_BOOT_CMD( + ddrm, 2, 1, do_ddrm, + "UniPhier DDR PHY parameters dumper", + "- dump all of the followings\n" + "ddrm zq - dump Impedance Data\n" + "ddrm wbdl - dump Write Bit Delay\n" + "ddrm rbdl - dump Read Bit Delay\n" + "ddrm wld - dump Write Leveling\n" + "ddrm dqsgd - dump DQS Gating Delay\n" + "ddrm mdl - dump Master Delay Line\n" + "ddrm reg - dump registers\n" +); diff --git a/arch/arm/mach-uniphier/cpu_info.c b/arch/arm/mach-uniphier/cpu_info.c index 935b209fa1..4e9d01bafd 100644 --- a/arch/arm/mach-uniphier/cpu_info.c +++ b/arch/arm/mach-uniphier/cpu_info.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "sg-regs.h" int print_cpuinfo(void) { diff --git a/arch/arm/mach-uniphier/debug_ll.S b/arch/arm/mach-uniphier/debug_ll.S index d8c9fe43e3..6aa5f897a1 100644 --- a/arch/arm/mach-uniphier/debug_ll.S +++ b/arch/arm/mach-uniphier/debug_ll.S @@ -8,9 +8,10 @@ #include #include -#include -#include -#include + +#include "bcu/bcu-regs.h" +#include "sc-regs.h" +#include "sg-regs.h" #if !defined(CONFIG_DEBUG_SEMIHOSTING) #include CONFIG_DEBUG_LL_INCLUDE diff --git a/arch/arm/mach-uniphier/dram/Makefile b/arch/arm/mach-uniphier/dram/Makefile index d3a767b525..cab7df1653 100644 --- a/arch/arm/mach-uniphier/dram/Makefile +++ b/arch/arm/mach-uniphier/dram/Makefile @@ -8,3 +8,8 @@ obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += umc-ph1-pro4.o \ ddrphy-training.o ddrphy-ph1-pro4.o obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += umc-ph1-sld8.o \ ddrphy-training.o ddrphy-ph1-sld8.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += umc-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += umc-proxstream2.o + +obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o +obj-$(CONFIG_CMD_DDRMPHY_DUMP) += cmd_ddrmphy.o diff --git a/arch/arm/mach-uniphier/cmd_ddrphy.c b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c similarity index 99% rename from arch/arm/mach-uniphier/cmd_ddrphy.c rename to arch/arm/mach-uniphier/dram/cmd_ddrphy.c index f9b79ab3d9..078eb6f71b 100644 --- a/arch/arm/mach-uniphier/cmd_ddrphy.c +++ b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "ddrphy-regs.h" /* Select either decimal or hexadecimal */ #if 1 diff --git a/arch/arm/mach-uniphier/dram/ddrmphy-regs.h b/arch/arm/mach-uniphier/dram/ddrmphy-regs.h new file mode 100644 index 0000000000..569504d657 --- /dev/null +++ b/arch/arm/mach-uniphier/dram/ddrmphy-regs.h @@ -0,0 +1,146 @@ +/* + * UniPhier DDR MultiPHY registers + * + * Copyright (C) 2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARCH_DDRMPHY_REGS_H +#define ARCH_DDRMPHY_REGS_H + +#include + +#define DMPHY_SHIFT 2 + +#define DMPHY_RIDR (0x000 << DMPHY_SHIFT) +#define DMPHY_PIR (0x001 << DMPHY_SHIFT) +#define DMPHY_PIR_INIT BIT(0) /* Initialization Trigger */ +#define DMPHY_PIR_ZCAL BIT(1) /* Impedance Calibration */ +#define DMPHY_PIR_PLLINIT BIT(4) /* PLL Initialization */ +#define DMPHY_PIR_DCAL BIT(5) /* DDL Calibration */ +#define DMPHY_PIR_PHYRST BIT(6) /* PHY Reset */ +#define DMPHY_PIR_DRAMRST BIT(7) /* DRAM Reset */ +#define DMPHY_PIR_DRAMINIT BIT(8) /* DRAM Initialization */ +#define DMPHY_PIR_WL BIT(9) /* Write Leveling */ +#define DMPHY_PIR_QSGATE BIT(10) /* Read DQS Gate Training */ +#define DMPHY_PIR_WLADJ BIT(11) /* Write Leveling Adjust */ +#define DMPHY_PIR_RDDSKW BIT(12) /* Read Data Bit Deskew */ +#define DMPHY_PIR_WRDSKW BIT(13) /* Write Data Bit Deskew */ +#define DMPHY_PIR_RDEYE BIT(14) /* Read Data Eye Training */ +#define DMPHY_PIR_WREYE BIT(15) /* Write Data Eye Training */ +#define DMPHY_PIR_ZCALBYP BIT(30) /* Impedance Calib Bypass */ +#define DMPHY_PIR_INITBYP BIT(31) /* Initialization Bypass */ +#define DMPHY_PGCR0 (0x002 << DMPHY_SHIFT) +#define DMPHY_PGCR0_PHYFRST BIT(26) /* PHY FIFO Reset */ +#define DMPHY_PGCR1 (0x003 << DMPHY_SHIFT) +#define DMPHY_PGCR1_INHVT BIT(26) /* VT Calculation Inhibit */ +#define DMPHY_PGCR2 (0x004 << DMPHY_SHIFT) +#define DMPHY_PGCR2_DUALCHN BIT(28) /* Dual Channel Configuration*/ +#define DMPHY_PGCR2_ACPDDC BIT(29) /* AC Power-Down with Dual Ch*/ +#define DMPHY_PGCR3 (0x005 << DMPHY_SHIFT) +#define DMPHY_PGSR0 (0x006 << DMPHY_SHIFT) +#define DMPHY_PGSR0_IDONE BIT(0) /* Initialization Done */ +#define DMPHY_PGSR0_PLDONE BIT(1) /* PLL Lock Done */ +#define DMPHY_PGSR0_DCDONE BIT(2) /* DDL Calibration Done */ +#define DMPHY_PGSR0_ZCDONE BIT(3) /* Impedance Calibration Done */ +#define DMPHY_PGSR0_DIDONE BIT(4) /* DRAM Initialization Done */ +#define DMPHY_PGSR0_WLDONE BIT(5) /* Write Leveling Done */ +#define DMPHY_PGSR0_QSGDONE BIT(6) /* DQS Gate Training Done */ +#define DMPHY_PGSR0_WLADONE BIT(7) /* Write Leveling Adjust Done */ +#define DMPHY_PGSR0_RDDONE BIT(8) /* Read Bit Deskew Done */ +#define DMPHY_PGSR0_WDDONE BIT(9) /* Write Bit Deskew Done */ +#define DMPHY_PGSR0_REDONE BIT(10) /* Read Eye Training Done */ +#define DMPHY_PGSR0_WEDONE BIT(11) /* Write Eye Training Done */ +#define DMPHY_PGSR0_ZCERR BIT(20) /* Impedance Calib Error */ +#define DMPHY_PGSR0_WLERR BIT(21) /* Write Leveling Error */ +#define DMPHY_PGSR0_QSGERR BIT(22) /* DQS Gate Training Error */ +#define DMPHY_PGSR0_WLAERR BIT(23) /* Write Leveling Adj Error */ +#define DMPHY_PGSR0_RDERR BIT(24) /* Read Bit Deskew Error */ +#define DMPHY_PGSR0_WDERR BIT(25) /* Write Bit Deskew Error */ +#define DMPHY_PGSR0_REERR BIT(26) /* Read Eye Training Error */ +#define DMPHY_PGSR0_WEERR BIT(27) /* Write Eye Training Error */ +#define DMPHY_PGSR1 (0x007 << DMPHY_SHIFT) +#define DMPHY_PGSR1_VTSTOP BIT(30) /* VT Stop */ +#define DMPHY_PLLCR (0x008 << DMPHY_SHIFT) +#define DMPHY_PTR0 (0x009 << DMPHY_SHIFT) +#define DMPHY_PTR1 (0x00A << DMPHY_SHIFT) +#define DMPHY_PTR2 (0x00B << DMPHY_SHIFT) +#define DMPHY_PTR3 (0x00C << DMPHY_SHIFT) +#define DMPHY_PTR4 (0x00D << DMPHY_SHIFT) +#define DMPHY_ACMDLR (0x00E << DMPHY_SHIFT) +#define DMPHY_ACLCDLR (0x00F << DMPHY_SHIFT) +#define DMPHY_ACBDLR0 (0x010 << DMPHY_SHIFT) +#define DMPHY_ACBDLR1 (0x011 << DMPHY_SHIFT) +#define DMPHY_ACBDLR2 (0x012 << DMPHY_SHIFT) +#define DMPHY_ACBDLR3 (0x013 << DMPHY_SHIFT) +#define DMPHY_ACBDLR4 (0x014 << DMPHY_SHIFT) +#define DMPHY_ACBDLR5 (0x015 << DMPHY_SHIFT) +#define DMPHY_ACBDLR6 (0x016 << DMPHY_SHIFT) +#define DMPHY_ACBDLR7 (0x017 << DMPHY_SHIFT) +#define DMPHY_ACBDLR8 (0x018 << DMPHY_SHIFT) +#define DMPHY_ACBDLR9 (0x019 << DMPHY_SHIFT) +#define DMPHY_ACIOCR0 (0x01A << DMPHY_SHIFT) +#define DMPHY_ACIOCR1 (0x01B << DMPHY_SHIFT) +#define DMPHY_ACIOCR2 (0x01C << DMPHY_SHIFT) +#define DMPHY_ACIOCR3 (0x01D << DMPHY_SHIFT) +#define DMPHY_ACIOCR4 (0x01E << DMPHY_SHIFT) +#define DMPHY_ACIOCR5 (0x01F << DMPHY_SHIFT) +#define DMPHY_DXCCR (0x020 << DMPHY_SHIFT) +#define DMPHY_DSGCR (0x021 << DMPHY_SHIFT) +#define DMPHY_DCR (0x022 << DMPHY_SHIFT) +#define DMPHY_DTPR0 (0x023 << DMPHY_SHIFT) +#define DMPHY_DTPR1 (0x024 << DMPHY_SHIFT) +#define DMPHY_DTPR2 (0x025 << DMPHY_SHIFT) +#define DMPHY_DTPR3 (0x026 << DMPHY_SHIFT) +#define DMPHY_MR0 (0x027 << DMPHY_SHIFT) +#define DMPHY_MR1 (0x028 << DMPHY_SHIFT) +#define DMPHY_MR2 (0x029 << DMPHY_SHIFT) +#define DMPHY_MR3 (0x02A << DMPHY_SHIFT) +#define DMPHY_ODTCR (0x02B << DMPHY_SHIFT) +#define DMPHY_DTCR (0x02C << DMPHY_SHIFT) +#define DMPHY_DTCR_RANKEN_SHIFT 24 /* Rank Enable */ +#define DMPHY_DTCR_RANKEN_MASK (0xf << (DMPHY_DTCR_RANKEN_SHIFT)) +#define DMPHY_DTAR0 (0x02D << DMPHY_SHIFT) +#define DMPHY_DTAR1 (0x02E << DMPHY_SHIFT) +#define DMPHY_DTAR2 (0x02F << DMPHY_SHIFT) +#define DMPHY_DTAR3 (0x030 << DMPHY_SHIFT) +#define DMPHY_DTDR0 (0x031 << DMPHY_SHIFT) +#define DMPHY_DTDR1 (0x032 << DMPHY_SHIFT) +#define DMPHY_DTEDR0 (0x033 << DMPHY_SHIFT) +#define DMPHY_DTEDR1 (0x034 << DMPHY_SHIFT) +#define DMPHY_ZQCR (0x090 << DMPHY_SHIFT) +#define DMPHY_ZQCR_AVGEN BIT(16) /* Average Algorithm */ +#define DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE BIT(27) /* force VT update */ +/* ZQ */ +#define DMPHY_ZQ_BASE (0x091 << DMPHY_SHIFT) +#define DMPHY_ZQ_STRIDE (0x004 << DMPHY_SHIFT) +#define DMPHY_ZQ_PR (0x000 << DMPHY_SHIFT) +#define DMPHY_ZQ_DR (0x001 << DMPHY_SHIFT) +#define DMPHY_ZQ_SR (0x002 << DMPHY_SHIFT) +/* DATX8 */ +#define DMPHY_DX_BASE (0x0A0 << DMPHY_SHIFT) +#define DMPHY_DX_STRIDE (0x020 << DMPHY_SHIFT) +#define DMPHY_DX_GCR0 (0x000 << DMPHY_SHIFT) +#define DMPHY_DX_GCR0_WLRKEN_SHIFT 26 /* Write Level Rank Enable */ +#define DMPHY_DX_GCR0_WLRKEN_MASK (0xf << (DMPHY_DX_GCR0_WLRKEN_SHIFT)) +#define DMPHY_DX_GCR1 (0x001 << DMPHY_SHIFT) +#define DMPHY_DX_GCR2 (0x002 << DMPHY_SHIFT) +#define DMPHY_DX_GCR3 (0x003 << DMPHY_SHIFT) +#define DMPHY_DX_GSR0 (0x004 << DMPHY_SHIFT) +#define DMPHY_DX_GSR1 (0x005 << DMPHY_SHIFT) +#define DMPHY_DX_GSR2 (0x006 << DMPHY_SHIFT) +#define DMPHY_DX_BDLR0 (0x007 << DMPHY_SHIFT) +#define DMPHY_DX_BDLR1 (0x008 << DMPHY_SHIFT) +#define DMPHY_DX_BDLR2 (0x009 << DMPHY_SHIFT) +#define DMPHY_DX_BDLR3 (0x00A << DMPHY_SHIFT) +#define DMPHY_DX_BDLR4 (0x00B << DMPHY_SHIFT) +#define DMPHY_DX_BDLR5 (0x00C << DMPHY_SHIFT) +#define DMPHY_DX_BDLR6 (0x00D << DMPHY_SHIFT) +#define DMPHY_DX_LCDLR0 (0x00E << DMPHY_SHIFT) +#define DMPHY_DX_LCDLR1 (0x00F << DMPHY_SHIFT) +#define DMPHY_DX_LCDLR2 (0x010 << DMPHY_SHIFT) +#define DMPHY_DX_MDLR (0x011 << DMPHY_SHIFT) +#define DMPHY_DX_GTR (0x012 << DMPHY_SHIFT) + +#endif /* ARCH_DDRMPHY_REGS_H */ diff --git a/arch/arm/mach-uniphier/dram/ddrphy-ph1-ld4.c b/arch/arm/mach-uniphier/dram/ddrphy-ph1-ld4.c index 991d9294fd..d2bc5a15d4 100644 --- a/arch/arm/mach-uniphier/dram/ddrphy-ph1-ld4.c +++ b/arch/arm/mach-uniphier/dram/ddrphy-ph1-ld4.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "ddrphy-regs.h" int ph1_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { diff --git a/arch/arm/mach-uniphier/dram/ddrphy-ph1-pro4.c b/arch/arm/mach-uniphier/dram/ddrphy-ph1-pro4.c index bc47ba3280..2c8cbc2579 100644 --- a/arch/arm/mach-uniphier/dram/ddrphy-ph1-pro4.c +++ b/arch/arm/mach-uniphier/dram/ddrphy-ph1-pro4.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "ddrphy-regs.h" int ph1_pro4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { diff --git a/arch/arm/mach-uniphier/dram/ddrphy-ph1-sld8.c b/arch/arm/mach-uniphier/dram/ddrphy-ph1-sld8.c index 39024a09d5..651069073c 100644 --- a/arch/arm/mach-uniphier/dram/ddrphy-ph1-sld8.c +++ b/arch/arm/mach-uniphier/dram/ddrphy-ph1-sld8.c @@ -7,7 +7,8 @@ #include #include #include -#include + +#include "ddrphy-regs.h" int ph1_sld8_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { diff --git a/arch/arm/mach-uniphier/include/mach/ddrphy-regs.h b/arch/arm/mach-uniphier/dram/ddrphy-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/ddrphy-regs.h rename to arch/arm/mach-uniphier/dram/ddrphy-regs.h diff --git a/arch/arm/mach-uniphier/dram/ddrphy-training.c b/arch/arm/mach-uniphier/dram/ddrphy-training.c index 4852f2dec8..a3481363fe 100644 --- a/arch/arm/mach-uniphier/dram/ddrphy-training.c +++ b/arch/arm/mach-uniphier/dram/ddrphy-training.c @@ -7,7 +7,8 @@ #include #include #include -#include + +#include "ddrphy-regs.h" void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank) { diff --git a/arch/arm/mach-uniphier/dram/umc-ph1-ld4.c b/arch/arm/mach-uniphier/dram/umc-ph1-ld4.c index 81246850b3..ffd7aa97b2 100644 --- a/arch/arm/mach-uniphier/dram/umc-ph1-ld4.c +++ b/arch/arm/mach-uniphier/dram/umc-ph1-ld4.c @@ -8,9 +8,10 @@ #include #include #include -#include -#include -#include + +#include "../init.h" +#include "ddrphy-regs.h" +#include "umc-regs.h" static void umc_start_ssif(void __iomem *ssif_base) { diff --git a/arch/arm/mach-uniphier/dram/umc-ph1-pro4.c b/arch/arm/mach-uniphier/dram/umc-ph1-pro4.c index 8c9f0579fc..4d976e3a97 100644 --- a/arch/arm/mach-uniphier/dram/umc-ph1-pro4.c +++ b/arch/arm/mach-uniphier/dram/umc-ph1-pro4.c @@ -8,9 +8,10 @@ #include #include #include -#include -#include -#include + +#include "../init.h" +#include "ddrphy-regs.h" +#include "umc-regs.h" static void umc_start_ssif(void __iomem *ssif_base) { diff --git a/arch/arm/mach-uniphier/dram/umc-ph1-sld8.c b/arch/arm/mach-uniphier/dram/umc-ph1-sld8.c index bc60a3472e..09f9ccfb43 100644 --- a/arch/arm/mach-uniphier/dram/umc-ph1-sld8.c +++ b/arch/arm/mach-uniphier/dram/umc-ph1-sld8.c @@ -8,9 +8,10 @@ #include #include #include -#include -#include -#include + +#include "../init.h" +#include "ddrphy-regs.h" +#include "umc-regs.h" static void umc_start_ssif(void __iomem *ssif_base) { diff --git a/arch/arm/mach-uniphier/dram/umc-proxstream2.c b/arch/arm/mach-uniphier/dram/umc-proxstream2.c new file mode 100644 index 0000000000..63a84e68c0 --- /dev/null +++ b/arch/arm/mach-uniphier/dram/umc-proxstream2.c @@ -0,0 +1,669 @@ +/* + * Copyright (C) 2015 Masahiro Yamada + * + * based on commit 21b6e480f92ccc38fe0502e3116411d6509d3bf2 of Diag by: + * Copyright (C) 2015 Socionext Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#include "../init.h" +#include "../soc-info.h" +#include "ddrmphy-regs.h" + +/* UM registers */ +#define UMC_MBUS0 0x00080004 +#define UMC_MBUS1 0x00081004 +#define UMC_MBUS2 0x00082004 +#define UMC_MBUS3 0x00083004 + +/* UD registers */ +#define UMC_BITPERPIXELMODE_D0 0x010 +#define UMC_PAIR1DOFF_D0 0x054 + +/* DC registers */ +#define UMC_INITSET 0x014 +#define UMC_INITSTAT 0x018 +#define UMC_CMDCTLA 0x000 +#define UMC_CMDCTLB 0x004 +#define UMC_SPCCTLA 0x030 +#define UMC_SPCCTLB 0x034 +#define UMC_SPCSETB 0x03c +#define UMC_SPCSETB_AREFMD_MASK (0x3) /* Auto Refresh Mode */ +#define UMC_SPCSETB_AREFMD_ARB (0x0) /* control by arbitor */ +#define UMC_SPCSETB_AREFMD_CONT (0x1) /* control by DRAMCONT */ +#define UMC_SPCSETB_AREFMD_REG (0x2) /* control by register */ +#define UMC_ACSSETA 0x060 +#define UMC_FLOWCTLA 0x400 +#define UMC_FLOWCTLB 0x404 +#define UMC_FLOWCTLC 0x408 +#define UMC_FLOWCTLG 0x508 +#define UMC_FLOWCTLOB0 0x520 +#define UMC_FLOWCTLOB1 0x524 +#define UMC_RDATACTL_D0 0x600 +#define UMC_RDATACTL_RADLTY_SHIFT 4 +#define UMC_RDATACTL_RADLTY_MASK (0xf << (UMC_RDATACTL_RADLTY_SHIFT)) +#define UMC_RDATACTL_RAD2LTY_SHIFT 8 +#define UMC_RDATACTL_RAD2LTY_MASK (0xf << (UMC_RDATACTL_RAD2LTY_SHIFT)) +#define UMC_WDATACTL_D0 0x604 +#define UMC_RDATACTL_D1 0x608 +#define UMC_WDATACTL_D1 0x60c +#define UMC_DATASET 0x610 +#define UMC_RESPCTL 0x624 +#define UMC_DCCGCTL 0x720 +#define UMC_ERRMASKA 0x958 +#define UMC_ERRMASKB 0x95c +#define UMC_BSICMAPSET 0x988 +#define UMC_DIOCTLA 0xc00 +#define UMC_DIOCTLA_CTL_NRST BIT(8) /* ctl_rst_n */ +#define UMC_DIOCTLA_CFG_NRST BIT(0) /* cfg_rst_n */ +#define UMC_DFICUPDCTLA 0xc20 + +enum dram_freq { + FREQ_1866M, + FREQ_2133M, + FREQ_NR, +}; + +enum dram_size { + SIZE_0, + SIZE_512M, + SIZE_1G, + SIZE_NR, +}; + +static u32 ddrphy_pgcr2[FREQ_NR] = {0x00FC7E5D, 0x00FC90AB}; +static u32 ddrphy_ptr0[FREQ_NR] = {0x0EA09205, 0x10C0A6C6}; +static u32 ddrphy_ptr1[FREQ_NR] = {0x0DAC041B, 0x0FA104B1}; +static u32 ddrphy_ptr3[FREQ_NR] = {0x15171e45, 0x18182357}; +static u32 ddrphy_ptr4[FREQ_NR] = {0x0e9ad8e9, 0x10b34157}; +static u32 ddrphy_dtpr0[FREQ_NR] = {0x35a00d88, 0x39e40e88}; +static u32 ddrphy_dtpr1[FREQ_NR] = {0x2288cc2c, 0x228a04d0}; +static u32 ddrphy_dtpr2[FREQ_NR] = {0x50005e00, 0x50006a00}; +static u32 ddrphy_dtpr3[FREQ_NR] = {0x0010cb49, 0x0010ec89}; +static u32 ddrphy_mr0[FREQ_NR] = {0x00000115, 0x00000125}; +static u32 ddrphy_mr2[FREQ_NR] = {0x000002a0, 0x000002a8}; + +static u32 umc_cmdctla[FREQ_NR] = {0x66DD131D, 0x77EE1722}; +/* + * The ch2 is a different generation UMC core. + * The register spec is different, unfortunately. + */ +static u32 umc_cmdctlb_ch01[FREQ_NR] = {0x13E87C44, 0x18F88C44}; +static u32 umc_cmdctlb_ch2[FREQ_NR] = {0x19E8DC44, 0x1EF8EC44}; +static u32 umc_spcctla[FREQ_NR][SIZE_NR] = { + {0x00000000, 0x004A071D, 0x0078071D}, + {0x00000000, 0x0055081E, 0x0089081E}, +}; + +static u32 umc_spcctlb[] = {0x00FF000A, 0x00FF000B}; +/* The ch2 is different for some reason only hardware guys know... */ +static u32 umc_flowctla_ch01[] = {0x0800001E, 0x08000022}; +static u32 umc_flowctla_ch2[] = {0x0800001E, 0x0800001E}; + +/* DDR multiPHY */ +static inline int ddrphy_get_rank(int dx) +{ + return dx / 2; +} + +static void ddrphy_fifo_reset(void __iomem *phy_base) +{ + u32 tmp; + + tmp = readl(phy_base + DMPHY_PGCR0); + tmp &= ~DMPHY_PGCR0_PHYFRST; + writel(tmp, phy_base + DMPHY_PGCR0); + + udelay(1); + + tmp |= DMPHY_PGCR0_PHYFRST; + writel(tmp, phy_base + DMPHY_PGCR0); + + udelay(1); +} + +static void ddrphy_vt_ctrl(void __iomem *phy_base, int enable) +{ + u32 tmp; + + tmp = readl(phy_base + DMPHY_PGCR1); + + if (enable) + tmp &= ~DMPHY_PGCR1_INHVT; + else + tmp |= DMPHY_PGCR1_INHVT; + + writel(tmp, phy_base + DMPHY_PGCR1); + + if (!enable) { + while (!(readl(phy_base + DMPHY_PGSR1) & DMPHY_PGSR1_VTSTOP)) + cpu_relax(); + } +} + +static void ddrphy_dqs_delay_fixup(void __iomem *phy_base, int nr_dx, int step) +{ + int dx; + u32 lcdlr1, rdqsd; + void __iomem *dx_base = phy_base + DMPHY_DX_BASE; + + ddrphy_vt_ctrl(phy_base, 0); + + for (dx = 0; dx < nr_dx; dx++) { + lcdlr1 = readl(dx_base + DMPHY_DX_LCDLR1); + rdqsd = (lcdlr1 >> 8) & 0xff; + rdqsd = clamp(rdqsd + step, 0U, 0xffU); + lcdlr1 = (lcdlr1 & ~(0xff << 8)) | (rdqsd << 8); + writel(lcdlr1, dx_base + DMPHY_DX_LCDLR1); + readl(dx_base + DMPHY_DX_LCDLR1); /* relax */ + dx_base += DMPHY_DX_STRIDE; + } + + ddrphy_vt_ctrl(phy_base, 1); +} + +static int ddrphy_get_system_latency(void __iomem *phy_base, int width) +{ + void __iomem *dx_base = phy_base + DMPHY_DX_BASE; + const int nr_dx = width / 8; + int dx, rank; + u32 gtr; + int dgsl, dgsl_min = INT_MAX, dgsl_max = 0; + + for (dx = 0; dx < nr_dx; dx++) { + gtr = readl(dx_base + DMPHY_DX_GTR); + for (rank = 0; rank < 4; rank++) { + dgsl = gtr & 0x7; + /* if dgsl is zero, this rank was not trained. skip. */ + if (dgsl) { + dgsl_min = min(dgsl_min, dgsl); + dgsl_max = max(dgsl_max, dgsl); + } + gtr >>= 3; + } + dx_base += DMPHY_DX_STRIDE; + } + + if (dgsl_min != dgsl_max) + printf("DQS Gateing System Latencies are not all leveled.\n"); + + return dgsl_max; +} + +static void ddrphy_init(void __iomem *phy_base, enum dram_freq freq, int width) +{ + u32 tmp; + void __iomem *zq_base, *dx_base; + int zq, dx; + int nr_dx; + + nr_dx = width / 8; + + writel(DMPHY_PIR_ZCALBYP, phy_base + DMPHY_PIR); + /* + * Disable RGLVT bit (Read DQS Gating LCDL Delay VT Compensation) + * to avoid read error issue. + */ + writel(0x07d81e37, phy_base + DMPHY_PGCR0); + writel(0x0200c4e0, phy_base + DMPHY_PGCR1); + + tmp = ddrphy_pgcr2[freq]; + if (width >= 32) + tmp |= DMPHY_PGCR2_DUALCHN | DMPHY_PGCR2_ACPDDC; + writel(tmp, phy_base + DMPHY_PGCR2); + + writel(ddrphy_ptr0[freq], phy_base + DMPHY_PTR0); + writel(ddrphy_ptr1[freq], phy_base + DMPHY_PTR1); + writel(0x00083def, phy_base + DMPHY_PTR2); + writel(ddrphy_ptr3[freq], phy_base + DMPHY_PTR3); + writel(ddrphy_ptr4[freq], phy_base + DMPHY_PTR4); + + writel(0x55555555, phy_base + DMPHY_ACIOCR1); + writel(0x00000000, phy_base + DMPHY_ACIOCR2); + writel(0x55555555, phy_base + DMPHY_ACIOCR3); + writel(0x00000000, phy_base + DMPHY_ACIOCR4); + writel(0x00000055, phy_base + DMPHY_ACIOCR5); + writel(0x00181aa4, phy_base + DMPHY_DXCCR); + + writel(0x0024641e, phy_base + DMPHY_DSGCR); + writel(0x0000040b, phy_base + DMPHY_DCR); + writel(ddrphy_dtpr0[freq], phy_base + DMPHY_DTPR0); + writel(ddrphy_dtpr1[freq], phy_base + DMPHY_DTPR1); + writel(ddrphy_dtpr2[freq], phy_base + DMPHY_DTPR2); + writel(ddrphy_dtpr3[freq], phy_base + DMPHY_DTPR3); + writel(ddrphy_mr0[freq], phy_base + DMPHY_MR0); + writel(0x00000006, phy_base + DMPHY_MR1); + writel(ddrphy_mr2[freq], phy_base + DMPHY_MR2); + writel(0x00000000, phy_base + DMPHY_MR3); + + tmp = 0; + for (dx = 0; dx < nr_dx; dx++) + tmp |= BIT(DMPHY_DTCR_RANKEN_SHIFT + ddrphy_get_rank(dx)); + writel(0x90003087 | tmp, phy_base + DMPHY_DTCR); + + writel(0x00000000, phy_base + DMPHY_DTAR0); + writel(0x00000008, phy_base + DMPHY_DTAR1); + writel(0x00000010, phy_base + DMPHY_DTAR2); + writel(0x00000018, phy_base + DMPHY_DTAR3); + writel(0xdd22ee11, phy_base + DMPHY_DTDR0); + writel(0x7788bb44, phy_base + DMPHY_DTDR1); + + /* impedance control settings */ + writel(0x04048900, phy_base + DMPHY_ZQCR); + + zq_base = phy_base + DMPHY_ZQ_BASE; + for (zq = 0; zq < 4; zq++) { + /* + * board-dependent + * PXS2: CH0ZQ0=0x5B, CH1ZQ0=0x5B, CH2ZQ0=0x59, others=0x5D + */ + writel(0x0007BB5D, zq_base + DMPHY_ZQ_PR); + zq_base += DMPHY_ZQ_STRIDE; + } + + /* DATX8 settings */ + dx_base = phy_base + DMPHY_DX_BASE; + for (dx = 0; dx < 4; dx++) { + tmp = readl(dx_base + DMPHY_DX_GCR0); + tmp &= ~DMPHY_DX_GCR0_WLRKEN_MASK; + tmp |= BIT(DMPHY_DX_GCR0_WLRKEN_SHIFT + ddrphy_get_rank(dx)) & + DMPHY_DX_GCR0_WLRKEN_MASK; + writel(tmp, dx_base + DMPHY_DX_GCR0); + + writel(0x00000000, dx_base + DMPHY_DX_GCR1); + writel(0x00000000, dx_base + DMPHY_DX_GCR2); + writel(0x00000000, dx_base + DMPHY_DX_GCR3); + dx_base += DMPHY_DX_STRIDE; + } + + while (!(readl(phy_base + DMPHY_PGSR0) & DMPHY_PGSR0_IDONE)) + cpu_relax(); + + ddrphy_dqs_delay_fixup(phy_base, nr_dx, -4); +} + +struct ddrphy_init_sequence { + char *description; + u32 init_flag; + u32 done_flag; + u32 err_flag; +}; + +static const struct ddrphy_init_sequence impedance_calibration_sequence[] = { + { + "Impedance Calibration", + DMPHY_PIR_ZCAL, + DMPHY_PGSR0_ZCDONE, + DMPHY_PGSR0_ZCERR, + }, + { /* sentinel */ } +}; + +static const struct ddrphy_init_sequence dram_init_sequence[] = { + { + "DRAM Initialization", + DMPHY_PIR_DRAMRST | DMPHY_PIR_DRAMINIT, + DMPHY_PGSR0_DIDONE, + 0, + }, + { /* sentinel */ } +}; + +static const struct ddrphy_init_sequence training_sequence[] = { + { + "Write Leveling", + DMPHY_PIR_WL, + DMPHY_PGSR0_WLDONE, + DMPHY_PGSR0_WLERR, + }, + { + "Read DQS Gate Training", + DMPHY_PIR_QSGATE, + DMPHY_PGSR0_QSGDONE, + DMPHY_PGSR0_QSGERR, + }, + { + "Write Leveling Adjustment", + DMPHY_PIR_WLADJ, + DMPHY_PGSR0_WLADONE, + DMPHY_PGSR0_WLAERR, + }, + { + "Read Bit Deskew", + DMPHY_PIR_RDDSKW, + DMPHY_PGSR0_RDDONE, + DMPHY_PGSR0_RDERR, + }, + { + "Write Bit Deskew", + DMPHY_PIR_WRDSKW, + DMPHY_PGSR0_WDDONE, + DMPHY_PGSR0_WDERR, + }, + { + "Read Eye Training", + DMPHY_PIR_RDEYE, + DMPHY_PGSR0_REDONE, + DMPHY_PGSR0_REERR, + }, + { + "Write Eye Training", + DMPHY_PIR_WREYE, + DMPHY_PGSR0_WEDONE, + DMPHY_PGSR0_WEERR, + }, + { /* sentinel */ } +}; + +static int __ddrphy_training(void __iomem *phy_base, + const struct ddrphy_init_sequence *seq) +{ + const struct ddrphy_init_sequence *s; + u32 pgsr0; + u32 init_flag = DMPHY_PIR_INIT; + u32 done_flag = DMPHY_PGSR0_IDONE; + int timeout = 50000; /* 50 msec is long enough */ +#ifdef DISPLAY_ELAPSED_TIME + ulong start = get_timer(0); +#endif + + for (s = seq; s->description; s++) { + init_flag |= s->init_flag; + done_flag |= s->done_flag; + } + + writel(init_flag, phy_base + DMPHY_PIR); + + do { + if (--timeout < 0) { + printf("%s: error: timeout during DDR training\n", + __func__); + return -ETIMEDOUT; + } + udelay(1); + pgsr0 = readl(phy_base + DMPHY_PGSR0); + } while ((pgsr0 & done_flag) != done_flag); + + for (s = seq; s->description; s++) { + if (pgsr0 & s->err_flag) { + printf("%s: error: %s failed\n", __func__, + s->description); + return -EIO; + } + } + +#ifdef DISPLAY_ELAPSED_TIME + printf("%s: info: elapsed time %ld msec\n", get_timer(start)); +#endif + + return 0; +} + +static int ddrphy_impedance_calibration(void __iomem *phy_base) +{ + int ret; + u32 tmp; + + ret = __ddrphy_training(phy_base, impedance_calibration_sequence); + if (ret) + return ret; + + /* + * Because of a hardware bug, IDONE flag is set when the first ZQ block + * is calibrated. The flag does not guarantee the completion for all + * the ZQ blocks. Wait a little more just in case. + */ + udelay(1); + + /* reflect ZQ settings and enable average algorithm*/ + tmp = readl(phy_base + DMPHY_ZQCR); + tmp |= DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; + writel(tmp, phy_base + DMPHY_ZQCR); + tmp &= ~DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; + tmp |= DMPHY_ZQCR_AVGEN; + writel(tmp, phy_base + DMPHY_ZQCR); + + return 0; +} + +static int ddrphy_dram_init(void __iomem *phy_base) +{ + return __ddrphy_training(phy_base, dram_init_sequence); +} + +static int ddrphy_training(void __iomem *phy_base) +{ + return __ddrphy_training(phy_base, training_sequence); +} + +/* UMC */ +static void umc_set_system_latency(void __iomem *umc_dc_base, int phy_latency) +{ + u32 val; + int latency; + + val = readl(umc_dc_base + UMC_RDATACTL_D0); + latency = (val & UMC_RDATACTL_RADLTY_MASK) >> UMC_RDATACTL_RADLTY_SHIFT; + latency += (val & UMC_RDATACTL_RAD2LTY_MASK) >> + UMC_RDATACTL_RAD2LTY_SHIFT; + /* + * UMC works at the half clock rate of the PHY. + * The LSB of latency is ignored + */ + latency += phy_latency & ~1; + + val &= ~(UMC_RDATACTL_RADLTY_MASK | UMC_RDATACTL_RAD2LTY_MASK); + if (latency > 0xf) { + val |= 0xf << UMC_RDATACTL_RADLTY_SHIFT; + val |= (latency - 0xf) << UMC_RDATACTL_RAD2LTY_SHIFT; + } else { + val |= latency << UMC_RDATACTL_RADLTY_SHIFT; + } + + writel(val, umc_dc_base + UMC_RDATACTL_D0); + writel(val, umc_dc_base + UMC_RDATACTL_D1); + + readl(umc_dc_base + UMC_RDATACTL_D1); /* relax */ +} + +/* enable/disable auto refresh */ +void umc_refresh_ctrl(void __iomem *umc_dc_base, int enable) +{ + u32 tmp; + + tmp = readl(umc_dc_base + UMC_SPCSETB); + tmp &= ~UMC_SPCSETB_AREFMD_MASK; + + if (enable) + tmp |= UMC_SPCSETB_AREFMD_ARB; + else + tmp |= UMC_SPCSETB_AREFMD_REG; + + writel(tmp, umc_dc_base + UMC_SPCSETB); + udelay(1); +} + +static void umc_ud_init(void __iomem *umc_base, int ch) +{ + writel(0x00000003, umc_base + UMC_BITPERPIXELMODE_D0); + + if (ch == 2) + writel(0x00000033, umc_base + UMC_PAIR1DOFF_D0); +} + +static void umc_dc_init(void __iomem *umc_dc_base, enum dram_freq freq, + enum dram_size size, int ch, int width) +{ + int latency; + u32 val; + + writel(umc_cmdctla[freq], umc_dc_base + UMC_CMDCTLA); + + writel(ch == 2 ? umc_cmdctlb_ch2[freq] : umc_cmdctlb_ch01[freq], + umc_dc_base + UMC_CMDCTLB); + + writel(umc_spcctla[freq][size / (width / 16)], + umc_dc_base + UMC_SPCCTLA); + writel(umc_spcctlb[freq], umc_dc_base + UMC_SPCCTLB); + + val = 0x000e000e; + latency = 12; + /* ES2 inserted one more FF to the logic. */ + if (uniphier_get_soc_model() >= 2) + latency += 2; + + if (latency > 0xf) { + val |= 0xf << UMC_RDATACTL_RADLTY_SHIFT; + val |= (latency - 0xf) << UMC_RDATACTL_RAD2LTY_SHIFT; + } else { + val |= latency << UMC_RDATACTL_RADLTY_SHIFT; + } + + writel(val, umc_dc_base + UMC_RDATACTL_D0); + if (width >= 32) + writel(val, umc_dc_base + UMC_RDATACTL_D1); + + writel(0x04060A02, umc_dc_base + UMC_WDATACTL_D0); + if (width >= 32) + writel(0x04060A02, umc_dc_base + UMC_WDATACTL_D1); + writel(0x04000000, umc_dc_base + UMC_DATASET); + writel(0x00400020, umc_dc_base + UMC_DCCGCTL); + writel(0x00000084, umc_dc_base + UMC_FLOWCTLG); + writel(0x00000000, umc_dc_base + UMC_ACSSETA); + + writel(ch == 2 ? umc_flowctla_ch2[freq] : umc_flowctla_ch01[freq], + umc_dc_base + UMC_FLOWCTLA); + + writel(0x00004400, umc_dc_base + UMC_FLOWCTLC); + writel(0x200A0A00, umc_dc_base + UMC_SPCSETB); + writel(0x00000520, umc_dc_base + UMC_DFICUPDCTLA); + writel(0x0000000D, umc_dc_base + UMC_RESPCTL); + + if (ch != 2) { + writel(0x00202000, umc_dc_base + UMC_FLOWCTLB); + writel(0xFDBFFFFF, umc_dc_base + UMC_FLOWCTLOB0); + writel(0xFFFFFFFF, umc_dc_base + UMC_FLOWCTLOB1); + writel(0x00080700, umc_dc_base + UMC_BSICMAPSET); + } else { + writel(0x00200000, umc_dc_base + UMC_FLOWCTLB); + writel(0x00000000, umc_dc_base + UMC_BSICMAPSET); + } + + writel(0x00000000, umc_dc_base + UMC_ERRMASKA); + writel(0x00000000, umc_dc_base + UMC_ERRMASKB); +} + +static int umc_init(void __iomem *umc_base, enum dram_freq freq, int ch, + enum dram_size size, int width) +{ + void __iomem *umc_dc_base = umc_base + 0x00011000; + void __iomem *phy_base = umc_base + 0x00030000; + int ret; + + writel(0x00000002, umc_dc_base + UMC_INITSET); + while (readl(umc_dc_base + UMC_INITSTAT) & BIT(2)) + cpu_relax(); + + /* deassert PHY reset signals */ + writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST, + umc_dc_base + UMC_DIOCTLA); + + ddrphy_init(phy_base, freq, width); + + ret = ddrphy_impedance_calibration(phy_base); + if (ret) + return ret; + + ddrphy_dram_init(phy_base); + if (ret) + return ret; + + umc_dc_init(umc_dc_base, freq, size, ch, width); + + umc_ud_init(umc_base, ch); + + if (size) { + ret = ddrphy_training(phy_base); + if (ret) + return ret; + } + + udelay(1); + + /* match the system latency between UMC and PHY */ + umc_set_system_latency(umc_dc_base, + ddrphy_get_system_latency(phy_base, width)); + + udelay(1); + + /* stop auto refresh before clearing FIFO in PHY */ + umc_refresh_ctrl(umc_dc_base, 0); + ddrphy_fifo_reset(phy_base); + umc_refresh_ctrl(umc_dc_base, 1); + + udelay(10); + + return 0; +} + +static void um_init(void __iomem *um_base) +{ + writel(0x000000ff, um_base + UMC_MBUS0); + writel(0x000000ff, um_base + UMC_MBUS1); + writel(0x000000ff, um_base + UMC_MBUS2); + writel(0x000000ff, um_base + UMC_MBUS3); +} + +int proxstream2_umc_init(const struct uniphier_board_data *bd) +{ + void __iomem *um_base = (void __iomem *)0x5b600000; + void __iomem *umc_ch0_base = (void __iomem *)0x5b800000; + void __iomem *umc_ch1_base = (void __iomem *)0x5ba00000; + void __iomem *umc_ch2_base = (void __iomem *)0x5bc00000; + enum dram_freq freq; + int ret; + + switch (bd->dram_freq) { + case 1866: + freq = FREQ_1866M; + break; + case 2133: + freq = FREQ_2133M; + break; + default: + printf("unsupported DRAM frequency %d MHz\n", bd->dram_freq); + return -EINVAL; + } + + ret = umc_init(umc_ch0_base, freq, 0, bd->dram_ch0_size / SZ_256M, + bd->dram_ch0_width); + if (ret) { + printf("failed to initialize UMC ch0\n"); + return ret; + } + + ret = umc_init(umc_ch1_base, freq, 1, bd->dram_ch1_size / SZ_256M, + bd->dram_ch1_width); + if (ret) { + printf("failed to initialize UMC ch1\n"); + return ret; + } + + ret = umc_init(umc_ch2_base, freq, 2, bd->dram_ch2_size / SZ_256M, + bd->dram_ch2_width); + if (ret) { + printf("failed to initialize UMC ch2\n"); + return ret; + } + + um_init(um_base); + + return 0; +} diff --git a/arch/arm/mach-uniphier/include/mach/umc-regs.h b/arch/arm/mach-uniphier/dram/umc-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/umc-regs.h rename to arch/arm/mach-uniphier/dram/umc-regs.h diff --git a/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c index f646c9b7df..6574767f30 100644 --- a/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c +++ b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c @@ -7,8 +7,9 @@ #include #include #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" int ph1_ld4_early_clk_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/early-clk/early-clk-ph1-pro5.c b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-pro5.c index 007d3b8570..d98635878b 100644 --- a/arch/arm/mach-uniphier/early-clk/early-clk-ph1-pro5.c +++ b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-pro5.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" int ph1_pro5_early_clk_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c b/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c index c303f16a57..a573a96ee5 100644 --- a/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c +++ b/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c @@ -7,8 +7,9 @@ #include #include #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" int proxstream2_early_clk_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/early-pinctrl/early-pinctrl-ph1-sld3.c b/arch/arm/mach-uniphier/early-pinctrl/early-pinctrl-ph1-sld3.c index 1bb9375016..7923644cd5 100644 --- a/arch/arm/mach-uniphier/early-pinctrl/early-pinctrl-ph1-sld3.c +++ b/arch/arm/mach-uniphier/early-pinctrl/early-pinctrl-ph1-sld3.c @@ -4,8 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include -#include +#include "../init.h" +#include "../sg-regs.h" int ph1_sld3_early_pin_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/include/mach/init.h b/arch/arm/mach-uniphier/init.h similarity index 97% rename from arch/arm/mach-uniphier/include/mach/init.h rename to arch/arm/mach-uniphier/init.h index 27ae27dc9f..0a47e70dcf 100644 --- a/arch/arm/mach-uniphier/include/mach/init.h +++ b/arch/arm/mach-uniphier/init.h @@ -80,6 +80,7 @@ int ph1_sld3_early_pin_init(const struct uniphier_board_data *bd); int ph1_ld4_umc_init(const struct uniphier_board_data *bd); int ph1_pro4_umc_init(const struct uniphier_board_data *bd); int ph1_sld8_umc_init(const struct uniphier_board_data *bd); +int proxstream2_umc_init(const struct uniphier_board_data *bd); void ph1_sld3_pin_init(void); void ph1_ld4_pin_init(void); diff --git a/arch/arm/mach-uniphier/init/init-ph1-ld4.c b/arch/arm/mach-uniphier/init/init-ph1-ld4.c index 8d0ef0389e..a9c6d72e0b 100644 --- a/arch/arm/mach-uniphier/init/init-ph1-ld4.c +++ b/arch/arm/mach-uniphier/init/init-ph1-ld4.c @@ -6,9 +6,9 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int ph1_ld4_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/init/init-ph1-pro4.c b/arch/arm/mach-uniphier/init/init-ph1-pro4.c index b9ce08d88f..6fcd8b6c85 100644 --- a/arch/arm/mach-uniphier/init/init-ph1-pro4.c +++ b/arch/arm/mach-uniphier/init/init-ph1-pro4.c @@ -6,9 +6,9 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int ph1_pro4_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/init/init-ph1-pro5.c b/arch/arm/mach-uniphier/init/init-ph1-pro5.c index 92b3f21d93..45c65cf49a 100644 --- a/arch/arm/mach-uniphier/init/init-ph1-pro5.c +++ b/arch/arm/mach-uniphier/init/init-ph1-pro5.c @@ -6,9 +6,9 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int ph1_pro5_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/init/init-ph1-sld3.c b/arch/arm/mach-uniphier/init/init-ph1-sld3.c index 1146fdab97..7827ec0bdc 100644 --- a/arch/arm/mach-uniphier/init/init-ph1-sld3.c +++ b/arch/arm/mach-uniphier/init/init-ph1-sld3.c @@ -6,9 +6,9 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int ph1_sld3_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/init/init-ph1-sld8.c b/arch/arm/mach-uniphier/init/init-ph1-sld8.c index 741e88c212..6c96aede2a 100644 --- a/arch/arm/mach-uniphier/init/init-ph1-sld8.c +++ b/arch/arm/mach-uniphier/init/init-ph1-sld8.c @@ -6,9 +6,9 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int ph1_sld8_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/init/init-proxstream2.c b/arch/arm/mach-uniphier/init/init-proxstream2.c index 8d03b8f86a..029c544997 100644 --- a/arch/arm/mach-uniphier/init/init-proxstream2.c +++ b/arch/arm/mach-uniphier/init/init-proxstream2.c @@ -6,12 +6,14 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../micro-support-card.h" int proxstream2_init(const struct uniphier_board_data *bd) { + int ret; + proxstream2_sbc_init(bd); support_card_reset(); @@ -37,5 +39,11 @@ int proxstream2_init(const struct uniphier_board_data *bd) led_puts("L4"); + ret = proxstream2_umc_init(bd); + if (ret) + return ret; + + led_puts("L5"); + return 0; } diff --git a/arch/arm/mach-uniphier/init/init.c b/arch/arm/mach-uniphier/init/init.c index eda169e374..b30f3bd9d6 100644 --- a/arch/arm/mach-uniphier/init/init.c +++ b/arch/arm/mach-uniphier/init/init.c @@ -6,8 +6,9 @@ #include #include -#include -#include + +#include "../init.h" +#include "../soc-info.h" void spl_board_init(void) { diff --git a/arch/arm/mach-uniphier/late_lowlevel_init.S b/arch/arm/mach-uniphier/late_lowlevel_init.S index 1363364c80..cce91dfac7 100644 --- a/arch/arm/mach-uniphier/late_lowlevel_init.S +++ b/arch/arm/mach-uniphier/late_lowlevel_init.S @@ -6,7 +6,8 @@ */ #include -#include + +#include "ssc-regs.h" ENTRY(lowlevel_init) ldr r1, = SSCC diff --git a/arch/arm/mach-uniphier/lowlevel_init.S b/arch/arm/mach-uniphier/lowlevel_init.S index 5936045e86..291337070e 100644 --- a/arch/arm/mach-uniphier/lowlevel_init.S +++ b/arch/arm/mach-uniphier/lowlevel_init.S @@ -8,9 +8,8 @@ #include #include #include -#include -#include -#include + +#include "ssc-regs.h" ENTRY(lowlevel_init) mov r8, lr @ persevere link reg across call diff --git a/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c b/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c index e13f56d1dc..9718cc560f 100644 --- a/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c +++ b/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c @@ -8,8 +8,9 @@ #include #include #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" int ph1_sld3_memconf_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c b/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c index d7bf0d4e5f..9a91fb33ef 100644 --- a/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c +++ b/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c @@ -8,8 +8,9 @@ #include #include #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" int proxstream2_memconf_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/memconf/memconf.c b/arch/arm/mach-uniphier/memconf/memconf.c index d490736fa4..f2a0eaf3f5 100644 --- a/arch/arm/mach-uniphier/memconf/memconf.c +++ b/arch/arm/mach-uniphier/memconf/memconf.c @@ -8,8 +8,9 @@ #include #include #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" int memconf_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/micro-support-card.c b/arch/arm/mach-uniphier/micro-support-card.c index 4c34748c25..f777ac1ffe 100644 --- a/arch/arm/mach-uniphier/micro-support-card.c +++ b/arch/arm/mach-uniphier/micro-support-card.c @@ -7,7 +7,8 @@ #include #include #include -#include + +#include "micro-support-card.h" #define MICRO_SUPPORT_CARD_BASE 0x43f00000 #define SMC911X_BASE ((MICRO_SUPPORT_CARD_BASE) + 0x00000) @@ -70,7 +71,6 @@ int board_eth_init(bd_t *bis) #if !defined(CONFIG_SYS_NO_FLASH) #include -#include struct memory_bank { phys_addr_t base; diff --git a/arch/arm/mach-uniphier/include/mach/micro-support-card.h b/arch/arm/mach-uniphier/micro-support-card.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/micro-support-card.h rename to arch/arm/mach-uniphier/micro-support-card.h diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c index 160d3ef299..8168a63d31 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void ph1_ld4_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c index 4f950d3fc6..4faeaf535c 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void ph1_ld6b_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c index f50644c52b..23b5f9349a 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void ph1_pro4_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c index a6cc0824e2..79160d6c95 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void ph1_pro5_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c index f1b2bbbb4a..6fc0dee70e 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c @@ -4,8 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include -#include +#include "../init.h" +#include "../sg-regs.h" void ph1_sld3_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c index f936a53d1f..a4e3e7a614 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void ph1_sld8_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c index 96abd0235c..a662db8ac9 100644 --- a/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" void proxstream2_pin_init(void) { diff --git a/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c index a272a900e1..b2de9e8d5e 100644 --- a/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c @@ -7,9 +7,10 @@ #include #include #include -#include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" +#include "../sg-regs.h" #undef DPLL_SSC_RATE_1PER diff --git a/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c index 906c22f6c5..69d518d265 100644 --- a/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c @@ -7,9 +7,10 @@ #include #include #include -#include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" +#include "../sg-regs.h" #undef DPLL_SSC_RATE_1PER diff --git a/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c index 6294a452c2..b93806cdc0 100644 --- a/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include +#include "../init.h" int ph1_sld3_pll_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c index f249abeeda..3c7550446a 100644 --- a/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c @@ -6,9 +6,10 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" +#include "../sg-regs.h" static void dpll_init(void) { diff --git a/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c index cad0ed8cdd..a1c8089de7 100644 --- a/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c +++ b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c @@ -5,8 +5,9 @@ */ #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" int ph1_ld4_enable_dpll_ssc(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c index 43dc973654..94654eeba0 100644 --- a/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c +++ b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c @@ -6,8 +6,9 @@ #include #include -#include -#include + +#include "../init.h" +#include "../sc-regs.h" int ph1_sld3_enable_dpll_ssc(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/print_misc_info.c b/arch/arm/mach-uniphier/print_misc_info.c index 5140b0c438..695b7aeeb3 100644 --- a/arch/arm/mach-uniphier/print_misc_info.c +++ b/arch/arm/mach-uniphier/print_misc_info.c @@ -1,11 +1,10 @@ /* - * Copyright (C) 2015 Panasonic Corporation - * Author: Masahiro Yamada + * Copyright (C) 2015 Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ */ -#include +#include "micro-support-card.h" int misc_init_f(void) { diff --git a/arch/arm/mach-uniphier/reset.c b/arch/arm/mach-uniphier/reset.c index 4c825116f7..b5825bc0c7 100644 --- a/arch/arm/mach-uniphier/reset.c +++ b/arch/arm/mach-uniphier/reset.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "sc-regs.h" void reset_cpu(unsigned long ignored) { diff --git a/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c index 929f50a883..fcce43cb99 100644 --- a/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c @@ -6,9 +6,10 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" +#include "sbc-regs.h" int ph1_ld4_sbc_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c index 1032c54e64..8313c5a3e5 100644 --- a/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c @@ -6,9 +6,10 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" +#include "sbc-regs.h" int ph1_pro4_sbc_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c index fb707be83a..c03c2843a6 100644 --- a/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c @@ -6,9 +6,10 @@ #include #include -#include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" +#include "sbc-regs.h" int ph1_sld3_sbc_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c b/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c index 9c3aeb7cd0..0d9ffe153f 100644 --- a/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c +++ b/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c @@ -5,9 +5,10 @@ */ #include -#include -#include -#include + +#include "../init.h" +#include "../sg-regs.h" +#include "sbc-regs.h" int proxstream2_sbc_init(const struct uniphier_board_data *bd) { diff --git a/arch/arm/mach-uniphier/include/mach/sbc-regs.h b/arch/arm/mach-uniphier/sbc/sbc-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/sbc-regs.h rename to arch/arm/mach-uniphier/sbc/sbc-regs.h diff --git a/arch/arm/mach-uniphier/include/mach/sc-regs.h b/arch/arm/mach-uniphier/sc-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/sc-regs.h rename to arch/arm/mach-uniphier/sc-regs.h diff --git a/arch/arm/mach-uniphier/include/mach/sg-regs.h b/arch/arm/mach-uniphier/sg-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/sg-regs.h rename to arch/arm/mach-uniphier/sg-regs.h diff --git a/arch/arm/mach-uniphier/include/mach/soc_info.h b/arch/arm/mach-uniphier/soc-info.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/soc_info.h rename to arch/arm/mach-uniphier/soc-info.h diff --git a/arch/arm/mach-uniphier/soc_info.c b/arch/arm/mach-uniphier/soc_info.c index 6cdeae6578..fd799ca39a 100644 --- a/arch/arm/mach-uniphier/soc_info.c +++ b/arch/arm/mach-uniphier/soc_info.c @@ -6,8 +6,9 @@ #include #include -#include -#include + +#include "sg-regs.h" +#include "soc-info.h" #if UNIPHIER_MULTI_SOC enum uniphier_soc_id uniphier_get_soc_type(void) diff --git a/arch/arm/mach-uniphier/include/mach/ssc-regs.h b/arch/arm/mach-uniphier/ssc-regs.h similarity index 100% rename from arch/arm/mach-uniphier/include/mach/ssc-regs.h rename to arch/arm/mach-uniphier/ssc-regs.h diff --git a/arch/arm/mach-uniphier/timer.c b/arch/arm/mach-uniphier/timer.c index 27ada2924c..a34e30b72b 100644 --- a/arch/arm/mach-uniphier/timer.c +++ b/arch/arm/mach-uniphier/timer.c @@ -6,7 +6,8 @@ #include #include -#include + +#include "arm-mpcore.h" #define PERIPHCLK (50 * 1000 * 1000) /* 50 MHz */ #define PRESCALER ((PERIPHCLK) / (CONFIG_SYS_TIMER_RATE) - 1) diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c index b76a7319ae..528865f5d3 100644 --- a/arch/sandbox/cpu/eth-raw-os.c +++ b/arch/sandbox/cpu/eth-raw-os.c @@ -76,6 +76,10 @@ static int _raw_packet_start(const char *ifname, unsigned char *ethmac, printf("Failed to set promiscuous mode: %d %s\n" "Falling back to the old \"flags\" way...\n", errno, strerror(errno)); + if (strlen(ifname) >= IFNAMSIZ) { + printf("Interface name %s is too long.\n", ifname); + return -EINVAL; + } strncpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) { printf("Failed to read flags: %d %s\n", errno, diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 9b30451b28..7299f2cddc 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -14,12 +14,12 @@ static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD }, + {}, }; int cpu_mmc_init(bd_t *bis) { - return pci_mmc_init("ValleyView SDHCI", mmc_supported, - ARRAY_SIZE(mmc_supported)); + return pci_mmc_init("ValleyView SDHCI", mmc_supported); } #ifndef CONFIG_EFI_APP diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 3e7a907e00..434dfd649f 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -86,8 +86,10 @@ static int bd82x6x_probe(struct udevice *dev) debug("%s: Cannot find GMA node\n", __func__); return -EINVAL; } - ret = gma_func0_init(PCH_VIDEO_DEV, pci_bus_to_hose(0), blob, - gma_node); + ret = dm_pci_bus_find_bdf(PCH_VIDEO_DEV, &dev); + if (ret) + return ret; + ret = gma_func0_init(dev, blob, gma_node); if (ret) return ret; diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c index 89d4a5e9cc..85a09c64b6 100644 --- a/arch/x86/cpu/ivybridge/gma.c +++ b/arch/x86/cpu/ivybridge/gma.c @@ -728,8 +728,7 @@ static int int15_handler(void) return res; } -int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, - const void *blob, int node) +int gma_func0_init(struct udevice *dev, const void *blob, int node) { #ifdef CONFIG_VIDEO ulong start; @@ -740,16 +739,16 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, int ret; /* IGD needs to be Bus Master */ - reg32 = x86_pci_read_config32(dev, PCI_COMMAND); + dm_pci_read_config32(dev, PCI_COMMAND, ®32); reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - x86_pci_write_config32(dev, PCI_COMMAND, reg32); + dm_pci_write_config32(dev, PCI_COMMAND, reg32); /* Use write-combining for the graphics memory, 256MB */ - base = pci_read_bar32(hose, dev, 2); + base = dm_pci_read_bar32(dev, 2); mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20); mtrr_commit(true); - gtt_bar = (void *)pci_read_bar32(pci_bus_to_hose(0), dev, 0); + gtt_bar = (void *)dm_pci_read_bar32(dev, 0); debug("GT bar %p\n", gtt_bar); ret = gma_pm_init_pre_vbios(gtt_bar); if (ret) @@ -757,8 +756,8 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, #ifdef CONFIG_VIDEO start = get_timer(0); - ret = pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE | - PCI_ROM_ALLOW_FALLBACK); + ret = dm_pci_run_vga_bios(dev, int15_handler, + PCI_ROM_USE_NATIVE | PCI_ROM_ALLOW_FALLBACK); debug("BIOS ran in %lums\n", get_timer(start)); #endif /* Post VBIOS init */ diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index c2bf497d68..37ce3940b0 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -19,6 +19,7 @@ static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO }, + {}, }; /* @@ -337,8 +338,7 @@ int arch_early_init_r(void) int cpu_mmc_init(bd_t *bis) { - return pci_mmc_init("Quark SDHCI", mmc_supported, - ARRAY_SIZE(mmc_supported)); + return pci_mmc_init("Quark SDHCI", mmc_supported); } void cpu_irq_init(void) diff --git a/arch/x86/cpu/queensbay/topcliff.c b/arch/x86/cpu/queensbay/topcliff.c index 9faf1b92bb..b76dd7de69 100644 --- a/arch/x86/cpu/queensbay/topcliff.c +++ b/arch/x86/cpu/queensbay/topcliff.c @@ -11,10 +11,10 @@ static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 }, + {}, }; int cpu_mmc_init(bd_t *bis) { - return pci_mmc_init("Topcliff SDHCI", mmc_supported, - ARRAY_SIZE(mmc_supported)); + return pci_mmc_init("Topcliff SDHCI", mmc_supported); } diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h index 7786493be7..fcdf6e26cb 100644 --- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h +++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h @@ -12,8 +12,7 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node); void bd82x6x_pci_init(pci_dev_t dev); void bd82x6x_usb_ehci_init(pci_dev_t dev); void bd82x6x_usb_xhci_init(pci_dev_t dev); -int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, - const void *blob, int node); +int gma_func0_init(struct udevice *dev, const void *blob, int node); int bd82x6x_init(void); /** diff --git a/arch/x86/lib/bios.c b/arch/x86/lib/bios.c index 1d75cfc263..9324bdb83e 100644 --- a/arch/x86/lib/bios.c +++ b/arch/x86/lib/bios.c @@ -242,9 +242,10 @@ static void vbe_set_graphics(int vesa_mode, struct vbe_mode_info *mode_info) vbe_set_mode(mode_info); } -void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode, +void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode, struct vbe_mode_info *mode_info) { + pci_dev_t pcidev = dm_pci_get_bdf(dev); u32 num_dev; num_dev = PCI_BUS(pcidev) << 8 | PCI_DEV(pcidev) << 3 | diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c index 47d9f599a3..e8ca6e60f2 100644 --- a/arch/x86/lib/bios_interrupts.c +++ b/arch/x86/lib/bios_interrupts.c @@ -105,13 +105,15 @@ int int1a_handler(void) unsigned short func = (unsigned short)M.x86.R_EAX; int retval = 1; unsigned short devid, vendorid, devfn; + struct udevice *dev; /* Use short to get rid of gabage in upper half of 32-bit register */ short devindex; unsigned char bus; - pci_dev_t dev; + pci_dev_t bdf; u32 dword; u16 word; u8 byte, reg; + int ret; switch (func) { case 0xb101: /* PCIBIOS Check */ @@ -131,17 +133,20 @@ int int1a_handler(void) devid = M.x86.R_ECX; vendorid = M.x86.R_EDX; devindex = M.x86.R_ESI; - dev = pci_find_device(vendorid, devid, devindex); - if (dev != -1) { + bdf = -1; + ret = dm_pci_find_device(vendorid, devid, devindex, &dev); + if (!ret) { unsigned short busdevfn; + + bdf = dm_pci_get_bdf(dev); M.x86.R_EAX &= 0xffff00ff; /* Clear AH */ M.x86.R_EAX |= PCIBIOS_SUCCESSFUL; /* * busnum is an unsigned char; * devfn is an int, so we mask it off. */ - busdevfn = (PCI_BUS(dev) << 8) | PCI_DEV(dev) << 3 | - PCI_FUNC(dev); + busdevfn = (PCI_BUS(bdf) << 8) | PCI_DEV(bdf) << 3 | + PCI_FUNC(bdf); debug("0x%x: return 0x%x\n", func, busdevfn); M.x86.R_EBX = busdevfn; retval = 1; @@ -160,35 +165,40 @@ int int1a_handler(void) devfn = M.x86.R_EBX & 0xff; bus = M.x86.R_EBX >> 8; reg = M.x86.R_EDI; - dev = PCI_BDF(bus, devfn >> 3, devfn & 7); + bdf = PCI_BDF(bus, devfn >> 3, devfn & 7); + + ret = dm_pci_bus_find_bdf(bdf, &dev); + if (ret) { + debug("%s: Device %x not found\n", __func__, bdf); + break; + } switch (func) { case 0xb108: /* Read Config Byte */ - byte = x86_pci_read_config8(dev, reg); + dm_pci_read_config8(dev, reg, &byte); M.x86.R_ECX = byte; break; case 0xb109: /* Read Config Word */ - word = x86_pci_read_config16(dev, reg); + dm_pci_read_config16(dev, reg, &word); M.x86.R_ECX = word; break; case 0xb10a: /* Read Config Dword */ - dword = x86_pci_read_config32(dev, reg); + dm_pci_read_config32(dev, reg, &dword); M.x86.R_ECX = dword; break; case 0xb10b: /* Write Config Byte */ byte = M.x86.R_ECX; - x86_pci_write_config8(dev, reg, byte); + dm_pci_write_config8(dev, reg, byte); break; case 0xb10c: /* Write Config Word */ word = M.x86.R_ECX; - x86_pci_write_config16(dev, reg, word); + dm_pci_write_config16(dev, reg, word); break; case 0xb10d: /* Write Config Dword */ dword = M.x86.R_ECX; - x86_pci_write_config32(dev, reg, dword); + dm_pci_write_config32(dev, reg, dword); break; } - #ifdef CONFIG_REALMODE_DEBUG debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func, bus, devfn, reg, M.x86.R_ECX); diff --git a/board/compulab/trimslice/trimslice.c b/board/compulab/trimslice/trimslice.c index c9da80d5eb..723293fef3 100644 --- a/board/compulab/trimslice/trimslice.c +++ b/board/compulab/trimslice/trimslice.c @@ -13,7 +13,6 @@ #include #include #include -#include void pin_mux_usb(void) { @@ -41,10 +40,3 @@ void pin_mux_mmc(void) /* For CD GPIO PP1 */ pinmux_tristate_disable(PMUX_PINGRP_DAP3); } - -#ifdef CONFIG_PCI -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} -#endif diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c index 1540526a61..ba15e2e6cf 100644 --- a/board/nvidia/cardhu/cardhu.c +++ b/board/nvidia/cardhu/cardhu.c @@ -13,7 +13,6 @@ #include #include "pinmux-config-cardhu.h" #include -#include #define PMU_I2C_ADDRESS 0x2D #define MAX_I2C_RETRY 3 @@ -129,9 +128,4 @@ int tegra_pcie_board_init(void) return 0; } - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} #endif /* PCI */ diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c b/board/nvidia/jetson-tk1/jetson-tk1.c index 52425a8f6d..6f189aa74e 100644 --- a/board/nvidia/jetson-tk1/jetson-tk1.c +++ b/board/nvidia/jetson-tk1/jetson-tk1.c @@ -6,7 +6,6 @@ */ #include -#include #include #include @@ -73,9 +72,4 @@ int tegra_pcie_board_init(void) return 0; } - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} #endif /* PCI */ diff --git a/board/nvidia/p2371-2180/p2371-2180.c b/board/nvidia/p2371-2180/p2371-2180.c index 57f577d85d..0f587eaaa7 100644 --- a/board/nvidia/p2371-2180/p2371-2180.c +++ b/board/nvidia/p2371-2180/p2371-2180.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -73,9 +72,4 @@ int tegra_pcie_board_init(void) return 0; } - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} #endif /* PCI */ diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c index 879006f8e0..3f56971a13 100644 --- a/board/toradex/apalis_t30/apalis_t30.c +++ b/board/toradex/apalis_t30/apalis_t30.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "pinmux-config-apalis_t30.h" @@ -92,9 +91,4 @@ int tegra_pcie_board_init(void) return 0; } - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} #endif /* CONFIG_PCI_TEGRA */ diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 4e0951f864..8094d3380f 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -606,7 +606,7 @@ static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #ifdef CONFIG_DM_PCI - ret = pci_bus_find_bdf(bdf, &dev); + ret = dm_pci_bus_find_bdf(bdf, &dev); if (ret) { printf("No such device\n"); return CMD_RET_FAILURE; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 31c43195e4..86954089fe 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -184,7 +184,7 @@ int scsi_get_disk_count(void) #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) void scsi_init(void) { - int busdevfunc; + int busdevfunc = -1; int i; /* * Find a device from the list, this driver will support a single @@ -192,9 +192,21 @@ void scsi_init(void) */ for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) { /* get PCI Device ID */ +#ifdef CONFIG_DM_PCI + struct udevice *dev; + int ret; + + ret = dm_pci_find_device(scsi_device_list[i].vendor, + scsi_device_list[i].device, 0, &dev); + if (!ret) { + busdevfunc = dm_pci_get_bdf(dev); + break; + } +#else busdevfunc = pci_find_device(scsi_device_list[i].vendor, scsi_device_list[i].device, 0); +#endif if (busdevfunc != -1) break; } diff --git a/common/fdt_support.c b/common/fdt_support.c index a539389a9e..09f923716c 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -482,47 +482,49 @@ int fdt_fixup_memory(void *blob, u64 start, u64 size) void fdt_fixup_ethernet(void *fdt) { int node, i, j; - char enet[16], *tmp, *end; + char *tmp, *end; char mac[16]; const char *path; unsigned char mac_addr[6]; + int offset; node = fdt_path_offset(fdt, "/aliases"); if (node < 0) return; - if (!getenv("ethaddr")) { - if (getenv("usbethaddr")) { - strcpy(mac, "usbethaddr"); - } else { - debug("No ethernet MAC Address defined\n"); - return; - } - } else { - strcpy(mac, "ethaddr"); - } - - i = 0; - while ((tmp = getenv(mac)) != NULL) { - sprintf(enet, "ethernet%d", i); - path = fdt_getprop(fdt, node, enet, NULL); - if (!path) { - debug("No alias for %s\n", enet); - sprintf(mac, "eth%daddr", ++i); - continue; - } + for (offset = fdt_first_property_offset(fdt, node); + offset > 0; + offset = fdt_next_property_offset(fdt, offset)) { + const char *name; + int len = strlen("ethernet"); + + path = fdt_getprop_by_offset(fdt, offset, &name, NULL); + if (!strncmp(name, "ethernet", len)) { + i = trailing_strtol(name); + if (i != -1) { + if (i == 0) + strcpy(mac, "ethaddr"); + else + sprintf(mac, "eth%daddr", i); + } else { + continue; + } + tmp = getenv(mac); + if (!tmp) + continue; + + for (j = 0; j < 6; j++) { + mac_addr[j] = tmp ? + simple_strtoul(tmp, &end, 16) : 0; + if (tmp) + tmp = (*end) ? end + 1 : end; + } - for (j = 0; j < 6; j++) { - mac_addr[j] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; + do_fixup_by_path(fdt, path, "mac-address", + &mac_addr, 6, 0); + do_fixup_by_path(fdt, path, "local-mac-address", + &mac_addr, 6, 1); } - - do_fixup_by_path(fdt, path, "mac-address", &mac_addr, 6, 0); - do_fixup_by_path(fdt, path, "local-mac-address", - &mac_addr, 6, 1); - - sprintf(mac, "eth%daddr", ++i); } } diff --git a/common/hash.c b/common/hash.c index a1b048204d..41de4df536 100644 --- a/common/hash.c +++ b/common/hash.c @@ -247,6 +247,29 @@ int hash_parse_string(const char *algo_name, const char *str, uint8_t *result) return 0; } +int hash_block(const char *algo_name, const void *data, unsigned int len, + uint8_t *output, int *output_size) +{ + struct hash_algo *algo; + int ret; + + ret = hash_lookup_algo(algo_name, &algo); + if (ret) + return ret; + + if (output_size && *output_size < algo->digest_size) { + debug("Output buffer size %d too small (need %d bytes)", + *output_size, algo->digest_size); + return -ENOSPC; + } + if (output_size) + *output_size = algo->digest_size; + algo->hash_func_ws(data, len, output, algo->chunk_size); + + return 0; +} + +#if defined(CONFIG_CMD_HASH) || defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32) /** * store_result: Store the resulting sum to an address or variable * @@ -359,7 +382,7 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, return 0; } -void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) +static void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) { int i; @@ -368,28 +391,6 @@ void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) printf("%02x", output[i]); } -int hash_block(const char *algo_name, const void *data, unsigned int len, - uint8_t *output, int *output_size) -{ - struct hash_algo *algo; - int ret; - - ret = hash_lookup_algo(algo_name, &algo); - if (ret) - return ret; - - if (output_size && *output_size < algo->digest_size) { - debug("Output buffer size %d too small (need %d bytes)", - *output_size, algo->digest_size); - return -ENOSPC; - } - if (output_size) - *output_size = algo->digest_size; - algo->hash_func_ws(data, len, output, algo->chunk_size); - - return 0; -} - int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -473,3 +474,4 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, return 0; } #endif +#endif diff --git a/common/image.c b/common/image.c index c36927fca8..d63d9e0169 100644 --- a/common/image.c +++ b/common/image.c @@ -1113,8 +1113,7 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, if (initrd_high == ~0) initrd_copy_to_ram = 0; } else { - /* not set, no restrictions to load high */ - initrd_high = ~0; + initrd_high = getenv_bootm_mapsize() + getenv_bootm_low(); } diff --git a/configs/am437x_sk_evm_defconfig b/configs/am437x_sk_evm_defconfig index a9b6f52117..8f78eeb8b9 100644 --- a/configs/am437x_sk_evm_defconfig +++ b/configs/am437x_sk_evm_defconfig @@ -18,3 +18,6 @@ CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SYS_NS16550=y CONFIG_TI_QSPI=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/dra72_evm_defconfig b/configs/dra72_evm_defconfig index 3205bd5754..b57ecca696 100644 --- a/configs/dra72_evm_defconfig +++ b/configs/dra72_evm_defconfig @@ -20,3 +20,5 @@ CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SYS_NS16550=y CONFIG_TI_QSPI=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y diff --git a/configs/dra74_evm_defconfig b/configs/dra74_evm_defconfig index 394edbec2e..6e5a7051a4 100644 --- a/configs/dra74_evm_defconfig +++ b/configs/dra74_evm_defconfig @@ -19,3 +19,5 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_TI_QSPI=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig index 2e915ff05c..c196bd6f76 100644 --- a/configs/evb-rk3036_defconfig +++ b/configs/evb-rk3036_defconfig @@ -24,3 +24,9 @@ CONFIG_DM_MMC=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_NS16550=y +CONFIG_DEBUG_UART_BASE=0x20068000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART_SHIFT=2 +# CONFIG_SPL_SERIAL_PRESENT is not set diff --git a/disk/part_dos.c b/disk/part_dos.c index 89263d38aa..628066041b 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -26,7 +26,7 @@ /* Convert char[4] in little endian format to the host format integer */ -static inline int le32_to_int(unsigned char *le32) +static inline unsigned int le32_to_int(unsigned char *le32) { return ((le32[3] << 24) + (le32[2] << 16) + @@ -47,13 +47,14 @@ static inline int is_bootable(dos_partition_t *p) return p->boot_ind == 0x80; } -static void print_one_part(dos_partition_t *p, int ext_part_sector, +static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector, int part_num, unsigned int disksig) { - int lba_start = ext_part_sector + le32_to_int (p->start4); - int lba_size = le32_to_int (p->size4); + lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4); + lbaint_t lba_size = le32_to_int (p->size4); - printf("%3d\t%-10d\t%-10d\t%08x-%02x\t%02x%s%s\n", + printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength + "u\t%08x-%02x\t%02x%s%s\n", part_num, lba_start, lba_size, disksig, part_num, p->sys_ind, (is_extended(p->sys_ind) ? " Extd" : ""), (is_bootable(p) ? " Boot" : "")); @@ -102,7 +103,8 @@ int test_part_dos (block_dev_desc_t *dev_desc) /* Print a partition that is relative to its Extended partition table */ static void print_partition_extended(block_dev_desc_t *dev_desc, - int ext_part_sector, int relative, + lbaint_t ext_part_sector, + lbaint_t relative, int part_num, unsigned int disksig) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); @@ -110,7 +112,7 @@ static void print_partition_extended(block_dev_desc_t *dev_desc, int i; if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { - printf ("** Can't read partition table on %d:%d **\n", + printf ("** Can't read partition table on %d:" LBAFU " **\n", dev_desc->dev, ext_part_sector); return; } @@ -149,7 +151,8 @@ static void print_partition_extended(block_dev_desc_t *dev_desc, pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { if (is_extended (pt->sys_ind)) { - int lba_start = le32_to_int (pt->start4) + relative; + lbaint_t lba_start + = le32_to_int (pt->start4) + relative; print_partition_extended(dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, @@ -163,8 +166,9 @@ static void print_partition_extended(block_dev_desc_t *dev_desc, /* Print a partition that is relative to its Extended partition table */ -static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, - int relative, int part_num, +static int get_partition_info_extended (block_dev_desc_t *dev_desc, + lbaint_t ext_part_sector, + lbaint_t relative, int part_num, int which_part, disk_partition_t *info, unsigned int disksig) { @@ -174,7 +178,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part int dos_type; if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { - printf ("** Can't read partition table on %d:%d **\n", + printf ("** Can't read partition table on %d:" LBAFU " **\n", dev_desc->dev, ext_part_sector); return -1; } @@ -250,7 +254,8 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { if (is_extended (pt->sys_ind)) { - int lba_start = le32_to_int (pt->start4) + relative; + lbaint_t lba_start + = le32_to_int (pt->start4) + relative; return get_partition_info_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, diff --git a/doc/README.uniphier b/doc/README.uniphier index f0f5346f53..bce70cf5fe 100644 --- a/doc/README.uniphier +++ b/doc/README.uniphier @@ -119,7 +119,7 @@ The recommended bit switch settings are as follows: SW8 OFF(1)/ON(0) Description ------------------------------------------ - bit 1 ----> CS1_SPLIT + bit 1 <---- CS1_SPLIT bit 2 <---- CASE9_ON bit 3 <---- CASE10_ON bit 4 Don't Care Reserve diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 5efa821dad..d29642be77 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -168,9 +169,14 @@ int ahci_reset(void __iomem *base) static int ahci_host_init(struct ahci_probe_ent *probe_ent) { #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + struct udevice *dev = probe_ent->dev; + struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); +# else pci_dev_t pdev = probe_ent->dev; - u16 tmp16; unsigned short vendor; +# endif + u16 tmp16; #endif void __iomem *mmio = probe_ent->mmio_base; u32 tmp, cap_save, cmd; @@ -193,6 +199,14 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) writel_with_flush(0xf, mmio + HOST_PORTS_IMPL); #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + if (pplat->vendor == PCI_VENDOR_ID_INTEL) { + u16 tmp16; + + dm_pci_read_config16(dev, 0x92, &tmp16); + dm_pci_write_config16(dev, 0x92, tmp16 | 0xf); + } +# else pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor); if (vendor == PCI_VENDOR_ID_INTEL) { @@ -201,6 +215,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) tmp16 |= 0xf; pci_write_config_word(pdev, 0x92, tmp16); } +# endif #endif probe_ent->cap = readl(mmio + HOST_CAP); probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL); @@ -313,9 +328,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) tmp = readl(mmio + HOST_CTL); debug("HOST_CTL 0x%x\n", tmp); #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + dm_pci_read_config16(dev, PCI_COMMAND, &tmp16); + tmp |= PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, tmp16); +# else pci_read_config_word(pdev, PCI_COMMAND, &tmp16); tmp |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, tmp16); +# endif #endif return 0; } @@ -324,7 +345,11 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) static void ahci_print_info(struct ahci_probe_ent *probe_ent) { #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + struct udevice *dev = probe_ent->dev; +# else pci_dev_t pdev = probe_ent->dev; +# endif u16 cc; #endif void __iomem *mmio = probe_ent->mmio_base; @@ -350,7 +375,11 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) #ifdef CONFIG_SCSI_AHCI_PLAT scc_s = "SATA"; #else +# ifdef CONFIG_DM_PCI + dm_pci_read_config16(dev, 0x0a, &cc); +# else pci_read_config_word(pdev, 0x0a, &cc); +# endif if (cc == 0x0101) scc_s = "IDE"; else if (cc == 0x0106) @@ -395,7 +424,11 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent) } #ifndef CONFIG_SCSI_AHCI_PLAT -static int ahci_init_one(pci_dev_t pdev) +# ifdef CONFIG_DM_PCI +static int ahci_init_one(struct udevice *dev) +# else +static int ahci_init_one(pci_dev_t dev) +# endif { u16 vendor; int rc; @@ -407,7 +440,7 @@ static int ahci_init_one(pci_dev_t pdev) } memset(probe_ent, 0, sizeof(struct ahci_probe_ent)); - probe_ent->dev = pdev; + probe_ent->dev = dev; probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY @@ -417,18 +450,31 @@ static int ahci_init_one(pci_dev_t pdev) probe_ent->pio_mask = 0x1f; probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ - probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5, +#ifdef CONFIG_DM_PCI + probe_ent->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5, + PCI_REGION_MEM); + + /* Take from kernel: + * JMicron-specific fixup: + * make sure we're in AHCI mode + */ + dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor); + if (vendor == 0x197b) + dm_pci_write_config8(dev, 0x41, 0xa1); +#else + probe_ent->mmio_base = pci_map_bar(dev, PCI_BASE_ADDRESS_5, PCI_REGION_MEM); - debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base); /* Take from kernel: * JMicron-specific fixup: * make sure we're in AHCI mode */ - pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor); + pci_read_config_word(dev, PCI_VENDOR_ID, &vendor); if (vendor == 0x197b) - pci_write_config_byte(pdev, 0x41, 0xa1); + pci_write_config_byte(dev, 0x41, 0xa1); +#endif + debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base); /* initialize adapter */ rc = ahci_host_init(probe_ent); if (rc) @@ -915,7 +961,17 @@ void scsi_low_level_init(int busdevfunc) u32 linkmap; #ifndef CONFIG_SCSI_AHCI_PLAT +# ifdef CONFIG_DM_PCI + struct udevice *dev; + int ret; + + ret = dm_pci_bus_find_bdf(busdevfunc, &dev); + if (ret) + return; + ahci_init_one(dev); +# else ahci_init_one(busdevfunc); +# endif #endif linkmap = probe_ent->link_port_map; diff --git a/drivers/core/device.c b/drivers/core/device.c index b237b88c0a..818d03fac1 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -581,38 +581,65 @@ const char *dev_get_uclass_name(struct udevice *dev) return dev->uclass->uc_drv->name; } -fdt_addr_t dev_get_addr(struct udevice *dev) +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) { #if CONFIG_IS_ENABLED(OF_CONTROL) fdt_addr_t addr; if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { const fdt32_t *reg; + int len = 0; + int na, ns; + + na = fdt_address_cells(gd->fdt_blob, dev->parent->of_offset); + if (na < 1) { + debug("bad #address-cells\n"); + return FDT_ADDR_T_NONE; + } + + ns = fdt_size_cells(gd->fdt_blob, dev->parent->of_offset); + if (ns < 0) { + debug("bad #size-cells\n"); + return FDT_ADDR_T_NONE; + } - reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", NULL); - if (!reg) + reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", &len); + if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { + debug("Req index out of range\n"); return FDT_ADDR_T_NONE; + } + + reg += index * (na + ns); /* * Use the full-fledged translate function for complex * bus setups. */ - return fdt_translate_address((void *)gd->fdt_blob, + addr = fdt_translate_address((void *)gd->fdt_blob, dev->of_offset, reg); + } else { + /* + * Use the "simple" translate function for less complex + * bus setups. + */ + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, + dev->parent->of_offset, + dev->of_offset, "reg", + index, NULL); + if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { + if (device_get_uclass_id(dev->parent) == + UCLASS_SIMPLE_BUS) + addr = simple_bus_translate(dev->parent, addr); + } } /* - * Use the "simple" translate function for less complex - * bus setups. + * Some platforms need a special address translation. Those + * platforms (e.g. mvebu in SPL) can configure a translation + * offset in the DM by calling dm_set_translation_offset() that + * will get added to all addresses returned by dev_get_addr(). */ - addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, - dev->parent->of_offset, - dev->of_offset, "reg", - 0, NULL); - if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { - if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) - addr = simple_bus_translate(dev->parent, addr); - } + addr += dm_get_translation_offset(); return addr; #else @@ -620,6 +647,11 @@ fdt_addr_t dev_get_addr(struct udevice *dev) #endif } +fdt_addr_t dev_get_addr(struct udevice *dev) +{ + return dev_get_addr_index(dev, 0); +} + bool device_has_children(struct udevice *dev) { return !list_empty(&dev->child_head); diff --git a/drivers/core/root.c b/drivers/core/root.c index e7b1f24968..13c2713e61 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -23,6 +23,10 @@ DECLARE_GLOBAL_DATA_PTR; +struct root_priv { + fdt_addr_t translation_offset; /* optional translation offset */ +}; + static const struct driver_info root_info = { .name = "root_driver", }; @@ -37,6 +41,22 @@ struct udevice *dm_root(void) return gd->dm_root; } +fdt_addr_t dm_get_translation_offset(void) +{ + struct udevice *root = dm_root(); + struct root_priv *priv = dev_get_priv(root); + + return priv->translation_offset; +} + +void dm_set_translation_offset(fdt_addr_t offs) +{ + struct udevice *root = dm_root(); + struct root_priv *priv = dev_get_priv(root); + + priv->translation_offset = offs; +} + #if defined(CONFIG_NEEDS_MANUAL_RELOC) void fix_drivers(void) { @@ -228,6 +248,7 @@ int dm_init_and_scan(bool pre_reloc_only) U_BOOT_DRIVER(root_driver) = { .name = "root_driver", .id = UCLASS_ROOT, + .priv_auto_alloc_size = sizeof(struct root_priv), }; /* This is the root uclass */ diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index 37171bfa71..5fb71518c4 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -11,26 +11,25 @@ #include #include -int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported, - int num_ids) +int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported) { struct sdhci_host *mmc_host; - pci_dev_t devbusfn; u32 iobase; int ret; int i; - for (i = 0; i < num_ids; i++) { - devbusfn = pci_find_devices(mmc_supported, i); - if (devbusfn == -1) - return -ENODEV; + for (i = 0; ; i++) { + struct udevice *dev; + ret = pci_find_device_id(mmc_supported, i, &dev); + if (ret) + return ret; mmc_host = malloc(sizeof(struct sdhci_host)); if (!mmc_host) return -ENOMEM; mmc_host->name = (char *)name; - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase); mmc_host->ioaddr = (void *)iobase; mmc_host->quirks = 0; ret = add_sdhci(mmc_host, 0, 0); diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 72e0f6b3fb..95ffad476d 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -46,7 +46,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, void spi_flash_free(struct spi_flash *flash) { - spi_flash_remove(flash->spi->dev); + device_remove(flash->spi->dev); } int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, @@ -69,11 +69,6 @@ int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, return 0; } -int spi_flash_remove(struct udevice *dev) -{ - return device_remove(dev); -} - static int spi_flash_post_bind(struct udevice *dev) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index ed5c391dc2..007a5a085c 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -16,18 +16,18 @@ /* Dual SPI flash memories - see SPI_COMM_DUAL_... */ enum spi_dual_flash { SF_SINGLE_FLASH = 0, - SF_DUAL_STACKED_FLASH = 1 << 0, - SF_DUAL_PARALLEL_FLASH = 1 << 1, + SF_DUAL_STACKED_FLASH = BIT(0), + SF_DUAL_PARALLEL_FLASH = BIT(1), }; /* Enum list - Full read commands */ enum spi_read_cmds { - ARRAY_SLOW = 1 << 0, - ARRAY_FAST = 1 << 1, - DUAL_OUTPUT_FAST = 1 << 2, - DUAL_IO_FAST = 1 << 3, - QUAD_OUTPUT_FAST = 1 << 4, - QUAD_IO_FAST = 1 << 5, + ARRAY_SLOW = BIT(0), + ARRAY_FAST = BIT(1), + DUAL_OUTPUT_FAST = BIT(2), + QUAD_OUTPUT_FAST = BIT(3), + DUAL_IO_FAST = BIT(4), + QUAD_IO_FAST = BIT(5), }; /* Normal - Extended - Full command set */ @@ -37,20 +37,20 @@ enum spi_read_cmds { /* sf param flags */ enum { -#ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS - SECT_4K = 1 << 0, +#ifndef CONFIG_SPI_FLASH_USE_4K_SECTORS + SECT_4K = 0, #else - SECT_4K = 0 << 0, + SECT_4K = BIT(0), #endif - SECT_32K = 1 << 1, - E_FSR = 1 << 2, - SST_WR = 1 << 3, - WR_QPP = 1 << 4, + SECT_32K = BIT(1), + E_FSR = BIT(2), + SST_WR = BIT(3), + WR_QPP = BIT(4), }; enum spi_nor_option_flags { - SNOR_F_SST_WR = (1 << 0), - SNOR_F_USE_FSR = (1 << 1), + SNOR_F_SST_WR = BIT(0), + SNOR_F_USE_FSR = BIT(1), }; #define SPI_FLASH_3B_ADDR_LEN 3 @@ -75,12 +75,9 @@ enum spi_nor_option_flags { #define CMD_WRITE_STATUS 0x01 #define CMD_PAGE_PROGRAM 0x02 #define CMD_WRITE_DISABLE 0x04 -#define CMD_READ_STATUS 0x05 -#define CMD_QUAD_PAGE_PROGRAM 0x32 -#define CMD_READ_STATUS1 0x35 #define CMD_WRITE_ENABLE 0x06 -#define CMD_READ_CONFIG 0x35 -#define CMD_FLAG_STATUS 0x70 +#define CMD_QUAD_PAGE_PROGRAM 0x32 +#define CMD_WRITE_EVCR 0x61 /* Read commands */ #define CMD_READ_ARRAY_SLOW 0x03 @@ -90,6 +87,11 @@ enum spi_nor_option_flags { #define CMD_READ_QUAD_OUTPUT_FAST 0x6b #define CMD_READ_QUAD_IO_FAST 0xeb #define CMD_READ_ID 0x9f +#define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS1 0x35 +#define CMD_READ_CONFIG 0x35 +#define CMD_FLAG_STATUS 0x70 +#define CMD_READ_EVCR 0x65 /* Bank addr access commands */ #ifdef CONFIG_SPI_FLASH_BAR @@ -100,10 +102,11 @@ enum spi_nor_option_flags { #endif /* Common status */ -#define STATUS_WIP (1 << 0) -#define STATUS_QEB_WINSPAN (1 << 1) -#define STATUS_QEB_MXIC (1 << 6) -#define STATUS_PEC (1 << 7) +#define STATUS_WIP BIT(0) +#define STATUS_QEB_WINSPAN BIT(1) +#define STATUS_QEB_MXIC BIT(6) +#define STATUS_PEC BIT(7) +#define STATUS_QEB_MICRON BIT(7) #define SR_BP0 BIT(2) /* Block protect 0 */ #define SR_BP1 BIT(3) /* Block protect 1 */ #define SR_BP2 BIT(4) /* Block protect 2 */ diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 0cafc29123..daa1d5b249 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -128,7 +128,7 @@ static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, #if defined(CONFIG_SPI_FLASH_SST) if (flash->flags & SNOR_F_SST_WR) { - if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) + if (flash->spi->mode & SPI_TX_BYTE) return sst_write_bp(flash, offset, len, buf); else return sst_write_wp(flash, offset, len, buf); diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index b7b7f0044e..a567414669 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -29,16 +29,6 @@ static void spi_flash_addr(u32 addr, u8 *cmd) cmd[3] = addr >> 0; } -/* Read commands array */ -static u8 spi_read_cmds_array[] = { - CMD_READ_ARRAY_SLOW, - CMD_READ_ARRAY_FAST, - CMD_READ_DUAL_OUTPUT_FAST, - CMD_READ_DUAL_IO_FAST, - CMD_READ_QUAD_OUTPUT_FAST, - CMD_READ_QUAD_IO_FAST, -}; - static int read_sr(struct spi_flash *flash, u8 *rs) { int ret; @@ -121,6 +111,37 @@ static int write_cr(struct spi_flash *flash, u8 wc) } #endif +#ifdef CONFIG_SPI_FLASH_STMICRO +static int read_evcr(struct spi_flash *flash, u8 *evcr) +{ + int ret; + const u8 cmd = CMD_READ_EVCR; + + ret = spi_flash_read_common(flash, &cmd, 1, evcr, 1); + if (ret < 0) { + debug("SF: error reading EVCR\n"); + return ret; + } + + return 0; +} + +static int write_evcr(struct spi_flash *flash, u8 evcr) +{ + u8 cmd; + int ret; + + cmd = CMD_WRITE_EVCR; + ret = spi_flash_write_common(flash, &cmd, 1, &evcr, 1); + if (ret < 0) { + debug("SF: error while writing EVCR register\n"); + return ret; + } + + return 0; +} +#endif + #ifdef CONFIG_SPI_FLASH_BAR static int spi_flash_write_bar(struct spi_flash *flash, u32 offset) { @@ -149,7 +170,7 @@ static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) int ret; if (flash->size <= SPI_FLASH_16MB_BOUN) - goto bank_end; + goto bar_end; switch (idcode0) { case SPI_FLASH_CFI_MFR_SPANSION: @@ -168,7 +189,7 @@ static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) return ret; } -bank_end: +bar_end: flash->bank_curr = curr_bank; return 0; } @@ -177,13 +198,15 @@ bank_end: #ifdef CONFIG_SF_DUAL_FLASH static void spi_flash_dual(struct spi_flash *flash, u32 *addr) { + struct spi_slave *spi = flash->spi; + switch (flash->dual_flash) { case SF_DUAL_STACKED_FLASH: if (*addr >= (flash->size >> 1)) { *addr -= flash->size >> 1; - flash->spi->flags |= SPI_XFER_U_PAGE; + spi->flags |= SPI_XFER_U_PAGE; } else { - flash->spi->flags &= ~SPI_XFER_U_PAGE; + spi->flags &= ~SPI_XFER_U_PAGE; } break; case SF_DUAL_PARALLEL_FLASH: @@ -268,7 +291,7 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, if (buf == NULL) timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT; - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(spi); if (ret) { debug("SF: unable to claim SPI bus\n"); return ret; @@ -353,6 +376,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, size_t len, const void *buf) { + struct spi_slave *spi = flash->spi; unsigned long byte_addr, page_size; u32 write_addr; size_t chunk_len, actual; @@ -385,9 +409,9 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, byte_addr = offset % page_size; chunk_len = min(len - actual, (size_t)(page_size - byte_addr)); - if (flash->spi->max_write_size) + if (spi->max_write_size) chunk_len = min(chunk_len, - (size_t)flash->spi->max_write_size); + (size_t)spi->max_write_size); spi_flash_addr(write_addr, cmd); @@ -413,7 +437,7 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, struct spi_slave *spi = flash->spi; int ret; - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(spi); if (ret) { debug("SF: unable to claim SPI bus\n"); return ret; @@ -438,6 +462,7 @@ void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len) int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, size_t len, void *data) { + struct spi_slave *spi = flash->spi; u8 *cmd, cmdsz; u32 remain_len, read_len, read_addr; int bank_sel = 0; @@ -445,15 +470,15 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, /* Handle memory-mapped SPI */ if (flash->memory_map) { - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(spi); if (ret) { debug("SF: unable to claim SPI bus\n"); return ret; } - spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP); + spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP); spi_flash_copy_mmap(data, flash->memory_map + offset, len); - spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END); - spi_release_bus(flash->spi); + spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP_END); + spi_release_bus(spi); return 0; } @@ -505,6 +530,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, #ifdef CONFIG_SPI_FLASH_SST static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) { + struct spi_slave *spi = flash->spi; int ret; u8 cmd[4] = { CMD_SST_BP, @@ -514,13 +540,13 @@ static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) }; debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", - spi_w8r8(flash->spi, CMD_READ_STATUS), buf, cmd[0], offset); + spi_w8r8(spi, CMD_READ_STATUS), buf, cmd[0], offset); ret = spi_flash_cmd_write_enable(flash); if (ret) return ret; - ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1); + ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd), buf, 1); if (ret) return ret; @@ -530,11 +556,12 @@ static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, const void *buf) { + struct spi_slave *spi = flash->spi; size_t actual, cmd_len; int ret; u8 cmd[4]; - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(spi); if (ret) { debug("SF: Unable to claim SPI bus\n"); return ret; @@ -561,10 +588,10 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, for (; actual < len - 1; actual += 2) { debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", - spi_w8r8(flash->spi, CMD_READ_STATUS), buf + actual, + spi_w8r8(spi, CMD_READ_STATUS), buf + actual, cmd[0], offset); - ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len, + ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf + actual, 2); if (ret) { debug("SF: sst word program failed\n"); @@ -590,17 +617,18 @@ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, debug("SF: sst: program %s %zu bytes @ 0x%zx\n", ret ? "failure" : "success", len, offset - actual); - spi_release_bus(flash->spi); + spi_release_bus(spi); return ret; } int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, const void *buf) { + struct spi_slave *spi = flash->spi; size_t actual; int ret; - ret = spi_claim_bus(flash->spi); + ret = spi_claim_bus(spi); if (ret) { debug("SF: Unable to claim SPI bus\n"); return ret; @@ -621,7 +649,7 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, debug("SF: sst: program %s %zu bytes @ 0x%zx\n", ret ? "failure" : "success", len, offset - actual); - spi_release_bus(flash->spi); + spi_release_bus(spi); return ret; } #endif @@ -803,7 +831,7 @@ int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) #ifdef CONFIG_SPI_FLASH_MACRONIX -static int spi_flash_set_qeb_mxic(struct spi_flash *flash) +static int macronix_quad_enable(struct spi_flash *flash) { u8 qeb_status; int ret; @@ -812,12 +840,18 @@ static int spi_flash_set_qeb_mxic(struct spi_flash *flash) if (ret < 0) return ret; - if (qeb_status & STATUS_QEB_MXIC) { - debug("SF: mxic: QEB is already set\n"); - } else { - ret = write_sr(flash, STATUS_QEB_MXIC); - if (ret < 0) - return ret; + if (qeb_status & STATUS_QEB_MXIC) + return 0; + + ret = write_sr(flash, qeb_status | STATUS_QEB_MXIC); + if (ret < 0) + return ret; + + /* read SR and check it */ + ret = read_sr(flash, &qeb_status); + if (!(ret >= 0 && (qeb_status & STATUS_QEB_MXIC))) { + printf("SF: Macronix SR Quad bit not clear\n"); + return -EINVAL; } return ret; @@ -825,7 +859,7 @@ static int spi_flash_set_qeb_mxic(struct spi_flash *flash) #endif #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) -static int spi_flash_set_qeb_winspan(struct spi_flash *flash) +static int spansion_quad_enable(struct spi_flash *flash) { u8 qeb_status; int ret; @@ -834,34 +868,67 @@ static int spi_flash_set_qeb_winspan(struct spi_flash *flash) if (ret < 0) return ret; - if (qeb_status & STATUS_QEB_WINSPAN) { - debug("SF: winspan: QEB is already set\n"); - } else { - ret = write_cr(flash, STATUS_QEB_WINSPAN); - if (ret < 0) - return ret; + if (qeb_status & STATUS_QEB_WINSPAN) + return 0; + + ret = write_cr(flash, qeb_status | STATUS_QEB_WINSPAN); + if (ret < 0) + return ret; + + /* read CR and check it */ + ret = read_cr(flash, &qeb_status); + if (!(ret >= 0 && (qeb_status & STATUS_QEB_WINSPAN))) { + printf("SF: Spansion CR Quad bit not clear\n"); + return -EINVAL; + } + + return ret; +} +#endif + +#ifdef CONFIG_SPI_FLASH_STMICRO +static int micron_quad_enable(struct spi_flash *flash) +{ + u8 qeb_status; + int ret; + + ret = read_evcr(flash, &qeb_status); + if (ret < 0) + return ret; + + if (!(qeb_status & STATUS_QEB_MICRON)) + return 0; + + ret = write_evcr(flash, qeb_status & ~STATUS_QEB_MICRON); + if (ret < 0) + return ret; + + /* read EVCR and check it */ + ret = read_evcr(flash, &qeb_status); + if (!(ret >= 0 && !(qeb_status & STATUS_QEB_MICRON))) { + printf("SF: Micron EVCR Quad bit not clear\n"); + return -EINVAL; } return ret; } #endif -static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) +static int set_quad_mode(struct spi_flash *flash, u8 idcode0) { switch (idcode0) { #ifdef CONFIG_SPI_FLASH_MACRONIX case SPI_FLASH_CFI_MFR_MACRONIX: - return spi_flash_set_qeb_mxic(flash); + return macronix_quad_enable(flash); #endif #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) case SPI_FLASH_CFI_MFR_SPANSION: case SPI_FLASH_CFI_MFR_WINBOND: - return spi_flash_set_qeb_winspan(flash); + return spansion_quad_enable(flash); #endif #ifdef CONFIG_SPI_FLASH_STMICRO case SPI_FLASH_CFI_MFR_STMICRO: - debug("SF: QEB is volatile for %02x flash\n", idcode0); - return 0; + return micron_quad_enable(flash); #endif default: printf("SF: Need set QEB func for %02x flash\n", idcode0); @@ -902,9 +969,15 @@ int spi_flash_scan(struct spi_flash *flash) struct spi_slave *spi = flash->spi; const struct spi_flash_params *params; u16 jedec, ext_jedec; - u8 idcode[5]; - u8 cmd; + u8 cmd, idcode[5]; int ret; + static u8 spi_read_cmds_array[] = { + CMD_READ_ARRAY_SLOW, + CMD_READ_ARRAY_FAST, + CMD_READ_DUAL_OUTPUT_FAST, + CMD_READ_QUAD_OUTPUT_FAST, + CMD_READ_DUAL_IO_FAST, + CMD_READ_QUAD_IO_FAST }; /* Read the ID codes */ ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); @@ -950,7 +1023,7 @@ int spi_flash_scan(struct spi_flash *flash) /* Assign spi data */ flash->name = params->name; flash->memory_map = spi->memory_map; - flash->dual_flash = flash->spi->option; + flash->dual_flash = spi->option; /* Assign spi flash flags */ if (params->flags & SST_WR) @@ -961,7 +1034,7 @@ int spi_flash_scan(struct spi_flash *flash) flash->write = spi_flash_cmd_write_ops; #if defined(CONFIG_SPI_FLASH_SST) if (flash->flags & SNOR_F_SST_WR) { - if (flash->spi->op_mode_tx & SPI_OPM_TX_BP) + if (spi->mode & SPI_TX_BYTE) flash->write = sst_write_bp; else flash->write = sst_write_wp; @@ -1025,7 +1098,7 @@ int spi_flash_scan(struct spi_flash *flash) flash->sector_size = flash->erase_size; /* Look for the fastest read cmd */ - cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx); + cmd = fls(params->e_rd_cmd & spi->mode_rx); if (cmd) { cmd = spi_read_cmds_array[cmd - 1]; flash->read_cmd = cmd; @@ -1035,7 +1108,7 @@ int spi_flash_scan(struct spi_flash *flash) } /* Not require to look for fastest only two write cmds yet */ - if (params->flags & WR_QPP && flash->spi->op_mode_tx & SPI_OPM_TX_QPP) + if (params->flags & WR_QPP && spi->mode & SPI_TX_QUAD) flash->write_cmd = CMD_QUAD_PAGE_PROGRAM; else /* Go for default supported write cmd */ @@ -1045,7 +1118,7 @@ int spi_flash_scan(struct spi_flash *flash) if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { - ret = spi_flash_set_qeb(flash, idcode[0]); + ret = set_quad_mode(flash, idcode[0]); if (ret) { debug("SF: Fail to set QEB for %02x\n", idcode[0]); return -EINVAL; diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 04114a1244..0fccbc0040 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -584,7 +584,7 @@ static int designware_eth_probe(struct udevice *dev) * or via a PCI bridge, fill in platdata before we probe the hardware. */ if (device_is_on_pci_bus(dev)) { - pci_dev_t bdf = pci_get_bdf(dev); + pci_dev_t bdf = dm_pci_get_bdf(dev); dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase); iobase &= PCI_BASE_ADDRESS_MEM_MASK; diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 6124bf0ab3..70fc02ee5c 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -551,43 +551,6 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->use_eerd = true; eeprom->use_eewr = false; break; - - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - case e1000_ich8lan: - { - int32_t i = 0; - - eeprom->type = e1000_eeprom_ich8; - eeprom->use_eerd = false; - eeprom->use_eewr = false; - eeprom->word_size = E1000_SHADOW_RAM_WORDS; - uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw, - ICH_FLASH_GFPREG); - /* Zero the shadow RAM structure. But don't load it from NVM - * so as to save time for driver init */ - if (hw->eeprom_shadow_ram != NULL) { - for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { - hw->eeprom_shadow_ram[i].modified = false; - hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF; - } - } - - hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) * - ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size = ((flash_size >> 16) - & ICH_GFPREG_BASE_MASK) + 1; - hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK); - - hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size /= 2 * sizeof(uint16_t); - break; - } -#endif default: break; } @@ -838,14 +801,6 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, if (eeprom->use_eerd == true) return e1000_read_eeprom_eerd(hw, offset, words, data); - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - /* ICH EEPROM access is done via the ICH flash controller */ - if (eeprom->type == e1000_eeprom_ich8) - return e1000_read_eeprom_ich8(hw, offset, words, data); -#endif /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have * acquired the EEPROM at this point, so any returns should relase it */ if (eeprom->type == e1000_eeprom_spi) { @@ -1732,17 +1687,7 @@ e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6]) * occuring when accessing our register space */ E1000_WRITE_FLUSH(hw); } -#if 0 - /* Set the PCI priority bit correctly in the CTRL register. This - * determines if the adapter gives priority to receives, or if it - * gives equal priority to transmits and receives. Valid only on - * 82542 and 82543 silicon. - */ - if (hw->dma_fairness && hw->mac_type <= e1000_82543) { - ctrl = E1000_READ_REG(hw, CTRL); - E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); - } -#endif + switch (hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: @@ -1842,20 +1787,6 @@ e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6]) break; } -#if 0 - /* Clear all of the statistics registers (clear on read). It is - * important that we do this after we have tried to establish link - * because the symbol error count will increment wildly if there - * is no link. - */ - e1000_clear_hw_cntrs(hw); - - /* ICH8 No-snoop bits are opposite polarity. - * Set to snoop by default after reset. */ - if (hw->mac_type == e1000_ich8lan) - e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL); -#endif - if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) { ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); @@ -5230,10 +5161,6 @@ _e1000_disable(struct e1000_hw *hw) E1000_WRITE_REG(hw, RDH, 0); E1000_WRITE_REG(hw, RDT, 0); - /* put the card in its initial state */ -#if 0 - E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST); -#endif mdelay(10); } @@ -5359,7 +5286,6 @@ static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno, #ifndef CONFIG_E1000_NO_NVM /* Validate the EEPROM and get chipset information */ -#if !defined(CONFIG_MVBC_1G) if (e1000_init_eeprom_params(hw)) { E1000_ERR(hw, "EEPROM is invalid!\n"); return -EINVAL; @@ -5367,7 +5293,6 @@ static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno, if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) && e1000_validate_eeprom_checksum(hw)) return -ENXIO; -#endif e1000_read_mac_addr(hw, enetaddr); #endif e1000_get_bus_type(hw); @@ -5628,8 +5553,8 @@ static int e1000_eth_probe(struct udevice *dev) int ret; hw->name = dev->name; - ret = e1000_init_one(hw, trailing_strtol(dev->name), pci_get_bdf(dev), - plat->enetaddr); + ret = e1000_init_one(hw, trailing_strtol(dev->name), + dm_pci_get_bdf(dev), plat->enetaddr); if (ret < 0) { printf(pr_fmt("failed to initialize card: %d\n"), ret); return ret; diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index c851922ae5..e46edcd4e1 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -1093,11 +1093,6 @@ struct e1000_hw { e1000_media_type media_type; e1000_fc_type fc; e1000_bus_type bus_type; -#if 0 - e1000_bus_speed bus_speed; - e1000_bus_width bus_width; - uint32_t io_base; -#endif uint32_t asf_firmware_present; #ifndef CONFIG_E1000_NO_NVM uint32_t eeprom_semaphore_present; @@ -1116,29 +1111,11 @@ struct e1000_hw { uint32_t original_fc; uint32_t txcw; uint32_t autoneg_failed; -#if 0 - uint32_t max_frame_size; - uint32_t min_frame_size; - uint32_t mc_filter_type; - uint32_t num_mc_addrs; - uint32_t collision_delta; - uint32_t tx_packet_delta; - uint32_t ledctl_default; - uint32_t ledctl_mode1; - uint32_t ledctl_mode2; -#endif uint16_t autoneg_advertised; uint16_t pci_cmd_word; uint16_t fc_high_water; uint16_t fc_low_water; uint16_t fc_pause_time; -#if 0 - uint16_t current_ifs_val; - uint16_t ifs_min_val; - uint16_t ifs_max_val; - uint16_t ifs_step_size; - uint16_t ifs_ratio; -#endif uint16_t device_id; uint16_t vendor_id; uint16_t subsystem_id; @@ -1149,9 +1126,6 @@ struct e1000_hw { uint8_t forced_speed_duplex; uint8_t wait_autoneg_complete; uint8_t dma_fairness; -#if 0 - uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; -#endif bool disable_polarity_correction; bool speed_downgraded; bool get_link_status; @@ -1162,11 +1136,6 @@ struct e1000_hw { bool report_tx_early; bool phy_reset_disable; bool initialize_hw_bits_disable; -#if 0 - bool adaptive_ifs; - bool ifs_params_forced; - bool in_ifs_mode; -#endif e1000_smart_speed smart_speed; e1000_dsp_config dsp_config_state; }; diff --git a/drivers/net/e1000_spi.c b/drivers/net/e1000_spi.c index df72375238..576ddb8b24 100644 --- a/drivers/net/e1000_spi.c +++ b/drivers/net/e1000_spi.c @@ -182,22 +182,21 @@ static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, bool intr) * These have been tested to perform correctly, but they are not used by any * of the EEPROM commands at this time. */ -#if 0 -static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, bool intr) +static __maybe_unused int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, + bool intr) { u8 op[] = { SPI_EEPROM_DISABLE_WR }; e1000_standby_eeprom(hw); return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); } -static int e1000_spi_eeprom_write_status(struct e1000_hw *hw, - u8 status, bool intr) +static __maybe_unused int e1000_spi_eeprom_write_status(struct e1000_hw *hw, + u8 status, bool intr) { u8 op[] = { SPI_EEPROM_WRITE_STATUS, status }; e1000_standby_eeprom(hw); return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); } -#endif static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, bool intr) { diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c index dfc01000fc..1b4dd56d52 100644 --- a/drivers/net/pch_gbe.c +++ b/drivers/net/pch_gbe.c @@ -424,7 +424,7 @@ int pch_gbe_probe(struct udevice *dev) pci_dev_t devno; u32 iobase; - devno = pci_get_bdf(dev); + devno = dm_pci_get_bdf(dev); /* * The priv structure contains the descriptors and frame buffers which diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 19422c4a2a..9e60adf61a 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -513,8 +513,13 @@ static void rtl_flush_buffer(void *buf, size_t size) /************************************************************************** RECV - Receive a frame ***************************************************************************/ -static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase, +#ifdef CONFIG_DM_ETH +static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase, + uchar **packetp) +#else +static int rtl_recv_common(pci_dev_t dev, unsigned long dev_iobase, uchar **packetp) +#endif { /* return true if there's an ethernet packet ready to read */ /* nic->packet should contain data on return */ @@ -545,9 +550,16 @@ static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase, else tpc->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit + RX_BUF_SIZE); +#ifdef CONFIG_DM_ETH tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32( - pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long) + dm_pci_mem_to_phys(dev, + (pci_addr_t)(unsigned long) + tpc->RxBufferRing[cur_rx])); +#else + tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32( + pci_mem_to_phys(dev, (pci_addr_t)(unsigned long) tpc->RxBufferRing[cur_rx])); +#endif rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); #ifdef CONFIG_DM_ETH *packetp = rxdata; @@ -576,7 +588,7 @@ int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct rtl8169_private *priv = dev_get_priv(dev); - return rtl_recv_common(pci_get_bdf(dev), priv->iobase, packetp); + return rtl_recv_common(dev, priv->iobase, packetp); } #else static int rtl_recv(struct eth_device *dev) @@ -590,8 +602,13 @@ static int rtl_recv(struct eth_device *dev) /************************************************************************** SEND - Transmit a frame ***************************************************************************/ -static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase, +#ifdef CONFIG_DM_ETH +static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase, void *packet, int length) +#else +static int rtl_send_common(pci_dev_t dev, unsigned long dev_iobase, + void *packet, int length) +#endif { /* send the packet to destination */ @@ -618,8 +635,13 @@ static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase, ptxb[len++] = '\0'; tpc->TxDescArray[entry].buf_Haddr = 0; +#ifdef CONFIG_DM_ETH tpc->TxDescArray[entry].buf_addr = cpu_to_le32( - pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)ptxb)); + dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb)); +#else + tpc->TxDescArray[entry].buf_addr = cpu_to_le32( + pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)ptxb)); +#endif if (entry != (NUM_TX_DESC - 1)) { tpc->TxDescArray[entry].status = cpu_to_le32((OWNbit | FSbit | LSbit) | @@ -661,7 +683,7 @@ int rtl8169_eth_send(struct udevice *dev, void *packet, int length) { struct rtl8169_private *priv = dev_get_priv(dev); - return rtl_send_common(pci_get_bdf(dev), priv->iobase, packet, length); + return rtl_send_common(dev, priv->iobase, packet, length); } #else @@ -695,7 +717,11 @@ static void rtl8169_set_rx_mode(void) RTL_W32(MAR0 + 4, mc_filter[1]); } -static void rtl8169_hw_start(pci_dev_t bdf) +#ifdef CONFIG_DM_ETH +static void rtl8169_hw_start(struct udevice *dev) +#else +static void rtl8169_hw_start(pci_dev_t dev) +#endif { u32 i; @@ -740,11 +766,21 @@ static void rtl8169_hw_start(pci_dev_t bdf) tpc->cur_rx = 0; - RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(bdf, +#ifdef CONFIG_DM_ETH + RTL_W32(TxDescStartAddrLow, dm_pci_mem_to_phys(dev, (pci_addr_t)(unsigned long)tpc->TxDescArray)); +#else + RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(dev, + (pci_addr_t)(unsigned long)tpc->TxDescArray)); +#endif RTL_W32(TxDescStartAddrHigh, (unsigned long)0); +#ifdef CONFIG_DM_ETH + RTL_W32(RxDescStartAddrLow, dm_pci_mem_to_phys( + dev, (pci_addr_t)(unsigned long)tpc->RxDescArray)); +#else RTL_W32(RxDescStartAddrLow, pci_mem_to_phys( - bdf, (pci_addr_t)(unsigned long)tpc->RxDescArray)); + dev, (pci_addr_t)(unsigned long)tpc->RxDescArray)); +#endif RTL_W32(RxDescStartAddrHigh, (unsigned long)0); /* RTL-8169sc/8110sc or later version */ @@ -766,7 +802,11 @@ static void rtl8169_hw_start(pci_dev_t bdf) #endif } -static void rtl8169_init_ring(pci_dev_t bdf) +#ifdef CONFIG_DM_ETH +static void rtl8169_init_ring(struct udevice *dev) +#else +static void rtl8169_init_ring(pci_dev_t dev) +#endif { int i; @@ -794,8 +834,13 @@ static void rtl8169_init_ring(pci_dev_t bdf) cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; +#ifdef CONFIG_DM_ETH + tpc->RxDescArray[i].buf_addr = cpu_to_le32(dm_pci_mem_to_phys( + dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i])); +#else tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys( - bdf, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i])); + dev, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i])); +#endif rtl_flush_rx_desc(&tpc->RxDescArray[i]); } @@ -804,7 +849,11 @@ static void rtl8169_init_ring(pci_dev_t bdf) #endif } -static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr) +#ifdef CONFIG_DM_ETH +static void rtl8169_common_start(struct udevice *dev, unsigned char *enetaddr) +#else +static void rtl8169_common_start(pci_dev_t dev, unsigned char *enetaddr) +#endif { int i; @@ -813,8 +862,8 @@ static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr) printf ("%s\n", __FUNCTION__); #endif - rtl8169_init_ring(bdf); - rtl8169_hw_start(bdf); + rtl8169_init_ring(dev); + rtl8169_hw_start(dev); /* Construct a perfect filter frame with the mac address as first match * and broadcast for all others */ for (i = 0; i < 192; i++) @@ -837,7 +886,7 @@ static int rtl8169_eth_start(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); - rtl8169_common_start(pci_get_bdf(dev), plat->enetaddr); + rtl8169_common_start(dev, plat->enetaddr); return 0; } @@ -1130,10 +1179,9 @@ static int rtl8169_eth_probe(struct udevice *dev) region = 1; break; } - pci_read_config32(pci_get_bdf(dev), PCI_BASE_ADDRESS_0 + region * 4, - &iobase); + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0 + region * 4, &iobase); iobase &= ~0xf; - priv->iobase = (int)pci_mem_to_phys(pci_get_bdf(dev), iobase); + priv->iobase = (int)dm_pci_mem_to_phys(dev, iobase); ret = rtl_init(priv->iobase, dev->name, plat->enetaddr); if (ret < 0) { diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 6b761b453d..f8be9bf1ea 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -6,15 +6,16 @@ # ifneq ($(CONFIG_DM_PCI),) -obj-$(CONFIG_PCI) += pci-uclass.o +obj-y += pci_rom.o +obj-$(CONFIG_PCI) += pci-uclass.o pci_auto.o obj-$(CONFIG_DM_PCI_COMPAT) += pci_compat.o obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o obj-$(CONFIG_X86) += pci_x86.o else -obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PCI) += pci.o pci_auto_old.o endif -obj-$(CONFIG_PCI) += pci_auto_common.o pci_auto_old.o pci_common.o pci_rom.o +obj-$(CONFIG_PCI) += pci_auto_common.o pci_common.o obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 5fe30723c2..685df9d274 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) #include #endif +#include "pci_internal.h" DECLARE_GLOBAL_DATA_PTR; @@ -61,7 +63,7 @@ struct udevice *pci_get_controller(struct udevice *dev) return dev; } -pci_dev_t pci_get_bdf(struct udevice *dev) +pci_dev_t dm_pci_get_bdf(struct udevice *dev) { struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); struct udevice *bus = dev->parent; @@ -128,7 +130,7 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, return -ENODEV; } -int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp) +int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp) { struct udevice *bus; int ret; @@ -194,6 +196,65 @@ int pci_find_device_id(struct pci_device_id *ids, int index, return -ENODEV; } +static int dm_pci_bus_find_device(struct udevice *bus, unsigned int vendor, + unsigned int device, int *indexp, + struct udevice **devp) +{ + struct pci_child_platdata *pplat; + struct udevice *dev; + + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + pplat = dev_get_parent_platdata(dev); + if (pplat->vendor == vendor && pplat->device == device) { + if (!(*indexp)--) { + *devp = dev; + return 0; + } + } + } + + return -ENODEV; +} + +int dm_pci_find_device(unsigned int vendor, unsigned int device, int index, + struct udevice **devp) +{ + struct udevice *bus; + + /* Scan all known buses */ + for (uclass_first_device(UCLASS_PCI, &bus); + bus; + uclass_next_device(&bus)) { + if (!dm_pci_bus_find_device(bus, vendor, device, &index, devp)) + return device_probe(*devp); + } + *devp = NULL; + + return -ENODEV; +} + +int dm_pci_find_class(uint find_class, int index, struct udevice **devp) +{ + struct udevice *dev; + + /* Scan all known buses */ + for (pci_find_first_device(&dev); + dev; + pci_find_next_device(&dev)) { + struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); + + if (pplat->class == find_class && !index--) { + *devp = dev; + return device_probe(*devp); + } + } + *devp = NULL; + + return -ENODEV; +} + int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long value, enum pci_size_t size) { @@ -225,7 +286,8 @@ int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value, for (bus = dev; device_is_on_pci_bus(bus);) bus = bus->parent; - return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size); + return pci_bus_write_config(bus, dm_pci_get_bdf(dev), offset, value, + size); } @@ -290,7 +352,7 @@ int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep, for (bus = dev; device_is_on_pci_bus(bus);) bus = bus->parent; - return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep, + return pci_bus_read_config(bus, dm_pci_get_bdf(dev), offset, valuep, size); } @@ -403,7 +465,7 @@ int pci_auto_config_devices(struct udevice *bus) int ret; debug("%s: device %s\n", __func__, dev->name); - ret = pciauto_config_device(hose, pci_get_bdf(dev)); + ret = dm_pciauto_config_device(dev); if (ret < 0) return ret; max_bus = ret; @@ -418,26 +480,16 @@ int pci_auto_config_devices(struct udevice *bus) return sub_bus; } -int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) +int dm_pci_hose_probe_bus(struct udevice *bus) { - struct udevice *parent, *bus; int sub_bus; int ret; debug("%s\n", __func__); - parent = hose->bus; - - /* Find the bus within the parent */ - ret = pci_bus_find_devfn(parent, PCI_MASK_BUS(bdf), &bus); - if (ret) { - debug("%s: Cannot find device %x on bus %s: %d\n", __func__, - bdf, parent->name, ret); - return ret; - } sub_bus = pci_get_bus_max() + 1; debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name); - pciauto_prescan_setup_bridge(hose, bdf, sub_bus); + dm_pciauto_prescan_setup_bridge(bus, sub_bus); ret = device_probe(bus); if (ret) { @@ -451,7 +503,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) return -EPIPE; } sub_bus = pci_get_bus_max(); - pciauto_postscan_setup_bridge(hose, bdf, sub_bus); + dm_pciauto_postscan_setup_bridge(bus, sub_bus); return sub_bus; } @@ -622,9 +674,7 @@ int pci_bind_bus_devices(struct udevice *bus) /* Find this device in the device tree */ ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev); - /* Search for a driver */ - - /* If nothing in the device tree, bind a generic device */ + /* If nothing in the device tree, bind a device */ if (ret == -ENODEV) { struct pci_device_id find_id; ulong val; @@ -1004,6 +1054,154 @@ int pci_get_regions(struct udevice *dev, struct pci_region **iop, return (*iop != NULL) + (*memp != NULL) + (*prefp != NULL); } +u32 dm_pci_read_bar32(struct udevice *dev, int barnum) +{ + u32 addr; + int bar; + + bar = PCI_BASE_ADDRESS_0 + barnum * 4; + dm_pci_read_config32(dev, bar, &addr); + if (addr & PCI_BASE_ADDRESS_SPACE_IO) + return addr & PCI_BASE_ADDRESS_IO_MASK; + else + return addr & PCI_BASE_ADDRESS_MEM_MASK; +} + +static int _dm_pci_bus_to_phys(struct udevice *ctlr, + pci_addr_t bus_addr, unsigned long flags, + unsigned long skip_mask, phys_addr_t *pa) +{ + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + struct pci_region *res; + int i; + + for (i = 0; i < hose->region_count; i++) { + res = &hose->regions[i]; + + if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) + continue; + + if (res->flags & skip_mask) + continue; + + if (bus_addr >= res->bus_start && + (bus_addr - res->bus_start) < res->size) { + *pa = (bus_addr - res->bus_start + res->phys_start); + return 0; + } + } + + return 1; +} + +phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t bus_addr, + unsigned long flags) +{ + phys_addr_t phys_addr = 0; + struct udevice *ctlr; + int ret; + + /* The root controller has the region information */ + ctlr = pci_get_controller(dev); + + /* + * 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_TYPE) == PCI_REGION_MEM) { + ret = _dm_pci_bus_to_phys(ctlr, bus_addr, + flags, PCI_REGION_SYS_MEMORY, + &phys_addr); + if (!ret) + return phys_addr; + } + + ret = _dm_pci_bus_to_phys(ctlr, bus_addr, flags, 0, &phys_addr); + + if (ret) + puts("pci_hose_bus_to_phys: invalid physical address\n"); + + return phys_addr; +} + +int _dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, + unsigned long flags, unsigned long skip_mask, + pci_addr_t *ba) +{ + struct pci_region *res; + struct udevice *ctlr; + pci_addr_t bus_addr; + int i; + struct pci_controller *hose; + + /* The root controller has the region information */ + ctlr = pci_get_controller(dev); + hose = dev_get_uclass_priv(ctlr); + + for (i = 0; i < hose->region_count; i++) { + res = &hose->regions[i]; + + if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0) + continue; + + if (res->flags & skip_mask) + continue; + + bus_addr = phys_addr - res->phys_start + res->bus_start; + + if (bus_addr >= res->bus_start && + (bus_addr - res->bus_start) < res->size) { + *ba = bus_addr; + return 0; + } + } + + return 1; +} + +pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr, + unsigned long flags) +{ + pci_addr_t bus_addr = 0; + int ret; + + /* + * 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_TYPE) == PCI_REGION_MEM) { + ret = _dm_pci_phys_to_bus(dev, phys_addr, flags, + PCI_REGION_SYS_MEMORY, &bus_addr); + if (!ret) + return bus_addr; + } + + ret = _dm_pci_phys_to_bus(dev, phys_addr, flags, 0, &bus_addr); + + if (ret) + puts("pci_hose_phys_to_bus: invalid physical address\n"); + + return bus_addr; +} + +void *dm_pci_map_bar(struct udevice *dev, int bar, int flags) +{ + pci_addr_t pci_bus_addr; + u32 bar_response; + + /* read BAR address */ + dm_pci_read_config32(dev, bar, &bar_response); + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); + + /* + * Pass "0" as the length argument to pci_bus_to_virt. The arg + * isn't actualy used on any platform because u-boot assumes a static + * linear mapping. In the future, this could read the BAR size + * and pass that as the size if needed. + */ + return dm_pci_bus_to_virt(dev, pci_bus_addr, flags, 0, MAP_NOCACHE); +} + UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 645ecd423f..461908941d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -9,7 +9,10 @@ */ /* - * PCI routines + * Old PCI routines + * + * Do not change this file. Instead, convert your board to use CONFIG_DM_PCI + * and change pci-uclass.c. */ #include diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c new file mode 100644 index 0000000000..842eafc4f8 --- /dev/null +++ b/drivers/pci/pci_auto.c @@ -0,0 +1,386 @@ +/* + * PCI autoconfiguration library + * + * Author: Matt Porter + * + * Copyright 2000 MontaVista Software Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */ +#ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE +#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8 +#endif + +void dm_pciauto_setup_device(struct udevice *dev, int bars_num, + struct pci_region *mem, + struct pci_region *prefetch, struct pci_region *io, + bool enum_only) +{ + u32 bar_response; + pci_size_t bar_size; + u16 cmdstat = 0; + int bar, bar_nr = 0; + u8 header_type; + int rom_addr; + pci_addr_t bar_value; + struct pci_region *bar_res; + int found_mem64 = 0; + u16 class; + + dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat); + cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | + PCI_COMMAND_MASTER; + + for (bar = PCI_BASE_ADDRESS_0; + bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { + /* Tickle the BAR and get the response */ + if (!enum_only) + dm_pci_write_config32(dev, bar, 0xffffffff); + dm_pci_read_config32(dev, bar, &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + found_mem64 = 0; + + /* Check the BAR type and set our address mask */ + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) + & 0xffff) + 1; + if (!enum_only) + bar_res = io; + + debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", + bar_nr, (unsigned long long)bar_size); + } else { + if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) { + u32 bar_response_upper; + u64 bar64; + + if (!enum_only) { + dm_pci_write_config32(dev, bar + 4, + 0xffffffff); + } + dm_pci_read_config32(dev, bar + 4, + &bar_response_upper); + + bar64 = ((u64)bar_response_upper << 32) | + bar_response; + + bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + + 1; + if (!enum_only) + found_mem64 = 1; + } else { + bar_size = (u32)(~(bar_response & + PCI_BASE_ADDRESS_MEM_MASK) + 1); + } + if (!enum_only) { + if (prefetch && (bar_response & + PCI_BASE_ADDRESS_MEM_PREFETCH)) { + bar_res = prefetch; + } else { + bar_res = mem; + } + } + + debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ", + bar_nr, bar_res == prefetch ? "Prf" : "Mem", + (unsigned long long)bar_size); + } + + if (!enum_only && pciauto_region_allocate(bar_res, bar_size, + &bar_value) == 0) { + /* Write it out and update our limit */ + dm_pci_write_config32(dev, bar, (u32)bar_value); + + if (found_mem64) { + bar += 4; +#ifdef CONFIG_SYS_PCI_64BIT + dm_pci_write_config32(dev, bar, + (u32)(bar_value >> 32)); +#else + /* + * If we are a 64-bit decoder then increment to + * the upper 32 bits of the bar and force it to + * locate in the lower 4GB of memory. + */ + dm_pci_write_config32(dev, bar, 0x00000000); +#endif + } + } + + cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? + PCI_COMMAND_IO : PCI_COMMAND_MEMORY; + + debug("\n"); + + bar_nr++; + } + + if (!enum_only) { + /* Configure the expansion ROM address */ + dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type); + header_type &= 0x7f; + if (header_type != PCI_HEADER_TYPE_CARDBUS) { + rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ? + PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1; + dm_pci_write_config32(dev, rom_addr, 0xfffffffe); + dm_pci_read_config32(dev, rom_addr, &bar_response); + if (bar_response) { + bar_size = -(bar_response & ~1); + debug("PCI Autoconfig: ROM, size=%#x, ", + (unsigned int)bar_size); + if (pciauto_region_allocate(mem, bar_size, + &bar_value) == 0) { + dm_pci_write_config32(dev, rom_addr, + bar_value); + } + cmdstat |= PCI_COMMAND_MEMORY; + debug("\n"); + } + } + } + + /* PCI_COMMAND_IO must be set for VGA device */ + dm_pci_read_config16(dev, PCI_CLASS_DEVICE, &class); + if (class == PCI_CLASS_DISPLAY_VGA) + cmdstat |= PCI_COMMAND_IO; + + dm_pci_write_config16(dev, PCI_COMMAND, cmdstat); + dm_pci_write_config8(dev, PCI_CACHE_LINE_SIZE, + CONFIG_SYS_PCI_CACHE_LINE_SIZE); + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x80); +} + +void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) +{ + struct pci_region *pci_mem; + struct pci_region *pci_prefetch; + struct pci_region *pci_io; + u16 cmdstat, prefechable_64; + /* The root controller has the region information */ + struct pci_controller *ctlr_hose = pci_bus_to_hose(0); + + pci_mem = ctlr_hose->pci_mem; + pci_prefetch = ctlr_hose->pci_prefetch; + pci_io = ctlr_hose->pci_io; + + dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat); + dm_pci_read_config16(dev, PCI_PREF_MEMORY_BASE, &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; + + /* Configure bus number registers */ + dm_pci_write_config8(dev, PCI_PRIMARY_BUS, + PCI_BUS(dm_pci_get_bdf(dev))); + dm_pci_write_config8(dev, PCI_SECONDARY_BUS, sub_bus); + dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff); + + if (pci_mem) { + /* Round memory allocator to 1MB boundary */ + pciauto_region_align(pci_mem, 0x100000); + + /* + * Set up memory and I/O filter limits, assume 32-bit + * I/O space + */ + dm_pci_write_config16(dev, PCI_MEMORY_BASE, + (pci_mem->bus_lower & 0xfff00000) >> 16); + + cmdstat |= PCI_COMMAND_MEMORY; + } + + if (pci_prefetch) { + /* Round memory allocator to 1MB boundary */ + pciauto_region_align(pci_prefetch, 0x100000); + + /* + * Set up memory and I/O filter limits, assume 32-bit + * I/O space + */ + dm_pci_write_config16(dev, PCI_PREF_MEMORY_BASE, + (pci_prefetch->bus_lower & 0xfff00000) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + dm_pci_write_config32(dev, PCI_PREF_BASE_UPPER32, + pci_prefetch->bus_lower >> 32); +#else + dm_pci_write_config32(dev, PCI_PREF_BASE_UPPER32, 0x0); +#endif + + cmdstat |= PCI_COMMAND_MEMORY; + } else { + /* We don't support prefetchable memory for now, so disable */ + dm_pci_write_config16(dev, PCI_PREF_MEMORY_BASE, 0x1000); + dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, 0x0); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) { + dm_pci_write_config16(dev, PCI_PREF_BASE_UPPER32, 0x0); + dm_pci_write_config16(dev, PCI_PREF_LIMIT_UPPER32, 0x0); + } + } + + if (pci_io) { + /* Round I/O allocator to 4KB boundary */ + pciauto_region_align(pci_io, 0x1000); + + dm_pci_write_config8(dev, PCI_IO_BASE, + (pci_io->bus_lower & 0x0000f000) >> 8); + dm_pci_write_config16(dev, PCI_IO_BASE_UPPER16, + (pci_io->bus_lower & 0xffff0000) >> 16); + + cmdstat |= PCI_COMMAND_IO; + } + + /* Enable memory and I/O accesses, enable bus master */ + dm_pci_write_config16(dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER); +} + +void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) +{ + struct pci_region *pci_mem; + struct pci_region *pci_prefetch; + struct pci_region *pci_io; + + /* The root controller has the region information */ + struct pci_controller *ctlr_hose = pci_bus_to_hose(0); + + pci_mem = ctlr_hose->pci_mem; + pci_prefetch = ctlr_hose->pci_prefetch; + pci_io = ctlr_hose->pci_io; + + /* Configure bus number registers */ + dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus); + + if (pci_mem) { + /* Round memory allocator to 1MB boundary */ + pciauto_region_align(pci_mem, 0x100000); + + dm_pci_write_config16(dev, PCI_MEMORY_LIMIT, + (pci_mem->bus_lower - 1) >> 16); + } + + if (pci_prefetch) { + u16 prefechable_64; + + dm_pci_read_config16(dev, PCI_PREF_MEMORY_LIMIT, + &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; + + /* Round memory allocator to 1MB boundary */ + pciauto_region_align(pci_prefetch, 0x100000); + + dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, + (pci_prefetch->bus_lower - 1) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + dm_pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, + (pci_prefetch->bus_lower - 1) >> 32); +#else + dm_pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, 0x0); +#endif + } + + if (pci_io) { + /* Round I/O allocator to 4KB boundary */ + pciauto_region_align(pci_io, 0x1000); + + dm_pci_write_config8(dev, PCI_IO_LIMIT, + ((pci_io->bus_lower - 1) & 0x0000f000) >> 8); + dm_pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, + ((pci_io->bus_lower - 1) & 0xffff0000) >> 16); + } +} + +/* + * HJF: Changed this to return int. I think this is required + * to get the correct result when scanning bridges + */ +int dm_pciauto_config_device(struct udevice *dev) +{ + struct pci_region *pci_mem; + struct pci_region *pci_prefetch; + struct pci_region *pci_io; + unsigned int sub_bus = PCI_BUS(dm_pci_get_bdf(dev)); + unsigned short class; + bool enum_only = false; + int n; + +#ifdef CONFIG_PCI_ENUM_ONLY + enum_only = true; +#endif + /* The root controller has the region information */ + struct pci_controller *ctlr_hose = pci_bus_to_hose(0); + + pci_mem = ctlr_hose->pci_mem; + pci_prefetch = ctlr_hose->pci_prefetch; + pci_io = ctlr_hose->pci_io; + + dm_pci_read_config16(dev, PCI_CLASS_DEVICE, &class); + + switch (class) { + case PCI_CLASS_BRIDGE_PCI: + debug("PCI Autoconfig: Found P2P bridge, device %d\n", + PCI_DEV(dm_pci_get_bdf(dev))); + + dm_pciauto_setup_device(dev, 2, pci_mem, pci_prefetch, pci_io, + enum_only); + + n = dm_pci_hose_probe_bus(dev); + if (n < 0) + return n; + sub_bus = (unsigned int)n; + break; + + case PCI_CLASS_BRIDGE_CARDBUS: + /* + * just do a minimal setup of the bridge, + * let the OS take care of the rest + */ + dm_pciauto_setup_device(dev, 0, pci_mem, pci_prefetch, pci_io, + enum_only); + + debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n", + PCI_DEV(dm_pci_get_bdf(dev))); + + break; + +#if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE) + case PCI_CLASS_BRIDGE_OTHER: + debug("PCI Autoconfig: Skipping bridge device %d\n", + PCI_DEV(dm_pci_get_bdf(dev))); + break; +#endif +#if defined(CONFIG_MPC834x) && !defined(CONFIG_VME8349) + case PCI_CLASS_BRIDGE_OTHER: + /* + * The host/PCI bridge 1 seems broken in 8349 - it presents + * itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_ + * device claiming resources io/mem/irq.. we only allow for + * the PIMMR window to be allocated (BAR0 - 1MB size) + */ + debug("PCI Autoconfig: Broken bridge found, only minimal config\n"); + dm_pciauto_setup_device(dev, 0, hose->pci_mem, + hose->pci_prefetch, hose->pci_io, + enum_only); + break; +#endif + + case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ + debug("PCI AutoConfig: Found PowerPC device\n"); + + default: + dm_pciauto_setup_device(dev, 6, pci_mem, pci_prefetch, pci_io, + enum_only); + break; + } + + return sub_bus; +} diff --git a/drivers/pci/pci_auto_old.c b/drivers/pci/pci_auto_old.c index 932eab85bf..9126f78b89 100644 --- a/drivers/pci/pci_auto_old.c +++ b/drivers/pci/pci_auto_old.c @@ -1,7 +1,5 @@ /* - * arch/powerpc/kernel/pci_auto.c - * - * PCI autoconfiguration library + * PCI autoconfiguration library (legacy version, do not change) * * Author: Matt Porter * @@ -14,6 +12,11 @@ #include #include +/* + * Do not change this file. Instead, convert your board to use CONFIG_DM_PCI + * and change pci_auto.c. + */ + /* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */ #ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8 @@ -177,18 +180,9 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_io; u16 cmdstat, prefechable_64; -#ifdef CONFIG_DM_PCI - /* The root controller has the region information */ - struct pci_controller *ctlr_hose = pci_bus_to_hose(0); - - pci_mem = ctlr_hose->pci_mem; - pci_prefetch = ctlr_hose->pci_prefetch; - pci_io = ctlr_hose->pci_io; -#else pci_mem = hose->pci_mem; pci_prefetch = hose->pci_prefetch; pci_io = hose->pci_io; -#endif pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE, @@ -196,15 +190,10 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; /* Configure bus number registers */ -#ifdef CONFIG_DM_PCI - pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev)); - pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus); -#else pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev) - hose->first_busno); pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus - hose->first_busno); -#endif pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { @@ -271,26 +260,13 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_prefetch; struct pci_region *pci_io; -#ifdef CONFIG_DM_PCI - /* The root controller has the region information */ - struct pci_controller *ctlr_hose = pci_bus_to_hose(0); - - pci_mem = ctlr_hose->pci_mem; - pci_prefetch = ctlr_hose->pci_prefetch; - pci_io = ctlr_hose->pci_io; -#else pci_mem = hose->pci_mem; pci_prefetch = hose->pci_prefetch; pci_io = hose->pci_io; -#endif /* Configure bus number registers */ -#ifdef CONFIG_DM_PCI - pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus); -#else pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus - hose->first_busno); -#endif if (pci_mem) { /* Round memory allocator to 1MB boundary */ @@ -350,18 +326,9 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) unsigned short class; int n; -#ifdef CONFIG_DM_PCI - /* The root controller has the region information */ - struct pci_controller *ctlr_hose = pci_bus_to_hose(0); - - pci_mem = ctlr_hose->pci_mem; - pci_prefetch = ctlr_hose->pci_prefetch; - pci_io = ctlr_hose->pci_io; -#else pci_mem = hose->pci_mem; pci_prefetch = hose->pci_prefetch; pci_io = hose->pci_io; -#endif pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); @@ -373,12 +340,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pciauto_setup_device(hose, dev, 2, pci_mem, pci_prefetch, pci_io); -#ifdef CONFIG_DM_PCI - n = dm_pci_hose_probe_bus(hose, dev); - if (n < 0) - return n; - sub_bus = (unsigned int)n; -#else /* Passing in current_busno allows for sibling P2P bridges */ hose->current_busno++; pciauto_prescan_setup_bridge(hose, dev, hose->current_busno); @@ -393,7 +354,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pciauto_postscan_setup_bridge(hose, dev, sub_bus); sub_bus = hose->current_busno; -#endif break; case PCI_CLASS_BRIDGE_CARDBUS: @@ -407,9 +367,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev)); -#ifndef CONFIG_DM_PCI hose->current_busno++; -#endif break; #if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE) diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c index 2a149022e2..1755914b4e 100644 --- a/drivers/pci/pci_common.c +++ b/drivers/pci/pci_common.c @@ -79,48 +79,6 @@ const char *pci_class_str(u8 class) }; } -pci_dev_t pci_find_class(uint find_class, int index) -{ - int bus; - int devnum; - pci_dev_t bdf; - uint32_t class; - - for (bus = 0; bus <= pci_last_busno(); bus++) { - for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { - pci_read_config_dword(PCI_BDF(bus, devnum, 0), - PCI_CLASS_REVISION, &class); - if (class >> 16 == 0xffff) - continue; - - for (bdf = PCI_BDF(bus, devnum, 0); - bdf <= PCI_BDF(bus, devnum, - PCI_MAX_PCI_FUNCTIONS - 1); - bdf += PCI_BDF(0, 0, 1)) { - pci_read_config_dword(bdf, PCI_CLASS_REVISION, - &class); - class >>= 8; - - if (class != find_class) - continue; - /* - * Decrement the index. We want to return the - * correct device, so index is 0 for the first - * matching device, 1 for the second, etc. - */ - if (index) { - index--; - continue; - } - /* Return index'th controller. */ - return bdf; - } - } - } - - return -ENODEV; -} - __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) { /* @@ -141,6 +99,7 @@ __weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) return 0; } +#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT) /* Get a virtual address associated with a BAR region */ void *pci_map_bar(pci_dev_t pdev, int bar, int flags) { @@ -363,3 +322,46 @@ pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum, return -1; } + +pci_dev_t pci_find_class(uint find_class, int index) +{ + int bus; + int devnum; + pci_dev_t bdf; + uint32_t class; + + for (bus = 0; bus <= pci_last_busno(); bus++) { + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { + pci_read_config_dword(PCI_BDF(bus, devnum, 0), + PCI_CLASS_REVISION, &class); + if (class >> 16 == 0xffff) + continue; + + for (bdf = PCI_BDF(bus, devnum, 0); + bdf <= PCI_BDF(bus, devnum, + PCI_MAX_PCI_FUNCTIONS - 1); + bdf += PCI_BDF(0, 0, 1)) { + pci_read_config_dword(bdf, PCI_CLASS_REVISION, + &class); + class >>= 8; + + if (class != find_class) + continue; + /* + * Decrement the index. We want to return the + * correct device, so index is 0 for the first + * matching device, 1 for the second, etc. + */ + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; + } + } + } + + return -ENODEV; +} +#endif /* !CONFIG_DM_PCI || CONFIG_DM_PCI_COMPAT */ diff --git a/drivers/pci/pci_compat.c b/drivers/pci/pci_compat.c index 712c48f28f..dd15eb19f8 100644 --- a/drivers/pci/pci_compat.c +++ b/drivers/pci/pci_compat.c @@ -34,5 +34,5 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) if (pci_find_device_id(ids, index, &dev)) return -1; - return pci_get_bdf(dev); + return dm_pci_get_bdf(dev); } diff --git a/drivers/pci/pci_internal.h b/drivers/pci/pci_internal.h new file mode 100644 index 0000000000..0867575a58 --- /dev/null +++ b/drivers/pci/pci_internal.h @@ -0,0 +1,50 @@ +/* + * Internal PCI functions, not exported outside drivers/pci + * + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __pci_internal_h +#define __pci_internal_h + +/** + * dm_pciauto_prescan_setup_bridge() - Set up a bridge for scanning + * + * This gets a bridge ready so that its downstream devices can be scanned. + * It sets up the bus number and memory range registers. Once the scan is + * completed, dm_pciauto_postscan_setup_bridge() should be called. + * + * @dev: Bridge device to be scanned + * @sub_bus: Bus number of the 'other side' of the bridge + */ +void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus); + +/** + * dm_pciauto_postscan_setup_bridge() - Finish set up of a bridge after scanning + * + * This should be called after a bus scan is complete. It adjusts the memory + * ranges to fit with the devices actually found on the other side (downstream) + * of the bridge. + * + * @dev: Bridge device that was scanned + * @sub_bus: Bus number of the 'other side' of the bridge + */ +void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus); + +/** + * dm_pciauto_config_device() - Configure a PCI device ready for use + * + * If the device is a bridge, downstream devices will be probed. + * + * @dev: Device to configure + * @return the maximum PCI bus number found by this device. If there are no + * bridges, this just returns the device's bus number. If the device is a + * bridge then it will return a larger number, depending on the devices on + * that bridge. On error, returns a -ve error number. + */ +int dm_pciauto_config_device(struct udevice *dev); + +#endif diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index ad1167e2b6..2cb81b66b7 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -33,12 +34,12 @@ #include #include -__weak bool board_should_run_oprom(pci_dev_t dev) +__weak bool board_should_run_oprom(struct udevice *dev) { return true; } -static bool should_load_oprom(pci_dev_t dev) +static bool should_load_oprom(struct udevice *dev) { if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM)) return 1; @@ -53,21 +54,18 @@ __weak uint32_t board_map_oprom_vendev(uint32_t vendev) return vendev; } -static int pci_rom_probe(pci_dev_t dev, uint class, - struct pci_rom_header **hdrp) +static int pci_rom_probe(struct udevice *dev, struct pci_rom_header **hdrp) { + struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); struct pci_rom_header *rom_header; struct pci_rom_data *rom_data; - u16 vendor, device; u16 rom_vendor, rom_device; u32 rom_class; u32 vendev; u32 mapped_vendev; u32 rom_address; - pci_read_config_word(dev, PCI_VENDOR_ID, &vendor); - pci_read_config_word(dev, PCI_DEVICE_ID, &device); - vendev = vendor << 16 | device; + vendev = pplat->vendor << 16 | pplat->device; mapped_vendev = board_map_oprom_vendev(vendev); if (vendev != mapped_vendev) debug("Device ID mapped to %#08x\n", mapped_vendev); @@ -76,15 +74,15 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_address = CONFIG_VGA_BIOS_ADDR; #else - pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); + dm_pci_read_config32(dev, PCI_ROM_ADDRESS, &rom_address); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { debug("%s: rom_address=%x\n", __func__, rom_address); return -ENOENT; } /* Enable expansion ROM address decoding. */ - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - rom_address | PCI_ROM_ADDRESS_ENABLE); + dm_pci_write_config32(dev, PCI_ROM_ADDRESS, + rom_address | PCI_ROM_ADDRESS_ENABLE); #endif debug("Option ROM address %x\n", rom_address); rom_header = (struct pci_rom_header *)(unsigned long)rom_address; @@ -98,7 +96,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, le16_to_cpu(rom_header->signature)); #ifndef CONFIG_VGA_BIOS_ADDR /* Disable expansion ROM address decoding */ - pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address); + dm_pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address); #endif return -EINVAL; } @@ -111,7 +109,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_vendor, rom_device); /* If the device id is mapped, a mismatch is expected */ - if ((vendor != rom_vendor || device != rom_device) && + if ((pplat->vendor != rom_vendor || pplat->device != rom_device) && (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", rom_vendor, rom_device); @@ -122,9 +120,9 @@ static int pci_rom_probe(pci_dev_t dev, uint class, debug("PCI ROM image, Class Code %06x, Code Type %02x\n", rom_class, rom_data->type); - if (class != rom_class) { + if (pplat->class != rom_class) { debug("Class Code mismatch ROM %06x, dev %06x\n", - rom_class, class); + rom_class, pplat->class); } *hdrp = rom_header; @@ -251,27 +249,26 @@ void setup_video(struct screen_info *screen_info) screen_info->rsvd_pos = vesa->reserved_mask_pos; } -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) +int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void), + int exec_method) { + struct pci_child_platdata *pplat = dev_get_parent_platdata(dev); struct pci_rom_header *rom, *ram; int vesa_mode = -1; - uint class; bool emulate; int ret; /* Only execute VGA ROMs */ - pci_read_config_dword(dev, PCI_REVISION_ID, &class); - if (((class >> 16) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) { - debug("%s: Class %#x, should be %#x\n", __func__, class, + if (((pplat->class >> 8) ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) { + debug("%s: Class %#x, should be %#x\n", __func__, pplat->class, PCI_CLASS_DISPLAY_VGA); return -ENODEV; } - class >>= 8; if (!should_load_oprom(dev)) return -ENXIO; - ret = pci_rom_probe(dev, class, &rom); + ret = pci_rom_probe(dev, &rom); if (ret) return ret; @@ -314,12 +311,12 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) #ifdef CONFIG_BIOSEMU BE_VGAInfo *info; - ret = biosemu_setup(dev, &info); + ret = biosemu_setup(dm_pci_get_bdf(dev), &info); if (ret) return ret; biosemu_set_interrupt_handler(0x15, int15_handler); - ret = biosemu_run(dev, (uchar *)ram, 1 << 16, info, true, - vesa_mode, &mode_info); + ret = biosemu_run(dm_pci_get_bdf(dev), (uchar *)ram, 1 << 16, + info, true, vesa_mode, &mode_info); if (ret) return ret; #endif diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1fc287ee98..04541c9ff3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -15,6 +15,26 @@ config REQUIRE_SERIAL_CONSOLE during serial port initialization (default y). Set this to n on boards which have no debug serial port whatsoever. +config SERIAL_PRESENT + bool "Provide a serial driver" + depends on DM_SERIAL + default y + help + In very space-constrained devices even the full UART driver is too + large. In this case the debug UART can still be used in some cases. + This option enables the full UART in U-Boot, so if is it disabled, + the full UART driver will be omitted, thus saving space. + +config SPL_SERIAL_PRESENT + bool "Provide a serial driver in SPL" + depends on DM_SERIAL + default y + help + In very space-constrained devices even the full UART driver is too + large. In this case the debug UART can still be used in some cases. + This option enables the full UART in SPL, so if is it disabled, + the full UART driver will be omitted, thus saving space. + config DM_SERIAL bool "Enable Driver Model for serial drivers" depends on DM diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 3fab3f1efb..021b211ab4 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -368,7 +368,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) /* try Processor Local Bus device first */ addr = dev_get_addr(dev); -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI) if (addr == FDT_ADDR_T_NONE) { /* then try pci device */ struct fdt_pci_addr pci_addr; @@ -389,8 +389,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) return ret; } - ret = fdtdec_get_pci_bar32(gd->fdt_blob, dev->of_offset, - &pci_addr, &bar); + ret = fdtdec_get_pci_bar32(dev, &pci_addr, &bar); if (ret) return ret; @@ -440,6 +439,7 @@ static const struct udevice_id ns16550_serial_ids[] = { }; #endif +#if CONFIG_IS_ENABLED(SERIAL_PRESENT) U_BOOT_DRIVER(ns16550_serial) = { .name = "ns16550_serial", .id = UCLASS_SERIAL, @@ -453,4 +453,5 @@ U_BOOT_DRIVER(ns16550_serial) = { .ops = &ns16550_serial_ops, .flags = DM_FLAG_PRE_RELOC, }; +#endif #endif /* CONFIG_DM_SERIAL */ diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 4bf9a5c681..1c447ff27a 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -204,7 +204,7 @@ void serial_stdio_init(void) { } -#ifdef CONFIG_DM_STDIO +#if defined(CONFIG_DM_STDIO) && CONFIG_IS_ENABLED(SERIAL_PRESENT) static void serial_stub_putc(struct stdio_dev *sdev, const char ch) { _serial_putc(sdev->priv, ch); @@ -287,6 +287,7 @@ static int on_baudrate(const char *name, const char *value, enum env_op op, } U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); +#if CONFIG_IS_ENABLED(SERIAL_PRESENT) static int serial_post_probe(struct udevice *dev) { struct dm_serial_ops *ops = serial_get_ops(dev); @@ -356,3 +357,4 @@ UCLASS_DRIVER(serial) = { .pre_remove = serial_pre_remove, .per_device_auto_alloc_size = sizeof(struct serial_dev_priv), }; +#endif diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index f85af9c9fb..59eaaea693 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -752,8 +752,8 @@ static int ich_spi_child_pre_probe(struct udevice *dev) * and byte program command for SST flash */ if (plat->ich_version == 7) { - slave->op_mode_rx = SPI_OPM_RX_AS; - slave->op_mode_tx = SPI_OPM_TX_BP; + slave->mode_rx = SPI_RX_SLOW; + slave->mode = SPI_TX_BYTE; } return 0; diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index e0f6b25f30..677c020b11 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -157,6 +157,7 @@ static int spi_child_pre_probe(struct udevice *dev) slave->max_hz = plat->max_hz; slave->mode = plat->mode; + slave->mode_rx = plat->mode_rx; return 0; } @@ -368,7 +369,8 @@ void spi_free_slave(struct spi_slave *slave) int spi_slave_ofdata_to_platdata(const void *blob, int node, struct dm_spi_slave_platdata *plat) { - int mode = 0; + int mode = 0, mode_rx = 0; + int value; plat->cs = fdtdec_get_int(blob, node, "reg", -1); plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0); @@ -382,8 +384,42 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node, mode |= SPI_3WIRE; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; + + /* Device DUAL/QUAD mode */ + value = fdtdec_get_uint(blob, node, "spi-tx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + mode |= SPI_TX_DUAL; + break; + case 4: + mode |= SPI_TX_QUAD; + break; + default: + error("spi-tx-bus-width %d not supported\n", value); + break; + } + plat->mode = mode; + value = fdtdec_get_uint(blob, node, "spi-rx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + mode_rx |= SPI_RX_DUAL; + break; + case 4: + mode_rx |= SPI_RX_QUAD; + break; + default: + error("spi-rx-bus-width %d not supported\n", value); + break; + } + + plat->mode_rx = mode_rx; + return 0; } diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 5747ed1fa9..78d8b1368d 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -11,11 +11,14 @@ #include #include #include +#include #include #include #include #include +DECLARE_GLOBAL_DATA_PTR; + /* ti qpsi register bit masks */ #define QSPI_TIMEOUT 2000000 #define QSPI_FCLK 192000000 @@ -41,19 +44,21 @@ #define QSPI_WC_BUSY (QSPI_WC | QSPI_BUSY) #define QSPI_XFER_DONE QSPI_WC #define MM_SWITCH 0x01 -#define MEM_CS 0x100 +#define MEM_CS(cs) ((cs + 1) << 8) #define MEM_CS_UNSELECT 0xfffff0ff #define MMAP_START_ADDR_DRA 0x5c000000 #define MMAP_START_ADDR_AM43x 0x30000000 #define CORE_CTRL_IO 0x4a002558 #define QSPI_CMD_READ (0x3 << 0) +#define QSPI_CMD_READ_DUAL (0x6b << 0) #define QSPI_CMD_READ_QUAD (0x6b << 0) #define QSPI_CMD_READ_FAST (0x0b << 0) #define QSPI_SETUP0_NUM_A_BYTES (0x2 << 8) #define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10) #define QSPI_SETUP0_NUM_D_BYTES_8_BITS (0x1 << 10) #define QSPI_SETUP0_READ_NORMAL (0x0 << 12) +#define QSPI_SETUP0_READ_DUAL (0x1 << 12) #define QSPI_SETUP0_READ_QUAD (0x3 << 12) #define QSPI_CMD_WRITE (0x2 << 16) #define QSPI_NUM_DUMMY_BITS (0x0 << 24) @@ -85,50 +90,24 @@ struct ti_qspi_regs { u32 data3; }; -/* ti qspi slave */ -struct ti_qspi_slave { +/* ti qspi priv */ +struct ti_qspi_priv { +#ifndef CONFIG_DM_SPI struct spi_slave slave; +#else + void *memory_map; + uint max_hz; + u32 num_cs; +#endif struct ti_qspi_regs *base; + void *ctrl_mod_mmap; unsigned int mode; u32 cmd; u32 dc; }; -static inline struct ti_qspi_slave *to_ti_qspi_slave(struct spi_slave *slave) -{ - return container_of(slave, struct ti_qspi_slave, slave); -} - -static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) +static void ti_spi_set_speed(struct ti_qspi_priv *priv, uint hz) { - struct spi_slave *slave = &qslave->slave; - u32 memval = 0; - -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - slave->memory_map = (void *)MMAP_START_ADDR_DRA; -#else - slave->memory_map = (void *)MMAP_START_ADDR_AM43x; -#endif - -#ifdef CONFIG_QSPI_QUAD_SUPPORT - memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES | - QSPI_SETUP0_NUM_D_BYTES_8_BITS | - QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE | - QSPI_NUM_DUMMY_BITS); - slave->op_mode_rx = SPI_OPM_RX_QOF; -#else - memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | - QSPI_SETUP0_NUM_D_BYTES_NO_BITS | - QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE | - QSPI_NUM_DUMMY_BITS; -#endif - - writel(memval, &qslave->base->setup0); -} - -static void ti_spi_set_speed(struct spi_slave *slave, uint hz) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); uint clk_div; debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div); @@ -139,8 +118,8 @@ static void ti_spi_set_speed(struct spi_slave *slave, uint hz) clk_div = (QSPI_FCLK / hz) - 1; /* disable SCLK */ - writel(readl(&qslave->base->clk_ctrl) & ~QSPI_CLK_EN, - &qslave->base->clk_ctrl); + writel(readl(&priv->base->clk_ctrl) & ~QSPI_CLK_EN, + &priv->base->clk_ctrl); /* assign clk_div values */ if (clk_div < 0) @@ -149,135 +128,80 @@ static void ti_spi_set_speed(struct spi_slave *slave, uint hz) clk_div = QSPI_CLK_DIV_MAX; /* enable SCLK */ - writel(QSPI_CLK_EN | clk_div, &qslave->base->clk_ctrl); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - return 1; + writel(QSPI_CLK_EN | clk_div, &priv->base->clk_ctrl); } -void spi_cs_activate(struct spi_slave *slave) +static void ti_qspi_cs_deactivate(struct ti_qspi_priv *priv) { - /* CS handled in xfer */ - return; -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - - debug("spi_cs_deactivate: 0x%08x\n", (u32)slave); - - writel(qslave->cmd | QSPI_INVAL, &qslave->base->cmd); + writel(priv->cmd | QSPI_INVAL, &priv->base->cmd); /* dummy readl to ensure bus sync */ - readl(&qslave->base->cmd); + readl(&priv->base->cmd); } -void spi_init(void) +static int __ti_qspi_set_mode(struct ti_qspi_priv *priv, unsigned int mode) { - /* nothing to do */ -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct ti_qspi_slave *qslave; - -#ifdef CONFIG_AM43XX - gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio"); - gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1); -#endif - - qslave = spi_alloc_slave(struct ti_qspi_slave, bus, cs); - if (!qslave) { - printf("SPI_error: Fail to allocate ti_qspi_slave\n"); - return NULL; - } - - qslave->base = (struct ti_qspi_regs *)QSPI_BASE; - qslave->mode = mode; - - ti_spi_set_speed(&qslave->slave, max_hz); + priv->dc = 0; + if (mode & SPI_CPHA) + priv->dc |= QSPI_CKPHA(0); + if (mode & SPI_CPOL) + priv->dc |= QSPI_CKPOL(0); + if (mode & SPI_CS_HIGH) + priv->dc |= QSPI_CSPOL(0); -#ifdef CONFIG_TI_SPI_MMAP - ti_spi_setup_spi_register(qslave); -#endif - - return &qslave->slave; + return 0; } -void spi_free_slave(struct spi_slave *slave) +static int __ti_qspi_claim_bus(struct ti_qspi_priv *priv, int cs) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - free(qslave); -} + writel(priv->dc, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data); -int spi_claim_bus(struct spi_slave *slave) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - - debug("spi_claim_bus: bus:%i cs:%i\n", slave->bus, slave->cs); - - qslave->dc = 0; - if (qslave->mode & SPI_CPHA) - qslave->dc |= QSPI_CKPHA(slave->cs); - if (qslave->mode & SPI_CPOL) - qslave->dc |= QSPI_CKPOL(slave->cs); - if (qslave->mode & SPI_CS_HIGH) - qslave->dc |= QSPI_CSPOL(slave->cs); - - writel(qslave->dc, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); + priv->dc <<= cs * 8; + writel(priv->dc, &priv->base->dc); return 0; } -void spi_release_bus(struct spi_slave *slave) +static void __ti_qspi_release_bus(struct ti_qspi_priv *priv) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + writel(0, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data); +} - debug("spi_release_bus: bus:%i cs:%i\n", slave->bus, slave->cs); +static void ti_qspi_ctrl_mode_mmap(void *ctrl_mod_mmap, int cs, bool enable) +{ + u32 val; - writel(0, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); + val = readl(ctrl_mod_mmap); + if (enable) + val |= MEM_CS(cs); + else + val &= MEM_CS_UNSELECT; + writel(val, ctrl_mod_mmap); } -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) +static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen, + const void *dout, void *din, unsigned long flags, + u32 cs) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); uint words = bitlen >> 3; /* fixed 8-bit word length */ const uchar *txp = dout; uchar *rxp = din; uint status; int timeout; -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - int val; -#endif - - debug("spi_xfer: bus:%i cs:%i bitlen:%i words:%i flags:%lx\n", - slave->bus, slave->cs, bitlen, words, flags); - /* Setup mmap flags */ if (flags & SPI_XFER_MMAP) { - writel(MM_SWITCH, &qslave->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val |= MEM_CS; - writel(val, CORE_CTRL_IO); -#endif + writel(MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, true); return 0; } else if (flags & SPI_XFER_MMAP_END) { - writel(~MM_SWITCH, &qslave->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val &= MEM_CS_UNSELECT; - writel(val, CORE_CTRL_IO); -#endif + writel(~MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, false); return 0; } @@ -290,12 +214,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } /* Setup command reg */ - qslave->cmd = 0; - qslave->cmd |= QSPI_WLEN(8); - qslave->cmd |= QSPI_EN_CS(slave->cs); - if (qslave->mode & SPI_3WIRE) - qslave->cmd |= QSPI_3_PIN; - qslave->cmd |= 0xfff; + priv->cmd = 0; + priv->cmd |= QSPI_WLEN(8); + priv->cmd |= QSPI_EN_CS(cs); + if (priv->mode & SPI_3WIRE) + priv->cmd |= QSPI_3_PIN; + priv->cmd |= 0xfff; /* FIXME: This delay is required for successfull * completion of read/write/erase. Once its root @@ -307,39 +231,39 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, while (words--) { if (txp) { debug("tx cmd %08x dc %08x data %02x\n", - qslave->cmd | QSPI_WR_SNGL, qslave->dc, *txp); - writel(*txp++, &qslave->base->data); - writel(qslave->cmd | QSPI_WR_SNGL, - &qslave->base->cmd); - status = readl(&qslave->base->status); + priv->cmd | QSPI_WR_SNGL, priv->dc, *txp); + writel(*txp++, &priv->base->data); + writel(priv->cmd | QSPI_WR_SNGL, + &priv->base->cmd); + status = readl(&priv->base->status); timeout = QSPI_TIMEOUT; while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) { if (--timeout < 0) { printf("spi_xfer: TX timeout!\n"); return -1; } - status = readl(&qslave->base->status); + status = readl(&priv->base->status); } debug("tx done, status %08x\n", status); } if (rxp) { - qslave->cmd |= QSPI_RD_SNGL; + priv->cmd |= QSPI_RD_SNGL; debug("rx cmd %08x dc %08x\n", - qslave->cmd, qslave->dc); + priv->cmd, priv->dc); #ifdef CONFIG_DRA7XX udelay(500); #endif - writel(qslave->cmd, &qslave->base->cmd); - status = readl(&qslave->base->status); + writel(priv->cmd, &priv->base->cmd); + status = readl(&priv->base->status); timeout = QSPI_TIMEOUT; while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) { if (--timeout < 0) { printf("spi_xfer: RX timeout!\n"); return -1; } - status = readl(&qslave->base->status); + status = readl(&priv->base->status); } - *rxp++ = readl(&qslave->base->data); + *rxp++ = readl(&priv->base->data); debug("rx done, status %08x, read %02x\n", status, *(rxp-1)); } @@ -347,7 +271,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* Terminate frame */ if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); + ti_qspi_cs_deactivate(priv); return 0; } @@ -374,3 +298,293 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len) *((unsigned int *)offset) += len; } #endif + +#ifndef CONFIG_DM_SPI + +static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) +{ + return container_of(slave, struct ti_qspi_priv, slave); +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return 1; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + /* CS handled in xfer */ + return; +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + ti_qspi_cs_deactivate(priv); +} + +void spi_init(void) +{ + /* nothing to do */ +} + +static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv) +{ + u32 memval = 0; + +#ifdef CONFIG_QSPI_QUAD_SUPPORT + struct spi_slave *slave = &priv->slave; + memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES | + QSPI_SETUP0_NUM_D_BYTES_8_BITS | + QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE | + QSPI_NUM_DUMMY_BITS); + slave->mode_rx = SPI_RX_QUAD; +#else + memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | + QSPI_SETUP0_NUM_D_BYTES_NO_BITS | + QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE | + QSPI_NUM_DUMMY_BITS; +#endif + + writel(memval, &priv->base->setup0); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct ti_qspi_priv *priv; + +#ifdef CONFIG_AM43XX + gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio"); + gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1); +#endif + + priv = spi_alloc_slave(struct ti_qspi_priv, bus, cs); + if (!priv) { + printf("SPI_error: Fail to allocate ti_qspi_priv\n"); + return NULL; + } + + priv->base = (struct ti_qspi_regs *)QSPI_BASE; + priv->mode = mode; +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + priv->ctrl_mod_mmap = (void *)CORE_CTRL_IO; + priv->slave.memory_map = (void *)MMAP_START_ADDR_DRA; +#else + priv->slave.memory_map = (void *)MMAP_START_ADDR_AM43x; +#endif + + ti_spi_set_speed(priv, max_hz); + +#ifdef CONFIG_TI_SPI_MMAP + ti_spi_setup_spi_register(priv); +#endif + + return &priv->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + free(priv); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs); + __ti_qspi_set_mode(priv, priv->mode); + return __ti_qspi_claim_bus(priv, priv->slave.cs); +} +void spi_release_bus(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs); + __ti_qspi_release_bus(priv); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("spi_xfer: bus:%i cs:%i bitlen:%i flags:%lx\n", + priv->slave.bus, priv->slave.cs, bitlen, flags); + return __ti_qspi_xfer(priv, bitlen, dout, din, flags, priv->slave.cs); +} + +#else /* CONFIG_DM_SPI */ + +static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, + struct spi_slave *slave, + bool enable) +{ + u32 memval; + u32 mode = slave->mode_rx & (SPI_RX_QUAD | SPI_RX_DUAL); + + if (!enable) { + writel(0, &priv->base->setup0); + return; + } + + memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS; + + switch (mode) { + case SPI_RX_QUAD: + memval |= QSPI_CMD_READ_QUAD; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_QUAD; + slave->mode_rx = SPI_RX_QUAD; + break; + case SPI_RX_DUAL: + memval |= QSPI_CMD_READ_DUAL; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_DUAL; + break; + default: + memval |= QSPI_CMD_READ; + memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS; + memval |= QSPI_SETUP0_READ_NORMAL; + break; + } + + writel(memval, &priv->base->setup0); +} + + +static int ti_qspi_set_speed(struct udevice *bus, uint max_hz) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + + ti_spi_set_speed(priv, max_hz); + + return 0; +} + +static int ti_qspi_set_mode(struct udevice *bus, uint mode) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + return __ti_qspi_set_mode(priv, mode); +} + +static int ti_qspi_claim_bus(struct udevice *dev) +{ + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + if (slave_plat->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + __ti_qspi_setup_memorymap(priv, slave, true); + + return __ti_qspi_claim_bus(priv, slave_plat->cs); +} + +static int ti_qspi_release_bus(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + __ti_qspi_setup_memorymap(priv, slave, false); + __ti_qspi_release_bus(priv); + + return 0; +} + +static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + if (slave->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + return __ti_qspi_xfer(priv, bitlen, dout, din, flags, slave->cs); +} + +static int ti_qspi_probe(struct udevice *bus) +{ + /* Nothing to do in probe */ + return 0; +} + +static int ti_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + fdt_addr_t addr; + + priv->base = (struct ti_qspi_regs *)dev_get_addr(bus); + priv->memory_map = (void *)dev_get_addr_index(bus, 1); + addr = dev_get_addr_index(bus, 2); + priv->ctrl_mod_mmap = (addr == FDT_ADDR_T_NONE) ? NULL : (void *)addr; + + priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1); + if (priv->max_hz < 0) { + debug("Error: Max frequency missing\n"); + return -ENODEV; + } + priv->num_cs = fdtdec_get_int(blob, node, "num-cs", 4); + + debug("%s: regs=<0x%x>, max-frequency=%d\n", __func__, + (int)priv->base, priv->max_hz); + + return 0; +} + +static int ti_qspi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct udevice *bus = dev_get_parent(dev); + struct ti_qspi_priv *priv = dev_get_priv(bus); + + slave->memory_map = priv->memory_map; + return 0; +} + +static const struct dm_spi_ops ti_qspi_ops = { + .claim_bus = ti_qspi_claim_bus, + .release_bus = ti_qspi_release_bus, + .xfer = ti_qspi_xfer, + .set_speed = ti_qspi_set_speed, + .set_mode = ti_qspi_set_mode, +}; + +static const struct udevice_id ti_qspi_ids[] = { + { .compatible = "ti,dra7xxx-qspi" }, + { .compatible = "ti,am4372-qspi" }, + { } +}; + +U_BOOT_DRIVER(ti_qspi) = { + .name = "ti_qspi", + .id = UCLASS_SPI, + .of_match = ti_qspi_ids, + .ops = &ti_qspi_ops, + .ofdata_to_platdata = ti_qspi_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct ti_qspi_priv), + .probe = ti_qspi_probe, + .child_pre_probe = ti_qspi_child_pre_probe, +}; +#endif /* CONFIG_DM_SPI */ diff --git a/drivers/usb/eth/mcs7830.c b/drivers/usb/eth/mcs7830.c index bbdad8b79a..9d6cf8ce7b 100644 --- a/drivers/usb/eth/mcs7830.c +++ b/drivers/usb/eth/mcs7830.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -83,19 +84,23 @@ struct mcs7830_regs { * @mchash: shadow for the network adapter's multicast hash registers */ struct mcs7830_private { +#ifdef CONFIG_DM_ETH + uint8_t rx_buf[MCS7830_RX_URB_SIZE]; + struct ueth_data ueth; +#endif uint8_t config; uint8_t mchash[8]; }; /* * mcs7830_read_reg() - read a register of the network adapter - * @dev: network device to read from + * @udev: network device to read from * @idx: index of the register to start reading from * @size: number of bytes to read * @data: buffer to read into * Return: zero upon success, negative upon error */ -static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx, +static int mcs7830_read_reg(struct usb_device *udev, uint8_t idx, uint16_t size, void *data) { int len; @@ -103,8 +108,8 @@ static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx, debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size); - len = usb_control_msg(dev->pusb_dev, - usb_rcvctrlpipe(dev->pusb_dev, 0), + len = usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), MCS7830_RD_BREQ, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, idx, buf, size, @@ -119,13 +124,13 @@ static int mcs7830_read_reg(struct ueth_data *dev, uint8_t idx, /* * mcs7830_write_reg() - write a register of the network adapter - * @dev: network device to write to + * @udev: network device to write to * @idx: index of the register to start writing to * @size: number of bytes to write * @data: buffer holding the data to write * Return: zero upon success, negative upon error */ -static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx, +static int mcs7830_write_reg(struct usb_device *udev, uint8_t idx, uint16_t size, void *data) { int len; @@ -134,8 +139,8 @@ static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx, debug("%s() idx=0x%04X sz=%d\n", __func__, idx, size); memcpy(buf, data, size); - len = usb_control_msg(dev->pusb_dev, - usb_sndctrlpipe(dev->pusb_dev, 0), + len = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), MCS7830_WR_BREQ, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, idx, buf, size, @@ -149,12 +154,12 @@ static int mcs7830_write_reg(struct ueth_data *dev, uint8_t idx, /* * mcs7830_phy_emit_wait() - emit PHY read/write access, wait for its execution - * @dev: network device to talk to + * @udev: network device to talk to * @rwflag: PHY_CMD1_READ or PHY_CMD1_WRITE opcode * @index: number of the PHY register to read or write * Return: zero upon success, negative upon error */ -static int mcs7830_phy_emit_wait(struct ueth_data *dev, +static int mcs7830_phy_emit_wait(struct usb_device *udev, uint8_t rwflag, uint8_t index) { int rc; @@ -164,14 +169,14 @@ static int mcs7830_phy_emit_wait(struct ueth_data *dev, /* send the PHY read/write request */ cmd[0] = rwflag | PHY_CMD1_PHYADDR; cmd[1] = PHY_CMD2_PEND | (index & 0x1f); - rc = mcs7830_write_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd); + rc = mcs7830_write_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd); if (rc < 0) return rc; /* wait for the response to become available (usually < 1ms) */ retry = 10; do { - rc = mcs7830_read_reg(dev, REG_PHY_CMD, sizeof(cmd), cmd); + rc = mcs7830_read_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd); if (rc < 0) return rc; if (cmd[1] & PHY_CMD2_READY) @@ -185,50 +190,51 @@ static int mcs7830_phy_emit_wait(struct ueth_data *dev, /* * mcs7830_read_phy() - read a PHY register of the network adapter - * @dev: network device to read from + * @udev: network device to read from * @index: index of the PHY register to read from * Return: non-negative 16bit register content, negative upon error */ -static int mcs7830_read_phy(struct ueth_data *dev, uint8_t index) +static int mcs7830_read_phy(struct usb_device *udev, uint8_t index) { int rc; uint16_t val; /* issue the PHY read request and wait for its execution */ - rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_READ, index); + rc = mcs7830_phy_emit_wait(udev, PHY_CMD1_READ, index); if (rc < 0) return rc; /* fetch the PHY data which was read */ - rc = mcs7830_read_reg(dev, REG_PHY_DATA, sizeof(val), &val); + rc = mcs7830_read_reg(udev, REG_PHY_DATA, sizeof(val), &val); if (rc < 0) return rc; rc = le16_to_cpu(val); - debug("%s(%s, %d) => 0x%04X\n", __func__, dev->eth_dev.name, index, rc); + debug("%s(%d) => 0x%04X\n", __func__, index, rc); return rc; } /* * mcs7830_write_phy() - write a PHY register of the network adapter - * @dev: network device to write to + * @udev: network device to write to * @index: index of the PHY register to write to * @val: value to write to the PHY register * Return: zero upon success, negative upon error */ -static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val) +static int mcs7830_write_phy(struct usb_device *udev, uint8_t index, + uint16_t val) { int rc; - debug("%s(%s, %d, 0x%04X)\n", __func__, dev->eth_dev.name, index, val); + debug("%s(%d, 0x%04X)\n", __func__, index, val); /* setup the PHY data which is to get written */ val = cpu_to_le16(val); - rc = mcs7830_write_reg(dev, REG_PHY_DATA, sizeof(val), &val); + rc = mcs7830_write_reg(udev, REG_PHY_DATA, sizeof(val), &val); if (rc < 0) return rc; /* issue the PHY write request and wait for its execution */ - rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_WRITE, index); + rc = mcs7830_phy_emit_wait(udev, PHY_CMD1_WRITE, index); if (rc < 0) return rc; @@ -237,21 +243,21 @@ static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val) /* * mcs7830_write_config() - write to the network adapter's config register - * @eth: network device to write to + * @udev: network device to write to + * @priv: private data * Return: zero upon success, negative upon error * * the data which gets written is taken from the shadow config register * within the device driver's private data */ -static int mcs7830_write_config(struct ueth_data *dev) +static int mcs7830_write_config(struct usb_device *udev, + struct mcs7830_private *priv) { - struct mcs7830_private *priv; int rc; debug("%s()\n", __func__); - priv = dev->dev_priv; - rc = mcs7830_write_reg(dev, REG_CONFIG, + rc = mcs7830_write_reg(udev, REG_CONFIG, sizeof(priv->config), &priv->config); if (rc < 0) { debug("writing config to adapter failed\n"); @@ -263,21 +269,21 @@ static int mcs7830_write_config(struct ueth_data *dev) /* * mcs7830_write_mchash() - write the network adapter's multicast filter - * @eth: network device to write to + * @udev: network device to write to + * @priv: private data * Return: zero upon success, negative upon error * * the data which gets written is taken from the shadow multicast hashes * within the device driver's private data */ -static int mcs7830_write_mchash(struct ueth_data *dev) +static int mcs7830_write_mchash(struct usb_device *udev, + struct mcs7830_private *priv) { - struct mcs7830_private *priv; int rc; debug("%s()\n", __func__); - priv = dev->dev_priv; - rc = mcs7830_write_reg(dev, REG_MULTICAST_HASH, + rc = mcs7830_write_reg(udev, REG_MULTICAST_HASH, sizeof(priv->mchash), &priv->mchash); if (rc < 0) { debug("writing multicast hash to adapter failed\n"); @@ -289,12 +295,12 @@ static int mcs7830_write_mchash(struct ueth_data *dev) /* * mcs7830_set_autoneg() - setup and trigger ethernet link autonegotiation - * @eth: network device to run link negotiation on + * @udev: network device to run link negotiation on * Return: zero upon success, negative upon error * * the routine advertises available media and starts autonegotiation */ -static int mcs7830_set_autoneg(struct ueth_data *dev) +static int mcs7830_set_autoneg(struct usb_device *udev) { int adv, flg; int rc; @@ -310,39 +316,39 @@ static int mcs7830_set_autoneg(struct ueth_data *dev) */ adv = ADVERTISE_PAUSE_CAP | ADVERTISE_ALL | ADVERTISE_CSMA; - rc = mcs7830_write_phy(dev, MII_ADVERTISE, adv); + rc = mcs7830_write_phy(udev, MII_ADVERTISE, adv); flg = 0; if (!rc) - rc = mcs7830_write_phy(dev, MII_BMCR, flg); + rc = mcs7830_write_phy(udev, MII_BMCR, flg); flg |= BMCR_ANENABLE; if (!rc) - rc = mcs7830_write_phy(dev, MII_BMCR, flg); + rc = mcs7830_write_phy(udev, MII_BMCR, flg); flg |= BMCR_ANRESTART; if (!rc) - rc = mcs7830_write_phy(dev, MII_BMCR, flg); + rc = mcs7830_write_phy(udev, MII_BMCR, flg); return rc; } /* * mcs7830_get_rev() - identify a network adapter's chip revision - * @eth: network device to identify + * @udev: network device to identify * Return: non-negative number, reflecting the revision number * * currently, only "rev C and higher" and "below rev C" are needed, so * the return value is #1 for "below rev C", and #2 for "rev C and above" */ -static int mcs7830_get_rev(struct ueth_data *dev) +static int mcs7830_get_rev(struct usb_device *udev) { uint8_t buf[2]; int rc; int rev; /* register 22 is readable in rev C and higher */ - rc = mcs7830_read_reg(dev, REG_FRAME_DROP_COUNTER, sizeof(buf), buf); + rc = mcs7830_read_reg(udev, REG_FRAME_DROP_COUNTER, sizeof(buf), buf); if (rc < 0) rev = 1; else @@ -353,19 +359,19 @@ static int mcs7830_get_rev(struct ueth_data *dev) /* * mcs7830_apply_fixup() - identify an adapter and potentially apply fixups - * @eth: network device to identify and apply fixups to + * @udev: network device to identify and apply fixups to * Return: zero upon success (no errors emitted from here) * * this routine identifies the network adapter's chip revision, and applies * fixups for known issues */ -static int mcs7830_apply_fixup(struct ueth_data *dev) +static int mcs7830_apply_fixup(struct usb_device *udev) { int rev; int i; uint8_t thr; - rev = mcs7830_get_rev(dev); + rev = mcs7830_get_rev(udev); debug("%s() rev=%d\n", __func__, rev); /* @@ -374,10 +380,10 @@ static int mcs7830_apply_fixup(struct ueth_data *dev) * exactly", the introductory comment says "rev C and above") */ if (rev == 2) { - debug("%s: applying rev C fixup\n", dev->eth_dev.name); + debug("%s: applying rev C fixup\n", __func__); thr = PAUSE_THRESHOLD_DEFAULT; for (i = 0; i < 2; i++) { - (void)mcs7830_write_reg(dev, REG_PAUSE_THRESHOLD, + (void)mcs7830_write_reg(udev, REG_PAUSE_THRESHOLD, sizeof(thr), &thr); mdelay(1); } @@ -395,13 +401,12 @@ static int mcs7830_apply_fixup(struct ueth_data *dev) * of the interface callbacks can exchange ethernet frames; link negotiation is * triggered from here already and continues in background */ -static int mcs7830_basic_reset(struct ueth_data *dev) +static int mcs7830_basic_reset(struct usb_device *udev, + struct mcs7830_private *priv) { - struct mcs7830_private *priv; int rc; debug("%s()\n", __func__); - priv = dev->dev_priv; /* * comment from the respective Linux driver, which @@ -411,25 +416,25 @@ static int mcs7830_basic_reset(struct ueth_data *dev) priv->config = CONF_TXENABLE; priv->config |= CONF_ALLMULTICAST; - rc = mcs7830_set_autoneg(dev); + rc = mcs7830_set_autoneg(udev); if (rc < 0) { error("setting autoneg failed\n"); return rc; } - rc = mcs7830_write_mchash(dev); + rc = mcs7830_write_mchash(udev, priv); if (rc < 0) { error("failed to set multicast hash\n"); return rc; } - rc = mcs7830_write_config(dev); + rc = mcs7830_write_config(udev, priv); if (rc < 0) { error("failed to set configuration\n"); return rc; } - rc = mcs7830_apply_fixup(dev); + rc = mcs7830_apply_fixup(udev); if (rc < 0) { error("fixup application failed\n"); return rc; @@ -440,51 +445,38 @@ static int mcs7830_basic_reset(struct ueth_data *dev) /* * mcs7830_read_mac() - read an ethernet adapter's MAC address - * @eth: network device to read from + * @udev: network device to read from + * @enetaddr: place to put ethernet MAC address * Return: zero upon success, negative upon error * * this routine fetches the MAC address stored within the ethernet adapter, * and stores it in the ethernet interface's data structure */ -static int mcs7830_read_mac(struct eth_device *eth) +static int mcs7830_read_mac(struct usb_device *udev, unsigned char enetaddr[]) { - struct ueth_data *dev; int rc; uint8_t buf[ETH_ALEN]; debug("%s()\n", __func__); - dev = eth->priv; - rc = mcs7830_read_reg(dev, REG_ETHER_ADDR, ETH_ALEN, buf); + rc = mcs7830_read_reg(udev, REG_ETHER_ADDR, ETH_ALEN, buf); if (rc < 0) { debug("reading MAC from adapter failed\n"); return rc; } - memcpy(ð->enetaddr[0], buf, ETH_ALEN); + memcpy(enetaddr, buf, ETH_ALEN); return 0; } -/* - * mcs7830_write_mac() - write an ethernet adapter's MAC address - * @eth: network device to write to - * Return: zero upon success, negative upon error - * - * this routine takes the MAC address from the ethernet interface's data - * structure, and writes it into the ethernet adapter such that subsequent - * exchange of ethernet frames uses this address - */ -static int mcs7830_write_mac(struct eth_device *eth) +static int mcs7830_write_mac_common(struct usb_device *udev, + unsigned char enetaddr[]) { - struct ueth_data *dev; int rc; debug("%s()\n", __func__); - dev = eth->priv; - if (sizeof(eth->enetaddr) != ETH_ALEN) - return -EINVAL; - rc = mcs7830_write_reg(dev, REG_ETHER_ADDR, ETH_ALEN, eth->enetaddr); + rc = mcs7830_write_reg(udev, REG_ETHER_ADDR, ETH_ALEN, enetaddr); if (rc < 0) { debug("writing MAC to adapter failed\n"); return rc; @@ -492,28 +484,16 @@ static int mcs7830_write_mac(struct eth_device *eth) return 0; } -/* - * mcs7830_init() - network interface's init callback - * @eth: network device to initialize - * @bd: board information - * Return: zero upon success, negative upon error - * - * after initial setup during probe() and get_info(), this init() callback - * ensures that the link is up and subsequent send() and recv() calls can - * exchange ethernet frames - */ -static int mcs7830_init(struct eth_device *eth, bd_t *bd) +static int mcs7830_init_common(struct usb_device *udev) { - struct ueth_data *dev; int timeout; int have_link; debug("%s()\n", __func__); - dev = eth->priv; timeout = 0; do { - have_link = mcs7830_read_phy(dev, MII_BMSR) & BMSR_LSTATUS; + have_link = mcs7830_read_phy(udev, MII_BMSR) & BMSR_LSTATUS; if (have_link) break; udelay(LINKSTATUS_TIMEOUT_RES * 1000); @@ -526,28 +506,18 @@ static int mcs7830_init(struct eth_device *eth, bd_t *bd) return 0; } -/* - * mcs7830_send() - network interface's send callback - * @eth: network device to send the frame from - * @packet: ethernet frame content - * @length: ethernet frame length - * Return: zero upon success, negative upon error - * - * this routine send an ethernet frame out of the network interface - */ -static int mcs7830_send(struct eth_device *eth, void *packet, int length) +static int mcs7830_send_common(struct ueth_data *ueth, void *packet, + int length) { - struct ueth_data *dev; + struct usb_device *udev = ueth->pusb_dev; int rc; int gotlen; /* there is a status byte after the ethernet frame */ ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, PKTSIZE + sizeof(uint8_t)); - dev = eth->priv; - memcpy(buf, packet, length); - rc = usb_bulk_msg(dev->pusb_dev, - usb_sndbulkpipe(dev->pusb_dev, dev->ep_out), + rc = usb_bulk_msg(udev, + usb_sndbulkpipe(udev, ueth->ep_out), &buf[0], length, &gotlen, USBCALL_TIMEOUT); debug("%s() TX want len %d, got len %d, rc %d\n", @@ -555,28 +525,17 @@ static int mcs7830_send(struct eth_device *eth, void *packet, int length) return rc; } -/* - * mcs7830_recv() - network interface's recv callback - * @eth: network device to receive frames from - * Return: zero upon success, negative upon error - * - * this routine checks for available ethernet frames that the network - * interface might have received, and notifies the network stack - */ -static int mcs7830_recv(struct eth_device *eth) +static int mcs7830_recv_common(struct ueth_data *ueth, uint8_t *buf) { - struct ueth_data *dev; - ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, MCS7830_RX_URB_SIZE); int rc, wantlen, gotlen; uint8_t sts; debug("%s()\n", __func__); - dev = eth->priv; /* fetch input data from the adapter */ wantlen = MCS7830_RX_URB_SIZE; - rc = usb_bulk_msg(dev->pusb_dev, - usb_rcvbulkpipe(dev->pusb_dev, dev->ep_in), + rc = usb_bulk_msg(ueth->pusb_dev, + usb_rcvbulkpipe(ueth->pusb_dev, ueth->ep_in), &buf[0], wantlen, &gotlen, USBCALL_TIMEOUT); debug("%s() RX want len %d, got len %d, rc %d\n", @@ -601,8 +560,7 @@ static int mcs7830_recv(struct eth_device *eth) if (sts == STAT_RX_FRAME_CORRECT) { debug("%s() got a frame, len=%d\n", __func__, gotlen); - net_process_received_packet(buf, gotlen); - return 0; + return gotlen; } debug("RX: frame error (sts 0x%02X, %s %s %s %s %s)\n", @@ -615,6 +573,61 @@ static int mcs7830_recv(struct eth_device *eth) return -EIO; } +#ifndef CONFIG_DM_ETH +/* + * mcs7830_init() - network interface's init callback + * @udev: network device to initialize + * @bd: board information + * Return: zero upon success, negative upon error + * + * after initial setup during probe() and get_info(), this init() callback + * ensures that the link is up and subsequent send() and recv() calls can + * exchange ethernet frames + */ +static int mcs7830_init(struct eth_device *eth, bd_t *bd) +{ + struct ueth_data *dev = eth->priv; + + return mcs7830_init_common(dev->pusb_dev); +} + +/* + * mcs7830_send() - network interface's send callback + * @eth: network device to send the frame from + * @packet: ethernet frame content + * @length: ethernet frame length + * Return: zero upon success, negative upon error + * + * this routine send an ethernet frame out of the network interface + */ +static int mcs7830_send(struct eth_device *eth, void *packet, int length) +{ + struct ueth_data *dev = eth->priv; + + return mcs7830_send_common(dev, packet, length); +} + +/* + * mcs7830_recv() - network interface's recv callback + * @eth: network device to receive frames from + * Return: zero upon success, negative upon error + * + * this routine checks for available ethernet frames that the network + * interface might have received, and notifies the network stack + */ +static int mcs7830_recv(struct eth_device *eth) +{ + ALLOC_CACHE_ALIGN_BUFFER(uint8_t, buf, MCS7830_RX_URB_SIZE); + struct ueth_data *ueth = eth->priv; + int len; + + len = mcs7830_recv_common(ueth, buf); + if (len <= 0) + net_process_received_packet(buf, len); + + return 0; +} + /* * mcs7830_halt() - network interface's halt callback * @eth: network device to cease operation of @@ -628,6 +641,22 @@ static void mcs7830_halt(struct eth_device *eth) debug("%s()\n", __func__); } +/* + * mcs7830_write_mac() - write an ethernet adapter's MAC address + * @eth: network device to write to + * Return: zero upon success, negative upon error + * + * this routine takes the MAC address from the ethernet interface's data + * structure, and writes it into the ethernet adapter such that subsequent + * exchange of ethernet frames uses this address + */ +static int mcs7830_write_mac(struct eth_device *eth) +{ + struct ueth_data *ueth = eth->priv; + + return mcs7830_write_mac_common(ueth->pusb_dev, eth->enetaddr); +} + /* * mcs7830_iface_idx - index of detected network interfaces * @@ -802,12 +831,111 @@ int mcs7830_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->write_hwaddr = mcs7830_write_mac; eth->priv = ss; - if (mcs7830_basic_reset(ss)) + if (mcs7830_basic_reset(ss->pusb_dev, ss->dev_priv)) return 0; - if (mcs7830_read_mac(eth)) + if (mcs7830_read_mac(ss->pusb_dev, eth->enetaddr)) return 0; debug("MAC %pM\n", eth->enetaddr); return 1; } +#endif + + +#ifdef CONFIG_DM_ETH +static int mcs7830_eth_start(struct udevice *dev) +{ + struct usb_device *udev = dev_get_parent_priv(dev); + + return mcs7830_init_common(udev); +} + +void mcs7830_eth_stop(struct udevice *dev) +{ + debug("** %s()\n", __func__); +} + +int mcs7830_eth_send(struct udevice *dev, void *packet, int length) +{ + struct mcs7830_private *priv = dev_get_priv(dev); + struct ueth_data *ueth = &priv->ueth; + + return mcs7830_send_common(ueth, packet, length); +} + +int mcs7830_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct mcs7830_private *priv = dev_get_priv(dev); + struct ueth_data *ueth = &priv->ueth; + int len; + + len = mcs7830_recv_common(ueth, priv->rx_buf); + *packetp = priv->rx_buf; + + return len; +} + +static int mcs7830_free_pkt(struct udevice *dev, uchar *packet, int packet_len) +{ + struct mcs7830_private *priv = dev_get_priv(dev); + + packet_len = ALIGN(packet_len, 4); + usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len); + + return 0; +} + +int mcs7830_write_hwaddr(struct udevice *dev) +{ + struct usb_device *udev = dev_get_parent_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + return mcs7830_write_mac_common(udev, pdata->enetaddr); +} + +static int mcs7830_eth_probe(struct udevice *dev) +{ + struct usb_device *udev = dev_get_parent_priv(dev); + struct mcs7830_private *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + struct ueth_data *ueth = &priv->ueth; + + if (mcs7830_basic_reset(udev, priv)) + return 0; + + if (mcs7830_read_mac(udev, pdata->enetaddr)) + return 0; + + return usb_ether_register(dev, ueth, MCS7830_RX_URB_SIZE); +} + +static const struct eth_ops mcs7830_eth_ops = { + .start = mcs7830_eth_start, + .send = mcs7830_eth_send, + .recv = mcs7830_eth_recv, + .free_pkt = mcs7830_free_pkt, + .stop = mcs7830_eth_stop, + .write_hwaddr = mcs7830_write_hwaddr, +}; + +U_BOOT_DRIVER(mcs7830_eth) = { + .name = "mcs7830_eth", + .id = UCLASS_ETH, + .probe = mcs7830_eth_probe, + .ops = &mcs7830_eth_ops, + .priv_auto_alloc_size = sizeof(struct mcs7830_private), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; + +static const struct usb_device_id mcs7830_eth_id_table[] = { + { USB_DEVICE(0x9710, 0x7832) }, /* Moschip 7832 */ + { USB_DEVICE(0x9710, 0x7830), }, /* Moschip 7830 */ + { USB_DEVICE(0x9710, 0x7730), }, /* Moschip 7730 */ + { USB_DEVICE(0x0df6, 0x0021), }, /* Sitecom LN 30 */ + { } /* Terminating entry */ +}; + +U_BOOT_USB_DEVICE(mcs7830_eth, mcs7830_eth_id_table); +#endif diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 0cb9fcc166..cda1c6d5f7 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -18,32 +18,34 @@ struct ehci_pci_priv { struct ehci_ctrl ehci; }; -static void ehci_pci_common_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr, - struct ehci_hcor **ret_hcor) +#ifdef CONFIG_DM_USB + +static void ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr, + struct ehci_hcor **ret_hcor) { struct ehci_hccr *hccr; struct ehci_hcor *hcor; - uint32_t cmd; + u32 cmd; - hccr = (struct ehci_hccr *)pci_map_bar(pdev, + hccr = (struct ehci_hccr *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); - hcor = (struct ehci_hcor *)((uint32_t) hccr + + hcor = (struct ehci_hcor *)((uintptr_t) hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", - (uint32_t)hccr, (uint32_t)hcor, - (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + (u32)hccr, (u32)hcor, + (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); *ret_hccr = hccr; *ret_hcor = hcor; /* enable busmaster */ - pci_read_config_dword(pdev, PCI_COMMAND, &cmd); + dm_pci_read_config32(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MASTER; - pci_write_config_dword(pdev, PCI_COMMAND, cmd); + dm_pci_write_config32(dev, PCI_COMMAND, cmd); } -#ifndef CONFIG_DM_USB +#else #ifdef CONFIG_PCI_EHCI_DEVICE static struct pci_device_id ehci_pci_ids[] = { @@ -55,6 +57,31 @@ static struct pci_device_id ehci_pci_ids[] = { }; #endif +static void ehci_pci_legacy_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr, + struct ehci_hcor **ret_hcor) +{ + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + u32 cmd; + + hccr = (struct ehci_hccr *)pci_map_bar(pdev, + PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + hcor = (struct ehci_hcor *)((uintptr_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + + debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", + (u32)hccr, (u32)hcor, + (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + + *ret_hccr = hccr; + *ret_hcor = hcor; + + /* enable busmaster */ + pci_read_config_dword(pdev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_dword(pdev, PCI_COMMAND, cmd); +} + /* * Create the appropriate control structures to manage * a new EHCI host controller. @@ -73,7 +100,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, printf("EHCI host controller not found\n"); return -1; } - ehci_pci_common_init(pdev, ret_hccr, ret_hcor); + ehci_pci_legacy_init(pdev, ret_hccr, ret_hcor); return 0; } @@ -94,7 +121,7 @@ static int ehci_pci_probe(struct udevice *dev) struct ehci_hccr *hccr; struct ehci_hcor *hcor; - ehci_pci_common_init(pci_get_bdf(dev), &hccr, &hcor); + ehci_pci_init(dev, &hccr, &hcor); return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); } diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index a19651f5f3..021c1d68ed 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -19,8 +19,8 @@ GraphicDevice ctfb; void *video_hw_init(void) { GraphicDevice *gdev = &ctfb; + struct udevice *dev; int bits_per_pixel; - pci_dev_t dev; int ret; printf("Video: "); @@ -33,14 +33,14 @@ void *video_hw_init(void) return NULL; } if (vbe_get_video_info(gdev)) { - dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0); - if (dev < 0) { + ret = dm_pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0, &dev); + if (ret) { printf("no card detected\n"); return NULL; } bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); - ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE | - PCI_ROM_ALLOW_FALLBACK); + ret = dm_pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE | + PCI_ROM_ALLOW_FALLBACK); bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); if (ret) { printf("failed to run video BIOS: %d\n", ret); diff --git a/include/ahci.h b/include/ahci.h index 0bdedac187..a956c6ff5d 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -145,7 +145,11 @@ struct ahci_ioports { }; struct ahci_probe_ent { +#ifdef CONFIG_DM_PCI + struct udevice *dev; +#else pci_dev_t dev; +#endif struct ahci_ioports port[AHCI_MAX_PORTS]; u32 n_ports; u32 hard_port_no; diff --git a/include/bios_emul.h b/include/bios_emul.h index 3643b82b3a..80979edd04 100644 --- a/include/bios_emul.h +++ b/include/bios_emul.h @@ -42,7 +42,7 @@ struct vbe_mode_info; int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int cleanUp); /* Run a BIOS ROM natively (only supported on x86 machines) */ -void bios_run_on_x86(pci_dev_t pcidev, unsigned long addr, int vesa_mode, +void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode, struct vbe_mode_info *mode_info); /** diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index aac550a477..de7538fc9e 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -142,6 +142,8 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH #endif #ifndef CONFIG_SPL_BUILD diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 81070b1fd0..9d62421050 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -142,6 +142,11 @@ #define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 #define CONFIG_QSPI_QUAD_SUPPORT +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH +#endif + /* * Default to using SPI for environment, etc. * 0x000000 - 0x010000 : QSPI.SPL (64KiB) diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h index f753e684a6..d22ea74136 100644 --- a/include/configs/rk3036_common.h +++ b/include/configs/rk3036_common.h @@ -24,6 +24,8 @@ #define CONFIG_SYS_TIMER_BASE 0x200440a0 /* TIMER5 */ #define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8) +#define CONFIG_SPL_SERIAL_SUPPORT + #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_MEM32 diff --git a/include/dm/device.h b/include/dm/device.h index 7fb99356be..1cf81501ed 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -453,6 +453,17 @@ int device_find_next_child(struct udevice **devp); */ fdt_addr_t dev_get_addr(struct udevice *dev); +/** + * dev_get_addr_index() - Get the indexed reg property of a device + * + * @dev: Pointer to a device + * @index: the 'reg' property can hold a list of pairs + * and @index is used to select which one is required + * + * @return addr + */ +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index); + /** * device_has_children() - check if a device has any children * @@ -776,4 +787,25 @@ static inline void devm_kfree(struct udevice *dev, void *ptr) #endif /* ! CONFIG_DEVRES */ +/** + * dm_set_translation_offset() - Set translation offset + * @offs: Translation offset + * + * Some platforms need a special address translation. Those + * platforms (e.g. mvebu in SPL) can configure a translation + * offset in the DM by calling this function. It will be + * added to all addresses returned in dev_get_addr(). + */ +void dm_set_translation_offset(fdt_addr_t offs); + +/** + * dm_get_translation_offset() - Get translation offset + * + * This function returns the translation offset that can + * be configured by calling dm_set_translation_offset(). + * + * @return translation offset for the device address (0 as default). + */ +fdt_addr_t dm_get_translation_offset(void); + #endif diff --git a/include/fdtdec.h b/include/fdtdec.h index d82dc35073..7a1450c576 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -443,34 +443,17 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device); -/** - * Look at the pci address of a device node that represents a PCI device - * and parse the bus, device and function number from it. For some cases - * like the bus number encoded in reg property is not correct after pci - * enumeration, this function looks through the node's compatible strings - * to get these numbers extracted instead. - * - * @param blob FDT blob - * @param node node to examine - * @param addr pci address in the form of fdt_pci_addr - * @param bdf returns bus, device, function triplet - * @return 0 if ok, negative on error - */ -int fdtdec_get_pci_bdf(const void *blob, int node, - struct fdt_pci_addr *addr, pci_dev_t *bdf); - /** * Look at the pci address of a device node that represents a PCI device * and return base address of the pci device's registers. * - * @param blob FDT blob - * @param node node to examine + * @param dev device to examine * @param addr pci address in the form of fdt_pci_addr * @param bar returns base address of the pci device's registers * @return 0 if ok, negative on error */ -int fdtdec_get_pci_bar32(const void *blob, int node, - struct fdt_pci_addr *addr, u32 *bar); +int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, + u32 *bar); /** * Look up a 32-bit integer property in a node and return it. The property diff --git a/include/hash.h b/include/hash.h index e6d0f1db92..d81433772f 100644 --- a/include/hash.h +++ b/include/hash.h @@ -114,21 +114,6 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int hash_block(const char *algo_name, const void *data, unsigned int len, uint8_t *output, int *output_size); -/** - * hash_show() - Print out a hash algorithm and value - * - * You will get a message like this (without a newline at the end): - * - * "sha1 for 9eb3337c ... 9eb3338f ==> 7942ef1df479fd3130f716eb9613d107dab7e257" - * - * @algo: Algorithm used for hash - * @addr: Address of data that was hashed - * @len: Length of data that was hashed - * @output: Hash value to display - */ -void hash_show(struct hash_algo *algo, ulong addr, ulong len, - uint8_t *output); - #endif /* !USE_HOSTCC */ /** diff --git a/include/ide.h b/include/ide.h index d5e05e97cb..f9b43cb23a 100644 --- a/include/ide.h +++ b/include/ide.h @@ -28,13 +28,13 @@ void ide_led(uchar led, uchar status); #ifdef CONFIG_SYS_64BIT_LBA typedef uint64_t lbaint_t; -#define LBAF "%llx" -#define LBAFU "%llu" +#define LBAFlength "ll" #else typedef ulong lbaint_t; -#define LBAF "%lx" -#define LBAFU "%lu" +#define LBAFlength "l" #endif +#define LBAF "%" LBAFlength "x" +#define LBAFU "%" LBAFlength "u" /* * Function Prototypes diff --git a/include/mmc.h b/include/mmc.h index b89962a562..9254b716b9 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -489,11 +489,9 @@ struct pci_device_id; * This finds all the matching PCI IDs and sets them up as MMC devices. * * @name: Name to use for devices - * @mmc_supported: PCI IDs to search for - * @num_ids: Number of elements in @mmc_supported + * @mmc_supported: PCI IDs to search for, terminated by {0, 0} */ -int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported, - int num_ids); +int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported); /* Set block count limit because of 16 bit register limit on some hardware*/ #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT diff --git a/include/net.h b/include/net.h index ebed29ad57..ac44d614ca 100644 --- a/include/net.h +++ b/include/net.h @@ -181,8 +181,7 @@ int eth_unregister(struct eth_device *dev);/* Remove network device */ extern struct eth_device *eth_current; -static inline __attribute__((always_inline)) -struct eth_device *eth_get_dev(void) +static __always_inline struct eth_device *eth_get_dev(void) { return eth_current; } @@ -200,14 +199,14 @@ static inline unsigned char *eth_get_ethaddr(void) /* Used only when NetConsole is enabled */ int eth_is_active(struct eth_device *dev); /* Test device for active state */ /* Set active state */ -static inline __attribute__((always_inline)) int eth_init_state_only(void) +static __always_inline int eth_init_state_only(void) { eth_get_dev()->state = ETH_STATE_ACTIVE; return 0; } /* Set passive state */ -static inline __attribute__((always_inline)) void eth_halt_state_only(void) +static __always_inline void eth_halt_state_only(void) { eth_get_dev()->state = ETH_STATE_PASSIVE; } @@ -657,7 +656,7 @@ int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port, unsigned src_port, unsigned len); #endif -static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) +static __always_inline int eth_is_on_demand_init(void) { #ifdef CONFIG_NETCONSOLE extern enum proto_t net_loop_last_protocol; diff --git a/include/pci.h b/include/pci.h index 2adca850b4..cb2562f109 100644 --- a/include/pci.h +++ b/include/pci.h @@ -621,6 +621,7 @@ static inline void pci_set_ops(struct pci_controller *hose, extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data); #endif +#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT) extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, pci_addr_t addr, unsigned long flags); extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose, @@ -656,7 +657,6 @@ extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose, pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags)) /* For driver model these are defined in macros in pci_compat.c */ -#if !defined(CONFIG_DM_PCI) || defined(CONFIG_DM_PCI_COMPAT) extern int pci_hose_read_config_byte(struct pci_controller *hose, pci_dev_t dev, int where, u8 *val); extern int pci_hose_read_config_word(struct pci_controller *hose, @@ -862,12 +862,12 @@ struct dm_pci_ops { #define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops) /** - * pci_get_bdf() - Get the BDF value for a device + * dm_pci_get_bdf() - Get the BDF value for a device * * @dev: Device to check * @return bus/device/function value (see PCI_BDF()) */ -pci_dev_t pci_get_bdf(struct udevice *dev); +pci_dev_t dm_pci_get_bdf(struct udevice *dev); /** * pci_bind_bus_devices() - scan a PCI bus and bind devices @@ -902,13 +902,13 @@ int pci_bind_bus_devices(struct udevice *bus); int pci_auto_config_devices(struct udevice *bus); /** - * pci_bus_find_bdf() - Find a device given its PCI bus address + * dm_pci_bus_find_bdf() - Find a device given its PCI bus address * * @bdf: PCI device address: bus, device and function -see PCI_BDF() * @devp: Returns the device for this address, if found * @return 0 if OK, -ENODEV if not found */ -int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp); +int dm_pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp); /** * pci_bus_find_devfn() - Find a device on a bus @@ -995,7 +995,7 @@ int pci_find_device_id(struct pci_device_id *ids, int index, * @bdf: PCI bus address to scan (PCI_BUS(bdf) is the bus number) * @return 0 if OK, -ve on error */ -int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf); +int dm_pci_hose_probe_bus(struct udevice *bus); /** * pci_bus_read_config() - Read a configuration value from a device @@ -1166,6 +1166,96 @@ struct udevice *pci_get_controller(struct udevice *dev); int pci_get_regions(struct udevice *dev, struct pci_region **iop, struct pci_region **memp, struct pci_region **prefp); +/** + * dm_pci_read_bar32() - read a base address register from a device + * + * @dev: Device to check + * @barnum: Bar number to read (numbered from 0) + * @return: value of BAR + */ +u32 dm_pci_read_bar32(struct udevice *dev, int barnum); + +/** + * dm_pci_bus_to_phys() - convert a PCI bus address to a physical address + * + * @dev: Device containing the PCI address + * @addr: PCI address to convert + * @flags: Flags for the region type (PCI_REGION_...) + * @return physical address corresponding to that PCI bus address + */ +phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, + unsigned long flags); + +/** + * dm_pci_phys_to_bus() - convert a physical address to a PCI bus address + * + * @dev: Device containing the bus address + * @addr: Physical address to convert + * @flags: Flags for the region type (PCI_REGION_...) + * @return PCI bus address corresponding to that physical address + */ +pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, + unsigned long flags); + +/** + * dm_pci_map_bar() - get a virtual address associated with a BAR region + * + * Looks up a base address register and finds the physical memory address + * that corresponds to it + * + * @dev: Device to check + * @bar: Bar number to read (numbered from 0) + * @flags: Flags for the region type (PCI_REGION_...) + * @return: pointer to the virtual address to use + */ +void *dm_pci_map_bar(struct udevice *dev, int bar, int flags); + +#define dm_pci_virt_to_bus(dev, addr, flags) \ + dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags)) +#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \ + map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \ + (len), (map_flags)) + +#define dm_pci_phys_to_mem(dev, addr) \ + dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM) +#define dm_pci_mem_to_phys(dev, addr) \ + dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM) +#define dm_pci_phys_to_io(dev, addr) \ + dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO) +#define dm_pci_io_to_phys(dev, addr) \ + dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO) + +#define dm_pci_virt_to_mem(dev, addr) \ + dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM) +#define dm_pci_mem_to_virt(dev, addr, len, map_flags) \ + dm_pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags)) +#define dm_pci_virt_to_io(dev, addr) \ + dm_dm_pci_virt_to_bus((dev), (addr), PCI_REGION_IO) +#define dm_pci_io_to_virt(dev, addr, len, map_flags) \ + dm_dm_pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags)) + +/** + * dm_pci_find_device() - find a device by vendor/device ID + * + * @vendor: Vendor ID + * @device: Device ID + * @index: 0 to find the first match, 1 for second, etc. + * @devp: Returns pointer to the device, if found + * @return 0 if found, -ve on error + */ +int dm_pci_find_device(unsigned int vendor, unsigned int device, int index, + struct udevice **devp); + +/** + * dm_pci_find_class() - find a device by class + * + * @find_class: 3-byte (24-bit) class value to find + * @index: 0 to find the first match, 1 for second, etc. + * @devp: Returns pointer to the device, if found + * @return 0 if found, -ve on error + */ +int dm_pci_find_class(uint find_class, int index, struct udevice **devp); + /** * struct dm_pci_emul_ops - PCI device emulator operations */ diff --git a/include/pci_rom.h b/include/pci_rom.h index 2f1665d17a..95c6d079fb 100644 --- a/include/pci_rom.h +++ b/include/pci_rom.h @@ -44,14 +44,14 @@ enum pci_rom_emul { }; /** - * pci_run_vga_bios() - Run the VGA BIOS in an x86 PC + * dm_pci_run_vga_bios() - Run the VGA BIOS in an x86 PC * * @dev: Video device containing the BIOS * @int15_handler: Function to call to handle int 0x15 * @exec_method: flags from enum pci_rom_emul */ -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), - int exec_method); +int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void), + int exec_method); /** * board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects diff --git a/include/power/pmic.h b/include/power/pmic.h index 6ba4b6ecd6..e0b2e129dd 100644 --- a/include/power/pmic.h +++ b/include/power/pmic.h @@ -12,7 +12,6 @@ #define __CORE_PMIC_H_ #include -#include #include #include diff --git a/include/spi.h b/include/spi.h index b4d27232ec..4b88d3986e 100644 --- a/include/spi.h +++ b/include/spi.h @@ -11,41 +11,27 @@ #define _SPI_H_ /* SPI mode flags */ -#define SPI_CPHA 0x01 /* clock phase */ -#define SPI_CPOL 0x02 /* clock polarity */ -#define SPI_MODE_0 (0|0) /* (original MicroWire) */ -#define SPI_MODE_1 (0|SPI_CPHA) -#define SPI_MODE_2 (SPI_CPOL|0) -#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) -#define SPI_CS_HIGH 0x04 /* CS active high */ -#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ -#define SPI_3WIRE 0x10 /* SI/SO signals shared */ -#define SPI_LOOP 0x20 /* loopback mode */ -#define SPI_SLAVE 0x40 /* slave mode */ -#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ - -/* SPI transfer flags */ -#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ -#define SPI_XFER_END 0x02 /* Deassert CS after transfer */ -#define SPI_XFER_MMAP 0x08 /* Memory Mapped start */ -#define SPI_XFER_MMAP_END 0x10 /* Memory Mapped End */ -#define SPI_XFER_ONCE (SPI_XFER_BEGIN | SPI_XFER_END) -#define SPI_XFER_U_PAGE (1 << 5) - -/* SPI TX operation modes */ -#define SPI_OPM_TX_QPP (1 << 0) -#define SPI_OPM_TX_BP (1 << 1) - -/* SPI RX operation modes */ -#define SPI_OPM_RX_AS (1 << 0) -#define SPI_OPM_RX_AF (1 << 1) -#define SPI_OPM_RX_DOUT (1 << 2) -#define SPI_OPM_RX_DIO (1 << 3) -#define SPI_OPM_RX_QOF (1 << 4) -#define SPI_OPM_RX_QIOF (1 << 5) -#define SPI_OPM_RX_EXTN (SPI_OPM_RX_AS | SPI_OPM_RX_AF | SPI_OPM_RX_DOUT | \ - SPI_OPM_RX_DIO | SPI_OPM_RX_QOF | \ - SPI_OPM_RX_QIOF) +#define SPI_CPHA BIT(0) /* clock phase */ +#define SPI_CPOL BIT(1) /* clock polarity */ +#define SPI_MODE_0 (0|0) /* (original MicroWire) */ +#define SPI_MODE_1 (0|SPI_CPHA) +#define SPI_MODE_2 (SPI_CPOL|0) +#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) +#define SPI_CS_HIGH BIT(2) /* CS active high */ +#define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */ +#define SPI_3WIRE BIT(4) /* SI/SO signals shared */ +#define SPI_LOOP BIT(5) /* loopback mode */ +#define SPI_SLAVE BIT(6) /* slave mode */ +#define SPI_PREAMBLE BIT(7) /* Skip preamble bytes */ +#define SPI_TX_BYTE BIT(8) /* transmit with 1 wire byte */ +#define SPI_TX_DUAL BIT(9) /* transmit with 2 wires */ +#define SPI_TX_QUAD BIT(10) /* transmit with 4 wires */ + +/* SPI mode_rx flags */ +#define SPI_RX_SLOW BIT(0) /* receive with 1 wire slow */ +#define SPI_RX_FAST BIT(1) /* receive with 1 wire fast */ +#define SPI_RX_DUAL BIT(2) /* receive with 2 wires */ +#define SPI_RX_QUAD BIT(3) /* receive with 4 wires */ /* SPI bus connection options - see enum spi_dual_flash */ #define SPI_CONN_DUAL_SHARED (1 << 0) @@ -75,11 +61,13 @@ struct dm_spi_bus { * @cs: Chip select number (0..n-1) * @max_hz: Maximum bus speed that this slave can tolerate * @mode: SPI mode to use for this device (see SPI mode flags) + * @mode_rx: SPI RX mode to use for this slave (see SPI mode_rx flags) */ struct dm_spi_slave_platdata { unsigned int cs; uint max_hz; uint mode; + u8 mode_rx; }; #endif /* CONFIG_DM_SPI */ @@ -99,15 +87,14 @@ struct dm_spi_slave_platdata { * * @dev: SPI slave device * @max_hz: Maximum speed for this slave - * @mode: SPI mode to use for this slave (see SPI mode flags) * @speed: Current bus speed. This is 0 until the bus is first * claimed. * @bus: ID of the bus that the slave is attached to. For * driver model this is the sequence number of the SPI * bus (bus->seq) so does not need to be stored * @cs: ID of the chip select connected to the slave. - * @op_mode_rx: SPI RX operation mode. - * @op_mode_tx: SPI TX operation mode. + * @mode: SPI mode to use for this slave (see SPI mode flags) + * @mode_rx: SPI RX mode to use for this slave (see SPI mode_rx flags) * @wordlen: Size of SPI word in number of bits * @max_write_size: If non-zero, the maximum number of bytes which can * be written at once, excluding command bytes. @@ -120,18 +107,24 @@ struct spi_slave { struct udevice *dev; /* struct spi_slave is dev->parentdata */ uint max_hz; uint speed; - uint mode; #else unsigned int bus; unsigned int cs; #endif - u8 op_mode_rx; - u8 op_mode_tx; + uint mode; + u8 mode_rx; unsigned int wordlen; unsigned int max_write_size; void *memory_map; u8 option; + u8 flags; +#define SPI_XFER_BEGIN BIT(0) /* Assert CS before transfer */ +#define SPI_XFER_END BIT(1) /* Deassert CS after transfer */ +#define SPI_XFER_ONCE (SPI_XFER_BEGIN | SPI_XFER_END) +#define SPI_XFER_MMAP BIT(2) /* Memory Mapped start */ +#define SPI_XFER_MMAP_END BIT(3) /* Memory Mapped End */ +#define SPI_XFER_U_PAGE BIT(4) }; /** diff --git a/include/spi_flash.h b/include/spi_flash.h index f25b3e7819..0d26b8a5aa 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -170,8 +170,6 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, /* Compatibility function - this is the old U-Boot API */ void spi_flash_free(struct spi_flash *flash); -int spi_flash_remove(struct udevice *flash); - static inline int spi_flash_read(struct spi_flash *flash, u32 offset, size_t len, void *buf) { diff --git a/lib/fdtdec.c b/lib/fdtdec.c index ae0b708ddc..1093c30526 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -5,6 +5,7 @@ #ifndef USE_HOSTCC #include +#include #include #include #include @@ -190,7 +191,7 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node, return fdtdec_get_addr_size(blob, node, prop_name, NULL); } -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI) int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type, const char *prop_name, struct fdt_pci_addr *addr) { @@ -283,58 +284,10 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device) return -ENOENT; } -int fdtdec_get_pci_bdf(const void *blob, int node, - struct fdt_pci_addr *addr, pci_dev_t *bdf) +int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, + u32 *bar) { - u16 dt_vendor, dt_device, vendor, device; - int ret; - - /* get vendor id & device id from the compatible string */ - ret = fdtdec_get_pci_vendev(blob, node, &dt_vendor, &dt_device); - if (ret) - return ret; - - /* extract the bdf from fdt_pci_addr */ - *bdf = addr->phys_hi & 0xffff00; - - /* read vendor id & device id based on bdf */ - pci_read_config_word(*bdf, PCI_VENDOR_ID, &vendor); - pci_read_config_word(*bdf, PCI_DEVICE_ID, &device); - - /* - * Note there are two places in the device tree to fully describe - * a pci device: one is via compatible string with a format of - * "pciVVVV,DDDD" and the other one is the bdf numbers encoded in - * the device node's reg address property. We read the vendor id - * and device id based on bdf and compare the values with the - * "VVVV,DDDD". If they are the same, then we are good to use bdf - * to read device's bar. But if they are different, we have to rely - * on the vendor id and device id extracted from the compatible - * string and locate the real bdf by pci_find_device(). This is - * because normally we may only know device's device number and - * function number when writing device tree. The bus number is - * dynamically assigned during the pci enumeration process. - */ - if ((dt_vendor != vendor) || (dt_device != device)) { - *bdf = pci_find_device(dt_vendor, dt_device, 0); - if (*bdf == -1) - return -ENODEV; - } - - return 0; -} - -int fdtdec_get_pci_bar32(const void *blob, int node, - struct fdt_pci_addr *addr, u32 *bar) -{ - pci_dev_t bdf; int barnum; - int ret; - - /* get pci devices's bdf */ - ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf); - if (ret) - return ret; /* extract the bar number from fdt_pci_addr */ barnum = addr->phys_hi & 0xff; @@ -342,7 +295,7 @@ int fdtdec_get_pci_bar32(const void *blob, int node, return -EINVAL; barnum = (barnum - PCI_BASE_ADDRESS_0) / 4; - *bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum); + *bar = dm_pci_read_bar32(dev, barnum); return 0; } diff --git a/test/dm/pci.c b/test/dm/pci.c index 3ab4ba811c..a5b1290112 100644 --- a/test/dm/pci.c +++ b/test/dm/pci.c @@ -35,20 +35,17 @@ DM_TEST(dm_test_pci_busnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* Test that we can use the swapcase device correctly */ static int dm_test_pci_swapcase(struct unit_test_state *uts) { - pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0); - struct pci_controller *hose; - struct udevice *bus, *swap; + struct udevice *emul, *swap; ulong io_addr, mem_addr; char *ptr; /* Check that asking for the device automatically fires up PCI */ - ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap)); - - ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus)); - hose = dev_get_uclass_priv(bus); + ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &emul)); + ut_assertok(dm_pci_bus_find_bdf(PCI_BDF(0, 0x1f, 0), &swap)); + ut_assert(device_active(swap)); /* First test I/O */ - io_addr = pci_read_bar32(hose, pci_dev, 0); + io_addr = dm_pci_read_bar32(swap, 0); outb(2, io_addr); ut_asserteq(2, inb(io_addr)); @@ -56,7 +53,7 @@ static int dm_test_pci_swapcase(struct unit_test_state *uts) * Now test memory mapping - note we must unmap and remap to cause * the swapcase emulation to see our data and response. */ - mem_addr = pci_read_bar32(hose, pci_dev, 1); + mem_addr = dm_pci_read_bar32(swap, 1); ptr = map_sysmem(mem_addr, 20); strcpy(ptr, "This is a TesT"); unmap_sysmem(ptr);