diff options
174 files changed, 7603 insertions, 1966 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 5afe8a91fd..5f10243fe6 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -45,8 +45,11 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ph1-ld4-ref.dtb \ uniphier-ph1-ld6b-ref.dtb \ uniphier-ph1-pro4-ref.dtb \ + uniphier-ph1-pro5-4kbox.dtb \ uniphier-ph1-sld3-ref.dtb \ - uniphier-ph1-sld8-ref.dtb + uniphier-ph1-sld8-ref.dtb \ + uniphier-proxstream2-gentil.dtb \ + uniphier-proxstream2-vodka.dtb dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \ zynq-zc706.dtb \ zynq-zed.dtb \ diff --git a/arch/arm/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/dts/uniphier-ph1-ld4-ref.dts index 20f2e9a7d2..9d697c1c88 100644 --- a/arch/arm/dts/uniphier-ph1-ld4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-ld4-ref.dts @@ -61,6 +61,20 @@ }; /* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + &serial0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart0 { + u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/uniphier-ph1-ld6b-ref.dts b/arch/arm/dts/uniphier-ph1-ld6b-ref.dts index 58dc20e602..bd86f09326 100644 --- a/arch/arm/dts/uniphier-ph1-ld6b-ref.dts +++ b/arch/arm/dts/uniphier-ph1-ld6b-ref.dts @@ -3,6 +3,7 @@ * * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> * + * SPDX-License-Identifier: GPL-2.0+ */ /dts-v1/; @@ -54,6 +55,20 @@ }; /* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + &serial0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart0 { + u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/dts/uniphier-ph1-pro4-ref.dts index ec1117d4a2..a825069638 100644 --- a/arch/arm/dts/uniphier-ph1-pro4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-pro4-ref.dts @@ -68,6 +68,20 @@ }; /* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + &serial0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart0 { + u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/uniphier-ph1-pro5-4kbox.dts b/arch/arm/dts/uniphier-ph1-pro5-4kbox.dts new file mode 100644 index 0000000000..912bc27bea --- /dev/null +++ b/arch/arm/dts/uniphier-ph1-pro5-4kbox.dts @@ -0,0 +1,64 @@ +/* + * Device Tree Source for UniPhier PH1-Pro5 4KBOX Board (EVB-Pro5-4KBOX-M-V0) + * + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "uniphier-ph1-pro5.dtsi" + +/ { + model = "UniPhier PH1-Pro5 4KBOX Board"; + compatible = "socionext,ph1-pro5-4kbox", "socionext,ph1-pro5"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + chosen { + bootargs = "console=ttyS1,115200"; + stdout-path = &serial1; + }; + + aliases { + serial1 = &serial1; + serial2 = &serial2; + i2c0 = &i2c0; + i2c5 = &i2c5; + i2c6 = &i2c6; + }; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +/* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + +&serial1 { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart1 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/dts/uniphier-ph1-sld8-ref.dts index 6269f9afd3..2cfcaff54a 100644 --- a/arch/arm/dts/uniphier-ph1-sld8-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld8-ref.dts @@ -65,6 +65,20 @@ }; /* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + &serial0 { - u-boot,dm-pre-reloc; + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart0 { + u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/uniphier-pinctrl.dtsi b/arch/arm/dts/uniphier-pinctrl.dtsi index f67445f4f1..b58421396d 100644 --- a/arch/arm/dts/uniphier-pinctrl.dtsi +++ b/arch/arm/dts/uniphier-pinctrl.dtsi @@ -3,43 +3,7 @@ * * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: GPL-2.0+ X11 */ &pinctrl { diff --git a/arch/arm/dts/uniphier-proxstream2-gentil.dts b/arch/arm/dts/uniphier-proxstream2-gentil.dts new file mode 100644 index 0000000000..81d2385bf9 --- /dev/null +++ b/arch/arm/dts/uniphier-proxstream2-gentil.dts @@ -0,0 +1,62 @@ +/* + * Device Tree Source for UniPhier ProXstream2 Gentil Board + * + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "uniphier-proxstream2.dtsi" + +/ { + model = "UniPhier ProXstream2 Gentil Board"; + compatible = "socionext,proxstream2-gentil", "socionext,proxstream2"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + chosen { + bootargs = "console=ttyS2,115200"; + stdout-path = &serial2; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + i2c0 = &i2c0; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + }; +}; + +&serial2 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +/* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + +&serial2 { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart2 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/uniphier-proxstream2-vodka.dts b/arch/arm/dts/uniphier-proxstream2-vodka.dts new file mode 100644 index 0000000000..fba7b742ca --- /dev/null +++ b/arch/arm/dts/uniphier-proxstream2-vodka.dts @@ -0,0 +1,62 @@ +/* + * Device Tree Source for UniPhier ProXstream2 Vodka Board + * + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "uniphier-proxstream2.dtsi" + +/ { + model = "UniPhier ProXstream2 Vodka Board"; + compatible = "socionext,proxstream2-vodka", "socionext,proxstream2"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + chosen { + bootargs = "console=ttyS2,115200"; + stdout-path = &serial2; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + i2c0 = &i2c0; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + }; +}; + +&serial2 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +/* for U-boot only */ +/ { + soc { + u-boot,dm-pre-reloc; + }; +}; + +&serial2 { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart2 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 089280a91d..a413ea4d1b 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -50,8 +50,8 @@ config SYS_SOC default "socfpga" config SYS_CONFIG_NAME - default "socfpga_arria5" if TARGET_SOCFPGA_ARRIA5_SOCDK - default "socfpga_cyclone5" if TARGET_SOCFPGA_CYCLONE5_SOCDK + default "socfpga_arria5_socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK + default "socfpga_cyclone5_socdk" if TARGET_SOCFPGA_CYCLONE5_SOCDK default "socfpga_de0_nano_soc" if TARGET_SOCFPGA_TERASIC_DE0_NANO default "socfpga_mcvevk" if TARGET_SOCFPGA_DENX_MCVEVK default "socfpga_sockit" if TARGET_SOCFPGA_TERASIC_SOCKIT diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index 7b49ad3b49..22ab798b96 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -6,49 +6,68 @@ config SYS_CONFIG_NAME config UNIPHIER_SMP bool -choice - prompt "UniPhier SoC select" - default MACH_PH1_PRO4 - -config MACH_PH1_SLD3 - bool "PH1-sLD3" +config ARCH_UNIPHIER_PH1_SLD3 + bool "UniPhier PH1-sLD3 SoC" select UNIPHIER_SMP + help + This enables support for UniPhier PH1-sLD3 SoC. -config MACH_PH1_LD4 - bool "PH1-LD4" +config ARCH_UNIPHIER_PH1_LD4 + bool "UniPhier PH1-LD4 SoC" + depends on !ARCH_UNIPHIER_PH1_SLD3 + help + This enables support for UniPhier PH1-LD4 SoC. -config MACH_PH1_PRO4 - bool "PH1-Pro4" +config ARCH_UNIPHIER_PH1_PRO4 + bool "UniPhier PH1-Pro4 SoC" select UNIPHIER_SMP + depends on !ARCH_UNIPHIER_PH1_SLD3 && \ + !ARCH_UNIPHIER_PH1_LD4 && \ + !ARCH_UNIPHIER_PH1_SLD8 + help + This enables support for UniPhier PH1-Pro4 SoC. -config MACH_PH1_SLD8 - bool "PH1-sLD8" - -endchoice +config ARCH_UNIPHIER_PH1_SLD8 + bool "UniPhier PH1-sLD8 SoC" + depends on !ARCH_UNIPHIER_PH1_SLD3 + help + This enables support for UniPhier PH1-sLD8 SoC. -choice - prompt "UniPhier Support Card select" - optional +config ARCH_UNIPHIER_PH1_PRO5 + bool "UniPhier PH1-Pro5 SoC" + select UNIPHIER_SMP + depends on !ARCH_UNIPHIER_PH1_SLD3 && \ + !ARCH_UNIPHIER_PH1_LD4 && \ + !ARCH_UNIPHIER_PH1_SLD8 + help + This enables support for UniPhier PH1-Pro5 SoC. -config PFC_MICRO_SUPPORT_CARD - bool "Support card with PFC CPLD" +config ARCH_UNIPHIER_PROXSTREAM2 + bool "UniPhier ProXstream2 SoC" + select UNIPHIER_SMP + depends on !ARCH_UNIPHIER_PH1_SLD3 && \ + !ARCH_UNIPHIER_PH1_LD4 && \ + !ARCH_UNIPHIER_PH1_SLD8 help - This option provides support for the expansion board with PFC - original address mapping. + This enables support for UniPhier ProXstream2 SoC. - Say Y to use the on-board UART, Ether, LED devices. +config ARCH_UNIPHIER_PH1_LD6B + bool "UniPhier PH1-LD6b SoC" + select UNIPHIER_SMP + depends on !ARCH_UNIPHIER_PH1_SLD3 && \ + !ARCH_UNIPHIER_PH1_LD4 && \ + !ARCH_UNIPHIER_PH1_SLD8 + help + This enables support for UniPhier PH1-LD6b SoC. -config DCC_MICRO_SUPPORT_CARD - bool "Support card with DCC CPLD" +config MICRO_SUPPORT_CARD + bool "Use Micro Support Card" help - This option provides support for the expansion board with DCC- - arranged address mapping that is compatible with legacy UniPhier - reference boards. + This option provides support for the expansion board, available + on some UniPhier reference boards. Say Y to use the on-board UART, Ether, LED devices. -endchoice - config CMD_PINMON bool "Enable boot mode pins monitor command" default y @@ -63,22 +82,4 @@ config CMD_DDRPHY_DUMP The command "ddrphy" shows the resulting parameters of DDR PHY training; it is useful for the evaluation of DDR PHY training. -choice - prompt "DDR3 Frequency select" - -config DDR_FREQ_1600 - bool "DDR3 1600" - depends on MACH_PH1_SLD3 || MACH_PH1_LD4 || MACH_PH1_PRO4 - -config DDR_FREQ_1333 - bool "DDR3 1333" - depends on MACH_PH1_SLD3 || MACH_PH1_LD4 || MACH_PH1_SLD8 - -endchoice - -config DDR_FREQ - int - default 1333 if DDR_FREQ_1333 - default 1600 if DDR_FREQ_1600 - endif diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile index 103db6d7dc..b597a1352c 100644 --- a/arch/arm/mach-uniphier/Makefile +++ b/arch/arm/mach-uniphier/Makefile @@ -6,9 +6,12 @@ ifdef CONFIG_SPL_BUILD obj-y += lowlevel_init.o obj-y += init_page_table.o -obj-y += spl.o -obj-y += memconf.o -obj-y += ddrphy_training.o +obj-y += boards.o + +obj-y += init/ bcu/ memconf/ pll/ early-clk/ early-pinctrl/ umc/ ddrphy/ +obj-$(CONFIG_MICRO_SUPPORT_CARD) += sbc/ + +obj-$(CONFIG_DEBUG_LL) += debug_ll.o else @@ -25,14 +28,12 @@ obj-y += cache_uniphier.o obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o +obj-y += pinctrl/ clk/ + endif obj-y += timer.o +obj-y += soc_info.o +obj-y += boot-mode/ -obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += support_card.o -obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += support_card.o - -obj-$(CONFIG_MACH_PH1_SLD3) += ph1-sld3/ -obj-$(CONFIG_MACH_PH1_LD4) += ph1-ld4/ -obj-$(CONFIG_MACH_PH1_PRO4) += ph1-pro4/ -obj-$(CONFIG_MACH_PH1_SLD8) += ph1-sld8/ +obj-$(CONFIG_MICRO_SUPPORT_CARD) += micro-support-card.o diff --git a/arch/arm/mach-uniphier/bcu/Makefile b/arch/arm/mach-uniphier/bcu/Makefile new file mode 100644 index 0000000000..5b95bdad95 --- /dev/null +++ b/arch/arm/mach-uniphier/bcu/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += bcu-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += bcu-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += bcu-ph1-ld4.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/bcu_init.c b/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c index a7bc15e7e0..e9d3761fde 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/bcu_init.c +++ b/arch/arm/mach-uniphier/bcu/bcu-ph1-ld4.c @@ -4,13 +4,13 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include <common.h> #include <linux/io.h> #include <mach/bcu-regs.h> +#include <mach/init.h> #define ch(x) ((x) >= 32 ? 0 : (x) < 0 ? 0x11111111 : 0x11111111 << (x)) -void bcu_init(void) +int ph1_ld4_bcu_init(const struct uniphier_board_data *bd) { int shift; @@ -21,7 +21,7 @@ void bcu_init(void) writel(0x11111111, BCSCR5); /* 0xe0000000-0Xffffffff: IPPC/IPPD-bus */ /* Specify DDR channel */ - shift = (CONFIG_SDRAM1_BASE - CONFIG_SDRAM0_BASE) / 0x04000000 * 4; + shift = (bd->dram_ch1_base - bd->dram_ch0_base) / 0x04000000 * 4; writel(ch(shift), BCIPPCCHR2); /* 0x80000000-0x9fffffff */ shift -= 32; @@ -29,4 +29,6 @@ void bcu_init(void) shift -= 32; writel(ch(shift), BCIPPCCHR4); /* 0xc0000000-0xdfffffff */ + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld3/bcu_init.c b/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c index ccc6897d0a..cb6f862721 100644 --- a/arch/arm/mach-uniphier/ph1-sld3/bcu_init.c +++ b/arch/arm/mach-uniphier/bcu/bcu-ph1-sld3.c @@ -4,13 +4,13 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include <common.h> #include <linux/io.h> #include <mach/bcu-regs.h> +#include <mach/init.h> #define ch(x) ((x) >= 32 ? 0 : (x) < 0 ? 0x11111111 : 0x11111111 << (x)) -void bcu_init(void) +int ph1_sld3_bcu_init(const struct uniphier_board_data *bd) { int shift; @@ -25,7 +25,7 @@ void bcu_init(void) writel(0x24440000, BCSCR5); /* Specify DDR channel */ - shift = (CONFIG_SDRAM1_BASE - CONFIG_SDRAM0_BASE) / 0x04000000 * 4; + shift = (bd->dram_ch1_base - bd->dram_ch0_base) / 0x04000000 * 4; writel(ch(shift), BCIPPCCHR2); /* 0x80000000-0x9fffffff */ shift -= 32; @@ -33,4 +33,6 @@ void bcu_init(void) shift -= 32; writel(ch(shift), BCIPPCCHR4); /* 0xc0000000-0xdfffffff */ + + return 0; } diff --git a/arch/arm/mach-uniphier/board_common.c b/arch/arm/mach-uniphier/board_common.c index 5f2d5f6f5b..198004b59b 100644 --- a/arch/arm/mach-uniphier/board_common.c +++ b/arch/arm/mach-uniphier/board_common.c @@ -1,32 +1,15 @@ /* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <mach/led.h> +#include <mach/micro-support-card.h> -/* - * Routine: board_init - * Description: Early hardware init. - */ int board_init(void) { - led_write(U, B, O, O); + led_puts("Uboo"); return 0; } - -#if CONFIG_NR_DRAM_BANKS >= 2 -void dram_init_banksize(void) -{ - DECLARE_GLOBAL_DATA_PTR; - - gd->bd->bi_dram[0].start = CONFIG_SDRAM0_BASE; - gd->bd->bi_dram[0].size = CONFIG_SDRAM0_SIZE; - gd->bd->bi_dram[1].start = CONFIG_SDRAM1_BASE; - gd->bd->bi_dram[1].size = CONFIG_SDRAM1_SIZE; -} -#endif diff --git a/arch/arm/mach-uniphier/board_early_init_f.c b/arch/arm/mach-uniphier/board_early_init_f.c index 7108740408..5e0d246ce4 100644 --- a/arch/arm/mach-uniphier/board_early_init_f.c +++ b/arch/arm/mach-uniphier/board_early_init_f.c @@ -1,27 +1,72 @@ /* - * Copyright (C) 2012-2015 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ -#include <mach/led.h> -#include <mach/board.h> - -void pin_init(void); -void clkrst_init(void); +#include <mach/init.h> +#include <mach/micro-support-card.h> +#include <mach/soc_info.h> int board_early_init_f(void) { - led_write(U, 0, , ); - - pin_init(); - - led_write(U, 1, , ); + led_puts("U0"); - clkrst_init(); + switch (uniphier_get_soc_type()) { +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + case SOC_UNIPHIER_PH1_SLD3: + ph1_sld3_pin_init(); + led_puts("U1"); + ph1_ld4_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) + case SOC_UNIPHIER_PH1_LD4: + ph1_ld4_pin_init(); + led_puts("U1"); + ph1_ld4_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) + case SOC_UNIPHIER_PH1_PRO4: + ph1_pro4_pin_init(); + led_puts("U1"); + ph1_pro4_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + case SOC_UNIPHIER_PH1_SLD8: + ph1_sld8_pin_init(); + led_puts("U1"); + ph1_ld4_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + case SOC_UNIPHIER_PH1_PRO5: + ph1_pro5_pin_init(); + led_puts("U1"); + ph1_pro5_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) + case SOC_UNIPHIER_PROXSTREAM2: + proxstream2_pin_init(); + led_puts("U1"); + proxstream2_clk_init(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + case SOC_UNIPHIER_PH1_LD6B: + ph1_ld6b_pin_init(); + led_puts("U1"); + proxstream2_clk_init(); + break; +#endif + default: + break; + } - led_write(U, 2, , ); + led_puts("U2"); return 0; } diff --git a/arch/arm/mach-uniphier/board_early_init_r.c b/arch/arm/mach-uniphier/board_early_init_r.c index 579fe70463..28c7f82228 100644 --- a/arch/arm/mach-uniphier/board_early_init_r.c +++ b/arch/arm/mach-uniphier/board_early_init_r.c @@ -1,15 +1,14 @@ /* - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <mach/board.h> +#include <mach/micro-support-card.h> int board_early_init_r(void) { - uniphier_board_late_init(); + support_card_late_init(); return 0; } diff --git a/arch/arm/mach-uniphier/boards.c b/arch/arm/mach-uniphier/boards.c new file mode 100644 index 0000000000..812c58ff96 --- /dev/null +++ b/arch/arm/mach-uniphier/boards.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <libfdt.h> +#include <linux/kernel.h> +#include <mach/init.h> + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) +static const struct uniphier_board_data ph1_sld3_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x20000000, + .dram_ch0_width = 32, + .dram_ch1_base = 0xc0000000, + .dram_ch1_size = 0x20000000, + .dram_ch1_width = 16, + .dram_ch2_base = 0xc0000000, + .dram_ch2_size = 0x10000000, + .dram_ch2_width = 16, + .dram_freq = 1600, +}; +#endif + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) +static const struct uniphier_board_data ph1_ld4_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x10000000, + .dram_ch0_width = 16, + .dram_ch1_base = 0x90000000, + .dram_ch1_size = 0x10000000, + .dram_ch1_width = 16, + .dram_freq = 1600, +}; +#endif + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) +static const struct uniphier_board_data ph1_pro4_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x20000000, + .dram_ch0_width = 32, + .dram_ch1_base = 0xa0000000, + .dram_ch1_size = 0x20000000, + .dram_ch1_width = 32, + .dram_freq = 1600, +}; +#endif + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) +static const struct uniphier_board_data ph1_sld8_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x10000000, + .dram_ch0_width = 16, + .dram_ch1_base = 0x90000000, + .dram_ch1_size = 0x10000000, + .dram_ch1_width = 16, + .dram_freq = 1333, +}; +#endif + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) +static const struct uniphier_board_data ph1_pro5_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x20000000, + .dram_ch0_width = 32, + .dram_ch1_base = 0xa0000000, + .dram_ch1_size = 0x20000000, + .dram_ch1_width = 32, + .dram_freq = 1866, +}; +#endif + +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) +static const struct uniphier_board_data proxstream2_data = { + .dram_ch0_base = 0x80000000, + .dram_ch0_size = 0x40000000, + .dram_ch0_width = 32, + .dram_ch1_base = 0xc0000000, + .dram_ch1_size = 0x20000000, + .dram_ch1_width = 32, + .dram_ch2_base = 0xe0000000, + .dram_ch2_size = 0x20000000, + .dram_ch2_width = 16, + .dram_freq = 1866, +}; +#endif + +struct uniphier_board_id { + const char *compatible; + const struct uniphier_board_data *param; +}; + +static const struct uniphier_board_id uniphier_boards[] = { +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + { "socionext,ph1-sld3", &ph1_sld3_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) + { "socionext,ph1-ld4", &ph1_ld4_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) + { "socionext,ph1-pro4", &ph1_pro4_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + { "socionext,ph1-sld8", &ph1_sld8_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + { "socionext,ph1-pro5", &ph1_pro5_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) + { "socionext,proxstream2", &proxstream2_data, }, +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + { "socionext,ph1-ld6b", &proxstream2_data, }, +#endif +}; + +const struct uniphier_board_data *uniphier_get_board_param(const void *fdt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(uniphier_boards); i++) { + if (!fdt_node_check_compatible(fdt, 0, + uniphier_boards[i].compatible)) + return uniphier_boards[i].param; + } + + return NULL; +} diff --git a/arch/arm/mach-uniphier/boot-mode/Makefile b/arch/arm/mach-uniphier/boot-mode/Makefile new file mode 100644 index 0000000000..30c8874905 --- /dev/null +++ b/arch/arm/mach-uniphier/boot-mode/Makefile @@ -0,0 +1,9 @@ +obj-y += boot-mode.o + +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += boot-mode-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += boot-mode-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += boot-mode-ph1-ld4.o +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 diff --git a/arch/arm/mach-uniphier/ph1-pro4/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c index 54a2510b97..f974d9f08d 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/boot-mode.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-ld4.c @@ -44,22 +44,31 @@ struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, - { /* sentinel */ } }; -int get_boot_mode_sel(void) +static int get_boot_mode_sel(void) { return (readl(SG_PINMON0) >> 1) & 0x1f; } -u32 spl_boot_device(void) +u32 ph1_ld4_boot_device(void) { int boot_mode; - if (boot_is_swapped()) - return BOOT_DEVICE_NOR; - boot_mode = get_boot_mode_sel(); return boot_device_table[boot_mode].type; } + +void ph1_ld4_boot_mode_show(void) +{ + int mode_sel, i; + + mode_sel = get_boot_mode_sel(); + + puts("Boot Mode Pin:\n"); + + for (i = 0; i < ARRAY_SIZE(boot_device_table); i++) + printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, + boot_device_table[i].info); +} 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 new file mode 100644 index 0000000000..c68cb59fc0 --- /dev/null +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-pro5.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/io.h> +#include <mach/boot-device.h> +#include <mach/sbc-regs.h> +#include <mach/sg-regs.h> + +static struct boot_device_info boot_device_table[] = { + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128MB, Addr 4)"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 512MB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, ONFI, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, ONFI, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, ONFI, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, ONFI, Addr 4)"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_MMC1, "eMMC Boot (1.8V)"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NONE, "Reserved"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128MB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 256KB, Addr 5)"}, + { /* sentinel */ } +}; + +static int get_boot_mode_sel(void) +{ + return (readl(SG_PINMON0) >> 1) & 0x1f; +} + +u32 ph1_pro5_boot_device(void) +{ + int boot_mode; + + boot_mode = get_boot_mode_sel(); + + return boot_device_table[boot_mode].type; +} + +void ph1_pro5_boot_mode_show(void) +{ + int mode_sel, i; + + mode_sel = get_boot_mode_sel(); + + puts("Boot Mode Pin:\n"); + + for (i = 0; i < ARRAY_SIZE(boot_device_table); i++) + printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, + boot_device_table[i].info); +} diff --git a/arch/arm/mach-uniphier/ph1-sld3/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c index 40000afe74..c943e12db1 100644 --- a/arch/arm/mach-uniphier/ph1-sld3/boot-mode.c +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-ph1-sld3.c @@ -11,7 +11,7 @@ #include <mach/sg-regs.h> #include <mach/sbc-regs.h> -struct boot_device_info boot_device_table[] = { +static struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "External Master"}, {BOOT_DEVICE_NONE, "Reserved"}, @@ -76,22 +76,31 @@ struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, - { /* sentinel */ } }; -int get_boot_mode_sel(void) +static int get_boot_mode_sel(void) { return readl(SG_PINMON0) & 0x3f; } -u32 spl_boot_device(void) +u32 ph1_sld3_boot_device(void) { int boot_mode; - if (boot_is_swapped()) - return BOOT_DEVICE_NOR; - boot_mode = get_boot_mode_sel(); return boot_device_table[boot_mode].type; } + +void ph1_sld3_boot_mode_show(void) +{ + int mode_sel, i; + + mode_sel = get_boot_mode_sel(); + + puts("Boot Mode Pin:\n"); + + for (i = 0; i < ARRAY_SIZE(boot_device_table); i++) + printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, + boot_device_table[i].info); +} diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c new file mode 100644 index 0000000000..10a47c6fcc --- /dev/null +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/io.h> +#include <mach/boot-device.h> +#include <mach/init.h> +#include <mach/sbc-regs.h> +#include <mach/sg-regs.h> + +static struct boot_device_info boot_device_table[] = { + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 256KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 512KB, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128KB, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, ONFI, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, ONFI, Addr 4)"}, + {BOOT_DEVICE_MMC1, "eMMC Boot (1.8V)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, ONFI, Addr 5)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, ONFI, Addr 4)"}, + {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, ONFI, Addr 4)"}, + {BOOT_DEVICE_SPI, "SPI 3Byte CS0"}, + {BOOT_DEVICE_SPI, "SPI 4Byte CS0"}, + {BOOT_DEVICE_SPI, "SPI 3Byte CS1"}, + {BOOT_DEVICE_SPI, "SPI 4Byte CS1"}, + {BOOT_DEVICE_SPI, "SPI 4Byte CS0"}, + {BOOT_DEVICE_SPI, "SPI 3Byte CS0"}, + {BOOT_DEVICE_NONE, "Reserved"}, +}; + +int get_boot_mode_sel(void) +{ + return (readl(SG_PINMON0) >> 1) & 0x1f; +} + +u32 proxstream2_boot_device(void) +{ + int boot_mode; + + boot_mode = get_boot_mode_sel(); + + return boot_device_table[boot_mode].type; +} + +void proxstream2_boot_mode_show(void) +{ + int mode_sel, i; + + mode_sel = get_boot_mode_sel(); + + puts("Boot Mode Pin:\n"); + + for (i = 0; i < ARRAY_SIZE(boot_device_table); i++) + printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, + boot_device_table[i].info); +} diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode.c new file mode 100644 index 0000000000..c6cafa7919 --- /dev/null +++ b/arch/arm/mach-uniphier/boot-mode/boot-mode.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/io.h> +#include <mach/boot-device.h> +#include <mach/sbc-regs.h> +#include <mach/soc_info.h> + +u32 spl_boot_device(void) +{ + if (boot_is_swapped()) + return BOOT_DEVICE_NOR; + + switch (uniphier_get_soc_type()) { +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + case SOC_UNIPHIER_PH1_SLD3: + return ph1_sld3_boot_device(); +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + case SOC_UNIPHIER_PH1_LD4: + case SOC_UNIPHIER_PH1_PRO4: + case SOC_UNIPHIER_PH1_SLD8: + return ph1_ld4_boot_device(); +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + case SOC_UNIPHIER_PH1_PRO5: + return ph1_pro5_boot_device(); +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + case SOC_UNIPHIER_PROXSTREAM2: + case SOC_UNIPHIER_PH1_LD6B: + return proxstream2_boot_device(); +#endif + default: + return BOOT_DEVICE_NONE; + } +} diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile new file mode 100644 index 0000000000..4f397b986b --- /dev/null +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += clk-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += clk-ph1-pro5.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += clk-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += clk-proxstream2.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/clkrst_init.c b/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c index 2de81f0a56..8b95fbb008 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/clkrst_init.c +++ b/arch/arm/mach-uniphier/clk/clk-ph1-ld4.c @@ -5,9 +5,10 @@ */ #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> -void clkrst_init(void) +void ph1_ld4_clk_init(void) { u32 tmp; diff --git a/arch/arm/mach-uniphier/ph1-pro4/clkrst_init.c b/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c index 46cace77e5..2e1b20a423 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/clkrst_init.c +++ b/arch/arm/mach-uniphier/clk/clk-ph1-pro4.c @@ -5,9 +5,10 @@ */ #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> -void clkrst_init(void) +void ph1_pro4_clk_init(void) { u32 tmp; diff --git a/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c b/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c new file mode 100644 index 0000000000..f78edbbe3f --- /dev/null +++ b/arch/arm/mach-uniphier/clk/clk-ph1-pro5.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sc-regs.h> + +void ph1_pro5_clk_init(void) +{ + u32 tmp; + + /* deassert reset */ + tmp = readl(SC_RSTCTRL); +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; +#endif +#ifdef CONFIG_NAND_DENALI + tmp |= SC_RSTCTRL_NRST_NAND; +#endif + writel(tmp, SC_RSTCTRL); + readl(SC_RSTCTRL); /* dummy read */ + +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp = readl(SC_RSTCTRL2); + tmp |= SC_RSTCTRL2_NRST_USB3B1; + writel(tmp, SC_RSTCTRL2); + readl(SC_RSTCTRL2); /* dummy read */ +#endif + + /* privide clocks */ + tmp = readl(SC_CLKCTRL); +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | + SC_CLKCTRL_CEN_GIO; +#endif +#ifdef CONFIG_NAND_DENALI + tmp |= SC_CLKCTRL_CEN_NAND; +#endif + writel(tmp, SC_CLKCTRL); + readl(SC_CLKCTRL); /* dummy read */ +} diff --git a/arch/arm/mach-uniphier/clk/clk-proxstream2.c b/arch/arm/mach-uniphier/clk/clk-proxstream2.c new file mode 100644 index 0000000000..b494021ecf --- /dev/null +++ b/arch/arm/mach-uniphier/clk/clk-proxstream2.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sc-regs.h> + +void proxstream2_clk_init(void) +{ + u32 tmp; + + /* deassert reset */ + tmp = readl(SC_RSTCTRL); +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; +#endif +#ifdef CONFIG_UNIPHIER_ETH + tmp |= SC_RSTCTRL_NRST_ETHER; +#endif +#ifdef CONFIG_NAND_DENALI + tmp |= SC_RSTCTRL_NRST_NAND; +#endif + writel(tmp, SC_RSTCTRL); + readl(SC_RSTCTRL); /* dummy read */ + +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp = readl(SC_RSTCTRL2); + tmp |= SC_RSTCTRL2_NRST_USB3B1; + writel(tmp, SC_RSTCTRL2); + readl(SC_RSTCTRL2); /* dummy read */ +#endif + + /* privide clocks */ + tmp = readl(SC_CLKCTRL); +#ifdef CONFIG_USB_XHCI_UNIPHIER + tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | + SC_CLKCTRL_CEN_GIO; +#endif +#ifdef CONFIG_UNIPHIER_ETH + tmp |= SC_CLKCTRL_CEN_ETHER; +#endif +#ifdef CONFIG_NAND_DENALI + tmp |= SC_CLKCTRL_CEN_NAND; +#endif + writel(tmp, SC_CLKCTRL); + readl(SC_CLKCTRL); /* dummy read */ +} diff --git a/arch/arm/mach-uniphier/cmd_pinmon.c b/arch/arm/mach-uniphier/cmd_pinmon.c index 8be2ed4fe6..b15ee9dd60 100644 --- a/arch/arm/mach-uniphier/cmd_pinmon.c +++ b/arch/arm/mach-uniphier/cmd_pinmon.c @@ -1,6 +1,5 @@ /* - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,20 +7,42 @@ #include <common.h> #include <mach/boot-device.h> #include <mach/sbc-regs.h> +#include <mach/soc_info.h> static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int mode_sel, i; - printf("Boot Swap: %s\n\n", boot_is_swapped() ? "ON" : "OFF"); - mode_sel = get_boot_mode_sel(); - - puts("Boot Mode Pin:\n"); - - for (i = 0; boot_device_table[i].info; i++) - printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, - boot_device_table[i].info); + switch (uniphier_get_soc_type()) { +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + case SOC_UNIPHIER_PH1_SLD3: + ph1_sld3_boot_mode_show(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + case SOC_UNIPHIER_PH1_LD4: + case SOC_UNIPHIER_PH1_PRO4: + case SOC_UNIPHIER_PH1_SLD8: + ph1_ld4_boot_mode_show(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + case SOC_UNIPHIER_PH1_PRO5: + ph1_pro5_boot_mode_show(); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + case SOC_UNIPHIER_PROXSTREAM2: + case SOC_UNIPHIER_PH1_LD6B: + proxstream2_boot_mode_show(); + break; +#endif + default: + break; + } return 0; } diff --git a/arch/arm/mach-uniphier/ddrphy/Makefile b/arch/arm/mach-uniphier/ddrphy/Makefile new file mode 100644 index 0000000000..e2d109df57 --- /dev/null +++ b/arch/arm/mach-uniphier/ddrphy/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += ddrphy-training.o ddrphy-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += ddrphy-training.o ddrphy-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += ddrphy-training.o ddrphy-ph1-sld8.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/ddrphy_init.c b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-ld4.c index 2add8fa691..991d9294fd 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/ddrphy_init.c +++ b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-ld4.c @@ -8,7 +8,7 @@ #include <linux/io.h> #include <mach/ddrphy-regs.h> -void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +int ph1_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { u32 tmp; @@ -67,4 +67,6 @@ void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) writel(0x0300C473, &phy->pgcr[1]); writel(0x0000005D, &phy->zq[0].cr[1]); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-pro4/ddrphy_init.c b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-pro4.c index 61ddcf4ec6..bc47ba3280 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/ddrphy_init.c +++ b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-pro4.c @@ -8,7 +8,7 @@ #include <linux/io.h> #include <mach/ddrphy-regs.h> -void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +int ph1_pro4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { u32 tmp; @@ -67,4 +67,6 @@ void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) writel(0x0300C473, &phy->pgcr[1]); writel(0x0000005D, &phy->zq[0].cr[1]); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld8/ddrphy_init.c b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-sld8.c index 21efe62da6..39024a09d5 100644 --- a/arch/arm/mach-uniphier/ph1-sld8/ddrphy_init.c +++ b/arch/arm/mach-uniphier/ddrphy/ddrphy-ph1-sld8.c @@ -9,7 +9,7 @@ #include <linux/io.h> #include <mach/ddrphy-regs.h> -void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +int ph1_sld8_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) { u32 tmp; @@ -72,4 +72,6 @@ void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) writel(0x0300C473, &phy->pgcr[1]); writel(0x0000005D, &phy->zq[0].cr[1]); + + return 0; } diff --git a/arch/arm/mach-uniphier/ddrphy_training.c b/arch/arm/mach-uniphier/ddrphy/ddrphy-training.c index a98b814df0..a98b814df0 100644 --- a/arch/arm/mach-uniphier/ddrphy_training.c +++ b/arch/arm/mach-uniphier/ddrphy/ddrphy-training.c diff --git a/arch/arm/mach-uniphier/debug_ll.S b/arch/arm/mach-uniphier/debug_ll.S new file mode 100644 index 0000000000..d8c9fe43e3 --- /dev/null +++ b/arch/arm/mach-uniphier/debug_ll.S @@ -0,0 +1,185 @@ +/* + * On-chip UART initializaion for low-level debugging + * + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/serial_reg.h> +#include <linux/linkage.h> +#include <mach/bcu-regs.h> +#include <mach/sc-regs.h> +#include <mach/sg-regs.h> + +#if !defined(CONFIG_DEBUG_SEMIHOSTING) +#include CONFIG_DEBUG_LL_INCLUDE +#endif + +#define BAUDRATE 115200 +#define DIV_ROUND(x, d) (((x) + ((d) / 2)) / (d)) + +ENTRY(debug_ll_init) + ldr r0, =SG_REVISION + ldr r1, [r0] + and r1, r1, #SG_REVISION_TYPE_MASK + mov r1, r1, lsr #SG_REVISION_TYPE_SHIFT + +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) +#define PH1_SLD3_UART_CLK 36864000 + cmp r1, #0x25 + bne ph1_sld3_end + + sg_set_pinsel 64, 1, 4, 4, r0, r1 @ TXD0 -> TXD0 + + ldr r0, =BCSCR5 + ldr r1, =0x24440000 + str r1, [r0] + + ldr r0, =SC_CLKCTRL + ldr r1, [r0] + orr r1, r1, #SC_CLKCTRL_CEN_PERI + str r1, [r0] + + ldr r3, =DIV_ROUND(PH1_SLD3_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_sld3_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) +#define PH1_LD4_UART_CLK 36864000 + cmp r1, #0x26 + bne ph1_ld4_end + + ldr r0, =SG_IECTRL + ldr r1, [r0] + orr r1, r1, #1 + str r1, [r0] + + sg_set_pinsel 88, 1, 8, 4, r0, r1 @ HSDOUT6 -> TXD0 + + ldr r3, =DIV_ROUND(PH1_LD4_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_ld4_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) +#define PH1_PRO4_UART_CLK 73728000 + cmp r1, #0x28 + bne ph1_pro4_end + + sg_set_pinsel 128, 0, 4, 8, r0, r1 @ TXD0 -> TXD0 + + ldr r0, =SG_LOADPINCTRL + mov r1, #1 + str r1, [r0] + + ldr r0, =SC_CLKCTRL + ldr r1, [r0] + orr r1, r1, #SC_CLKCTRL_CEN_PERI + str r1, [r0] + + ldr r3, =DIV_ROUND(PH1_PRO4_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_pro4_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) +#define PH1_SLD8_UART_CLK 80000000 + cmp r1, #0x29 + bne ph1_sld8_end + + ldr r0, =SG_IECTRL + ldr r1, [r0] + orr r1, r1, #1 + str r1, [r0] + + sg_set_pinsel 70, 3, 8, 4, r0, r1 @ HSDOUT0 -> TXD0 + + ldr r3, =DIV_ROUND(PH1_SLD8_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_sld8_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) +#define PH1_PRO5_UART_CLK 73728000 + cmp r1, #0x2A + bne ph1_pro5_end + + sg_set_pinsel 47, 0, 4, 8, r0, r1 @ TXD0 -> TXD0 + sg_set_pinsel 49, 0, 4, 8, r0, r1 @ TXD1 -> TXD1 + sg_set_pinsel 51, 0, 4, 8, r0, r1 @ TXD2 -> TXD2 + sg_set_pinsel 53, 0, 4, 8, r0, r1 @ TXD3 -> TXD3 + + ldr r0, =SG_LOADPINCTRL + mov r1, #1 + str r1, [r0] + + ldr r0, =SC_CLKCTRL + ldr r1, [r0] + orr r1, r1, #SC_CLKCTRL_CEN_PERI + str r1, [r0] + + ldr r3, =DIV_ROUND(PH1_PRO5_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_pro5_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) +#define PROXSTREAM2_UART_CLK 88900000 + cmp r1, #0x2E + bne proxstream2_end + + ldr r0, =SG_IECTRL + ldr r1, [r0] + orr r1, r1, #1 + str r1, [r0] + + sg_set_pinsel 217, 8, 8, 4, r0, r1 @ TXD0 -> TXD0 + sg_set_pinsel 115, 8, 8, 4, r0, r1 @ TXD1 -> TXD1 + sg_set_pinsel 113, 8, 8, 4, r0, r1 @ TXD2 -> TXD2 + sg_set_pinsel 219, 8, 8, 4, r0, r1 @ TXD3 -> TXD3 + + ldr r0, =SC_CLKCTRL + ldr r1, [r0] + orr r1, r1, #SC_CLKCTRL_CEN_PERI + str r1, [r0] + + ldr r3, =DIV_ROUND(PROXSTREAM2_UART_CLK, 16 * BAUDRATE) + + b init_uart +proxstream2_end: +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) +#define PH1_LD6B_UART_CLK 88900000 + cmp r1, #0x2F + bne ph1_ld6b_end + + ldr r0, =SG_IECTRL + ldr r1, [r0] + orr r1, r1, #1 + str r1, [r0] + + sg_set_pinsel 135, 3, 8, 4, r0, r1 @ PORT10 -> TXD0 + sg_set_pinsel 115, 0, 8, 4, r0, r1 @ TXD1 -> TXD1 + sg_set_pinsel 113, 2, 8, 4, r0, r1 @ SBO0 -> TXD2 + + ldr r0, =SC_CLKCTRL + ldr r1, [r0] + orr r1, r1, #SC_CLKCTRL_CEN_PERI + str r1, [r0] + + ldr r3, =DIV_ROUND(PH1_LD6B_UART_CLK, 16 * BAUDRATE) + + b init_uart +ph1_ld6b_end: +#endif + +init_uart: + addruart r0, r1, r2 + mov r1, #UART_LCR_WLEN8 << 8 + str r1, [r0, #0x10] + str r3, [r0, #0x24] + + mov pc, lr +ENDPROC(debug_ll_init) diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c index 4b8c938b5e..32cc448aeb 100644 --- a/arch/arm/mach-uniphier/dram_init.c +++ b/arch/arm/mach-uniphier/dram_init.c @@ -1,16 +1,59 @@ /* - * Copyright (C) 2012-2015 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <libfdt.h> +#include <linux/err.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const void *get_memory_reg_prop(const void *fdt, int *lenp) +{ + int offset; + + offset = fdt_path_offset(fdt, "/memory"); + if (offset < 0) + return NULL; + + return fdt_getprop(fdt, offset, "reg", lenp); +} int dram_init(void) { - DECLARE_GLOBAL_DATA_PTR; - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + const fdt32_t *val; + int len; + + val = get_memory_reg_prop(gd->fdt_blob, &len); + if (len < sizeof(*val)) + return -EINVAL; + + gd->ram_size = fdt32_to_cpu(*(val + 1)); + + debug("DRAM size = %08lx\n", gd->ram_size); return 0; } + +void dram_init_banksize(void) +{ + const fdt32_t *val; + int len, i; + + val = get_memory_reg_prop(gd->fdt_blob, &len); + if (len < 0) + return; + + len /= sizeof(*val); + len /= 2; + + for (i = 0; i < len; i++) { + gd->bd->bi_dram[i].start = fdt32_to_cpu(*val++); + gd->bd->bi_dram[i].size = fdt32_to_cpu(*val++); + + debug("DRAM bank %d: start = %08lx, size = %08lx\n", + i, gd->bd->bi_dram[i].start, gd->bd->bi_dram[i].size); + } +} diff --git a/arch/arm/mach-uniphier/early-clk/Makefile b/arch/arm/mach-uniphier/early-clk/Makefile new file mode 100644 index 0000000000..393ea96f90 --- /dev/null +++ b/arch/arm/mach-uniphier/early-clk/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += early-clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += early-clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += early-clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += early-clk-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += early-clk-ph1-pro5.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += early-clk-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += early-clk-proxstream2.o diff --git a/arch/arm/mach-uniphier/ph1-pro4/early_clkrst_init.c b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c index 60204b53ba..f646c9b7df 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/early_clkrst_init.c +++ b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-ld4.c @@ -7,9 +7,10 @@ #include <common.h> #include <spl.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> -void early_clkrst_init(void) +int ph1_ld4_early_clk_init(const struct uniphier_board_data *bd) { u32 tmp; @@ -27,4 +28,6 @@ void early_clkrst_init(void) tmp |= SC_CLKCTRL_CEN_UMC | SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI; writel(tmp, SC_CLKCTRL); readl(SC_CLKCTRL); /* dummy read */ + + return 0; } 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 new file mode 100644 index 0000000000..007d3b8570 --- /dev/null +++ b/arch/arm/mach-uniphier/early-clk/early-clk-ph1-pro5.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sc-regs.h> + +int ph1_pro5_early_clk_init(const struct uniphier_board_data *bd) +{ + u32 tmp; + + /* + * deassert reset + * UMCA2: Ch1 (DDR3) + * UMCA1, UMC31: Ch0 (WIO1) + * UMCA0, UMC30: Ch0 (WIO0) + */ + tmp = readl(SC_RSTCTRL4); + tmp |= SC_RSTCTRL4_NRST_UMCSB | SC_RSTCTRL4_NRST_UMCA2 | + SC_RSTCTRL4_NRST_UMCA1 | SC_RSTCTRL4_NRST_UMCA0 | + SC_RSTCTRL4_NRST_UMC31 | SC_RSTCTRL4_NRST_UMC30; + writel(tmp, SC_RSTCTRL4); + readl(SC_RSTCTRL); /* dummy read */ + + /* privide clocks */ + tmp = readl(SC_CLKCTRL); + tmp |= SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI; + writel(tmp, SC_CLKCTRL); + tmp = readl(SC_CLKCTRL4); + tmp |= SC_CLKCTRL4_CEN_UMCSB | SC_CLKCTRL4_CEN_UMC1 | + SC_CLKCTRL4_CEN_UMC0; + writel(tmp, SC_CLKCTRL4); + readl(SC_CLKCTRL4); /* dummy read */ + + return 0; +} diff --git a/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c b/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c new file mode 100644 index 0000000000..c303f16a57 --- /dev/null +++ b/arch/arm/mach-uniphier/early-clk/early-clk-proxstream2.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sc-regs.h> + +int proxstream2_early_clk_init(const struct uniphier_board_data *bd) +{ + u32 tmp; + + /* deassert reset */ + if (spl_boot_device() != BOOT_DEVICE_NAND) { + tmp = readl(SC_RSTCTRL); + tmp &= ~SC_RSTCTRL_NRST_NAND; + writel(tmp, SC_RSTCTRL); + }; + + tmp = readl(SC_RSTCTRL4); + tmp |= SC_RSTCTRL4_NRST_UMCSB | SC_RSTCTRL4_NRST_UMCA2 | + SC_RSTCTRL4_NRST_UMCA1 | SC_RSTCTRL4_NRST_UMCA0 | + SC_RSTCTRL4_NRST_UMC32 | SC_RSTCTRL4_NRST_UMC31 | + SC_RSTCTRL4_NRST_UMC30; + writel(tmp, SC_RSTCTRL4); + readl(SC_RSTCTRL4); /* dummy read */ + + /* privide clocks */ + tmp = readl(SC_CLKCTRL); + tmp |= SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI; + writel(tmp, SC_CLKCTRL); + + tmp = readl(SC_CLKCTRL4); + tmp |= SC_CLKCTRL4_CEN_UMCSB | SC_CLKCTRL4_CEN_UMC2 | + SC_CLKCTRL4_CEN_UMC1 | SC_CLKCTRL4_CEN_UMC0; + writel(tmp, SC_CLKCTRL4); + readl(SC_CLKCTRL4); /* dummy read */ + + return 0; +} diff --git a/arch/arm/mach-uniphier/early-pinctrl/Makefile b/arch/arm/mach-uniphier/early-pinctrl/Makefile new file mode 100644 index 0000000000..e497d28f79 --- /dev/null +++ b/arch/arm/mach-uniphier/early-pinctrl/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += early-pinctrl-ph1-sld3.o 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 new file mode 100644 index 0000000000..1bb9375016 --- /dev/null +++ b/arch/arm/mach-uniphier/early-pinctrl/early-pinctrl-ph1-sld3.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <mach/init.h> +#include <mach/sg-regs.h> + +int ph1_sld3_early_pin_init(const struct uniphier_board_data *bd) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_UNIPHIER_SERIAL + sg_set_pinsel(63, 0, 4, 4); /* RXD0 */ + sg_set_pinsel(64, 1, 4, 4); /* TXD0 */ + + sg_set_pinsel(65, 0, 4, 4); /* RXD1 */ + sg_set_pinsel(66, 1, 4, 4); /* TXD1 */ + + sg_set_pinsel(96, 2, 4, 4); /* RXD2 */ + sg_set_pinsel(102, 2, 4, 4); /* TXD2 */ +#endif + + return 0; +} diff --git a/arch/arm/mach-uniphier/include/mach/board.h b/arch/arm/mach-uniphier/include/mach/board.h deleted file mode 100644 index e3cba5befe..0000000000 --- a/arch/arm/mach-uniphier/include/mach/board.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef ARCH_BOARD_H -#define ARCH_BOARD_H - -#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) || \ - defined(CONFIG_DCC_MICRO_SUPPORT_CARD) -void support_card_reset(void); -void support_card_init(void); -void support_card_late_init(void); -int check_support_card(void); -#else -#define support_card_reset() do {} while (0) -#define support_card_init() do {} while (0) -#define support_card_late_init() do {} while (0) -static inline int check_support_card(void) -{ - return 0; -} -#endif - -static inline void uniphier_board_reset(void) -{ - support_card_reset(); -} - -static inline void uniphier_board_init(void) -{ - support_card_init(); -} - -static inline void uniphier_board_late_init(void) -{ - support_card_late_init(); -} - -#endif /* ARCH_BOARD_H */ diff --git a/arch/arm/mach-uniphier/include/mach/boot-device.h b/arch/arm/mach-uniphier/include/mach/boot-device.h index 7a10f1c5b2..2ab5a535fa 100644 --- a/arch/arm/mach-uniphier/include/mach/boot-device.h +++ b/arch/arm/mach-uniphier/include/mach/boot-device.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2011-2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,13 +7,19 @@ #ifndef _ASM_BOOT_DEVICE_H_ #define _ASM_BOOT_DEVICE_H_ -int get_boot_mode_sel(void); - struct boot_device_info { u32 type; char *info; }; -extern struct boot_device_info boot_device_table[]; +u32 ph1_sld3_boot_device(void); +u32 ph1_ld4_boot_device(void); +u32 ph1_pro5_boot_device(void); +u32 proxstream2_boot_device(void); + +void ph1_sld3_boot_mode_show(void); +void ph1_ld4_boot_mode_show(void); +void ph1_pro5_boot_mode_show(void); +void proxstream2_boot_mode_show(void); #endif /* _ASM_BOOT_DEVICE_H_ */ diff --git a/arch/arm/mach-uniphier/include/mach/ddrphy-regs.h b/arch/arm/mach-uniphier/include/mach/ddrphy-regs.h index fce0c01246..adcc972877 100644 --- a/arch/arm/mach-uniphier/include/mach/ddrphy-regs.h +++ b/arch/arm/mach-uniphier/include/mach/ddrphy-regs.h @@ -156,7 +156,8 @@ struct ddrphy { /* SoC-specific parameters */ #define NR_DATX8_PER_DDRPHY 2 -#if defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8) +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) #define NR_DDRPHY_PER_CH 1 #else #define NR_DDRPHY_PER_CH 2 @@ -167,7 +168,9 @@ struct ddrphy { #define DDRPHY_BASE(ch, phy) (0x5bc01000 + 0x200000 * (ch) + 0x1000 * (phy)) #ifndef __ASSEMBLY__ -void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size); +int ph1_ld4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size); +int ph1_pro4_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size); +int ph1_sld8_ddrphy_init(struct ddrphy __iomem *phy, int freq, int size); void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank); int ddrphy_training(struct ddrphy __iomem *phy); #endif diff --git a/arch/arm/mach-uniphier/include/mach/debug-uart.S b/arch/arm/mach-uniphier/include/mach/debug-uart.S deleted file mode 100644 index d2b431f544..0000000000 --- a/arch/arm/mach-uniphier/include/mach/debug-uart.S +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/serial_reg.h> - -#if !defined(CONFIG_DEBUG_SEMIHOSTING) -#include CONFIG_DEBUG_LL_INCLUDE -#endif - -#define BAUDRATE 115200 -#define DIV_ROUND(x, d) (((x) + ((d) / 2)) / (d)) -#define DIVISOR DIV_ROUND(UART_CLK, 16 * BAUDRATE) - - .macro init_debug_uart, ra, rb, rc - addruart \ra, \rb, \rc - mov \rb, #UART_LCR_WLEN8 << 8 - str \rb, [\ra, #0x10] - ldr \rb, =DIVISOR - str \rb, [\ra, #0x24] - .endm diff --git a/arch/arm/mach-uniphier/include/mach/init.h b/arch/arm/mach-uniphier/include/mach/init.h new file mode 100644 index 0000000000..5108eddfc4 --- /dev/null +++ b/arch/arm/mach-uniphier/include/mach/init.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MACH_INIT_H +#define __MACH_INIT_H + +struct uniphier_board_data { + unsigned long dram_ch0_base; + unsigned long dram_ch0_size; + unsigned long dram_ch0_width; + unsigned long dram_ch1_base; + unsigned long dram_ch1_size; + unsigned long dram_ch1_width; + unsigned long dram_ch2_base; + unsigned long dram_ch2_size; + unsigned long dram_ch2_width; + unsigned int dram_freq; +}; + +const struct uniphier_board_data *uniphier_get_board_param(const void *fdt); + +int ph1_sld3_init(const struct uniphier_board_data *bd); +int ph1_ld4_init(const struct uniphier_board_data *bd); +int ph1_pro4_init(const struct uniphier_board_data *bd); +int ph1_sld8_init(const struct uniphier_board_data *bd); +int ph1_pro5_init(const struct uniphier_board_data *bd); +int proxstream2_init(const struct uniphier_board_data *bd); + +#if defined(CONFIG_MICRO_SUPPORT_CARD) +int ph1_sld3_sbc_init(const struct uniphier_board_data *bd); +int ph1_ld4_sbc_init(const struct uniphier_board_data *bd); +int ph1_pro4_sbc_init(const struct uniphier_board_data *bd); +int proxstream2_sbc_init(const struct uniphier_board_data *bd); +#else +static inline int ph1_sld3_sbc_init(const struct uniphier_board_data *bd) +{ + return 0; +} + +static inline int ph1_ld4_sbc_init(const struct uniphier_board_data *bd) +{ + return 0; +} + +static inline int ph1_pro4_sbc_init(const struct uniphier_board_data *bd) +{ + return 0; +} + +static inline int proxstream2_sbc_init(const struct uniphier_board_data *bd) +{ + return 0; +} +#endif + +int ph1_sld3_bcu_init(const struct uniphier_board_data *bd); +int ph1_ld4_bcu_init(const struct uniphier_board_data *bd); + +int memconf_init(const struct uniphier_board_data *bd); +int ph1_sld3_memconf_init(const struct uniphier_board_data *bd); +int proxstream2_memconf_init(const struct uniphier_board_data *bd); + +int ph1_sld3_pll_init(const struct uniphier_board_data *bd); +int ph1_ld4_pll_init(const struct uniphier_board_data *bd); +int ph1_pro4_pll_init(const struct uniphier_board_data *bd); +int ph1_sld8_pll_init(const struct uniphier_board_data *bd); + +int ph1_sld3_enable_dpll_ssc(const struct uniphier_board_data *bd); +int ph1_ld4_enable_dpll_ssc(const struct uniphier_board_data *bd); + +int ph1_ld4_early_clk_init(const struct uniphier_board_data *bd); +int ph1_pro5_early_clk_init(const struct uniphier_board_data *bd); +int proxstream2_early_clk_init(const struct uniphier_board_data *bd); + +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); + +void ph1_sld3_pin_init(void); +void ph1_ld4_pin_init(void); +void ph1_pro4_pin_init(void); +void ph1_sld8_pin_init(void); +void ph1_pro5_pin_init(void); +void proxstream2_pin_init(void); +void ph1_ld6b_pin_init(void); + +void ph1_ld4_clk_init(void); +void ph1_pro4_clk_init(void); +void ph1_pro5_clk_init(void); +void proxstream2_clk_init(void); + +#define pr_err(fmt, args...) printf(fmt, ##args) + +#endif /* __MACH_INIT_H */ diff --git a/arch/arm/mach-uniphier/include/mach/led.h b/arch/arm/mach-uniphier/include/mach/led.h deleted file mode 100644 index f7749b4860..0000000000 --- a/arch/arm/mach-uniphier/include/mach/led.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef ARCH_LED_H -#define ARCH_LED_H - -#include <config.h> - -#define LED_CHAR_0 0x7e -#define LED_CHAR_1 0x0c -#define LED_CHAR_2 0xb6 -#define LED_CHAR_3 0x9e -#define LED_CHAR_4 0xcc -#define LED_CHAR_5 0xda -#define LED_CHAR_6 0xfa -#define LED_CHAR_7 0x4e -#define LED_CHAR_8 0xfe -#define LED_CHAR_9 0xde - -#define LED_CHAR_A 0xee -#define LED_CHAR_B 0xf8 -#define LED_CHAR_C 0x72 -#define LED_CHAR_D 0xbc -#define LED_CHAR_E 0xf2 -#define LED_CHAR_F 0xe2 -#define LED_CHAR_G 0x7a -#define LED_CHAR_H 0xe8 -#define LED_CHAR_I 0x08 -#define LED_CHAR_J 0x3c -#define LED_CHAR_K 0xea -#define LED_CHAR_L 0x70 -#define LED_CHAR_M 0x6e -#define LED_CHAR_N 0xa8 -#define LED_CHAR_O 0xb8 -#define LED_CHAR_P 0xe6 -#define LED_CHAR_Q 0xce -#define LED_CHAR_R 0xa0 -#define LED_CHAR_S 0xc8 -#define LED_CHAR_T 0x8c -#define LED_CHAR_U 0x7c -#define LED_CHAR_V 0x54 -#define LED_CHAR_W 0xfc -#define LED_CHAR_X 0xec -#define LED_CHAR_Y 0xdc -#define LED_CHAR_Z 0xa4 - -#define LED_CHAR_SPACE 0x00 -#define LED_CHAR_DOT 0x01 - -#define LED_CHAR_ (LED_CHAR_SPACE) - -/** Macro to translate 4 characters into integer to display led */ -#define LED_C2I(C0, C1, C2, C3) \ - (~( \ - (LED_CHAR_##C0 << 24) | \ - (LED_CHAR_##C1 << 16) | \ - (LED_CHAR_##C2 << 8) | \ - (LED_CHAR_##C3) \ - )) - -#if defined(CONFIG_SUPPORT_CARD_LED_BASE) - -#define LED_ADDR CONFIG_SUPPORT_CARD_LED_BASE - -#ifdef __ASSEMBLY__ - -#define led_write(C0, C1, C2, C3) raw_led_write LED_C2I(C0, C1, C2, C3) -.macro raw_led_write data - ldr r0, =\data - ldr r1, =LED_ADDR - str r0, [r1] -.endm - -#else /* __ASSEMBLY__ */ - -#include <linux/io.h> - -#define led_write(C0, C1, C2, C3) \ -do { \ - raw_led_write(LED_C2I(C0, C1, C2, C3)); \ -} while (0) - -static inline void raw_led_write(u32 data) -{ - writel(data, LED_ADDR); -} - -#endif /* __ASSEMBLY__ */ - -#else /* CONFIG_SUPPORT_CARD_LED_BASE */ - -#define led_write(C0, C1, C2, C3) -#define raw_led_write(x) - -#endif /* CONFIG_SUPPORT_CARD_LED_BASE */ - -#endif /* ARCH_LED_H */ diff --git a/arch/arm/mach-uniphier/include/mach/micro-support-card.h b/arch/arm/mach-uniphier/include/mach/micro-support-card.h new file mode 100644 index 0000000000..5da0ada726 --- /dev/null +++ b/arch/arm/mach-uniphier/include/mach/micro-support-card.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARCH_BOARD_H +#define ARCH_BOARD_H + +#if defined(CONFIG_MICRO_SUPPORT_CARD) +void support_card_reset(void); +void support_card_init(void); +void support_card_late_init(void); +int check_support_card(void); +void led_puts(const char *s); +#else +static inline void support_card_reset(void) +{ +} + +static inline void support_card_init(void) +{ +} + +static inline void support_card_late_init(void) +{ +} + +static inline int check_support_card(void) +{ + return 0; +} + +static inline void led_puts(const char *s) +{ +} +#endif + +#endif /* ARCH_BOARD_H */ diff --git a/arch/arm/mach-uniphier/include/mach/platdevice.h b/arch/arm/mach-uniphier/include/mach/platdevice.h deleted file mode 100644 index cdf7d132d4..0000000000 --- a/arch/arm/mach-uniphier/include/mach/platdevice.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef ARCH_PLATDEVICE_H -#define ARCH_PLATDEVICE_H - -#include <dm/platdata.h> -#include <dm/platform_data/serial-uniphier.h> - -#define SERIAL_DEVICE(n, ba, clk) \ -static struct uniphier_serial_platform_data serial_device##n = { \ - .base = ba, \ - .uartclk = clk \ -}; \ -U_BOOT_DEVICE(serial##n) = { \ - .name = DRIVER_NAME, \ - .platdata = &serial_device##n \ -}; - -#endif /* ARCH_PLATDEVICE_H */ diff --git a/arch/arm/mach-uniphier/include/mach/sc-regs.h b/arch/arm/mach-uniphier/include/mach/sc-regs.h index df50294077..474b82d243 100644 --- a/arch/arm/mach-uniphier/include/mach/sc-regs.h +++ b/arch/arm/mach-uniphier/include/mach/sc-regs.h @@ -9,12 +9,16 @@ #ifndef ARCH_SC_REGS_H #define ARCH_SC_REGS_H -#if defined(CONFIG_MACH_PH1_SLD3) +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) #define SC_BASE_ADDR 0xf1840000 #else #define SC_BASE_ADDR 0x61840000 #endif +#define SC_DPLLOSCCTRL (SC_BASE_ADDR | 0x1110) +#define SC_DPLLOSCCTRL_DPLLST (0x1 << 1) +#define SC_DPLLOSCCTRL_DPLLEN (0x1 << 0) + #define SC_DPLLCTRL (SC_BASE_ADDR | 0x1200) #define SC_DPLLCTRL_SSC_EN (0x1 << 31) #define SC_DPLLCTRL_FOUTMODE_MASK (0xf << 16) @@ -43,6 +47,7 @@ #define SC_RSTCTRL_NRST_ETHER (0x1 << 12) #define SC_RSTCTRL_NRST_STDMAC (0x1 << 10) #define SC_RSTCTRL_NRST_GIO (0x1 << 6) +/* Pro4 or older */ #define SC_RSTCTRL_NRST_UMC1 (0x1 << 5) #define SC_RSTCTRL_NRST_UMC0 (0x1 << 4) #define SC_RSTCTRL_NRST_NAND (0x1 << 2) @@ -53,6 +58,16 @@ #define SC_RSTCTRL3 (SC_BASE_ADDR | 0x2008) +/* Pro5 or newer */ +#define SC_RSTCTRL4 (SC_BASE_ADDR | 0x200c) +#define SC_RSTCTRL4_NRST_UMCSB (0x1 << 12) /* UMC system bus */ +#define SC_RSTCTRL4_NRST_UMCA2 (0x1 << 10) /* UMC ch2 standby */ +#define SC_RSTCTRL4_NRST_UMCA1 (0x1 << 9) /* UMC ch1 standby */ +#define SC_RSTCTRL4_NRST_UMCA0 (0x1 << 8) /* UMC ch0 standby */ +#define SC_RSTCTRL4_NRST_UMC32 (0x1 << 6) /* UMC ch2 */ +#define SC_RSTCTRL4_NRST_UMC31 (0x1 << 5) /* UMC ch1 */ +#define SC_RSTCTRL4_NRST_UMC30 (0x1 << 4) /* UMC ch0 */ + #define SC_CLKCTRL (SC_BASE_ADDR | 0x2104) #define SC_CLKCTRL_CEN_USB31 (0x1 << 17) /* USB3 #1 */ #define SC_CLKCTRL_CEN_USB30 (0x1 << 16) /* USB3 #0 */ @@ -60,11 +75,19 @@ #define SC_CLKCTRL_CEN_MIO (0x1 << 11) #define SC_CLKCTRL_CEN_STDMAC (0x1 << 10) #define SC_CLKCTRL_CEN_GIO (0x1 << 6) +/* Pro4 or older */ #define SC_CLKCTRL_CEN_UMC (0x1 << 4) #define SC_CLKCTRL_CEN_NAND (0x1 << 2) #define SC_CLKCTRL_CEN_SBC (0x1 << 1) #define SC_CLKCTRL_CEN_PERI (0x1 << 0) +/* Pro5 or newer */ +#define SC_CLKCTRL4 (SC_BASE_ADDR | 0x210c) +#define SC_CLKCTRL4_CEN_UMCSB (0x1 << 12) /* UMC system bus */ +#define SC_CLKCTRL4_CEN_UMC2 (0x1 << 2) /* UMC ch2 */ +#define SC_CLKCTRL4_CEN_UMC1 (0x1 << 1) /* UMC ch1 */ +#define SC_CLKCTRL4_CEN_UMC0 (0x1 << 0) /* UMC ch0 */ + /* System reset control register */ #define SC_IRQTIMSET (SC_BASE_ADDR | 0x3000) #define SC_SLFRSTSEL (SC_BASE_ADDR | 0x3010) diff --git a/arch/arm/mach-uniphier/include/mach/sg-regs.h b/arch/arm/mach-uniphier/include/mach/sg-regs.h index 43a6c35339..678d437fc9 100644 --- a/arch/arm/mach-uniphier/include/mach/sg-regs.h +++ b/arch/arm/mach-uniphier/include/mach/sg-regs.h @@ -25,53 +25,43 @@ /* Memory Configuration */ #define SG_MEMCONF (SG_CTRL_BASE | 0x0400) +#define SG_MEMCONF_CH0_SZ_MASK ((0x1 << 10) | (0x03 << 0)) #define SG_MEMCONF_CH0_SZ_64M ((0x0 << 10) | (0x01 << 0)) #define SG_MEMCONF_CH0_SZ_128M ((0x0 << 10) | (0x02 << 0)) #define SG_MEMCONF_CH0_SZ_256M ((0x0 << 10) | (0x03 << 0)) #define SG_MEMCONF_CH0_SZ_512M ((0x1 << 10) | (0x00 << 0)) #define SG_MEMCONF_CH0_SZ_1G ((0x1 << 10) | (0x01 << 0)) +#define SG_MEMCONF_CH0_NUM_MASK (0x1 << 8) #define SG_MEMCONF_CH0_NUM_1 (0x1 << 8) #define SG_MEMCONF_CH0_NUM_2 (0x0 << 8) +#define SG_MEMCONF_CH1_SZ_MASK ((0x1 << 11) | (0x03 << 2)) #define SG_MEMCONF_CH1_SZ_64M ((0x0 << 11) | (0x01 << 2)) #define SG_MEMCONF_CH1_SZ_128M ((0x0 << 11) | (0x02 << 2)) #define SG_MEMCONF_CH1_SZ_256M ((0x0 << 11) | (0x03 << 2)) #define SG_MEMCONF_CH1_SZ_512M ((0x1 << 11) | (0x00 << 2)) #define SG_MEMCONF_CH1_SZ_1G ((0x1 << 11) | (0x01 << 2)) +#define SG_MEMCONF_CH1_NUM_MASK (0x1 << 9) #define SG_MEMCONF_CH1_NUM_1 (0x1 << 9) #define SG_MEMCONF_CH1_NUM_2 (0x0 << 9) +#define SG_MEMCONF_CH2_SZ_MASK ((0x1 << 26) | (0x03 << 16)) #define SG_MEMCONF_CH2_SZ_64M ((0x0 << 26) | (0x01 << 16)) #define SG_MEMCONF_CH2_SZ_128M ((0x0 << 26) | (0x02 << 16)) #define SG_MEMCONF_CH2_SZ_256M ((0x0 << 26) | (0x03 << 16)) #define SG_MEMCONF_CH2_SZ_512M ((0x1 << 26) | (0x00 << 16)) +#define SG_MEMCONF_CH2_NUM_MASK (0x1 << 24) #define SG_MEMCONF_CH2_NUM_1 (0x1 << 24) #define SG_MEMCONF_CH2_NUM_2 (0x0 << 24) +/* PH1-LD6b, ProXstream2 only */ +#define SG_MEMCONF_CH2_DISABLE (0x1 << 21) #define SG_MEMCONF_SPARSEMEM (0x1 << 4) /* Pin Control */ #define SG_PINCTRL_BASE (SG_CTRL_BASE | 0x1000) -#if defined(CONFIG_MACH_PH1_PRO4) -# define SG_PINCTRL(n) (SG_PINCTRL_BASE + (n) * 8) -#elif defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_LD4) || \ - defined(CONFIG_MACH_PH1_SLD8) -# define SG_PINCTRL(n) (SG_PINCTRL_BASE + (n) * 4) -#endif - -#if defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_PRO4) -#define SG_PINSELBITS 4 -#elif defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8) -#define SG_PINSELBITS 8 -#endif - -#define SG_PINSEL_ADDR(n) (SG_PINCTRL((n) * (SG_PINSELBITS) / 32)) -#define SG_PINSEL_MASK(n) (~(((1 << (SG_PINSELBITS)) - 1) << \ - ((n) * (SG_PINSELBITS) % 32))) -#define SG_PINSEL_MODE(n, mode) ((mode) << ((n) * (SG_PINSELBITS) % 32)) - -/* Only for PH1-Pro4 */ +/* PH1-Pro4, PH1-Pro5 */ #define SG_LOADPINCTRL (SG_CTRL_BASE | 0x1700) /* Input Enable */ @@ -98,11 +88,11 @@ #ifdef __ASSEMBLY__ - .macro set_pinsel, n, value, ra, rd - ldr \ra, =SG_PINSEL_ADDR(\n) + .macro sg_set_pinsel, pin, muxval, mux_bits, reg_stride, ra, rd + ldr \ra, =(SG_PINCTRL_BASE + \pin * \mux_bits / 32 * \reg_stride) ldr \rd, [\ra] - and \rd, \rd, #SG_PINSEL_MASK(\n) - orr \rd, \rd, #SG_PINSEL_MODE(\n, \value) + and \rd, \rd, #~(((1 << \mux_bits) - 1) << (\pin * \mux_bits % 32)) + orr \rd, \rd, #(\muxval << (\pin * \mux_bits % 32)) str \rd, [\ra] .endm @@ -111,10 +101,18 @@ #include <linux/types.h> #include <linux/io.h> -static inline void sg_set_pinsel(int n, int value) +static inline void sg_set_pinsel(unsigned pin, unsigned muxval, + unsigned mux_bits, unsigned reg_stride) { - writel((readl(SG_PINSEL_ADDR(n)) & SG_PINSEL_MASK(n)) - | SG_PINSEL_MODE(n, value), SG_PINSEL_ADDR(n)); + unsigned shift = pin * mux_bits % 32; + unsigned reg = SG_PINCTRL_BASE + pin * mux_bits / 32 * reg_stride; + u32 mask = (1U << mux_bits) - 1; + u32 tmp; + + tmp = readl(reg); + tmp &= ~(mask << shift); + tmp |= (mask & muxval) << shift; + writel(tmp, reg); } #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/mach-uniphier/include/mach/soc_info.h b/arch/arm/mach-uniphier/include/mach/soc_info.h new file mode 100644 index 0000000000..623e7ef20e --- /dev/null +++ b/arch/arm/mach-uniphier/include/mach/soc_info.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MACH_SOC_INFO_H__ +#define __MACH_SOC_INFO_H__ + +enum uniphier_soc_id { + SOC_UNIPHIER_PH1_SLD3, + SOC_UNIPHIER_PH1_LD4, + SOC_UNIPHIER_PH1_PRO4, + SOC_UNIPHIER_PH1_SLD8, + SOC_UNIPHIER_PH1_PRO5, + SOC_UNIPHIER_PROXSTREAM2, + SOC_UNIPHIER_PH1_LD6B, + SOC_UNIPHIER_UNKNOWN, +}; + +#define UNIPHIER_NR_ENABLED_SOCS \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_LD4) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_PRO4) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) + \ + IS_ENABLED(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + +#define UNIPHIER_MULTI_SOC ((UNIPHIER_NR_ENABLED_SOCS) > 1) + +#if UNIPHIER_MULTI_SOC +enum uniphier_soc_id uniphier_get_soc_type(void); +#else +static inline enum uniphier_soc_id uniphier_get_soc_type(void) +{ +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + return SOC_UNIPHIER_PH1_SLD3; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) + return SOC_UNIPHIER_PH1_LD4; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) + return SOC_UNIPHIER_PH1_PRO4; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + return SOC_UNIPHIER_PH1_SLD8; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + return SOC_UNIPHIER_PH1_PRO5; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) + return SOC_UNIPHIER_PROXSTREAM2; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + return SOC_UNIPHIER_PH1_LD6B; +#endif + + return SOC_UNIPHIER_UNKNOWN; +} +#endif + +#endif /* __MACH_SOC_INFO_H__ */ diff --git a/arch/arm/mach-uniphier/init/Makefile b/arch/arm/mach-uniphier/init/Makefile new file mode 100644 index 0000000000..98833b55de --- /dev/null +++ b/arch/arm/mach-uniphier/init/Makefile @@ -0,0 +1,9 @@ +obj-y += init.o + +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += init-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += init-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += init-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += init-ph1-sld8.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += init-ph1-pro5.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += init-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += init-proxstream2.o diff --git a/arch/arm/mach-uniphier/init/init-ph1-ld4.c b/arch/arm/mach-uniphier/init/init-ph1-ld4.c new file mode 100644 index 0000000000..8d0ef0389e --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-ph1-ld4.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int ph1_ld4_init(const struct uniphier_board_data *bd) +{ + ph1_ld4_bcu_init(bd); + + ph1_ld4_sbc_init(bd); + + support_card_reset(); + + ph1_ld4_pll_init(bd); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + + led_puts("L1"); + + ph1_ld4_early_clk_init(bd); + + led_puts("L2"); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + { + int res; + + res = ph1_ld4_umc_init(bd); + if (res < 0) { + while (1) + ; + } + } + + led_puts("L5"); + + ph1_ld4_enable_dpll_ssc(bd); + + led_puts("L6"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init-ph1-pro4.c b/arch/arm/mach-uniphier/init/init-ph1-pro4.c new file mode 100644 index 0000000000..b9ce08d88f --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-ph1-pro4.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int ph1_pro4_init(const struct uniphier_board_data *bd) +{ + ph1_pro4_sbc_init(bd); + + support_card_reset(); + + ph1_pro4_pll_init(bd); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + + led_puts("L1"); + + ph1_ld4_early_clk_init(bd); + + led_puts("L2"); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + { + int res; + + res = ph1_pro4_umc_init(bd); + if (res < 0) { + while (1) + ; + } + } + + led_puts("L5"); + + ph1_ld4_enable_dpll_ssc(bd); + + led_puts("L6"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init-ph1-pro5.c b/arch/arm/mach-uniphier/init/init-ph1-pro5.c new file mode 100644 index 0000000000..92b3f21d93 --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-ph1-pro5.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int ph1_pro5_init(const struct uniphier_board_data *bd) +{ + ph1_pro4_sbc_init(bd); + + support_card_reset(); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + + led_puts("L1"); + + ph1_pro5_early_clk_init(bd); + + led_puts("L2"); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + led_puts("L5"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init-ph1-sld3.c b/arch/arm/mach-uniphier/init/init-ph1-sld3.c new file mode 100644 index 0000000000..1146fdab97 --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-ph1-sld3.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int ph1_sld3_init(const struct uniphier_board_data *bd) +{ + ph1_sld3_bcu_init(bd); + + ph1_sld3_sbc_init(bd); + + support_card_reset(); + + ph1_sld3_pll_init(bd); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + ph1_sld3_memconf_init(bd); + + led_puts("L1"); + + ph1_ld4_early_clk_init(bd); + + led_puts("L2"); + + ph1_sld3_early_pin_init(bd); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + led_puts("L5"); + + ph1_sld3_enable_dpll_ssc(bd); + + led_puts("L6"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init-ph1-sld8.c b/arch/arm/mach-uniphier/init/init-ph1-sld8.c new file mode 100644 index 0000000000..741e88c212 --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-ph1-sld8.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int ph1_sld8_init(const struct uniphier_board_data *bd) +{ + ph1_ld4_bcu_init(bd); + + ph1_ld4_sbc_init(bd); + + support_card_reset(); + + ph1_sld8_pll_init(bd); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + + led_puts("L1"); + + ph1_ld4_early_clk_init(bd); + + led_puts("L2"); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + { + int res; + + res = ph1_sld8_umc_init(bd); + if (res < 0) { + while (1) + ; + } + } + + led_puts("L5"); + + ph1_ld4_enable_dpll_ssc(bd); + + led_puts("L6"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init-proxstream2.c b/arch/arm/mach-uniphier/init/init-proxstream2.c new file mode 100644 index 0000000000..8d03b8f86a --- /dev/null +++ b/arch/arm/mach-uniphier/init/init-proxstream2.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <linux/compiler.h> +#include <mach/init.h> +#include <mach/micro-support-card.h> + +int proxstream2_init(const struct uniphier_board_data *bd) +{ + proxstream2_sbc_init(bd); + + support_card_reset(); + + support_card_init(); + + led_puts("L0"); + + memconf_init(bd); + proxstream2_memconf_init(bd); + + led_puts("L1"); + + proxstream2_early_clk_init(bd); + + led_puts("L2"); + + led_puts("L3"); + +#ifdef CONFIG_SPL_SERIAL_SUPPORT + preloader_console_init(); +#endif + + led_puts("L4"); + + return 0; +} diff --git a/arch/arm/mach-uniphier/init/init.c b/arch/arm/mach-uniphier/init/init.c new file mode 100644 index 0000000000..bbfc8e5e08 --- /dev/null +++ b/arch/arm/mach-uniphier/init/init.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <mach/init.h> +#include <mach/soc_info.h> + +DECLARE_GLOBAL_DATA_PTR; + +void spl_board_init(void) +{ + const struct uniphier_board_data *param; + + param = uniphier_get_board_param(gd->fdt_blob); + if (!param) + hang(); + + switch (uniphier_get_soc_type()) { +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) + case SOC_UNIPHIER_PH1_SLD3: + ph1_sld3_init(param); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) + case SOC_UNIPHIER_PH1_LD4: + ph1_ld4_init(param); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO4) + case SOC_UNIPHIER_PH1_PRO4: + ph1_pro4_init(param); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) + case SOC_UNIPHIER_PH1_SLD8: + ph1_sld8_init(param); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PH1_PRO5) + case SOC_UNIPHIER_PH1_PRO5: + ph1_pro5_init(param); + break; +#endif +#if defined(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_LD6B) + case SOC_UNIPHIER_PROXSTREAM2: + case SOC_UNIPHIER_PH1_LD6B: + proxstream2_init(param); + break; +#endif + default: + break; + } +} diff --git a/arch/arm/mach-uniphier/init_page_table.S b/arch/arm/mach-uniphier/init_page_table.S index ac2959a17d..2d3ad15c6e 100644 --- a/arch/arm/mach-uniphier/init_page_table.S +++ b/arch/arm/mach-uniphier/init_page_table.S @@ -1,7 +1,5 @@ /* - * Copyright (C) 2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -23,7 +21,7 @@ ENTRY(init_page_table) section = 0 .rept NR_SECTIONS - .if section == TEXT_SECTION || section == STACK_SECTION + .if section == 0 || section == 1 || section == STACK_SECTION attr = NORMAL .else attr = DEVICE diff --git a/arch/arm/mach-uniphier/lowlevel_init.S b/arch/arm/mach-uniphier/lowlevel_init.S index fd34a4a321..66cad42dde 100644 --- a/arch/arm/mach-uniphier/lowlevel_init.S +++ b/arch/arm/mach-uniphier/lowlevel_init.S @@ -8,7 +8,6 @@ #include <linux/linkage.h> #include <linux/sizes.h> #include <asm/system.h> -#include <mach/led.h> #include <mach/arm-mpcore.h> #include <mach/sbc-regs.h> #include <mach/ssc-regs.h> @@ -28,7 +27,7 @@ ENTRY(lowlevel_init) mcr p15, 0, r0, c1, c0, 0 #ifdef CONFIG_DEBUG_LL - bl setup_lowlevel_debug + bl debug_ll_init #endif /* diff --git a/arch/arm/mach-uniphier/memconf.c b/arch/arm/mach-uniphier/memconf.c deleted file mode 100644 index 59ed0b5dd8..0000000000 --- a/arch/arm/mach-uniphier/memconf.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/sizes.h> -#include <linux/io.h> -#include <mach/sg-regs.h> - -static inline u32 sg_memconf_val_ch0(unsigned long size, int num) -{ - int size_mb = size / num; - u32 ret; - - switch (size_mb) { - case SZ_64M: - ret = SG_MEMCONF_CH0_SZ_64M; - break; - case SZ_128M: - ret = SG_MEMCONF_CH0_SZ_128M; - break; - case SZ_256M: - ret = SG_MEMCONF_CH0_SZ_256M; - break; - case SZ_512M: - ret = SG_MEMCONF_CH0_SZ_512M; - break; - case SZ_1G: - ret = SG_MEMCONF_CH0_SZ_1G; - break; - default: - BUG(); - break; - } - - switch (num) { - case 1: - ret |= SG_MEMCONF_CH0_NUM_1; - break; - case 2: - ret |= SG_MEMCONF_CH0_NUM_2; - break; - default: - BUG(); - break; - } - return ret; -} - -static inline u32 sg_memconf_val_ch1(unsigned long size, int num) -{ - int size_mb = size / num; - u32 ret; - - switch (size_mb) { - case SZ_64M: - ret = SG_MEMCONF_CH1_SZ_64M; - break; - case SZ_128M: - ret = SG_MEMCONF_CH1_SZ_128M; - break; - case SZ_256M: - ret = SG_MEMCONF_CH1_SZ_256M; - break; - case SZ_512M: - ret = SG_MEMCONF_CH1_SZ_512M; - break; - case SZ_1G: - ret = SG_MEMCONF_CH1_SZ_1G; - break; - default: - BUG(); - break; - } - - switch (num) { - case 1: - ret |= SG_MEMCONF_CH1_NUM_1; - break; - case 2: - ret |= SG_MEMCONF_CH1_NUM_2; - break; - default: - BUG(); - break; - } - return ret; -} - -void memconf_init(void) -{ - u32 tmp; - - /* Set DDR size */ - tmp = sg_memconf_val_ch0(CONFIG_SDRAM0_SIZE, CONFIG_DDR_NUM_CH0); - tmp |= sg_memconf_val_ch1(CONFIG_SDRAM1_SIZE, CONFIG_DDR_NUM_CH1); -#if CONFIG_SDRAM0_BASE + CONFIG_SDRAM0_SIZE < CONFIG_SDRAM1_BASE - tmp |= SG_MEMCONF_SPARSEMEM; -#endif - writel(tmp, SG_MEMCONF); -} diff --git a/arch/arm/mach-uniphier/memconf/Makefile b/arch/arm/mach-uniphier/memconf/Makefile new file mode 100644 index 0000000000..42057a2077 --- /dev/null +++ b/arch/arm/mach-uniphier/memconf/Makefile @@ -0,0 +1,4 @@ +obj-y += memconf.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += memconf-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += memconf-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += memconf-proxstream2.o diff --git a/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c b/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c new file mode 100644 index 0000000000..e13f56d1dc --- /dev/null +++ b/arch/arm/mach-uniphier/memconf/memconf-ph1-sld3.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +int ph1_sld3_memconf_init(const struct uniphier_board_data *bd) +{ + u32 tmp; + unsigned long size_per_word; + + tmp = readl(SG_MEMCONF); + + tmp &= ~(SG_MEMCONF_CH2_SZ_MASK | SG_MEMCONF_CH2_NUM_MASK); + + switch (bd->dram_ch2_width) { + case 16: + tmp |= SG_MEMCONF_CH2_NUM_1; + size_per_word = bd->dram_ch2_size; + break; + case 32: + tmp |= SG_MEMCONF_CH2_NUM_2; + size_per_word = bd->dram_ch2_size >> 1; + break; + default: + pr_err("error: unsupported DRAM Ch2 width\n"); + return -EINVAL; + } + + /* Set DDR size */ + switch (size_per_word) { + case SZ_64M: + tmp |= SG_MEMCONF_CH2_SZ_64M; + break; + case SZ_128M: + tmp |= SG_MEMCONF_CH2_SZ_128M; + break; + case SZ_256M: + tmp |= SG_MEMCONF_CH2_SZ_256M; + break; + case SZ_512M: + tmp |= SG_MEMCONF_CH2_SZ_512M; + break; + default: + pr_err("error: unsupported DRAM Ch2 size\n"); + return -EINVAL; + } + + writel(tmp, SG_MEMCONF); + + return 0; +} diff --git a/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c b/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c new file mode 100644 index 0000000000..d7bf0d4e5f --- /dev/null +++ b/arch/arm/mach-uniphier/memconf/memconf-proxstream2.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +int proxstream2_memconf_init(const struct uniphier_board_data *bd) +{ + u32 tmp; + unsigned long size_per_word; + + tmp = readl(SG_MEMCONF); + + tmp &= ~(SG_MEMCONF_CH2_SZ_MASK | SG_MEMCONF_CH2_NUM_MASK); + + switch (bd->dram_ch2_width) { + case 16: + tmp |= SG_MEMCONF_CH2_NUM_1; + size_per_word = bd->dram_ch2_size; + break; + case 32: + tmp |= SG_MEMCONF_CH2_NUM_2; + size_per_word = bd->dram_ch2_size >> 1; + break; + default: + pr_err("error: unsupported DRAM Ch2 width\n"); + return -EINVAL; + } + + /* Set DDR size */ + switch (size_per_word) { + case SZ_64M: + tmp |= SG_MEMCONF_CH2_SZ_64M; + break; + case SZ_128M: + tmp |= SG_MEMCONF_CH2_SZ_128M; + break; + case SZ_256M: + tmp |= SG_MEMCONF_CH2_SZ_256M; + break; + case SZ_512M: + tmp |= SG_MEMCONF_CH2_SZ_512M; + break; + default: + pr_err("error: unsupported DRAM Ch2 size\n"); + return -EINVAL; + } + + if (size_per_word) + tmp &= ~SG_MEMCONF_CH2_DISABLE; + else + tmp |= SG_MEMCONF_CH2_DISABLE; + + writel(tmp, SG_MEMCONF); + + return 0; +} diff --git a/arch/arm/mach-uniphier/memconf/memconf.c b/arch/arm/mach-uniphier/memconf/memconf.c new file mode 100644 index 0000000000..d490736fa4 --- /dev/null +++ b/arch/arm/mach-uniphier/memconf/memconf.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +int memconf_init(const struct uniphier_board_data *bd) +{ + u32 tmp = 0; + unsigned long size_per_word; + + tmp = readl(SG_MEMCONF); + + tmp &= ~(SG_MEMCONF_CH0_SZ_MASK | SG_MEMCONF_CH0_NUM_MASK); + + switch (bd->dram_ch0_width) { + case 16: + tmp |= SG_MEMCONF_CH0_NUM_1; + size_per_word = bd->dram_ch0_size; + break; + case 32: + tmp |= SG_MEMCONF_CH0_NUM_2; + size_per_word = bd->dram_ch0_size >> 1; + break; + default: + pr_err("error: unsupported DRAM Ch0 width\n"); + return -EINVAL; + } + + /* Set DDR size */ + switch (size_per_word) { + case SZ_64M: + tmp |= SG_MEMCONF_CH0_SZ_64M; + break; + case SZ_128M: + tmp |= SG_MEMCONF_CH0_SZ_128M; + break; + case SZ_256M: + tmp |= SG_MEMCONF_CH0_SZ_256M; + break; + case SZ_512M: + tmp |= SG_MEMCONF_CH0_SZ_512M; + break; + case SZ_1G: + tmp |= SG_MEMCONF_CH0_SZ_1G; + break; + default: + pr_err("error: unsupported DRAM Ch0 size\n"); + return -EINVAL; + } + + tmp &= ~(SG_MEMCONF_CH1_SZ_MASK | SG_MEMCONF_CH1_NUM_MASK); + + switch (bd->dram_ch1_width) { + case 16: + tmp |= SG_MEMCONF_CH1_NUM_1; + size_per_word = bd->dram_ch1_size; + break; + case 32: + tmp |= SG_MEMCONF_CH1_NUM_2; + size_per_word = bd->dram_ch1_size >> 1; + break; + default: + pr_err("error: unsupported DRAM Ch1 width\n"); + return -EINVAL; + } + + switch (size_per_word) { + case SZ_64M: + tmp |= SG_MEMCONF_CH1_SZ_64M; + break; + case SZ_128M: + tmp |= SG_MEMCONF_CH1_SZ_128M; + break; + case SZ_256M: + tmp |= SG_MEMCONF_CH1_SZ_256M; + break; + case SZ_512M: + tmp |= SG_MEMCONF_CH1_SZ_512M; + break; + case SZ_1G: + tmp |= SG_MEMCONF_CH1_SZ_1G; + break; + default: + pr_err("error: unsupported DRAM Ch1 size\n"); + return -EINVAL; + } + + if (bd->dram_ch0_base + bd->dram_ch0_size < bd->dram_ch1_base) + tmp |= SG_MEMCONF_SPARSEMEM; + else + tmp &= ~SG_MEMCONF_SPARSEMEM; + + writel(tmp, SG_MEMCONF); + + return 0; +} diff --git a/arch/arm/mach-uniphier/support_card.c b/arch/arm/mach-uniphier/micro-support-card.c index ea85b20e97..4c34748c25 100644 --- a/arch/arm/mach-uniphier/support_card.c +++ b/arch/arm/mach-uniphier/micro-support-card.c @@ -5,15 +5,17 @@ */ #include <common.h> +#include <linux/ctype.h> #include <linux/io.h> -#include <mach/board.h> +#include <mach/micro-support-card.h> -#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) +#define MICRO_SUPPORT_CARD_BASE 0x43f00000 +#define SMC911X_BASE ((MICRO_SUPPORT_CARD_BASE) + 0x00000) +#define LED_BASE ((MICRO_SUPPORT_CARD_BASE) + 0x90000) +#define NS16550A_BASE ((MICRO_SUPPORT_CARD_BASE) + 0xb0000) +#define MICRO_SUPPORT_CARD_RESET ((MICRO_SUPPORT_CARD_BASE) + 0xd0034) +#define MICRO_SUPPORT_CARD_REVISION ((MICRO_SUPPORT_CARD_BASE) + 0xd00E0) -#define PFC_MICRO_SUPPORT_CARD_RESET \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x000D0034) -#define PFC_MICRO_SUPPORT_CARD_REVISION \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x000D00E0) /* * 0: reset deassert, 1: reset * @@ -22,65 +24,22 @@ */ void support_card_reset_deassert(void) { - writel(0, PFC_MICRO_SUPPORT_CARD_RESET); + writel(0, MICRO_SUPPORT_CARD_RESET); } void support_card_reset(void) { - writel(3, PFC_MICRO_SUPPORT_CARD_RESET); + writel(3, MICRO_SUPPORT_CARD_RESET); } static int support_card_show_revision(void) { u32 revision; - revision = readl(PFC_MICRO_SUPPORT_CARD_REVISION); - printf("(PFC CPLD version %d.%d)\n", revision >> 4, revision & 0xf); + revision = readl(MICRO_SUPPORT_CARD_REVISION); + printf("(CPLD version %d.%d)\n", revision >> 4, revision & 0xf); return 0; } -#endif - -#if defined(CONFIG_DCC_MICRO_SUPPORT_CARD) - -#define DCC_MICRO_SUPPORT_CARD_RESET_LAN \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x00401300) -#define DCC_MICRO_SUPPORT_CARD_RESET_UART \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x00401304) -#define DCC_MICRO_SUPPORT_CARD_RESET_I2C \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x00401308) -#define DCC_MICRO_SUPPORT_CARD_REVISION \ - ((CONFIG_SUPPORT_CARD_BASE) + 0x005000E0) - -void support_card_reset_deassert(void) -{ - writel(1, DCC_MICRO_SUPPORT_CARD_RESET_LAN); /* LAN and LED */ - writel(1, DCC_MICRO_SUPPORT_CARD_RESET_UART); /* UART */ - writel(1, DCC_MICRO_SUPPORT_CARD_RESET_I2C); /* I2C */ -} - -void support_card_reset(void) -{ - writel(0, DCC_MICRO_SUPPORT_CARD_RESET_LAN); /* LAN and LED */ - writel(0, DCC_MICRO_SUPPORT_CARD_RESET_UART); /* UART */ - writel(0, DCC_MICRO_SUPPORT_CARD_RESET_I2C); /* I2C */ -} - -static int support_card_show_revision(void) -{ - u32 revision; - - revision = readl(DCC_MICRO_SUPPORT_CARD_REVISION); - - if (revision >= 0x67) { - printf("(DCC CPLD version 3.%d.%d)\n", - revision >> 4, revision & 0xf); - return 0; - } else { - printf("(DCC CPLD unknown version)\n"); - return -1; - } -} -#endif int check_support_card(void) { @@ -104,7 +63,7 @@ void support_card_init(void) int board_eth_init(bd_t *bis) { - return smc911x_initialize(0, CONFIG_SMC911X_BASE); + return smc911x_initialize(0, SMC911X_BASE); } #endif @@ -146,27 +105,10 @@ static int mem_is_flash(const struct memory_bank *mem) return ret; } -#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) - /* {address, size} */ -static const struct memory_bank memory_banks_boot_swap_off[] = { - {0x02000000, 0x01f00000}, -}; - -static const struct memory_bank memory_banks_boot_swap_on[] = { - {0x00000000, 0x01f00000}, -}; -#endif - -#if defined(CONFIG_DCC_MICRO_SUPPORT_CARD) -static const struct memory_bank memory_banks_boot_swap_off[] = { - {0x04000000, 0x02000000}, -}; - -static const struct memory_bank memory_banks_boot_swap_on[] = { - {0x00000000, 0x02000000}, - {0x04000000, 0x02000000}, +/* {address, size} */ +static const struct memory_bank memory_banks[] = { + {0x42000000, 0x01f00000}, }; -#endif static const struct memory_bank *flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; @@ -187,13 +129,8 @@ static void detect_num_flash_banks(void) cfi_flash_num_flash_banks = 0; - if (boot_is_swapped()) { - memory_bank = memory_banks_boot_swap_on; - end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_on); - } else { - memory_bank = memory_banks_boot_swap_off; - end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_off); - } + memory_bank = memory_banks; + end = memory_bank + ARRAY_SIZE(memory_banks); for (; memory_bank < end; memory_bank++) { if (cfi_flash_num_flash_banks >= @@ -222,3 +159,73 @@ void support_card_late_init(void) { detect_num_flash_banks(); } + +static const u8 ledval_num[] = { + 0x7e, /* 0 */ + 0x0c, /* 1 */ + 0xb6, /* 2 */ + 0x9e, /* 3 */ + 0xcc, /* 4 */ + 0xda, /* 5 */ + 0xfa, /* 6 */ + 0x4e, /* 7 */ + 0xfe, /* 8 */ + 0xde, /* 9 */ +}; + +static const u8 ledval_alpha[] = { + 0xee, /* A */ + 0xf8, /* B */ + 0x72, /* C */ + 0xbc, /* D */ + 0xf2, /* E */ + 0xe2, /* F */ + 0x7a, /* G */ + 0xe8, /* H */ + 0x08, /* I */ + 0x3c, /* J */ + 0xea, /* K */ + 0x70, /* L */ + 0x6e, /* M */ + 0xa8, /* N */ + 0xb8, /* O */ + 0xe6, /* P */ + 0xce, /* Q */ + 0xa0, /* R */ + 0xc8, /* S */ + 0x8c, /* T */ + 0x7c, /* U */ + 0x54, /* V */ + 0xfc, /* W */ + 0xec, /* X */ + 0xdc, /* Y */ + 0xa4, /* Z */ +}; + +static u8 char2ledval(char c) +{ + if (isdigit(c)) + return ledval_num[c - '0']; + else if (isalpha(c)) + return ledval_alpha[toupper(c) - 'A']; + + return 0; +} + +void led_puts(const char *s) +{ + int i; + u32 val = 0; + + if (!s) + return; + + for (i = 0; i < 4; i++) { + val <<= 8; + val |= char2ledval(*s); + if (*s != '\0') + s++; + } + + writel(~val, LED_BASE); +} diff --git a/arch/arm/mach-uniphier/ph1-ld4/Makefile b/arch/arm/mach-uniphier/ph1-ld4/Makefile deleted file mode 100644 index 1410b12cb6..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# SPDX-License-Identifier: GPL-2.0+ -# - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-y += bcu_init.o sg_init.o pll_init.o early_clkrst_init.o \ - early_pinctrl.o pll_spectrum.o umc_init.o ddrphy_init.o -obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += sbc_init.o -obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += sbc_init_3cs.o -else -obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o clkrst_init.o -endif - -obj-y += boot-mode.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/boot-mode.c b/arch/arm/mach-uniphier/ph1-ld4/boot-mode.c deleted file mode 100644 index d359b56291..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/boot-mode.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/boot-mode.c" diff --git a/arch/arm/mach-uniphier/ph1-ld4/early_clkrst_init.c b/arch/arm/mach-uniphier/ph1-ld4/early_clkrst_init.c deleted file mode 100644 index d7ef16b10a..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/early_clkrst_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/early_clkrst_init.c" diff --git a/arch/arm/mach-uniphier/ph1-ld4/early_pinctrl.c b/arch/arm/mach-uniphier/ph1-ld4/early_pinctrl.c deleted file mode 100644 index e5e86bb363..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/early_pinctrl.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2011-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <mach/sg-regs.h> - -void early_pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_UNIPHIER_SERIAL - sg_set_pinsel(85, 1); /* HSDOUT3 -> RXD0 */ - sg_set_pinsel(88, 1); /* HDDOUT6 -> TXD0 */ - - sg_set_pinsel(69, 23); /* PCIOWR -> TXD1 */ - sg_set_pinsel(70, 23); /* PCIORD -> RXD1 */ - - sg_set_pinsel(128, 13); /* XIRQ6 -> TXD2 */ - sg_set_pinsel(129, 13); /* XIRQ7 -> RXD2 */ - - sg_set_pinsel(110, 1); /* SBO0 -> TXD3 */ - sg_set_pinsel(111, 1); /* SBI0 -> RXD3 */ -#endif -} diff --git a/arch/arm/mach-uniphier/ph1-ld4/lowlevel_debug.S b/arch/arm/mach-uniphier/ph1-ld4/lowlevel_debug.S deleted file mode 100644 index 7928c5c87c..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/lowlevel_debug.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * On-chip UART initializaion for low-level debugging - * - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/linkage.h> -#include <mach/sg-regs.h> - -#define UART_CLK 36864000 -#include <mach/debug-uart.S> - -ENTRY(setup_lowlevel_debug) - init_debug_uart r0, r1, r2 - - /* UART Port 0 */ - set_pinsel 85, 1, r0, r1 - set_pinsel 88, 1, r0, r1 - - ldr r0, =SG_IECTRL - ldr r1, [r0] - orr r1, r1, #1 - str r1, [r0] - - mov pc, lr -ENDPROC(setup_lowlevel_debug) diff --git a/arch/arm/mach-uniphier/ph1-ld4/pinctrl.c b/arch/arm/mach-uniphier/ph1-ld4/pinctrl.c deleted file mode 100644 index 20cc7b30c4..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/pinctrl.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void pin_init(void) -{ - u32 tmp; - - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_NAND_DENALI - sg_set_pinsel(158, 0); /* XNFRE -> XNFRE_GB */ - sg_set_pinsel(159, 0); /* XNFWE -> XNFWE_GB */ - sg_set_pinsel(160, 0); /* XFALE -> NFALE_GB */ - sg_set_pinsel(161, 0); /* XFCLE -> NFCLE_GB */ - sg_set_pinsel(162, 0); /* XNFWP -> XFNWP_GB */ - sg_set_pinsel(163, 0); /* XNFCE0 -> XNFCE0_GB */ - sg_set_pinsel(164, 0); /* NANDRYBY0 -> NANDRYBY0_GB */ - sg_set_pinsel(22, 0); /* MMCCLK -> XFNCE1_GB */ - sg_set_pinsel(23, 0); /* MMCCMD -> NANDRYBY1_GB */ - sg_set_pinsel(24, 0); /* MMCDAT0 -> NFD0_GB */ - sg_set_pinsel(25, 0); /* MMCDAT1 -> NFD1_GB */ - sg_set_pinsel(26, 0); /* MMCDAT2 -> NFD2_GB */ - sg_set_pinsel(27, 0); /* MMCDAT3 -> NFD3_GB */ - sg_set_pinsel(28, 0); /* MMCDAT4 -> NFD4_GB */ - sg_set_pinsel(29, 0); /* MMCDAT5 -> NFD5_GB */ - sg_set_pinsel(30, 0); /* MMCDAT6 -> NFD6_GB */ - sg_set_pinsel(31, 0); /* MMCDAT7 -> NFD7_GB */ -#endif - -#ifdef CONFIG_USB_EHCI_UNIPHIER - sg_set_pinsel(53, 0); /* USB0VBUS -> USB0VBUS */ - sg_set_pinsel(54, 0); /* USB0OD -> USB0OD */ - sg_set_pinsel(55, 0); /* USB1VBUS -> USB1VBUS */ - sg_set_pinsel(56, 0); /* USB1OD -> USB1OD */ - /* sg_set_pinsel(67, 23); */ /* PCOE -> USB2VBUS */ - /* sg_set_pinsel(68, 23); */ /* PCWAIT -> USB2OD */ -#endif - - tmp = readl(SG_IECTRL); - tmp |= 0x41; - writel(tmp, SG_IECTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-ld4/pll_spectrum.c b/arch/arm/mach-uniphier/ph1-ld4/pll_spectrum.c deleted file mode 100644 index 837b2a891b..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/pll_spectrum.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/pll_spectrum.c" diff --git a/arch/arm/mach-uniphier/ph1-ld4/sbc_init_3cs.c b/arch/arm/mach-uniphier/ph1-ld4/sbc_init_3cs.c deleted file mode 100644 index 5b5958be05..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/sbc_init_3cs.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/io.h> -#include <mach/sbc-regs.h> -#include <mach/sg-regs.h> - -void sbc_init(void) -{ - u32 tmp; - - /* system bus output enable */ - tmp = readl(PC0CTRL); - tmp &= 0xfffffcff; - writel(tmp, PC0CTRL); - - /* XECS1: sub/boot memory (boot swap = off/on) */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL10); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL11); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL12); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL14); - - /* XECS0: boot/sub memory (boot swap = off/on) */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL00); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL01); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL02); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL04); - - /* XECS3: peripherals */ - writel(SBCTRL0_SAVEPIN_PERI_VALUE, SBCTRL30); - writel(SBCTRL1_SAVEPIN_PERI_VALUE, SBCTRL31); - writel(SBCTRL2_SAVEPIN_PERI_VALUE, SBCTRL32); - writel(SBCTRL4_SAVEPIN_PERI_VALUE, SBCTRL34); - - /* base address regsiters */ - writel(0x0000bc01, SBBASE0); - writel(0x0400bc01, SBBASE1); - writel(0x0800bf01, SBBASE3); - - /* enable access to sub memory when boot swap is on */ - if (boot_is_swapped()) - sg_set_pinsel(155, 1); /* PORT24 -> XECS0 */ - - sg_set_pinsel(156, 1); /* PORT25 -> XECS3 */ -} diff --git a/arch/arm/mach-uniphier/ph1-ld4/sg_init.c b/arch/arm/mach-uniphier/ph1-ld4/sg_init.c deleted file mode 100644 index dab56e949c..0000000000 --- a/arch/arm/mach-uniphier/ph1-ld4/sg_init.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void sg_init(void) -{ - u32 tmp; - - /* Input ports must be enabled before deasserting reset of cores */ - tmp = readl(SG_IECTRL); - tmp |= 0x1; - writel(tmp, SG_IECTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-pro4/Makefile b/arch/arm/mach-uniphier/ph1-pro4/Makefile deleted file mode 100644 index 229f4432ff..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# SPDX-License-Identifier: GPL-2.0+ -# - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-y += sg_init.o pll_init.o early_clkrst_init.o \ - early_pinctrl.o pll_spectrum.o umc_init.o ddrphy_init.o -obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += sbc_init.o -obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += sbc_init_3cs.o -else -obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o clkrst_init.o -endif - -obj-y += boot-mode.o diff --git a/arch/arm/mach-uniphier/ph1-pro4/early_pinctrl.c b/arch/arm/mach-uniphier/ph1-pro4/early_pinctrl.c deleted file mode 100644 index e78d6ab501..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/early_pinctrl.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void early_pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_UNIPHIER_SERIAL - sg_set_pinsel(127, 0); /* RXD0 -> RXD0 */ - sg_set_pinsel(128, 0); /* TXD0 -> TXD0 */ - sg_set_pinsel(129, 0); /* RXD1 -> RXD1 */ - sg_set_pinsel(130, 0); /* TXD1 -> TXD1 */ - sg_set_pinsel(131, 0); /* RXD2 -> RXD2 */ - sg_set_pinsel(132, 0); /* TXD2 -> TXD2 */ - sg_set_pinsel(88, 2); /* CH6CLK -> RXD3 */ - sg_set_pinsel(89, 2); /* CH6VAL -> TXD3 */ -#endif - - writel(1, SG_LOADPINCTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-pro4/lowlevel_debug.S b/arch/arm/mach-uniphier/ph1-pro4/lowlevel_debug.S deleted file mode 100644 index fcaf6d12d8..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/lowlevel_debug.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * On-chip UART initializaion for low-level debugging - * - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/linkage.h> -#include <mach/sc-regs.h> -#include <mach/sg-regs.h> - -#define UART_CLK 73728000 -#include <mach/debug-uart.S> - -ENTRY(setup_lowlevel_debug) - ldr r0, =SC_CLKCTRL - ldr r1, [r0] - orr r1, r1, #SC_CLKCTRL_CEN_PERI - str r1, [r0] - - init_debug_uart r0, r1, r2 - - /* UART Port 0 */ - set_pinsel 127, 0, r0, r1 - set_pinsel 128, 0, r0, r1 - - ldr r0, =SG_LOADPINCTRL - mov r1, #1 - str r1, [r0] - - ldr r0, =SG_IECTRL - ldr r1, [r0] - orr r1, r1, #1 - str r1, [r0] - - mov pc, lr -ENDPROC(setup_lowlevel_debug) diff --git a/arch/arm/mach-uniphier/ph1-pro4/pinctrl.c b/arch/arm/mach-uniphier/ph1-pro4/pinctrl.c deleted file mode 100644 index 2a5a296f88..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/pinctrl.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_NAND_DENALI - sg_set_pinsel(40, 0); /* NFD0 -> NFD0 */ - sg_set_pinsel(41, 0); /* NFD1 -> NFD1 */ - sg_set_pinsel(42, 0); /* NFD2 -> NFD2 */ - sg_set_pinsel(43, 0); /* NFD3 -> NFD3 */ - sg_set_pinsel(44, 0); /* NFD4 -> NFD4 */ - sg_set_pinsel(45, 0); /* NFD5 -> NFD5 */ - sg_set_pinsel(46, 0); /* NFD6 -> NFD6 */ - sg_set_pinsel(47, 0); /* NFD7 -> NFD7 */ - sg_set_pinsel(48, 0); /* NFALE -> NFALE */ - sg_set_pinsel(49, 0); /* NFCLE -> NFCLE */ - sg_set_pinsel(50, 0); /* XNFRE -> XNFRE */ - sg_set_pinsel(51, 0); /* XNFWE -> XNFWE */ - sg_set_pinsel(52, 0); /* XNFWP -> XNFWP */ - sg_set_pinsel(53, 0); /* XNFCE0 -> XNFCE0 */ - sg_set_pinsel(54, 0); /* NRYBY0 -> NRYBY0 */ - /* sg_set_pinsel(131, 1); */ /* RXD2 -> NRYBY1 */ - /* sg_set_pinsel(132, 1); */ /* TXD2 -> XNFCE1 */ -#endif - -#ifdef CONFIG_USB_XHCI_UNIPHIER - sg_set_pinsel(180, 0); /* USB0VBUS -> USB0VBUS */ - sg_set_pinsel(181, 0); /* USB0OD -> USB0OD */ - sg_set_pinsel(182, 0); /* USB1VBUS -> USB1VBUS */ - sg_set_pinsel(183, 0); /* USB1OD -> USB1OD */ -#endif - -#ifdef CONFIG_USB_EHCI_UNIPHIER - sg_set_pinsel(184, 0); /* USB2VBUS -> USB2VBUS */ - sg_set_pinsel(185, 0); /* USB2OD -> USB2OD */ - sg_set_pinsel(187, 0); /* USB3VBUS -> USB3VBUS */ - sg_set_pinsel(188, 0); /* USB3OD -> USB3OD */ -#endif - - writel(1, SG_LOADPINCTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-pro4/sbc_init_3cs.c b/arch/arm/mach-uniphier/ph1-pro4/sbc_init_3cs.c deleted file mode 100644 index 877ba79f68..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/sbc_init_3cs.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/io.h> -#include <mach/sbc-regs.h> -#include <mach/sg-regs.h> - -void sbc_init(void) -{ - /* XECS0: boot/sub memory (boot swap = off/on) */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL00); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL01); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL02); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL04); - - /* XECS1: sub/boot memory (boot swap = off/on) */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL10); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL11); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL12); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL14); - - /* XECS3: peripherals */ - writel(SBCTRL0_SAVEPIN_PERI_VALUE, SBCTRL30); - writel(SBCTRL1_SAVEPIN_PERI_VALUE, SBCTRL31); - writel(SBCTRL2_SAVEPIN_PERI_VALUE, SBCTRL32); - writel(SBCTRL4_SAVEPIN_PERI_VALUE, SBCTRL34); - - writel(0x0000bc01, SBBASE0); /* boot memory */ - writel(0x0400bc01, SBBASE1); /* sub memory */ - writel(0x0800bf01, SBBASE3); /* peripherals */ - - /* enable access to sub memory when boot swap is on */ - if (boot_is_swapped()) - sg_set_pinsel(318, 5); /* PORT22 -> XECS0 */ - - sg_set_pinsel(313, 5); /* PORT15 -> XECS3 */ - writel(0x00000001, SG_LOADPINCTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-pro4/sg_init.c b/arch/arm/mach-uniphier/ph1-pro4/sg_init.c deleted file mode 100644 index d6ccffbbc3..0000000000 --- a/arch/arm/mach-uniphier/ph1-pro4/sg_init.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void sg_init(void) -{ - u32 tmp; - - /* Input ports must be enabled before deasserting reset of cores */ - tmp = readl(SG_IECTRL); - tmp |= 1 << 6; - writel(tmp, SG_IECTRL); -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/Makefile b/arch/arm/mach-uniphier/ph1-sld3/Makefile deleted file mode 100644 index aff5d640d6..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# SPDX-License-Identifier: GPL-2.0+ -# - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-y += bcu_init.o memconf.o sg_init.o pll_init.o early_clkrst_init.o \ - early_pinctrl.o pll_spectrum.o umc_init.o -obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += sbc_init.o -obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += sbc_init_3cs.o -else -obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o clkrst_init.o -endif - -obj-y += boot-mode.o diff --git a/arch/arm/mach-uniphier/ph1-sld3/clkrst_init.c b/arch/arm/mach-uniphier/ph1-sld3/clkrst_init.c deleted file mode 100644 index 3a3dab7a15..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/clkrst_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/clkrst_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld3/early_clkrst_init.c b/arch/arm/mach-uniphier/ph1-sld3/early_clkrst_init.c deleted file mode 100644 index d7ef16b10a..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/early_clkrst_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/early_clkrst_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld3/early_pinctrl.c b/arch/arm/mach-uniphier/ph1-sld3/early_pinctrl.c deleted file mode 100644 index f113e658d8..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/early_pinctrl.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <mach/sg-regs.h> - -void early_pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_UNIPHIER_SERIAL - sg_set_pinsel(63, 0); /* RXD0 */ - sg_set_pinsel(64, 1); /* TXD0 */ - - sg_set_pinsel(65, 0); /* RXD1 */ - sg_set_pinsel(66, 1); /* TXD1 */ - - sg_set_pinsel(96, 2); /* RXD2 */ - sg_set_pinsel(102, 2); /* TXD2 */ -#endif -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/lowlevel_debug.S b/arch/arm/mach-uniphier/ph1-sld3/lowlevel_debug.S deleted file mode 100644 index 41f67b7a8f..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/lowlevel_debug.S +++ /dev/null @@ -1,33 +0,0 @@ -/* - * On-chip UART initializaion for low-level debugging - * - * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/linkage.h> -#include <mach/bcu-regs.h> -#include <mach/sc-regs.h> -#include <mach/sg-regs.h> - -#define UART_CLK 36864000 -#include <mach/debug-uart.S> - -ENTRY(setup_lowlevel_debug) - ldr r0, =BCSCR5 - ldr r1, =0x24440000 - str r1, [r0] - - ldr r0, =SC_CLKCTRL - ldr r1, [r0] - orr r1, r1, #SC_CLKCTRL_CEN_PERI - str r1, [r0] - - init_debug_uart r0, r1, r2 - - set_pinsel 63, 0, r0, r1 - set_pinsel 64, 1, r0, r1 - - mov pc, lr -ENDPROC(setup_lowlevel_debug) diff --git a/arch/arm/mach-uniphier/ph1-sld3/memconf.c b/arch/arm/mach-uniphier/ph1-sld3/memconf.c deleted file mode 100644 index 553a9e3384..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/memconf.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/types.h> -#include <linux/sizes.h> -#include <mach/sg-regs.h> - -static inline u32 sg_memconf_val_ch2(unsigned long size, int num) -{ - int size_mb = size / num; - u32 ret; - - switch (size_mb) { - case SZ_64M: - ret = SG_MEMCONF_CH2_SZ_64M; - break; - case SZ_128M: - ret = SG_MEMCONF_CH2_SZ_128M; - break; - case SZ_256M: - ret = SG_MEMCONF_CH2_SZ_256M; - break; - case SZ_512M: - ret = SG_MEMCONF_CH2_SZ_512M; - break; - default: - BUG(); - break; - } - - switch (num) { - case 1: - ret |= SG_MEMCONF_CH2_NUM_1; - break; - case 2: - ret |= SG_MEMCONF_CH2_NUM_2; - break; - default: - BUG(); - break; - } - return ret; -} - -u32 memconf_additional_val(void) -{ - return sg_memconf_val_ch2(CONFIG_SDRAM2_SIZE, CONFIG_DDR_NUM_CH2); -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/pinctrl.c b/arch/arm/mach-uniphier/ph1-sld3/pinctrl.c deleted file mode 100644 index 5ecbe4cca3..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/pinctrl.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <mach/sg-regs.h> - -void pin_init(void) -{ -#ifdef CONFIG_USB_EHCI_UNIPHIER - sg_set_pinsel(13, 0); /* USB0OC */ - sg_set_pinsel(14, 1); /* USB0VBUS */ - - sg_set_pinsel(15, 0); /* USB1OC */ - sg_set_pinsel(16, 1); /* USB1VBUS */ - - sg_set_pinsel(17, 0); /* USB2OC */ - sg_set_pinsel(18, 1); /* USB2VBUS */ - - sg_set_pinsel(19, 0); /* USB3OC */ - sg_set_pinsel(20, 1); /* USB3VBUS */ -#endif -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/sbc_init_3cs.c b/arch/arm/mach-uniphier/ph1-sld3/sbc_init_3cs.c deleted file mode 100644 index f5e24467ce..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/sbc_init_3cs.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/io.h> -#include <mach/sbc-regs.h> -#include <mach/sg-regs.h> - -void sbc_init(void) -{ - /* only address/data multiplex mode is supported */ - - /* XECS0 : boot/sub memory (boot swap = off/on) */ - writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL00); - writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL01); - writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL02); - - /* XECS1 : sub/boot memory (boot swap = off/on) */ - writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL10); - writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL11); - writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL12); - - /* XECS2 : peripherals */ - writel(SBCTRL0_ADMULTIPLX_PERI_VALUE, SBCTRL20); - writel(SBCTRL1_ADMULTIPLX_PERI_VALUE, SBCTRL21); - writel(SBCTRL2_ADMULTIPLX_PERI_VALUE, SBCTRL22); - - /* base address regsiters */ - writel(0x0000bc01, SBBASE0); - writel(0x0400bc01, SBBASE1); - writel(0x0800bf01, SBBASE2); - - sg_set_pinsel(99, 1); /* GPIO26 -> EA24 */ -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/sg_init.c b/arch/arm/mach-uniphier/ph1-sld3/sg_init.c deleted file mode 100644 index ca3cb9c6b8..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/sg_init.c +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -void sg_init(void) -{ -} diff --git a/arch/arm/mach-uniphier/ph1-sld3/umc_init.c b/arch/arm/mach-uniphier/ph1-sld3/umc_init.c deleted file mode 100644 index 91ee3de282..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld3/umc_init.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -int umc_init(void) -{ - /* add UMC init code here */ - printf("Implement memory init code\n"); - - return 0; -} diff --git a/arch/arm/mach-uniphier/ph1-sld8/Makefile b/arch/arm/mach-uniphier/ph1-sld8/Makefile deleted file mode 100644 index 8eb575e1d3..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(src)/../ph1-ld4/Makefile diff --git a/arch/arm/mach-uniphier/ph1-sld8/bcu_init.c b/arch/arm/mach-uniphier/ph1-sld8/bcu_init.c deleted file mode 100644 index 69b172e4e7..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/bcu_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/bcu_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/boot-mode.c b/arch/arm/mach-uniphier/ph1-sld8/boot-mode.c deleted file mode 100644 index d359b56291..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/boot-mode.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-pro4/boot-mode.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/clkrst_init.c b/arch/arm/mach-uniphier/ph1-sld8/clkrst_init.c deleted file mode 100644 index 8d3435d632..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/clkrst_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/clkrst_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/early_clkrst_init.c b/arch/arm/mach-uniphier/ph1-sld8/early_clkrst_init.c deleted file mode 100644 index dd236b7e50..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/early_clkrst_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/early_clkrst_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/early_pinctrl.c b/arch/arm/mach-uniphier/ph1-sld8/early_pinctrl.c deleted file mode 100644 index 28cc4296fc..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/early_pinctrl.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2011-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <mach/sg-regs.h> - -void early_pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_UNIPHIER_SERIAL - sg_set_pinsel(70, 3); /* HDDOUT0 -> TXD0 */ - sg_set_pinsel(71, 3); /* HSDOUT1 -> RXD0 */ - - sg_set_pinsel(114, 0); /* TXD1 -> TXD1 */ - sg_set_pinsel(115, 0); /* RXD1 -> RXD1 */ - - sg_set_pinsel(112, 1); /* SBO1 -> TXD2 */ - sg_set_pinsel(113, 1); /* SBI1 -> RXD2 */ - - sg_set_pinsel(110, 1); /* SBO0 -> TXD3 */ - sg_set_pinsel(111, 1); /* SBI0 -> RXD3 */ -#endif -} diff --git a/arch/arm/mach-uniphier/ph1-sld8/lowlevel_debug.S b/arch/arm/mach-uniphier/ph1-sld8/lowlevel_debug.S deleted file mode 100644 index 73f0f63eba..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/lowlevel_debug.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * On-chip UART initializaion for low-level debugging - * - * Copyright (C) 2014 Panasonic Corporation - * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/linkage.h> -#include <mach/sg-regs.h> - -#define UART_CLK 80000000 -#include <mach/debug-uart.S> - -ENTRY(setup_lowlevel_debug) - init_debug_uart r0, r1, r2 - - /* UART Port 0 */ - set_pinsel 70, 3, r0, r1 - set_pinsel 71, 3, r0, r1 - - ldr r0, =SG_IECTRL - ldr r1, [r0] - orr r1, r1, #1 - str r1, [r0] - - mov pc, lr -ENDPROC(setup_lowlevel_debug) diff --git a/arch/arm/mach-uniphier/ph1-sld8/pinctrl.c b/arch/arm/mach-uniphier/ph1-sld8/pinctrl.c deleted file mode 100644 index 130c831736..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/pinctrl.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/io.h> -#include <mach/sg-regs.h> - -void pin_init(void) -{ - /* Comment format: PAD Name -> Function Name */ - -#ifdef CONFIG_SYS_I2C_UNIPHIER - { - u32 tmp; - tmp = readl(SG_IECTRL); - tmp |= 0xc00; /* enable SCL0, SDA0, SCL1, SDA1 */ - writel(tmp, SG_IECTRL); - } -#endif - -#ifdef CONFIG_NAND_DENALI - sg_set_pinsel(15, 0); /* XNFRE_GB -> XNFRE_GB */ - sg_set_pinsel(16, 0); /* XNFWE_GB -> XNFWE_GB */ - sg_set_pinsel(17, 0); /* XFALE_GB -> NFALE_GB */ - sg_set_pinsel(18, 0); /* XFCLE_GB -> NFCLE_GB */ - sg_set_pinsel(19, 0); /* XNFWP_GB -> XFNWP_GB */ - sg_set_pinsel(20, 0); /* XNFCE0_GB -> XNFCE0_GB */ - sg_set_pinsel(21, 0); /* NANDRYBY0_GB -> NANDRYBY0_GB */ - sg_set_pinsel(22, 0); /* XFNCE1_GB -> XFNCE1_GB */ - sg_set_pinsel(23, 0); /* NANDRYBY1_GB -> NANDRYBY1_GB */ - sg_set_pinsel(24, 0); /* NFD0_GB -> NFD0_GB */ - sg_set_pinsel(25, 0); /* NFD1_GB -> NFD1_GB */ - sg_set_pinsel(26, 0); /* NFD2_GB -> NFD2_GB */ - sg_set_pinsel(27, 0); /* NFD3_GB -> NFD3_GB */ - sg_set_pinsel(28, 0); /* NFD4_GB -> NFD4_GB */ - sg_set_pinsel(29, 0); /* NFD5_GB -> NFD5_GB */ - sg_set_pinsel(30, 0); /* NFD6_GB -> NFD6_GB */ - sg_set_pinsel(31, 0); /* NFD7_GB -> NFD7_GB */ -#endif - -#ifdef CONFIG_USB_EHCI_UNIPHIER - sg_set_pinsel(41, 0); /* USB0VBUS -> USB0VBUS */ - sg_set_pinsel(42, 0); /* USB0OD -> USB0OD */ - sg_set_pinsel(43, 0); /* USB1VBUS -> USB1VBUS */ - sg_set_pinsel(44, 0); /* USB1OD -> USB1OD */ - /* sg_set_pinsel(114, 1); */ /* TXD1 -> USB2VBUS (shared with UART) */ - /* sg_set_pinsel(115, 1); */ /* RXD1 -> USB2OD */ -#endif -} diff --git a/arch/arm/mach-uniphier/ph1-sld8/pll_spectrum.c b/arch/arm/mach-uniphier/ph1-sld8/pll_spectrum.c deleted file mode 100644 index 9b8c4855e5..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/pll_spectrum.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/pll_spectrum.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/sbc_init.c b/arch/arm/mach-uniphier/ph1-sld8/sbc_init.c deleted file mode 100644 index 225c0d24de..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/sbc_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/sbc_init.c" diff --git a/arch/arm/mach-uniphier/ph1-sld8/sbc_init_3cs.c b/arch/arm/mach-uniphier/ph1-sld8/sbc_init_3cs.c deleted file mode 100644 index c2267c73ee..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/sbc_init_3cs.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/io.h> -#include <mach/sbc-regs.h> -#include <mach/sg-regs.h> - -void sbc_init(void) -{ - u32 tmp; - - /* system bus output enable */ - tmp = readl(PC0CTRL); - tmp &= 0xfffffcff; - writel(tmp, PC0CTRL); - - /* - * SBCTRL0* does not need settings because PH1-sLD8 has no support for - * XECS0. The boot swap must be enabled to boot from the support card. - */ - - if (boot_is_swapped()) { - /* XECS1 : boot memory if boot swap is on */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL10); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL11); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL12); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL14); - } - - /* XECS4 : sub memory */ - writel(SBCTRL0_SAVEPIN_MEM_VALUE, SBCTRL40); - writel(SBCTRL1_SAVEPIN_MEM_VALUE, SBCTRL41); - writel(SBCTRL2_SAVEPIN_MEM_VALUE, SBCTRL42); - writel(SBCTRL4_SAVEPIN_MEM_VALUE, SBCTRL44); - - /* XECS5 : peripherals */ - writel(SBCTRL0_SAVEPIN_PERI_VALUE, SBCTRL50); - writel(SBCTRL1_SAVEPIN_PERI_VALUE, SBCTRL51); - writel(SBCTRL2_SAVEPIN_PERI_VALUE, SBCTRL52); - writel(SBCTRL4_SAVEPIN_PERI_VALUE, SBCTRL54); - - /* base address regsiters */ - writel(0x0000bc01, SBBASE0); /* boot memory */ - writel(0x0900bfff, SBBASE1); /* dummy */ - writel(0x0400bc01, SBBASE4); /* sub memory */ - writel(0x0800bf01, SBBASE5); /* peripherals */ - - sg_set_pinsel(134, 16); /* XIRQ6 -> XECS4 */ - sg_set_pinsel(135, 16); /* XIRQ7 -> XECS5 */ - - /* dummy read to assure write process */ - readl(SG_PINCTRL(0)); -} diff --git a/arch/arm/mach-uniphier/ph1-sld8/sg_init.c b/arch/arm/mach-uniphier/ph1-sld8/sg_init.c deleted file mode 100644 index a808289a56..0000000000 --- a/arch/arm/mach-uniphier/ph1-sld8/sg_init.c +++ /dev/null @@ -1 +0,0 @@ -#include "../ph1-ld4/sg_init.c" diff --git a/arch/arm/mach-uniphier/pinctrl/Makefile b/arch/arm/mach-uniphier/pinctrl/Makefile new file mode 100644 index 0000000000..85175955d3 --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += pinctrl-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += pinctrl-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += pinctrl-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += pinctrl-ph1-sld8.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += pinctrl-ph1-pro5.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += pinctrl-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += pinctrl-ph1-ld6b.o diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c new file mode 100644 index 0000000000..160d3ef299 --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld4.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_ld4_pin_init(void) +{ + u32 tmp; + + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(158, 0, 8, 4); /* XNFRE -> XNFRE_GB */ + sg_set_pinsel(159, 0, 8, 4); /* XNFWE -> XNFWE_GB */ + sg_set_pinsel(160, 0, 8, 4); /* XFALE -> NFALE_GB */ + sg_set_pinsel(161, 0, 8, 4); /* XFCLE -> NFCLE_GB */ + sg_set_pinsel(162, 0, 8, 4); /* XNFWP -> XFNWP_GB */ + sg_set_pinsel(163, 0, 8, 4); /* XNFCE0 -> XNFCE0_GB */ + sg_set_pinsel(164, 0, 8, 4); /* NANDRYBY0 -> NANDRYBY0_GB */ + sg_set_pinsel(22, 0, 8, 4); /* MMCCLK -> XFNCE1_GB */ + sg_set_pinsel(23, 0, 8, 4); /* MMCCMD -> NANDRYBY1_GB */ + sg_set_pinsel(24, 0, 8, 4); /* MMCDAT0 -> NFD0_GB */ + sg_set_pinsel(25, 0, 8, 4); /* MMCDAT1 -> NFD1_GB */ + sg_set_pinsel(26, 0, 8, 4); /* MMCDAT2 -> NFD2_GB */ + sg_set_pinsel(27, 0, 8, 4); /* MMCDAT3 -> NFD3_GB */ + sg_set_pinsel(28, 0, 8, 4); /* MMCDAT4 -> NFD4_GB */ + sg_set_pinsel(29, 0, 8, 4); /* MMCDAT5 -> NFD5_GB */ + sg_set_pinsel(30, 0, 8, 4); /* MMCDAT6 -> NFD6_GB */ + sg_set_pinsel(31, 0, 8, 4); /* MMCDAT7 -> NFD7_GB */ +#endif + +#ifdef CONFIG_USB_EHCI_UNIPHIER + sg_set_pinsel(53, 0, 8, 4); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(54, 0, 8, 4); /* USB0OD -> USB0OD */ + sg_set_pinsel(55, 0, 8, 4); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(56, 0, 8, 4); /* USB1OD -> USB1OD */ + /* sg_set_pinsel(67, 23, 8, 4); */ /* PCOE -> USB2VBUS */ + /* sg_set_pinsel(68, 23, 8, 4); */ /* PCWAIT -> USB2OD */ +#endif + + tmp = readl(SG_IECTRL); + tmp |= 0x41; + writel(tmp, SG_IECTRL); +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c new file mode 100644 index 0000000000..4f950d3fc6 --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-ld6b.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_ld6b_pin_init(void) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(30, 0, 8, 4); /* XNFRE -> XNFRE */ + sg_set_pinsel(31, 0, 8, 4); /* XNFWE -> XNFWE */ + sg_set_pinsel(32, 0, 8, 4); /* NFALE -> NFALE */ + sg_set_pinsel(33, 0, 8, 4); /* NFCLE -> NFCLE */ + sg_set_pinsel(34, 0, 8, 4); /* XNFWP -> XNFWP */ + sg_set_pinsel(35, 0, 8, 4); /* XNFCE0 -> XNFCE0 */ + sg_set_pinsel(36, 0, 8, 4); /* NRYBY0 -> NRYBY0 */ + sg_set_pinsel(37, 0, 8, 4); /* XNFCE1 -> NRYBY1 */ + sg_set_pinsel(38, 0, 8, 4); /* NRYBY1 -> XNFCE1 */ + sg_set_pinsel(39, 0, 8, 4); /* NFD0 -> NFD0 */ + sg_set_pinsel(40, 0, 8, 4); /* NFD1 -> NFD1 */ + sg_set_pinsel(41, 0, 8, 4); /* NFD2 -> NFD2 */ + sg_set_pinsel(42, 0, 8, 4); /* NFD3 -> NFD3 */ + sg_set_pinsel(43, 0, 8, 4); /* NFD4 -> NFD4 */ + sg_set_pinsel(44, 0, 8, 4); /* NFD5 -> NFD5 */ + sg_set_pinsel(45, 0, 8, 4); /* NFD6 -> NFD6 */ + sg_set_pinsel(46, 0, 8, 4); /* NFD7 -> NFD7 */ +#endif + +#ifdef CONFIG_USB_XHCI_UNIPHIER + sg_set_pinsel(56, 0, 8, 4); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(57, 0, 8, 4); /* USB0OD -> USB0OD */ + sg_set_pinsel(58, 0, 8, 4); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(59, 0, 8, 4); /* USB1OD -> USB1OD */ + sg_set_pinsel(60, 0, 8, 4); /* USB2VBUS -> USB2VBUS */ + sg_set_pinsel(61, 0, 8, 4); /* USB2OD -> USB2OD */ + sg_set_pinsel(62, 0, 8, 4); /* USB3VBUS -> USB3VBUS */ + sg_set_pinsel(63, 0, 8, 4); /* USB3OD -> USB3OD */ +#endif +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c new file mode 100644 index 0000000000..f50644c52b --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro4.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_pro4_pin_init(void) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(40, 0, 4, 8); /* NFD0 -> NFD0 */ + sg_set_pinsel(41, 0, 4, 8); /* NFD1 -> NFD1 */ + sg_set_pinsel(42, 0, 4, 8); /* NFD2 -> NFD2 */ + sg_set_pinsel(43, 0, 4, 8); /* NFD3 -> NFD3 */ + sg_set_pinsel(44, 0, 4, 8); /* NFD4 -> NFD4 */ + sg_set_pinsel(45, 0, 4, 8); /* NFD5 -> NFD5 */ + sg_set_pinsel(46, 0, 4, 8); /* NFD6 -> NFD6 */ + sg_set_pinsel(47, 0, 4, 8); /* NFD7 -> NFD7 */ + sg_set_pinsel(48, 0, 4, 8); /* NFALE -> NFALE */ + sg_set_pinsel(49, 0, 4, 8); /* NFCLE -> NFCLE */ + sg_set_pinsel(50, 0, 4, 8); /* XNFRE -> XNFRE */ + sg_set_pinsel(51, 0, 4, 8); /* XNFWE -> XNFWE */ + sg_set_pinsel(52, 0, 4, 8); /* XNFWP -> XNFWP */ + sg_set_pinsel(53, 0, 4, 8); /* XNFCE0 -> XNFCE0 */ + sg_set_pinsel(54, 0, 4, 8); /* NRYBY0 -> NRYBY0 */ + /* sg_set_pinsel(131, 1, 4, 8); */ /* RXD2 -> NRYBY1 */ + /* sg_set_pinsel(132, 1, 4, 8); */ /* TXD2 -> XNFCE1 */ +#endif + +#ifdef CONFIG_USB_XHCI_UNIPHIER + sg_set_pinsel(180, 0, 4, 8); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(181, 0, 4, 8); /* USB0OD -> USB0OD */ + sg_set_pinsel(182, 0, 4, 8); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(183, 0, 4, 8); /* USB1OD -> USB1OD */ +#endif + +#ifdef CONFIG_USB_EHCI_UNIPHIER + sg_set_pinsel(184, 0, 4, 8); /* USB2VBUS -> USB2VBUS */ + sg_set_pinsel(185, 0, 4, 8); /* USB2OD -> USB2OD */ + sg_set_pinsel(187, 0, 4, 8); /* USB3VBUS -> USB3VBUS */ + sg_set_pinsel(188, 0, 4, 8); /* USB3OD -> USB3OD */ +#endif + + writel(1, SG_LOADPINCTRL); +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c new file mode 100644 index 0000000000..a6cc0824e2 --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-pro5.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_pro5_pin_init(void) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(19, 0, 4, 8); /* XNFRE -> XNFRE */ + sg_set_pinsel(20, 0, 4, 8); /* XNFWE -> XNFWE */ + sg_set_pinsel(21, 0, 4, 8); /* NFALE -> NFALE */ + sg_set_pinsel(22, 0, 4, 8); /* NFCLE -> NFCLE */ + sg_set_pinsel(23, 0, 4, 8); /* XNFWP -> XNFWP */ + sg_set_pinsel(24, 0, 4, 8); /* XNFCE0 -> XNFCE0 */ + sg_set_pinsel(25, 0, 4, 8); /* NRYBY0 -> NRYBY0 */ + sg_set_pinsel(26, 0, 4, 8); /* XNFCE1 -> XNFCE1 */ + sg_set_pinsel(27, 0, 4, 8); /* NRYBY1 -> NRYBY1 */ + sg_set_pinsel(28, 0, 4, 8); /* NFD0 -> NFD0 */ + sg_set_pinsel(29, 0, 4, 8); /* NFD1 -> NFD1 */ + sg_set_pinsel(30, 0, 4, 8); /* NFD2 -> NFD2 */ + sg_set_pinsel(31, 0, 4, 8); /* NFD3 -> NFD3 */ + sg_set_pinsel(32, 0, 4, 8); /* NFD4 -> NFD4 */ + sg_set_pinsel(33, 0, 4, 8); /* NFD5 -> NFD5 */ + sg_set_pinsel(34, 0, 4, 8); /* NFD6 -> NFD6 */ + sg_set_pinsel(35, 0, 4, 8); /* NFD7 -> NFD7 */ +#endif + +#ifdef CONFIG_USB_XHCI_UNIPHIER + sg_set_pinsel(124, 0, 4, 8); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(125, 0, 4, 8); /* USB0OD -> USB0OD */ + sg_set_pinsel(126, 0, 4, 8); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(127, 0, 4, 8); /* USB1OD -> USB1OD */ +#endif + + writel(1, SG_LOADPINCTRL); +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c new file mode 100644 index 0000000000..f1b2bbbb4a --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld3.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_sld3_pin_init(void) +{ +#ifdef CONFIG_USB_EHCI_UNIPHIER + sg_set_pinsel(13, 0, 4, 4); /* USB0OC */ + sg_set_pinsel(14, 1, 4, 4); /* USB0VBUS */ + + sg_set_pinsel(15, 0, 4, 4); /* USB1OC */ + sg_set_pinsel(16, 1, 4, 4); /* USB1VBUS */ + + sg_set_pinsel(17, 0, 4, 4); /* USB2OC */ + sg_set_pinsel(18, 1, 4, 4); /* USB2VBUS */ + + sg_set_pinsel(19, 0, 4, 4); /* USB3OC */ + sg_set_pinsel(20, 1, 4, 4); /* USB3VBUS */ +#endif +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c new file mode 100644 index 0000000000..f936a53d1f --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-ph1-sld8.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void ph1_sld8_pin_init(void) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(15, 0, 8, 4); /* XNFRE_GB -> XNFRE_GB */ + sg_set_pinsel(16, 0, 8, 4); /* XNFWE_GB -> XNFWE_GB */ + sg_set_pinsel(17, 0, 8, 4); /* XFALE_GB -> NFALE_GB */ + sg_set_pinsel(18, 0, 8, 4); /* XFCLE_GB -> NFCLE_GB */ + sg_set_pinsel(19, 0, 8, 4); /* XNFWP_GB -> XFNWP_GB */ + sg_set_pinsel(20, 0, 8, 4); /* XNFCE0_GB -> XNFCE0_GB */ + sg_set_pinsel(21, 0, 8, 4); /* NANDRYBY0_GB -> NANDRYBY0_GB */ + sg_set_pinsel(22, 0, 8, 4); /* XFNCE1_GB -> XFNCE1_GB */ + sg_set_pinsel(23, 0, 8, 4); /* NANDRYBY1_GB -> NANDRYBY1_GB */ + sg_set_pinsel(24, 0, 8, 4); /* NFD0_GB -> NFD0_GB */ + sg_set_pinsel(25, 0, 8, 4); /* NFD1_GB -> NFD1_GB */ + sg_set_pinsel(26, 0, 8, 4); /* NFD2_GB -> NFD2_GB */ + sg_set_pinsel(27, 0, 8, 4); /* NFD3_GB -> NFD3_GB */ + sg_set_pinsel(28, 0, 8, 4); /* NFD4_GB -> NFD4_GB */ + sg_set_pinsel(29, 0, 8, 4); /* NFD5_GB -> NFD5_GB */ + sg_set_pinsel(30, 0, 8, 4); /* NFD6_GB -> NFD6_GB */ + sg_set_pinsel(31, 0, 8, 4); /* NFD7_GB -> NFD7_GB */ +#endif + +#ifdef CONFIG_USB_EHCI_UNIPHIER + sg_set_pinsel(41, 0, 8, 4); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(42, 0, 8, 4); /* USB0OD -> USB0OD */ + sg_set_pinsel(43, 0, 8, 4); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(44, 0, 8, 4); /* USB1OD -> USB1OD */ + /* sg_set_pinsel(114, 1, 8, 4); */ /* TXD1 -> USB2VBUS (shared with UART) */ + /* sg_set_pinsel(115, 1, 8, 4); */ /* RXD1 -> USB2OD */ +#endif +} diff --git a/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c b/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c new file mode 100644 index 0000000000..96abd0235c --- /dev/null +++ b/arch/arm/mach-uniphier/pinctrl/pinctrl-proxstream2.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sg-regs.h> + +void proxstream2_pin_init(void) +{ + /* Comment format: PAD Name -> Function Name */ + +#ifdef CONFIG_NAND_DENALI + sg_set_pinsel(30, 8, 8, 4); /* XNFRE -> XNFRE */ + sg_set_pinsel(31, 8, 8, 4); /* XNFWE -> XNFWE */ + sg_set_pinsel(32, 8, 8, 4); /* NFALE -> NFALE */ + sg_set_pinsel(33, 8, 8, 4); /* NFCLE -> NFCLE */ + sg_set_pinsel(34, 8, 8, 4); /* XNFWP -> XNFWP */ + sg_set_pinsel(35, 8, 8, 4); /* XNFCE0 -> XNFCE0 */ + sg_set_pinsel(36, 8, 8, 4); /* NRYBY0 -> NRYBY0 */ + sg_set_pinsel(37, 8, 8, 4); /* XNFCE1 -> NRYBY1 */ + sg_set_pinsel(38, 8, 8, 4); /* NRYBY1 -> XNFCE1 */ + sg_set_pinsel(39, 8, 8, 4); /* NFD0 -> NFD0 */ + sg_set_pinsel(40, 8, 8, 4); /* NFD1 -> NFD1 */ + sg_set_pinsel(41, 8, 8, 4); /* NFD2 -> NFD2 */ + sg_set_pinsel(42, 8, 8, 4); /* NFD3 -> NFD3 */ + sg_set_pinsel(43, 8, 8, 4); /* NFD4 -> NFD4 */ + sg_set_pinsel(44, 8, 8, 4); /* NFD5 -> NFD5 */ + sg_set_pinsel(45, 8, 8, 4); /* NFD6 -> NFD6 */ + sg_set_pinsel(46, 8, 8, 4); /* NFD7 -> NFD7 */ +#endif + +#ifdef CONFIG_USB_XHCI_UNIPHIER + sg_set_pinsel(56, 8, 8, 4); /* USB0VBUS -> USB0VBUS */ + sg_set_pinsel(57, 8, 8, 4); /* USB0OD -> USB0OD */ + sg_set_pinsel(58, 8, 8, 4); /* USB1VBUS -> USB1VBUS */ + sg_set_pinsel(59, 8, 8, 4); /* USB1OD -> USB1OD */ + sg_set_pinsel(60, 8, 8, 4); /* USB2VBUS -> USB2VBUS */ + sg_set_pinsel(61, 8, 8, 4); /* USB2OD -> USB2OD */ + sg_set_pinsel(62, 8, 8, 4); /* USB3VBUS -> USB3VBUS */ + sg_set_pinsel(63, 8, 8, 4); /* USB3OD -> USB3OD */ +#endif +} diff --git a/arch/arm/mach-uniphier/pll/Makefile b/arch/arm/mach-uniphier/pll/Makefile new file mode 100644 index 0000000000..d33f99e446 --- /dev/null +++ b/arch/arm/mach-uniphier/pll/Makefile @@ -0,0 +1,8 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += pll-init-ph1-sld3.o \ + pll-spectrum-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += pll-init-ph1-ld4.o \ + pll-spectrum-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += pll-init-ph1-pro4.o \ + pll-spectrum-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += pll-init-ph1-sld8.o \ + pll-spectrum-ph1-ld4.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/pll_init.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c index f8ec2b61fb..a272a900e1 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/pll_init.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-ld4.c @@ -5,13 +5,15 @@ */ #include <common.h> +#include <linux/err.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> #include <mach/sg-regs.h> #undef DPLL_SSC_RATE_1PER -static void dpll_init(void) +static int dpll_init(unsigned int dram_freq) { u32 tmp; @@ -22,13 +24,17 @@ static void dpll_init(void) */ tmp = readl(SC_DPLLCTRL); tmp &= ~0x000f0000; -#if CONFIG_DDR_FREQ == 1600 - tmp |= 0x000c0000; -#elif CONFIG_DDR_FREQ == 1333 - tmp |= 0x000d0000; -#else -# error "Unknown frequency" -#endif + switch (dram_freq) { + case 1333: + tmp |= 0x000d0000; + break; + case 1600: + tmp |= 0x000c0000; + break; + default: + pr_err("Unsupported frequency"); + return -EINVAL; + } #if defined(DPLL_SSC_RATE_1PER) tmp &= ~SC_DPLLCTRL_SSC_RATE; @@ -40,6 +46,8 @@ static void dpll_init(void) tmp = readl(SC_DPLLCTRL2); tmp |= SC_DPLLCTRL2_NRSTDS; writel(tmp, SC_DPLLCTRL2); + + return 0; } static void upll_init(void) @@ -174,9 +182,13 @@ static void vpll_init(void) writel(tmp, SC_VPLL27BCTRL); } -void pll_init(void) +int ph1_ld4_pll_init(const struct uniphier_board_data *bd) { - dpll_init(); + int ret; + + ret = dpll_init(bd->dram_freq); + if (ret) + return ret; upll_init(); vpll_init(); @@ -186,4 +198,6 @@ void pll_init(void) * so 20 usec can be saved here. */ udelay(480); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-pro4/pll_init.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c index d693368816..906c22f6c5 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/pll_init.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c @@ -5,13 +5,15 @@ */ #include <common.h> +#include <linux/err.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> #include <mach/sg-regs.h> #undef DPLL_SSC_RATE_1PER -static void dpll_init(void) +static int dpll_init(unsigned int dram_freq) { u32 tmp; @@ -22,13 +24,17 @@ static void dpll_init(void) */ tmp = readl(SC_DPLLCTRL); tmp &= ~(0x000f0000); -#if CONFIG_DDR_FREQ == 1600 - tmp |= 0x000c0000; -#elif CONFIG_DDR_FREQ == 1333 - tmp |= 0x000d0000; -#else -# error "Unsupported frequency" -#endif + switch (dram_freq) { + case 1333: + tmp |= 0x000d0000; + break; + case 1600: + tmp |= 0x000c0000; + break; + default: + pr_err("Unsupported frequency"); + return -EINVAL; + } /* * Set Moduration rate @@ -44,6 +50,8 @@ static void dpll_init(void) tmp = readl(SC_DPLLCTRL2); tmp |= SC_DPLLCTRL2_NRSTDS; writel(tmp, SC_DPLLCTRL2); + + return 0; } static void vpll_init(void) @@ -54,12 +62,10 @@ static void vpll_init(void) tmp = readl(SG_PINMON0); clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK; -#if defined(CONFIG_MACH_PH1_PRO4) /* 25MHz or 6.25MHz is default for Pro4R, no need to set VPLLA/B */ if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ || clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_6250KHZ) return; -#endif /* Disable write protect of VPLL27ACTRL[2-7]*, VPLL27BCTRL[2-8] */ tmp = readl(SC_VPLL27ACTRL); @@ -138,9 +144,13 @@ static void vpll_init(void) writel(tmp, SC_VPLL27BCTRL); } -void pll_init(void) +int ph1_pro4_pll_init(const struct uniphier_board_data *bd) { - dpll_init(); + int ret; + + ret = dpll_init(bd->dram_freq); + if (ret) + return ret; vpll_init(); /* @@ -148,4 +158,6 @@ void pll_init(void) * We wait 1 usec in vpll_init() so 1 usec can be saved here. */ udelay(499); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld3/pll_init.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c index ebd1c310b7..6294a452c2 100644 --- a/arch/arm/mach-uniphier/ph1-sld3/pll_init.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld3.c @@ -4,7 +4,10 @@ * SPDX-License-Identifier: GPL-2.0+ */ -void pll_init(void) +#include <mach/init.h> + +int ph1_sld3_pll_init(const struct uniphier_board_data *bd) { /* add pll init code here */ + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld8/pll_init.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c index 109cb5fee0..f249abeeda 100644 --- a/arch/arm/mach-uniphier/ph1-sld8/pll_init.c +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-sld8.c @@ -6,6 +6,7 @@ #include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> #include <mach/sg-regs.h> @@ -186,7 +187,7 @@ static void vpll_init(void) writel(tmp, SC_VPLL27BCTRL); } -void pll_init(void) +int ph1_sld8_pll_init(const struct uniphier_board_data *bd) { dpll_init(); upll_init(); @@ -198,4 +199,6 @@ void pll_init(void) * so 20 usec can be saved here. */ udelay(480); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-pro4/pll_spectrum.c b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c index fcf2ad282a..cad0ed8cdd 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/pll_spectrum.c +++ b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-ld4.c @@ -4,15 +4,17 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> -void enable_dpll_ssc(void) +int ph1_ld4_enable_dpll_ssc(const struct uniphier_board_data *bd) { u32 tmp; tmp = readl(SC_DPLLCTRL); tmp |= SC_DPLLCTRL_SSC_EN; writel(tmp, SC_DPLLCTRL); + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld3/pll_spectrum.c b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c index fcf2ad282a..43dc973654 100644 --- a/arch/arm/mach-uniphier/ph1-sld3/pll_spectrum.c +++ b/arch/arm/mach-uniphier/pll/pll-spectrum-ph1-sld3.c @@ -6,13 +6,16 @@ #include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sc-regs.h> -void enable_dpll_ssc(void) +int ph1_sld3_enable_dpll_ssc(const struct uniphier_board_data *bd) { u32 tmp; tmp = readl(SC_DPLLCTRL); tmp |= SC_DPLLCTRL_SSC_EN; writel(tmp, SC_DPLLCTRL); + + return 0; } diff --git a/arch/arm/mach-uniphier/print_misc_info.c b/arch/arm/mach-uniphier/print_misc_info.c index 22ea512285..5140b0c438 100644 --- a/arch/arm/mach-uniphier/print_misc_info.c +++ b/arch/arm/mach-uniphier/print_misc_info.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include <mach/board.h> +#include <mach/micro-support-card.h> int misc_init_f(void) { diff --git a/arch/arm/mach-uniphier/sbc/Makefile b/arch/arm/mach-uniphier/sbc/Makefile new file mode 100644 index 0000000000..db622d2034 --- /dev/null +++ b/arch/arm/mach-uniphier/sbc/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD3) += sbc-ph1-sld3.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += sbc-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += sbc-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += sbc-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO5) += sbc-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PROXSTREAM2) += sbc-proxstream2.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD6B) += sbc-proxstream2.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/sbc_init.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c index 8e25792b50..929f50a883 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/sbc_init.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-ld4.c @@ -6,10 +6,11 @@ #include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sbc-regs.h> #include <mach/sg-regs.h> -void sbc_init(void) +int ph1_ld4_sbc_init(const struct uniphier_board_data *bd) { u32 tmp; @@ -30,20 +31,22 @@ void sbc_init(void) if (boot_is_swapped()) { /* * Boot Swap On: boot from external NOR/SRAM - * 0x02000000-0x03ffffff is a mirror of 0x00000000-0x01ffffff. + * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff. * - * 0x00000000-0x01efffff, 0x02000000-0x03efffff: memory bank - * 0x01f00000-0x01ffffff, 0x03f00000-0x03ffffff: peripherals + * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank + * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals */ writel(0x0000bc01, SBBASE0); } else { /* * Boot Swap Off: boot from mask ROM - * 0x00000000-0x01ffffff: mask ROM - * 0x02000000-0x03efffff: memory bank (31MB) - * 0x03f00000-0x03ffffff: peripherals (1MB) + * 0x40000000-0x41ffffff: mask ROM + * 0x42000000-0x43efffff: memory bank (31MB) + * 0x43f00000-0x43ffffff: peripherals (1MB) */ writel(0x0000be01, SBBASE0); /* dummy */ writel(0x0200be01, SBBASE1); } + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-pro4/sbc_init.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c index 533739c364..1032c54e64 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/sbc_init.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-pro4.c @@ -6,10 +6,11 @@ #include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sbc-regs.h> #include <mach/sg-regs.h> -void sbc_init(void) +int ph1_pro4_sbc_init(const struct uniphier_board_data *bd) { /* * Only CS1 is connected to support card. @@ -23,20 +24,22 @@ void sbc_init(void) if (boot_is_swapped()) { /* * Boot Swap On: boot from external NOR/SRAM - * 0x02000000-0x03ffffff is a mirror of 0x00000000-0x01ffffff. + * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff. * - * 0x00000000-0x01efffff, 0x02000000-0x03efffff: memory bank - * 0x01f00000-0x01ffffff, 0x03f00000-0x03ffffff: peripherals + * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank + * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals */ writel(0x0000bc01, SBBASE0); } else { /* * Boot Swap Off: boot from mask ROM - * 0x00000000-0x01ffffff: mask ROM - * 0x02000000-0x03efffff: memory bank (31MB) - * 0x03f00000-0x03ffffff: peripherals (1MB) + * 0x40000000-0x41ffffff: mask ROM + * 0x42000000-0x43efffff: memory bank (31MB) + * 0x43f00000-0x43ffffff: peripherals (1MB) */ writel(0x0000be01, SBBASE0); /* dummy */ writel(0x0200be01, SBBASE1); } + + return 0; } diff --git a/arch/arm/mach-uniphier/ph1-sld3/sbc_init.c b/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c index d66f89ea51..fb707be83a 100644 --- a/arch/arm/mach-uniphier/ph1-sld3/sbc_init.c +++ b/arch/arm/mach-uniphier/sbc/sbc-ph1-sld3.c @@ -6,10 +6,11 @@ #include <common.h> #include <linux/io.h> +#include <mach/init.h> #include <mach/sbc-regs.h> #include <mach/sg-regs.h> -void sbc_init(void) +int ph1_sld3_sbc_init(const struct uniphier_board_data *bd) { /* only address/data multiplex mode is supported */ @@ -24,22 +25,24 @@ void sbc_init(void) if (boot_is_swapped()) { /* * Boot Swap On: boot from external NOR/SRAM - * 0x02000000-0x03ffffff is a mirror of 0x00000000-0x01ffffff. + * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff. * - * 0x00000000-0x01efffff, 0x02000000-0x03efffff: memory bank - * 0x01f00000-0x01ffffff, 0x03f00000-0x03ffffff: peripherals + * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank + * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals */ writel(0x0000bc01, SBBASE0); } else { /* * Boot Swap Off: boot from mask ROM - * 0x00000000-0x01ffffff: mask ROM - * 0x02000000-0x03efffff: memory bank (31MB) - * 0x03f00000-0x03ffffff: peripherals (1MB) + * 0x40000000-0x41ffffff: mask ROM + * 0x42000000-0x43efffff: memory bank (31MB) + * 0x43f00000-0x43ffffff: peripherals (1MB) */ writel(0x0000be01, SBBASE0); /* dummy */ writel(0x0200be01, SBBASE1); } - sg_set_pinsel(99, 1); /* GPIO26 -> EA24 */ + sg_set_pinsel(99, 1, 4, 4); /* GPIO26 -> EA24 */ + + return 0; } diff --git a/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c b/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c new file mode 100644 index 0000000000..9c3aeb7cd0 --- /dev/null +++ b/arch/arm/mach-uniphier/sbc/sbc-proxstream2.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <mach/init.h> +#include <mach/sbc-regs.h> +#include <mach/sg-regs.h> + +int proxstream2_sbc_init(const struct uniphier_board_data *bd) +{ + /* necessary for ROM boot ?? */ + /* system bus output enable */ + writel(0x17, PC0CTRL); + + /* + * Only CS1 is connected to support card. + * BKSZ[1:0] should be set to "01". + */ + writel(SBCTRL0_SAVEPIN_PERI_VALUE, SBCTRL10); + writel(SBCTRL1_SAVEPIN_PERI_VALUE, SBCTRL11); + writel(SBCTRL2_SAVEPIN_PERI_VALUE, SBCTRL12); + writel(SBCTRL4_SAVEPIN_PERI_VALUE, SBCTRL14); + + if (boot_is_swapped()) { + /* + * Boot Swap On: boot from external NOR/SRAM + * 0x42000000-0x43ffffff is a mirror of 0x40000000-0x41ffffff. + * + * 0x40000000-0x41efffff, 0x42000000-0x43efffff: memory bank + * 0x41f00000-0x41ffffff, 0x43f00000-0x43ffffff: peripherals + */ + writel(0x0000bc01, SBBASE0); + } else { + /* + * Boot Swap Off: boot from mask ROM + * 0x40000000-0x41ffffff: mask ROM + * 0x42000000-0x43efffff: memory bank (31MB) + * 0x43f00000-0x43ffffff: peripherals (1MB) + */ + writel(0x0000be01, SBBASE0); /* dummy */ + writel(0x0200be01, SBBASE1); + } + + return 0; +} diff --git a/arch/arm/mach-uniphier/soc_info.c b/arch/arm/mach-uniphier/soc_info.c new file mode 100644 index 0000000000..3e8e7f4ef3 --- /dev/null +++ b/arch/arm/mach-uniphier/soc_info.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/io.h> +#include <linux/types.h> +#include <mach/sg-regs.h> +#include <mach/soc_info.h> + +#if UNIPHIER_MULTI_SOC +enum uniphier_soc_id uniphier_get_soc_type(void) +{ + u32 revision = readl(SG_REVISION); + enum uniphier_soc_id ret; + + switch ((revision & SG_REVISION_TYPE_MASK) >> SG_REVISION_TYPE_SHIFT) { +#ifdef CONFIG_ARCH_UNIPHIER_PH1_SLD3 + case 0x25: + ret = SOC_UNIPHIER_PH1_SLD3; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PH1_LD4 + case 0x26: + ret = SOC_UNIPHIER_PH1_LD4; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PH1_PRO4 + case 0x28: + ret = SOC_UNIPHIER_PH1_PRO4; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PH1_SLD8 + case 0x29: + ret = SOC_UNIPHIER_PH1_SLD8; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PH1_PRO5 + case 0x2A: + ret = SOC_UNIPHIER_PH1_PRO5; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PROXSTREAM2 + case 0x2E: + ret = SOC_UNIPHIER_PROXSTREAM2; + break; +#endif +#ifdef CONFIG_ARCH_UNIPHIER_PH1_LD6B + case 0x2F: + ret = SOC_UNIPHIER_PH1_LD6B; + break; +#endif + default: + ret = SOC_UNIPHIER_UNKNOWN; + break; + } + + return ret; +} +#endif diff --git a/arch/arm/mach-uniphier/spl.c b/arch/arm/mach-uniphier/spl.c deleted file mode 100644 index a34d3a167c..0000000000 --- a/arch/arm/mach-uniphier/spl.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2013-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <spl.h> -#include <linux/compiler.h> -#include <mach/led.h> -#include <mach/board.h> - -void __weak bcu_init(void) -{ -}; -void sbc_init(void); -void sg_init(void); -void pll_init(void); -void pin_init(void); -void memconf_init(void); -void early_clkrst_init(void); -void early_pin_init(void); -int umc_init(void); -void enable_dpll_ssc(void); - -void spl_board_init(void) -{ - bcu_init(); - - sbc_init(); - - sg_init(); - - uniphier_board_reset(); - - pll_init(); - - uniphier_board_init(); - - led_write(L, 0, , ); - - memconf_init(); - - led_write(L, 1, , ); - - early_clkrst_init(); - - led_write(L, 2, , ); - - early_pin_init(); - - led_write(L, 3, , ); - -#ifdef CONFIG_SPL_SERIAL_SUPPORT - preloader_console_init(); -#endif - - led_write(L, 4, , ); - - { - int res; - - res = umc_init(); - if (res < 0) { - while (1) - ; - } - } - led_write(L, 5, , ); - - enable_dpll_ssc(); - - led_write(L, 6, , ); -} diff --git a/arch/arm/mach-uniphier/umc/Makefile b/arch/arm/mach-uniphier/umc/Makefile new file mode 100644 index 0000000000..dd35e77dab --- /dev/null +++ b/arch/arm/mach-uniphier/umc/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ARCH_UNIPHIER_PH1_LD4) += umc-ph1-ld4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_PRO4) += umc-ph1-pro4.o +obj-$(CONFIG_ARCH_UNIPHIER_PH1_SLD8) += umc-ph1-sld8.o diff --git a/arch/arm/mach-uniphier/ph1-ld4/umc_init.c b/arch/arm/mach-uniphier/umc/umc-ph1-ld4.c index a7a4157e79..81246850b3 100644 --- a/arch/arm/mach-uniphier/ph1-ld4/umc_init.c +++ b/arch/arm/mach-uniphier/umc/umc-ph1-ld4.c @@ -5,7 +5,10 @@ */ #include <common.h> +#include <linux/err.h> #include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> #include <mach/umc-regs.h> #include <mach/ddrphy-regs.h> @@ -136,14 +139,14 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); - ddrphy_init(phy0_0, freq, size_ch0); + ph1_ld4_ddrphy_init(phy0_0, freq, size_ch0); ddrphy_prepare_training(phy0_0, 0); ddrphy_training(phy0_0); writel(0x00000101, dramcont1 + UMC_DIOCTLA); - ddrphy_init(phy1_0, freq, size_ch1); + ph1_ld4_ddrphy_init(phy1_0, freq, size_ch1); ddrphy_prepare_training(phy1_0, 1); ddrphy_training(phy1_0); @@ -156,16 +159,17 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) return 0; } -int umc_init(void) +int ph1_ld4_umc_init(const struct uniphier_board_data *bd) { - return umc_init_sub(CONFIG_DDR_FREQ, CONFIG_SDRAM0_SIZE / 0x08000000, - CONFIG_SDRAM1_SIZE / 0x08000000); + if ((bd->dram_ch0_size == SZ_128M || bd->dram_ch0_size == SZ_256M) && + (bd->dram_ch1_size == SZ_128M || bd->dram_ch1_size == SZ_256M) && + (bd->dram_freq == 1333 || bd->dram_freq == 1600) && + bd->dram_ch0_width == 16 && bd->dram_ch1_width == 16) { + return umc_init_sub(bd->dram_freq, + bd->dram_ch0_size / SZ_128M, + bd->dram_ch1_size / SZ_128M); + } else { + pr_err("Unsupported DDR configuration\n"); + return -EINVAL; + } } - -#if (CONFIG_SDRAM0_SIZE == 0x08000000 || CONFIG_SDRAM0_SIZE == 0x10000000) && \ - (CONFIG_SDRAM1_SIZE == 0x08000000 || CONFIG_SDRAM1_SIZE == 0x10000000) && \ - CONFIG_DDR_NUM_CH0 == 1 && CONFIG_DDR_NUM_CH1 == 1 -/* OK */ -#else -#error Unsupported DDR configuration. -#endif diff --git a/arch/arm/mach-uniphier/ph1-pro4/umc_init.c b/arch/arm/mach-uniphier/umc/umc-ph1-pro4.c index bd8b9d83b2..8c9f0579fc 100644 --- a/arch/arm/mach-uniphier/ph1-pro4/umc_init.c +++ b/arch/arm/mach-uniphier/umc/umc-ph1-pro4.c @@ -5,7 +5,10 @@ */ #include <common.h> +#include <linux/err.h> #include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> #include <mach/umc-regs.h> #include <mach/ddrphy-regs.h> @@ -107,28 +110,28 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); - ddrphy_init(phy0_0, freq, size_ch0); + ph1_pro4_ddrphy_init(phy0_0, freq, size_ch0); ddrphy_prepare_training(phy0_0, 0); ddrphy_training(phy0_0); writel(0x00000103, dramcont0 + UMC_DIOCTLA); - ddrphy_init(phy0_1, freq, size_ch0); + ph1_pro4_ddrphy_init(phy0_1, freq, size_ch0); ddrphy_prepare_training(phy0_1, 1); ddrphy_training(phy0_1); writel(0x00000101, dramcont1 + UMC_DIOCTLA); - ddrphy_init(phy1_0, freq, size_ch1); + ph1_pro4_ddrphy_init(phy1_0, freq, size_ch1); ddrphy_prepare_training(phy1_0, 0); ddrphy_training(phy1_0); writel(0x00000103, dramcont1 + UMC_DIOCTLA); - ddrphy_init(phy1_1, freq, size_ch1); + ph1_pro4_ddrphy_init(phy1_1, freq, size_ch1); ddrphy_prepare_training(phy1_1, 1); ddrphy_training(phy1_1); @@ -141,17 +144,18 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) return 0; } -int umc_init(void) +int ph1_pro4_umc_init(const struct uniphier_board_data *bd) { - return umc_init_sub(CONFIG_DDR_FREQ, CONFIG_SDRAM0_SIZE / 0x08000000, - CONFIG_SDRAM1_SIZE / 0x08000000); + if (((bd->dram_ch0_size == SZ_512M && bd->dram_ch0_width == 32) || + (bd->dram_ch0_size == SZ_256M && bd->dram_ch0_width == 16)) && + ((bd->dram_ch1_size == SZ_512M && bd->dram_ch1_width == 32) || + (bd->dram_ch1_size == SZ_256M && bd->dram_ch1_width == 16)) && + bd->dram_freq == 1600) { + return umc_init_sub(bd->dram_freq, + bd->dram_ch0_size / SZ_128M, + bd->dram_ch1_size / SZ_128M); + } else { + pr_err("Unsupported DDR configuration\n"); + return -EINVAL; + } } - -#if ((CONFIG_SDRAM0_SIZE == 0x20000000 && CONFIG_DDR_NUM_CH0 == 2) || \ - (CONFIG_SDRAM0_SIZE == 0x10000000 && CONFIG_DDR_NUM_CH0 == 1)) && \ - ((CONFIG_SDRAM1_SIZE == 0x20000000 && CONFIG_DDR_NUM_CH1 == 2) || \ - (CONFIG_SDRAM1_SIZE == 0x10000000 && CONFIG_DDR_NUM_CH1 == 1)) -/* OK */ -#else - #error Unsupported DDR configuration. -#endif diff --git a/arch/arm/mach-uniphier/ph1-sld8/umc_init.c b/arch/arm/mach-uniphier/umc/umc-ph1-sld8.c index 7baea7e852..bc60a3472e 100644 --- a/arch/arm/mach-uniphier/ph1-sld8/umc_init.c +++ b/arch/arm/mach-uniphier/umc/umc-ph1-sld8.c @@ -5,7 +5,10 @@ */ #include <common.h> +#include <linux/err.h> #include <linux/io.h> +#include <linux/sizes.h> +#include <mach/init.h> #include <mach/umc-regs.h> #include <mach/ddrphy-regs.h> @@ -116,14 +119,14 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); - ddrphy_init(phy0_0, freq, size_ch0); + ph1_sld8_ddrphy_init(phy0_0, freq, size_ch0); ddrphy_prepare_training(phy0_0, 0); ddrphy_training(phy0_0); writel(0x00000101, dramcont1 + UMC_DIOCTLA); - ddrphy_init(phy1_0, freq, size_ch1); + ph1_sld8_ddrphy_init(phy1_0, freq, size_ch1); ddrphy_prepare_training(phy1_0, 1); ddrphy_training(phy1_0); @@ -136,16 +139,17 @@ static int umc_init_sub(int freq, int size_ch0, int size_ch1) return 0; } -int umc_init(void) +int ph1_sld8_umc_init(const struct uniphier_board_data *bd) { - return umc_init_sub(CONFIG_DDR_FREQ, CONFIG_SDRAM0_SIZE / 0x08000000, - CONFIG_SDRAM1_SIZE / 0x08000000); + if ((bd->dram_ch0_size == SZ_128M || bd->dram_ch0_size == SZ_256M) && + (bd->dram_ch1_size == SZ_128M || bd->dram_ch1_size == SZ_256M) && + bd->dram_freq == 1333 && + bd->dram_ch0_width == 16 && bd->dram_ch1_width == 16) { + return umc_init_sub(bd->dram_freq, + bd->dram_ch0_size / SZ_128M, + bd->dram_ch1_size / SZ_128M); + } else { + pr_err("Unsupported DDR configuration\n"); + return -EINVAL; + } } - -#if (CONFIG_SDRAM0_SIZE == 0x08000000 || CONFIG_SDRAM0_SIZE == 0x10000000) && \ - (CONFIG_SDRAM1_SIZE == 0x08000000 || CONFIG_SDRAM1_SIZE == 0x10000000) && \ - CONFIG_DDR_NUM_CH0 == 1 && CONFIG_DDR_NUM_CH1 == 1 -/* OK */ -#else -#error Unsupported DDR configuration. -#endif diff --git a/board/altera/arria5-socdk/MAINTAINERS b/board/altera/arria5-socdk/MAINTAINERS index 30f2477681..ba35b3647f 100644 --- a/board/altera/arria5-socdk/MAINTAINERS +++ b/board/altera/arria5-socdk/MAINTAINERS @@ -1,7 +1,7 @@ SOCFPGA BOARD -M: Dinh Nguyen <dinguyen@altera.com> +M: Dinh Nguyen <dinguyen@opensource.altera.com> M: Chin-Liang See <clsee@altera.com> S: Maintained F: board/altera/arria5-socdk/ -F: include/configs/socfpga_arria5.h +F: include/configs/socfpga_arria5_socdk.h F: configs/socfpga_arria5_defconfig diff --git a/board/altera/cyclone5-socdk/MAINTAINERS b/board/altera/cyclone5-socdk/MAINTAINERS index f218ca411c..6374d592ac 100644 --- a/board/altera/cyclone5-socdk/MAINTAINERS +++ b/board/altera/cyclone5-socdk/MAINTAINERS @@ -1,9 +1,9 @@ SOCFPGA BOARD -M: Dinh Nguyen <dinguyen@altera.com> +M: Dinh Nguyen <dinguyen@opensource.altera.com> M: Chin-Liang See <clsee@altera.com> S: Maintained F: board/altera/cyclone5-socdk/ -F: include/configs/socfpga_cyclone5.h +F: include/configs/socfpga_cyclone5_socdk.h F: configs/socfpga_cyclone5_defconfig SOCRATES BOARD diff --git a/common/Makefile b/common/Makefile index 556fb07592..491c56552f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -214,6 +214,7 @@ obj-$(CONFIG_DFU_TFTP) += update.o obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o obj-$(CONFIG_CMD_DFU) += cmd_dfu.o obj-$(CONFIG_CMD_GPT) += cmd_gpt.o +obj-$(CONFIG_CMD_ETHSW) += cmd_ethsw.o # Power obj-$(CONFIG_CMD_PMIC) += cmd_pmic.o diff --git a/common/cmd_ethsw.c b/common/cmd_ethsw.c new file mode 100644 index 0000000000..8e452e95be --- /dev/null +++ b/common/cmd_ethsw.c @@ -0,0 +1,1027 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Ethernet Switch commands + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <env_flags.h> +#include <ethsw.h> + +static const char *ethsw_name; + +#define ETHSW_PORT_STATS_HELP "ethsw [port <port_no>] statistics " \ +"{ [help] | [clear] } - show an l2 switch port's statistics" + +static int ethsw_port_stats_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_PORT_STATS_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_LEARN_HELP "ethsw [port <port_no>] learning " \ +"{ [help] | show | auto | disable } " \ +"- enable/disable/show learning configuration on a port" + +static int ethsw_learn_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_LEARN_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_FDB_HELP "ethsw [port <port_no>] [vlan <vid>] fdb " \ +"{ [help] | show | flush | { add | del } <mac> } " \ +"- Add/delete a mac entry in FDB; use show to see FDB entries; " \ +"if vlan <vid> is missing, VID 1 will be used" + +static int ethsw_fdb_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_FDB_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_PVID_HELP "ethsw [port <port_no>] " \ +"pvid { [help] | show | <pvid> } " \ +"- set/show PVID (ingress and egress VLAN tagging) for a port" + +static int ethsw_pvid_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_PVID_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_VLAN_HELP "ethsw [port <port_no>] vlan " \ +"{ [help] | show | add <vid> | del <vid> } " \ +"- add a VLAN to a port (VLAN members)" + +static int ethsw_vlan_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_VLAN_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_PORT_UNTAG_HELP "ethsw [port <port_no>] untagged " \ +"{ [help] | show | all | none | pvid } " \ +" - set egress tagging mod for a port" + +static int ethsw_port_untag_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_PORT_UNTAG_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_EGR_VLAN_TAG_HELP "ethsw [port <port_no>] egress tag " \ +"{ [help] | show | pvid | classified } " \ +"- Configure VID source for egress tag. " \ +"Tag's VID could be the frame's classified VID or the PVID of the port" + +static int ethsw_egr_tag_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_EGR_VLAN_TAG_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_VLAN_FDB_HELP "ethsw vlan fdb " \ +"{ [help] | show | shared | private } " \ +"- make VLAN learning shared or private" + +static int ethsw_vlan_learn_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_VLAN_FDB_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +#define ETHSW_PORT_INGR_FLTR_HELP "ethsw [port <port_no>] ingress filtering" \ +" { [help] | show | enable | disable } " \ +"- enable/disable VLAN ingress filtering on port" + +static int ethsw_ingr_fltr_help_key_func(struct ethsw_command_def *parsed_cmd) +{ + printf(ETHSW_PORT_INGR_FLTR_HELP"\n"); + + return CMD_RET_SUCCESS; +} + +static struct keywords_to_function { + enum ethsw_keyword_id cmd_keyword[ETHSW_MAX_CMD_PARAMS]; + int cmd_func_offset; + int (*keyword_function)(struct ethsw_command_def *parsed_cmd); +} ethsw_cmd_def[] = { + { + .cmd_keyword = { + ethsw_id_enable, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_enable), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_disable, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_disable), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_statistics, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_port_stats_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_statistics, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_stats), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_statistics, + ethsw_id_clear, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_stats_clear), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_learning, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_learn_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_learning, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_learn_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_learning, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_learn_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_learning, + ethsw_id_auto, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_learn), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_learning, + ethsw_id_disable, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_learn), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_fdb_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_fdb_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + fdb_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_flush, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + fdb_flush), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_add, + ethsw_id_add_del_mac, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + fdb_entry_add), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_fdb, + ethsw_id_del, + ethsw_id_add_del_mac, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + fdb_entry_del), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_pvid, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_pvid_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_pvid, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_pvid_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_pvid, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + pvid_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_pvid, + ethsw_id_pvid_no, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + pvid_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_vlan_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_vlan_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_add, + ethsw_id_add_del_no, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_del, + ethsw_id_add_del_no, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_port_untag_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_port_untag_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_untag_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_all, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_untag_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_none, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_untag_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_untagged, + ethsw_id_pvid, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_untag_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_egr_tag_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_egr_tag_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_egr_vlan_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_pvid, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_egr_vlan_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_classified, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_egr_vlan_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_vlan_learn_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_vlan_learn_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_learn_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_shared, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_learn_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_private, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + vlan_learn_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_ingr_fltr_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_help, + ethsw_id_key_end, + }, + .cmd_func_offset = -1, + .keyword_function = ðsw_ingr_fltr_help_key_func, + }, { + .cmd_keyword = { + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_show, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_ingr_filt_show), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_enable, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_ingr_filt_set), + .keyword_function = NULL, + }, { + .cmd_keyword = { + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_disable, + ethsw_id_key_end, + }, + .cmd_func_offset = offsetof(struct ethsw_command_func, + port_ingr_filt_set), + .keyword_function = NULL, + }, +}; + +struct keywords_optional { + int cmd_keyword[ETHSW_MAX_CMD_PARAMS]; +} cmd_opt_def[] = { + { + .cmd_keyword = { + ethsw_id_port, + ethsw_id_port_no, + ethsw_id_key_end, + }, + }, { + .cmd_keyword = { + ethsw_id_vlan, + ethsw_id_vlan_no, + ethsw_id_key_end, + }, + }, { + .cmd_keyword = { + ethsw_id_port, + ethsw_id_port_no, + ethsw_id_vlan, + ethsw_id_vlan_no, + ethsw_id_key_end, + }, + }, +}; + +static int keyword_match_gen(enum ethsw_keyword_id key_id, int argc, char + *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd); +static int keyword_match_port(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd); +static int keyword_match_vlan(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd); +static int keyword_match_pvid(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd); +static int keyword_match_mac_addr(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd); + +/* + * Define properties for each keyword; + * keep the order synced with enum ethsw_keyword_id + */ +struct keyword_def { + const char *keyword_name; + int (*match)(enum ethsw_keyword_id key_id, int argc, char *const argv[], + int *argc_nr, struct ethsw_command_def *parsed_cmd); +} keyword[] = { + { + .keyword_name = "help", + .match = &keyword_match_gen, + }, { + .keyword_name = "show", + .match = &keyword_match_gen, + }, { + .keyword_name = "port", + .match = &keyword_match_port + }, { + .keyword_name = "enable", + .match = &keyword_match_gen, + }, { + .keyword_name = "disable", + .match = &keyword_match_gen, + }, { + .keyword_name = "statistics", + .match = &keyword_match_gen, + }, { + .keyword_name = "clear", + .match = &keyword_match_gen, + }, { + .keyword_name = "learning", + .match = &keyword_match_gen, + }, { + .keyword_name = "auto", + .match = &keyword_match_gen, + }, { + .keyword_name = "vlan", + .match = &keyword_match_vlan, + }, { + .keyword_name = "fdb", + .match = &keyword_match_gen, + }, { + .keyword_name = "add", + .match = &keyword_match_mac_addr, + }, { + .keyword_name = "del", + .match = &keyword_match_mac_addr, + }, { + .keyword_name = "flush", + .match = &keyword_match_gen, + }, { + .keyword_name = "pvid", + .match = &keyword_match_pvid, + }, { + .keyword_name = "untagged", + .match = &keyword_match_gen, + }, { + .keyword_name = "all", + .match = &keyword_match_gen, + }, { + .keyword_name = "none", + .match = &keyword_match_gen, + }, { + .keyword_name = "egress", + .match = &keyword_match_gen, + }, { + .keyword_name = "tag", + .match = &keyword_match_gen, + }, { + .keyword_name = "classified", + .match = &keyword_match_gen, + }, { + .keyword_name = "shared", + .match = &keyword_match_gen, + }, { + .keyword_name = "private", + .match = &keyword_match_gen, + }, { + .keyword_name = "ingress", + .match = &keyword_match_gen, + }, { + .keyword_name = "filtering", + .match = &keyword_match_gen, + }, +}; + +/* + * Function used by an Ethernet Switch driver to set the functions + * that must be called by the parser when an ethsw command is given + */ +int ethsw_define_functions(const struct ethsw_command_func *cmd_func) +{ + int i; + void **aux_p; + int (*cmd_func_aux)(struct ethsw_command_def *); + + if (!cmd_func->ethsw_name) + return -EINVAL; + + ethsw_name = cmd_func->ethsw_name; + + for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { + /* + * get the pointer to the function send by the Ethernet Switch + * driver that corresponds to the proper ethsw command + */ + if (ethsw_cmd_def[i].keyword_function) + continue; + + aux_p = (void *)cmd_func + ethsw_cmd_def[i].cmd_func_offset; + + cmd_func_aux = (int (*)(struct ethsw_command_def *)) *aux_p; + ethsw_cmd_def[i].keyword_function = cmd_func_aux; + } + + return 0; +} + +/* Generic function used to match a keyword only by a string */ +static int keyword_match_gen(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd) +{ + if (strcmp(argv[*argc_nr], keyword[key_id].keyword_name) == 0) { + parsed_cmd->cmd_to_keywords[*argc_nr] = key_id; + + return 1; + } + return 0; +} + +/* Function used to match the command's port */ +static int keyword_match_port(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd) +{ + unsigned long val; + + if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) + return 0; + + if (*argc_nr + 1 >= argc) + return 0; + + if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) { + parsed_cmd->port = val; + (*argc_nr)++; + parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_port_no; + return 1; + } + + return 0; +} + +/* Function used to match the command's vlan */ +static int keyword_match_vlan(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd) +{ + unsigned long val; + int aux; + + if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) + return 0; + + if (*argc_nr + 1 >= argc) + return 0; + + if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) { + parsed_cmd->vid = val; + (*argc_nr)++; + parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_vlan_no; + return 1; + } + + aux = *argc_nr + 1; + + if (keyword_match_gen(ethsw_id_add, argc, argv, &aux, parsed_cmd)) + parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_add; + else if (keyword_match_gen(ethsw_id_del, argc, argv, &aux, parsed_cmd)) + parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_del; + else + return 0; + + if (*argc_nr + 2 >= argc) + return 0; + + if (strict_strtoul(argv[*argc_nr + 2], 10, &val) != -EINVAL) { + parsed_cmd->vid = val; + (*argc_nr) += 2; + parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_add_del_no; + return 1; + } + + return 0; +} + +/* Function used to match the command's pvid */ +static int keyword_match_pvid(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd) +{ + unsigned long val; + + if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) + return 0; + + if (*argc_nr + 1 >= argc) + return 1; + + if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) { + parsed_cmd->vid = val; + (*argc_nr)++; + parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_pvid_no; + } + + return 1; +} + +/* Function used to match the command's MAC address */ +static int keyword_match_mac_addr(enum ethsw_keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct ethsw_command_def *parsed_cmd) +{ + if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) + return 0; + + if ((*argc_nr + 1 >= argc) || + !is_broadcast_ethaddr(parsed_cmd->ethaddr)) + return 1; + + if (eth_validate_ethaddr_str(argv[*argc_nr + 1])) { + printf("Invalid MAC address: %s\n", argv[*argc_nr + 1]); + return 0; + } + + eth_parse_enetaddr(argv[*argc_nr + 1], parsed_cmd->ethaddr); + + if (is_broadcast_ethaddr(parsed_cmd->ethaddr)) { + memset(parsed_cmd->ethaddr, 0xFF, sizeof(parsed_cmd->ethaddr)); + return 0; + } + + parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_add_del_mac; + + return 1; +} + +/* Finds optional keywords and modifies *argc_va to skip them */ +static void cmd_keywords_opt_check(const struct ethsw_command_def *parsed_cmd, + int *argc_val) +{ + int i; + int keyw_opt_matched; + int argc_val_max; + int const *cmd_keyw_p; + int const *cmd_keyw_opt_p; + + /* remember the best match */ + argc_val_max = *argc_val; + + /* + * check if our command's optional keywords match the optional + * keywords of an available command + */ + for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { + keyw_opt_matched = 0; + cmd_keyw_p = &parsed_cmd->cmd_to_keywords[keyw_opt_matched]; + cmd_keyw_opt_p = &cmd_opt_def[i].cmd_keyword[keyw_opt_matched]; + + /* + * increase the number of keywords that + * matched with a command + */ + while (keyw_opt_matched + *argc_val < + parsed_cmd->cmd_keywords_nr && + *cmd_keyw_opt_p != ethsw_id_key_end && + *(cmd_keyw_p + *argc_val) == *cmd_keyw_opt_p) { + keyw_opt_matched++; + cmd_keyw_p++; + cmd_keyw_opt_p++; + } + + /* + * if all our optional command's keywords perfectly match an + * optional pattern, then we can move to the next defined + * keywords in our command; remember the one that matched the + * greatest number of keywords + */ + if (keyw_opt_matched + *argc_val <= + parsed_cmd->cmd_keywords_nr && + *cmd_keyw_opt_p == ethsw_id_key_end && + *argc_val + keyw_opt_matched > argc_val_max) + argc_val_max = *argc_val + keyw_opt_matched; + } + + *argc_val = argc_val_max; +} + +/* + * Finds the function to call based on keywords and + * modifies *argc_va to skip them + */ +static void cmd_keywords_check(struct ethsw_command_def *parsed_cmd, + int *argc_val) +{ + int i; + int keyw_matched; + int *cmd_keyw_p; + int *cmd_keyw_def_p; + + /* + * check if our command's keywords match the + * keywords of an available command + */ + for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { + keyw_matched = 0; + cmd_keyw_p = &parsed_cmd->cmd_to_keywords[keyw_matched]; + cmd_keyw_def_p = ðsw_cmd_def[i].cmd_keyword[keyw_matched]; + + /* + * increase the number of keywords that + * matched with a command + */ + while (keyw_matched + *argc_val < parsed_cmd->cmd_keywords_nr && + *cmd_keyw_def_p != ethsw_id_key_end && + *(cmd_keyw_p + *argc_val) == *cmd_keyw_def_p) { + keyw_matched++; + cmd_keyw_p++; + cmd_keyw_def_p++; + } + + /* + * if all our command's keywords perfectly match an + * available command, then we get the function we need to call + * to configure the Ethernet Switch + */ + if (keyw_matched && keyw_matched + *argc_val == + parsed_cmd->cmd_keywords_nr && + *cmd_keyw_def_p == ethsw_id_key_end) { + *argc_val += keyw_matched; + parsed_cmd->cmd_function = + ethsw_cmd_def[i].keyword_function; + return; + } + } +} + +/* find all the keywords in the command */ +static int keywords_find(int argc, char * const argv[], + struct ethsw_command_def *parsed_cmd) +{ + int i; + int j; + int argc_val; + int rc = CMD_RET_SUCCESS; + + for (i = 1; i < argc; i++) { + for (j = 0; j < ethsw_id_count; j++) { + if (keyword[j].match(j, argc, argv, &i, parsed_cmd)) + break; + } + } + + /* if there is no keyword match for a word, the command is invalid */ + for (i = 1; i < argc; i++) + if (parsed_cmd->cmd_to_keywords[i] == ethsw_id_key_end) + rc = CMD_RET_USAGE; + + parsed_cmd->cmd_keywords_nr = argc; + argc_val = 1; + + /* get optional parameters first */ + cmd_keywords_opt_check(parsed_cmd, &argc_val); + + if (argc_val == parsed_cmd->cmd_keywords_nr) + return CMD_RET_USAGE; + + /* + * check the keywords and if a match is found, + * get the function to call + */ + cmd_keywords_check(parsed_cmd, &argc_val); + + /* error if not all commands' parameters were matched */ + if (argc_val == parsed_cmd->cmd_keywords_nr) { + if (!parsed_cmd->cmd_function) { + printf("Command not available for: %s\n", ethsw_name); + rc = CMD_RET_FAILURE; + } + } else { + rc = CMD_RET_USAGE; + } + + return rc; +} + +static void command_def_init(struct ethsw_command_def *parsed_cmd) +{ + int i; + + for (i = 0; i < ETHSW_MAX_CMD_PARAMS; i++) + parsed_cmd->cmd_to_keywords[i] = ethsw_id_key_end; + + parsed_cmd->port = ETHSW_CMD_PORT_ALL; + parsed_cmd->vid = ETHSW_CMD_VLAN_ALL; + parsed_cmd->cmd_function = NULL; + + /* We initialize the MAC address with the Broadcast address */ + memset(parsed_cmd->ethaddr, 0xff, sizeof(parsed_cmd->ethaddr)); +} + +/* function to interpret commands starting with "ethsw " */ +static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct ethsw_command_def parsed_cmd; + int rc = CMD_RET_SUCCESS; + + if (argc == 1 || argc >= ETHSW_MAX_CMD_PARAMS) + return CMD_RET_USAGE; + + command_def_init(&parsed_cmd); + + rc = keywords_find(argc, argv, &parsed_cmd); + + if (rc == CMD_RET_SUCCESS) + rc = parsed_cmd.cmd_function(&parsed_cmd); + + return rc; +} + +#define ETHSW_PORT_CONF_HELP "[port <port_no>] { enable | disable | show } " \ +"- enable/disable a port; show shows a port's configuration" + +U_BOOT_CMD(ethsw, ETHSW_MAX_CMD_PARAMS, 0, do_ethsw, + "Ethernet l2 switch commands", + ETHSW_PORT_CONF_HELP"\n" + ETHSW_PORT_STATS_HELP"\n" + ETHSW_LEARN_HELP"\n" + ETHSW_FDB_HELP"\n" + ETHSW_PVID_HELP"\n" + ETHSW_VLAN_HELP"\n" + ETHSW_PORT_UNTAG_HELP"\n" + ETHSW_EGR_VLAN_TAG_HELP"\n" + ETHSW_VLAN_FDB_HELP"\n" + ETHSW_PORT_INGR_FLTR_HELP"\n" +); diff --git a/common/env_flags.c b/common/env_flags.c index 5189f5b2dd..e682d85178 100644 --- a/common/env_flags.c +++ b/common/env_flags.c @@ -187,6 +187,31 @@ static void skip_num(int hex, const char *value, const char **end, *end = value; } +#ifdef CONFIG_CMD_NET +int eth_validate_ethaddr_str(const char *addr) +{ + const char *end; + const char *cur; + int i; + + cur = addr; + for (i = 0; i < 6; i++) { + skip_num(1, cur, &end, 2); + if (cur == end) + return -1; + if (cur + 2 == end && is_hex_prefix(cur)) + return -1; + if (i != 5 && *end != ':') + return -1; + if (i == 5 && *end != '\0') + return -1; + cur = end + 1; + } + + return 0; +} +#endif + /* * Based on the declared type enum, validate that the value string complies * with that format @@ -239,19 +264,8 @@ static int _env_flags_validate_type(const char *value, } break; case env_flags_vartype_macaddr: - cur = value; - for (i = 0; i < 6; i++) { - skip_num(1, cur, &end, 2); - if (cur == end) - return -1; - if (cur + 2 == end && is_hex_prefix(cur)) - return -1; - if (i != 5 && *end != ':') - return -1; - if (i == 5 && *end != '\0') - return -1; - cur = end + 1; - } + if (eth_validate_ethaddr_str(value)) + return -1; break; #endif case env_flags_vartype_end: diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index 56c215fe37..e1665c090c 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -1,7 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_MACH_PH1_LD4=y -CONFIG_PFC_MICRO_SUPPORT_CARD=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_UNIPHIER_PH1_LD4=y +CONFIG_MICRO_SUPPORT_CARD=y CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld4-ref" CONFIG_HUSH_PARSER=y @@ -11,17 +12,19 @@ CONFIG_CMD_NAND=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y # CONFIG_CMD_FPGA is not set -# CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TFTPPUT=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_SIMPLE_BUS=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_SPL_NAND_DENALI=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/ph1_ld6b_defconfig b/configs/ph1_ld6b_defconfig new file mode 100644 index 0000000000..68f6ba847b --- /dev/null +++ b/configs/ph1_ld6b_defconfig @@ -0,0 +1,30 @@ +CONFIG_ARM=y +CONFIG_ARCH_UNIPHIER=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_UNIPHIER_PH1_LD6B=y +CONFIG_MICRO_SUPPORT_CARD=y +CONFIG_SYS_TEXT_BASE=0x84000000 +CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld6b-ref" +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_ENV_EXISTS is not set +CONFIG_CMD_NAND=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_PING=y +CONFIG_CMD_TIME=y +# CONFIG_CMD_MISC is not set +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_SIMPLE_BUS=y +CONFIG_NAND_DENALI=y +CONFIG_SYS_NAND_DENALI_64BIT=y +CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 +CONFIG_SPL_NAND_DENALI=y +CONFIG_UNIPHIER_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 7624c547f6..aaf1f46038 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -1,6 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_PFC_MICRO_SUPPORT_CARD=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_UNIPHIER_PH1_PRO4=y +CONFIG_MICRO_SUPPORT_CARD=y CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro4-ref" CONFIG_HUSH_PARSER=y @@ -10,17 +12,19 @@ CONFIG_CMD_NAND=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y # CONFIG_CMD_FPGA is not set -# CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TFTPPUT=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_SIMPLE_BUS=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_SPL_NAND_DENALI=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/ph1_pro5_defconfig b/configs/ph1_pro5_defconfig new file mode 100644 index 0000000000..967d0f100b --- /dev/null +++ b/configs/ph1_pro5_defconfig @@ -0,0 +1,30 @@ +CONFIG_ARM=y +CONFIG_ARCH_UNIPHIER=y +CONFIG_ARCH_UNIPHIER_PH1_PRO5=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_MICRO_SUPPORT_CARD=y +CONFIG_SYS_TEXT_BASE=0x84000000 +CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro5-4kbox" +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_ENV_EXISTS is not set +CONFIG_CMD_NAND=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_PING=y +CONFIG_CMD_TIME=y +# CONFIG_CMD_MISC is not set +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_SIMPLE_BUS=y +CONFIG_NAND_DENALI=y +CONFIG_SYS_NAND_DENALI_64BIT=y +CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 +CONFIG_SPL_NAND_DENALI=y +CONFIG_UNIPHIER_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y diff --git a/configs/ph1_sld3_defconfig b/configs/ph1_sld3_defconfig index d49513251e..4b871d0ebd 100644 --- a/configs/ph1_sld3_defconfig +++ b/configs/ph1_sld3_defconfig @@ -1,7 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_MACH_PH1_SLD3=y -CONFIG_PFC_MICRO_SUPPORT_CARD=y +CONFIG_ARCH_UNIPHIER_PH1_SLD3=y +CONFIG_MICRO_SUPPORT_CARD=y CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld3-ref" CONFIG_HUSH_PARSER=y @@ -11,7 +11,6 @@ CONFIG_CMD_NAND=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y # CONFIG_CMD_FPGA is not set -# CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TFTPPUT=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 1a35a77f67..00917fbc51 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -1,7 +1,8 @@ CONFIG_ARM=y CONFIG_ARCH_UNIPHIER=y -CONFIG_MACH_PH1_SLD8=y -CONFIG_PFC_MICRO_SUPPORT_CARD=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_ARCH_UNIPHIER_PH1_SLD8=y +CONFIG_MICRO_SUPPORT_CARD=y CONFIG_SYS_TEXT_BASE=0x84000000 CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld8-ref" CONFIG_HUSH_PARSER=y @@ -11,17 +12,19 @@ CONFIG_CMD_NAND=y CONFIG_CMD_I2C=y CONFIG_CMD_USB=y # CONFIG_CMD_FPGA is not set -# CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TFTPPUT=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_SIMPLE_BUS=y CONFIG_NAND_DENALI=y CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_SPL_NAND_DENALI=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/doc/README.uniphier b/doc/README.uniphier index e936f40254..6ba0320f4f 100644 --- a/doc/README.uniphier +++ b/doc/README.uniphier @@ -44,6 +44,18 @@ PH1-sLD8: $ make ph1_sld8_defconfig $ make CROSS_COMPILE=arm-linux-gnueabi- +PH1-Pro5: + $ make ph1_pro5_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + +ProXstream2: + $ make pxs2_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + +PH1-LD6b: + $ make ph1_ld6b_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + You may wish to change the "CROSS_COMPILE=arm-linux-gnueabi-" to use your favorite compiler. diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c index fed7358448..7595db1acb 100644 --- a/drivers/net/vsc9953.c +++ b/drivers/net/vsc9953.c @@ -1,5 +1,5 @@ /* - * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2014 - 2015 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ * @@ -10,7 +10,11 @@ #include <asm/fsl_serdes.h> #include <fm_eth.h> #include <fsl_memac.h> +#include <bitfield.h> +#include <errno.h> +#include <malloc.h> #include <vsc9953.h> +#include <ethsw.h> static struct vsc9953_info vsc9953_l2sw = { .port[0] = VSC9953_PORT_INFO_INITIALIZER(0), @@ -25,50 +29,50 @@ static struct vsc9953_info vsc9953_l2sw = { .port[9] = VSC9953_PORT_INFO_INITIALIZER(9), }; -void vsc9953_port_info_set_mdio(int port, struct mii_dev *bus) +void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus) { - if (!VSC9953_PORT_CHECK(port)) + if (!VSC9953_PORT_CHECK(port_no)) return; - vsc9953_l2sw.port[port].bus = bus; + vsc9953_l2sw.port[port_no].bus = bus; } -void vsc9953_port_info_set_phy_address(int port, int address) +void vsc9953_port_info_set_phy_address(int port_no, int address) { - if (!VSC9953_PORT_CHECK(port)) + if (!VSC9953_PORT_CHECK(port_no)) return; - vsc9953_l2sw.port[port].phyaddr = address; + vsc9953_l2sw.port[port_no].phyaddr = address; } -void vsc9953_port_info_set_phy_int(int port, phy_interface_t phy_int) +void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int) { - if (!VSC9953_PORT_CHECK(port)) + if (!VSC9953_PORT_CHECK(port_no)) return; - vsc9953_l2sw.port[port].enet_if = phy_int; + vsc9953_l2sw.port[port_no].enet_if = phy_int; } -void vsc9953_port_enable(int port) +void vsc9953_port_enable(int port_no) { - if (!VSC9953_PORT_CHECK(port)) + if (!VSC9953_PORT_CHECK(port_no)) return; - vsc9953_l2sw.port[port].enabled = 1; + vsc9953_l2sw.port[port_no].enabled = 1; } -void vsc9953_port_disable(int port) +void vsc9953_port_disable(int port_no) { - if (!VSC9953_PORT_CHECK(port)) + if (!VSC9953_PORT_CHECK(port_no)) return; - vsc9953_l2sw.port[port].enabled = 0; + vsc9953_l2sw.port[port_no].enabled = 0; } static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr, int regnum, int value) { - int timeout = 50000; + int timeout = 50000; out_le32(&phyregs->miimcmd, (0x1 << 31) | ((port_addr & 0x1f) << 25) | ((regnum & 0x1f) << 20) | ((value & 0xffff) << 4) | @@ -85,8 +89,8 @@ static void vsc9953_mdio_write(struct vsc9953_mii_mng *phyregs, int port_addr, static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr, int regnum) { - int value = 0xFFFF; - int timeout = 50000; + int value = 0xFFFF; + int timeout = 50000; while ((in_le32(&phyregs->miimstatus) & MIIMIND_OPR_PEND) && --timeout) udelay(1); @@ -120,8 +124,8 @@ static int vsc9953_mdio_read(struct vsc9953_mii_mng *phyregs, int port_addr, static int init_phy(struct eth_device *dev) { - struct vsc9953_port_info *l2sw_port = dev->priv; - struct phy_device *phydev = NULL; + struct vsc9953_port_info *l2sw_port = dev->priv; + struct phy_device *phydev = NULL; #ifdef CONFIG_PHYLIB if (!l2sw_port->bus) @@ -148,21 +152,21 @@ static int init_phy(struct eth_device *dev) return 0; } -static int vsc9953_port_init(int port) +static int vsc9953_port_init(int port_no) { - struct eth_device *dev; + struct eth_device *dev; /* Internal ports never have a PHY */ - if (VSC9953_INTERNAL_PORT_CHECK(port)) + if (VSC9953_INTERNAL_PORT_CHECK(port_no)) return 0; /* alloc eth device */ dev = (struct eth_device *)calloc(1, sizeof(struct eth_device)); if (!dev) - return 1; + return -ENOMEM; - sprintf(dev->name, "SW@PORT%d", port); - dev->priv = &vsc9953_l2sw.port[port]; + sprintf(dev->name, "SW@PORT%d", port_no); + dev->priv = &vsc9953_l2sw.port[port_no]; dev->init = NULL; dev->halt = NULL; dev->send = NULL; @@ -170,225 +174,485 @@ static int vsc9953_port_init(int port) if (init_phy(dev)) { free(dev); - return 1; + return -ENODEV; } return 0; } -void vsc9953_init(bd_t *bis) +static int vsc9953_vlan_table_poll_idle(void) { - u32 i, hdx_cfg = 0, phy_addr = 0; - int timeout; - struct vsc9953_system_reg *l2sys_reg; - struct vsc9953_qsys_reg *l2qsys_reg; - struct vsc9953_dev_gmii *l2dev_gmii_reg; - struct vsc9953_analyzer *l2ana_reg; - struct vsc9953_devcpu_gcb *l2dev_gcb; + struct vsc9953_analyzer *l2ana_reg; + int timeout; - l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET + - VSC9953_DEV_GMII_OFFSET); + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + timeout = 50000; + while (((in_le32(&l2ana_reg->ana_tables.vlan_access) & + VSC9953_VLAN_CMD_MASK) != VSC9953_VLAN_CMD_IDLE) && --timeout) + udelay(1); + + return timeout ? 0 : -EBUSY; +} + +#ifdef CONFIG_CMD_ETHSW +/* Add/remove a port to/from a VLAN */ +static void vsc9953_vlan_table_membership_set(int vid, u32 port_no, u8 add) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + VSC9953_ANA_OFFSET); - l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + - VSC9953_SYS_OFFSET); + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; + } - l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + - VSC9953_QSYS_OFFSET); + val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); + val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid); + out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); - l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET + - VSC9953_DEVCPU_GCB); + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); - out_le32(&l2dev_gcb->chip_regs.soft_rst, - CONFIG_VSC9953_SOFT_SWC_RST_ENA); - timeout = 50000; - while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) & - CONFIG_VSC9953_SOFT_SWC_RST_ENA) && --timeout) - udelay(1); /* busy wait for vsc9953 soft reset */ - if (timeout == 0) - debug("Timeout waiting for VSC9953 to reset\n"); + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; + } - out_le32(&l2sys_reg->sys.reset_cfg, CONFIG_VSC9953_MEM_ENABLE | - CONFIG_VSC9953_MEM_INIT); + val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); + val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid); + out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); + + val = in_le32(&l2ana_reg->ana_tables.vlan_access); + if (!add) { + val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK, + VSC9953_VLAN_CMD_WRITE) & + ~(bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK, + (1 << port_no))); + ; + } else { + val = bitfield_replace_by_mask(val, VSC9953_VLAN_CMD_MASK, + VSC9953_VLAN_CMD_WRITE) | + bitfield_replace_by_mask(0, VSC9953_VLAN_PORT_MASK, + (1 << port_no)); + } + out_le32(&l2ana_reg->ana_tables.vlan_access, val); - timeout = 50000; - while ((in_le32(&l2sys_reg->sys.reset_cfg) & - CONFIG_VSC9953_MEM_INIT) && --timeout) - udelay(1); /* busy wait for vsc9953 memory init */ - if (timeout == 0) - debug("Timeout waiting for VSC9953 memory to initialize\n"); + /* wait for VLAN table command to flush */ + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; + } +} - out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg) - | CONFIG_VSC9953_CORE_ENABLE)); +/* show VLAN membership for a port */ +static void vsc9953_vlan_membership_show(int port_no) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + u32 vid; - /* VSC9953 Setting to be done once only */ - out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00); + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); - for (i = 0; i < VSC9953_MAX_PORTS; i++) { - if (vsc9953_port_init(i)) - printf("Failed to initialize l2switch port %d\n", i); + printf("Port %d VLAN membership: ", port_no); - /* Enable VSC9953 GMII Ports Port ID 0 - 7 */ - if (VSC9953_INTERNAL_PORT_CHECK(i)) { - out_le32(&l2ana_reg->pfc[i].pfc_cfg, - CONFIG_VSC9953_PFC_FC_QSGMII); - out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], - CONFIG_VSC9953_MAC_FC_CFG_QSGMII); - } else { - out_le32(&l2ana_reg->pfc[i].pfc_cfg, - CONFIG_VSC9953_PFC_FC); - out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], - CONFIG_VSC9953_MAC_FC_CFG); + for (vid = 0; vid < VSC9953_MAX_VLAN; vid++) { + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; } - out_le32(&l2dev_gmii_reg->port_mode.clock_cfg, - CONFIG_VSC9953_CLOCK_CFG); - out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg, - CONFIG_VSC9953_MAC_ENA_CFG); - out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg, - CONFIG_VSC9953_MAC_MODE_CFG); - out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg, - CONFIG_VSC9953_MAC_IFG_CFG); - /* mac_hdx_cfg varies with port id*/ - hdx_cfg = (CONFIG_VSC9953_MAC_HDX_CFG | (i << 16)); - out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg); - out_le32(&l2sys_reg->sys.front_port_mode[i], - CONFIG_VSC9953_FRONT_PORT_MODE); - out_le32(&l2qsys_reg->sys.switch_port_mode[i], - CONFIG_VSC9953_PORT_ENA); - out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg, - CONFIG_VSC9953_MAC_MAX_LEN); - out_le32(&l2sys_reg->pause_cfg.pause_cfg[i], - CONFIG_VSC9953_PAUSE_CFG); - /* WAIT FOR 2 us*/ - udelay(2); - l2dev_gmii_reg = (struct vsc9953_dev_gmii *)( - (char *)l2dev_gmii_reg - + T1040_SWITCH_GMII_DEV_OFFSET); + val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); + val = bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, + vid); + out_le32(&l2ana_reg->ana_tables.vlan_tidx, val); - /* Initialize Lynx PHY Wrappers */ - phy_addr = 0; - if (vsc9953_l2sw.port[i].enet_if == - PHY_INTERFACE_MODE_QSGMII) - phy_addr = (i + 0x4) & 0x1F; - else if (vsc9953_l2sw.port[i].enet_if == - PHY_INTERFACE_MODE_SGMII) - phy_addr = (i + 1) & 0x1F; - - if (phy_addr) { - /* SGMII IF mode + AN enable */ - vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, - 0x14, PHY_SGMII_IF_MODE_AN | - PHY_SGMII_IF_MODE_SGMII); - /* Dev ability according to SGMII specification */ - vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, - 0x4, PHY_SGMII_DEV_ABILITY_SGMII); - /* Adjust link timer for SGMII - * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 - */ - vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, - 0x13, 0x0003); - vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, - 0x12, 0x0d40); - /* Restart AN */ - vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, - 0x0, PHY_SGMII_CR_DEF_VAL | - PHY_SGMII_CR_RESET_AN); + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); - timeout = 50000; - while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0], - phy_addr, 0x01) & 0x0020) && --timeout) - udelay(1); /* wait for AN to complete */ - if (timeout == 0) - debug("Timeout waiting for AN to complete\n"); + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; } + + val = in_le32(&l2ana_reg->ana_tables.vlan_access); + + if (bitfield_extract_by_mask(val, VSC9953_VLAN_PORT_MASK) & + (1 << port_no)) + printf("%d ", vid); } + printf("\n"); +} +#endif - printf("VSC9953 L2 switch initialized\n"); - return; +/* vlan table set/clear all membership of vid */ +static void vsc9953_vlan_table_membership_all_set(int vid, int set_member) +{ + uint val; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; + } + + /* read current vlan configuration */ + val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); + out_le32(&l2ana_reg->ana_tables.vlan_tidx, + bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); + + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + VSC9953_VLAN_CMD_MASK, VSC9953_VLAN_CMD_READ); + + if (vsc9953_vlan_table_poll_idle() < 0) { + debug("VLAN table timeout\n"); + return; + } + + val = in_le32(&l2ana_reg->ana_tables.vlan_tidx); + out_le32(&l2ana_reg->ana_tables.vlan_tidx, + bitfield_replace_by_mask(val, VSC9953_ANA_TBL_VID_MASK, vid)); + + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + VSC9953_VLAN_PORT_MASK | VSC9953_VLAN_CMD_MASK, + VSC9953_VLAN_CMD_WRITE | + (set_member ? VSC9953_VLAN_PORT_MASK : 0)); } -#ifdef CONFIG_VSC9953_CMD -/* Enable/disable status of a VSC9953 port */ -static void vsc9953_port_status_set(int port_nr, u8 enabled) +#ifdef CONFIG_CMD_ETHSW +/* Get PVID of a VSC9953 port */ +static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid) { - u32 val; - struct vsc9953_qsys_reg *l2qsys_reg; + u32 val; + struct vsc9953_analyzer *l2ana_reg; /* Administrative down */ - if (vsc9953_l2sw.port[port_nr].enabled == 0) + if (vsc9953_l2sw.port[port_nr].enabled) { + printf("Port %d is administrative down\n", port_nr); + return -1; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* Get ingress PVID */ + val = in_le32(&l2ana_reg->port[port_nr].vlan_cfg); + *pvid = bitfield_extract_by_mask(val, VSC9953_VLAN_CFG_VID_MASK); + + return 0; +} +#endif + +/* Set PVID for a VSC9953 port */ +static void vsc9953_port_vlan_pvid_set(int port_no, int pvid) +{ + uint val; + struct vsc9953_analyzer *l2ana_reg; + struct vsc9953_rew_reg *l2rew_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); return; + } - l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + - VSC9953_QSYS_OFFSET); + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + /* Set PVID on ingress */ + val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); + val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_VID_MASK, pvid); + out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); + + /* Set PVID on egress */ + val = in_le32(&l2rew_reg->port[port_no].port_vlan_cfg); + val = bitfield_replace_by_mask(val, VSC9953_PORT_VLAN_CFG_VID_MASK, + pvid); + out_le32(&l2rew_reg->port[port_no].port_vlan_cfg, val); +} + +static void vsc9953_port_all_vlan_pvid_set(int pvid) +{ + int i; + + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_pvid_set(i, pvid); +} + +/* Enable/disable vlan aware of a VSC9953 port */ +static void vsc9953_port_vlan_aware_set(int port_no, int enabled) +{ + struct vsc9953_analyzer *l2ana_reg; - val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_nr]); - if (enabled == 1) - val |= (1 << 13); + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + if (enabled) + setbits_le32(&l2ana_reg->port[port_no].vlan_cfg, + VSC9953_VLAN_CFG_AWARE_ENA); else - val &= ~(1 << 13); + clrbits_le32(&l2ana_reg->port[port_no].vlan_cfg, + VSC9953_VLAN_CFG_AWARE_ENA); +} + +/* Set all VSC9953 ports' vlan aware */ +static void vsc9953_port_all_vlan_aware_set(int enabled) +{ + int i; - out_le32(&l2qsys_reg->sys.switch_port_mode[port_nr], val); + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_aware_set(i, enabled); } -/* Set all VSC9953 ports' status */ -static void vsc9953_port_all_status_set(u8 enabled) +/* Enable/disable vlan pop count of a VSC9953 port */ +static void vsc9953_port_vlan_popcnt_set(int port_no, int popcnt) { - int i; + uint val; + struct vsc9953_analyzer *l2ana_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + if (popcnt > 3 || popcnt < 0) { + printf("Invalid pop count value: %d\n", port_no); + return; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + val = in_le32(&l2ana_reg->port[port_no].vlan_cfg); + val = bitfield_replace_by_mask(val, VSC9953_VLAN_CFG_POP_CNT_MASK, + popcnt); + out_le32(&l2ana_reg->port[port_no].vlan_cfg, val); +} + +/* Set all VSC9953 ports' pop count */ +static void vsc9953_port_all_vlan_poncnt_set(int popcnt) +{ + int i; for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_port_status_set(i, enabled); + vsc9953_port_vlan_popcnt_set(i, popcnt); } -/* Start autonegotiation for a VSC9953 PHY */ -static void vsc9953_phy_autoneg(int port_nr) +/* Enable/disable learning for frames dropped due to ingress filtering */ +static void vsc9953_vlan_ingr_fltr_learn_drop(int enable) +{ + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + if (enable) + setbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); + else + clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); +} + +/* Egress untag modes of a VSC9953 port */ +enum egress_untag_mode { + EGRESS_UNTAG_ALL = 0, + EGRESS_UNTAG_PVID_AND_ZERO, + EGRESS_UNTAG_ZERO, + EGRESS_UNTAG_NONE, +}; + +#ifdef CONFIG_CMD_ETHSW +/* Get egress tagging configuration for a VSC9953 port */ +static int vsc9953_port_vlan_egr_untag_get(int port_no, + enum egress_untag_mode *mode) { - if (!vsc9953_l2sw.port[port_nr].phydev) + u32 val; + struct vsc9953_rew_reg *l2rew_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return -1; + } + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); + + switch (val & VSC9953_TAG_CFG_MASK) { + case VSC9953_TAG_CFG_NONE: + *mode = EGRESS_UNTAG_ALL; + return 0; + case VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO: + *mode = EGRESS_UNTAG_PVID_AND_ZERO; + return 0; + case VSC9953_TAG_CFG_ALL_BUT_ZERO: + *mode = EGRESS_UNTAG_ZERO; + return 0; + case VSC9953_TAG_CFG_ALL: + *mode = EGRESS_UNTAG_NONE; + return 0; + default: + printf("Unknown egress tagging configuration for port %d\n", + port_no); + return -1; + } +} + +/* Show egress tagging configuration for a VSC9953 port */ +static void vsc9953_port_vlan_egr_untag_show(int port_no) +{ + enum egress_untag_mode mode; + + if (vsc9953_port_vlan_egr_untag_get(port_no, &mode)) { + printf("%7d\t%17s\n", port_no, "-"); return; + } - if (vsc9953_l2sw.port[port_nr].phydev->drv->startup( - vsc9953_l2sw.port[port_nr].phydev)) - printf("Failed to start PHY for port %d\n", port_nr); + printf("%7d\t", port_no); + switch (mode) { + case EGRESS_UNTAG_ALL: + printf("%17s\n", "all"); + break; + case EGRESS_UNTAG_NONE: + printf("%17s\n", "none"); + break; + case EGRESS_UNTAG_PVID_AND_ZERO: + printf("%17s\n", "PVID and 0"); + break; + case EGRESS_UNTAG_ZERO: + printf("%17s\n", "0"); + break; + default: + printf("%17s\n", "-"); + } } +#endif -/* Start autonegotiation for all VSC9953 PHYs */ -static void vsc9953_phy_all_autoneg(void) +static void vsc9953_port_vlan_egr_untag_set(int port_no, + enum egress_untag_mode mode) { - int i; + struct vsc9953_rew_reg *l2rew_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + switch (mode) { + case EGRESS_UNTAG_ALL: + clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_NONE); + break; + case EGRESS_UNTAG_PVID_AND_ZERO: + clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_CFG_MASK, + VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO); + break; + case EGRESS_UNTAG_ZERO: + clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_CFG_MASK, + VSC9953_TAG_CFG_ALL_BUT_ZERO); + break; + case EGRESS_UNTAG_NONE: + clrsetbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_CFG_MASK, VSC9953_TAG_CFG_ALL); + break; + default: + printf("Unknown untag mode for port %d\n", port_no); + } +} + +static void vsc9953_port_all_vlan_egress_untagged_set( + enum egress_untag_mode mode) +{ + int i; for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_phy_autoneg(i); + vsc9953_port_vlan_egr_untag_set(i, mode); +} + +#ifdef CONFIG_CMD_ETHSW + +/* Enable/disable status of a VSC9953 port */ +static void vsc9953_port_status_set(int port_no, u8 enabled) +{ + struct vsc9953_qsys_reg *l2qsys_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) + return; + + l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + + VSC9953_QSYS_OFFSET); + + if (enabled) + setbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], + VSC9953_PORT_ENA); + else + clrbits_le32(&l2qsys_reg->sys.switch_port_mode[port_no], + VSC9953_PORT_ENA); +} + +/* Start autonegotiation for a VSC9953 PHY */ +static void vsc9953_phy_autoneg(int port_no) +{ + if (!vsc9953_l2sw.port[port_no].phydev) + return; + + if (vsc9953_l2sw.port[port_no].phydev->drv->startup( + vsc9953_l2sw.port[port_no].phydev)) + printf("Failed to start PHY for port %d\n", port_no); } /* Print a VSC9953 port's configuration */ -static void vsc9953_port_config_show(int port) +static void vsc9953_port_config_show(int port_no) { - int speed; - int duplex; - int link; - u8 enabled; - u32 val; - struct vsc9953_qsys_reg *l2qsys_reg; + int speed; + int duplex; + int link; + u8 enabled; + u32 val; + struct vsc9953_qsys_reg *l2qsys_reg; l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + VSC9953_QSYS_OFFSET); - val = in_le32(&l2qsys_reg->sys.switch_port_mode[port]); - enabled = vsc9953_l2sw.port[port].enabled & - ((val & 0x00002000) >> 13); + val = in_le32(&l2qsys_reg->sys.switch_port_mode[port_no]); + enabled = vsc9953_l2sw.port[port_no].enabled && + (val & VSC9953_PORT_ENA); /* internal ports (8 and 9) are fixed */ - if (VSC9953_INTERNAL_PORT_CHECK(port)) { + if (VSC9953_INTERNAL_PORT_CHECK(port_no)) { link = 1; speed = SPEED_2500; duplex = DUPLEX_FULL; } else { - if (vsc9953_l2sw.port[port].phydev) { - link = vsc9953_l2sw.port[port].phydev->link; - speed = vsc9953_l2sw.port[port].phydev->speed; - duplex = vsc9953_l2sw.port[port].phydev->duplex; + if (vsc9953_l2sw.port[port_no].phydev) { + link = vsc9953_l2sw.port[port_no].phydev->link; + speed = vsc9953_l2sw.port[port_no].phydev->speed; + duplex = vsc9953_l2sw.port[port_no].phydev->duplex; } else { link = -1; speed = -1; @@ -396,7 +660,7 @@ static void vsc9953_port_config_show(int port) } } - printf("%8d ", port); + printf("%8d ", port_no); printf("%8s ", enabled == 1 ? "enabled" : "disabled"); printf("%8s ", link == 1 ? "up" : "down"); @@ -423,75 +687,1575 @@ static void vsc9953_port_config_show(int port) printf("%8s\n", duplex == DUPLEX_FULL ? "full" : "half"); } -/* Print VSC9953 ports' configuration */ -static void vsc9953_port_all_config_show(void) +/* Show VSC9953 ports' statistics */ +static void vsc9953_port_statistics_show(int port_no) { - int i; + u32 rx_val; + u32 tx_val; + struct vsc9953_system_reg *l2sys_reg; - for (i = 0; i < VSC9953_MAX_PORTS; i++) - vsc9953_port_config_show(i); + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + + VSC9953_SYS_OFFSET); + + printf("Statistics for L2 Switch port %d:\n", port_no); + + /* Set counter view for our port */ + out_le32(&l2sys_reg->sys.stat_cfg, port_no); + +#define VSC9953_STATS_PRINTF "%-15s %10u" + + /* Get number of Rx and Tx frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx frames:", rx_val, "Tx frames:", tx_val); + + /* Get number of Rx and Tx bytes */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_oct); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_oct); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx bytes:", rx_val, "Tx bytes:", tx_val); + + /* Get number of Rx frames received ok and Tx frames sent ok */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_0) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_1) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_2) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_3) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_4) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_5) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_6) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_yellow_prio_7) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_0) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_1) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_2) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_3) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_4) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_5) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_6) + + in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_green_prio_7); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx frames ok:", rx_val, "Tx frames ok:", tx_val); + + /* Get number of Rx and Tx unicast frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_uc); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_uc); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx unicast:", rx_val, "Tx unicast:", tx_val); + + /* Get number of Rx and Tx broadcast frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_bc); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_bc); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx broadcast:", rx_val, "Tx broadcast:", tx_val); + + /* Get number of Rx and Tx frames of 64B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_64); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_64); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 64B:", rx_val, "Tx 64B:", tx_val); + + /* Get number of Rx and Tx frames with sizes between 65B and 127B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_65_127); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_65_127); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 65B-127B:", rx_val, "Tx 65B-127B:", tx_val); + + /* Get number of Rx and Tx frames with sizes between 128B and 255B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_128_255); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_128_255); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 128B-255B:", rx_val, "Tx 128B-255B:", tx_val); + + /* Get number of Rx and Tx frames with sizes between 256B and 511B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_256_511); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_256_511); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 256B-511B:", rx_val, "Tx 256B-511B:", tx_val); + + /* Get number of Rx and Tx frames with sizes between 512B and 1023B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_512_1023); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_512_1023); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 512B-1023B:", rx_val, "Tx 512B-1023B:", tx_val); + + /* Get number of Rx and Tx frames with sizes between 1024B and 1526B */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_1024_1526); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_1024_1526); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx 1024B-1526B:", rx_val, "Tx 1024B-1526B:", tx_val); + + /* Get number of Rx and Tx jumbo frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_sz_jumbo); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_sz_jumbo); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx jumbo:", rx_val, "Tx jumbo:", tx_val); + + /* Get number of Rx and Tx dropped frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_tail) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_0) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_1) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_2) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_3) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_4) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_5) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_6) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_yellow_prio_7) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_0) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_1) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_2) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_3) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_4) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_5) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_6) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_green_prio_7); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_drop) + + in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx drops:", rx_val, "Tx drops:", tx_val); + + /* + * Get number of Rx frames with CRC or alignment errors + * and number of detected Tx collisions + */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_crc); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_col); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx CRC&align:", rx_val, "Tx coll:", tx_val); + + /* + * Get number of Rx undersized frames and + * number of Tx aged frames + */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_short); + tx_val = in_le32(&l2sys_reg->stat.tx_cntrs.c_tx_aged); + printf(VSC9953_STATS_PRINTF"\t\t"VSC9953_STATS_PRINTF"\n", + "Rx undersize:", rx_val, "Tx aged:", tx_val); + + /* Get number of Rx oversized frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_long); + printf(VSC9953_STATS_PRINTF"\n", "Rx oversized:", rx_val); + + /* Get number of Rx fragmented frames */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_frag); + printf(VSC9953_STATS_PRINTF"\n", "Rx fragments:", rx_val); + + /* Get number of Rx jabber errors */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_jabber); + printf(VSC9953_STATS_PRINTF"\n", "Rx jabbers:", rx_val); + + /* + * Get number of Rx frames filtered due to classification rules or + * no destination ports + */ + rx_val = in_le32(&l2sys_reg->stat.rx_cntrs.c_rx_cat_drop) + + in_le32(&l2sys_reg->stat.drop_cntrs.c_dr_local); + printf(VSC9953_STATS_PRINTF"\n", "Rx filtered:", rx_val); + + printf("\n"); } -/* function to interpret commands starting with "ethsw " */ -static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +/* Clear statistics for a VSC9953 port */ +static void vsc9953_port_statistics_clear(int port_no) { - u8 enable; - u32 port; + struct vsc9953_system_reg *l2sys_reg; - if (argc < 4) + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + + VSC9953_SYS_OFFSET); + + /* Clear all counter groups for our ports */ + out_le32(&l2sys_reg->sys.stat_cfg, port_no | + VSC9953_STAT_CLEAR_RX | VSC9953_STAT_CLEAR_TX | + VSC9953_STAT_CLEAR_DR); +} + +enum port_learn_mode { + PORT_LEARN_NONE, + PORT_LEARN_AUTO +}; + +/* Set learning configuration for a VSC9953 port */ +static void vsc9953_port_learn_mode_set(int port_no, enum port_learn_mode mode) +{ + struct vsc9953_analyzer *l2ana_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); + return; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + switch (mode) { + case PORT_LEARN_NONE: + clrbits_le32(&l2ana_reg->port[port_no].port_cfg, + VSC9953_PORT_CFG_LEARN_DROP | + VSC9953_PORT_CFG_LEARN_CPU | + VSC9953_PORT_CFG_LEARN_AUTO | + VSC9953_PORT_CFG_LEARN_ENA); + break; + case PORT_LEARN_AUTO: + clrsetbits_le32(&l2ana_reg->port[port_no].port_cfg, + VSC9953_PORT_CFG_LEARN_DROP | + VSC9953_PORT_CFG_LEARN_CPU, + VSC9953_PORT_CFG_LEARN_ENA | + VSC9953_PORT_CFG_LEARN_AUTO); + break; + default: + printf("Unknown learn mode for port %d\n", port_no); + } +} + +/* Get learning configuration for a VSC9953 port */ +static int vsc9953_port_learn_mode_get(int port_no, enum port_learn_mode *mode) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + /* Administrative down */ + if (!vsc9953_l2sw.port[port_no].enabled) { + printf("Port %d is administrative down\n", port_no); return -1; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* For now we only support HW learning (auto) and no learning */ + val = in_le32(&l2ana_reg->port[port_no].port_cfg); + if ((val & (VSC9953_PORT_CFG_LEARN_ENA | + VSC9953_PORT_CFG_LEARN_AUTO)) == + (VSC9953_PORT_CFG_LEARN_ENA | VSC9953_PORT_CFG_LEARN_AUTO)) + *mode = PORT_LEARN_AUTO; + else + *mode = PORT_LEARN_NONE; + + return 0; +} - if (strcmp(argv[1], "port")) +/* wait for FDB to become available */ +static int vsc9953_mac_table_poll_idle(void) +{ + struct vsc9953_analyzer *l2ana_reg; + u32 timeout; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + timeout = 50000; + while (((in_le32(&l2ana_reg->ana_tables.mac_access) & + VSC9953_MAC_CMD_MASK) != + VSC9953_MAC_CMD_IDLE) && --timeout) + udelay(1); + + return timeout ? 0 : -EBUSY; +} + +/* enum describing available commands for the MAC table */ +enum mac_table_cmd { + MAC_TABLE_READ, + MAC_TABLE_LOOKUP, + MAC_TABLE_WRITE, + MAC_TABLE_LEARN, + MAC_TABLE_FORGET, + MAC_TABLE_GET_NEXT, + MAC_TABLE_AGE, +}; + +/* Issues a command to the FDB table */ +static int vsc9953_mac_table_cmd(enum mac_table_cmd cmd) +{ + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + switch (cmd) { + case MAC_TABLE_READ: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | VSC9953_MAC_CMD_VALID, + VSC9953_MAC_CMD_READ); + break; + case MAC_TABLE_LOOKUP: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK, VSC9953_MAC_CMD_READ | + VSC9953_MAC_CMD_VALID); + break; + case MAC_TABLE_WRITE: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | + VSC9953_MAC_ENTRYTYPE_MASK, + VSC9953_MAC_CMD_WRITE | + VSC9953_MAC_ENTRYTYPE_LOCKED); + break; + case MAC_TABLE_LEARN: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | + VSC9953_MAC_ENTRYTYPE_MASK, + VSC9953_MAC_CMD_LEARN | + VSC9953_MAC_ENTRYTYPE_LOCKED | + VSC9953_MAC_CMD_VALID); + break; + case MAC_TABLE_FORGET: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | + VSC9953_MAC_ENTRYTYPE_MASK, + VSC9953_MAC_CMD_FORGET); + break; + case MAC_TABLE_GET_NEXT: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | + VSC9953_MAC_ENTRYTYPE_MASK, + VSC9953_MAC_CMD_NEXT); + break; + case MAC_TABLE_AGE: + clrsetbits_le32(&l2ana_reg->ana_tables.mac_access, + VSC9953_MAC_CMD_MASK | + VSC9953_MAC_ENTRYTYPE_MASK, + VSC9953_MAC_CMD_AGE); + break; + default: + printf("Unknown MAC table command\n"); + } + + if (vsc9953_mac_table_poll_idle() < 0) { + debug("MAC table timeout\n"); return -1; + } - if (!strcmp(argv[3], "show")) { - if (!strcmp(argv[2], "all")) { - vsc9953_phy_all_autoneg(); - printf("%8s %8s %8s %8s %8s\n", - "Port", "Status", "Link", "Speed", - "Duplex"); - vsc9953_port_all_config_show(); - return 0; - } else { - port = simple_strtoul(argv[2], NULL, 10); - if (!VSC9953_PORT_CHECK(port)) - return -1; - vsc9953_phy_autoneg(port); - printf("%8s %8s %8s %8s %8s\n", - "Port", "Status", "Link", "Speed", - "Duplex"); - vsc9953_port_config_show(port); - return 0; - } - } else if (!strcmp(argv[3], "enable")) { - enable = 1; - } else if (!strcmp(argv[3], "disable")) { - enable = 0; + return 0; +} + +/* show the FDB entries that correspond to a port and a VLAN */ +static void vsc9953_mac_table_show(int port_no, int vid) +{ + int rc[VSC9953_MAX_PORTS]; + enum port_learn_mode mode[VSC9953_MAX_PORTS]; + int i; + u32 val; + u32 vlan; + u32 mach; + u32 macl; + u32 dest_indx; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* disable auto learning */ + if (port_no == ETHSW_CMD_PORT_ALL) { + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]); + if (!rc[i] && mode[i] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE); + } + } else { + rc[port_no] = vsc9953_port_learn_mode_get(port_no, + &mode[port_no]); + if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE); + } + + /* write port and vid to get selected FDB entries */ + val = in_le32(&l2ana_reg->ana.anag_efil); + if (port_no != ETHSW_CMD_PORT_ALL) { + val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK, + port_no) | VSC9953_AGE_PORT_EN; + } + if (vid != ETHSW_CMD_VLAN_ALL) { + val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, + vid) | VSC9953_AGE_VID_EN; + } + out_le32(&l2ana_reg->ana.anag_efil, val); + + /* set MAC and VLAN to 0 to look from beginning */ + clrbits_le32(&l2ana_reg->ana_tables.mach_data, + VSC9953_MAC_VID_MASK | VSC9953_MAC_MACH_MASK); + out_le32(&l2ana_reg->ana_tables.macl_data, 0); + + /* get entries */ + printf("%10s %17s %5s %4s\n", "EntryType", "MAC", "PORT", "VID"); + do { + if (vsc9953_mac_table_cmd(MAC_TABLE_GET_NEXT) < 0) { + debug("GET NEXT MAC table command failed\n"); + break; + } + + val = in_le32(&l2ana_reg->ana_tables.mac_access); + + /* get out when an invalid entry is found */ + if (!(val & VSC9953_MAC_CMD_VALID)) + break; + + switch (val & VSC9953_MAC_ENTRYTYPE_MASK) { + case VSC9953_MAC_ENTRYTYPE_NORMAL: + printf("%10s ", "Dynamic"); + break; + case VSC9953_MAC_ENTRYTYPE_LOCKED: + printf("%10s ", "Static"); + break; + case VSC9953_MAC_ENTRYTYPE_IPV4MCAST: + printf("%10s ", "IPv4 Mcast"); + break; + case VSC9953_MAC_ENTRYTYPE_IPV6MCAST: + printf("%10s ", "IPv6 Mcast"); + break; + default: + printf("%10s ", "Unknown"); + } + + dest_indx = bitfield_extract_by_mask(val, + VSC9953_MAC_DESTIDX_MASK); + + val = in_le32(&l2ana_reg->ana_tables.mach_data); + vlan = bitfield_extract_by_mask(val, VSC9953_MAC_VID_MASK); + mach = bitfield_extract_by_mask(val, VSC9953_MAC_MACH_MASK); + macl = in_le32(&l2ana_reg->ana_tables.macl_data); + + printf("%02x:%02x:%02x:%02x:%02x:%02x ", (mach >> 8) & 0xff, + mach & 0xff, (macl >> 24) & 0xff, (macl >> 16) & 0xff, + (macl >> 8) & 0xff, macl & 0xff); + printf("%5d ", dest_indx); + printf("%4d\n", vlan); + } while (1); + + /* set learning mode to previous value */ + if (port_no == ETHSW_CMD_PORT_ALL) { + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (!rc[i] && mode[i] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(i, mode[i]); + } } else { + /* If administrative down, skip */ + if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(port_no, mode[port_no]); + } + + /* reset FDB port and VLAN FDB selection */ + clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN | + VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN | + VSC9953_AGE_VID_MASK); +} + +/* Add a static FDB entry */ +static int vsc9953_mac_table_add(u8 port_no, uchar mac[6], int vid) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + val = in_le32(&l2ana_reg->ana_tables.mach_data); + val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | + (mac[0] << 8) | (mac[1] << 0); + out_le32(&l2ana_reg->ana_tables.mach_data, val); + + out_le32(&l2ana_reg->ana_tables.macl_data, + (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | + (mac[5] << 0)); + + /* set on which port is the MAC address added */ + val = in_le32(&l2ana_reg->ana_tables.mac_access); + val = bitfield_replace_by_mask(val, VSC9953_MAC_DESTIDX_MASK, port_no); + out_le32(&l2ana_reg->ana_tables.mac_access, val); + + if (vsc9953_mac_table_cmd(MAC_TABLE_LEARN) < 0) + return -1; + + /* check if the MAC address was indeed added */ + val = in_le32(&l2ana_reg->ana_tables.mach_data); + val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | + (mac[0] << 8) | (mac[1] << 0); + out_le32(&l2ana_reg->ana_tables.mach_data, val); + + out_le32(&l2ana_reg->ana_tables.macl_data, + (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | + (mac[5] << 0)); + + if (vsc9953_mac_table_cmd(MAC_TABLE_READ) < 0) + return -1; + + val = in_le32(&l2ana_reg->ana_tables.mac_access); + + if ((port_no != bitfield_extract_by_mask(val, + VSC9953_MAC_DESTIDX_MASK))) { + printf("Failed to add MAC address\n"); return -1; } + return 0; +} - if (!strcmp(argv[2], "all")) { - vsc9953_port_all_status_set(enable); - return 0; +/* Delete a FDB entry */ +static int vsc9953_mac_table_del(uchar mac[6], u16 vid) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* check first if MAC entry is present */ + val = in_le32(&l2ana_reg->ana_tables.mach_data); + val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | + (mac[0] << 8) | (mac[1] << 0); + out_le32(&l2ana_reg->ana_tables.mach_data, val); + + out_le32(&l2ana_reg->ana_tables.macl_data, + (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | + (mac[5] << 0)); + + if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) { + debug("Lookup in the MAC table failed\n"); + return -1; + } + + if (!(in_le32(&l2ana_reg->ana_tables.mac_access) & + VSC9953_MAC_CMD_VALID)) { + printf("The MAC address: %02x:%02x:%02x:%02x:%02x:%02x ", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + printf("VLAN: %d does not exist.\n", vid); + return -1; + } + + /* FDB entry found, proceed to delete */ + val = in_le32(&l2ana_reg->ana_tables.mach_data); + val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | + (mac[0] << 8) | (mac[1] << 0); + out_le32(&l2ana_reg->ana_tables.mach_data, val); + + out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) | + (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0)); + + if (vsc9953_mac_table_cmd(MAC_TABLE_FORGET) < 0) + return -1; + + /* check if the MAC entry is still in FDB */ + val = in_le32(&l2ana_reg->ana_tables.mach_data); + val = bitfield_replace_by_mask(val, VSC9953_MACHDATA_VID_MASK, vid) | + (mac[0] << 8) | (mac[1] << 0); + out_le32(&l2ana_reg->ana_tables.mach_data, val); + + out_le32(&l2ana_reg->ana_tables.macl_data, (mac[2] << 24) | + (mac[3] << 16) | (mac[4] << 8) | (mac[5] << 0)); + + if (vsc9953_mac_table_cmd(MAC_TABLE_LOOKUP) < 0) { + debug("Lookup in the MAC table failed\n"); + return -1; + } + if (in_le32(&l2ana_reg->ana_tables.mac_access) & + VSC9953_MAC_CMD_VALID) { + printf("Failed to delete MAC address\n"); + return -1; + } + + return 0; +} + +/* age the unlocked entries in FDB */ +static void vsc9953_mac_table_age(int port_no, int vid) +{ + int rc[VSC9953_MAX_PORTS]; + enum port_learn_mode mode[VSC9953_MAX_PORTS]; + u32 val; + int i; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* set port and VID for selective aging */ + val = in_le32(&l2ana_reg->ana.anag_efil); + if (port_no != ETHSW_CMD_PORT_ALL) { + /* disable auto learning */ + rc[port_no] = vsc9953_port_learn_mode_get(port_no, + &mode[port_no]); + if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(port_no, PORT_LEARN_NONE); + + val = bitfield_replace_by_mask(val, VSC9953_AGE_PORT_MASK, + port_no) | VSC9953_AGE_PORT_EN; } else { - port = simple_strtoul(argv[2], NULL, 10); - if (!VSC9953_PORT_CHECK(port)) - return -1; - vsc9953_port_status_set(port, enable); - return 0; + /* disable auto learning on all ports */ + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + rc[i] = vsc9953_port_learn_mode_get(i, &mode[i]); + if (!rc[i] && mode[i] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(i, PORT_LEARN_NONE); + } + } + + if (vid != ETHSW_CMD_VLAN_ALL) { + val = bitfield_replace_by_mask(val, VSC9953_AGE_VID_MASK, vid) | + VSC9953_AGE_VID_EN; + } + out_le32(&l2ana_reg->ana.anag_efil, val); + + /* age the dynamic FDB entries */ + vsc9953_mac_table_cmd(MAC_TABLE_AGE); + + /* clear previously set port and VID */ + clrbits_le32(&l2ana_reg->ana.anag_efil, VSC9953_AGE_PORT_EN | + VSC9953_AGE_PORT_MASK | VSC9953_AGE_VID_EN | + VSC9953_AGE_VID_MASK); + + if (port_no != ETHSW_CMD_PORT_ALL) { + if (!rc[port_no] && mode[port_no] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(port_no, mode[port_no]); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (!rc[i] && mode[i] != PORT_LEARN_NONE) + vsc9953_port_learn_mode_set(i, mode[i]); + } + } +} + +/* Delete all the dynamic FDB entries */ +static void vsc9953_mac_table_flush(int port, int vid) +{ + vsc9953_mac_table_age(port, vid); + vsc9953_mac_table_age(port, vid); +} + +enum egress_vlan_tag { + EGR_TAG_CLASS = 0, + EGR_TAG_PVID, +}; + +/* Set egress tag mode for a VSC9953 port */ +static void vsc9953_port_vlan_egress_tag_set(int port_no, + enum egress_vlan_tag mode) +{ + struct vsc9953_rew_reg *l2rew_reg; + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + switch (mode) { + case EGR_TAG_CLASS: + clrbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_VID_PVID); + break; + case EGR_TAG_PVID: + setbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + VSC9953_TAG_VID_PVID); + break; + default: + printf("Unknown egress VLAN tag mode for port %d\n", port_no); } +} - return -1; +/* Get egress tag mode for a VSC9953 port */ +static void vsc9953_port_vlan_egress_tag_get(int port_no, + enum egress_vlan_tag *mode) +{ + u32 val; + struct vsc9953_rew_reg *l2rew_reg; + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); + if (val & VSC9953_TAG_VID_PVID) + *mode = EGR_TAG_PVID; + else + *mode = EGR_TAG_CLASS; } -U_BOOT_CMD(ethsw, 5, 0, do_ethsw, - "vsc9953 l2 switch commands", - "port <port_nr> enable|disable\n" - " - enable/disable an l2 switch port\n" - " port_nr=0..9; use \"all\" for all ports\n" - "ethsw port <port_nr> show\n" - " - show an l2 switch port's configuration\n" - " port_nr=0..9; use \"all\" for all ports\n" -); -#endif /* CONFIG_VSC9953_CMD */ +/* VSC9953 VLAN learning modes */ +enum vlan_learning_mode { + SHARED_VLAN_LEARNING, + PRIVATE_VLAN_LEARNING, +}; + +/* Set VLAN learning mode for VSC9953 */ +static void vsc9953_vlan_learning_set(enum vlan_learning_mode lrn_mode) +{ + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + switch (lrn_mode) { + case SHARED_VLAN_LEARNING: + setbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL); + break; + case PRIVATE_VLAN_LEARNING: + clrbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL); + break; + default: + printf("Unknown VLAN learn mode\n"); + } +} + +/* Get VLAN learning mode for VSC9953 */ +static int vsc9953_vlan_learning_get(enum vlan_learning_mode *lrn_mode) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + val = in_le32(&l2ana_reg->ana.agen_ctrl); + + if (!(val & VSC9953_FID_MASK_ALL)) { + *lrn_mode = PRIVATE_VLAN_LEARNING; + } else if ((val & VSC9953_FID_MASK_ALL) == VSC9953_FID_MASK_ALL) { + *lrn_mode = SHARED_VLAN_LEARNING; + } else { + printf("Unknown VLAN learning mode\n"); + return -EINVAL; + } + + return 0; +} + +/* Enable/disable VLAN ingress filtering on a VSC9953 port */ +static void vsc9953_port_ingress_filtering_set(int port_no, int enabled) +{ + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + if (enabled) + setbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no); + else + clrbits_le32(&l2ana_reg->ana.vlan_mask, 1 << port_no); +} + +/* Return VLAN ingress filtering on a VSC9953 port */ +static int vsc9953_port_ingress_filtering_get(int port_no) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + val = in_le32(&l2ana_reg->ana.vlan_mask); + return !!(val & (1 << port_no)); +} + +static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + u8 enabled; + + /* Last keyword should tell us if we should enable/disable the port */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_enable) + enabled = 1; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_disable) + enabled = 0; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_status_set(parsed_cmd->port, enabled); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_status_set(i, enabled); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_port_config_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_phy_autoneg(parsed_cmd->port); + printf("%8s %8s %8s %8s %8s\n", + "Port", "Status", "Link", "Speed", + "Duplex"); + vsc9953_port_config_show(parsed_cmd->port); + + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_phy_autoneg(i); + printf("%8s %8s %8s %8s %8s\n", + "Port", "Status", "Link", "Speed", "Duplex"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_config_show(i); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_port_stats_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_statistics_show(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_statistics_show(i); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_port_stats_clear_key_func(struct ethsw_command_def + *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_statistics_clear(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_statistics_clear(i); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_learn_show_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + enum port_learn_mode mode; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + if (vsc9953_port_learn_mode_get(parsed_cmd->port, &mode)) + return CMD_RET_FAILURE; + printf("%7s %11s\n", "Port", "Learn mode"); + switch (mode) { + case PORT_LEARN_NONE: + printf("%7d %11s\n", parsed_cmd->port, "disable"); + break; + case PORT_LEARN_AUTO: + printf("%7d %11s\n", parsed_cmd->port, "auto"); + break; + default: + printf("%7d %11s\n", parsed_cmd->port, "-"); + } + } else { + printf("%7s %11s\n", "Port", "Learn mode"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (vsc9953_port_learn_mode_get(i, &mode)) + continue; + switch (mode) { + case PORT_LEARN_NONE: + printf("%7d %11s\n", i, "disable"); + break; + case PORT_LEARN_AUTO: + printf("%7d %11s\n", i, "auto"); + break; + default: + printf("%7d %11s\n", i, "-"); + } + } + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_learn_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + enum port_learn_mode mode; + + /* Last keyword should tell us the learn mode */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_auto) + mode = PORT_LEARN_AUTO; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_disable) + mode = PORT_LEARN_NONE; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_learn_mode_set(parsed_cmd->port, mode); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_learn_mode_set(i, mode); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_fdb_show_key_func(struct ethsw_command_def *parsed_cmd) +{ + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL && + !VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + + if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL && + !VSC9953_VLAN_CHECK(parsed_cmd->vid)) { + printf("Invalid VID number: %d\n", parsed_cmd->vid); + return CMD_RET_FAILURE; + } + + vsc9953_mac_table_show(parsed_cmd->port, parsed_cmd->vid); + + return CMD_RET_SUCCESS; +} + +static int vsc9953_fdb_flush_key_func(struct ethsw_command_def *parsed_cmd) +{ + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL && + !VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + + if (parsed_cmd->vid != ETHSW_CMD_VLAN_ALL && + !VSC9953_VLAN_CHECK(parsed_cmd->vid)) { + printf("Invalid VID number: %d\n", parsed_cmd->vid); + return CMD_RET_FAILURE; + } + + vsc9953_mac_table_flush(parsed_cmd->port, parsed_cmd->vid); + + return CMD_RET_SUCCESS; +} + +static int vsc9953_fdb_entry_add_key_func(struct ethsw_command_def *parsed_cmd) +{ + int vid; + + /* a port number must be present */ + if (parsed_cmd->port == ETHSW_CMD_PORT_ALL) { + printf("Please specify a port\n"); + return CMD_RET_FAILURE; + } + + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + + /* Use VLAN 1 if VID is not set */ + vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid); + + if (!VSC9953_VLAN_CHECK(vid)) { + printf("Invalid VID number: %d\n", vid); + return CMD_RET_FAILURE; + } + + if (vsc9953_mac_table_add(parsed_cmd->port, parsed_cmd->ethaddr, vid)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int vsc9953_fdb_entry_del_key_func(struct ethsw_command_def *parsed_cmd) +{ + int vid; + + /* Use VLAN 1 if VID is not set */ + vid = (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL ? 1 : parsed_cmd->vid); + + if (!VSC9953_VLAN_CHECK(vid)) { + printf("Invalid VID number: %d\n", vid); + return CMD_RET_FAILURE; + } + + if (vsc9953_mac_table_del(parsed_cmd->ethaddr, vid)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int vsc9953_pvid_show_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + int pvid; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + + if (vsc9953_port_vlan_pvid_get(parsed_cmd->port, &pvid)) + return CMD_RET_FAILURE; + printf("%7s %7s\n", "Port", "PVID"); + printf("%7d %7d\n", parsed_cmd->port, pvid); + } else { + printf("%7s %7s\n", "Port", "PVID"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (vsc9953_port_vlan_pvid_get(i, &pvid)) + continue; + printf("%7d %7d\n", i, pvid); + } + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_pvid_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + /* PVID number should be set in parsed_cmd->vid */ + if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) { + printf("Please set a pvid value\n"); + return CMD_RET_FAILURE; + } + + if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) { + printf("Invalid VID number: %d\n", parsed_cmd->vid); + return CMD_RET_FAILURE; + } + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_vlan_pvid_set(parsed_cmd->port, parsed_cmd->vid); + } else { + vsc9953_port_all_vlan_pvid_set(parsed_cmd->vid); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_vlan_show_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_vlan_membership_show(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_vlan_membership_show(i); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_vlan_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + int add; + + /* VLAN should be set in parsed_cmd->vid */ + if (parsed_cmd->vid == ETHSW_CMD_VLAN_ALL) { + printf("Please set a vlan value\n"); + return CMD_RET_FAILURE; + } + + if (!VSC9953_VLAN_CHECK(parsed_cmd->vid)) { + printf("Invalid VID number: %d\n", parsed_cmd->vid); + return CMD_RET_FAILURE; + } + + /* keywords add/delete should be the last but one in array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == + ethsw_id_add) + add = 1; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == + ethsw_id_del) + add = 0; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_vlan_table_membership_set(parsed_cmd->vid, + parsed_cmd->port, add); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_vlan_table_membership_set(parsed_cmd->vid, i, + add); + } + + return CMD_RET_SUCCESS; +} +static int vsc9953_port_untag_show_key_func( + struct ethsw_command_def *parsed_cmd) +{ + int i; + + printf("%7s\t%17s\n", "Port", "Untag"); + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_vlan_egr_untag_show(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egr_untag_show(i); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_port_untag_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + enum egress_untag_mode mode; + + /* keywords for the untagged mode are the last in the array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_all) + mode = EGRESS_UNTAG_ALL; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_none) + mode = EGRESS_UNTAG_NONE; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_pvid) + mode = EGRESS_UNTAG_PVID_AND_ZERO; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_vlan_egr_untag_set(parsed_cmd->port, mode); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egr_untag_set(i, mode); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_egr_vlan_tag_show_key_func( + struct ethsw_command_def *parsed_cmd) +{ + int i; + enum egress_vlan_tag mode; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_vlan_egress_tag_get(parsed_cmd->port, &mode); + printf("%7s\t%12s\n", "Port", "Egress VID"); + printf("%7d\t", parsed_cmd->port); + switch (mode) { + case EGR_TAG_CLASS: + printf("%12s\n", "classified"); + break; + case EGR_TAG_PVID: + printf("%12s\n", "pvid"); + break; + default: + printf("%12s\n", "-"); + } + } else { + printf("%7s\t%12s\n", "Port", "Egress VID"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + vsc9953_port_vlan_egress_tag_get(i, &mode); + switch (mode) { + case EGR_TAG_CLASS: + printf("%7d\t%12s\n", i, "classified"); + break; + case EGR_TAG_PVID: + printf("%7d\t%12s\n", i, "pvid"); + break; + default: + printf("%7d\t%12s\n", i, "-"); + } + } + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_egr_vlan_tag_set_key_func( + struct ethsw_command_def *parsed_cmd) +{ + int i; + enum egress_vlan_tag mode; + + /* keywords for the egress vlan tag mode are the last in the array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_pvid) + mode = EGR_TAG_PVID; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_classified) + mode = EGR_TAG_CLASS; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_vlan_egress_tag_set(parsed_cmd->port, mode); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egress_tag_set(i, mode); + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_vlan_learn_show_key_func( + struct ethsw_command_def *parsed_cmd) +{ + int rc; + enum vlan_learning_mode mode; + + rc = vsc9953_vlan_learning_get(&mode); + if (rc) + return CMD_RET_FAILURE; + + switch (mode) { + case SHARED_VLAN_LEARNING: + printf("VLAN learning mode: shared\n"); + break; + case PRIVATE_VLAN_LEARNING: + printf("VLAN learning mode: private\n"); + break; + default: + printf("Unknown VLAN learning mode\n"); + rc = CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_vlan_learn_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + enum vlan_learning_mode mode; + + /* keywords for shared/private are the last in the array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_shared) + mode = SHARED_VLAN_LEARNING; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_private) + mode = PRIVATE_VLAN_LEARNING; + else + return CMD_RET_USAGE; + + vsc9953_vlan_learning_set(mode); + + return CMD_RET_SUCCESS; +} + +static int vsc9953_ingr_fltr_show_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + int enabled; + + printf("%7s\t%18s\n", "Port", "Ingress filtering"); + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + enabled = vsc9953_port_ingress_filtering_get(parsed_cmd->port); + printf("%7d\t%18s\n", parsed_cmd->port, enabled ? "enable" : + "disable"); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + enabled = vsc9953_port_ingress_filtering_get(i); + printf("%7d\t%18s\n", parsed_cmd->port, enabled ? + "enable" : + "disable"); + } + } + + return CMD_RET_SUCCESS; +} + +static int vsc9953_ingr_fltr_set_key_func(struct ethsw_command_def *parsed_cmd) +{ + int i; + int enable; + + /* keywords for enabling/disabling ingress filtering + * are the last in the array + */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_enable) + enable = 1; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + ethsw_id_disable) + enable = 0; + else + return CMD_RET_USAGE; + + if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) { + if (!VSC9953_PORT_CHECK(parsed_cmd->port)) { + printf("Invalid port number: %d\n", parsed_cmd->port); + return CMD_RET_FAILURE; + } + vsc9953_port_ingress_filtering_set(parsed_cmd->port, enable); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_ingress_filtering_set(i, enable); + } + + return CMD_RET_SUCCESS; +} + +static struct ethsw_command_func vsc9953_cmd_func = { + .ethsw_name = "L2 Switch VSC9953", + .port_enable = &vsc9953_port_status_key_func, + .port_disable = &vsc9953_port_status_key_func, + .port_show = &vsc9953_port_config_key_func, + .port_stats = &vsc9953_port_stats_key_func, + .port_stats_clear = &vsc9953_port_stats_clear_key_func, + .port_learn = &vsc9953_learn_set_key_func, + .port_learn_show = &vsc9953_learn_show_key_func, + .fdb_show = &vsc9953_fdb_show_key_func, + .fdb_flush = &vsc9953_fdb_flush_key_func, + .fdb_entry_add = &vsc9953_fdb_entry_add_key_func, + .fdb_entry_del = &vsc9953_fdb_entry_del_key_func, + .pvid_show = &vsc9953_pvid_show_key_func, + .pvid_set = &vsc9953_pvid_set_key_func, + .vlan_show = &vsc9953_vlan_show_key_func, + .vlan_set = &vsc9953_vlan_set_key_func, + .port_untag_show = &vsc9953_port_untag_show_key_func, + .port_untag_set = &vsc9953_port_untag_set_key_func, + .port_egr_vlan_show = &vsc9953_egr_vlan_tag_show_key_func, + .port_egr_vlan_set = &vsc9953_egr_vlan_tag_set_key_func, + .vlan_learn_show = &vsc9953_vlan_learn_show_key_func, + .vlan_learn_set = &vsc9953_vlan_learn_set_key_func, + .port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func, + .port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func +}; + +#endif /* CONFIG_CMD_ETHSW */ + +/***************************************************************************** +At startup, the default configuration would be: + - HW learning enabled on all ports; (HW default) + - All ports are in VLAN 1; + - All ports are VLAN aware; + - All ports have POP_COUNT 1; + - All ports have PVID 1; + - All ports have TPID 0x8100; (HW default) + - All ports tag frames classified to all VLANs that are not PVID; +*****************************************************************************/ +void vsc9953_default_configuration(void) +{ + int i; + + for (i = 0; i < VSC9953_MAX_VLAN; i++) + vsc9953_vlan_table_membership_all_set(i, 0); + vsc9953_port_all_vlan_aware_set(1); + vsc9953_port_all_vlan_pvid_set(1); + vsc9953_port_all_vlan_poncnt_set(1); + vsc9953_vlan_table_membership_all_set(1, 1); + vsc9953_vlan_ingr_fltr_learn_drop(1); + vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO); +} + +void vsc9953_init(bd_t *bis) +{ + u32 i; + u32 hdx_cfg = 0; + u32 phy_addr = 0; + int timeout; + struct vsc9953_system_reg *l2sys_reg; + struct vsc9953_qsys_reg *l2qsys_reg; + struct vsc9953_dev_gmii *l2dev_gmii_reg; + struct vsc9953_analyzer *l2ana_reg; + struct vsc9953_devcpu_gcb *l2dev_gcb; + + l2dev_gmii_reg = (struct vsc9953_dev_gmii *)(VSC9953_OFFSET + + VSC9953_DEV_GMII_OFFSET); + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + l2sys_reg = (struct vsc9953_system_reg *)(VSC9953_OFFSET + + VSC9953_SYS_OFFSET); + + l2qsys_reg = (struct vsc9953_qsys_reg *)(VSC9953_OFFSET + + VSC9953_QSYS_OFFSET); + + l2dev_gcb = (struct vsc9953_devcpu_gcb *)(VSC9953_OFFSET + + VSC9953_DEVCPU_GCB); + + out_le32(&l2dev_gcb->chip_regs.soft_rst, + VSC9953_SOFT_SWC_RST_ENA); + timeout = 50000; + while ((in_le32(&l2dev_gcb->chip_regs.soft_rst) & + VSC9953_SOFT_SWC_RST_ENA) && --timeout) + udelay(1); /* busy wait for vsc9953 soft reset */ + if (timeout == 0) + debug("Timeout waiting for VSC9953 to reset\n"); + + out_le32(&l2sys_reg->sys.reset_cfg, VSC9953_MEM_ENABLE | + VSC9953_MEM_INIT); + + timeout = 50000; + while ((in_le32(&l2sys_reg->sys.reset_cfg) & + VSC9953_MEM_INIT) && --timeout) + udelay(1); /* busy wait for vsc9953 memory init */ + if (timeout == 0) + debug("Timeout waiting for VSC9953 memory to initialize\n"); + + out_le32(&l2sys_reg->sys.reset_cfg, (in_le32(&l2sys_reg->sys.reset_cfg) + | VSC9953_CORE_ENABLE)); + + /* VSC9953 Setting to be done once only */ + out_le32(&l2qsys_reg->sys.ext_cpu_cfg, 0x00000b00); + + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (vsc9953_port_init(i)) + printf("Failed to initialize l2switch port %d\n", i); + + /* Enable VSC9953 GMII Ports Port ID 0 - 7 */ + if (VSC9953_INTERNAL_PORT_CHECK(i)) { + out_le32(&l2ana_reg->pfc[i].pfc_cfg, + VSC9953_PFC_FC_QSGMII); + out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], + VSC9953_MAC_FC_CFG_QSGMII); + } else { + out_le32(&l2ana_reg->pfc[i].pfc_cfg, + VSC9953_PFC_FC); + out_le32(&l2sys_reg->pause_cfg.mac_fc_cfg[i], + VSC9953_MAC_FC_CFG); + } + out_le32(&l2dev_gmii_reg->port_mode.clock_cfg, + VSC9953_CLOCK_CFG); + out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ena_cfg, + VSC9953_MAC_ENA_CFG); + out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_mode_cfg, + VSC9953_MAC_MODE_CFG); + out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_ifg_cfg, + VSC9953_MAC_IFG_CFG); + /* mac_hdx_cfg varies with port id*/ + hdx_cfg = VSC9953_MAC_HDX_CFG | (i << 16); + out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_hdx_cfg, hdx_cfg); + out_le32(&l2sys_reg->sys.front_port_mode[i], + VSC9953_FRONT_PORT_MODE); + setbits_le32(&l2qsys_reg->sys.switch_port_mode[i], + VSC9953_PORT_ENA); + out_le32(&l2dev_gmii_reg->mac_cfg_status.mac_maxlen_cfg, + VSC9953_MAC_MAX_LEN); + out_le32(&l2sys_reg->pause_cfg.pause_cfg[i], + VSC9953_PAUSE_CFG); + /* WAIT FOR 2 us*/ + udelay(2); + + l2dev_gmii_reg = (struct vsc9953_dev_gmii *)( + (char *)l2dev_gmii_reg + + T1040_SWITCH_GMII_DEV_OFFSET); + + /* Initialize Lynx PHY Wrappers */ + phy_addr = 0; + if (vsc9953_l2sw.port[i].enet_if == + PHY_INTERFACE_MODE_QSGMII) + phy_addr = (i + 0x4) & 0x1F; + else if (vsc9953_l2sw.port[i].enet_if == + PHY_INTERFACE_MODE_SGMII) + phy_addr = (i + 1) & 0x1F; + + if (phy_addr) { + /* SGMII IF mode + AN enable */ + vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, + 0x14, PHY_SGMII_IF_MODE_AN | + PHY_SGMII_IF_MODE_SGMII); + /* Dev ability according to SGMII specification */ + vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, + 0x4, PHY_SGMII_DEV_ABILITY_SGMII); + /* Adjust link timer for SGMII + * 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 + */ + vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, + 0x13, 0x0003); + vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, + 0x12, 0x0d40); + /* Restart AN */ + vsc9953_mdio_write(&l2dev_gcb->mii_mng[0], phy_addr, + 0x0, PHY_SGMII_CR_DEF_VAL | + PHY_SGMII_CR_RESET_AN); + + timeout = 50000; + while ((vsc9953_mdio_read(&l2dev_gcb->mii_mng[0], + phy_addr, 0x01) & 0x0020) && --timeout) + udelay(1); /* wait for AN to complete */ + if (timeout == 0) + debug("Timeout waiting for AN to complete\n"); + } + } + + vsc9953_default_configuration(); + +#ifdef CONFIG_CMD_ETHSW + if (ethsw_define_functions(&vsc9953_cmd_func) < 0) + debug("Unable to use \"ethsw\" commands\n"); +#endif + + printf("VSC9953 L2 switch initialized\n"); + return; +} diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b8146df99b..3b6e3b7060 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -124,4 +124,6 @@ config PINCTRL_SANDBOX endif +source "drivers/pinctrl/uniphier/Kconfig" + endmenu diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f537df4e88..e56a17f966 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -3,3 +3,5 @@ obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o + +obj-$(CONFIG_ARCH_UNIPHIER) += uniphier/ diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 58001ef572..b5fdcd12a8 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -11,7 +11,6 @@ #include <dm/device.h> #include <dm/lists.h> #include <dm/pinctrl.h> -#include <dm/root.h> #include <dm/uclass.h> DECLARE_GLOBAL_DATA_PTR; @@ -160,8 +159,7 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) static int pinconfig_post_bind(struct udevice *dev) { - /* Scan the bus for devices */ - return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); + return 0; } #endif @@ -249,10 +247,15 @@ static int pinctrl_post_bind(struct udevice *dev) } /* - * The pinctrl driver child nodes should be bound so that peripheral - * devices can easily search in parent devices during later DT-parsing. + * If set_state callback is set, we assume this pinctrl driver is the + * full implementation. In this case, its child nodes should be bound + * so that peripheral devices can easily search in parent devices + * during later DT-parsing. */ - return pinconfig_post_bind(dev); + if (ops->set_state) + return pinconfig_post_bind(dev); + + return 0; } UCLASS_DRIVER(pinctrl) = { diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c index 5205498b36..c432a008e7 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c @@ -17,6 +17,7 @@ #include <asm/arch/periph.h> #include <asm/arch/pmu_rk3288.h> #include <dm/pinctrl.h> +#include <dm/root.h> DECLARE_GLOBAL_DATA_PTR; @@ -415,6 +416,12 @@ static struct pinctrl_ops rk3288_pinctrl_ops = { .get_periph_id = rk3288_pinctrl_get_periph_id, }; +static int rk3288_pinctrl_bind(struct udevice *dev) +{ + /* scan child GPIO banks */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + static int rk3288_pinctrl_probe(struct udevice *dev) { struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); @@ -437,5 +444,6 @@ U_BOOT_DRIVER(pinctrl_rk3288) = { .of_match = rk3288_pinctrl_ids, .priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv), .ops = &rk3288_pinctrl_ops, + .bind = rk3288_pinctrl_bind, .probe = rk3288_pinctrl_probe, }; diff --git a/drivers/pinctrl/uniphier/Kconfig b/drivers/pinctrl/uniphier/Kconfig new file mode 100644 index 0000000000..2ff616e946 --- /dev/null +++ b/drivers/pinctrl/uniphier/Kconfig @@ -0,0 +1,42 @@ +if ARCH_UNIPHIER + +config PINCTRL_UNIPHIER_CORE + bool + +config PINCTRL_UNIPHIER_PH1_LD4 + bool "UniPhier PH1-LD4 SoC pinctrl driver" + depends on ARCH_UNIPHIER_PH1_LD4 + default y + select PINCTRL_UNIPHIER_CORE + +config PINCTRL_UNIPHIER_PH1_PRO4 + bool "UniPhier PH1-Pro4 SoC pinctrl driver" + depends on ARCH_UNIPHIER_PH1_PRO4 + default y + select PINCTRL_UNIPHIER_CORE + +config PINCTRL_UNIPHIER_PH1_SLD8 + bool "UniPhier PH1-sLD8 SoC pinctrl driver" + depends on ARCH_UNIPHIER_PH1_SLD8 + default y + select PINCTRL_UNIPHIER_CORE + +config PINCTRL_UNIPHIER_PH1_PRO5 + bool "UniPhier PH1-Pro5 SoC pinctrl driver" + depends on ARCH_UNIPHIER_PH1_PRO5 + default y + select PINCTRL_UNIPHIER_CORE + +config PINCTRL_UNIPHIER_PROXSTREAM2 + bool "UniPhier ProXstream2 SoC pinctrl driver" + depends on ARCH_UNIPHIER_PROXSTREAM2 + default y + select PINCTRL_UNIPHIER_CORE + +config PINCTRL_UNIPHIER_PH1_LD6B + bool "UniPhier PH1-LD6b SoC pinctrl driver" + depends on ARCH_UNIPHIER_PH1_LD6B + default y + select PINCTRL_UNIPHIER_CORE + +endif diff --git a/drivers/pinctrl/uniphier/Makefile b/drivers/pinctrl/uniphier/Makefile new file mode 100644 index 0000000000..e215b10972 --- /dev/null +++ b/drivers/pinctrl/uniphier/Makefile @@ -0,0 +1,8 @@ +obj-$(CONFIG_PINCTRL_UNIPHIER_CORE) += pinctrl-uniphier-core.o + +obj-$(CONFIG_PINCTRL_UNIPHIER_PH1_LD4) += pinctrl-ph1-ld4.o +obj-$(CONFIG_PINCTRL_UNIPHIER_PH1_PRO4) += pinctrl-ph1-pro4.o +obj-$(CONFIG_PINCTRL_UNIPHIER_PH1_SLD8) += pinctrl-ph1-sld8.o +obj-$(CONFIG_PINCTRL_UNIPHIER_PH1_PRO5) += pinctrl-ph1-pro5.o +obj-$(CONFIG_PINCTRL_UNIPHIER_PROXSTREAM2) += pinctrl-proxstream2.o +obj-$(CONFIG_PINCTRL_UNIPHIER_PH1_LD6B) += pinctrl-ph1-ld6b.o diff --git a/drivers/pinctrl/uniphier/pinctrl-ph1-ld4.c b/drivers/pinctrl/uniphier/pinctrl-ph1-ld4.c new file mode 100644 index 0000000000..b3d47f0915 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-ph1-ld4.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin ph1_ld4_pins[] = { + UNIPHIER_PINCTRL_PIN(53, 0), + UNIPHIER_PINCTRL_PIN(54, 0), + UNIPHIER_PINCTRL_PIN(55, 0), + UNIPHIER_PINCTRL_PIN(56, 0), + UNIPHIER_PINCTRL_PIN(67, 0), + UNIPHIER_PINCTRL_PIN(68, 0), + UNIPHIER_PINCTRL_PIN(69, 0), + UNIPHIER_PINCTRL_PIN(70, 0), + UNIPHIER_PINCTRL_PIN(85, 0), + UNIPHIER_PINCTRL_PIN(88, 0), + UNIPHIER_PINCTRL_PIN(156, 0), +}; + +static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27}; +static const unsigned emmc_muxvals[] = {0, 1, 1, 1, 1, 1, 1}; +static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31}; +static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned i2c0_pins[] = {102, 103}; +static const unsigned i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {104, 105}; +static const unsigned i2c1_muxvals[] = {0, 0}; +static const unsigned i2c2_pins[] = {108, 109}; +static const unsigned i2c2_muxvals[] = {2, 2}; +static const unsigned i2c3_pins[] = {108, 109}; +static const unsigned i2c3_muxvals[] = {3, 3}; +static const unsigned nand_pins[] = {24, 25, 26, 27, 28, 29, 30, 31, 158, 159, + 160, 161, 162, 163, 164}; +static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}; +static const unsigned nand_cs1_pins[] = {22, 23}; +static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const unsigned sd_pins[] = {44, 45, 46, 47, 48, 49, 50, 51, 52}; +static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned uart0_pins[] = {85, 88}; +static const unsigned uart0_muxvals[] = {1, 1}; +static const unsigned uart1_pins[] = {155, 156}; +static const unsigned uart1_muxvals[] = {13, 13}; +static const unsigned uart1b_pins[] = {69, 70}; +static const unsigned uart1b_muxvals[] = {23, 23}; +static const unsigned uart2_pins[] = {128, 129}; +static const unsigned uart2_muxvals[] = {13, 13}; +static const unsigned uart3_pins[] = {110, 111}; +static const unsigned uart3_muxvals[] = {1, 1}; +static const unsigned usb0_pins[] = {53, 54}; +static const unsigned usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {55, 56}; +static const unsigned usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {155, 156}; +static const unsigned usb2_muxvals[] = {4, 4}; +static const unsigned usb2b_pins[] = {67, 68}; +static const unsigned usb2b_muxvals[] = {23, 23}; + +static const struct uniphier_pinctrl_group ph1_ld4_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart1b), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP(usb2b), +}; + +static const char * const ph1_ld4_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "nand", + "sd", + "uart0", + "uart1", + "uart2", + "uart3", + "usb0", + "usb1", + "usb2", +}; + +static struct uniphier_pinctrl_socdata ph1_ld4_pinctrl_socdata = { + .pins = ph1_ld4_pins, + .pins_count = ARRAY_SIZE(ph1_ld4_pins), + .groups = ph1_ld4_groups, + .groups_count = ARRAY_SIZE(ph1_ld4_groups), + .functions = ph1_ld4_functions, + .functions_count = ARRAY_SIZE(ph1_ld4_functions), + .mux_bits = 8, + .reg_stride = 4, + .load_pinctrl = false, +}; + +static int ph1_ld4_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &ph1_ld4_pinctrl_socdata); +} + +static const struct udevice_id ph1_ld4_pinctrl_match[] = { + { .compatible = "socionext,ph1-ld4-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ph1_ld4_pinctrl) = { + .name = "ph1-ld4-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ph1_ld4_pinctrl_match), + .probe = ph1_ld4_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-ph1-ld6b.c b/drivers/pinctrl/uniphier/pinctrl-ph1-ld6b.c new file mode 100644 index 0000000000..8703a215e4 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-ph1-ld6b.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin ph1_ld6b_pins[] = { + UNIPHIER_PINCTRL_PIN(113, 0), + UNIPHIER_PINCTRL_PIN(114, 0), + UNIPHIER_PINCTRL_PIN(115, 0), + UNIPHIER_PINCTRL_PIN(116, 0), + UNIPHIER_PINCTRL_PIN(217, 0), + UNIPHIER_PINCTRL_PIN(218, 0), + UNIPHIER_PINCTRL_PIN(219, 0), + UNIPHIER_PINCTRL_PIN(220, 0), +}; + +static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; +static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; +static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned i2c0_pins[] = {109, 110}; +static const unsigned i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {111, 112}; +static const unsigned i2c1_muxvals[] = {0, 0}; +static const unsigned i2c2_pins[] = {115, 116}; +static const unsigned i2c2_muxvals[] = {1, 1}; +static const unsigned i2c3_pins[] = {118, 119}; +static const unsigned i2c3_muxvals[] = {1, 1}; +static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41, + 42, 43, 44, 45, 46}; +static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}; +static const unsigned nand_cs1_pins[] = {37, 38}; +static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55}; +static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned uart0_pins[] = {135, 136}; +static const unsigned uart0_muxvals[] = {3, 3}; +static const unsigned uart0b_pins[] = {11, 12}; +static const unsigned uart0b_muxvals[] = {2, 2}; +static const unsigned uart1_pins[] = {115, 116}; +static const unsigned uart1_muxvals[] = {0, 0}; +static const unsigned uart1b_pins[] = {113, 114}; +static const unsigned uart1b_muxvals[] = {1, 1}; +static const unsigned uart2_pins[] = {113, 114}; +static const unsigned uart2_muxvals[] = {2, 2}; +static const unsigned uart2b_pins[] = {86, 87}; +static const unsigned uart2b_muxvals[] = {1, 1}; +static const unsigned usb0_pins[] = {56, 57}; +static const unsigned usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {58, 59}; +static const unsigned usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {60, 61}; +static const unsigned usb2_muxvals[] = {0, 0}; +static const unsigned usb3_pins[] = {62, 63}; +static const unsigned usb3_muxvals[] = {0, 0}; + +static const struct uniphier_pinctrl_group ph1_ld6b_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart0b), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart1b), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart2b), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP(usb3), +}; + +static const char * const ph1_ld6b_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "nand", + "sd", + "uart0", + "uart1", + "uart2", + "usb0", + "usb1", + "usb2", + "usb3", +}; + +static struct uniphier_pinctrl_socdata ph1_ld6b_pinctrl_socdata = { + .pins = ph1_ld6b_pins, + .pins_count = ARRAY_SIZE(ph1_ld6b_pins), + .groups = ph1_ld6b_groups, + .groups_count = ARRAY_SIZE(ph1_ld6b_groups), + .functions = ph1_ld6b_functions, + .functions_count = ARRAY_SIZE(ph1_ld6b_functions), + .mux_bits = 8, + .reg_stride = 4, + .load_pinctrl = false, +}; + +static int ph1_ld6b_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &ph1_ld6b_pinctrl_socdata); +} + +static const struct udevice_id ph1_ld6b_pinctrl_match[] = { + { .compatible = "socionext,ph1-ld6b-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ph1_ld6b_pinctrl) = { + .name = "ph1-ld6b-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ph1_ld6b_pinctrl_match), + .probe = ph1_ld6b_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-ph1-pro4.c b/drivers/pinctrl/uniphier/pinctrl-ph1-pro4.c new file mode 100644 index 0000000000..b3eaf138f7 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-ph1-pro4.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin ph1_pro4_pins[] = { +}; + +static const unsigned emmc_pins[] = {40, 41, 42, 43, 51, 52, 53}; +static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const unsigned emmc_dat8_pins[] = {44, 45, 46, 47}; +static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned i2c0_pins[] = {142, 143}; +static const unsigned i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {144, 145}; +static const unsigned i2c1_muxvals[] = {0, 0}; +static const unsigned i2c2_pins[] = {146, 147}; +static const unsigned i2c2_muxvals[] = {0, 0}; +static const unsigned i2c3_pins[] = {148, 149}; +static const unsigned i2c3_muxvals[] = {0, 0}; +static const unsigned i2c6_pins[] = {308, 309}; +static const unsigned i2c6_muxvals[] = {6, 6}; +static const unsigned nand_pins[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54}; +static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}; +static const unsigned nand_cs1_pins[] = {131, 132}; +static const unsigned nand_cs1_muxvals[] = {1, 1}; +static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158}; +static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326, + 327}; +static const unsigned sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned uart0_pins[] = {127, 128}; +static const unsigned uart0_muxvals[] = {0, 0}; +static const unsigned uart1_pins[] = {129, 130}; +static const unsigned uart1_muxvals[] = {0, 0}; +static const unsigned uart2_pins[] = {131, 132}; +static const unsigned uart2_muxvals[] = {0, 0}; +static const unsigned uart3_pins[] = {88, 89}; +static const unsigned uart3_muxvals[] = {2, 2}; +static const unsigned usb0_pins[] = {180, 181}; +static const unsigned usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {182, 183}; +static const unsigned usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {184, 185}; +static const unsigned usb2_muxvals[] = {0, 0}; +static const unsigned usb3_pins[] = {186, 187}; +static const unsigned usb3_muxvals[] = {0, 0}; + +static const struct uniphier_pinctrl_group ph1_pro4_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(i2c6), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(sd1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP(usb3), +}; + +static const char * const ph1_pro4_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "i2c6", + "nand", + "sd", + "sd1", + "uart0", + "uart1", + "uart2", + "uart3", + "usb0", + "usb1", + "usb2", + "usb3", +}; + +static struct uniphier_pinctrl_socdata ph1_pro4_pinctrl_socdata = { + .pins = ph1_pro4_pins, + .pins_count = ARRAY_SIZE(ph1_pro4_pins), + .groups = ph1_pro4_groups, + .groups_count = ARRAY_SIZE(ph1_pro4_groups), + .functions = ph1_pro4_functions, + .functions_count = ARRAY_SIZE(ph1_pro4_functions), + .mux_bits = 4, + .reg_stride = 8, + .load_pinctrl = true, +}; + +static int ph1_pro4_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &ph1_pro4_pinctrl_socdata); +} + +static const struct udevice_id ph1_pro4_pinctrl_match[] = { + { .compatible = "socionext,ph1-pro4-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ph1_pro4_pinctrl) = { + .name = "ph1-pro4-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ph1_pro4_pinctrl_match), + .probe = ph1_pro4_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-ph1-pro5.c b/drivers/pinctrl/uniphier/pinctrl-ph1-pro5.c new file mode 100644 index 0000000000..3749250066 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-ph1-pro5.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin ph1_pro5_pins[] = { + UNIPHIER_PINCTRL_PIN(47, 0), + UNIPHIER_PINCTRL_PIN(48, 0), + UNIPHIER_PINCTRL_PIN(49, 0), + UNIPHIER_PINCTRL_PIN(50, 0), + UNIPHIER_PINCTRL_PIN(53, 0), + UNIPHIER_PINCTRL_PIN(54, 0), + UNIPHIER_PINCTRL_PIN(87, 0), + UNIPHIER_PINCTRL_PIN(88, 0), + UNIPHIER_PINCTRL_PIN(101, 0), + UNIPHIER_PINCTRL_PIN(102, 0), +}; + +static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; +static const unsigned emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0}; +static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; +static const unsigned emmc_dat8_muxvals[] = {0, 0, 0, 0}; +static const unsigned i2c0_pins[] = {112, 113}; +static const unsigned i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {114, 115}; +static const unsigned i2c1_muxvals[] = {0, 0}; +static const unsigned i2c2_pins[] = {116, 117}; +static const unsigned i2c2_muxvals[] = {0, 0}; +static const unsigned i2c3_pins[] = {118, 119}; +static const unsigned i2c3_muxvals[] = {0, 0}; +static const unsigned i2c5_pins[] = {87, 88}; +static const unsigned i2c5_muxvals[] = {2, 2}; +static const unsigned i2c5b_pins[] = {196, 197}; +static const unsigned i2c5b_muxvals[] = {2, 2}; +static const unsigned i2c5c_pins[] = {215, 216}; +static const unsigned i2c5c_muxvals[] = {2, 2}; +static const unsigned i2c6_pins[] = {101, 102}; +static const unsigned i2c6_muxvals[] = {2, 2}; +static const unsigned nand_pins[] = {19, 20, 21, 22, 23, 24, 25, 28, 29, 30, + 31, 32, 33, 34, 35}; +static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}; +static const unsigned nand_cs1_pins[] = {26, 27}; +static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const unsigned sd_pins[] = {250, 251, 252, 253, 254, 255, 256, 257, 258}; +static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned uart0_pins[] = {47, 48}; +static const unsigned uart0_muxvals[] = {0, 0}; +static const unsigned uart0b_pins[] = {227, 228}; +static const unsigned uart0b_muxvals[] = {3, 3}; +static const unsigned uart1_pins[] = {49, 50}; +static const unsigned uart1_muxvals[] = {0, 0}; +static const unsigned uart2_pins[] = {51, 52}; +static const unsigned uart2_muxvals[] = {0, 0}; +static const unsigned uart3_pins[] = {53, 54}; +static const unsigned uart3_muxvals[] = {0, 0}; +static const unsigned usb0_pins[] = {124, 125}; +static const unsigned usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {126, 127}; +static const unsigned usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {128, 129}; +static const unsigned usb2_muxvals[] = {0, 0}; + +static const struct uniphier_pinctrl_group ph1_pro5_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(i2c5), + UNIPHIER_PINCTRL_GROUP(i2c5b), + UNIPHIER_PINCTRL_GROUP(i2c5c), + UNIPHIER_PINCTRL_GROUP(i2c6), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart0b), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), +}; + +static const char * const ph1_pro5_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "i2c5", + "i2c6", + "nand", + "sd", + "uart0", + "uart1", + "uart2", + "uart3", + "usb0", + "usb1", + "usb2", +}; + +static struct uniphier_pinctrl_socdata ph1_pro5_pinctrl_socdata = { + .pins = ph1_pro5_pins, + .pins_count = ARRAY_SIZE(ph1_pro5_pins), + .groups = ph1_pro5_groups, + .groups_count = ARRAY_SIZE(ph1_pro5_groups), + .functions = ph1_pro5_functions, + .functions_count = ARRAY_SIZE(ph1_pro5_functions), + .mux_bits = 4, + .reg_stride = 8, + .load_pinctrl = true, +}; + +static int ph1_pro5_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &ph1_pro5_pinctrl_socdata); +} + +static const struct udevice_id ph1_pro5_pinctrl_match[] = { + { .compatible = "socionext,ph1-pro5-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ph1_pro5_pinctrl) = { + .name = "ph1-pro5-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ph1_pro5_pinctrl_match), + .probe = ph1_pro5_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-ph1-sld8.c b/drivers/pinctrl/uniphier/pinctrl-ph1-sld8.c new file mode 100644 index 0000000000..5fafdb6100 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-ph1-sld8.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin ph1_sld8_pins[] = { + UNIPHIER_PINCTRL_PIN(32, 8), + UNIPHIER_PINCTRL_PIN(33, 8), + UNIPHIER_PINCTRL_PIN(34, 8), + UNIPHIER_PINCTRL_PIN(35, 8), + UNIPHIER_PINCTRL_PIN(36, 8), + UNIPHIER_PINCTRL_PIN(37, 8), + UNIPHIER_PINCTRL_PIN(38, 8), + UNIPHIER_PINCTRL_PIN(39, 8), + UNIPHIER_PINCTRL_PIN(40, 9), + UNIPHIER_PINCTRL_PIN(41, 0), + UNIPHIER_PINCTRL_PIN(42, 0), + UNIPHIER_PINCTRL_PIN(43, 0), + UNIPHIER_PINCTRL_PIN(44, 0), + UNIPHIER_PINCTRL_PIN(70, 0), + UNIPHIER_PINCTRL_PIN(71, 0), + UNIPHIER_PINCTRL_PIN(102, 10), + UNIPHIER_PINCTRL_PIN(103, 10), + UNIPHIER_PINCTRL_PIN(104, 11), + UNIPHIER_PINCTRL_PIN(105, 11), + UNIPHIER_PINCTRL_PIN(108, 13), + UNIPHIER_PINCTRL_PIN(109, 13), + UNIPHIER_PINCTRL_PIN(112, 0), + UNIPHIER_PINCTRL_PIN(113, 0), + UNIPHIER_PINCTRL_PIN(114, 0), + UNIPHIER_PINCTRL_PIN(115, 0), +}; + +static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27}; +static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31}; +static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned i2c0_pins[] = {102, 103}; +static const unsigned i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {104, 105}; +static const unsigned i2c1_muxvals[] = {0, 0}; +static const unsigned i2c2_pins[] = {108, 109}; +static const unsigned i2c2_muxvals[] = {2, 2}; +static const unsigned i2c3_pins[] = {108, 109}; +static const unsigned i2c3_muxvals[] = {3, 3}; +static const unsigned nand_pins[] = {15, 16, 17, 18, 19, 20, 21, 24, 25, 26, + 27, 28, 29, 30, 31}; +static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0}; +static const unsigned nand_cs1_pins[] = {22, 23}; +static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const unsigned sd_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40}; +static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned uart0_pins[] = {70, 71}; +static const unsigned uart0_muxvals[] = {3, 3}; +static const unsigned uart1_pins[] = {114, 115}; +static const unsigned uart1_muxvals[] = {0, 0}; +static const unsigned uart2_pins[] = {112, 113}; +static const unsigned uart2_muxvals[] = {1, 1}; +static const unsigned uart3_pins[] = {110, 111}; +static const unsigned uart3_muxvals[] = {1, 1}; +static const unsigned usb0_pins[] = {41, 42}; +static const unsigned usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {43, 44}; +static const unsigned usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {114, 115}; +static const unsigned usb2_muxvals[] = {1, 1}; + +static const struct uniphier_pinctrl_group ph1_sld8_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), +}; + +static const char * const ph1_sld8_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "nand", + "sd", + "uart0", + "uart1", + "uart2", + "uart3", + "usb0", + "usb1", + "usb2", +}; + +static struct uniphier_pinctrl_socdata ph1_sld8_pinctrl_socdata = { + .pins = ph1_sld8_pins, + .pins_count = ARRAY_SIZE(ph1_sld8_pins), + .groups = ph1_sld8_groups, + .groups_count = ARRAY_SIZE(ph1_sld8_groups), + .functions = ph1_sld8_functions, + .functions_count = ARRAY_SIZE(ph1_sld8_functions), + .mux_bits = 8, + .reg_stride = 4, + .load_pinctrl = false, +}; + +static int ph1_sld8_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &ph1_sld8_pinctrl_socdata); +} + +static const struct udevice_id ph1_sld8_pinctrl_match[] = { + { .compatible = "socionext,ph1-sld8-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ph1_sld8_pinctrl) = { + .name = "ph1-sld8-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(ph1_sld8_pinctrl_match), + .probe = ph1_sld8_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-proxstream2.c b/drivers/pinctrl/uniphier/pinctrl-proxstream2.c new file mode 100644 index 0000000000..2cca69d514 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-proxstream2.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static const struct uniphier_pinctrl_pin proxstream2_pins[] = { + UNIPHIER_PINCTRL_PIN(113, 0), + UNIPHIER_PINCTRL_PIN(114, 0), + UNIPHIER_PINCTRL_PIN(115, 0), + UNIPHIER_PINCTRL_PIN(116, 0), +}; + +static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; +static const unsigned emmc_muxvals[] = {9, 9, 9, 9, 9, 9, 9}; +static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; +static const unsigned emmc_dat8_muxvals[] = {9, 9, 9, 9}; +static const unsigned i2c0_pins[] = {109, 110}; +static const unsigned i2c0_muxvals[] = {8, 8}; +static const unsigned i2c1_pins[] = {111, 112}; +static const unsigned i2c1_muxvals[] = {8, 8}; +static const unsigned i2c2_pins[] = {171, 172}; +static const unsigned i2c2_muxvals[] = {8, 8}; +static const unsigned i2c3_pins[] = {159, 160}; +static const unsigned i2c3_muxvals[] = {8, 8}; +static const unsigned i2c5_pins[] = {183, 184}; +static const unsigned i2c5_muxvals[] = {11, 11}; +static const unsigned i2c6_pins[] = {185, 186}; +static const unsigned i2c6_muxvals[] = {11, 11}; +static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41, + 42, 43, 44, 45, 46}; +static const unsigned nand_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8}; +static const unsigned nand_cs1_pins[] = {37, 38}; +static const unsigned nand_cs1_muxvals[] = {8, 8}; +static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55}; +static const unsigned sd_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8}; +static const unsigned uart0_pins[] = {217, 218}; +static const unsigned uart0_muxvals[] = {8, 8}; +static const unsigned uart0b_pins[] = {179, 180}; +static const unsigned uart0b_muxvals[] = {10, 10}; +static const unsigned uart1_pins[] = {115, 116}; +static const unsigned uart1_muxvals[] = {8, 8}; +static const unsigned uart2_pins[] = {113, 114}; +static const unsigned uart2_muxvals[] = {8, 8}; +static const unsigned uart3_pins[] = {219, 220}; +static const unsigned uart3_muxvals[] = {8, 8}; +static const unsigned uart3b_pins[] = {181, 182}; +static const unsigned uart3b_muxvals[] = {10, 10}; +static const unsigned usb0_pins[] = {56, 57}; +static const unsigned usb0_muxvals[] = {8, 8}; +static const unsigned usb1_pins[] = {58, 59}; +static const unsigned usb1_muxvals[] = {8, 8}; +static const unsigned usb2_pins[] = {60, 61}; +static const unsigned usb2_muxvals[] = {8, 8}; +static const unsigned usb3_pins[] = {62, 63}; +static const unsigned usb3_muxvals[] = {8, 8}; + +static const struct uniphier_pinctrl_group proxstream2_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c2), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(i2c5), + UNIPHIER_PINCTRL_GROUP(i2c6), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(nand_cs1), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart0b), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(uart3b), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP(usb3), +}; + +static const char * const proxstream2_functions[] = { + "emmc", + "i2c0", + "i2c1", + "i2c2", + "i2c3", + "i2c5", + "i2c6", + "nand", + "sd", + "uart0", + "uart0b", + "uart1", + "uart2", + "uart3", + "uart3b", + "usb0", + "usb1", + "usb2", + "usb3", +}; + +static struct uniphier_pinctrl_socdata proxstream2_pinctrl_socdata = { + .pins = proxstream2_pins, + .pins_count = ARRAY_SIZE(proxstream2_pins), + .groups = proxstream2_groups, + .groups_count = ARRAY_SIZE(proxstream2_groups), + .functions = proxstream2_functions, + .functions_count = ARRAY_SIZE(proxstream2_functions), + .mux_bits = 8, + .reg_stride = 4, + .load_pinctrl = false, +}; + +static int proxstream2_pinctrl_probe(struct udevice *dev) +{ + return uniphier_pinctrl_probe(dev, &proxstream2_pinctrl_socdata); +} + +static const struct udevice_id proxstream2_pinctrl_match[] = { + { .compatible = "socionext,proxstream2-pinctrl" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(proxstream2_pinctrl) = { + .name = "proxstream2-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(proxstream2_pinctrl_match), + .probe = proxstream2_pinctrl_probe, + .remove = uniphier_pinctrl_remove, + .priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv), + .ops = &uniphier_pinctrl_ops, +}; diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c new file mode 100644 index 0000000000..37a920ca8b --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mapmem.h> +#include <linux/io.h> +#include <linux/err.h> +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +DECLARE_GLOBAL_DATA_PTR; + +static int uniphier_pinctrl_get_groups_count(struct udevice *dev) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->socdata->groups_count; +} + +static const char *uniphier_pinctrl_get_group_name(struct udevice *dev, + unsigned selector) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->socdata->groups[selector].name; +} + +static int uniphier_pinmux_get_functions_count(struct udevice *dev) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->socdata->functions_count; +} + +static const char *uniphier_pinmux_get_function_name(struct udevice *dev, + unsigned selector) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->socdata->functions[selector]; +} + +static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + int pins_count = priv->socdata->pins_count; + const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; + int i; + + for (i = 0; i < pins_count; i++) { + if (pins[i].number == pin) { + unsigned int iectrl; + u32 tmp; + + iectrl = uniphier_pin_get_iectrl(pins[i].data); + tmp = readl(priv->base + UNIPHIER_PINCTRL_IECTRL); + tmp |= 1 << iectrl; + writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL); + } + } +} + +static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, + unsigned muxval) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + unsigned mux_bits = priv->socdata->mux_bits; + unsigned reg_stride = priv->socdata->reg_stride; + unsigned reg, reg_end, shift, mask; + u32 tmp; + + reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; + reg_end = reg + reg_stride; + shift = pin * mux_bits % 32; + mask = (1U << mux_bits) - 1; + + /* + * If reg_stride is greater than 4, the MSB of each pinsel shall be + * stored in the offset+4. + */ + for (; reg < reg_end; reg += 4) { + tmp = readl(priv->base + reg); + tmp &= ~(mask << shift); + tmp |= (mask & muxval) << shift; + writel(tmp, priv->base + reg); + + muxval >>= mux_bits; + } + + if (priv->socdata->load_pinctrl) + writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX); + + /* some pins need input-enabling */ + uniphier_pinconf_input_enable(dev, pin); +} + +static int uniphier_pinmux_group_set(struct udevice *dev, + unsigned group_selector, + unsigned func_selector) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + const struct uniphier_pinctrl_group *grp = + &priv->socdata->groups[group_selector]; + int i; + + for (i = 0; i < grp->num_pins; i++) + uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]); + + return 0; +} + +const struct pinctrl_ops uniphier_pinctrl_ops = { + .get_groups_count = uniphier_pinctrl_get_groups_count, + .get_group_name = uniphier_pinctrl_get_group_name, + .get_functions_count = uniphier_pinmux_get_functions_count, + .get_function_name = uniphier_pinmux_get_function_name, + .pinmux_group_set = uniphier_pinmux_group_set, + .set_state = pinctrl_generic_set_state, +}; + +int uniphier_pinctrl_probe(struct udevice *dev, + struct uniphier_pinctrl_socdata *socdata) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + fdt_addr_t addr; + fdt_size_t size; + + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", + &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = map_sysmem(addr, size); + if (!priv->base) + return -ENOMEM; + + priv->socdata = socdata; + + return 0; +} + +int uniphier_pinctrl_remove(struct udevice *dev) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + unmap_sysmem(priv->base); + + return 0; +} diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h new file mode 100644 index 0000000000..7eaec6a702 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PINCTRL_UNIPHIER_H__ +#define __PINCTRL_UNIPHIER_H__ + +/* TODO: move this to include/linux/bug.h */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) + +#include <linux/kernel.h> +#include <linux/types.h> + +#define UNIPHIER_PINCTRL_PINMUX_BASE 0x0 +#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 +#define UNIPHIER_PINCTRL_IECTRL 0xd00 + +#define UNIPHIER_PIN_ATTR_PACKED(iectrl) (iectrl) + +static inline unsigned int uniphier_pin_get_iectrl(unsigned long data) +{ + return data; +} + +/** + * struct uniphier_pinctrl_pin - pin data for UniPhier SoC + * + * @number: pin number + * @data: additional per-pin data + */ +struct uniphier_pinctrl_pin { + unsigned number; + unsigned long data; +}; + +/** + * struct uniphier_pinctrl_group - pin group data for UniPhier SoC + * + * @name: pin group name + * @pins: array of pins that belong to the group + * @num_pins: number of pins in the group + * @muxvals: array of values to be set to pinmux registers + */ +struct uniphier_pinctrl_group { + const char *name; + const unsigned *pins; + unsigned num_pins; + const unsigned *muxvals; +}; + +/** + * struct uniphier_pinctrl_socdata - SoC data for UniPhier pin controller + * + * @pins: array of pin data + * @pins_count: number of pin data + * @groups: array of pin group data + * @groups_count: number of pin group data + * @functions: array of pinmux function names + * @functions_count: number of pinmux functions + * @mux_bits: bit width of each pinmux register + * @reg_stride: stride of pinmux register address + * @load_pinctrl: if true, LOAD_PINMUX register must be set to one for new + * values in pinmux registers to become really effective + */ +struct uniphier_pinctrl_socdata { + const struct uniphier_pinctrl_pin *pins; + int pins_count; + const struct uniphier_pinctrl_group *groups; + int groups_count; + const char * const *functions; + int functions_count; + unsigned mux_bits; + unsigned reg_stride; + bool load_pinctrl; +}; + +#define UNIPHIER_PINCTRL_PIN(a, b) \ +{ \ + .number = a, \ + .data = UNIPHIER_PIN_ATTR_PACKED(b), \ +} + +#define UNIPHIER_PINCTRL_GROUP(grp) \ + { \ + .name = #grp, \ + .pins = grp##_pins, \ + .num_pins = ARRAY_SIZE(grp##_pins), \ + .muxvals = grp##_muxvals + \ + BUILD_BUG_ON_ZERO(ARRAY_SIZE(grp##_pins) != \ + ARRAY_SIZE(grp##_muxvals)), \ + } + +/** + * struct uniphier_pinctrl_priv - private data for UniPhier pinctrl driver + * + * @base: base address of the pinctrl device + * @socdata: SoC specific data + */ +struct uniphier_pinctrl_priv { + void __iomem *base; + struct uniphier_pinctrl_socdata *socdata; +}; + +extern const struct pinctrl_ops uniphier_pinctrl_ops; + +int uniphier_pinctrl_probe(struct udevice *dev, + struct uniphier_pinctrl_socdata *socdata); + +int uniphier_pinctrl_remove(struct udevice *dev); + +#endif /* __PINCTRL_UNIPHIER_H__ */ diff --git a/include/bitfield.h b/include/bitfield.h index b884c74600..a59f3c279a 100644 --- a/include/bitfield.h +++ b/include/bitfield.h @@ -27,6 +27,12 @@ * old = bitfield_extract(old_reg_val, 10, 5); * new_reg_val = bitfield_replace(old_reg_val, 10, 5, new); * + * or + * + * mask = bitfield_mask(10, 5); + * old = bitfield_extract_by_mask(old_reg_val, mask); + * new_reg_val = bitfield_replace_by_mask(old_reg_val, mask, new); + * * The numbers 10 and 5 could for example come from data * tables which describe all bitfields in all registers. */ @@ -56,3 +62,29 @@ static inline uint bitfield_replace(uint reg_val, uint shift, uint width, return (reg_val & ~mask) | ((bitfield_val << shift) & mask); } + +/* Produces a shift of the bitfield given a mask */ +static inline uint bitfield_shift(uint mask) +{ + return mask ? ffs(mask) - 1 : 0; +} + +/* Extract the value of a bitfield found within a given register value */ +static inline uint bitfield_extract_by_mask(uint reg_val, uint mask) +{ + uint shift = bitfield_shift(mask); + + return (reg_val & mask) >> shift; +} + +/* + * Replace the value of a bitfield found within a given register value + * Returns the newly modified uint value with the replaced field. + */ +static inline uint bitfield_replace_by_mask(uint reg_val, uint mask, + uint bitfield_val) +{ + uint shift = bitfield_shift(mask); + + return (reg_val & ~mask) | ((bitfield_val << shift) & mask); +} diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index cd5b3e2ada..5b61b56a4e 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -759,7 +759,7 @@ $(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg /* Enable VSC9953 L2 Switch driver on T1040 SoC */ #if defined(CONFIG_T1040RDB) || defined(CONFIG_T1040D4RDB) #define CONFIG_VSC9953 -#define CONFIG_VSC9953_CMD +#define CONFIG_CMD_ETHSW #ifdef CONFIG_T1040RDB #define CONFIG_SYS_FM1_QSGMII11_PHY_ADDR 0x04 #define CONFIG_SYS_FM1_QSGMII21_PHY_ADDR 0x08 diff --git a/include/configs/socfpga_arria5.h b/include/configs/socfpga_arria5_socdk.h index 3193684798..b75b0a27fa 100644 --- a/include/configs/socfpga_arria5.h +++ b/include/configs/socfpga_arria5_socdk.h @@ -59,6 +59,10 @@ #endif +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* device 0 */ +#define CONFIG_ENV_OFFSET 512 /* just after the MBR */ + /* USB */ #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2_REG_ADDR SOCFPGA_USB1_ADDRESS diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 38ae763653..cece0950e2 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -73,7 +73,6 @@ /* * Cache */ -#define CONFIG_SYS_ARM_CACHE_WRITEALLOC #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE SOCFPGA_MPUL2_ADDRESS @@ -282,7 +281,6 @@ unsigned int cm_get_qspi_controller_clk_hz(void); #define CONFIG_SYS_CONSOLE_IS_IN_ENV #define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE #define CONFIG_SYS_CONSOLE_ENV_OVERWRITE -#define CONFIG_ENV_IS_NOWHERE #define CONFIG_ENV_SIZE 4096 /* diff --git a/include/configs/socfpga_cyclone5.h b/include/configs/socfpga_cyclone5_socdk.h index 9e733e5c48..fa67b25a79 100644 --- a/include/configs/socfpga_cyclone5.h +++ b/include/configs/socfpga_cyclone5_socdk.h @@ -59,6 +59,10 @@ #endif +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* device 0 */ +#define CONFIG_ENV_OFFSET 512 /* just after the MBR */ + /* USB */ #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2_REG_ADDR SOCFPGA_USB1_ADDRESS diff --git a/include/configs/socfpga_de0_nano_soc.h b/include/configs/socfpga_de0_nano_soc.h index 2508d037e3..191e1f7a43 100644 --- a/include/configs/socfpga_de0_nano_soc.h +++ b/include/configs/socfpga_de0_nano_soc.h @@ -55,6 +55,10 @@ #endif +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* device 0 */ +#define CONFIG_ENV_OFFSET 512 /* just after the MBR */ + /* USB */ #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2_REG_ADDR SOCFPGA_USB1_ADDRESS diff --git a/include/configs/socfpga_mcvevk.h b/include/configs/socfpga_mcvevk.h index c5b4b4ca9d..65816a05cf 100644 --- a/include/configs/socfpga_mcvevk.h +++ b/include/configs/socfpga_mcvevk.h @@ -43,6 +43,12 @@ #define CONFIG_LOADADDR 0x01000000 #define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR +/* Environment is in MMC */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* device 0 */ +#define CONFIG_ENV_OFFSET 512 /* just after the MBR */ + /* USB */ #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2_REG_ADDR SOCFPGA_USB1_ADDRESS diff --git a/include/configs/socfpga_sockit.h b/include/configs/socfpga_sockit.h index 747e988ac9..6c71ef4e23 100644 --- a/include/configs/socfpga_sockit.h +++ b/include/configs/socfpga_sockit.h @@ -59,6 +59,10 @@ #endif +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 /* device 0 */ +#define CONFIG_ENV_OFFSET 512 /* just after the MBR */ + /* USB */ #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2_REG_ADDR SOCFPGA_USB1_ADDRESS diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index d59564bafd..9109b7f8d9 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -9,73 +9,9 @@ #ifndef __CONFIG_UNIPHIER_COMMON_H__ #define __CONFIG_UNIPHIER_COMMON_H__ -#if defined(CONFIG_MACH_PH1_SLD3) -#define CONFIG_DDR_NUM_CH0 2 -#define CONFIG_DDR_NUM_CH1 1 -#define CONFIG_DDR_NUM_CH2 1 - -/* Physical start address of SDRAM */ -#define CONFIG_SDRAM0_BASE 0x80000000 -#define CONFIG_SDRAM0_SIZE 0x20000000 -#define CONFIG_SDRAM1_BASE 0xc0000000 -#define CONFIG_SDRAM1_SIZE 0x20000000 -#define CONFIG_SDRAM2_BASE 0xc0000000 -#define CONFIG_SDRAM2_SIZE 0x10000000 -#endif - -#if defined(CONFIG_MACH_PH1_LD4) -#define CONFIG_DDR_NUM_CH0 1 -#define CONFIG_DDR_NUM_CH1 1 - -/* Physical start address of SDRAM */ -#define CONFIG_SDRAM0_BASE 0x80000000 -#define CONFIG_SDRAM0_SIZE 0x10000000 -#define CONFIG_SDRAM1_BASE 0x90000000 -#define CONFIG_SDRAM1_SIZE 0x10000000 -#endif - -#if defined(CONFIG_MACH_PH1_PRO4) -#define CONFIG_DDR_NUM_CH0 2 -#define CONFIG_DDR_NUM_CH1 2 - -/* Physical start address of SDRAM */ -#define CONFIG_SDRAM0_BASE 0x80000000 -#define CONFIG_SDRAM0_SIZE 0x20000000 -#define CONFIG_SDRAM1_BASE 0xa0000000 -#define CONFIG_SDRAM1_SIZE 0x20000000 -#endif - -#if defined(CONFIG_MACH_PH1_SLD8) -#define CONFIG_DDR_NUM_CH0 1 -#define CONFIG_DDR_NUM_CH1 1 - -/* Physical start address of SDRAM */ -#define CONFIG_SDRAM0_BASE 0x80000000 -#define CONFIG_SDRAM0_SIZE 0x10000000 -#define CONFIG_SDRAM1_BASE 0x90000000 -#define CONFIG_SDRAM1_SIZE 0x10000000 -#endif - #define CONFIG_I2C_EEPROM #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 -/* - * Support card address map - */ -#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) -# define CONFIG_SUPPORT_CARD_BASE 0x03f00000 -# define CONFIG_SUPPORT_CARD_ETHER_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00000000) -# define CONFIG_SUPPORT_CARD_LED_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00090000) -# define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x000b0000) -#endif - -#if defined(CONFIG_DCC_MICRO_SUPPORT_CARD) -# define CONFIG_SUPPORT_CARD_BASE 0x08000000 -# define CONFIG_SUPPORT_CARD_ETHER_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00000000) -# define CONFIG_SUPPORT_CARD_LED_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00401630) -# define CONFIG_SUPPORT_CARD_UART_BASE (CONFIG_SUPPORT_CARD_BASE + 0x00200000) -#endif - #ifdef CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_COM1 CONFIG_SUPPORT_CARD_UART_BASE @@ -90,7 +26,8 @@ #define CONFIG_SMC911X -#define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE +/* dummy: referenced by examples/standalone/smc911x_eeprom.c */ +#define CONFIG_SMC911X_BASE 0 #define CONFIG_SMC911X_32_BIT /*----------------------------------------------------------------------- @@ -140,7 +77,7 @@ #define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ -#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 2 +#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 1 /* serial console configuration */ #define CONFIG_BAUDRATE 115200 @@ -191,7 +128,7 @@ #define CONFIG_NAND_DENALI_ECC_SIZE 1024 -#ifdef CONFIG_MACH_PH1_SLD3 +#ifdef CONFIG_ARCH_UNIPHIER_PH1_SLD3 #define CONFIG_SYS_NAND_REGS_BASE 0xf8100000 #define CONFIG_SYS_NAND_DATA_BASE 0xf8000000 #else @@ -240,21 +177,17 @@ "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off;" \ "tftpboot; bootm;" -#define CONFIG_BOOTARGS " earlyprintk loglevel=8" - #ifdef CONFIG_FIT #define CONFIG_BOOTFILE "fitImage" #define LINUXBOOT_ENV_SETTINGS \ "fit_addr=0x00100000\0" \ "fit_addr_r=0x84100000\0" \ "fit_size=0x00f00000\0" \ - "norboot=run add_default_bootargs &&" \ + "norboot=setexpr fit_addr $nor_base + $fit_addr &&" \ "bootm $fit_addr\0" \ - "nandboot=run add_default_bootargs &&" \ - "nand read $fit_addr_r $fit_addr $fit_size &&" \ + "nandboot=nand read $fit_addr_r $fit_addr $fit_size &&" \ "bootm $fit_addr_r\0" \ - "tftpboot=run add_default_bootargs &&" \ - "tftpboot $fit_addr_r $bootfile &&" \ + "tftpboot=tftpboot $fit_addr_r $bootfile &&" \ "bootm $fit_addr_r\0" #else #define CONFIG_BOOTFILE "uImage" @@ -270,15 +203,15 @@ "ramdisk_addr_r=0x84a00000\0" \ "ramdisk_size=0x00600000\0" \ "ramdisk_file=rootfs.cpio.uboot\0" \ - "norboot=run add_default_bootargs &&" \ + "norboot=setexpr kernel_addr $nor_base + $kernel_addr &&" \ + "setexpr ramdisk_addr $nor_base + $ramdisk_addr &&" \ + "setexpr fdt_addr $nor_base + $fdt_addr &&" \ "bootm $kernel_addr $ramdisk_addr $fdt_addr\0" \ - "nandboot=run add_default_bootargs &&" \ - "nand read $kernel_addr_r $kernel_addr $kernel_size &&" \ + "nandboot=nand read $kernel_addr_r $kernel_addr $kernel_size &&" \ "nand read $ramdisk_addr_r $ramdisk_addr $ramdisk_size &&" \ "nand read $fdt_addr_r $fdt_addr $fdt_size &&" \ "bootm $kernel_addr_r $ramdisk_addr_r $fdt_addr_r\0" \ - "tftpboot=run add_default_bootargs &&" \ - "tftpboot $kernel_addr_r $bootfile &&" \ + "tftpboot=tftpboot $kernel_addr_r $bootfile &&" \ "tftpboot $ramdisk_addr_r $ramdisk_file &&" \ "tftpboot $fdt_addr_r $fdt_file &&" \ "bootm $kernel_addr_r $ramdisk_addr_r $fdt_addr_r\0" @@ -287,35 +220,25 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ "verify=n\0" \ + "norbase=0x42000000\0" \ "nandupdate=nand erase 0 0x00100000 &&" \ "tftpboot u-boot-spl-dtb.bin &&" \ "nand write $loadaddr 0 0x00010000 &&" \ "tftpboot u-boot-dtb.img &&" \ "nand write $loadaddr 0x00010000 0x000f0000\0" \ - "add_default_bootargs=setenv bootargs $bootargs" \ - " console=ttyS0,$baudrate\0" \ LINUXBOOT_ENV_SETTINGS /* Open Firmware flat tree */ #define CONFIG_OF_LIBFDT -/* Memory Size & Mapping */ -#define CONFIG_SYS_SDRAM_BASE CONFIG_SDRAM0_BASE - -#if CONFIG_SDRAM0_BASE + CONFIG_SDRAM0_SIZE >= CONFIG_SDRAM1_BASE -/* Thre is no memory hole */ -#define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_SYS_SDRAM_SIZE (CONFIG_SDRAM0_SIZE + CONFIG_SDRAM1_SIZE) -#else +#define CONFIG_SYS_SDRAM_BASE 0x80000000 #define CONFIG_NR_DRAM_BANKS 2 -#define CONFIG_SYS_SDRAM_SIZE (CONFIG_SDRAM0_SIZE) -#endif -#if defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_LD4) || \ - defined(CONFIG_MACH_PH1_SLD8) +#if defined(CONFIG_ARCH_UNIPHIER_PH1_SLD3) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_LD4) || \ + defined(CONFIG_ARCH_UNIPHIER_PH1_SLD8) #define CONFIG_SPL_TEXT_BASE 0x00040000 -#endif -#if defined(CONFIG_MACH_PH1_PRO4) +#else #define CONFIG_SPL_TEXT_BASE 0x00100000 #endif diff --git a/include/env_flags.h b/include/env_flags.h index 2d2de88fc0..8823fb9602 100644 --- a/include/env_flags.h +++ b/include/env_flags.h @@ -109,6 +109,13 @@ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags); */ enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags); +#ifdef CONFIG_CMD_NET +/* + * Check if a string has the format of an Ethernet MAC address + */ +int eth_validate_ethaddr_str(const char *addr); +#endif + #ifdef USE_HOSTCC /* * Look up the type of a variable directly from the .flags var. diff --git a/include/ethsw.h b/include/ethsw.h new file mode 100644 index 0000000000..2d3c12a39e --- /dev/null +++ b/include/ethsw.h @@ -0,0 +1,95 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Ethernet Switch commands + */ + +#ifndef _CMD_ETHSW_H_ +#define _CMD_ETHSW_H_ + +#define ETHSW_MAX_CMD_PARAMS 20 +#define ETHSW_CMD_PORT_ALL -1 +#define ETHSW_CMD_VLAN_ALL -1 + +/* IDs used to track keywords in a command */ +enum ethsw_keyword_id { + ethsw_id_key_end = -1, + ethsw_id_help, + ethsw_id_show, + ethsw_id_port, + ethsw_id_enable, + ethsw_id_disable, + ethsw_id_statistics, + ethsw_id_clear, + ethsw_id_learning, + ethsw_id_auto, + ethsw_id_vlan, + ethsw_id_fdb, + ethsw_id_add, + ethsw_id_del, + ethsw_id_flush, + ethsw_id_pvid, + ethsw_id_untagged, + ethsw_id_all, + ethsw_id_none, + ethsw_id_egress, + ethsw_id_tag, + ethsw_id_classified, + ethsw_id_shared, + ethsw_id_private, + ethsw_id_ingress, + ethsw_id_filtering, + ethsw_id_count, /* keep last */ +}; + +enum ethsw_keyword_opt_id { + ethsw_id_port_no = ethsw_id_count + 1, + ethsw_id_vlan_no, + ethsw_id_pvid_no, + ethsw_id_add_del_no, + ethsw_id_add_del_mac, + ethsw_id_count_all, /* keep last */ +}; + +struct ethsw_command_def { + int cmd_to_keywords[ETHSW_MAX_CMD_PARAMS]; + int cmd_keywords_nr; + int port; + int vid; + uchar ethaddr[6]; + int (*cmd_function)(struct ethsw_command_def *parsed_cmd); +}; + +/* Structure to be created and initialized by an Ethernet Switch driver */ +struct ethsw_command_func { + const char *ethsw_name; + int (*port_enable)(struct ethsw_command_def *parsed_cmd); + int (*port_disable)(struct ethsw_command_def *parsed_cmd); + int (*port_show)(struct ethsw_command_def *parsed_cmd); + int (*port_stats)(struct ethsw_command_def *parsed_cmd); + int (*port_stats_clear)(struct ethsw_command_def *parsed_cmd); + int (*port_learn)(struct ethsw_command_def *parsed_cmd); + int (*port_learn_show)(struct ethsw_command_def *parsed_cmd); + int (*fdb_show)(struct ethsw_command_def *parsed_cmd); + int (*fdb_flush)(struct ethsw_command_def *parsed_cmd); + int (*fdb_entry_add)(struct ethsw_command_def *parsed_cmd); + int (*fdb_entry_del)(struct ethsw_command_def *parsed_cmd); + int (*pvid_show)(struct ethsw_command_def *parsed_cmd); + int (*pvid_set)(struct ethsw_command_def *parsed_cmd); + int (*vlan_show)(struct ethsw_command_def *parsed_cmd); + int (*vlan_set)(struct ethsw_command_def *parsed_cmd); + int (*port_untag_show)(struct ethsw_command_def *parsed_cmd); + int (*port_untag_set)(struct ethsw_command_def *parsed_cmd); + int (*port_egr_vlan_show)(struct ethsw_command_def *parsed_cmd); + int (*port_egr_vlan_set)(struct ethsw_command_def *parsed_cmd); + int (*vlan_learn_show)(struct ethsw_command_def *parsed_cmd); + int (*vlan_learn_set)(struct ethsw_command_def *parsed_cmd); + int (*port_ingr_filt_show)(struct ethsw_command_def *parsed_cmd); + int (*port_ingr_filt_set)(struct ethsw_command_def *parsed_cmd); +}; + +int ethsw_define_functions(const struct ethsw_command_func *cmd_func); + +#endif /* _CMD_ETHSW_H_ */ diff --git a/include/vsc9953.h b/include/vsc9953.h index 3d11b87a1f..cd5cfc76b0 100644 --- a/include/vsc9953.h +++ b/include/vsc9953.h @@ -1,14 +1,9 @@ /* - * vsc9953.h + * Copyright 2013, 2015 Freescale Semiconductor, Inc. * - * Driver for the Vitesse VSC9953 L2 Switch - * - * This software may be used and distributed according to the - * terms of the GNU Public License, Version 2, incorporated - * herein by reference. - * - * Copyright 2013 Freescale Semiconductor, Inc. + * SPDX-License-Identifier: GPL-2.0+ * + * Driver for the Vitesse VSC9953 L2 Switch */ #ifndef _VSC9953_H_ @@ -17,11 +12,11 @@ #include <config.h> #include <miiphy.h> #include <asm/types.h> -#include <malloc.h> #define VSC9953_OFFSET (CONFIG_SYS_CCSRBAR_DEFAULT + 0x800000) #define VSC9953_SYS_OFFSET 0x010000 +#define VSC9953_REW_OFFSET 0x030000 #define VSC9953_DEV_GMII_OFFSET 0x100000 #define VSC9953_QSYS_OFFSET 0x200000 #define VSC9953_ANA_OFFSET 0x280000 @@ -33,29 +28,131 @@ #define T1040_SWITCH_GMII_DEV_OFFSET 0x010000 #define VSC9953_PHY_REGS_OFFST 0x0000AC -#define CONFIG_VSC9953_SOFT_SWC_RST_ENA 0x00000001 -#define CONFIG_VSC9953_CORE_ENABLE 0x80 -#define CONFIG_VSC9953_MEM_ENABLE 0x40 -#define CONFIG_VSC9953_MEM_INIT 0x20 - -#define CONFIG_VSC9953_PORT_ENA 0x00003a00 -#define CONFIG_VSC9953_MAC_ENA_CFG 0x00000011 -#define CONFIG_VSC9953_MAC_MODE_CFG 0x00000011 -#define CONFIG_VSC9953_MAC_IFG_CFG 0x00000515 -#define CONFIG_VSC9953_MAC_HDX_CFG 0x00001043 -#define CONFIG_VSC9953_CLOCK_CFG 0x00000001 -#define CONFIG_VSC9953_CLOCK_CFG_1000M 0x00000001 -#define CONFIG_VSC9953_PFC_FC 0x00000001 -#define CONFIG_VSC9953_PFC_FC_QSGMII 0x00000000 -#define CONFIG_VSC9953_MAC_FC_CFG 0x04700000 -#define CONFIG_VSC9953_MAC_FC_CFG_QSGMII 0x00700000 -#define CONFIG_VSC9953_PAUSE_CFG 0x001ffffe -#define CONFIG_VSC9953_TOT_TAIL_DROP_LVL 0x000003ff -#define CONFIG_VSC9953_FRONT_PORT_MODE 0x00000000 -#define CONFIG_VSC9953_MAC_MAX_LEN 0x000005ee - -#define CONFIG_VSC9953_VCAP_MV_CFG 0x0000ffff -#define CONFIG_VSC9953_VCAP_UPDATE_CTRL 0x01000004 +/* Macros for vsc9953_chip_regs.soft_rst register */ +#define VSC9953_SOFT_SWC_RST_ENA 0x00000001 + +/* Macros for vsc9953_sys_sys.reset_cfg register */ +#define VSC9953_CORE_ENABLE 0x80 +#define VSC9953_MEM_ENABLE 0x40 +#define VSC9953_MEM_INIT 0x20 + +/* Macros for vsc9953_dev_gmii_mac_cfg_status.mac_ena_cfg register */ +#define VSC9953_MAC_ENA_CFG 0x00000011 + +/* Macros for vsc9953_dev_gmii_mac_cfg_status.mac_mode_cfg register */ +#define VSC9953_MAC_MODE_CFG 0x00000011 + +/* Macros for vsc9953_dev_gmii_mac_cfg_status.mac_ifg_cfg register */ +#define VSC9953_MAC_IFG_CFG 0x00000515 + +/* Macros for vsc9953_dev_gmii_mac_cfg_status.mac_hdx_cfg register */ +#define VSC9953_MAC_HDX_CFG 0x00001043 + +/* Macros for vsc9953_dev_gmii_mac_cfg_status.mac_maxlen_cfg register */ +#define VSC9953_MAC_MAX_LEN 0x000005ee + +/* Macros for vsc9953_dev_gmii_port_mode.clock_cfg register */ +#define VSC9953_CLOCK_CFG 0x00000001 +#define VSC9953_CLOCK_CFG_1000M 0x00000001 + +/* Macros for vsc9953_sys_sys.front_port_mode register */ +#define VSC9953_FRONT_PORT_MODE 0x00000000 + +/* Macros for vsc9953_ana_pfc.pfc_cfg register */ +#define VSC9953_PFC_FC 0x00000001 +#define VSC9953_PFC_FC_QSGMII 0x00000000 + +/* Macros for vsc9953_sys_pause_cfg.mac_fc_cfg register */ +#define VSC9953_MAC_FC_CFG 0x04700000 +#define VSC9953_MAC_FC_CFG_QSGMII 0x00700000 + +/* Macros for vsc9953_sys_pause_cfg.pause_cfg register */ +#define VSC9953_PAUSE_CFG 0x001ffffe + +/* Macros for vsc9953_sys_pause_cfgtot_tail_drop_lvl register */ +#define VSC9953_TOT_TAIL_DROP_LVL 0x000003ff + +/* Macros for vsc9953_sys_sys.stat_cfg register */ +#define VSC9953_STAT_CLEAR_RX 0x00000400 +#define VSC9953_STAT_CLEAR_TX 0x00000800 +#define VSC9953_STAT_CLEAR_DR 0x00001000 + +/* Macros for vsc9953_vcap_core_cfg.vcap_mv_cfg register */ +#define VSC9953_VCAP_MV_CFG 0x0000ffff +#define VSC9953_VCAP_UPDATE_CTRL 0x01000004 + +/* Macros for register vsc9953_ana_ana_tables.mac_access register */ +#define VSC9953_MAC_CMD_IDLE 0x00000000 +#define VSC9953_MAC_CMD_LEARN 0x00000001 +#define VSC9953_MAC_CMD_FORGET 0x00000002 +#define VSC9953_MAC_CMD_AGE 0x00000003 +#define VSC9953_MAC_CMD_NEXT 0x00000004 +#define VSC9953_MAC_CMD_READ 0x00000006 +#define VSC9953_MAC_CMD_WRITE 0x00000007 +#define VSC9953_MAC_CMD_MASK 0x00000007 +#define VSC9953_MAC_CMD_VALID 0x00000800 +#define VSC9953_MAC_ENTRYTYPE_NORMAL 0x00000000 +#define VSC9953_MAC_ENTRYTYPE_LOCKED 0x00000200 +#define VSC9953_MAC_ENTRYTYPE_IPV4MCAST 0x00000400 +#define VSC9953_MAC_ENTRYTYPE_IPV6MCAST 0x00000600 +#define VSC9953_MAC_ENTRYTYPE_MASK 0x00000600 +#define VSC9953_MAC_DESTIDX_MASK 0x000001f8 +#define VSC9953_MAC_VID_MASK 0x1fff0000 +#define VSC9953_MAC_MACH_MASK 0x0000ffff + +/* Macros for vsc9953_ana_port.vlan_cfg register */ +#define VSC9953_VLAN_CFG_AWARE_ENA 0x00100000 +#define VSC9953_VLAN_CFG_POP_CNT_MASK 0x000c0000 +#define VSC9953_VLAN_CFG_POP_CNT_NONE 0x00000000 +#define VSC9953_VLAN_CFG_POP_CNT_ONE 0x00040000 +#define VSC9953_VLAN_CFG_VID_MASK 0x00000fff + +/* Macros for vsc9953_rew_port.port_vlan_cfg register */ +#define VSC9953_PORT_VLAN_CFG_VID_MASK 0x00000fff + +/* Macros for vsc9953_ana_ana_tables.vlan_tidx register */ +#define VSC9953_ANA_TBL_VID_MASK 0x00000fff + +/* Macros for vsc9953_ana_ana_tables.vlan_access register */ +#define VSC9953_VLAN_PORT_MASK 0x00001ffc +#define VSC9953_VLAN_CMD_MASK 0x00000003 +#define VSC9953_VLAN_CMD_IDLE 0x00000000 +#define VSC9953_VLAN_CMD_READ 0x00000001 +#define VSC9953_VLAN_CMD_WRITE 0x00000002 +#define VSC9953_VLAN_CMD_INIT 0x00000003 + +/* Macros for vsc9953_ana_port.port_cfg register */ +#define VSC9953_PORT_CFG_LEARN_ENA 0x00000080 +#define VSC9953_PORT_CFG_LEARN_AUTO 0x00000100 +#define VSC9953_PORT_CFG_LEARN_CPU 0x00000200 +#define VSC9953_PORT_CFG_LEARN_DROP 0x00000400 + +/* Macros for vsc9953_qsys_sys.switch_port_mode register */ +#define VSC9953_PORT_ENA 0x00002000 + +/* Macros for vsc9953_ana_ana.agen_ctrl register */ +#define VSC9953_FID_MASK_ALL 0x00fff000 + +/* Macros for vsc9953_ana_ana.adv_learn register */ +#define VSC9953_VLAN_CHK 0x00000400 + +/* Macros for vsc9953_rew_port.port_tag_cfg register */ +#define VSC9953_TAG_CFG_MASK 0x00000180 +#define VSC9953_TAG_CFG_NONE 0x00000000 +#define VSC9953_TAG_CFG_ALL_BUT_PVID_ZERO 0x00000080 +#define VSC9953_TAG_CFG_ALL_BUT_ZERO 0x00000100 +#define VSC9953_TAG_CFG_ALL 0x00000180 +#define VSC9953_TAG_VID_PVID 0x00000010 + +/* Macros for vsc9953_ana_ana.anag_efil register */ +#define VSC9953_AGE_PORT_EN 0x00080000 +#define VSC9953_AGE_PORT_MASK 0x0007c000 +#define VSC9953_AGE_VID_EN 0x00002000 +#define VSC9953_AGE_VID_MASK 0x00001fff + +/* Macros for vsc9953_ana_ana_tables.mach_data register */ +#define VSC9953_MACHDATA_VID_MASK 0x1fff0000 + #define VSC9953_MAX_PORTS 10 #define VSC9953_PORT_CHECK(port) \ (((port) < 0 || (port) >= VSC9953_MAX_PORTS) ? 0 : 1) @@ -64,6 +161,9 @@ (port) < VSC9953_MAX_PORTS - 2 || (port) >= VSC9953_MAX_PORTS \ ) ? 0 : 1 \ ) +#define VSC9953_MAX_VLAN 4096 +#define VSC9953_VLAN_CHECK(vid) \ + (((vid) < 0 || (vid) >= VSC9953_MAX_VLAN) ? 0 : 1) #define DEFAULT_VSC9953_MDIO_NAME "VSC9953_MDIO0" @@ -74,9 +174,9 @@ struct vsc9953_mdio_info { char *name; }; -/* VSC9953 ANA structure for T1040 U-boot*/ +/* VSC9953 ANA structure */ -struct vsc9953_ana_port { +struct vsc9953_ana_port { u32 vlan_cfg; u32 drop_cfg; u32 qos_cfg; @@ -116,6 +216,7 @@ struct vsc9953_ana_ana_tables { struct vsc9953_ana_ana { u32 adv_learn; u32 vlan_mask; + u32 reserved; u32 anag_efil; u32 an_events; u32 storm_limit_burst; @@ -138,7 +239,7 @@ struct vsc9953_ana_pgid { u32 port_grp_id[91]; }; -struct vsc9953_ana_pfc { +struct vsc9953_ana_pfc { u32 pfc_cfg; u32 reserved1[15]; }; @@ -149,7 +250,7 @@ struct vsc9953_ana_pol_misc { u32 pol_hyst; }; -struct vsc9953_ana_common { +struct vsc9953_ana_common { u32 aggr_cfg; u32 cpuq_cfg; u32 cpuq_8021_cfg; @@ -176,18 +277,18 @@ struct vsc9953_analyzer { u32 reserved5[196]; struct vsc9953_ana_common common; }; -/* END VSC9953 ANA structure for T1040 U-boot*/ +/* END VSC9953 ANA structure t*/ -/* VSC9953 DEV_GMII structure for T1040 U-boot*/ +/* VSC9953 DEV_GMII structure */ -struct vsc9953_dev_gmii_port_mode { +struct vsc9953_dev_gmii_port_mode { u32 clock_cfg; u32 port_misc; u32 reserved1; u32 eee_cfg; }; -struct vsc9953_dev_gmii_mac_cfg_status { +struct vsc9953_dev_gmii_mac_cfg_status { u32 mac_ena_cfg; u32 mac_mode_cfg; u32 mac_maxlen_cfg; @@ -205,11 +306,11 @@ struct vsc9953_dev_gmii { struct vsc9953_dev_gmii_mac_cfg_status mac_cfg_status; }; -/* END VSC9953 DEV_GMII structure for T1040 U-boot*/ +/* END VSC9953 DEV_GMII structure */ -/* VSC9953 QSYS structure for T1040 U-boot*/ +/* VSC9953 QSYS structure */ -struct vsc9953_qsys_hsch { +struct vsc9953_qsys_hsch { u32 cir_cfg; u32 reserved1; u32 se_cfg; @@ -218,7 +319,7 @@ struct vsc9953_qsys_hsch { u32 reserved2[20]; }; -struct vsc9953_qsys_sys { +struct vsc9953_qsys_sys { u32 port_mode[12]; u32 switch_port_mode[11]; u32 stat_cnt_cfg; @@ -232,32 +333,32 @@ struct vsc9953_qsys_sys { u32 reserved1[23]; }; -struct vsc9953_qsys_qos_cfg { +struct vsc9953_qsys_qos_cfg { u32 red_profile[16]; u32 res_qos_mode; }; -struct vsc9953_qsys_drop_cfg { +struct vsc9953_qsys_drop_cfg { u32 egr_drop_mode; }; -struct vsc9953_qsys_mmgt { +struct vsc9953_qsys_mmgt { u32 eq_cntrl; u32 reserved1; }; -struct vsc9953_qsys_hsch_misc { +struct vsc9953_qsys_hsch_misc { u32 hsch_misc_cfg; u32 reserved1[546]; }; -struct vsc9953_qsys_res_ctrl { +struct vsc9953_qsys_res_ctrl { u32 res_cfg; u32 res_stat; }; -struct vsc9953_qsys_reg { +struct vsc9953_qsys_reg { struct vsc9953_qsys_hsch hsch[108]; struct vsc9953_qsys_sys sys; struct vsc9953_qsys_qos_cfg qos_cfg; @@ -267,18 +368,123 @@ struct vsc9953_qsys_reg { struct vsc9953_qsys_res_ctrl res_ctrl[1024]; }; -/* END VSC9953 QSYS structure for T1040 U-boot*/ - -/* VSC9953 SYS structure for T1040 U-boot*/ - -struct vsc9953_sys_stat { - u32 rx_cntrs[64]; - u32 tx_cntrs[64]; - u32 drop_cntrs[64]; +/* END VSC9953 QSYS structure */ + +/* VSC9953 SYS structure */ + +struct vsc9953_rx_cntrs { + u32 c_rx_oct; + u32 c_rx_uc; + u32 c_rx_mc; + u32 c_rx_bc; + u32 c_rx_short; + u32 c_rx_frag; + u32 c_rx_jabber; + u32 c_rx_crc; + u32 c_rx_symbol_err; + u32 c_rx_sz_64; + u32 c_rx_sz_65_127; + u32 c_rx_sz_128_255; + u32 c_rx_sz_256_511; + u32 c_rx_sz_512_1023; + u32 c_rx_sz_1024_1526; + u32 c_rx_sz_jumbo; + u32 c_rx_pause; + u32 c_rx_control; + u32 c_rx_long; + u32 c_rx_cat_drop; + u32 c_rx_red_prio_0; + u32 c_rx_red_prio_1; + u32 c_rx_red_prio_2; + u32 c_rx_red_prio_3; + u32 c_rx_red_prio_4; + u32 c_rx_red_prio_5; + u32 c_rx_red_prio_6; + u32 c_rx_red_prio_7; + u32 c_rx_yellow_prio_0; + u32 c_rx_yellow_prio_1; + u32 c_rx_yellow_prio_2; + u32 c_rx_yellow_prio_3; + u32 c_rx_yellow_prio_4; + u32 c_rx_yellow_prio_5; + u32 c_rx_yellow_prio_6; + u32 c_rx_yellow_prio_7; + u32 c_rx_green_prio_0; + u32 c_rx_green_prio_1; + u32 c_rx_green_prio_2; + u32 c_rx_green_prio_3; + u32 c_rx_green_prio_4; + u32 c_rx_green_prio_5; + u32 c_rx_green_prio_6; + u32 c_rx_green_prio_7; + u32 reserved[20]; +}; + +struct vsc9953_tx_cntrs { + u32 c_tx_oct; + u32 c_tx_uc; + u32 c_tx_mc; + u32 c_tx_bc; + u32 c_tx_col; + u32 c_tx_drop; + u32 c_tx_pause; + u32 c_tx_sz_64; + u32 c_tx_sz_65_127; + u32 c_tx_sz_128_255; + u32 c_tx_sz_256_511; + u32 c_tx_sz_512_1023; + u32 c_tx_sz_1024_1526; + u32 c_tx_sz_jumbo; + u32 c_tx_yellow_prio_0; + u32 c_tx_yellow_prio_1; + u32 c_tx_yellow_prio_2; + u32 c_tx_yellow_prio_3; + u32 c_tx_yellow_prio_4; + u32 c_tx_yellow_prio_5; + u32 c_tx_yellow_prio_6; + u32 c_tx_yellow_prio_7; + u32 c_tx_green_prio_0; + u32 c_tx_green_prio_1; + u32 c_tx_green_prio_2; + u32 c_tx_green_prio_3; + u32 c_tx_green_prio_4; + u32 c_tx_green_prio_5; + u32 c_tx_green_prio_6; + u32 c_tx_green_prio_7; + u32 c_tx_aged; + u32 reserved[33]; +}; + +struct vsc9953_drop_cntrs { + u32 c_dr_local; + u32 c_dr_tail; + u32 c_dr_yellow_prio_0; + u32 c_dr_yellow_prio_1; + u32 c_dr_yellow_prio_2; + u32 c_dr_yellow_prio_3; + u32 c_dr_yellow_prio_4; + u32 c_dr_yellow_prio_5; + u32 c_dr_yellow_prio_6; + u32 c_dr_yellow_prio_7; + u32 c_dr_green_prio_0; + u32 c_dr_green_prio_1; + u32 c_dr_green_prio_2; + u32 c_dr_green_prio_3; + u32 c_dr_green_prio_4; + u32 c_dr_green_prio_5; + u32 c_dr_green_prio_6; + u32 c_dr_green_prio_7; + u32 reserved[46]; +}; + +struct vsc9953_sys_stat { + struct vsc9953_rx_cntrs rx_cntrs; + struct vsc9953_tx_cntrs tx_cntrs; + struct vsc9953_drop_cntrs drop_cntrs; u32 reserved1[6]; }; -struct vsc9953_sys_sys { +struct vsc9953_sys_sys { u32 reset_cfg; u32 reserved1; u32 vlan_etype_cfg; @@ -289,7 +495,7 @@ struct vsc9953_sys_sys { u32 reserved2[50]; }; -struct vsc9953_sys_pause_cfg { +struct vsc9953_sys_pause_cfg { u32 pause_cfg[11]; u32 pause_tot_cfg; u32 tail_drop_level[11]; @@ -297,29 +503,52 @@ struct vsc9953_sys_pause_cfg { u32 mac_fc_cfg[10]; }; -struct vsc9953_sys_mmgt { +struct vsc9953_sys_mmgt { u16 free_cnt; }; -struct vsc9953_system_reg { +struct vsc9953_system_reg { struct vsc9953_sys_stat stat; struct vsc9953_sys_sys sys; struct vsc9953_sys_pause_cfg pause_cfg; struct vsc9953_sys_mmgt mmgt; }; -/* END VSC9953 SYS structure for T1040 U-boot*/ +/* END VSC9953 SYS structure */ + +/* VSC9953 REW structure */ + +struct vsc9953_rew_port { + u32 port_vlan_cfg; + u32 port_tag_cfg; + u32 port_port_cfg; + u32 port_dscp_cfg; + u32 port_pcp_dei_qos_map_cfg[16]; + u32 reserved[12]; +}; + +struct vsc9953_rew_common { + u32 reserve[4]; + u32 dscp_remap_dp1_cfg[64]; + u32 dscp_remap_cfg[64]; +}; + +struct vsc9953_rew_reg { + struct vsc9953_rew_port port[12]; + struct vsc9953_rew_common common; +}; +/* END VSC9953 REW structure */ -/* VSC9953 DEVCPU_GCB structure for T1040 U-boot*/ +/* VSC9953 DEVCPU_GCB structure */ -struct vsc9953_chip_regs { +struct vsc9953_chip_regs { u32 chipd_id; u32 gpr; u32 soft_rst; }; -struct vsc9953_gpio { +struct vsc9953_gpio { u32 gpio_out_set[10]; u32 gpio_out_clr[10]; u32 gpio_out[10]; @@ -338,31 +567,31 @@ struct vsc9953_mii_mng { u32 miiscan_lst_rslts_valid; }; -struct vsc9953_mii_read_scan { +struct vsc9953_mii_read_scan { u32 mii_scan_results_sticky[2]; }; -struct vsc9953_devcpu_gcb { +struct vsc9953_devcpu_gcb { struct vsc9953_chip_regs chip_regs; struct vsc9953_gpio gpio; struct vsc9953_mii_mng mii_mng[2]; struct vsc9953_mii_read_scan mii_read_scan; }; -/* END VSC9953 DEVCPU_GCB structure for T1040 U-boot*/ +/* END VSC9953 DEVCPU_GCB structure */ -/* VSC9953 IS* structure for T1040 U-boot*/ +/* VSC9953 IS* structure */ -struct vsc9953_vcap_core_cfg { +struct vsc9953_vcap_core_cfg { u32 vcap_update_ctrl; u32 vcap_mv_cfg; }; -struct vsc9953_vcap { -struct vsc9953_vcap_core_cfg vcap_core_cfg; +struct vsc9953_vcap { + struct vsc9953_vcap_core_cfg vcap_core_cfg; }; -/* END VSC9953 IS* structure for T1040 U-boot*/ +/* END VSC9953 IS* structure */ #define VSC9953_PORT_INFO_INITIALIZER(idx) \ { \ @@ -388,15 +617,15 @@ struct vsc9953_port_info { /* Structure to describe a VSC9953 switch */ struct vsc9953_info { - struct vsc9953_port_info port[VSC9953_MAX_PORTS]; + struct vsc9953_port_info port[VSC9953_MAX_PORTS]; }; void vsc9953_init(bd_t *bis); -void vsc9953_port_info_set_mdio(int port, struct mii_dev *bus); -void vsc9953_port_info_set_phy_address(int port, int address); -void vsc9953_port_enable(int port); -void vsc9953_port_disable(int port); -void vsc9953_port_info_set_phy_int(int port, phy_interface_t phy_int); +void vsc9953_port_info_set_mdio(int port_no, struct mii_dev *bus); +void vsc9953_port_info_set_phy_address(int port_no, int address); +void vsc9953_port_enable(int port_no); +void vsc9953_port_disable(int port_no); +void vsc9953_port_info_set_phy_int(int port_no, phy_interface_t phy_int); #endif /* _VSC9953_H_ */ |