From 5dea3a745b88041d677fc03d34df04dd2836265c Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 16 Jan 2015 12:46:51 +0800 Subject: bfin: enlarge the monitor size for ip04 board to avoid oversize link error Signed-off-by: Sonic Zhang --- include/configs/ip04.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/ip04.h b/include/configs/ip04.h index ec510bdac4..2ee215f706 100644 --- a/include/configs/ip04.h +++ b/include/configs/ip04.h @@ -61,7 +61,7 @@ #define CONFIG_EBIU_AMBCTL0_VAL 0xffc2ffc2 #define CONFIG_EBIU_AMBCTL1_VAL 0xffc2ffc2 -#define CONFIG_SYS_MONITOR_LEN (256 * 1024) +#define CONFIG_SYS_MONITOR_LEN (384 * 1024) #define CONFIG_SYS_MALLOC_LEN (128 * 1024) -- cgit From 0d3fd562c4977af4e992f3f73a441081ff8c60d0 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 16 Jan 2015 12:52:59 +0800 Subject: bfin: make env offset sector aligned for bct-brettl2 and ibf-dsp561 boards Signed-off-by: Sonic Zhang --- include/configs/bct-brettl2.h | 2 +- include/configs/ibf-dsp561.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/configs/bct-brettl2.h b/include/configs/bct-brettl2.h index 39982ef72c..2e0e9224cf 100644 --- a/include/configs/bct-brettl2.h +++ b/include/configs/bct-brettl2.h @@ -97,7 +97,7 @@ #define CONFIG_ENV_IS_IN_FLASH 1 #define CONFIG_ENV_OFFSET 0x4000 #define CONFIG_ENV_SIZE 0x2000 -#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_ENV_SECT_SIZE 0x12000 #if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS) #define ENV_IS_EMBEDDED diff --git a/include/configs/ibf-dsp561.h b/include/configs/ibf-dsp561.h index ac5ca9af37..2a937c6a22 100644 --- a/include/configs/ibf-dsp561.h +++ b/include/configs/ibf-dsp561.h @@ -82,7 +82,7 @@ #define CONFIG_ENV_OFFSET 0x4000 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) #define CONFIG_ENV_SIZE 0x2000 -#define CONFIG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */ +#define CONFIG_ENV_SECT_SIZE 0x12000 /* Total Size of Environment Sector */ #if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS) #define ENV_IS_EMBEDDED #else -- cgit From 99c618ff261e1b68e3245ecc467e5a5a8c5e7b8d Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Thu, 15 Jan 2015 13:32:29 -0200 Subject: wandboard: Use 32bit color depth for Fusion LCD The Fusion LCD needs the 32bit color depth to properly work; the default is different on the 3.10.17 kernels and it is better to ensure it work out of box using proper default color setting. Signed-off-by: Otavio Salvador --- include/configs/wandboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h index 809017c5fe..117d1f7087 100644 --- a/include/configs/wandboard.h +++ b/include/configs/wandboard.h @@ -175,7 +175,7 @@ "if i2c probe 0x10; then " \ "setenv bootargs ${bootargs} " \ "video=mxcfb${nextcon}:dev=lcd,800x480@60," \ - "if=RGB666; " \ + "if=RGB666,bpp=32; " \ "if test 0 -eq ${nextcon}; then " \ "setenv fbmem fbmem=10M; " \ "else " \ -- cgit From 834670eae0ddc3e4a809d05645f12f23ef216a41 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 29 Dec 2014 16:23:17 -0200 Subject: mx6sxsabresd: Remove unneeded board_late_init() Since commit 1f98e31bc0b2c37a ("imx: mx6sxsabresd: Use the pfuze common init function") board_late_init() became empty, so we can safely remove this unneeded function. Signed-off-by: Fabio Estevam --- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 5 ----- include/configs/mx6sxsabresd.h | 1 - 2 files changed, 6 deletions(-) diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index 5cc58ac868..a848f4103a 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -423,11 +423,6 @@ int board_init(void) return 0; } -int board_late_init(void) -{ - return 0; -} - int checkboard(void) { puts("Board: MX6SX SABRE SDB\n"); diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index fbaae3f505..3aae808ba9 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -28,7 +28,6 @@ #define CONFIG_SYS_MALLOC_LEN (3 * SZ_1M) #define CONFIG_BOARD_EARLY_INIT_F -#define CONFIG_BOARD_LATE_INIT #define CONFIG_MXC_GPIO #define CONFIG_MXC_UART -- cgit From 5d6050fdb8b0aaf3d3c43b3cad68d6b8f5037f9a Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 10 Dec 2014 10:15:23 +0100 Subject: arm: mx6: Add Barco platinum-picon and platinum-titanium This patch adds the new Barco platinum platform. It currently includes those two boards: platinum-titanium ----------------- This is the same board as the titanium that is already supported in mainline U-Boot. But its now moved to this new platform to support multiple "flavors" of imx6 boards in one directory. Its also moved to support SPL booting. And with this we use the run-time DDR configuration of this SPL support. The board is equipped with the Micron MT41J128M16JT-125 DDR chips. We now can remove the DDR related registers tuples from the imximage.cfg file. As all this is done in the SPL at run-time. platinum-picon -------------- This board is new and based on the MX6DL with 1GiB DDR using the Micron MT41K256M16HA DDR3 chips. Its also equipped with 2 NAND chips (each 512MiB). Signed-off-by: Stefan Roese Cc: Stefano Babic Cc: Pieter Ronsijn --- arch/arm/Kconfig | 11 ++ board/barco/platinum/Kconfig | 37 ++++ board/barco/platinum/MAINTAINERS | 7 + board/barco/platinum/Makefile | 14 ++ board/barco/platinum/platinum.c | 217 +++++++++++++++++++++ board/barco/platinum/platinum.h | 88 +++++++++ board/barco/platinum/platinum_picon.c | 244 +++++++++++++++++++++++ board/barco/platinum/platinum_titanium.c | 209 ++++++++++++++++++++ board/barco/platinum/spl_picon.c | 182 ++++++++++++++++++ board/barco/platinum/spl_titanium.c | 185 ++++++++++++++++++ configs/platinum_picon_defconfig | 4 + configs/platinum_titanium_defconfig | 4 + include/configs/platinum.h | 319 +++++++++++++++++++++++++++++++ include/configs/platinum_picon.h | 31 +++ include/configs/platinum_titanium.h | 38 ++++ 15 files changed, 1590 insertions(+) create mode 100644 board/barco/platinum/Kconfig create mode 100644 board/barco/platinum/MAINTAINERS create mode 100644 board/barco/platinum/Makefile create mode 100644 board/barco/platinum/platinum.c create mode 100644 board/barco/platinum/platinum.h create mode 100644 board/barco/platinum/platinum_picon.c create mode 100644 board/barco/platinum/platinum_titanium.c create mode 100644 board/barco/platinum/spl_picon.c create mode 100644 board/barco/platinum/spl_titanium.c create mode 100644 configs/platinum_picon_defconfig create mode 100644 configs/platinum_titanium_defconfig create mode 100644 include/configs/platinum.h create mode 100644 include/configs/platinum_picon.h create mode 100644 include/configs/platinum_titanium.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5eb1d03cfa..dd35992983 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -664,6 +664,16 @@ config TARGET_OT1200 bool "Bachmann OT1200" select CPU_V7 +config TARGET_PLATINUM_PICON + bool "Support platinum-picon" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PLATINUM_TITANIUM + bool "Support platinum-titanium" + select CPU_V7 + select SUPPORT_SPL + config OMAP34XX bool "OMAP34XX SoC" select CPU_V7 @@ -869,6 +879,7 @@ source "board/atmel/sama5d4_xplained/Kconfig" source "board/atmel/sama5d4ek/Kconfig" source "board/bachmann/ot1200/Kconfig" source "board/balloon3/Kconfig" +source "board/barco/platinum/Kconfig" source "board/barco/titanium/Kconfig" source "board/bluegiga/apx4devkit/Kconfig" source "board/bluewater/snapper9260/Kconfig" diff --git a/board/barco/platinum/Kconfig b/board/barco/platinum/Kconfig new file mode 100644 index 0000000000..8bbad24c0d --- /dev/null +++ b/board/barco/platinum/Kconfig @@ -0,0 +1,37 @@ +if TARGET_PLATINUM_PICON + +config SYS_CPU + default "armv7" + +config SYS_VENDOR + default "barco" + +config SYS_SOC + default "mx6" + +config SYS_BOARD + default "platinum" + +config SYS_CONFIG_NAME + default "platinum_picon" + +endif + +if TARGET_PLATINUM_TITANIUM + +config SYS_CPU + default "armv7" + +config SYS_VENDOR + default "barco" + +config SYS_SOC + default "mx6" + +config SYS_BOARD + default "platinum" + +config SYS_CONFIG_NAME + default "platinum_titanium" + +endif diff --git a/board/barco/platinum/MAINTAINERS b/board/barco/platinum/MAINTAINERS new file mode 100644 index 0000000000..a22584b5e5 --- /dev/null +++ b/board/barco/platinum/MAINTAINERS @@ -0,0 +1,7 @@ +PLATINUM BOARD +M: Stefan Roese +S: Maintained +F: board/barco/platinum/ +F: include/configs/platinum.h +F: configs/platinum_picon_defconfig +F: configs/platinum_titanium_defconfig diff --git a/board/barco/platinum/Makefile b/board/barco/platinum/Makefile new file mode 100644 index 0000000000..abc941914a --- /dev/null +++ b/board/barco/platinum/Makefile @@ -0,0 +1,14 @@ +# +# Copyright (C) 2014, Barco (www.barco.com) +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := platinum.o +obj-$(CONFIG_TARGET_PLATINUM_PICON) += platinum_picon.o +obj-$(CONFIG_TARGET_PLATINUM_TITANIUM) += platinum_titanium.o + +ifneq ($(CONFIG_SPL_BUILD),) +obj-$(CONFIG_TARGET_PLATINUM_PICON) += spl_picon.o +obj-$(CONFIG_TARGET_PLATINUM_TITANIUM) += spl_titanium.o +endif diff --git a/board/barco/platinum/platinum.c b/board/barco/platinum/platinum.c new file mode 100644 index 0000000000..1485a4856f --- /dev/null +++ b/board/barco/platinum/platinum.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platinum.h" + +DECLARE_GLOBAL_DATA_PTR; + +iomux_v3_cfg_t const usdhc3_pads[] = { + MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +}; + +iomux_v3_cfg_t nfc_pads[] = { + MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +struct fsl_esdhc_cfg usdhc_cfg[] = { + { USDHC3_BASE_ADDR }, +}; + +void setup_gpmi_nand(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* config gpmi nand iomux */ + imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); + + /* config gpmi and bch clock to 100 MHz */ + clrsetbits_le32(&mxc_ccm->cs2cdr, + MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, + MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | + MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | + MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)); + + /* enable gpmi and bch clock gating */ + setbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET); + + /* enable apbh clock gating */ + setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +int board_ehci_hcd_init(int port) +{ + return 0; +} + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + + if (cfg->esdhc_base == usdhc_cfg[0].esdhc_base) { + unsigned sd3_cd = IMX_GPIO_NR(7, 0); + gpio_direction_input(sd3_cd); + return !gpio_get_value(sd3_cd); + } + + return 0; +} + +int board_mmc_init(bd_t *bis) +{ + imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} + +void board_init_gpio(void) +{ + platinum_init_gpio(); +} + +void board_init_gpmi_nand(void) +{ + setup_gpmi_nand(); +} + +void board_init_i2c(void) +{ + platinum_setup_i2c(); +} + +void board_init_spi(void) +{ + platinum_setup_spi(); +} + +void board_init_uart(void) +{ + platinum_setup_uart(); +} + +void board_init_usb(void) +{ + platinum_init_usb(); +} + +void board_init_finished(void) +{ + platinum_init_finished(); +} + +int board_phy_config(struct phy_device *phydev) +{ + return platinum_phy_config(phydev); +} + +int board_eth_init(bd_t *bis) +{ + return cpu_eth_init(bis); +} + +int board_early_init_f(void) +{ + board_init_uart(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + board_init_spi(); + + board_init_i2c(); + + board_init_gpmi_nand(); + + board_init_gpio(); + + board_init_usb(); + + board_init_finished(); + + return 0; +} + +int checkboard(void) +{ + puts("Board: " CONFIG_PLATINUM_BOARD "\n"); + return 0; +} + +static const struct boot_mode board_boot_modes[] = { + /* NAND */ + { "nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00) }, + /* 4 bit bus width */ + { "mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00) }, + { "mmc1", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00) }, + { NULL, 0 }, +}; + +int misc_init_r(void) +{ + add_board_boot_modes(board_boot_modes); + + return 0; +} diff --git a/board/barco/platinum/platinum.h b/board/barco/platinum/platinum.h new file mode 100644 index 0000000000..8650d6d5e0 --- /dev/null +++ b/board/barco/platinum/platinum.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _PLATINUM_H_ +#define _PLATINUM_H_ + +#include +#include + +/* Defines */ + +#define ECSPI1_PAD_CLK (PAD_CTL_SRE_SLOW | PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS) +#define ECSPI2_PAD_CLK (PAD_CTL_SRE_FAST | PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS) +#define ECSPI_PAD_MOSI (PAD_CTL_SRE_SLOW | PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_120ohm | \ + PAD_CTL_HYS) +#define ECSPI_PAD_MISO (PAD_CTL_SRE_FAST | PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS) +#define ECSPI_PAD_SS (PAD_CTL_SRE_SLOW | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_120ohm | \ + PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) +#define I2C_PAD_CTRL_SCL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_SLOW) + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \ + PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | \ + PAD_CTL_HYS) + + +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +#define PC_SCL MUX_PAD_CTRL(I2C_PAD_CTRL_SCL) + +/* Prototypes */ + +int platinum_setup_enet(void); +int platinum_setup_i2c(void); +int platinum_setup_spi(void); +int platinum_setup_uart(void); +int platinum_phy_config(struct phy_device *phydev); +int platinum_init_gpio(void); +int platinum_init_usb(void); +int platinum_init_finished(void); + +static inline void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0xFFFFF300, &ccm->CCGR4); /* enable NAND/GPMI/BCH clks */ + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static inline void gpr_init(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* enable AXI cache for VDOA/VPU/IPU */ + writel(0xF00000CF, &iomux->gpr[4]); + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ + writel(0x007F007F, &iomux->gpr[6]); + writel(0x007F007F, &iomux->gpr[7]); +} + +#endif /* _PLATINUM_H_ */ diff --git a/board/barco/platinum/platinum_picon.c b/board/barco/platinum/platinum_picon.c new file mode 100644 index 0000000000..b2eab766c5 --- /dev/null +++ b/board/barco/platinum/platinum_picon.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platinum.h" + +#define GPIO_IP_NCONFIG IMX_GPIO_NR(5, 18) +#define GPIO_HK_NCONFIG IMX_GPIO_NR(7, 13) +#define GPIO_LS_NCONFIG IMX_GPIO_NR(5, 19) + +#define GPIO_I2C0_SEL0 IMX_GPIO_NR(5, 2) +#define GPIO_I2C0_SEL1 IMX_GPIO_NR(1, 11) +#define GPIO_I2C0_ENBN IMX_GPIO_NR(1, 13) + +#define GPIO_I2C2_SEL0 IMX_GPIO_NR(1, 17) +#define GPIO_I2C2_SEL1 IMX_GPIO_NR(1, 20) +#define GPIO_I2C2_ENBN IMX_GPIO_NR(1, 14) + +#define GPIO_USB_RESET IMX_GPIO_NR(1, 5) + +iomux_v3_cfg_t const ecspi1_pads[] = { + MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI1_PAD_CLK), + MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_MISO), + MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_MOSI), + MX6_PAD_CSI0_DAT7__ECSPI1_SS0 | MUX_PAD_CTRL(ECSPI_PAD_SS), + MX6_PAD_EIM_D24__ECSPI1_SS2 | MUX_PAD_CTRL(ECSPI_PAD_SS), + MX6_PAD_EIM_D25__ECSPI1_SS3 | MUX_PAD_CTRL(ECSPI_PAD_SS), +}; + +iomux_v3_cfg_t const ecspi2_pads[] = { + MX6_PAD_EIM_CS0__ECSPI2_SCLK | MUX_PAD_CTRL(ECSPI2_PAD_CLK), + MX6_PAD_EIM_OE__ECSPI2_MISO | MUX_PAD_CTRL(ECSPI_PAD_MISO), + MX6_PAD_EIM_CS1__ECSPI2_MOSI | MUX_PAD_CTRL(ECSPI_PAD_MOSI), + MX6_PAD_EIM_RW__ECSPI2_SS0 | MUX_PAD_CTRL(ECSPI_PAD_SS), + MX6_PAD_EIM_LBA__ECSPI2_SS1 | MUX_PAD_CTRL(ECSPI_PAD_SS), +}; + +iomux_v3_cfg_t const enet_pads[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_CRS_DV__ENET_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RX_ER__ENET_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RXD0__ENET_RX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_RXD1__ENET_RX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_TX_EN__ENET_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_TXD0__ENET_TX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_TXD1__ENET_TX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL), +}; + +/* PHY nRESET */ +iomux_v3_cfg_t const phy_reset_pad = { + MX6_PAD_SD1_DAT2__GPIO1_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart4_pads[] = { + MX6_PAD_CSI0_DAT12__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT13__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT16__UART4_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT17__UART4_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart5_pads[] = { + MX6_PAD_CSI0_DAT14__UART5_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT15__UART5_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT18__UART5_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT19__UART5_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +iomux_v3_cfg_t const i2c0_mux_pads[] = { + MX6_PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD2_CMD__GPIO1_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD2_DAT2__GPIO1_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +iomux_v3_cfg_t const i2c2_mux_pads[] = { + MX6_PAD_SD1_DAT1__GPIO1_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +struct i2c_pads_info i2c_pad_info0 = { + .scl = { + .i2c_mode = MX6_PAD_CSI0_DAT9__I2C1_SCL | PC_SCL, + .gpio_mode = MX6_PAD_CSI0_DAT9__GPIO5_IO27 | PC_SCL, + .gp = IMX_GPIO_NR(5, 27) + }, + .sda = { + .i2c_mode = MX6_PAD_CSI0_DAT8__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_CSI0_DAT8__GPIO5_IO26 | PC, + .gp = IMX_GPIO_NR(5, 26) + } +}; + +struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC_SCL, + .gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC_SCL, + .gp = IMX_GPIO_NR(1, 3) + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC, + .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC, + .gp = IMX_GPIO_NR(1, 6) + } +}; + +/* + * This enet related pin-muxing and GPIO handling is done + * in SPL U-Boot. For early initialization. And to give the + * PHY some time to come out of reset before the U-Boot + * ethernet driver tries to access its registers via MDIO. + */ +int platinum_setup_enet(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + unsigned phy_reset = IMX_GPIO_NR(1, 19); + + /* First configure PHY reset GPIO pin */ + imx_iomux_v3_setup_pad(phy_reset_pad); + + /* Reconfigure enet muxing while PHY is in reset */ + gpio_direction_output(phy_reset, 0); + imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); + mdelay(10); + gpio_set_value(phy_reset, 1); + udelay(100); + + /* set GPIO_16 as ENET_REF_CLK_OUT */ + setbits_le32(&iomux->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); + + return enable_fec_anatop_clock(ENET_50MHZ); +} + +int platinum_setup_i2c(void) +{ + imx_iomux_v3_setup_multiple_pads(i2c0_mux_pads, + ARRAY_SIZE(i2c0_mux_pads)); + imx_iomux_v3_setup_multiple_pads(i2c2_mux_pads, + ARRAY_SIZE(i2c2_mux_pads)); + + mdelay(10); + + /* Disable i2c mux 0 */ + gpio_direction_output(GPIO_I2C0_SEL0, 0); + gpio_direction_output(GPIO_I2C0_SEL1, 0); + gpio_direction_output(GPIO_I2C0_ENBN, 1); + + /* Disable i2c mux 1 */ + gpio_direction_output(GPIO_I2C2_SEL0, 0); + gpio_direction_output(GPIO_I2C2_SEL1, 0); + gpio_direction_output(GPIO_I2C2_ENBN, 1); + + udelay(10); + + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); + + /* Disable all leds */ + i2c_set_bus_num(0); + i2c_reg_write(0x60, 0x05, 0x55); + + return 0; +} + +int platinum_setup_spi(void) +{ + imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); + imx_iomux_v3_setup_multiple_pads(ecspi2_pads, ARRAY_SIZE(ecspi2_pads)); + + return 0; +} + +int platinum_setup_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); + imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); + imx_iomux_v3_setup_multiple_pads(uart5_pads, ARRAY_SIZE(uart5_pads)); + + return 0; +} + +int platinum_phy_config(struct phy_device *phydev) +{ + /* Use generic infrastructure, no specific setup */ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +int platinum_init_gpio(void) +{ + /* Reset FPGA's */ + gpio_direction_output(GPIO_IP_NCONFIG, 0); + gpio_direction_output(GPIO_HK_NCONFIG, 0); + gpio_direction_output(GPIO_LS_NCONFIG, 0); + udelay(3); + gpio_set_value(GPIO_IP_NCONFIG, 1); + gpio_set_value(GPIO_HK_NCONFIG, 1); + gpio_set_value(GPIO_LS_NCONFIG, 1); + + /* no dmd configuration yet */ + + return 0; +} + +int platinum_init_usb(void) +{ + /* Reset usb hub */ + gpio_direction_output(GPIO_USB_RESET, 0); + udelay(100); + gpio_set_value(GPIO_USB_RESET, 1); + + return 0; +} + +int platinum_init_finished(void) +{ + /* Enable led 0 */ + i2c_set_bus_num(0); + i2c_reg_write(0x60, 0x05, 0x54); + + return 0; +} diff --git a/board/barco/platinum/platinum_titanium.c b/board/barco/platinum/platinum_titanium.c new file mode 100644 index 0000000000..73a955f019 --- /dev/null +++ b/board/barco/platinum/platinum_titanium.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platinum.h" + +iomux_v3_cfg_t const ecspi1_pads[] = { + MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI1_PAD_CLK), + MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_MISO), + MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_MOSI), + MX6_PAD_CSI0_DAT7__ECSPI1_SS0 | MUX_PAD_CTRL(ECSPI_PAD_SS), + /* non mounted spi nor flash for booting */ + MX6_PAD_EIM_D19__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_EIM_D24__ECSPI1_SS2 | MUX_PAD_CTRL(ECSPI_PAD_SS), + MX6_PAD_EIM_D25__ECSPI1_SS3 | MUX_PAD_CTRL(ECSPI_PAD_SS), +}; + +iomux_v3_cfg_t const ecspi2_pads[] = { + MX6_PAD_EIM_CS0__ECSPI2_SCLK | MUX_PAD_CTRL(ECSPI2_PAD_CLK), + MX6_PAD_EIM_OE__ECSPI2_MISO | MUX_PAD_CTRL(ECSPI_PAD_MISO), + MX6_PAD_EIM_CS1__ECSPI2_MOSI | MUX_PAD_CTRL(ECSPI_PAD_MOSI), + MX6_PAD_EIM_RW__ECSPI2_SS0 | MUX_PAD_CTRL(ECSPI_PAD_SS), +}; + +iomux_v3_cfg_t const enet_pads1[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + /* pin 35 - 1 (PHY_AD2) on reset */ + MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 32 - 1 - (MODE0) all */ + MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 31 - 1 - (MODE1) all */ + MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 28 - 1 - (MODE2) all */ + MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 27 - 1 - (MODE3) all */ + MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */ + MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* pin 42 PHY nRST */ + MX6_PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +iomux_v3_cfg_t const enet_pads2[] = { + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart2_pads[] = { + MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D28__UART2_DTE_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_EIM_D29__UART2_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +iomux_v3_cfg_t const uart4_pads[] = { + MX6_PAD_CSI0_DAT12__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT13__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT16__UART4_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT17__UART4_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +struct i2c_pads_info i2c_pad_info0 = { + .scl = { + .i2c_mode = MX6_PAD_CSI0_DAT9__I2C1_SCL | PC_SCL, + .gpio_mode = MX6_PAD_CSI0_DAT9__GPIO5_IO27 | PC_SCL, + .gp = IMX_GPIO_NR(5, 27) + }, + .sda = { + .i2c_mode = MX6_PAD_CSI0_DAT8__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_CSI0_DAT8__GPIO5_IO26 | PC, + .gp = IMX_GPIO_NR(5, 26) + } +}; + +struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC_SCL, + .gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC_SCL, + .gp = IMX_GPIO_NR(1, 3) + }, + .sda = { + .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC, + .gpio_mode = MX6_PAD_GPIO_16__GPIO7_IO11 | PC, + .gp = IMX_GPIO_NR(7, 11) + } +}; + +/* + * This enet related pin-muxing and GPIO handling is done + * in SPL U-Boot. For early initialization. And to give the + * PHY some time to come out of reset before the U-Boot + * ethernet driver tries to access its registers via MDIO. + */ +int platinum_setup_enet(void) +{ + gpio_direction_output(IMX_GPIO_NR(3, 23), 0); + gpio_direction_output(IMX_GPIO_NR(6, 30), 1); + gpio_direction_output(IMX_GPIO_NR(6, 25), 1); + gpio_direction_output(IMX_GPIO_NR(6, 27), 1); + gpio_direction_output(IMX_GPIO_NR(6, 28), 1); + gpio_direction_output(IMX_GPIO_NR(6, 29), 1); + imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1)); + gpio_direction_output(IMX_GPIO_NR(6, 24), 1); + + /* Need delay 10ms according to KSZ9021 spec */ + mdelay(10); + gpio_set_value(IMX_GPIO_NR(3, 23), 1); + udelay(100); + + imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2)); + + return 0; +} + +int platinum_setup_i2c(void) +{ + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); + + return 0; +} + +int platinum_setup_spi(void) +{ + imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); + imx_iomux_v3_setup_multiple_pads(ecspi2_pads, ARRAY_SIZE(ecspi2_pads)); + + return 0; +} + +int platinum_setup_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); + imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); + imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads)); + + return 0; +} + +int platinum_phy_config(struct phy_device *phydev) +{ + /* min rx data delay */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, + 0x0); + /* min tx data delay */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, + 0x0); + /* max rx/tx clock delay, min rx/tx control */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, + 0xf0f0); + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +int platinum_init_gpio(void) +{ + /* Default GPIO's */ + /* Toggle CONFIG_n to reset fpga on every boot */ + gpio_direction_output(IMX_GPIO_NR(5, 18), 0); + /* Need delay >=2uS */ + udelay(3); + gpio_set_value(IMX_GPIO_NR(5, 18), 1); + + /* Default pin 1,15 high - DLP_FLASH_WPZ */ + gpio_direction_output(IMX_GPIO_NR(1, 15), 1); + + return 0; +} + +int platinum_init_usb(void) +{ + return 0; +} + +int platinum_init_finished(void) +{ + return 0; +} diff --git a/board/barco/platinum/spl_picon.c b/board/barco/platinum/spl_picon.c new file mode 100644 index 0000000000..f421c2108c --- /dev/null +++ b/board/barco/platinum/spl_picon.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * Based on: gw_ventana_spl.c which is: + * Copyright (C) 2014 Gateworks Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platinum.h" + +DECLARE_GLOBAL_DATA_PTR; + +#undef RTT_NOM_120OHM /* use 120ohm Rtt_nom vs 60ohm (lower power) */ + +/* Configure MX6Q/DUAL mmdc DDR io registers */ +struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = { + /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ + .dram_sdclk_0 = 0x00020030, + .dram_sdclk_1 = 0x00020030, + .dram_cas = 0x00020030, + .dram_ras = 0x00020030, + .dram_reset = 0x00020030, + /* SDCKE[0:1]: 100k pull-up */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + /* SDBA2: pull-up disabled */ + .dram_sdba2 = 0x00000000, + /* SDODT[0:1]: 100k pull-up, 40 ohm */ + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + /* SDQS[0:7]: Differential input, 40 ohm */ + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + /* DQM[0:7]: Differential input, 40 ohm */ + .dram_dqm0 = 0x00020030, + .dram_dqm1 = 0x00020030, + .dram_dqm2 = 0x00020030, + .dram_dqm3 = 0x00020030, + .dram_dqm4 = 0x00020030, + .dram_dqm5 = 0x00020030, + .dram_dqm6 = 0x00020030, + .dram_dqm7 = 0x00020030, +}; + +/* Configure MX6Q/DUAL mmdc GRP io registers */ +struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { + /* DDR3 */ + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + /* disable DDR pullups */ + .grp_ddrpke = 0x00000000, + /* ADDR[00:16], SDBA[0:1]: 40 ohm */ + .grp_addds = 0x00000030, + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ + .grp_ctlds = 0x00000030, + /* DATA[00:63]: Differential input, 40 ohm */ + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +/* MT41K256M16HA-125 */ +static struct mx6_ddr3_cfg mt41k256m16ha_125 = { + .mem_speed = 1600, + .density = 4, /* 4Gbit */ + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* + * Values from running the Freescale DDR stress tool via USB + */ +static struct mx6_mmdc_calibration mx6dq_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x0044004E, + .p0_mpwldectrl1 = 0x001F0023, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x02480248, + .p0_mpdgctrl1 = 0x0210021C, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x42444444, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x36322C32, +}; + +static void spl_dram_init(int width) +{ + struct mx6_ddr3_cfg *mem = &mt41k256m16ha_125; + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = width / 32, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* single chip select */ + .ncs = 1, + .cs1_mirror = 1, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ +#ifdef RTT_NOM_120OHM + .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */ +#else + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ +#endif + .walat = 0, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + }; + + mx6sdl_dram_iocfg(width, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6dq_mmdc_calib, mem); +} + +/* + * Called from C runtime startup code (arch/arm/lib/crt0.S:_main) + * - we have a stack and a place to store GD, both in SRAM + * - no variable global data is available + */ +void board_init_f(ulong dummy) +{ + /* Setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* UART iomux */ + board_early_init_f(); + + /* Setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* Init DDR with 32bit width */ + spl_dram_init(32); + + /* Clear the BSS */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* + * Setup enet related MUXing early to give the PHY + * some time to wake-up from reset + */ + platinum_setup_enet(); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} diff --git a/board/barco/platinum/spl_titanium.c b/board/barco/platinum/spl_titanium.c new file mode 100644 index 0000000000..26fe26ba2b --- /dev/null +++ b/board/barco/platinum/spl_titanium.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * Based on: gw_ventana_spl.c which is: + * Copyright (C) 2014 Gateworks Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platinum.h" + +DECLARE_GLOBAL_DATA_PTR; + +#undef RTT_NOM_120OHM /* use 120ohm Rtt_nom vs 60ohm (lower power) */ + +/* Configure MX6Q/DUAL mmdc DDR io registers */ +struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = { + /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ + .dram_sdclk_0 = 0x00020030, + .dram_sdclk_1 = 0x00020030, + .dram_cas = 0x00020030, + .dram_ras = 0x00020030, + .dram_reset = 0x00020030, + /* SDCKE[0:1]: 100k pull-up */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + /* SDBA2: pull-up disabled */ + .dram_sdba2 = 0x00000000, + /* SDODT[0:1]: 100k pull-up, 40 ohm */ + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + /* SDQS[0:7]: Differential input, 40 ohm */ + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + /* DQM[0:7]: Differential input, 40 ohm */ + .dram_dqm0 = 0x00020030, + .dram_dqm1 = 0x00020030, + .dram_dqm2 = 0x00020030, + .dram_dqm3 = 0x00020030, + .dram_dqm4 = 0x00020030, + .dram_dqm5 = 0x00020030, + .dram_dqm6 = 0x00020030, + .dram_dqm7 = 0x00020030, +}; + +/* Configure MX6Q/DUAL mmdc GRP io registers */ +struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = { + /* DDR3 */ + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + /* disable DDR pullups */ + .grp_ddrpke = 0x00000000, + /* ADDR[00:16], SDBA[0:1]: 40 ohm */ + .grp_addds = 0x00000030, + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ + .grp_ctlds = 0x00000030, + /* DATA[00:63]: Differential input, 40 ohm */ + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +/* MT41J128M16JT-125 */ +static struct mx6_ddr3_cfg mt41j128m16jt_125 = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +static struct mx6_mmdc_calibration mx6dq_mmdc_calib = { + /* Write leveling calibration determine */ + .p0_mpwldectrl0 = 0x001f001f, + .p0_mpwldectrl1 = 0x001f001f, + .p1_mpwldectrl0 = 0x00440044, + .p1_mpwldectrl1 = 0x00440044, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x434b0350, + .p0_mpdgctrl1 = 0x034c0359, + .p1_mpdgctrl0 = 0x434b0350, + .p1_mpdgctrl1 = 0x03650348, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x4436383b, + .p1_mprddlctl = 0x39393341, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x35373933, + .p1_mpwrdlctl = 0x48254a36, +}; + +static void spl_dram_init(int width) +{ + struct mx6_ddr3_cfg *mem = &mt41j128m16jt_125; + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = width / 32, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* single chip select */ + .ncs = 1, + .cs1_mirror = 1, + .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ +#ifdef RTT_NOM_120OHM + .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */ +#else + .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ +#endif + .walat = 0, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + }; + + mx6dq_dram_iocfg(width, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6dq_mmdc_calib, mem); +} + +/* + * Called from C runtime startup code (arch/arm/lib/crt0.S:_main) + * - we have a stack and a place to store GD, both in SRAM + * - no variable global data is available + */ +void board_init_f(ulong dummy) +{ + /* Setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* UART iomux */ + board_early_init_f(); + + /* Setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* Init DDR with 32bit width */ + spl_dram_init(32); + + /* Clear the BSS */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* + * Setup enet related MUXing early to give the PHY + * some time to wake-up from reset + */ + platinum_setup_enet(); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} diff --git a/configs/platinum_picon_defconfig b/configs/platinum_picon_defconfig new file mode 100644 index 0000000000..c3ca0400a1 --- /dev/null +++ b/configs/platinum_picon_defconfig @@ -0,0 +1,4 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6DL" ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_PLATINUM_PICON=y diff --git a/configs/platinum_titanium_defconfig b/configs/platinum_titanium_defconfig new file mode 100644 index 0000000000..db8cef9cf4 --- /dev/null +++ b/configs/platinum_titanium_defconfig @@ -0,0 +1,4 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6Q" ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_PLATINUM_TITANIUM=y diff --git a/include/configs/platinum.h b/include/configs/platinum.h new file mode 100644 index 0000000000..134bb45887 --- /dev/null +++ b/include/configs/platinum.h @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PLATINUM_CONFIG_H__ +#define __PLATINUM_CONFIG_H__ + +#define CONFIG_SYS_GENERIC_BOARD + +/* SPL */ +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT + +/* Location in NAND to read U-Boot from */ +#define CONFIG_SYS_NAND_U_BOOT_OFFS (14 * 1024 * 1024) + +#include "imx6_spl.h" /* common IMX6 SPL configuration */ +#include "mx6_common.h" +#include +#include + +/* + * Console configuration + */ + +#include +#define CONFIG_CMD_BMODE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_FUSE +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_I2C +#undef CONFIG_CMD_IMLS +#define CONFIG_CMD_MII +#define CONFIG_CMD_MMC +#define CONFIG_CMD_MTDPARTS +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NAND_TRIMFFS +#define CONFIG_CMD_NET +#define CONFIG_CMD_PING +#define CONFIG_CMD_TIME +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_CMD_USB + +/* + * Hardware configuration + */ + +/* GPIO config */ +#define CONFIG_MXC_GPIO + +/* UART config */ +#define CONFIG_MXC_UART +#define CONFIG_MXC_UART_BASE UART1_BASE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_CONS_INDEX 1 + +/* I2C config */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_SPEED 100000 + +/* MMC config */ +#define CONFIG_FSL_ESDHC +#define CONFIG_FSL_USDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 +#define CONFIG_SYS_FSL_USDHC_NUM 1 +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_BOUNCE_BUFFER +#define CONFIG_DOS_PARTITION + +/* Ethernet config */ +#define CONFIG_FEC_MXC +#define CONFIG_MII +#define IMX_FEC_BASE ENET_BASE_ADDR + +#define CONFIG_PHYLIB + +/* USB config */ +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_MX6 +#define CONFIG_USB_STORAGE +#define CONFIG_MXC_USB_PORT 1 +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#define CONFIG_MXC_USB_FLAGS 0 + +/* Memory config */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR +#ifndef PHYS_SDRAM_SIZE +#define PHYS_SDRAM_SIZE (1024 << 20) +#endif + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_SYS_MALLOC_LEN (16 * 1024 * 1024) + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH + +#ifdef CONFIG_CMD_NAND + +/* NAND config */ +#define CONFIG_NAND_MXS +#ifndef CONFIG_SYS_NAND_MAX_CHIPS +#define CONFIG_SYS_NAND_MAX_CHIPS 2 +#endif +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE 0x40000000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_SYS_NAND_ONFI_DETECTION + +/* DMA config, needed for GPMI/MXS NAND support */ +#define CONFIG_APBH_DMA +#define CONFIG_APBH_DMA_BURST +#define CONFIG_APBH_DMA_BURST8 + +/* Fuse support */ +#define CONFIG_MXC_OCOTP + +/* Environment in NAND */ +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET (16 << 20) +#define CONFIG_ENV_SECT_SIZE (128 << 10) +#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + (512 << 10)) +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE + +#else /* CONFIG_CMD_NAND */ + +/* Environment in MMC */ +#define CONFIG_ENV_SIZE (8 << 10) +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_OFFSET (6 * 64 * 1024) +#define CONFIG_SYS_MMC_ENV_DEV 0 + +#endif /* CONFIG_CMD_NAND */ + +/* + * U-Boot configuration + */ + +/* Console boot messages */ +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Tag config */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG + +/* Board startup config */ +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MISC_INIT_R + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Device tree support */ +#define CONFIG_OF_LIBFDT + +#define CONFIG_LOADADDR 0x12000000 +#define CONFIG_SYS_TEXT_BASE 0x17800000 + +#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ + PHYS_SDRAM_SIZE - (12 << 20)) + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTCOMMAND "run bootubi_scr" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_HUSH_PARSER + +#define CONFIG_AUTO_COMPLETE +#define CONFIG_CMDLINE_EDITING +#define CONFIG_PREBOOT + +#define CONFIG_SYS_CBSIZE 256 + +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +/* MTD/UBI/UBIFS config */ +#define CONFIG_LZO +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define CONFIG_RBTREE + +#if (CONFIG_SYS_NAND_MAX_CHIPS == 1) +#define MTDIDS_DEFAULT "nand0=gpmi-nand" +#define MTDPARTS_DEFAULT "mtdparts=gpmi-nand:14M(spl),2M(uboot)," \ + "512k(env1),512k(env2),-(ubi)" +#elif (CONFIG_SYS_NAND_MAX_CHIPS == 2) +#define MTDIDS_DEFAULT "nand0=gpmi-nand" +#define MTDPARTS_DEFAULT "mtdparts=gpmi-nand:14M(spl),2M(uboot)," \ + "512k(env1),512k(env2),495M(ubi0)," \ + "14M(res0),2M(res1)," \ + "512k(res2),512k(res3),-(ubi1)" +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +#define CONFIG_CMD_CACHE +#endif + +/* + * Environment configuration + */ + +#if (CONFIG_SYS_NAND_MAX_CHIPS == 1) +#define CONFIG_COMMON_ENV_UBI \ + "setubipartition=env set ubipartition ubi\0" \ + "setubirfs=env set ubirfs $ubipartition:rootfs$boot_vol\0" +#elif (CONFIG_SYS_NAND_MAX_CHIPS == 2) +#define CONFIG_COMMON_ENV_UBI \ + "setubipartition=env set ubipartition ubi$boot_vol\0" \ + "setubirfs=env set ubirfs ubi0:rootfs\0" +#endif + +#define CONFIG_COMMON_ENV_MISC \ + "user=user\0" \ + "project="CONFIG_PLATINUM_PROJECT"\0" \ + "uimage=uImage\0" \ + "dtb="CONFIG_PLATINUM_CPU"-platinum-"CONFIG_PLATINUM_PROJECT".dtb\0" \ + "serverip=serverip\0" \ + "memaddrlinux=0x10800000\0" \ + "memaddrsrc=0x11000000\0" \ + "memaddrdtb=0x12000000\0" \ + "console=ttymxc0\0" \ + "baudrate=115200\0" \ + "boot_scr=boot.uboot\0" \ + "boot_vol=0\0" \ + "mtdids="MTDIDS_DEFAULT"\0" \ + "mtdparts="MTDPARTS_DEFAULT"\0" \ + "mmcfs=ext2\0" \ + "mmcrootpart=1\0" \ + \ + "setnfspath=env set nfspath /home/nfs/$user/$project/root\0" \ + "settftpfilelinux=env set tftpfilelinux $user/$project/$uimage\0" \ + "settftpfiledtb=env set tftpfiledtb $user/$project/$dtb\0" \ + "setubifilelinux=env set ubifilelinux boot/$uimage\0" \ + "setubipfiledtb=env set ubifiledtb boot/$dtb\0" \ + "setmmcrootdev=env set mmcrootdev /dev/mmcblk0p$mmcrootpart\0" \ + "setmmcfilelinux=env set mmcfilelinux /boot/$uimage\0" \ + "setmmcfiledtb=env set mmcfiledtb /boot/$dtb\0" \ + \ + "loadtftpkernel=dhcp $memaddrlinux $tftpfilelinux\0" \ + "loadtftpdtb=dhcp $memaddrdtb $tftpfiledtb\0" \ + "loadubikernel=ubifsload $memaddrlinux $ubifilelinux\0" \ + "loadubidtb=ubifsload $memaddrdtb $ubifiledtb\0" \ + "loadmmckernel=${mmcfs}load mmc 0:$mmcrootpart $memaddrlinux " \ + "$mmcfilelinux\0" \ + "loadmmcdtb=${mmcfs}load mmc 0:$mmcrootpart $memaddrdtb " \ + "$mmcfiledtb\0" \ + \ + "ubipart=ubi part $ubipartition\0" \ + "ubimount=ubifsmount $ubirfs\0" \ + \ + "setbootargscommon=env set bootargs $bootargs " \ + "console=$console,$baudrate enable_wait_mode=off\0" \ + "setbootargsmtd=env set bootargs $bootargs $mtdparts\0" \ + "setbootargsdhcp=env set bootargs $bootargs ip=dhcp\0" \ + "setbootargsubirfs=env set bootargs $bootargs " \ + "ubi.mtd=$ubipartition root=$ubirfs rootfstype=ubifs\0" \ + "setbootargsnfsrfs=env set bootargs $bootargs root=/dev/nfs " \ + "nfsroot=$serverip:$nfspath,v3,tcp\0" \ + "setbootargsmmcrfs=env set bootargs $bootargs " \ + "root=$mmcrootdev rootwait rw\0" \ + \ + "bootnet=run settftpfilelinux settftpfiledtb setnfspath " \ + "setbootargscommon setbootargsmtd setbootargsdhcp " \ + "setbootargsnfsrfs;" \ + "run loadtftpkernel loadtftpdtb;" \ + "bootm $memaddrlinux - $memaddrdtb\0" \ + "bootnet_ubirfs=run settftpfilelinux settftpfiledtb;" \ + "run setubipartition setubirfs;" \ + "run setbootargscommon setbootargsmtd " \ + "setbootargsubirfs;" \ + "run loadtftpkernel loadtftpdtb;" \ + "bootm $memaddrlinux - $memaddrdtb\0" \ + "bootubi=run setubipartition setubirfs setubifilelinux " \ + "setubipfiledtb;" \ + "run setbootargscommon setbootargsmtd " \ + "setbootargsubirfs;" \ + "run ubipart ubimount loadubikernel loadubidtb;" \ + "bootm $memaddrlinux - $memaddrdtb\0" \ + "bootubi_scr=run setubipartition setubirfs;" \ + "run ubipart ubimount;" \ + "if ubifsload ${memaddrsrc} boot/${boot_scr}; " \ + "then source ${memaddrsrc}; else run bootubi; fi\0" \ + "bootmmc=run setmmcrootdev setmmcfilelinux setmmcfiledtb " \ + "setbootargscommon setbootargsmmcrfs;" \ + "run loadmmckernel loadmmcdtb;" \ + "bootm $memaddrlinux - $memaddrdtb\0" \ + \ + "bootcmd="CONFIG_BOOTCOMMAND"\0" + +#define CONFIG_COMMON_ENV_SETTINGS CONFIG_COMMON_ENV_MISC \ + CONFIG_COMMON_ENV_UBI +#endif /* __PLATINUM_CONFIG_H__ */ diff --git a/include/configs/platinum_picon.h b/include/configs/platinum_picon.h new file mode 100644 index 0000000000..4590df5a9e --- /dev/null +++ b/include/configs/platinum_picon.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PLATINUM_PICON_CONFIG_H__ +#define __PLATINUM_PICON_CONFIG_H__ + +#define CONFIG_PLATINUM_PICON +#define CONFIG_PLATINUM_BOARD "Barco Picon" +#define CONFIG_PLATINUM_PROJECT "picon" +#define CONFIG_PLATINUM_CPU "imx6dl" + +#define CONFIG_MX6 + +#include + +#define CONFIG_FEC_XCV_TYPE RMII +#define CONFIG_FEC_MXC_PHYADDR 0 + +#define CONFIG_HOSTNAME picon + +#define CONFIG_SYS_PROMPT "picon > " + +#define CONFIG_PLATFORM_ENV_SETTINGS "\0" + +#define CONFIG_EXTRA_ENV_SETTINGS CONFIG_COMMON_ENV_SETTINGS \ + CONFIG_PLATFORM_ENV_SETTINGS + +#endif /* __PLATINUM_PICON_CONFIG_H__ */ diff --git a/include/configs/platinum_titanium.h b/include/configs/platinum_titanium.h new file mode 100644 index 0000000000..678965505f --- /dev/null +++ b/include/configs/platinum_titanium.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014, Barco (www.barco.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __PLATINUM_TITANIUM_CONFIG_H__ +#define __PLATINUM_TITANIUM_CONFIG_H__ + +#define CONFIG_PLATINUM_TITANIUM +#define CONFIG_PLATINUM_BOARD "Barco Titanium" +#define CONFIG_PLATINUM_PROJECT "titanium" +#define CONFIG_PLATINUM_CPU "imx6q" + +#define CONFIG_MX6 + +#define PHYS_SDRAM_SIZE (512 << 20) +#define CONFIG_SYS_NAND_MAX_CHIPS 1 + +#include + +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 4 + +#define CONFIG_PHY_MICREL +#define CONFIG_PHY_MICREL_KSZ9021 +#define CONFIG_PHY_RESET_DELAY 1000 + +#define CONFIG_HOSTNAME titanium + +#define CONFIG_SYS_PROMPT "titanium > " + +#define CONFIG_PLATFORM_ENV_SETTINGS "\0" + +#define CONFIG_EXTRA_ENV_SETTINGS CONFIG_COMMON_ENV_SETTINGS \ + CONFIG_PLATFORM_ENV_SETTINGS + +#endif /* __PLATINUM_TITANIUM_CONFIG_H__ */ -- cgit From ca6dc4f81ce5a0d514cdeafd1823c92305368809 Mon Sep 17 00:00:00 2001 From: Alexandre Coffignal Date: Thu, 8 Jan 2015 17:14:42 +0100 Subject: mxsboot : Support of 224-bytes OOB area length Add support for the NAND Flash chip with page size of 4096+224-bytes OOB area length For example Micron MT29F4G08 NAND flash device defines a OOB area which is 224 bytes long (oobsize). Signed-off-by: Alexandre Coffignal --- tools/mxsboot.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/mxsboot.c b/tools/mxsboot.c index 90b21737b9..6d48cfb3e4 100644 --- a/tools/mxsboot.c +++ b/tools/mxsboot.c @@ -142,6 +142,9 @@ static inline uint32_t mx28_nand_get_ecc_strength(uint32_t page_data_size, if (page_oob_size == 218) return 16; + + if (page_oob_size == 224) + return 16; } return 0; @@ -269,6 +272,9 @@ static struct mx28_nand_fcb *mx28_nand_get_fcb(uint32_t size) } else if (nand_oobsize == 218) { fcb->ecc_block_n_ecc_type = 8; fcb->ecc_block_0_ecc_type = 8; + } else if (nand_oobsize == 224) { + fcb->ecc_block_n_ecc_type = 8; + fcb->ecc_block_0_ecc_type = 8; } } -- cgit From d1a2e91611dace8e33ce6257be21c3b7627df036 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:23:58 +0800 Subject: imx:mx6sxsabresd add spl config file Add a SPL default configuration file for mx6sxsabresd board. Signed-off-by: Peng Fan --- configs/mx6sxsabresd_spl_defconfig | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 configs/mx6sxsabresd_spl_defconfig diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig new file mode 100644 index 0000000000..6b36e06a85 --- /dev/null +++ b/configs/mx6sxsabresd_spl_defconfig @@ -0,0 +1,4 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX" ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_MX6SXSABRESD=y -- cgit From 3dae50d0a7ff4b2b097aad3e523ee2084cc66c37 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:23:59 +0800 Subject: imx:mx6sxsabresd select SUPPORT_SPL select SUPPORT_SPL for mx6sxsabresd. Signed-off-by: Peng Fan --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dd35992983..2ebc3e11f5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -637,6 +637,7 @@ config TARGET_MX6SLEVK config TARGET_MX6SXSABRESD bool "Support mx6sxsabresd" select CPU_V7 + select SUPPORT_SPL config TARGET_GW_VENTANA bool "Support gw_ventana" -- cgit From 71abf19b0f0ee1534ac8945a76606b34fea57b57 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:24:00 +0800 Subject: imx:mx6sxsabresd spl support in header file Add SPL support in mx6sxsabresd header file. Signed-off-by: Peng Fan --- include/configs/mx6sxsabresd.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 3aae808ba9..54cdd64115 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -18,6 +18,12 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#ifdef CONFIG_SPL +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#include "imx6_spl.h" +#endif + #define CONFIG_CMDLINE_TAG #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG -- cgit From d9efd47c036e8990d001baf245f5d0a31cfcb56b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:24:01 +0800 Subject: imx:mx6sx add dram io configure for mx6sx Define two structure mx6sx_iomux_ddr_regs and mx6sx_iomux_grp_regs. Add a new function mx6sx_dram_iocfg to configure dram io. Since mx6sx only have one channel mmdc0, define a new empty macro MMDC1 to replace mmdc1->entry=value for mx6sx. And to other mx6 soc, MMDC1 effects as "mmdc1->entry=value". Signed-off-by: Peng Fan --- arch/arm/cpu/armv7/mx6/ddr.c | 96 ++++++++++++++++++++++++++++----- arch/arm/include/asm/arch-mx6/mx6-ddr.h | 46 ++++++++++++++++ 2 files changed, 128 insertions(+), 14 deletions(-) diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c index 7a9b03a68f..fef2231a39 100644 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ b/arch/arm/cpu/armv7/mx6/ddr.c @@ -12,6 +12,65 @@ #include #include +#if defined(CONFIG_MX6SX) +/* Configure MX6SX mmdc iomux */ +void mx6sx_dram_iocfg(unsigned width, + const struct mx6sx_iomux_ddr_regs *ddr, + const struct mx6sx_iomux_grp_regs *grp) +{ + struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux; + struct mx6sx_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE; + + /* DDR IO TYPE */ + writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type); + writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke); + + /* CLOCK */ + writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0); + + /* ADDRESS */ + writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas); + writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras); + writel(grp->grp_addds, &mx6_grp_iomux->grp_addds); + + /* Control */ + writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset); + writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2); + writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0); + writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1); + writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0); + writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1); + writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds); + + /* Data Strobes */ + writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl); + writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0); + writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1); + if (width >= 32) { + writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2); + writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3); + } + + /* Data */ + writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode); + writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds); + writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds); + if (width >= 32) { + writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds); + writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds); + } + writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0); + writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1); + if (width >= 32) { + writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2); + writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3); + } +} +#endif + #if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) /* Configure MX6DQ mmdc iomux */ void mx6dq_dram_iocfg(unsigned width, @@ -184,12 +243,19 @@ void mx6sdl_dram_iocfg(unsigned width, */ #define MR(val, ba, cmd, cs1) \ ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) +#ifdef CONFIG_MX6SX +#define MMDC1(entry, value) do {} while (0) +#else +#define MMDC1(entry, value) do { mmdc1->entry = value; } while (0) +#endif void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, const struct mx6_mmdc_calibration *calib, const struct mx6_ddr3_cfg *ddr3_cfg) { volatile struct mmdc_p_regs *mmdc0; +#ifndef CONFIG_MX6SX volatile struct mmdc_p_regs *mmdc1; +#endif u32 val; u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd; u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl; @@ -203,7 +269,9 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, int cs; mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; +#ifndef CONFIG_MX6SX mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; +#endif /* MX6D/MX6Q: 1066 MHz memory clock, clkper = 1.894ns = 1894ps */ if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) { @@ -362,12 +430,12 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, mmdc0->mprddlctl = calib->p0_mprddlctl; mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; if (sysinfo->dsize > 1) { - mmdc1->mpwldectrl0 = calib->p1_mpwldectrl0; - mmdc1->mpwldectrl1 = calib->p1_mpwldectrl1; - mmdc1->mpdgctrl0 = calib->p1_mpdgctrl0; - mmdc1->mpdgctrl1 = calib->p1_mpdgctrl1; - mmdc1->mprddlctl = calib->p1_mprddlctl; - mmdc1->mpwrdlctl = calib->p1_mpwrdlctl; + MMDC1(mpwldectrl0, calib->p1_mpwldectrl0); + MMDC1(mpwldectrl1, calib->p1_mpwldectrl1); + MMDC1(mpdgctrl0, calib->p1_mpdgctrl0); + MMDC1(mpdgctrl1, calib->p1_mpdgctrl1); + MMDC1(mprddlctl, calib->p1_mprddlctl); + MMDC1(mpwrdlctl, calib->p1_mpwrdlctl); } /* Read data DQ Byte0-3 delay */ @@ -379,23 +447,23 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, } if (sysinfo->dsize > 1) { - mmdc1->mprddqby0dl = 0x33333333; - mmdc1->mprddqby1dl = 0x33333333; - mmdc1->mprddqby2dl = 0x33333333; - mmdc1->mprddqby3dl = 0x33333333; + MMDC1(mprddqby0dl, 0x33333333); + MMDC1(mprddqby1dl, 0x33333333); + MMDC1(mprddqby2dl, 0x33333333); + MMDC1(mprddqby3dl, 0x33333333); } /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; mmdc0->mpodtctrl = val; if (sysinfo->dsize > 1) - mmdc1->mpodtctrl = val; + MMDC1(mpodtctrl, val); /* complete calibration */ val = (1 << 11); /* Force measurement on delay-lines */ mmdc0->mpmur0 = val; if (sysinfo->dsize > 1) - mmdc1->mpmur0 = val; + MMDC1(mpmur0, val); /* Step 1: configuration request */ mmdc0->mdscr = (u32)(1 << 15); /* config request */ @@ -435,7 +503,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, val = 0xa1390001; /* one-time HW ZQ calib */ mmdc0->mpzqhwctrl = val; if (sysinfo->dsize > 1) - mmdc1->mpzqhwctrl = val; + MMDC1(mpzqhwctrl, val); /* Step 7: Enable MMDC with desired chip select */ mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */ @@ -477,7 +545,7 @@ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, val = 0xa1390003; mmdc0->mpzqhwctrl = val; if (sysinfo->dsize > 1) - mmdc1->mpzqhwctrl = val; + MMDC1(mpzqhwctrl, val); /* Step 12: Configure and activate periodic refresh */ mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */ diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h index 5ebabfa271..8e0d7d15c1 100644 --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h @@ -62,6 +62,49 @@ struct mmdc_p_regs { u32 mpmur0; }; +#define MX6SX_IOM_DDR_BASE 0x020e0200 +struct mx6sx_iomux_ddr_regs { + u32 res1[59]; + u32 dram_dqm0; + u32 dram_dqm1; + u32 dram_dqm2; + u32 dram_dqm3; + u32 dram_ras; + u32 dram_cas; + u32 res2[2]; + u32 dram_sdwe_b; + u32 dram_odt0; + u32 dram_odt1; + u32 dram_sdba0; + u32 dram_sdba1; + u32 dram_sdba2; + u32 dram_sdcke0; + u32 dram_sdcke1; + u32 dram_sdclk_0; + u32 dram_sdqs0; + u32 dram_sdqs1; + u32 dram_sdqs2; + u32 dram_sdqs3; + u32 dram_reset; +}; + +#define MX6SX_IOM_GRP_BASE 0x020e0500 +struct mx6sx_iomux_grp_regs { + u32 res1[61]; + u32 grp_addds; + u32 grp_ddrmode_ctl; + u32 grp_ddrpke; + u32 grp_ddrpk; + u32 grp_ddrhys; + u32 grp_ddrmode; + u32 grp_b0ds; + u32 grp_b1ds; + u32 grp_ctlds; + u32 grp_ddr_type; + u32 grp_b2ds; + u32 grp_b3ds; +}; + /* * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL) */ @@ -243,6 +286,9 @@ void mx6dq_dram_iocfg(unsigned width, void mx6sdl_dram_iocfg(unsigned width, const struct mx6sdl_iomux_ddr_regs *, const struct mx6sdl_iomux_grp_regs *); +void mx6sx_dram_iocfg(unsigned width, + const struct mx6sx_iomux_ddr_regs *, + const struct mx6sx_iomux_grp_regs *); /* configure mx6 mmdc registers */ void mx6_dram_cfg(const struct mx6_ddr_sysinfo *, -- cgit From f9e89ffd16b734997e6eacb32293899ceaed49ee Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:24:02 +0800 Subject: imx:mx6 add mx6sx in imx spl header file Since mx6sx's memory space is different to mx6dq, redefine the SPL related macro for mx6sx chip. Signed-off-by: Peng Fan --- include/configs/imx6_spl.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/configs/imx6_spl.h b/include/configs/imx6_spl.h index 1b9c2773be..21c5dce097 100644 --- a/include/configs/imx6_spl.h +++ b/include/configs/imx6_spl.h @@ -61,11 +61,19 @@ #define CONFIG_SPL_LIBDISK_SUPPORT #endif +#if defined(CONFIG_MX6SX) +#define CONFIG_SPL_BSS_START_ADDR 0x88200000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x100000 /* 1 MB */ +#define CONFIG_SYS_SPL_MALLOC_START 0x88300000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x3200000 /* 50 MB */ +#define CONFIG_SYS_TEXT_BASE 0x87800000 +#else #define CONFIG_SPL_BSS_START_ADDR 0x18200000 #define CONFIG_SPL_BSS_MAX_SIZE 0x100000 /* 1 MB */ #define CONFIG_SYS_SPL_MALLOC_START 0x18300000 #define CONFIG_SYS_SPL_MALLOC_SIZE 0x3200000 /* 50 MB */ #define CONFIG_SYS_TEXT_BASE 0x17800000 #endif +#endif #endif -- cgit From 1565d54a7671a139e225327dd2dc6871c590ac91 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 30 Dec 2014 17:24:03 +0800 Subject: imx:mx6sxsabresd board spl support Add board level spl support for mx6sxsabresd board. Signed-off-by: Peng Fan --- board/freescale/mx6sxsabresd/MAINTAINERS | 1 + board/freescale/mx6sxsabresd/mx6sxsabresd.c | 168 ++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/board/freescale/mx6sxsabresd/MAINTAINERS b/board/freescale/mx6sxsabresd/MAINTAINERS index f52f300bed..c0f5d9c8e4 100644 --- a/board/freescale/mx6sxsabresd/MAINTAINERS +++ b/board/freescale/mx6sxsabresd/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/freescale/mx6sxsabresd/ F: include/configs/mx6sxsabresd.h F: configs/mx6sxsabresd_defconfig +F: configs/mx6sxsabresd_spl_defconfig diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index a848f4103a..a2c9aae32c 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -326,6 +326,7 @@ int board_mmc_getcd(struct mmc *mmc) int board_mmc_init(bd_t *bis) { +#ifndef CONFIG_SPL_BUILD int i, ret; /* @@ -369,6 +370,47 @@ int board_mmc_init(bd_t *bis) } return 0; +#else + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + u32 val; + u32 port; + + val = readl(&src_regs->sbmr1); + + if ((val & 0xc0) != 0x40) { + printf("Not boot from USDHC!\n"); + return -EINVAL; + } + + port = (val >> 11) & 0x3; + printf("port %d\n", port); + switch (port) { + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + break; + case 2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + gpio_direction_input(USDHC3_CD_GPIO); + gpio_direction_output(USDHC3_PWR_GPIO, 1); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; + break; + case 3: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + gpio_direction_input(USDHC4_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; + break; + } + + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +#endif } #ifdef CONFIG_FSL_QSPI @@ -429,3 +471,129 @@ int checkboard(void) return 0; } + +#ifdef CONFIG_SPL_BUILD +#include +#include +#include + +const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = { + .dram_dqm0 = 0x00000028, + .dram_dqm1 = 0x00000028, + .dram_dqm2 = 0x00000028, + .dram_dqm3 = 0x00000028, + .dram_ras = 0x00000020, + .dram_cas = 0x00000020, + .dram_odt0 = 0x00000020, + .dram_odt1 = 0x00000020, + .dram_sdba2 = 0x00000000, + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + .dram_sdclk_0 = 0x00000030, + .dram_sdqs0 = 0x00000028, + .dram_sdqs1 = 0x00000028, + .dram_sdqs2 = 0x00000028, + .dram_sdqs3 = 0x00000028, + .dram_reset = 0x00000020, +}; + +const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = { + .grp_addds = 0x00000020, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000028, + .grp_b1ds = 0x00000028, + .grp_ctlds = 0x00000020, + .grp_ddr_type = 0x000c0000, + .grp_b2ds = 0x00000028, + .grp_b3ds = 0x00000028, +}; + +const struct mx6_mmdc_calibration mx6_mmcd_calib = { + .p0_mpwldectrl0 = 0x00290025, + .p0_mpwldectrl1 = 0x00220022, + .p0_mpdgctrl0 = 0x41480144, + .p0_mpdgctrl1 = 0x01340130, + .p0_mprddlctl = 0x3C3E4244, + .p0_mpwrdlctl = 0x34363638, +}; + +static struct mx6_ddr3_cfg mem_ddr = { + .mem_speed = 1600, + .density = 4, + .width = 32, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0xFFFFFFFF, &ccm->CCGR0); + writel(0xFFFFFFFF, &ccm->CCGR1); + writel(0xFFFFFFFF, &ccm->CCGR2); + writel(0xFFFFFFFF, &ccm->CCGR3); + writel(0xFFFFFFFF, &ccm->CCGR4); + writel(0xFFFFFFFF, &ccm->CCGR5); + writel(0xFFFFFFFF, &ccm->CCGR6); + writel(0xFFFFFFFF, &ccm->CCGR7); +} + +static void spl_dram_init(void) +{ + struct mx6_ddr_sysinfo sysinfo = { + .dsize = mem_ddr.width/32, + .cs_density = 24, + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 2, + .rtt_nom = 2, /* RTT_Nom = RZQ/2 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + }; + + mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs); + mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); +} + +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + + /* iomux and setup of i2c */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +void reset_cpu(ulong addr) +{ +} +#endif -- cgit From 0da040bfd4b7e3cafd739d3eebf20b3bdb27245f Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Fri, 16 Jan 2015 16:47:44 +0800 Subject: imx: mx6: Change ENV offset to 512K bytes for larger u-boot image To align with other mx6 boards, change ENV offset from 384KB to 512KB position to fit a larger u-boot image. Signed-off-by: Ye.Li --- include/configs/mx6slevk.h | 2 +- include/configs/mx6sxsabresd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h index e6c41306a3..c567d9dbb6 100644 --- a/include/configs/mx6slevk.h +++ b/include/configs/mx6slevk.h @@ -198,7 +198,7 @@ #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED #else -#define CONFIG_ENV_OFFSET (6 * SZ_64K) +#define CONFIG_ENV_OFFSET (8 * SZ_64K) #define CONFIG_ENV_IS_IN_MMC #endif diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 54cdd64115..404b922d39 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -260,7 +260,7 @@ #define FSL_QSPI_FLASH_NUM 2 #endif -#define CONFIG_ENV_OFFSET (6 * SZ_64K) +#define CONFIG_ENV_OFFSET (8 * SZ_64K) #define CONFIG_ENV_SIZE SZ_8K #define CONFIG_ENV_IS_IN_MMC -- cgit From 5ba49e75afa9c9f6a6de478f519dd5c284f260cc Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Thu, 22 Jan 2015 10:09:00 +0100 Subject: mx6: fix warning in platinum board Fix warning due to missing prototype for writel Signed-off-by: Stefano Babic Acked-by: Stefan Roese --- board/barco/platinum/platinum.h | 1 + 1 file changed, 1 insertion(+) diff --git a/board/barco/platinum/platinum.h b/board/barco/platinum/platinum.h index 8650d6d5e0..d3ea8bda73 100644 --- a/board/barco/platinum/platinum.h +++ b/board/barco/platinum/platinum.h @@ -9,6 +9,7 @@ #include #include +#include /* Defines */ -- cgit From 8551b3661c6baf547c4c046864dd5001a95778b0 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:44 +0100 Subject: ot1200: select SUPPORT_SPL Signed-off-by: Christian Gmeiner --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2ebc3e11f5..7df6221c0f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -664,6 +664,7 @@ config TARGET_TQMA6 config TARGET_OT1200 bool "Bachmann OT1200" select CPU_V7 + select SUPPORT_SPL config TARGET_PLATINUM_PICON bool "Support platinum-picon" -- cgit From f77dd6d7dbe42cee2b03d1b4c8b34ceb15643174 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:45 +0100 Subject: ot1200: make use of imx_ddr_size(..) To support different ddr3 memory sizes we should start using imx_ddr_size(..) instead of the define PHYS_SDRAM_SIZE. Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/ot1200.c | 3 ++- include/configs/ot1200.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index 93f3d65176..039e858706 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + gd->ram_size = imx_ddr_size(); return 0; } diff --git a/include/configs/ot1200.h b/include/configs/ot1200.h index 255c933baa..97ee664e20 100644 --- a/include/configs/ot1200.h +++ b/include/configs/ot1200.h @@ -159,7 +159,6 @@ /* Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 1 #define PHYS_SDRAM MMDC0_ARB_BASE_ADDR -#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024) #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM #define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR -- cgit From 84c5dd16a45cc6502bf622ea33543a53102d681f Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:46 +0100 Subject: ot1200: move ccgr and gpr init to c functions We need this way for SPL boot. Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/mx6q_4x_mt41j128.cfg | 14 -------------- board/bachmann/ot1200/ot1200.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/board/bachmann/ot1200/mx6q_4x_mt41j128.cfg b/board/bachmann/ot1200/mx6q_4x_mt41j128.cfg index bb6c60b4c3..c25f99dcfd 100644 --- a/board/bachmann/ot1200/mx6q_4x_mt41j128.cfg +++ b/board/bachmann/ot1200/mx6q_4x_mt41j128.cfg @@ -142,20 +142,6 @@ DATA 4 0x021b48b8 0x00000800 DATA 4 0x021b001c 0x00000000 DATA 4 0x021b0404 0x00011006 -/* set the default clock gate to save power */ -DATA 4 0x020c4068 0x00C03F3F -DATA 4 0x020c406c 0x0030FC03 -DATA 4 0x020c4070 0x0FFFC000 -DATA 4 0x020c4074 0x3FF00000 -DATA 4 0x020c4078 0x00FFF300 -DATA 4 0x020c407c 0x0F0000C3 -DATA 4 0x020c4080 0x000003FF - -/* enable AXI cache for VDOA/VPU/IPU */ -DATA 4 0x020e0010 0xF00000CF -/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ -DATA 4 0x020e0018 0x007F007F -DATA 4 0x020e001c 0x007F007F /* * Setup CCM_CCOSR register as follows: diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index 039e858706..6b6c1a33a9 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -119,8 +120,35 @@ static void setup_iomux_features(void) ARRAY_SIZE(feature_pads)); } +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000C3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void gpr_init(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* enable AXI cache for VDOA/VPU/IPU */ + writel(0xF00000CF, &iomux->gpr[4]); + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ + writel(0x007F007F, &iomux->gpr[6]); + writel(0x007F007F, &iomux->gpr[7]); +} + int board_early_init_f(void) { + ccgr_init(); + gpr_init(); + setup_iomux_uart(); setup_iomux_spi(); setup_iomux_features(); -- cgit From e88b83575a94b76a57161d98ec659460cb83ffab Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:47 +0100 Subject: ot1200: enable spi clock directly in ccgr_init(..) Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/ot1200.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/board/bachmann/ot1200/ot1200.c b/board/bachmann/ot1200/ot1200.c index 6b6c1a33a9..e434ed9b87 100644 --- a/board/bachmann/ot1200/ot1200.c +++ b/board/bachmann/ot1200/ot1200.c @@ -125,7 +125,7 @@ static void ccgr_init(void) struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; writel(0x00C03F3F, &ccm->CCGR0); - writel(0x0030FC03, &ccm->CCGR1); + writel(0x0030FC33, &ccm->CCGR1); writel(0x0FFFC000, &ccm->CCGR2); writel(0x3FF00000, &ccm->CCGR3); writel(0x00FFF300, &ccm->CCGR4); @@ -319,9 +319,6 @@ int board_init(void) leds_on(); - /* enable ecspi3 clocks */ - enable_cspi_clock(1, 2); - #ifdef CONFIG_CMD_SATA setup_sata(); #endif -- cgit From 68a3664aec94c10213f082dabe4921f556bdc928 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:48 +0100 Subject: ot1200: add SPL configuration We will only support loading u-boot.img from SPI flash stored at the offset of 64k. Signed-off-by: Christian Gmeiner --- include/configs/ot1200.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/configs/ot1200.h b/include/configs/ot1200.h index 97ee664e20..c061e93534 100644 --- a/include/configs/ot1200.h +++ b/include/configs/ot1200.h @@ -108,6 +108,16 @@ #endif +/* SPL */ +#ifdef CONFIG_SPL +#include "imx6_spl.h" +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SYS_SPI_U_BOOT_OFFS (64 * 1024) +#define CONFIG_SPL_SPI_LOAD +#endif + #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_CMD_MII -- cgit From 532491712610ef903e5f53b1da799fc0011829e0 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:49 +0100 Subject: ot1200: add basic SPL support Currently we only support the Micron MT41K128M16JT-125 ddr3 chip. Signed-off-by: Christian Gmeiner --- board/bachmann/ot1200/Makefile | 4 + board/bachmann/ot1200/ot1200_spl.c | 162 +++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 board/bachmann/ot1200/ot1200_spl.c diff --git a/board/bachmann/ot1200/Makefile b/board/bachmann/ot1200/Makefile index 1bd42e8321..9e50bfeb86 100644 --- a/board/bachmann/ot1200/Makefile +++ b/board/bachmann/ot1200/Makefile @@ -6,4 +6,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +ifdef CONFIG_SPL_BUILD +obj-y := ot1200.o ot1200_spl.o +else obj-y := ot1200.o +endif diff --git a/board/bachmann/ot1200/ot1200_spl.c b/board/bachmann/ot1200/ot1200_spl.c new file mode 100644 index 0000000000..9c77fd3330 --- /dev/null +++ b/board/bachmann/ot1200/ot1200_spl.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2015, Bachmann electronic GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Configure MX6Q/DUAL mmdc DDR io registers */ +static struct mx6dq_iomux_ddr_regs ot1200_ddr_ioregs = { + /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 48ohm */ + .dram_sdclk_0 = 0x00000028, + .dram_sdclk_1 = 0x00000028, + .dram_cas = 0x00000028, + .dram_ras = 0x00000028, + .dram_reset = 0x00000028, + /* SDCKE[0:1]: 100k pull-up */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + /* SDBA2: pull-up disabled */ + .dram_sdba2 = 0x00000000, + /* SDODT[0:1]: 100k pull-up, 48 ohm */ + .dram_sdodt0 = 0x00000028, + .dram_sdodt1 = 0x00000028, + /* SDQS[0:7]: Differential input, 48 ohm */ + .dram_sdqs0 = 0x00000028, + .dram_sdqs1 = 0x00000028, + .dram_sdqs2 = 0x00000028, + .dram_sdqs3 = 0x00000028, + .dram_sdqs4 = 0x00000028, + .dram_sdqs5 = 0x00000028, + .dram_sdqs6 = 0x00000028, + .dram_sdqs7 = 0x00000028, + /* DQM[0:7]: Differential input, 48 ohm */ + .dram_dqm0 = 0x00000028, + .dram_dqm1 = 0x00000028, + .dram_dqm2 = 0x00000028, + .dram_dqm3 = 0x00000028, + .dram_dqm4 = 0x00000028, + .dram_dqm5 = 0x00000028, + .dram_dqm6 = 0x00000028, + .dram_dqm7 = 0x00000028, +}; + +/* Configure MX6Q/DUAL mmdc GRP io registers */ +static struct mx6dq_iomux_grp_regs ot1200_grp_ioregs = { + /* DDR3 */ + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + /* Disable DDR pullups */ + .grp_ddrpke = 0x00000000, + /* ADDR[00:16], SDBA[0:1]: 48 ohm */ + .grp_addds = 0x00000028, + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 48 ohm */ + .grp_ctlds = 0x00000028, + /* DATA[00:63]: Differential input, 48 ohm */ + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000028, + .grp_b1ds = 0x00000028, + .grp_b2ds = 0x00000028, + .grp_b3ds = 0x00000028, + .grp_b4ds = 0x00000028, + .grp_b5ds = 0x00000028, + .grp_b6ds = 0x00000028, + .grp_b7ds = 0x00000028, +}; + +static struct mx6_ddr_sysinfo ot1200_ddr_sysinfo = { + /* Width of data bus: 0=16, 1=32, 2=64 */ + .dsize = 2, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + /* Single chip select */ + .ncs = 1, + .cs1_mirror = 0, /* war 0 */ + .rtt_wr = 1, /* DDR3_RTT_60_OHM - RTT_Wr = RZQ/4 */ + .rtt_nom = 1, /* DDR3_RTT_60_OHM - RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ /* war 1 */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ +}; + +/* MT41K128M16JT-125 */ +static struct mx6_ddr3_cfg micron_2gib_1600 = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, + .SRT = 1, +}; + +static struct mx6_mmdc_calibration micron_2gib_1600_mmdc_calib = { + /* write leveling calibration determine */ + .p0_mpwldectrl0 = 0x00260025, + .p0_mpwldectrl1 = 0x00270021, + .p1_mpwldectrl0 = 0x00180034, + .p1_mpwldectrl1 = 0x00180024, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x04380344, + .p0_mpdgctrl1 = 0x0330032C, + .p1_mpdgctrl0 = 0x0338033C, + .p1_mpdgctrl1 = 0x032C0300, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x3C2E3238, + .p1_mprddlctl = 0x3A2E303C, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x36384036, + .p1_mpwrdlctl = 0x442E4438, +}; + +static void ot1200_spl_dram_init(void) +{ + mx6dq_dram_iocfg(64, &ot1200_ddr_ioregs, &ot1200_grp_ioregs); + mx6_dram_cfg(&ot1200_ddr_sysinfo, µn_2gib_1600_mmdc_calib, + µn_2gib_1600); +} + +/* + * called from C runtime startup code (arch/arm/lib/crt0.S:_main) + * - we have a stack and a place to store GD, both in SRAM + * - no variable global data is available + */ +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + /* iomux and setup of i2c */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* configure MMDC for SDRAM width/size and per-model calibration */ + ot1200_spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +void reset_cpu(ulong addr) +{ +} -- cgit From 8af9aff1e51543cbe50cd9ffdf1b9d01169a8c03 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Mon, 19 Jan 2015 17:26:50 +0100 Subject: ot1200: add ot1200_spl_defconfig file Signed-off-by: Christian Gmeiner Acked-by: Stefano Babic # --- configs/ot1200_spl_defconfig | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 configs/ot1200_spl_defconfig diff --git a/configs/ot1200_spl_defconfig b/configs/ot1200_spl_defconfig new file mode 100644 index 0000000000..ad57f88c9d --- /dev/null +++ b/configs/ot1200_spl_defconfig @@ -0,0 +1,4 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6Q" ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_OT1200=y -- cgit From 40da2a2a08f12015d06d78a334e4d977963fee34 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 20 Jan 2015 09:05:23 +0100 Subject: ubi: reset mtd_devs when ubi part fail if "ubi part" fails, reset also mtd_devs to 0, as further "ubi part" would use wrong mtd_devs. Signed-off-by: Heiko Schocher --- drivers/mtd/ubi/build.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 584cf5f22b..290d524b1b 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1358,6 +1358,10 @@ out_version: out_class: class_destroy(ubi_class); out: +#ifdef __UBOOT__ + /* Reset any globals that the driver depends on being zeroed */ + mtd_devs = 0; +#endif ubi_err("cannot initialize UBI, error %d", err); return err; } @@ -1384,6 +1388,10 @@ void ubi_exit(void) misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); +#ifdef __UBOOT__ + /* Reset any globals that the driver depends on being zeroed */ + mtd_devs = 0; +#endif } module_exit(ubi_exit); -- cgit From dc2884315d492b1eefd9d32443c1f0aa3c0a991e Mon Sep 17 00:00:00 2001 From: Anton Habegger Date: Thu, 22 Jan 2015 22:29:10 +0100 Subject: ubifs: Import atomic_long operations from Linux This commit is a preperation for a subsequent UBIFS commit which needs atomic_long operations. Therefor "include/asm-generic/atomic-long.h" is imported from 1860e37 Linux 3.15 Signed-off-by: Anton Habegger --- fs/ubifs/ubifs.c | 6 + fs/ubifs/ubifs.h | 12 +- include/asm-generic/atomic-long.h | 260 ++++++++++++++++++++++++++++++++++++++ include/linux/compat.h | 1 - 4 files changed, 268 insertions(+), 11 deletions(-) create mode 100644 include/asm-generic/atomic-long.h diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 49e6f469ca..6dd617426a 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -150,6 +150,12 @@ static inline int crypto_comp_decompress(struct crypto_comp *tfm, return 0; } + +/* from shrinker.c */ + +/* Global clean znode counter (for all mounted UBIFS instances) */ +atomic_long_t ubifs_clean_zn_cnt; + #endif /** diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index c12026147f..a51b2376d2 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -31,6 +31,8 @@ #include #include "ubifs-media.h" #else +#include +#include #include #include @@ -63,16 +65,6 @@ struct page { void iput(struct inode *inode); -/* - * The atomic operations are used for budgeting etc which is not - * needed for the read-only U-Boot implementation: - */ -#define atomic_long_inc(a) -#define atomic_long_dec(a) -#define atomic_long_sub(a, b) - -typedef unsigned long atomic_long_t; - /* linux/include/time.h */ #define NSEC_PER_SEC 1000000000L #define get_seconds() 0 diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h new file mode 100644 index 0000000000..d0469ef2e3 --- /dev/null +++ b/include/asm-generic/atomic-long.h @@ -0,0 +1,260 @@ +#ifndef _ASM_GENERIC_ATOMIC_LONG_H +#define _ASM_GENERIC_ATOMIC_LONG_H +/* + * Copyright (C) 2005 Silicon Graphics, Inc. + * Christoph Lameter + * + * Allows to provide arch independent atomic definitions without the need to + * edit all arch specific atomic.h files. + */ + +#include + +/* + * Suppport for atomic_long_t + * + * Casts for parameters are avoided for existing atomic functions in order to + * avoid issues with cast-as-lval under gcc 4.x and other limitations that the + * macros of a platform may have. + */ + +#if BITS_PER_LONG == 64 + +typedef atomic64_t atomic_long_t; + +#define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i) + +static inline long atomic_long_read(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_read(v); +} + +static inline void atomic_long_set(atomic_long_t *l, long i) +{ + atomic64_t *v = (atomic64_t *)l; + + atomic64_set(v, i); +} + +static inline void atomic_long_inc(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + atomic64_inc(v); +} + +static inline void atomic_long_dec(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + atomic64_dec(v); +} + +static inline void atomic_long_add(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + atomic64_add(i, v); +} + +static inline void atomic_long_sub(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + atomic64_sub(i, v); +} + +static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return atomic64_sub_and_test(i, v); +} + +static inline int atomic_long_dec_and_test(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return atomic64_dec_and_test(v); +} + +static inline int atomic_long_inc_and_test(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return atomic64_inc_and_test(v); +} + +static inline int atomic_long_add_negative(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return atomic64_add_negative(i, v); +} + +static inline long atomic_long_add_return(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_add_return(i, v); +} + +static inline long atomic_long_sub_return(long i, atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_sub_return(i, v); +} + +static inline long atomic_long_inc_return(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_inc_return(v); +} + +static inline long atomic_long_dec_return(atomic_long_t *l) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_dec_return(v); +} + +static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) +{ + atomic64_t *v = (atomic64_t *)l; + + return (long)atomic64_add_unless(v, a, u); +} + +#define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l)) + +#define atomic_long_cmpxchg(l, old, new) \ + (atomic64_cmpxchg((atomic64_t *)(l), (old), (new))) +#define atomic_long_xchg(v, new) \ + (atomic64_xchg((atomic64_t *)(v), (new))) + +#else /* BITS_PER_LONG == 64 */ + +typedef atomic_t atomic_long_t; + +#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i) +static inline long atomic_long_read(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_read(v); +} + +static inline void atomic_long_set(atomic_long_t *l, long i) +{ + atomic_t *v = (atomic_t *)l; + + atomic_set(v, i); +} + +static inline void atomic_long_inc(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_inc(v); +} + +static inline void atomic_long_dec(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_dec(v); +} + +static inline void atomic_long_add(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_add(i, v); +} + +static inline void atomic_long_sub(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + atomic_sub(i, v); +} + +#ifndef __UBOOT__ +static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return atomic_sub_and_test(i, v); +} + +static inline int atomic_long_dec_and_test(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return atomic_dec_and_test(v); +} + +static inline int atomic_long_inc_and_test(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return atomic_inc_and_test(v); +} + +static inline int atomic_long_add_negative(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return atomic_add_negative(i, v); +} + +static inline long atomic_long_add_return(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_add_return(i, v); +} + +static inline long atomic_long_sub_return(long i, atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_sub_return(i, v); +} + +static inline long atomic_long_inc_return(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_inc_return(v); +} + +static inline long atomic_long_dec_return(atomic_long_t *l) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_dec_return(v); +} + +static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) +{ + atomic_t *v = (atomic_t *)l; + + return (long)atomic_add_unless(v, a, u); +} + +#define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l)) + +#define atomic_long_cmpxchg(l, old, new) \ + (atomic_cmpxchg((atomic_t *)(l), (old), (new))) +#define atomic_long_xchg(v, new) \ + (atomic_xchg((atomic_t *)(v), (new))) +#endif /* __UBOOT__ */ + +#endif /* BITS_PER_LONG == 64 */ + +#endif /* _ASM_GENERIC_ATOMIC_LONG_H */ diff --git a/include/linux/compat.h b/include/linux/compat.h index b40133cb3c..6eac17f0b6 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -262,7 +262,6 @@ typedef struct { /* from include/linux/types.h */ -typedef int atomic_t; /** * struct callback_head - callback structure for use with RCU and task_work * @next: next update requests in a list -- cgit From 040cc7b3beedecd971274a065564e39aac7fc76e Mon Sep 17 00:00:00 2001 From: Anton Habegger Date: Thu, 22 Jan 2015 22:29:11 +0100 Subject: ubifs: Enable journal replay during mount Enable ubifs_replay_journal during mount_ubifs, which was disabled before. This commit fix an issue with unrecoverable ubifs volumes after power cut. Therefor the gc.c is imported now from 1860e37 Linux 3.15 hs: added SPDX-License-Identifier for fs/ubifs/gc.c Signed-off-by: Anton Habegger --- fs/ubifs/Makefile | 2 +- fs/ubifs/gc.c | 976 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ubifs/replay.c | 4 - fs/ubifs/super.c | 8 +- fs/ubifs/tnc.c | 2 - 5 files changed, 978 insertions(+), 14 deletions(-) create mode 100644 fs/ubifs/gc.c diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile index 8c8c6ac683..5efb349d07 100644 --- a/fs/ubifs/Makefile +++ b/fs/ubifs/Makefile @@ -12,4 +12,4 @@ obj-y := ubifs.o io.o super.o sb.o master.o lpt.o obj-y += lpt_commit.o scan.o lprops.o obj-y += tnc.o tnc_misc.o debug.o crc16.o budget.o -obj-y += log.o orphan.o recovery.o replay.o +obj-y += log.o orphan.o recovery.o replay.o gc.o diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c new file mode 100644 index 0000000000..c6657a2711 --- /dev/null +++ b/fs/ubifs/gc.c @@ -0,0 +1,976 @@ +/* + * This file is part of UBIFS. + * + * Copyright (C) 2006-2008 Nokia Corporation. + * + * SPDX-License-Identifier: GPL-2.0 + * + * Authors: Adrian Hunter + * Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file implements garbage collection. The procedure for garbage collection + * is different depending on whether a LEB as an index LEB (contains index + * nodes) or not. For non-index LEBs, garbage collection finds a LEB which + * contains a lot of dirty space (obsolete nodes), and copies the non-obsolete + * nodes to the journal, at which point the garbage-collected LEB is free to be + * reused. For index LEBs, garbage collection marks the non-obsolete index nodes + * dirty in the TNC, and after the next commit, the garbage-collected LEB is + * to be reused. Garbage collection will cause the number of dirty index nodes + * to grow, however sufficient space is reserved for the index to ensure the + * commit will never run out of space. + * + * Notes about dead watermark. At current UBIFS implementation we assume that + * LEBs which have less than @c->dead_wm bytes of free + dirty space are full + * and not worth garbage-collecting. The dead watermark is one min. I/O unit + * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS + * Garbage Collector has to synchronize the GC head's write buffer before + * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can + * actually reclaim even very small pieces of dirty space by garbage collecting + * enough dirty LEBs, but we do not bother doing this at this implementation. + * + * Notes about dark watermark. The results of GC work depends on how big are + * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed, + * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would + * have to waste large pieces of free space at the end of LEB B, because nodes + * from LEB A would not fit. And the worst situation is when all nodes are of + * maximum size. So dark watermark is the amount of free + dirty space in LEB + * which are guaranteed to be reclaimable. If LEB has less space, the GC might + * be unable to reclaim it. So, LEBs with free + dirty greater than dark + * watermark are "good" LEBs from GC's point of few. The other LEBs are not so + * good, and GC takes extra care when moving them. + */ +#ifndef __UBOOT__ +#include +#include +#include +#endif +#include "ubifs.h" + +#ifndef __UBOOT__ +/* + * GC may need to move more than one LEB to make progress. The below constants + * define "soft" and "hard" limits on the number of LEBs the garbage collector + * may move. + */ +#define SOFT_LEBS_LIMIT 4 +#define HARD_LEBS_LIMIT 32 + +/** + * switch_gc_head - switch the garbage collection journal head. + * @c: UBIFS file-system description object + * @buf: buffer to write + * @len: length of the buffer to write + * @lnum: LEB number written is returned here + * @offs: offset written is returned here + * + * This function switch the GC head to the next LEB which is reserved in + * @c->gc_lnum. Returns %0 in case of success, %-EAGAIN if commit is required, + * and other negative error code in case of failures. + */ +static int switch_gc_head(struct ubifs_info *c) +{ + int err, gc_lnum = c->gc_lnum; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + + ubifs_assert(gc_lnum != -1); + dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)", + wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum, + c->leb_size - wbuf->offs - wbuf->used); + + err = ubifs_wbuf_sync_nolock(wbuf); + if (err) + return err; + + /* + * The GC write-buffer was synchronized, we may safely unmap + * 'c->gc_lnum'. + */ + err = ubifs_leb_unmap(c, gc_lnum); + if (err) + return err; + + err = ubifs_wbuf_sync_nolock(wbuf); + if (err) + return err; + + err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0); + if (err) + return err; + + c->gc_lnum = -1; + err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0); + return err; +} + +/** + * data_nodes_cmp - compare 2 data nodes. + * @priv: UBIFS file-system description object + * @a: first data node + * @a: second data node + * + * This function compares data nodes @a and @b. Returns %1 if @a has greater + * inode or block number, and %-1 otherwise. + */ +static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + ino_t inuma, inumb; + struct ubifs_info *c = priv; + struct ubifs_scan_node *sa, *sb; + + cond_resched(); + if (a == b) + return 0; + + sa = list_entry(a, struct ubifs_scan_node, list); + sb = list_entry(b, struct ubifs_scan_node, list); + + ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY); + ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY); + ubifs_assert(sa->type == UBIFS_DATA_NODE); + ubifs_assert(sb->type == UBIFS_DATA_NODE); + + inuma = key_inum(c, &sa->key); + inumb = key_inum(c, &sb->key); + + if (inuma == inumb) { + unsigned int blka = key_block(c, &sa->key); + unsigned int blkb = key_block(c, &sb->key); + + if (blka <= blkb) + return -1; + } else if (inuma <= inumb) + return -1; + + return 1; +} + +/* + * nondata_nodes_cmp - compare 2 non-data nodes. + * @priv: UBIFS file-system description object + * @a: first node + * @a: second node + * + * This function compares nodes @a and @b. It makes sure that inode nodes go + * first and sorted by length in descending order. Directory entry nodes go + * after inode nodes and are sorted in ascending hash valuer order. + */ +static int nondata_nodes_cmp(void *priv, struct list_head *a, + struct list_head *b) +{ + ino_t inuma, inumb; + struct ubifs_info *c = priv; + struct ubifs_scan_node *sa, *sb; + + cond_resched(); + if (a == b) + return 0; + + sa = list_entry(a, struct ubifs_scan_node, list); + sb = list_entry(b, struct ubifs_scan_node, list); + + ubifs_assert(key_type(c, &sa->key) != UBIFS_DATA_KEY && + key_type(c, &sb->key) != UBIFS_DATA_KEY); + ubifs_assert(sa->type != UBIFS_DATA_NODE && + sb->type != UBIFS_DATA_NODE); + + /* Inodes go before directory entries */ + if (sa->type == UBIFS_INO_NODE) { + if (sb->type == UBIFS_INO_NODE) + return sb->len - sa->len; + return -1; + } + if (sb->type == UBIFS_INO_NODE) + return 1; + + ubifs_assert(key_type(c, &sa->key) == UBIFS_DENT_KEY || + key_type(c, &sa->key) == UBIFS_XENT_KEY); + ubifs_assert(key_type(c, &sb->key) == UBIFS_DENT_KEY || + key_type(c, &sb->key) == UBIFS_XENT_KEY); + ubifs_assert(sa->type == UBIFS_DENT_NODE || + sa->type == UBIFS_XENT_NODE); + ubifs_assert(sb->type == UBIFS_DENT_NODE || + sb->type == UBIFS_XENT_NODE); + + inuma = key_inum(c, &sa->key); + inumb = key_inum(c, &sb->key); + + if (inuma == inumb) { + uint32_t hasha = key_hash(c, &sa->key); + uint32_t hashb = key_hash(c, &sb->key); + + if (hasha <= hashb) + return -1; + } else if (inuma <= inumb) + return -1; + + return 1; +} + +/** + * sort_nodes - sort nodes for GC. + * @c: UBIFS file-system description object + * @sleb: describes nodes to sort and contains the result on exit + * @nondata: contains non-data nodes on exit + * @min: minimum node size is returned here + * + * This function sorts the list of inodes to garbage collect. First of all, it + * kills obsolete nodes and separates data and non-data nodes to the + * @sleb->nodes and @nondata lists correspondingly. + * + * Data nodes are then sorted in block number order - this is important for + * bulk-read; data nodes with lower inode number go before data nodes with + * higher inode number, and data nodes with lower block number go before data + * nodes with higher block number; + * + * Non-data nodes are sorted as follows. + * o First go inode nodes - they are sorted in descending length order. + * o Then go directory entry nodes - they are sorted in hash order, which + * should supposedly optimize 'readdir()'. Direntry nodes with lower parent + * inode number go before direntry nodes with higher parent inode number, + * and direntry nodes with lower name hash values go before direntry nodes + * with higher name hash values. + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb, + struct list_head *nondata, int *min) +{ + int err; + struct ubifs_scan_node *snod, *tmp; + + *min = INT_MAX; + + /* Separate data nodes and non-data nodes */ + list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { + ubifs_assert(snod->type == UBIFS_INO_NODE || + snod->type == UBIFS_DATA_NODE || + snod->type == UBIFS_DENT_NODE || + snod->type == UBIFS_XENT_NODE || + snod->type == UBIFS_TRUN_NODE); + + if (snod->type != UBIFS_INO_NODE && + snod->type != UBIFS_DATA_NODE && + snod->type != UBIFS_DENT_NODE && + snod->type != UBIFS_XENT_NODE) { + /* Probably truncation node, zap it */ + list_del(&snod->list); + kfree(snod); + continue; + } + + ubifs_assert(key_type(c, &snod->key) == UBIFS_DATA_KEY || + key_type(c, &snod->key) == UBIFS_INO_KEY || + key_type(c, &snod->key) == UBIFS_DENT_KEY || + key_type(c, &snod->key) == UBIFS_XENT_KEY); + + err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum, + snod->offs, 0); + if (err < 0) + return err; + + if (!err) { + /* The node is obsolete, remove it from the list */ + list_del(&snod->list); + kfree(snod); + continue; + } + + if (snod->len < *min) + *min = snod->len; + + if (key_type(c, &snod->key) != UBIFS_DATA_KEY) + list_move_tail(&snod->list, nondata); + } + + /* Sort data and non-data nodes */ + list_sort(c, &sleb->nodes, &data_nodes_cmp); + list_sort(c, nondata, &nondata_nodes_cmp); + + err = dbg_check_data_nodes_order(c, &sleb->nodes); + if (err) + return err; + err = dbg_check_nondata_nodes_order(c, nondata); + if (err) + return err; + return 0; +} + +/** + * move_node - move a node. + * @c: UBIFS file-system description object + * @sleb: describes the LEB to move nodes from + * @snod: the mode to move + * @wbuf: write-buffer to move node to + * + * This function moves node @snod to @wbuf, changes TNC correspondingly, and + * destroys @snod. Returns zero in case of success and a negative error code in + * case of failure. + */ +static int move_node(struct ubifs_info *c, struct ubifs_scan_leb *sleb, + struct ubifs_scan_node *snod, struct ubifs_wbuf *wbuf) +{ + int err, new_lnum = wbuf->lnum, new_offs = wbuf->offs + wbuf->used; + + cond_resched(); + err = ubifs_wbuf_write_nolock(wbuf, snod->node, snod->len); + if (err) + return err; + + err = ubifs_tnc_replace(c, &snod->key, sleb->lnum, + snod->offs, new_lnum, new_offs, + snod->len); + list_del(&snod->list); + kfree(snod); + return err; +} + +/** + * move_nodes - move nodes. + * @c: UBIFS file-system description object + * @sleb: describes the LEB to move nodes from + * + * This function moves valid nodes from data LEB described by @sleb to the GC + * journal head. This function returns zero in case of success, %-EAGAIN if + * commit is required, and other negative error codes in case of other + * failures. + */ +static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) +{ + int err, min; + LIST_HEAD(nondata); + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + + if (wbuf->lnum == -1) { + /* + * The GC journal head is not set, because it is the first GC + * invocation since mount. + */ + err = switch_gc_head(c); + if (err) + return err; + } + + err = sort_nodes(c, sleb, &nondata, &min); + if (err) + goto out; + + /* Write nodes to their new location. Use the first-fit strategy */ + while (1) { + int avail; + struct ubifs_scan_node *snod, *tmp; + + /* Move data nodes */ + list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { + avail = c->leb_size - wbuf->offs - wbuf->used; + if (snod->len > avail) + /* + * Do not skip data nodes in order to optimize + * bulk-read. + */ + break; + + err = move_node(c, sleb, snod, wbuf); + if (err) + goto out; + } + + /* Move non-data nodes */ + list_for_each_entry_safe(snod, tmp, &nondata, list) { + avail = c->leb_size - wbuf->offs - wbuf->used; + if (avail < min) + break; + + if (snod->len > avail) { + /* + * Keep going only if this is an inode with + * some data. Otherwise stop and switch the GC + * head. IOW, we assume that data-less inode + * nodes and direntry nodes are roughly of the + * same size. + */ + if (key_type(c, &snod->key) == UBIFS_DENT_KEY || + snod->len == UBIFS_INO_NODE_SZ) + break; + continue; + } + + err = move_node(c, sleb, snod, wbuf); + if (err) + goto out; + } + + if (list_empty(&sleb->nodes) && list_empty(&nondata)) + break; + + /* + * Waste the rest of the space in the LEB and switch to the + * next LEB. + */ + err = switch_gc_head(c); + if (err) + goto out; + } + + return 0; + +out: + list_splice_tail(&nondata, &sleb->nodes); + return err; +} + +/** + * gc_sync_wbufs - sync write-buffers for GC. + * @c: UBIFS file-system description object + * + * We must guarantee that obsoleting nodes are on flash. Unfortunately they may + * be in a write-buffer instead. That is, a node could be written to a + * write-buffer, obsoleting another node in a LEB that is GC'd. If that LEB is + * erased before the write-buffer is sync'd and then there is an unclean + * unmount, then an existing node is lost. To avoid this, we sync all + * write-buffers. + * + * This function returns %0 on success or a negative error code on failure. + */ +static int gc_sync_wbufs(struct ubifs_info *c) +{ + int err, i; + + for (i = 0; i < c->jhead_cnt; i++) { + if (i == GCHD) + continue; + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + return err; + } + return 0; +} + +/** + * ubifs_garbage_collect_leb - garbage-collect a logical eraseblock. + * @c: UBIFS file-system description object + * @lp: describes the LEB to garbage collect + * + * This function garbage-collects an LEB and returns one of the @LEB_FREED, + * @LEB_RETAINED, etc positive codes in case of success, %-EAGAIN if commit is + * required, and other negative error codes in case of failures. + */ +int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) +{ + struct ubifs_scan_leb *sleb; + struct ubifs_scan_node *snod; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + int err = 0, lnum = lp->lnum; + + ubifs_assert(c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 || + c->need_recovery); + ubifs_assert(c->gc_lnum != lnum); + ubifs_assert(wbuf->lnum != lnum); + + if (lp->free + lp->dirty == c->leb_size) { + /* Special case - a free LEB */ + dbg_gc("LEB %d is free, return it", lp->lnum); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + + if (lp->free != c->leb_size) { + /* + * Write buffers must be sync'd before unmapping + * freeable LEBs, because one of them may contain data + * which obsoletes something in 'lp->pnum'. + */ + err = gc_sync_wbufs(c); + if (err) + return err; + err = ubifs_change_one_lp(c, lp->lnum, c->leb_size, + 0, 0, 0, 0); + if (err) + return err; + } + err = ubifs_leb_unmap(c, lp->lnum); + if (err) + return err; + + if (c->gc_lnum == -1) { + c->gc_lnum = lnum; + return LEB_RETAINED; + } + + return LEB_FREED; + } + + /* + * We scan the entire LEB even though we only really need to scan up to + * (c->leb_size - lp->free). + */ + sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0); + if (IS_ERR(sleb)) + return PTR_ERR(sleb); + + ubifs_assert(!list_empty(&sleb->nodes)); + snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); + + if (snod->type == UBIFS_IDX_NODE) { + struct ubifs_gced_idx_leb *idx_gc; + + dbg_gc("indexing LEB %d (free %d, dirty %d)", + lnum, lp->free, lp->dirty); + list_for_each_entry(snod, &sleb->nodes, list) { + struct ubifs_idx_node *idx = snod->node; + int level = le16_to_cpu(idx->level); + + ubifs_assert(snod->type == UBIFS_IDX_NODE); + key_read(c, ubifs_idx_key(c, idx), &snod->key); + err = ubifs_dirty_idx_node(c, &snod->key, level, lnum, + snod->offs); + if (err) + goto out; + } + + idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + if (!idx_gc) { + err = -ENOMEM; + goto out; + } + + idx_gc->lnum = lnum; + idx_gc->unmap = 0; + list_add(&idx_gc->list, &c->idx_gc); + + /* + * Don't release the LEB until after the next commit, because + * it may contain data which is needed for recovery. So + * although we freed this LEB, it will become usable only after + * the commit. + */ + err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, + LPROPS_INDEX, 1); + if (err) + goto out; + err = LEB_FREED_IDX; + } else { + dbg_gc("data LEB %d (free %d, dirty %d)", + lnum, lp->free, lp->dirty); + + err = move_nodes(c, sleb); + if (err) + goto out_inc_seq; + + err = gc_sync_wbufs(c); + if (err) + goto out_inc_seq; + + err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0); + if (err) + goto out_inc_seq; + + /* Allow for races with TNC */ + c->gced_lnum = lnum; + smp_wmb(); + c->gc_seq += 1; + smp_wmb(); + + if (c->gc_lnum == -1) { + c->gc_lnum = lnum; + err = LEB_RETAINED; + } else { + err = ubifs_wbuf_sync_nolock(wbuf); + if (err) + goto out; + + err = ubifs_leb_unmap(c, lnum); + if (err) + goto out; + + err = LEB_FREED; + } + } + +out: + ubifs_scan_destroy(sleb); + return err; + +out_inc_seq: + /* We may have moved at least some nodes so allow for races with TNC */ + c->gced_lnum = lnum; + smp_wmb(); + c->gc_seq += 1; + smp_wmb(); + goto out; +} + +/** + * ubifs_garbage_collect - UBIFS garbage collector. + * @c: UBIFS file-system description object + * @anyway: do GC even if there are free LEBs + * + * This function does out-of-place garbage collection. The return codes are: + * o positive LEB number if the LEB has been freed and may be used; + * o %-EAGAIN if the caller has to run commit; + * o %-ENOSPC if GC failed to make any progress; + * o other negative error codes in case of other errors. + * + * Garbage collector writes data to the journal when GC'ing data LEBs, and just + * marking indexing nodes dirty when GC'ing indexing LEBs. Thus, at some point + * commit may be required. But commit cannot be run from inside GC, because the + * caller might be holding the commit lock, so %-EAGAIN is returned instead; + * And this error code means that the caller has to run commit, and re-run GC + * if there is still no free space. + * + * There are many reasons why this function may return %-EAGAIN: + * o the log is full and there is no space to write an LEB reference for + * @c->gc_lnum; + * o the journal is too large and exceeds size limitations; + * o GC moved indexing LEBs, but they can be used only after the commit; + * o the shrinker fails to find clean znodes to free and requests the commit; + * o etc. + * + * Note, if the file-system is close to be full, this function may return + * %-EAGAIN infinitely, so the caller has to limit amount of re-invocations of + * the function. E.g., this happens if the limits on the journal size are too + * tough and GC writes too much to the journal before an LEB is freed. This + * might also mean that the journal is too large, and the TNC becomes to big, + * so that the shrinker is constantly called, finds not clean znodes to free, + * and requests commit. Well, this may also happen if the journal is all right, + * but another kernel process consumes too much memory. Anyway, infinite + * %-EAGAIN may happen, but in some extreme/misconfiguration cases. + */ +int ubifs_garbage_collect(struct ubifs_info *c, int anyway) +{ + int i, err, ret, min_space = c->dead_wm; + struct ubifs_lprops lp; + struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; + + ubifs_assert_cmt_locked(c); + ubifs_assert(!c->ro_media && !c->ro_mount); + + if (ubifs_gc_should_commit(c)) + return -EAGAIN; + + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + + if (c->ro_error) { + ret = -EROFS; + goto out_unlock; + } + + /* We expect the write-buffer to be empty on entry */ + ubifs_assert(!wbuf->used); + + for (i = 0; ; i++) { + int space_before, space_after; + + cond_resched(); + + /* Give the commit an opportunity to run */ + if (ubifs_gc_should_commit(c)) { + ret = -EAGAIN; + break; + } + + if (i > SOFT_LEBS_LIMIT && !list_empty(&c->idx_gc)) { + /* + * We've done enough iterations. Indexing LEBs were + * moved and will be available after the commit. + */ + dbg_gc("soft limit, some index LEBs GC'ed, -EAGAIN"); + ubifs_commit_required(c); + ret = -EAGAIN; + break; + } + + if (i > HARD_LEBS_LIMIT) { + /* + * We've moved too many LEBs and have not made + * progress, give up. + */ + dbg_gc("hard limit, -ENOSPC"); + ret = -ENOSPC; + break; + } + + /* + * Empty and freeable LEBs can turn up while we waited for + * the wbuf lock, or while we have been running GC. In that + * case, we should just return one of those instead of + * continuing to GC dirty LEBs. Hence we request + * 'ubifs_find_dirty_leb()' to return an empty LEB if it can. + */ + ret = ubifs_find_dirty_leb(c, &lp, min_space, anyway ? 0 : 1); + if (ret) { + if (ret == -ENOSPC) + dbg_gc("no more dirty LEBs"); + break; + } + + dbg_gc("found LEB %d: free %d, dirty %d, sum %d (min. space %d)", + lp.lnum, lp.free, lp.dirty, lp.free + lp.dirty, + min_space); + + space_before = c->leb_size - wbuf->offs - wbuf->used; + if (wbuf->lnum == -1) + space_before = 0; + + ret = ubifs_garbage_collect_leb(c, &lp); + if (ret < 0) { + if (ret == -EAGAIN) { + /* + * This is not error, so we have to return the + * LEB to lprops. But if 'ubifs_return_leb()' + * fails, its failure code is propagated to the + * caller instead of the original '-EAGAIN'. + */ + err = ubifs_return_leb(c, lp.lnum); + if (err) + ret = err; + break; + } + goto out; + } + + if (ret == LEB_FREED) { + /* An LEB has been freed and is ready for use */ + dbg_gc("LEB %d freed, return", lp.lnum); + ret = lp.lnum; + break; + } + + if (ret == LEB_FREED_IDX) { + /* + * This was an indexing LEB and it cannot be + * immediately used. And instead of requesting the + * commit straight away, we try to garbage collect some + * more. + */ + dbg_gc("indexing LEB %d freed, continue", lp.lnum); + continue; + } + + ubifs_assert(ret == LEB_RETAINED); + space_after = c->leb_size - wbuf->offs - wbuf->used; + dbg_gc("LEB %d retained, freed %d bytes", lp.lnum, + space_after - space_before); + + if (space_after > space_before) { + /* GC makes progress, keep working */ + min_space >>= 1; + if (min_space < c->dead_wm) + min_space = c->dead_wm; + continue; + } + + dbg_gc("did not make progress"); + + /* + * GC moved an LEB bud have not done any progress. This means + * that the previous GC head LEB contained too few free space + * and the LEB which was GC'ed contained only large nodes which + * did not fit that space. + * + * We can do 2 things: + * 1. pick another LEB in a hope it'll contain a small node + * which will fit the space we have at the end of current GC + * head LEB, but there is no guarantee, so we try this out + * unless we have already been working for too long; + * 2. request an LEB with more dirty space, which will force + * 'ubifs_find_dirty_leb()' to start scanning the lprops + * table, instead of just picking one from the heap + * (previously it already picked the dirtiest LEB). + */ + if (i < SOFT_LEBS_LIMIT) { + dbg_gc("try again"); + continue; + } + + min_space <<= 1; + if (min_space > c->dark_wm) + min_space = c->dark_wm; + dbg_gc("set min. space to %d", min_space); + } + + if (ret == -ENOSPC && !list_empty(&c->idx_gc)) { + dbg_gc("no space, some index LEBs GC'ed, -EAGAIN"); + ubifs_commit_required(c); + ret = -EAGAIN; + } + + err = ubifs_wbuf_sync_nolock(wbuf); + if (!err) + err = ubifs_leb_unmap(c, c->gc_lnum); + if (err) { + ret = err; + goto out; + } +out_unlock: + mutex_unlock(&wbuf->io_mutex); + return ret; + +out: + ubifs_assert(ret < 0); + ubifs_assert(ret != -ENOSPC && ret != -EAGAIN); + ubifs_wbuf_sync_nolock(wbuf); + ubifs_ro_mode(c, ret); + mutex_unlock(&wbuf->io_mutex); + ubifs_return_leb(c, lp.lnum); + return ret; +} + +/** + * ubifs_gc_start_commit - garbage collection at start of commit. + * @c: UBIFS file-system description object + * + * If a LEB has only dirty and free space, then we may safely unmap it and make + * it free. Note, we cannot do this with indexing LEBs because dirty space may + * correspond index nodes that are required for recovery. In that case, the + * LEB cannot be unmapped until after the next commit. + * + * This function returns %0 upon success and a negative error code upon failure. + */ +int ubifs_gc_start_commit(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc; + const struct ubifs_lprops *lp; + int err = 0, flags; + + ubifs_get_lprops(c); + + /* + * Unmap (non-index) freeable LEBs. Note that recovery requires that all + * wbufs are sync'd before this, which is done in 'do_commit()'. + */ + while (1) { + lp = ubifs_fast_find_freeable(c); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + if (!lp) + break; + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + err = ubifs_leb_unmap(c, lp->lnum); + if (err) + goto out; + lp = ubifs_change_lp(c, lp, c->leb_size, 0, lp->flags, 0); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + } + + /* Mark GC'd index LEBs OK to unmap after this commit finishes */ + list_for_each_entry(idx_gc, &c->idx_gc, list) + idx_gc->unmap = 1; + + /* Record index freeable LEBs for unmapping after commit */ + while (1) { + lp = ubifs_fast_find_frdi_idx(c); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + goto out; + } + if (!lp) + break; + idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + if (!idx_gc) { + err = -ENOMEM; + goto out; + } + ubifs_assert(!(lp->flags & LPROPS_TAKEN)); + ubifs_assert(lp->flags & LPROPS_INDEX); + /* Don't release the LEB until after the next commit */ + flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX; + lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1); + if (IS_ERR(lp)) { + err = PTR_ERR(lp); + kfree(idx_gc); + goto out; + } + ubifs_assert(lp->flags & LPROPS_TAKEN); + ubifs_assert(!(lp->flags & LPROPS_INDEX)); + idx_gc->lnum = lp->lnum; + idx_gc->unmap = 1; + list_add(&idx_gc->list, &c->idx_gc); + } +out: + ubifs_release_lprops(c); + return err; +} + +/** + * ubifs_gc_end_commit - garbage collection at end of commit. + * @c: UBIFS file-system description object + * + * This function completes out-of-place garbage collection of index LEBs. + */ +int ubifs_gc_end_commit(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc, *tmp; + struct ubifs_wbuf *wbuf; + int err = 0; + + wbuf = &c->jheads[GCHD].wbuf; + mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); + list_for_each_entry_safe(idx_gc, tmp, &c->idx_gc, list) + if (idx_gc->unmap) { + dbg_gc("LEB %d", idx_gc->lnum); + err = ubifs_leb_unmap(c, idx_gc->lnum); + if (err) + goto out; + err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC, + LPROPS_NC, 0, LPROPS_TAKEN, -1); + if (err) + goto out; + list_del(&idx_gc->list); + kfree(idx_gc); + } +out: + mutex_unlock(&wbuf->io_mutex); + return err; +} +#endif +/** + * ubifs_destroy_idx_gc - destroy idx_gc list. + * @c: UBIFS file-system description object + * + * This function destroys the @c->idx_gc list. It is called when unmounting + * so locks are not needed. Returns zero in case of success and a negative + * error code in case of failure. + */ +void ubifs_destroy_idx_gc(struct ubifs_info *c) +{ + while (!list_empty(&c->idx_gc)) { + struct ubifs_gced_idx_leb *idx_gc; + + idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, + list); + c->idx_gc_cnt -= 1; + list_del(&idx_gc->list); + kfree(idx_gc); + } +} +#ifndef __UBOOT__ +/** + * ubifs_get_idx_gc_leb - get a LEB from GC'd index LEB list. + * @c: UBIFS file-system description object + * + * Called during start commit so locks are not needed. + */ +int ubifs_get_idx_gc_leb(struct ubifs_info *c) +{ + struct ubifs_gced_idx_leb *idx_gc; + int lnum; + + if (list_empty(&c->idx_gc)) + return -ENOSPC; + idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, list); + lnum = idx_gc->lnum; + /* c->idx_gc_cnt is updated by the caller when lprops are updated */ + list_del(&idx_gc->list); + kfree(idx_gc); + return lnum; +} +#endif diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 7268b37a49..1064cb29ba 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -78,7 +78,6 @@ struct bud_entry { int dirty; }; -#ifndef __UBOOT__ /** * set_bud_lprops - set free and dirty space used by a bud. * @c: UBIFS file-system description object @@ -432,7 +431,6 @@ static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, list_add_tail(&r->list, &c->replay_list); return 0; } -#endif /** * ubifs_validate_entry - validate directory or extended attribute entry node. @@ -466,7 +464,6 @@ int ubifs_validate_entry(struct ubifs_info *c, return 0; } -#ifndef __UBOOT__ /** * is_last_bud - check if the bud is the last in the journal head. * @c: UBIFS file-system description object @@ -1063,4 +1060,3 @@ out: c->replaying = 0; return err; } -#endif diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 01d449a7af..10f8fff0be 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1049,7 +1049,6 @@ static void free_orphans(struct ubifs_info *c) c->orph_buf = NULL; } -#ifndef __UBOOT__ /** * free_buds - free per-bud objects. * @c: UBIFS file-system description object @@ -1061,7 +1060,6 @@ static void free_buds(struct ubifs_info *c) rbtree_postorder_for_each_entry_safe(bud, n, &c->buds, rb) kfree(bud); } -#endif /** * check_volume_empty - check if the UBI volume is empty. @@ -1242,6 +1240,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, return 0; } +#endif /** * destroy_journal - destroy journal data structures. @@ -1272,7 +1271,6 @@ static void destroy_journal(struct ubifs_info *c) ubifs_tnc_close(c); free_buds(c); } -#endif /** * bu_init - initialize bulk-read information. @@ -1502,11 +1500,9 @@ static int mount_ubifs(struct ubifs_info *c) if (err) goto out_lpt; -#ifndef __UBOOT__ err = ubifs_replay_journal(c); if (err) goto out_journal; -#endif /* Calculate 'min_idx_lebs' after journal replay */ c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c); @@ -1678,10 +1674,8 @@ out_infos: spin_unlock(&ubifs_infos_lock); out_orphans: free_orphans(c); -#ifndef __UBOOT__ out_journal: destroy_journal(c); -#endif out_lpt: ubifs_lpt_free(c, 0); out_master: diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 95cae548bf..e20cedda57 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -2827,7 +2827,6 @@ out_unlock: return ERR_PTR(err); } -#ifndef __UBOOT__ /** * tnc_destroy_cnext - destroy left-over obsolete znodes from a failed commit. * @c: UBIFS file-system description object @@ -2869,7 +2868,6 @@ void ubifs_tnc_close(struct ubifs_info *c) kfree(c->ilebs); destroy_old_idx(c); } -#endif /** * left_znode - get the znode to the left. -- cgit From 2b8bcc5a2fca54648ece966902b8230de971b609 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:27:56 +0000 Subject: MIPS: avoid .set ISA for cache operations As a step towards unifying the cache maintenance code for mips32 & mips64 CPUs, stop using ".set " directives in the more developed mips32 version of the code. Instead, when present make use of the GCC builtin for emitting a cache instruction. When not present, simply don't bother with the .set directives since U-boot always builds with -march=mips32 or higher anyway. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/cache.S | 18 +++++------------- arch/mips/cpu/mips32/cpu.c | 40 +++++++++++++++------------------------- arch/mips/include/asm/cacheops.h | 13 +++++++++++++ 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S index 22bd844eae..fb1d84b75a 100644 --- a/arch/mips/cpu/mips32/cache.S +++ b/arch/mips/cpu/mips32/cache.S @@ -22,14 +22,6 @@ #define INDEX_BASE CKSEG0 - .macro cache_op op addr - .set push - .set noreorder - .set mips3 - cache \op, 0(\addr) - .set pop - .endm - .macro f_fill64 dst, offset, val LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) @@ -60,17 +52,17 @@ LEAF(mips_init_icache) /* clear tag to invalidate */ PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, a1 -1: cache_op INDEX_STORE_TAG_I t0 +1: cache INDEX_STORE_TAG_I, 0(t0) PTR_ADDU t0, a2 bne t0, t1, 1b /* fill once, so data field parity is correct */ PTR_LI t0, INDEX_BASE -2: cache_op FILL t0 +2: cache FILL, 0(t0) PTR_ADDU t0, a2 bne t0, t1, 2b /* invalidate again - prudent but not strictly neccessary */ PTR_LI t0, INDEX_BASE -1: cache_op INDEX_STORE_TAG_I t0 +1: cache INDEX_STORE_TAG_I, 0(t0) PTR_ADDU t0, a2 bne t0, t1, 1b 9: jr ra @@ -85,7 +77,7 @@ LEAF(mips_init_dcache) /* clear all tags */ PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, a1 -1: cache_op INDEX_STORE_TAG_D t0 +1: cache INDEX_STORE_TAG_D, 0(t0) PTR_ADDU t0, a2 bne t0, t1, 1b /* load from each line (in cached space) */ @@ -95,7 +87,7 @@ LEAF(mips_init_dcache) bne t0, t1, 2b /* clear all tags */ PTR_LI t0, INDEX_BASE -1: cache_op INDEX_STORE_TAG_D t0 +1: cache INDEX_STORE_TAG_D, 0(t0) PTR_ADDU t0, a2 bne t0, t1, 1b 9: jr ra diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 278865b6ff..1af909a9a5 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -12,16 +12,6 @@ #include #include -#define cache_op(op,addr) \ - __asm__ __volatile__( \ - " .set push \n" \ - " .set noreorder \n" \ - " .set mips3\n\t \n" \ - " cache %0, %1 \n" \ - " .set pop \n" \ - : \ - : "i" (op), "R" (*(unsigned char *)(addr))) - void __attribute__((weak)) _machine_restart(void) { } @@ -74,20 +64,20 @@ void flush_cache(ulong start_addr, ulong size) { unsigned long ilsize = icache_line_size(); unsigned long dlsize = dcache_line_size(); - unsigned long addr, aend; + const void *addr, *aend; /* aend will be miscalculated when size is zero, so we return here */ if (size == 0) return; - addr = start_addr & ~(dlsize - 1); - aend = (start_addr + size - 1) & ~(dlsize - 1); + addr = (const void *)(start_addr & ~(dlsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); if (ilsize == dlsize) { /* flush I-cache & D-cache simultaneously */ while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); - cache_op(HIT_INVALIDATE_I, addr); + mips_cache(HIT_WRITEBACK_INV_D, addr); + mips_cache(HIT_INVALIDATE_I, addr); if (addr == aend) break; addr += dlsize; @@ -97,17 +87,17 @@ void flush_cache(ulong start_addr, ulong size) /* flush D-cache */ while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); + mips_cache(HIT_WRITEBACK_INV_D, addr); if (addr == aend) break; addr += dlsize; } /* flush I-cache */ - addr = start_addr & ~(ilsize - 1); - aend = (start_addr + size - 1) & ~(ilsize - 1); + addr = (const void *)(start_addr & ~(ilsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); while (1) { - cache_op(HIT_INVALIDATE_I, addr); + mips_cache(HIT_INVALIDATE_I, addr); if (addr == aend) break; addr += ilsize; @@ -117,11 +107,11 @@ void flush_cache(ulong start_addr, ulong size) void flush_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); + mips_cache(HIT_WRITEBACK_INV_D, addr); if (addr == aend) break; addr += lsize; @@ -131,11 +121,11 @@ void flush_dcache_range(ulong start_addr, ulong stop) void invalidate_dcache_range(ulong start_addr, ulong stop) { unsigned long lsize = dcache_line_size(); - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); while (1) { - cache_op(HIT_INVALIDATE_D, addr); + mips_cache(HIT_INVALIDATE_D, addr); if (addr == aend) break; addr += lsize; diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 6464250d84..75ec380980 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -11,6 +11,19 @@ #ifndef __ASM_CACHEOPS_H #define __ASM_CACHEOPS_H +#ifndef __ASSEMBLY__ + +static inline void mips_cache(int op, const volatile void *addr) +{ +#ifdef __GCC_HAVE_BUILTIN_MIPS_CACHE + __builtin_mips_cache(op, addr); +#else + __asm__ __volatile__("cache %0, %1" : : "i"(op), "R"(addr)) +#endif +} + +#endif /* !__ASSEMBLY__ */ + /* * Cache Operations available on all MIPS processors with R4000-style caches */ -- cgit From 30374f98d14d5979f95a9d21d66346eaa9a795a1 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:27:57 +0000 Subject: MIPS: unify cache maintenance functions Move the more developed mips32 version of the cache maintenance functions to a common arch/mips/lib/cache.c, in order to reduce duplication between mips32 & mips64. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/cpu.c | 109 ----------------------------------------- arch/mips/cpu/mips64/cpu.c | 58 ---------------------- arch/mips/lib/Makefile | 1 + arch/mips/lib/cache.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 167 deletions(-) create mode 100644 arch/mips/lib/cache.c diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 1af909a9a5..8e1cc4e1fe 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -9,7 +9,6 @@ #include #include #include -#include #include void __attribute__((weak)) _machine_restart(void) @@ -24,114 +23,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -#ifdef CONFIG_SYS_CACHELINE_SIZE - -static inline unsigned long icache_line_size(void) -{ - return CONFIG_SYS_CACHELINE_SIZE; -} - -static inline unsigned long dcache_line_size(void) -{ - return CONFIG_SYS_CACHELINE_SIZE; -} - -#else /* !CONFIG_SYS_CACHELINE_SIZE */ - -static inline unsigned long icache_line_size(void) -{ - unsigned long conf1, il; - conf1 = read_c0_config1(); - il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; - if (!il) - return 0; - return 2 << il; -} - -static inline unsigned long dcache_line_size(void) -{ - unsigned long conf1, dl; - conf1 = read_c0_config1(); - dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; - if (!dl) - return 0; - return 2 << dl; -} - -#endif /* !CONFIG_SYS_CACHELINE_SIZE */ - -void flush_cache(ulong start_addr, ulong size) -{ - unsigned long ilsize = icache_line_size(); - unsigned long dlsize = dcache_line_size(); - const void *addr, *aend; - - /* aend will be miscalculated when size is zero, so we return here */ - if (size == 0) - return; - - addr = (const void *)(start_addr & ~(dlsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); - - if (ilsize == dlsize) { - /* flush I-cache & D-cache simultaneously */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += dlsize; - } - return; - } - - /* flush D-cache */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += dlsize; - } - - /* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); - while (1) { - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += ilsize; - } -} - -void flush_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); - - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void invalidate_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); - - while (1) { - mips_cache(HIT_INVALIDATE_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) { write_c0_entrylo0(low0); diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c index 9f45cfca5d..1d32705b74 100644 --- a/arch/mips/cpu/mips64/cpu.c +++ b/arch/mips/cpu/mips64/cpu.c @@ -9,19 +9,8 @@ #include #include #include -#include #include -#define cache_op(op, addr) \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noreorder\n" \ - " .set mips64\n" \ - " cache %0, %1\n" \ - " .set pop\n" \ - : \ - : "i" (op), "R" (*(unsigned char *)(addr))) - void __attribute__((weak)) _machine_restart(void) { fprintf(stderr, "*** reset failed ***\n"); @@ -37,53 +26,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -void flush_cache(ulong start_addr, ulong size) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); - - /* aend will be miscalculated when size is zero, so we return here */ - if (size == 0) - return; - - while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); - cache_op(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void flush_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); - - while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void invalidate_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); - - while (1) { - cache_op(HIT_INVALIDATE_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) { write_c0_entrylo0(low0); diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 7f9b6536af..d939ee6a32 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += cache.o obj-y += io.o obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c new file mode 100644 index 0000000000..e245614d16 --- /dev/null +++ b/arch/mips/lib/cache.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#ifdef CONFIG_SYS_CACHELINE_SIZE + +static inline unsigned long icache_line_size(void) +{ + return CONFIG_SYS_CACHELINE_SIZE; +} + +static inline unsigned long dcache_line_size(void) +{ + return CONFIG_SYS_CACHELINE_SIZE; +} + +#else /* !CONFIG_SYS_CACHELINE_SIZE */ + +static inline unsigned long icache_line_size(void) +{ + unsigned long conf1, il; + conf1 = read_c0_config1(); + il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; + if (!il) + return 0; + return 2 << il; +} + +static inline unsigned long dcache_line_size(void) +{ + unsigned long conf1, dl; + conf1 = read_c0_config1(); + dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; + if (!dl) + return 0; + return 2 << dl; +} + +#endif /* !CONFIG_SYS_CACHELINE_SIZE */ + +void flush_cache(ulong start_addr, ulong size) +{ + unsigned long ilsize = icache_line_size(); + unsigned long dlsize = dcache_line_size(); + const void *addr, *aend; + + /* aend will be miscalculated when size is zero, so we return here */ + if (size == 0) + return; + + addr = (const void *)(start_addr & ~(dlsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); + + if (ilsize == dlsize) { + /* flush I-cache & D-cache simultaneously */ + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + mips_cache(HIT_INVALIDATE_I, addr); + if (addr == aend) + break; + addr += dlsize; + } + return; + } + + /* flush D-cache */ + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + if (addr == aend) + break; + addr += dlsize; + } + + /* flush I-cache */ + addr = (const void *)(start_addr & ~(ilsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); + while (1) { + mips_cache(HIT_INVALIDATE_I, addr); + if (addr == aend) + break; + addr += ilsize; + } +} + +void flush_dcache_range(ulong start_addr, ulong stop) +{ + unsigned long lsize = dcache_line_size(); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +void invalidate_dcache_range(ulong start_addr, ulong stop) +{ + unsigned long lsize = dcache_line_size(); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + + while (1) { + mips_cache(HIT_INVALIDATE_D, addr); + if (addr == aend) + break; + addr += lsize; + } +} -- cgit From 4a5d8898bca3e442b61e34b811aec8332752efd3 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:27:58 +0000 Subject: MIPS: unify cache initialization code The mips32 & mips64 cache initialization code differs only in that the mips32 code supports reading the cache size from coprocessor 0 registers at runtime. Move the more developed mips32 version to a common arch/mips/lib/cache_init.S & remove the now-redundant mips64 version in order to reduce duplication. The temporary registers used are shuffled slightly in order to work for both mips32 & mips64 builds. The RA register is defined differently to suit mips32 & mips64, but will be removed by a later commit in the series after further cleanup. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/Makefile | 3 +- arch/mips/cpu/mips32/cache.S | 273 ----------------------------------------- arch/mips/cpu/mips64/Makefile | 2 +- arch/mips/cpu/mips64/cache.S | 213 -------------------------------- arch/mips/lib/Makefile | 1 + arch/mips/lib/cache_init.S | 277 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 280 insertions(+), 489 deletions(-) delete mode 100644 arch/mips/cpu/mips32/cache.S delete mode 100644 arch/mips/cpu/mips64/cache.S create mode 100644 arch/mips/lib/cache_init.S diff --git a/arch/mips/cpu/mips32/Makefile b/arch/mips/cpu/mips32/Makefile index fa82dd375f..19d316ab75 100644 --- a/arch/mips/cpu/mips32/Makefile +++ b/arch/mips/cpu/mips32/Makefile @@ -6,7 +6,6 @@ # extra-y = start.o -obj-y = cache.o -obj-y += cpu.o interrupts.o time.o +obj-y = cpu.o interrupts.o time.o obj-$(CONFIG_SOC_AU1X00) += au1x00/ diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S deleted file mode 100644 index fb1d84b75a..0000000000 --- a/arch/mips/cpu/mips32/cache.S +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Cache-handling routined for MIPS CPUs - * - * Copyright (c) 2003 Wolfgang Denk - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SYS_MIPS_CACHE_MODE -#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT -#endif - -#define RA t9 - -#define INDEX_BASE CKSEG0 - - .macro f_fill64 dst, offset, val - LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) -#if LONGSIZE == 4 - LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) -#endif - .endm - -/* - * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) - */ -LEAF(mips_init_icache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - /* clear tag to invalidate */ - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 -1: cache INDEX_STORE_TAG_I, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b - /* fill once, so data field parity is correct */ - PTR_LI t0, INDEX_BASE -2: cache FILL, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 2b - /* invalidate again - prudent but not strictly neccessary */ - PTR_LI t0, INDEX_BASE -1: cache INDEX_STORE_TAG_I, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b -9: jr ra - END(mips_init_icache) - -/* - * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) - */ -LEAF(mips_init_dcache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - /* clear all tags */ - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 -1: cache INDEX_STORE_TAG_D, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b - /* load from each line (in cached space) */ - PTR_LI t0, INDEX_BASE -2: LONG_L zero, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 2b - /* clear all tags */ - PTR_LI t0, INDEX_BASE -1: cache INDEX_STORE_TAG_D, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b -9: jr ra - END(mips_init_dcache) - -/* - * mips_cache_reset - low level initialisation of the primary caches - * - * This routine initialises the primary caches to ensure that they have good - * parity. It must be called by the ROM before any cached locations are used - * to prevent the possibility of data with bad parity being written to memory. - * - * To initialise the instruction cache it is essential that a source of data - * with good parity is available. This routine will initialise an area of - * memory starting at location zero to be used as a source of parity. - * - * RETURNS: N/A - * - */ -NESTED(mips_cache_reset, 0, ra) - move RA, ra - -#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \ - !defined(CONFIG_SYS_CACHELINE_SIZE) - /* read Config1 for use below */ - mfc0 t5, CP0_CONFIG, 1 -#endif - -#ifdef CONFIG_SYS_CACHELINE_SIZE - li t7, CONFIG_SYS_CACHELINE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE -#else - /* Detect I-cache line size. */ - srl t8, t5, MIPS_CONF1_IL_SHIFT - andi t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT) - beqz t8, 1f - li t6, 2 - sllv t8, t6, t8 - -1: /* Detect D-cache line size. */ - srl t7, t5, MIPS_CONF1_DL_SHIFT - andi t7, t7, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT) - beqz t7, 1f - li t6, 2 - sllv t7, t6, t7 -1: -#endif - -#ifdef CONFIG_SYS_ICACHE_SIZE - li t2, CONFIG_SYS_ICACHE_SIZE -#else - /* Detect I-cache size. */ - srl t6, t5, MIPS_CONF1_IS_SHIFT - andi t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT) - li t4, 32 - xori t2, t6, 0x7 - beqz t2, 1f - addi t6, t6, 1 - sllv t4, t4, t6 -1: /* At this point t4 == I-cache sets. */ - mul t2, t4, t8 - srl t6, t5, MIPS_CONF1_IA_SHIFT - andi t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT) - addi t6, t6, 1 - /* At this point t6 == I-cache ways. */ - mul t2, t2, t6 -#endif - -#ifdef CONFIG_SYS_DCACHE_SIZE - li t3, CONFIG_SYS_DCACHE_SIZE -#else - /* Detect D-cache size. */ - srl t6, t5, MIPS_CONF1_DS_SHIFT - andi t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT) - li t4, 32 - xori t3, t6, 0x7 - beqz t3, 1f - addi t6, t6, 1 - sllv t4, t4, t6 -1: /* At this point t4 == I-cache sets. */ - mul t3, t4, t7 - srl t6, t5, MIPS_CONF1_DA_SHIFT - andi t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT) - addi t6, t6, 1 - /* At this point t6 == I-cache ways. */ - mul t3, t3, t6 -#endif - - /* Determine the largest L1 cache size */ -#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) -#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE - li v0, CONFIG_SYS_ICACHE_SIZE -#else - li v0, CONFIG_SYS_DCACHE_SIZE -#endif -#else - move v0, t2 - sltu t1, t2, t3 - movn v0, t3, t1 -#endif - /* - * Now clear that much memory starting from zero. - */ - PTR_LI a0, CKSEG1 - PTR_ADDU a1, a0, v0 -2: PTR_ADDIU a0, 64 - f_fill64 a0, -64, zero - bne a0, a1, 2b - - /* - * The caches are probably in an indeterminate state, - * so we force good parity into them by doing an - * invalidate, load/fill, invalidate for each line. - */ - - /* - * Assume bottom of RAM will generate good parity for the cache. - */ - - /* - * Initialize the I-cache first, - */ - move a1, t2 - move a2, t8 - PTR_LA v1, mips_init_icache - jalr v1 - - /* - * then initialize D-cache. - */ - move a1, t3 - move a2, t7 - PTR_LA v1, mips_init_dcache - jalr v1 - - jr RA - END(mips_cache_reset) - -/* - * dcache_status - get cache status - * - * RETURNS: 0 - cache disabled; 1 - cache enabled - * - */ -LEAF(dcache_status) - mfc0 t0, CP0_CONFIG - li t1, CONF_CM_UNCACHED - andi t0, t0, CONF_CM_CMASK - move v0, zero - beq t0, t1, 2f - li v0, 1 -2: jr ra - END(dcache_status) - -/* - * dcache_disable - disable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_disable) - mfc0 t0, CP0_CONFIG - li t1, -8 - and t0, t0, t1 - ori t0, t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_disable) - -/* - * dcache_enable - enable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_enable) - mfc0 t0, CP0_CONFIG - ori t0, CONF_CM_CMASK - xori t0, CONF_CM_CMASK - ori t0, CONFIG_SYS_MIPS_CACHE_MODE - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_enable) diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile index 899c319c9a..cb4db9c71b 100644 --- a/arch/mips/cpu/mips64/Makefile +++ b/arch/mips/cpu/mips64/Makefile @@ -6,4 +6,4 @@ # extra-y = start.o -obj-y = cpu.o interrupts.o time.o cache.o +obj-y = cpu.o interrupts.o time.o diff --git a/arch/mips/cpu/mips64/cache.S b/arch/mips/cpu/mips64/cache.S deleted file mode 100644 index 36d868818a..0000000000 --- a/arch/mips/cpu/mips64/cache.S +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Cache-handling routined for MIPS CPUs - * - * Copyright (c) 2003 Wolfgang Denk - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#define RA t9 - -/* - * 16kB is the maximum size of instruction and data caches on MIPS 4K, - * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience. - * - * Note that the above size is the maximum size of primary cache. U-Boot - * doesn't have L2 cache support for now. - */ -#define MIPS_MAX_CACHE_SIZE 0x10000 - -#define INDEX_BASE CKSEG0 - - .macro cache_op op addr - .set push - .set noreorder - .set mips3 - cache \op, 0(\addr) - .set pop - .endm - - .macro f_fill64 dst, offset, val - LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) -#if LONGSIZE == 4 - LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) - LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) -#endif - .endm - -/* - * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) - */ -LEAF(mips_init_icache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - /* clear tag to invalidate */ - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 -1: cache_op INDEX_STORE_TAG_I t0 - PTR_ADDU t0, a2 - bne t0, t1, 1b - /* fill once, so data field parity is correct */ - PTR_LI t0, INDEX_BASE -2: cache_op FILL t0 - PTR_ADDU t0, a2 - bne t0, t1, 2b - /* invalidate again - prudent but not strictly neccessary */ - PTR_LI t0, INDEX_BASE -1: cache_op INDEX_STORE_TAG_I t0 - PTR_ADDU t0, a2 - bne t0, t1, 1b -9: jr ra - END(mips_init_icache) - -/* - * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) - */ -LEAF(mips_init_dcache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - /* clear all tags */ - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 -1: cache_op INDEX_STORE_TAG_D t0 - PTR_ADDU t0, a2 - bne t0, t1, 1b - /* load from each line (in cached space) */ - PTR_LI t0, INDEX_BASE -2: LONG_L zero, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 2b - /* clear all tags */ - PTR_LI t0, INDEX_BASE -1: cache_op INDEX_STORE_TAG_D t0 - PTR_ADDU t0, a2 - bne t0, t1, 1b -9: jr ra - END(mips_init_dcache) - -/* - * mips_cache_reset - low level initialisation of the primary caches - * - * This routine initialises the primary caches to ensure that they have good - * parity. It must be called by the ROM before any cached locations are used - * to prevent the possibility of data with bad parity being written to memory. - * - * To initialise the instruction cache it is essential that a source of data - * with good parity is available. This routine will initialise an area of - * memory starting at location zero to be used as a source of parity. - * - * RETURNS: N/A - * - */ -NESTED(mips_cache_reset, 0, ra) - move RA, ra - li t2, CONFIG_SYS_ICACHE_SIZE - li t3, CONFIG_SYS_DCACHE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE - - li v0, MIPS_MAX_CACHE_SIZE - - /* - * Now clear that much memory starting from zero. - */ - PTR_LI a0, CKSEG1 - PTR_ADDU a1, a0, v0 -2: PTR_ADDIU a0, 64 - f_fill64 a0, -64, zero - bne a0, a1, 2b - - /* - * The caches are probably in an indeterminate state, - * so we force good parity into them by doing an - * invalidate, load/fill, invalidate for each line. - */ - - /* - * Assume bottom of RAM will generate good parity for the cache. - */ - - /* - * Initialize the I-cache first, - */ - move a1, t2 - move a2, t8 - PTR_LA v1, mips_init_icache - jalr v1 - - /* - * then initialize D-cache. - */ - move a1, t3 - move a2, t8 - PTR_LA v1, mips_init_dcache - jalr v1 - - jr RA - END(mips_cache_reset) - -/* - * dcache_status - get cache status - * - * RETURNS: 0 - cache disabled; 1 - cache enabled - * - */ -LEAF(dcache_status) - mfc0 t0, CP0_CONFIG - li t1, CONF_CM_UNCACHED - andi t0, t0, CONF_CM_CMASK - move v0, zero - beq t0, t1, 2f - li v0, 1 -2: jr ra - END(dcache_status) - -/* - * dcache_disable - disable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_disable) - mfc0 t0, CP0_CONFIG - li t1, -8 - and t0, t0, t1 - ori t0, t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_disable) - -/* - * dcache_enable - enable cache - * - * RETURNS: N/A - * - */ -LEAF(dcache_enable) - mfc0 t0, CP0_CONFIG - ori t0, CONF_CM_CMASK - xori t0, CONF_CM_CMASK - ori t0, CONF_CM_CACHABLE_NONCOHERENT - mtc0 t0, CP0_CONFIG - jr ra - END(dcache_enable) diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index d939ee6a32..ac536da674 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -6,6 +6,7 @@ # obj-y += cache.o +obj-y += cache_init.o obj-y += io.o obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S new file mode 100644 index 0000000000..6c02bf9b53 --- /dev/null +++ b/arch/mips/lib/cache_init.S @@ -0,0 +1,277 @@ +/* + * Cache-handling routined for MIPS CPUs + * + * Copyright (c) 2003 Wolfgang Denk + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_MIPS_CACHE_MODE +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT +#endif + +#ifdef CONFIG_64BIT +# define RA ta3 +#else +# define RA t7 +#endif + +#define INDEX_BASE CKSEG0 + + .macro f_fill64 dst, offset, val + LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) +#if LONGSIZE == 4 + LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) +#endif + .endm + +/* + * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) + */ +LEAF(mips_init_icache) + blez a1, 9f + mtc0 zero, CP0_TAGLO + /* clear tag to invalidate */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +1: cache INDEX_STORE_TAG_I, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 1b + /* fill once, so data field parity is correct */ + PTR_LI t0, INDEX_BASE +2: cache FILL, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 2b + /* invalidate again - prudent but not strictly neccessary */ + PTR_LI t0, INDEX_BASE +1: cache INDEX_STORE_TAG_I, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 1b +9: jr ra + END(mips_init_icache) + +/* + * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) + */ +LEAF(mips_init_dcache) + blez a1, 9f + mtc0 zero, CP0_TAGLO + /* clear all tags */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +1: cache INDEX_STORE_TAG_D, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 1b + /* load from each line (in cached space) */ + PTR_LI t0, INDEX_BASE +2: LONG_L zero, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 2b + /* clear all tags */ + PTR_LI t0, INDEX_BASE +1: cache INDEX_STORE_TAG_D, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 1b +9: jr ra + END(mips_init_dcache) + +/* + * mips_cache_reset - low level initialisation of the primary caches + * + * This routine initialises the primary caches to ensure that they have good + * parity. It must be called by the ROM before any cached locations are used + * to prevent the possibility of data with bad parity being written to memory. + * + * To initialise the instruction cache it is essential that a source of data + * with good parity is available. This routine will initialise an area of + * memory starting at location zero to be used as a source of parity. + * + * RETURNS: N/A + * + */ +NESTED(mips_cache_reset, 0, ra) + move RA, ra + +#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \ + !defined(CONFIG_SYS_CACHELINE_SIZE) + /* read Config1 for use below */ + mfc0 t5, CP0_CONFIG, 1 +#endif + +#ifdef CONFIG_SYS_CACHELINE_SIZE + li t9, CONFIG_SYS_CACHELINE_SIZE + li t8, CONFIG_SYS_CACHELINE_SIZE +#else + /* Detect I-cache line size. */ + srl t8, t5, MIPS_CONF1_IL_SHIFT + andi t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT) + beqz t8, 1f + li t6, 2 + sllv t8, t6, t8 + +1: /* Detect D-cache line size. */ + srl t9, t5, MIPS_CONF1_DL_SHIFT + andi t9, t9, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT) + beqz t9, 1f + li t6, 2 + sllv t9, t6, t9 +1: +#endif + +#ifdef CONFIG_SYS_ICACHE_SIZE + li t2, CONFIG_SYS_ICACHE_SIZE +#else + /* Detect I-cache size. */ + srl t6, t5, MIPS_CONF1_IS_SHIFT + andi t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT) + li t4, 32 + xori t2, t6, 0x7 + beqz t2, 1f + addi t6, t6, 1 + sllv t4, t4, t6 +1: /* At this point t4 == I-cache sets. */ + mul t2, t4, t8 + srl t6, t5, MIPS_CONF1_IA_SHIFT + andi t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT) + addi t6, t6, 1 + /* At this point t6 == I-cache ways. */ + mul t2, t2, t6 +#endif + +#ifdef CONFIG_SYS_DCACHE_SIZE + li t3, CONFIG_SYS_DCACHE_SIZE +#else + /* Detect D-cache size. */ + srl t6, t5, MIPS_CONF1_DS_SHIFT + andi t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT) + li t4, 32 + xori t3, t6, 0x7 + beqz t3, 1f + addi t6, t6, 1 + sllv t4, t4, t6 +1: /* At this point t4 == I-cache sets. */ + mul t3, t4, t9 + srl t6, t5, MIPS_CONF1_DA_SHIFT + andi t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT) + addi t6, t6, 1 + /* At this point t6 == I-cache ways. */ + mul t3, t3, t6 +#endif + + /* Determine the largest L1 cache size */ +#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) +#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE + li v0, CONFIG_SYS_ICACHE_SIZE +#else + li v0, CONFIG_SYS_DCACHE_SIZE +#endif +#else + move v0, t2 + sltu t1, t2, t3 + movn v0, t3, t1 +#endif + /* + * Now clear that much memory starting from zero. + */ + PTR_LI a0, CKSEG1 + PTR_ADDU a1, a0, v0 +2: PTR_ADDIU a0, 64 + f_fill64 a0, -64, zero + bne a0, a1, 2b + + /* + * The caches are probably in an indeterminate state, + * so we force good parity into them by doing an + * invalidate, load/fill, invalidate for each line. + */ + + /* + * Assume bottom of RAM will generate good parity for the cache. + */ + + /* + * Initialize the I-cache first, + */ + move a1, t2 + move a2, t8 + PTR_LA v1, mips_init_icache + jalr v1 + + /* + * then initialize D-cache. + */ + move a1, t3 + move a2, t9 + PTR_LA v1, mips_init_dcache + jalr v1 + + jr RA + END(mips_cache_reset) + +/* + * dcache_status - get cache status + * + * RETURNS: 0 - cache disabled; 1 - cache enabled + * + */ +LEAF(dcache_status) + mfc0 t0, CP0_CONFIG + li t1, CONF_CM_UNCACHED + andi t0, t0, CONF_CM_CMASK + move v0, zero + beq t0, t1, 2f + li v0, 1 +2: jr ra + END(dcache_status) + +/* + * dcache_disable - disable cache + * + * RETURNS: N/A + * + */ +LEAF(dcache_disable) + mfc0 t0, CP0_CONFIG + li t1, -8 + and t0, t0, t1 + ori t0, t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG + jr ra + END(dcache_disable) + +/* + * dcache_enable - enable cache + * + * RETURNS: N/A + * + */ +LEAF(dcache_enable) + mfc0 t0, CP0_CONFIG + ori t0, CONF_CM_CMASK + xori t0, CONF_CM_CMASK + ori t0, CONFIG_SYS_MIPS_CACHE_MODE + mtc0 t0, CP0_CONFIG + jr ra + END(dcache_enable) -- cgit From 536cb7ce1aca10c326ac864b3e1d05ab57b3ec7e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:27:59 +0000 Subject: MIPS: refactor L1 cache config reads to a macro Reduce duplication between reading the configuration of the L1 dcache & icache by performing both using a macro which calculates the appropriate line & cache sizes from the coprocessor 0 Config1 register. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/lib/cache_init.S | 97 ++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 6c02bf9b53..2e036d9b97 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -97,6 +97,43 @@ LEAF(mips_init_dcache) 9: jr ra END(mips_init_dcache) + .macro l1_info sz, line_sz, off + .set push + .set noat + + mfc0 $1, CP0_CONFIG, 1 + + /* detect line size */ + srl \line_sz, $1, \off + MIPS_CONF1_DL_SHIFT - MIPS_CONF1_DA_SHIFT + andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT) + move \sz, zero + beqz \line_sz, 10f + li \sz, 2 + sllv \line_sz, \sz, \line_sz + + /* detect associativity */ + srl \sz, $1, \off + MIPS_CONF1_DA_SHIFT - MIPS_CONF1_DA_SHIFT + andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT) + addi \sz, \sz, 1 + + /* sz *= line_sz */ + mul \sz, \sz, \line_sz + + /* detect log32(sets) */ + srl $1, $1, \off + MIPS_CONF1_DS_SHIFT - MIPS_CONF1_DA_SHIFT + andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT) + addiu $1, $1, 1 + andi $1, $1, 0x7 + + /* sz <<= log32(sets) */ + sllv \sz, \sz, $1 + + /* sz *= 32 */ + li $1, 32 + mul \sz, \sz, $1 +10: + .set pop + .endm /* * mips_cache_reset - low level initialisation of the primary caches * @@ -114,70 +151,18 @@ LEAF(mips_init_dcache) NESTED(mips_cache_reset, 0, ra) move RA, ra -#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \ - !defined(CONFIG_SYS_CACHELINE_SIZE) - /* read Config1 for use below */ - mfc0 t5, CP0_CONFIG, 1 -#endif - -#ifdef CONFIG_SYS_CACHELINE_SIZE - li t9, CONFIG_SYS_CACHELINE_SIZE - li t8, CONFIG_SYS_CACHELINE_SIZE -#else - /* Detect I-cache line size. */ - srl t8, t5, MIPS_CONF1_IL_SHIFT - andi t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT) - beqz t8, 1f - li t6, 2 - sllv t8, t6, t8 - -1: /* Detect D-cache line size. */ - srl t9, t5, MIPS_CONF1_DL_SHIFT - andi t9, t9, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT) - beqz t9, 1f - li t6, 2 - sllv t9, t6, t9 -1: -#endif - #ifdef CONFIG_SYS_ICACHE_SIZE li t2, CONFIG_SYS_ICACHE_SIZE + li t8, CONFIG_SYS_CACHELINE_SIZE #else - /* Detect I-cache size. */ - srl t6, t5, MIPS_CONF1_IS_SHIFT - andi t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT) - li t4, 32 - xori t2, t6, 0x7 - beqz t2, 1f - addi t6, t6, 1 - sllv t4, t4, t6 -1: /* At this point t4 == I-cache sets. */ - mul t2, t4, t8 - srl t6, t5, MIPS_CONF1_IA_SHIFT - andi t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT) - addi t6, t6, 1 - /* At this point t6 == I-cache ways. */ - mul t2, t2, t6 + l1_info t2, t8, MIPS_CONF1_IA_SHIFT #endif #ifdef CONFIG_SYS_DCACHE_SIZE li t3, CONFIG_SYS_DCACHE_SIZE + li t9, CONFIG_SYS_CACHELINE_SIZE #else - /* Detect D-cache size. */ - srl t6, t5, MIPS_CONF1_DS_SHIFT - andi t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT) - li t4, 32 - xori t3, t6, 0x7 - beqz t3, 1f - addi t6, t6, 1 - sllv t4, t4, t6 -1: /* At this point t4 == I-cache sets. */ - mul t3, t4, t9 - srl t6, t5, MIPS_CONF1_DA_SHIFT - andi t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT) - addi t6, t6, 1 - /* At this point t6 == I-cache ways. */ - mul t3, t3, t6 + l1_info t3, t9, MIPS_CONF1_DA_SHIFT #endif /* Determine the largest L1 cache size */ -- cgit From ac22feca1135b81ecc4d38995e98b59943d1bbf5 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:28:00 +0000 Subject: MIPS: refactor cache loops to a macro Reduce duplication by performing loops through cache tags using an assembler macro. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/lib/cache_init.S | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 2e036d9b97..dc207a6a1c 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -47,28 +47,28 @@ #endif .endm + .macro cache_loop curr, end, line_sz, op +10: cache \op, 0(\curr) + PTR_ADDU \curr, \curr, \line_sz + bne \curr, \end, 10b + .endm + /* * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) */ LEAF(mips_init_icache) blez a1, 9f mtc0 zero, CP0_TAGLO - /* clear tag to invalidate */ PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, a1 -1: cache INDEX_STORE_TAG_I, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b + /* clear tag to invalidate */ + cache_loop t0, t1, a2, INDEX_STORE_TAG_I /* fill once, so data field parity is correct */ PTR_LI t0, INDEX_BASE -2: cache FILL, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 2b + cache_loop t0, t1, a2, FILL /* invalidate again - prudent but not strictly neccessary */ PTR_LI t0, INDEX_BASE -1: cache INDEX_STORE_TAG_I, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b + cache_loop t0, t1, a2, INDEX_STORE_TAG_I 9: jr ra END(mips_init_icache) @@ -78,12 +78,10 @@ LEAF(mips_init_icache) LEAF(mips_init_dcache) blez a1, 9f mtc0 zero, CP0_TAGLO - /* clear all tags */ PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, a1 -1: cache INDEX_STORE_TAG_D, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b + /* clear all tags */ + cache_loop t0, t1, a2, INDEX_STORE_TAG_D /* load from each line (in cached space) */ PTR_LI t0, INDEX_BASE 2: LONG_L zero, 0(t0) @@ -91,9 +89,7 @@ LEAF(mips_init_dcache) bne t0, t1, 2b /* clear all tags */ PTR_LI t0, INDEX_BASE -1: cache INDEX_STORE_TAG_D, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 1b + cache_loop t0, t1, a2, INDEX_STORE_TAG_D 9: jr ra END(mips_init_dcache) -- cgit From ca4e833cd6409c72e5b13ee803a4f08381e6d160 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:28:01 +0000 Subject: MIPS: inline mips_init_[id]cache functions The mips_init_[id]cache functions are small & only called once from a single callsite. Inlining them allows mips_cache_reset to avoid having to bother moving arguments around & leaves it a leaf function which is thus able to simply keep the return address live in the ra register throughout, simplifying the code. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/lib/cache_init.S | 86 +++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index dc207a6a1c..cbd04bd2f3 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -18,12 +18,6 @@ #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #endif -#ifdef CONFIG_64BIT -# define RA ta3 -#else -# define RA t7 -#endif - #define INDEX_BASE CKSEG0 .macro f_fill64 dst, offset, val @@ -53,46 +47,6 @@ bne \curr, \end, 10b .endm -/* - * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) - */ -LEAF(mips_init_icache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 - /* clear tag to invalidate */ - cache_loop t0, t1, a2, INDEX_STORE_TAG_I - /* fill once, so data field parity is correct */ - PTR_LI t0, INDEX_BASE - cache_loop t0, t1, a2, FILL - /* invalidate again - prudent but not strictly neccessary */ - PTR_LI t0, INDEX_BASE - cache_loop t0, t1, a2, INDEX_STORE_TAG_I -9: jr ra - END(mips_init_icache) - -/* - * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) - */ -LEAF(mips_init_dcache) - blez a1, 9f - mtc0 zero, CP0_TAGLO - PTR_LI t0, INDEX_BASE - PTR_ADDU t1, t0, a1 - /* clear all tags */ - cache_loop t0, t1, a2, INDEX_STORE_TAG_D - /* load from each line (in cached space) */ - PTR_LI t0, INDEX_BASE -2: LONG_L zero, 0(t0) - PTR_ADDU t0, a2 - bne t0, t1, 2b - /* clear all tags */ - PTR_LI t0, INDEX_BASE - cache_loop t0, t1, a2, INDEX_STORE_TAG_D -9: jr ra - END(mips_init_dcache) - .macro l1_info sz, line_sz, off .set push .set noat @@ -144,9 +98,7 @@ LEAF(mips_init_dcache) * RETURNS: N/A * */ -NESTED(mips_cache_reset, 0, ra) - move RA, ra - +LEAF(mips_cache_reset) #ifdef CONFIG_SYS_ICACHE_SIZE li t2, CONFIG_SYS_ICACHE_SIZE li t8, CONFIG_SYS_CACHELINE_SIZE @@ -195,20 +147,38 @@ NESTED(mips_cache_reset, 0, ra) /* * Initialize the I-cache first, */ - move a1, t2 - move a2, t8 - PTR_LA v1, mips_init_icache - jalr v1 + blez t2, 1f + mtc0 zero, CP0_TAGLO + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, t2 + /* clear tag to invalidate */ + cache_loop t0, t1, t8, INDEX_STORE_TAG_I + /* fill once, so data field parity is correct */ + PTR_LI t0, INDEX_BASE + cache_loop t0, t1, t8, FILL + /* invalidate again - prudent but not strictly neccessary */ + PTR_LI t0, INDEX_BASE + cache_loop t0, t1, t8, INDEX_STORE_TAG_I /* * then initialize D-cache. */ - move a1, t3 - move a2, t9 - PTR_LA v1, mips_init_dcache - jalr v1 +1: blez t3, 3f + mtc0 zero, CP0_TAGLO + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, t3 + /* clear all tags */ + cache_loop t0, t1, t9, INDEX_STORE_TAG_D + /* load from each line (in cached space) */ + PTR_LI t0, INDEX_BASE +2: LONG_L zero, 0(t0) + PTR_ADDU t0, t9 + bne t0, t1, 2b + /* clear all tags */ + PTR_LI t0, INDEX_BASE + cache_loop t0, t1, t9, INDEX_STORE_TAG_D - jr RA +3: jr ra END(mips_cache_reset) /* -- cgit From dd7c72006e51f0d27e5cb1dcf60d5b9bf307565e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:28:02 +0000 Subject: MIPS: allow systems to skip loads during cache init Current MIPS systems do not require that loads be performed to force the parity of cache lines, a simple invalidate by clearing the tag for each line will suffice. Thus this patch makes the loads & subsequent second invalidation conditional upon the CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD option, and defines that for existing mips32 targets. Exceptions are malta where this is known to be unnecessary, and qemu-mips where caches are not implemented. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/Kconfig | 6 ++++++ arch/mips/lib/cache_init.S | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ef7892975a..bc4283d2f1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -36,6 +36,7 @@ config TARGET_VCT select SUPPORTS_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 + select SYS_MIPS_CACHE_INIT_RAM_LOAD config TARGET_DBAU1X00 bool "Support dbau1x00" @@ -43,12 +44,14 @@ config TARGET_DBAU1X00 select SUPPORTS_LITTLE_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 + select SYS_MIPS_CACHE_INIT_RAM_LOAD config TARGET_PB1X00 bool "Support pb1x00" select SUPPORTS_LITTLE_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 + select SYS_MIPS_CACHE_INIT_RAM_LOAD endchoice @@ -185,6 +188,9 @@ config 64BIT config SWAP_IO_SPACE bool +config SYS_MIPS_CACHE_INIT_RAM_LOAD + bool + endif endmenu diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index cbd04bd2f3..04a36b2528 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -113,6 +113,8 @@ LEAF(mips_cache_reset) l1_info t3, t9, MIPS_CONF1_DA_SHIFT #endif +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD + /* Determine the largest L1 cache size */ #if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE @@ -134,14 +136,15 @@ LEAF(mips_cache_reset) f_fill64 a0, -64, zero bne a0, a1, 2b - /* - * The caches are probably in an indeterminate state, - * so we force good parity into them by doing an - * invalidate, load/fill, invalidate for each line. - */ +#endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */ /* - * Assume bottom of RAM will generate good parity for the cache. + * The caches are probably in an indeterminate state, so we force good + * parity into them by doing an invalidate for each line. If + * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to + * perform a load/fill & a further invalidate for each line, assuming + * that the bottom of RAM (having just been cleared) will generate good + * parity for the cache. */ /* @@ -153,12 +156,14 @@ LEAF(mips_cache_reset) PTR_ADDU t1, t0, t2 /* clear tag to invalidate */ cache_loop t0, t1, t8, INDEX_STORE_TAG_I +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* fill once, so data field parity is correct */ PTR_LI t0, INDEX_BASE cache_loop t0, t1, t8, FILL /* invalidate again - prudent but not strictly neccessary */ PTR_LI t0, INDEX_BASE cache_loop t0, t1, t8, INDEX_STORE_TAG_I +#endif /* * then initialize D-cache. @@ -169,6 +174,7 @@ LEAF(mips_cache_reset) PTR_ADDU t1, t0, t3 /* clear all tags */ cache_loop t0, t1, t9, INDEX_STORE_TAG_D +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD /* load from each line (in cached space) */ PTR_LI t0, INDEX_BASE 2: LONG_L zero, 0(t0) @@ -177,6 +183,7 @@ LEAF(mips_cache_reset) /* clear all tags */ PTR_LI t0, INDEX_BASE cache_loop t0, t1, t9, INDEX_STORE_TAG_D +#endif 3: jr ra END(mips_cache_reset) -- cgit From 8755d50706742e4d302a335f4e69dd6430ec12a2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 01:28:03 +0000 Subject: MIPS: clear TagLo select 2 during cache init Current MIPS cores from Imagination Technologies use TagLo select 2 for the data cache. The architecture requires that it is safe for software to write to this register even if it isn't present, so take the trivial option of clearing both selects 0 & 2. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/lib/cache_init.S | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/cache_init.S b/arch/mips/lib/cache_init.S index 04a36b2528..137d7283ff 100644 --- a/arch/mips/lib/cache_init.S +++ b/arch/mips/lib/cache_init.S @@ -138,6 +138,14 @@ LEAF(mips_cache_reset) #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */ + /* + * The TagLo registers used depend upon the CPU implementation, but the + * architecture requires that it is safe for software to write to both + * TagLo selects 0 & 2 covering supported cases. + */ + mtc0 zero, CP0_TAGLO + mtc0 zero, CP0_TAGLO, 2 + /* * The caches are probably in an indeterminate state, so we force good * parity into them by doing an invalidate for each line. If @@ -151,7 +159,6 @@ LEAF(mips_cache_reset) * Initialize the I-cache first, */ blez t2, 1f - mtc0 zero, CP0_TAGLO PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, t2 /* clear tag to invalidate */ @@ -169,7 +176,6 @@ LEAF(mips_cache_reset) * then initialize D-cache. */ 1: blez t3, 3f - mtc0 zero, CP0_TAGLO PTR_LI t0, INDEX_BASE PTR_ADDU t1, t0, t3 /* clear all tags */ -- cgit From ba21a453a58fc02b890f4064b293b1cb09fe7484 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:38:20 +0000 Subject: malta: IDE support This patch adds IDE support to the MIPS Malta board. The IDE controller is enabled after probing the PCI bus and otherwise just makes use of U-boot generic IDE support. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/include/asm/malta.h | 5 +++++ board/imgtec/malta/malta.c | 19 +++++++++++++++++++ include/configs/malta.h | 11 +++++++++++ 3 files changed, 35 insertions(+) diff --git a/arch/mips/include/asm/malta.h b/arch/mips/include/asm/malta.h index 9e7c045aac..d9ffc1558d 100644 --- a/arch/mips/include/asm/malta.h +++ b/arch/mips/include/asm/malta.h @@ -64,4 +64,9 @@ #define PCI_CFG_PIIX4_GENCFG_SERIRQ (1 << 16) +#define PCI_CFG_PIIX4_IDETIM_PRI 0x40 +#define PCI_CFG_PIIX4_IDETIM_SEC 0x42 + +#define PCI_CFG_PIIX4_IDETIM_IDE (1 << 15) + #endif /* _MIPS_ASM_MALTA_H */ diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index 78c4bd4efe..72b03ff8cd 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -217,4 +218,22 @@ void pci_init_board(void) pci_read_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, &val8); val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT; pci_write_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, val8); + + bdf = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB, 0); + if (bdf == -1) + panic("Failed to find PIIX4 IDE controller\n"); + + /* enable bus master & IO access */ + val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; + pci_write_config_dword(bdf, PCI_COMMAND, val32); + + /* set latency */ + pci_write_config_byte(bdf, PCI_LATENCY_TIMER, 0x40); + + /* enable IDE/ATA */ + pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_PRI, + PCI_CFG_PIIX4_IDETIM_IDE); + pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC, + PCI_CFG_PIIX4_IDETIM_IDE); } diff --git a/include/configs/malta.h b/include/configs/malta.h index 684d249590..ed5da6cd73 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -106,6 +106,16 @@ #define CONFIG_ENV_ADDR \ (CONFIG_SYS_FLASH_BASE + (4 << 20) - CONFIG_ENV_SIZE) +/* + * IDE/ATA + */ +#define CONFIG_SYS_IDE_MAXBUS 1 +#define CONFIG_SYS_IDE_MAXDEVICE 2 +#define CONFIG_SYS_ATA_BASE_ADDR CONFIG_SYS_ISA_IO_BASE_ADDRESS +#define CONFIG_SYS_ATA_IDE0_OFFSET 0x01f0 +#define CONFIG_SYS_ATA_DATA_OFFSET 0 +#define CONFIG_SYS_ATA_REG_OFFSET 0 + /* * Commands */ @@ -118,6 +128,7 @@ #define CONFIG_CMD_DATE #define CONFIG_CMD_DHCP +#define CONFIG_CMD_IDE #define CONFIG_CMD_PCI #define CONFIG_CMD_PING -- cgit From 28c8c3d40fcc96e57d87c4a770adf7f11193bd69 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:38:21 +0000 Subject: malta: delay after reset Reset isn't instant, so delay to give it a chance. Otherwise we go on to print a failure message before resetting anyway. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- board/imgtec/malta/malta.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c index 72b03ff8cd..79562f79a8 100644 --- a/board/imgtec/malta/malta.c +++ b/board/imgtec/malta/malta.c @@ -124,6 +124,7 @@ void _machine_restart(void) reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE); __raw_writel(GORESET, reset_base); + mdelay(1000); } int board_early_init_f(void) -- cgit From a3bdaacaf61deb74565d1b9e9ad3497b6f7a4051 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:38:22 +0000 Subject: malta: enable HUSH parser The malta board is used for development and thus the shell is interacted with often. Enable HUSH to make the experience a little more pleasant. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- include/configs/malta.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/malta.h b/include/configs/malta.h index ed5da6cd73..4e64cc968d 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -71,6 +71,7 @@ sizeof(CONFIG_SYS_PROMPT) + 16) #define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_HUSH_PARSER #define CONFIG_AUTO_COMPLETE #define CONFIG_CMDLINE_EDITING -- cgit From d4d774e00e7232b524ddb20d992c5b12d84e3ef2 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:38:23 +0000 Subject: malta: enable ELF loading The ability to load ELF files is sometimes useful on Malta boards, particularly for use with small embedded applications. Enable the loadelf command in the malta config. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- include/configs/malta.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/malta.h b/include/configs/malta.h index 4e64cc968d..354672ecf8 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -129,6 +129,7 @@ #define CONFIG_CMD_DATE #define CONFIG_CMD_DHCP +#define CONFIG_CMD_ELF #define CONFIG_CMD_IDE #define CONFIG_CMD_PCI #define CONFIG_CMD_PING -- cgit From 508a6edea92877f81972a4ab04d1e2d5549030ec Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:41 +0200 Subject: arm: mx6: cm-fx6: expand boot sequence Expand boot sequence to the following order: 1) mmc boot: mmc boot script, then mmc bootm, then mmc bootz. 2) usb boot: usb boot script. 3) sata boot: sata boot script, sata bootm, sata bootz. 4) nand boot: nand bootm, then nand bootz. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- include/configs/cm_fx6.h | 127 +++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index f7277eb1d1..d79c83bf2d 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -103,97 +103,92 @@ #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_EXTRA_ENV_SETTINGS \ - "kernel=uImage-cm-fx6\0" \ "autoload=no\0" \ + "kernel=uImage-cm-fx6\0" \ + "script=boot.scr\0" \ + "dtb=cm-fx6.dtb\0" \ + "bootm_low=18000000\0" \ "loadaddr=0x10800000\0" \ "fdtaddr=0x11000000\0" \ "console=ttymxc3,115200\0" \ "ethprime=FEC0\0" \ - "bootscr=boot.scr\0" \ - "bootm_low=18000000\0" \ "video_hdmi=mxcfb0:dev=hdmi,1920x1080M-32@50,if=RGB32\0" \ "video_dvi=mxcfb0:dev=dvi,1280x800M-32@50,if=RGB32\0" \ - "fdtfile=cm-fx6.dtb\0" \ "doboot=bootm ${loadaddr}\0" \ - "loadfdt=false\0" \ + "doloadfdt=false\0" \ "setboottypez=setenv kernel zImage-cm-fx6;" \ "setenv doboot bootz ${loadaddr} - ${fdtaddr};" \ - "setenv loadfdt true;\0" \ + "setenv doloadfdt true;\0" \ "setboottypem=setenv kernel uImage-cm-fx6;" \ "setenv doboot bootm ${loadaddr};" \ - "setenv loadfdt false;\0"\ - "run_eboot=echo Starting EBOOT ...; "\ - "mmc dev ${mmcdev} && " \ - "mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \ - "mmcdev=2\0" \ + "setenv doloadfdt false;\0"\ "mmcroot=/dev/mmcblk0p2 rw rootwait\0" \ - "loadmmcbootscript=load mmc ${mmcdev} ${loadaddr} ${bootscr}\0" \ - "mmcbootscript=echo Running bootscript from mmc ...; "\ - "source ${loadaddr}\0" \ - "mmcargs=setenv bootargs console=${console} " \ - "root=${mmcroot} " \ - "${video}\0" \ - "mmcloadkernel=load mmc ${mmcdev} ${loadaddr} ${kernel}\0" \ - "mmcloadfdt=load mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \ - "mmcboot=echo Booting from mmc ...; " \ - "run mmcargs; " \ - "run doboot\0" \ - "satadev=0\0" \ "sataroot=/dev/sda2 rw rootwait\0" \ - "sataargs=setenv bootargs console=${console} " \ - "root=${sataroot} " \ - "${video}\0" \ - "loadsatabootscript=load sata ${satadev} ${loadaddr} ${bootscr}\0" \ - "satabootscript=echo Running bootscript from sata ...; " \ - "source ${loadaddr}\0" \ - "sataloadkernel=load sata ${satadev} ${loadaddr} ${kernel}\0" \ - "sataloadfdt=load sata ${satadev} ${fdtaddr} ${fdtfile}\0" \ - "sataboot=echo Booting from sata ...; "\ - "run sataargs; " \ - "run doboot\0" \ "nandroot=/dev/mtdblock4 rw\0" \ "nandrootfstype=ubifs\0" \ + "mmcargs=setenv bootargs console=${console} root=${mmcroot} " \ + "${video}\0" \ + "sataargs=setenv bootargs console=${console} root=${sataroot} " \ + "${video}\0" \ "nandargs=setenv bootargs console=${console} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype} " \ "${video}\0" \ - "nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \ - "nandboot=echo Booting from nand ...; " \ - "run nandargs; " \ - "nand read ${loadaddr} 0 780000; " \ - "if ${loadfdt}; then " \ + "nandboot=if run nandloadkernel; then " \ "run nandloadfdt;" \ - "fi; " \ - "run doboot\0" \ - "boot=mmc dev ${mmcdev}; " \ - "if mmc rescan; then " \ - "if run loadmmcbootscript; then " \ - "run mmcbootscript;" \ - "else " \ - "if run mmcloadkernel; then " \ - "if ${loadfdt}; then " \ - "run mmcloadfdt;" \ - "fi;" \ - "run mmcboot;" \ - "fi;" \ - "fi;" \ + "run setboottypem;" \ + "run storagebootcmd;" \ + "run setboottypez;" \ + "run storagebootcmd;" \ + "fi;\0" \ + "run_eboot=echo Starting EBOOT ...; "\ + "mmc dev 2 && " \ + "mmc rescan && mmc read 10042000 a 400 && go 10042000\0" \ + "loadscript=load ${storagetype} ${storagedev} ${loadaddr} ${script};\0"\ + "loadkernel=load ${storagetype} ${storagedev} ${loadaddr} ${kernel};\0"\ + "loadfdt=load ${storagetype} ${storagedev} ${fdtaddr} ${dtb};\0" \ + "bootscript=echo Running bootscript from ${storagetype} ...;" \ + "source ${loadaddr};\0" \ + "nandloadkernel=nand read ${loadaddr} 0 780000;\0" \ + "nandloadfdt=nand read ${fdtaddr} 780000 80000;\0" \ + "setupmmcboot=setenv storagetype mmc; setenv storagedev 2;\0" \ + "setupsataboot=setenv storagetype sata; setenv storagedev 0;\0" \ + "setupnandboot=setenv storagetype nand;\0" \ + "setupusbboot=setenv storagetype usb; setenv storagedev 0;\0" \ + "storagebootcmd=echo Booting from ${storagetype} ...;" \ + "run ${storagetype}args; run doboot;\0" \ + "trybootk=if run loadkernel; then " \ + "if ${doloadfdt}; then " \ + "run loadfdt;" \ "fi;" \ - "if sata init; then " \ - "if run loadsatabootscript; then " \ - "run satabootscript;" \ - "else "\ - "if run sataloadkernel; then " \ - "if ${loadfdt}; then " \ - "run sataloadfdt; " \ - "fi;" \ - "run sataboot;" \ - "fi;" \ - "fi;" \ + "run storagebootcmd;" \ + "fi;\0" \ + "trybootsmz=if run loadscript; then " \ + "run bootscript;" \ "fi;" \ - "run nandboot\0" + "run setboottypem;" \ + "run trybootk;" \ + "run setboottypez;" \ + "run trybootk;\0" #define CONFIG_BOOTCOMMAND \ - "run setboottypem; run boot" + "run setupmmcboot;" \ + "mmc dev ${storagedev};" \ + "if mmc rescan; then " \ + "run trybootsmz;" \ + "fi;" \ + "run setupusbboot;" \ + "if usb start; then "\ + "if run loadscript; then " \ + "run bootscript;" \ + "fi;" \ + "fi;" \ + "run setupsataboot;" \ + "if sata init; then " \ + "run trybootsmz;" \ + "fi;" \ + "run setupnandboot;" \ + "run nandboot;" /* SPI */ #define CONFIG_SPI -- cgit From cc67f4a63ff3c6ed0b8fab35ce4af6e683296e47 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:42 +0200 Subject: arm: mx6: cm-fx6: change dtb node for ethaddr When passing eth address to Linux via dtb, the "local-mac-address" property should be set for "/soc/aips-bus@02100000/ethernet@02188000", not "/fec". Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 84e36439fa..5ddf8c6688 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -464,8 +464,9 @@ int ft_board_setup(void *blob, bd_t *bd) /* MAC addr */ if (eth_getenv_enetaddr("ethaddr", enetaddr)) { - fdt_find_and_setprop(blob, "/fec", "local-mac-address", - enetaddr, 6, 1); + fdt_find_and_setprop(blob, + "/soc/aips-bus@02100000/ethernet@02188000", + "local-mac-address", enetaddr, 6, 1); } return 0; -- cgit From e7a2447ba2d8483b7d029e77c59b0ee26eeabe88 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:43 +0200 Subject: compulab: eeprom: allow reading mac address from multiple eeproms Implement the option to select the eeprom i2c bus when reading mac address. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Cc: Ilya Ledvich Cc: Dmitry Lifshitz Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 2 +- board/compulab/cm_t335/cm_t335.c | 2 +- board/compulab/cm_t35/cm_t35.c | 2 +- board/compulab/cm_t3517/cm_t3517.c | 2 +- board/compulab/cm_t54/cm_t54.c | 2 +- board/compulab/common/eeprom.c | 20 +++++++++++++------- board/compulab/common/eeprom.h | 4 ++-- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 5ddf8c6688..32f4434b65 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -354,7 +354,7 @@ static int handle_mac_address(void) if (rc) return 0; - rc = cl_eeprom_read_mac_addr(enetaddr); + rc = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); if (rc) return rc; diff --git a/board/compulab/cm_t335/cm_t335.c b/board/compulab/cm_t335/cm_t335.c index 9583149bed..592ef3d30f 100644 --- a/board/compulab/cm_t335/cm_t335.c +++ b/board/compulab/cm_t335/cm_t335.c @@ -110,7 +110,7 @@ static int handle_mac_address(void) if (rv) return 0; - rv = cl_eeprom_read_mac_addr(enetaddr); + rv = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); if (rv) get_efuse_mac_addr(enetaddr); diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c index 43463d5b47..9a3b2ee72f 100644 --- a/board/compulab/cm_t35/cm_t35.c +++ b/board/compulab/cm_t35/cm_t35.c @@ -429,7 +429,7 @@ static int handle_mac_address(void) if (rc) return 0; - rc = cl_eeprom_read_mac_addr(enetaddr); + rc = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); if (rc) return rc; diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c index cac1ad9ef1..624cf4c034 100644 --- a/board/compulab/cm_t3517/cm_t3517.c +++ b/board/compulab/cm_t3517/cm_t3517.c @@ -163,7 +163,7 @@ static int cm_t3517_handle_mac_address(void) if (ret) return 0; - ret = cl_eeprom_read_mac_addr(enetaddr); + ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); if (ret) { ret = am3517_get_efuse_enetaddr(enetaddr); if (ret) diff --git a/board/compulab/cm_t54/cm_t54.c b/board/compulab/cm_t54/cm_t54.c index 2c2530ab3f..fdea909ff7 100644 --- a/board/compulab/cm_t54/cm_t54.c +++ b/board/compulab/cm_t54/cm_t54.c @@ -165,7 +165,7 @@ static int handle_mac_address(void) if (ret) return 0; - ret = cl_eeprom_read_mac_addr(enetaddr); + ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); if (ret || !is_valid_ether_addr(enetaddr)) generate_mac_addr(enetaddr); diff --git a/board/compulab/common/eeprom.c b/board/compulab/common/eeprom.c index a45e7be11f..77bcea44b4 100644 --- a/board/compulab/common/eeprom.c +++ b/board/compulab/common/eeprom.c @@ -31,6 +31,7 @@ #define LAYOUT_INVALID 0 #define LAYOUT_LEGACY 0xff +static int cl_eeprom_bus; static int cl_eeprom_layout; /* Implicitly LAYOUT_INVALID */ static int cl_eeprom_read(uint offset, uchar *buf, int len) @@ -38,7 +39,7 @@ static int cl_eeprom_read(uint offset, uchar *buf, int len) int res; unsigned int current_i2c_bus = i2c_get_bus_num(); - res = i2c_set_bus_num(CONFIG_SYS_I2C_EEPROM_BUS); + res = i2c_set_bus_num(cl_eeprom_bus); if (res < 0) return res; @@ -50,13 +51,18 @@ static int cl_eeprom_read(uint offset, uchar *buf, int len) return res; } -static int cl_eeprom_setup_layout(void) +static int cl_eeprom_setup(uint eeprom_bus) { int res; - if (cl_eeprom_layout != LAYOUT_INVALID) + /* + * We know the setup was already done when the layout is set to a valid + * value and we're using the same bus as before. + */ + if (cl_eeprom_layout != LAYOUT_INVALID && eeprom_bus == cl_eeprom_bus) return 0; + cl_eeprom_bus = eeprom_bus; res = cl_eeprom_read(EEPROM_LAYOUT_VER_OFFSET, (uchar *)&cl_eeprom_layout, 1); if (res) { @@ -77,7 +83,7 @@ void get_board_serial(struct tag_serialnr *serialnr) memset(serialnr, 0, sizeof(*serialnr)); - if (cl_eeprom_setup_layout()) + if (cl_eeprom_setup(CONFIG_SYS_I2C_EEPROM_BUS)) return; offset = (cl_eeprom_layout != LAYOUT_LEGACY) ? @@ -96,11 +102,11 @@ void get_board_serial(struct tag_serialnr *serialnr) * Routine: cl_eeprom_read_mac_addr * Description: read mac address and store it in buf. */ -int cl_eeprom_read_mac_addr(uchar *buf) +int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus) { uint offset; - if (cl_eeprom_setup_layout()) + if (cl_eeprom_setup(eeprom_bus)) return 0; offset = (cl_eeprom_layout != LAYOUT_LEGACY) ? @@ -123,7 +129,7 @@ u32 cl_eeprom_get_board_rev(void) if (board_rev) return board_rev; - if (cl_eeprom_setup_layout()) + if (cl_eeprom_setup(CONFIG_SYS_I2C_EEPROM_BUS)) return 0; if (cl_eeprom_layout != LAYOUT_LEGACY) diff --git a/board/compulab/common/eeprom.h b/board/compulab/common/eeprom.h index 85d5bf03d6..50c6b0226f 100644 --- a/board/compulab/common/eeprom.h +++ b/board/compulab/common/eeprom.h @@ -11,10 +11,10 @@ #define _EEPROM_ #ifdef CONFIG_SYS_I2C -int cl_eeprom_read_mac_addr(uchar *buf); +int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus); u32 cl_eeprom_get_board_rev(void); #else -static inline int cl_eeprom_read_mac_addr(uchar *buf) +static inline int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus) { return 1; } -- cgit From eab29802d6211aeb9cd521a51d22a43c8fb4f94d Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:44 +0200 Subject: arm: mx6: cm-fx6: pass 2nd nic mac addr to Linux Obtain 2nd NIC MAC address from baseboard EEPROM and pass it to Linux. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 32f4434b65..eb18dfc44c 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -345,32 +345,36 @@ static iomux_v3_cfg_t const enet_pads[] = { MUX_PAD_CTRL(ENET_PAD_CTRL)), }; -static int handle_mac_address(void) +static int handle_mac_address(char *env_var, uint eeprom_bus) { unsigned char enetaddr[6]; int rc; - rc = eth_getenv_enetaddr("ethaddr", enetaddr); + rc = eth_getenv_enetaddr(env_var, enetaddr); if (rc) return 0; - rc = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS); + rc = cl_eeprom_read_mac_addr(enetaddr, eeprom_bus); if (rc) return rc; if (!is_valid_ether_addr(enetaddr)) return -1; - return eth_setenv_enetaddr("ethaddr", enetaddr); + return eth_setenv_enetaddr(env_var, enetaddr); } +#define SB_FX6_I2C_EEPROM_BUS 0 +#define NO_MAC_ADDR "No MAC address found for %s\n" int board_eth_init(bd_t *bis) { int err; - err = handle_mac_address(); - if (err) - puts("No MAC address found\n"); + if (handle_mac_address("ethaddr", CONFIG_SYS_I2C_EEPROM_BUS)) + printf(NO_MAC_ADDR, "primary NIC"); + + if (handle_mac_address("eth1addr", SB_FX6_I2C_EEPROM_BUS)) + printf(NO_MAC_ADDR, "secondary NIC"); SETUP_IOMUX_PADS(enet_pads); /* phy reset */ @@ -469,6 +473,11 @@ int ft_board_setup(void *blob, bd_t *bd) "local-mac-address", enetaddr, 6, 1); } + if (eth_getenv_enetaddr("eth1addr", enetaddr)) { + fdt_find_and_setprop(blob, "/eth@pcie", "local-mac-address", + enetaddr, 6, 1); + } + return 0; } #endif -- cgit From 9fbdcf018e5f4bf78126c2f6df42d6f5bf91c946 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:45 +0200 Subject: arm: mx6: cm-fx6: increase size of malloc area Increase size of malloc area to make room for framebuffer and other such big allocations. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg --- include/configs/cm_fx6.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index d79c83bf2d..a2e42c4592 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -276,7 +276,7 @@ /* misc */ #define CONFIG_SYS_GENERIC_BOARD #define CONFIG_STACKSIZE (128 * 1024) -#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024) #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 800 /* 400 KB */ #define CONFIG_OF_BOARD_SETUP -- cgit From deb94d6192e7507d743aefa69a86954c0c26be82 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:46 +0200 Subject: arm: mx6: cm-fx6: add hdmi console support Add support for hdmi console. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 51 ++++++++++++++++++++++++++++++++++++++++++ include/configs/cm_fx6.h | 15 +++++++++++++ 2 files changed, 66 insertions(+) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index eb18dfc44c..b31e1f59b6 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -18,8 +18,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -28,6 +30,53 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_IMX_HDMI +static void cm_fx6_enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +struct display_info_t const displays[] = { + { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = cm_fx6_enable_hdmi, + .mode = { + .name = "HDMI", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 40385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED, + } + }, +}; +size_t display_count = ARRAY_SIZE(displays); + +static void cm_fx6_setup_display(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + int reg; + + enable_ipu_clock(); + imx_setup_hdmi(); + reg = __raw_readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK; + writel(reg, &mxc_ccm->CCGR3); +} +#else +static inline void cm_fx6_setup_display(void) {} +#endif /* CONFIG_VIDEO_IPUV3 */ + #ifdef CONFIG_DWC_AHSATA static int cm_fx6_issd_gpios[] = { /* The order of the GPIOs in the array is important! */ @@ -516,6 +565,8 @@ int board_init(void) if (ret) printf("Warning: I2C setup failed: %d\n", ret); + cm_fx6_setup_display(); + return 0; } diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index a2e42c4592..a9f33a9e34 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -103,6 +103,9 @@ #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_EXTRA_ENV_SETTINGS \ + "stdout=serial,vga\0" \ + "stderr=serial,vga\0" \ + "panel=HDMI\0" \ "autoload=no\0" \ "kernel=uImage-cm-fx6\0" \ "script=boot.scr\0" \ @@ -291,4 +294,16 @@ #define CONFIG_SYS_SPI_U_BOOT_OFFS (64 * 1024) #define CONFIG_SPL_SPI_LOAD +/* Display */ +#define CONFIG_VIDEO +#define CONFIG_VIDEO_IPUV3 +#define CONFIG_IPUV3_CLK 260000000 +#define CONFIG_IMX_HDMI +#define CONFIG_IMX_VIDEO_SKIP +#define CONFIG_CFB_CONSOLE +#define CONFIG_VGA_AS_SINGLE_DEVICE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +#define CONFIG_CONSOLE_MUX +#define CONFIG_VIDEO_SW_CURSOR + #endif /* __CONFIG_CM_FX6_H */ -- cgit From 8015dde87876dc3f5cb600186d7ad30744a1b7dc Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:47 +0200 Subject: arm: mx6: cm-fx6: display compulab logo Add compulab logo and display it on boot. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- include/configs/cm_fx6.h | 3 +++ tools/logos/compulab.bmp | Bin 0 -> 31810 bytes 2 files changed, 3 insertions(+) create mode 100644 tools/logos/compulab.bmp diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index a9f33a9e34..5d0d303dfc 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -306,4 +306,7 @@ #define CONFIG_CONSOLE_MUX #define CONFIG_VIDEO_SW_CURSOR +#define CONFIG_VIDEO_LOGO +#define CONFIG_VIDEO_BMP_LOGO + #endif /* __CONFIG_CM_FX6_H */ diff --git a/tools/logos/compulab.bmp b/tools/logos/compulab.bmp new file mode 100644 index 0000000000..df5435cb59 Binary files /dev/null and b/tools/logos/compulab.bmp differ -- cgit From 1c2e529243b126a15b604cadd96e5dff3ce225de Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:48 +0200 Subject: arm: mx6: cm-fx6: add support for usb keyboard Add support for usb keyboard for cm_fx6. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- include/configs/cm_fx6.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 5d0d303dfc..49b1b0023e 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -103,6 +103,7 @@ #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_EXTRA_ENV_SETTINGS \ + "stdin=serial,usbkbd\0" \ "stdout=serial,vga\0" \ "stderr=serial,vga\0" \ "panel=HDMI\0" \ @@ -193,6 +194,8 @@ "run setupnandboot;" \ "run nandboot;" +#define CONFIG_PREBOOT "usb start" + /* SPI */ #define CONFIG_SPI #define CONFIG_MXC_SPI @@ -241,6 +244,9 @@ #define CONFIG_MXC_USB_FLAGS 0 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET /* For OTG port */ +#define CONFIG_USB_KEYBOARD +#define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP +#define CONFIG_SYS_STDIO_DEREGISTER /* I2C */ #define CONFIG_CMD_I2C -- cgit From 6947e3f56f265c9bb1f3832c74630adf6286987d Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:49 +0200 Subject: compulab: splash: use errno values Use errno values to improve return reporting. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/common/splash.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/board/compulab/common/splash.c b/board/compulab/common/splash.c index 49ed49b81e..33b2f9f570 100644 --- a/board/compulab/common/splash.c +++ b/board/compulab/common/splash.c @@ -8,6 +8,7 @@ #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -44,12 +45,12 @@ splash_address_too_high: printf("Error: splashimage address too high. Data overwrites U-Boot " "and/or placed beyond DRAM boundaries.\n"); - return -1; + return -EFAULT; } #else static inline int splash_load_from_nand(u32 bmp_load_addr, int nand_offset) { - return -1; + return -ENOSYS; } #endif /* CONFIG_CMD_NAND */ @@ -60,12 +61,12 @@ int cl_splash_screen_prepare(int nand_offset) env_splashimage_value = getenv("splashimage"); if (env_splashimage_value == NULL) - return -1; + return -ENOENT; bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16); if (bmp_load_addr == 0) { printf("Error: bad splashimage address specified\n"); - return -1; + return -EFAULT; } return splash_load_from_nand(bmp_load_addr, nand_offset); -- cgit From 7be4cd2cc54fc494dd550b9893e784bf1f9a31b5 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:50 +0200 Subject: compulab: splash: refactor splash.c Move storage device specific code into its own function instead of calling it directly from an otherwise storage device independent function (cl_splash_screen_prepare). This is a preparation for supporting multiple splash locations. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/common/common.h | 4 ++-- board/compulab/common/splash.c | 43 +++++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/board/compulab/common/common.h b/board/compulab/common/common.h index 68ffb111dc..80753b4b73 100644 --- a/board/compulab/common/common.h +++ b/board/compulab/common/common.h @@ -25,9 +25,9 @@ static inline void cl_usb_hub_deinit(int gpio) {} #endif /* CONFIG_CMD_USB */ #ifdef CONFIG_SPLASH_SCREEN -int cl_splash_screen_prepare(int nand_offset); +int cl_splash_screen_prepare(int offset); #else /* !CONFIG_SPLASH_SCREEN */ -static inline int cl_splash_screen_prepare(int nand_offset) +static inline int cl_splash_screen_prepare(int offset) { return -ENOSYS; } diff --git a/board/compulab/common/splash.c b/board/compulab/common/splash.c index 33b2f9f570..09a075568c 100644 --- a/board/compulab/common/splash.c +++ b/board/compulab/common/splash.c @@ -10,11 +10,32 @@ #include #include #include +#include "common.h" DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_CMD_NAND -static int splash_load_from_nand(u32 bmp_load_addr, int nand_offset) +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + return nand_read_skip_bad(&nand_info[nand_curr_device], offset, + &read_size, NULL, + nand_info[nand_curr_device].size, + (u_char *)bmp_load_addr); +} +#else +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: nand support not available\n", __func__); + return -ENOSYS; +} +#endif + +static int splash_storage_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + return splash_nand_read(bmp_load_addr, offset, read_size); +} + +static int splash_load_raw(u32 bmp_load_addr, int offset) { struct bmp_header *bmp_hdr; int res; @@ -23,10 +44,7 @@ static int splash_load_from_nand(u32 bmp_load_addr, int nand_offset) if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) goto splash_address_too_high; - res = nand_read_skip_bad(&nand_info[nand_curr_device], - nand_offset, &bmp_header_size, - NULL, nand_info[nand_curr_device].size, - (u_char *)bmp_load_addr); + res = splash_storage_read(bmp_load_addr, offset, bmp_header_size); if (res < 0) return res; @@ -36,10 +54,7 @@ static int splash_load_from_nand(u32 bmp_load_addr, int nand_offset) if (bmp_load_addr + bmp_size >= gd->start_addr_sp) goto splash_address_too_high; - return nand_read_skip_bad(&nand_info[nand_curr_device], - nand_offset, &bmp_size, - NULL, nand_info[nand_curr_device].size, - (u_char *)bmp_load_addr); + return splash_storage_read(bmp_load_addr, offset, bmp_size); splash_address_too_high: printf("Error: splashimage address too high. Data overwrites U-Boot " @@ -47,14 +62,8 @@ splash_address_too_high: return -EFAULT; } -#else -static inline int splash_load_from_nand(u32 bmp_load_addr, int nand_offset) -{ - return -ENOSYS; -} -#endif /* CONFIG_CMD_NAND */ -int cl_splash_screen_prepare(int nand_offset) +int cl_splash_screen_prepare(int offset) { char *env_splashimage_value; u32 bmp_load_addr; @@ -69,5 +78,5 @@ int cl_splash_screen_prepare(int nand_offset) return -EFAULT; } - return splash_load_from_nand(bmp_load_addr, nand_offset); + return splash_load_raw(bmp_load_addr, offset); } -- cgit From fd29dd554af6e88ff6d794886e5ab7ba176ace17 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:51 +0200 Subject: compulab: splash: support multiple splash sources Define a generic way for boards to define splash image locations: - introduce struct splash_location - introduce enum splash_storage - update cl_splash_screen_prepare() to take an array of above struct and select the appropriate one based on the splashsource environment variable (if it is not defined- use the first splash location as default). cm-t35 is updated to work with the new interface. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Igor Grinberg Acked-by: Igor Grinberg --- board/compulab/cm_t35/cm_t35.c | 11 +++++-- board/compulab/common/common.h | 15 +++++++-- board/compulab/common/splash.c | 70 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c index 9a3b2ee72f..8143c05353 100644 --- a/board/compulab/cm_t35/cm_t35.c +++ b/board/compulab/cm_t35/cm_t35.c @@ -59,11 +59,18 @@ void get_board_mem_timings(struct board_sdrc_timings *timings) } #endif -#define CM_T35_SPLASH_NAND_OFFSET 0x100000 +struct splash_location splash_locations[] = { + { + .name = "nand", + .storage = SPLASH_STORAGE_NAND, + .offset = 0x100000, + }, +}; int splash_screen_prepare(void) { - return cl_splash_screen_prepare(CM_T35_SPLASH_NAND_OFFSET); + return cl_splash_screen_prepare(splash_locations, + ARRAY_SIZE(splash_locations)); } /* diff --git a/board/compulab/common/common.h b/board/compulab/common/common.h index 80753b4b73..09b4de6fe3 100644 --- a/board/compulab/common/common.h +++ b/board/compulab/common/common.h @@ -24,10 +24,21 @@ static inline int cl_usb_hub_init(int gpio, const char *label) static inline void cl_usb_hub_deinit(int gpio) {} #endif /* CONFIG_CMD_USB */ +enum splash_storage { + SPLASH_STORAGE_NAND, +}; + +struct splash_location { + char *name; + enum splash_storage storage; + u32 offset; /* offset from start of storage */ +}; + #ifdef CONFIG_SPLASH_SCREEN -int cl_splash_screen_prepare(int offset); +int cl_splash_screen_prepare(struct splash_location *locations, uint size); #else /* !CONFIG_SPLASH_SCREEN */ -static inline int cl_splash_screen_prepare(int offset) +static inline int cl_splash_screen_prepare(struct splash_location *locations, + uint size) { return -ENOSYS; } diff --git a/board/compulab/common/splash.c b/board/compulab/common/splash.c index 09a075568c..f230d6db42 100644 --- a/board/compulab/common/splash.c +++ b/board/compulab/common/splash.c @@ -30,12 +30,26 @@ static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) } #endif -static int splash_storage_read(u32 bmp_load_addr, int offset, size_t read_size) +static int splash_storage_read(struct splash_location *location, + u32 bmp_load_addr, size_t read_size) { - return splash_nand_read(bmp_load_addr, offset, read_size); + u32 offset; + + if (!location) + return -EINVAL; + + offset = location->offset; + switch (location->storage) { + case SPLASH_STORAGE_NAND: + return splash_nand_read(bmp_load_addr, offset, read_size); + default: + printf("Unknown splash location\n"); + } + + return -EINVAL; } -static int splash_load_raw(u32 bmp_load_addr, int offset) +static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr) { struct bmp_header *bmp_hdr; int res; @@ -44,7 +58,7 @@ static int splash_load_raw(u32 bmp_load_addr, int offset) if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) goto splash_address_too_high; - res = splash_storage_read(bmp_load_addr, offset, bmp_header_size); + res = splash_storage_read(location, bmp_load_addr, bmp_header_size); if (res < 0) return res; @@ -54,7 +68,7 @@ static int splash_load_raw(u32 bmp_load_addr, int offset) if (bmp_load_addr + bmp_size >= gd->start_addr_sp) goto splash_address_too_high; - return splash_storage_read(bmp_load_addr, offset, bmp_size); + return splash_storage_read(location, bmp_load_addr, bmp_size); splash_address_too_high: printf("Error: splashimage address too high. Data overwrites U-Boot " @@ -63,8 +77,46 @@ splash_address_too_high: return -EFAULT; } -int cl_splash_screen_prepare(int offset) +/** + * select_splash_location - return the splash location based on board support + * and env variable "splashsource". + * + * @locations: An array of supported splash locations. + * @size: Size of splash_locations array. + * + * @return: If a null set of splash locations is given, or + * splashsource env variable is set to unsupported value + * return NULL. + * If splashsource env variable is not defined + * return the first entry in splash_locations as default. + * If splashsource env variable contains a supported value + * return the location selected by splashsource. + */ +static struct splash_location *select_splash_location( + struct splash_location *locations, uint size) +{ + int i; + char *env_splashsource; + + if (!locations || size == 0) + return NULL; + + env_splashsource = getenv("splashsource"); + if (env_splashsource == NULL) + return &locations[0]; + + for (i = 0; i < size; i++) { + if (!strcmp(locations[i].name, env_splashsource)) + return &locations[i]; + } + + printf("splashsource env variable set to unsupported value\n"); + return NULL; +} + +int cl_splash_screen_prepare(struct splash_location *locations, uint size) { + struct splash_location *splash_location; char *env_splashimage_value; u32 bmp_load_addr; @@ -78,5 +130,9 @@ int cl_splash_screen_prepare(int offset) return -EFAULT; } - return splash_load_raw(bmp_load_addr, offset); + splash_location = select_splash_location(locations, size); + if (!splash_location) + return -EINVAL; + + return splash_load_raw(splash_location, bmp_load_addr); } -- cgit From 7e8d7f2ac2035efa04382bbeede1b4fbe1c66987 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:52 +0200 Subject: compulab: splash: support loading splash from sf Add support for loading splash from sf. Signed-off-by: Nikita Kiryanov [grinberg@compulab.co.il: staticize the sf global variable] Signed-off-by: Igor Grinberg Cc: Stefano Babic Cc: Igor Grinberg --- board/compulab/common/common.h | 1 + board/compulab/common/splash.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/board/compulab/common/common.h b/board/compulab/common/common.h index 09b4de6fe3..b992965457 100644 --- a/board/compulab/common/common.h +++ b/board/compulab/common/common.h @@ -26,6 +26,7 @@ static inline void cl_usb_hub_deinit(int gpio) {} enum splash_storage { SPLASH_STORAGE_NAND, + SPLASH_STORAGE_SF, }; struct splash_location { diff --git a/board/compulab/common/splash.c b/board/compulab/common/splash.c index f230d6db42..16c315ca5a 100644 --- a/board/compulab/common/splash.c +++ b/board/compulab/common/splash.c @@ -9,11 +9,36 @@ #include #include #include +#include +#include #include #include "common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SPI_FLASH +static struct spi_flash *sf; +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + if (!sf) { + sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, + CONFIG_SF_DEFAULT_CS, + CONFIG_SF_DEFAULT_SPEED, + CONFIG_SF_DEFAULT_MODE); + if (!sf) + return -ENODEV; + } + + return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr); +} +#else +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: sf support not available\n", __func__); + return -ENOSYS; +} +#endif + #ifdef CONFIG_CMD_NAND static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) { @@ -42,6 +67,8 @@ static int splash_storage_read(struct splash_location *location, switch (location->storage) { case SPLASH_STORAGE_NAND: return splash_nand_read(bmp_load_addr, offset, read_size); + case SPLASH_STORAGE_SF: + return splash_sf_read(bmp_load_addr, offset, read_size); default: printf("Unknown splash location\n"); } -- cgit From 3a236a356397449bf3ad1e72221053b5a3d87b80 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:53 +0200 Subject: arm: mx6: cm-fx6: add splash screen support Add support for splash screen. The splash screen is loaded from the SPI flash and is displayed on the HDMI display. Signed-off-by: Nikita Kiryanov [grinberg@compulab.co.il: minor code and commit message updates] Signed-off-by: Igor Grinberg Cc: Stefano Babic Cc: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 17 +++++++++++++++++ include/configs/cm_fx6.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index b31e1f59b6..b5c3ea19d3 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -27,9 +27,26 @@ #include #include "common.h" #include "../common/eeprom.h" +#include "../common/common.h" DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SPLASH_SCREEN +static struct splash_location cm_fx6_splash_locations[] = { + { + .name = "sf", + .storage = SPLASH_STORAGE_SF, + .offset = 0x100000, + }, +}; + +int splash_screen_prepare(void) +{ + return cl_splash_screen_prepare(cm_fx6_splash_locations, + ARRAY_SIZE(cm_fx6_splash_locations)); +} +#endif + #ifdef CONFIG_IMX_HDMI static void cm_fx6_enable_hdmi(struct display_info_t const *dev) { diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 49b1b0023e..b92ba976e9 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -312,6 +312,10 @@ #define CONFIG_CONSOLE_MUX #define CONFIG_VIDEO_SW_CURSOR +#define CONFIG_SPLASH_SCREEN +#define CONFIG_CMD_BMP +#define CONFIG_VIDEO_BMP_RLE8 + #define CONFIG_VIDEO_LOGO #define CONFIG_VIDEO_BMP_LOGO -- cgit From f82eb2fa5df86b7180ea355a3cb98482f7c27269 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 14 Jan 2015 10:42:54 +0200 Subject: common: convert compulab splash load code to common code Move board/compulab/common/splash.c code to common/splash_source.c to make it available for everybody. This move renames cl_splash_screen_prepare() to splash_source_load(), and the compilation of this code is conditional on CONFIG_SPLASH_SOURCE. splash_source features: * Provide a standardized way for declaring board specific splash screen locations * Provide existing routines for auto loading the splash image from the locations as declared by the board * Introduce the "splashsource" environment variable, which makes it possible to select the splash image source. cm-t35 and cm-fx6 are updated to use the modified version. Signed-off-by: Nikita Kiryanov Cc: Stefano Babic Cc: Tom Rini Cc: Igor Grinberg Cc: Anatolij Gustschin Reviewed-by: Tom Rini Acked-by: Igor Grinberg --- board/compulab/cm_fx6/cm_fx6.c | 5 +- board/compulab/cm_t35/cm_t35.c | 5 +- board/compulab/common/Makefile | 1 - board/compulab/common/common.h | 21 ----- board/compulab/common/splash.c | 165 -------------------------------------- common/Makefile | 1 + common/splash_source.c | 176 +++++++++++++++++++++++++++++++++++++++++ doc/README.splashprepare | 13 +++ include/configs/cm_fx6.h | 1 + include/configs/cm_t35.h | 1 + include/splash.h | 11 +++ 11 files changed, 209 insertions(+), 191 deletions(-) delete mode 100644 board/compulab/common/splash.c create mode 100644 common/splash_source.c diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index b5c3ea19d3..ae6945ba9c 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,8 @@ static struct splash_location cm_fx6_splash_locations[] = { int splash_screen_prepare(void) { - return cl_splash_screen_prepare(cm_fx6_splash_locations, - ARRAY_SIZE(cm_fx6_splash_locations)); + return splash_source_load(cm_fx6_splash_locations, + ARRAY_SIZE(cm_fx6_splash_locations)); } #endif diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c index 8143c05353..c4ea8ea875 100644 --- a/board/compulab/cm_t35/cm_t35.c +++ b/board/compulab/cm_t35/cm_t35.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -69,8 +70,8 @@ struct splash_location splash_locations[] = { int splash_screen_prepare(void) { - return cl_splash_screen_prepare(splash_locations, - ARRAY_SIZE(splash_locations)); + return splash_source_load(splash_locations, + ARRAY_SIZE(splash_locations)); } /* diff --git a/board/compulab/common/Makefile b/board/compulab/common/Makefile index dbf0009652..286f32731d 100644 --- a/board/compulab/common/Makefile +++ b/board/compulab/common/Makefile @@ -9,5 +9,4 @@ obj-y += common.o obj-$(CONFIG_SYS_I2C) += eeprom.o obj-$(CONFIG_LCD) += omap3_display.o -obj-$(CONFIG_SPLASH_SCREEN) += splash.o obj-$(CONFIG_SMC911X) += omap3_smc911x.o diff --git a/board/compulab/common/common.h b/board/compulab/common/common.h index b992965457..8f38b79fb0 100644 --- a/board/compulab/common/common.h +++ b/board/compulab/common/common.h @@ -24,27 +24,6 @@ static inline int cl_usb_hub_init(int gpio, const char *label) static inline void cl_usb_hub_deinit(int gpio) {} #endif /* CONFIG_CMD_USB */ -enum splash_storage { - SPLASH_STORAGE_NAND, - SPLASH_STORAGE_SF, -}; - -struct splash_location { - char *name; - enum splash_storage storage; - u32 offset; /* offset from start of storage */ -}; - -#ifdef CONFIG_SPLASH_SCREEN -int cl_splash_screen_prepare(struct splash_location *locations, uint size); -#else /* !CONFIG_SPLASH_SCREEN */ -static inline int cl_splash_screen_prepare(struct splash_location *locations, - uint size) -{ - return -ENOSYS; -} -#endif /* CONFIG_SPLASH_SCREEN */ - #ifdef CONFIG_SMC911X int cl_omap3_smc911x_init(int id, int cs, u32 base_addr, int (*reset)(int), int rst_gpio); diff --git a/board/compulab/common/splash.c b/board/compulab/common/splash.c deleted file mode 100644 index 16c315ca5a..0000000000 --- a/board/compulab/common/splash.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * (C) Copyright 2014 CompuLab, Ltd. - * - * Authors: Igor Grinberg - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include "common.h" - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_SPI_FLASH -static struct spi_flash *sf; -static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) -{ - if (!sf) { - sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, - CONFIG_SF_DEFAULT_CS, - CONFIG_SF_DEFAULT_SPEED, - CONFIG_SF_DEFAULT_MODE); - if (!sf) - return -ENODEV; - } - - return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr); -} -#else -static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) -{ - debug("%s: sf support not available\n", __func__); - return -ENOSYS; -} -#endif - -#ifdef CONFIG_CMD_NAND -static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) -{ - return nand_read_skip_bad(&nand_info[nand_curr_device], offset, - &read_size, NULL, - nand_info[nand_curr_device].size, - (u_char *)bmp_load_addr); -} -#else -static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) -{ - debug("%s: nand support not available\n", __func__); - return -ENOSYS; -} -#endif - -static int splash_storage_read(struct splash_location *location, - u32 bmp_load_addr, size_t read_size) -{ - u32 offset; - - if (!location) - return -EINVAL; - - offset = location->offset; - switch (location->storage) { - case SPLASH_STORAGE_NAND: - return splash_nand_read(bmp_load_addr, offset, read_size); - case SPLASH_STORAGE_SF: - return splash_sf_read(bmp_load_addr, offset, read_size); - default: - printf("Unknown splash location\n"); - } - - return -EINVAL; -} - -static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr) -{ - struct bmp_header *bmp_hdr; - int res; - size_t bmp_size, bmp_header_size = sizeof(struct bmp_header); - - if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) - goto splash_address_too_high; - - res = splash_storage_read(location, bmp_load_addr, bmp_header_size); - if (res < 0) - return res; - - bmp_hdr = (struct bmp_header *)bmp_load_addr; - bmp_size = le32_to_cpu(bmp_hdr->file_size); - - if (bmp_load_addr + bmp_size >= gd->start_addr_sp) - goto splash_address_too_high; - - return splash_storage_read(location, bmp_load_addr, bmp_size); - -splash_address_too_high: - printf("Error: splashimage address too high. Data overwrites U-Boot " - "and/or placed beyond DRAM boundaries.\n"); - - return -EFAULT; -} - -/** - * select_splash_location - return the splash location based on board support - * and env variable "splashsource". - * - * @locations: An array of supported splash locations. - * @size: Size of splash_locations array. - * - * @return: If a null set of splash locations is given, or - * splashsource env variable is set to unsupported value - * return NULL. - * If splashsource env variable is not defined - * return the first entry in splash_locations as default. - * If splashsource env variable contains a supported value - * return the location selected by splashsource. - */ -static struct splash_location *select_splash_location( - struct splash_location *locations, uint size) -{ - int i; - char *env_splashsource; - - if (!locations || size == 0) - return NULL; - - env_splashsource = getenv("splashsource"); - if (env_splashsource == NULL) - return &locations[0]; - - for (i = 0; i < size; i++) { - if (!strcmp(locations[i].name, env_splashsource)) - return &locations[i]; - } - - printf("splashsource env variable set to unsupported value\n"); - return NULL; -} - -int cl_splash_screen_prepare(struct splash_location *locations, uint size) -{ - struct splash_location *splash_location; - char *env_splashimage_value; - u32 bmp_load_addr; - - env_splashimage_value = getenv("splashimage"); - if (env_splashimage_value == NULL) - return -ENOENT; - - bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16); - if (bmp_load_addr == 0) { - printf("Error: bad splashimage address specified\n"); - return -EFAULT; - } - - splash_location = select_splash_location(locations, size); - if (!splash_location) - return -EINVAL; - - return splash_load_raw(splash_location, bmp_load_addr); -} diff --git a/common/Makefile b/common/Makefile index 94554f2939..0f1416d1e8 100644 --- a/common/Makefile +++ b/common/Makefile @@ -196,6 +196,7 @@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o obj-$(CONFIG_I2C_EDID) += edid.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o +obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o obj-$(CONFIG_LCD) += lcd.o lcd_console.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o diff --git a/common/splash_source.c b/common/splash_source.c new file mode 100644 index 0000000000..d1bb5a4baf --- /dev/null +++ b/common/splash_source.c @@ -0,0 +1,176 @@ +/* + * (C) Copyright 2014 CompuLab, Ltd. + * + * Authors: Igor Grinberg + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_SPI_FLASH +static struct spi_flash *sf; +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + if (!sf) { + sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, + CONFIG_SF_DEFAULT_CS, + CONFIG_SF_DEFAULT_SPEED, + CONFIG_SF_DEFAULT_MODE); + if (!sf) + return -ENODEV; + } + + return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr); +} +#else +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: sf support not available\n", __func__); + return -ENOSYS; +} +#endif + +#ifdef CONFIG_CMD_NAND +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + return nand_read_skip_bad(&nand_info[nand_curr_device], offset, + &read_size, NULL, + nand_info[nand_curr_device].size, + (u_char *)bmp_load_addr); +} +#else +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: nand support not available\n", __func__); + return -ENOSYS; +} +#endif + +static int splash_storage_read(struct splash_location *location, + u32 bmp_load_addr, size_t read_size) +{ + u32 offset; + + if (!location) + return -EINVAL; + + offset = location->offset; + switch (location->storage) { + case SPLASH_STORAGE_NAND: + return splash_nand_read(bmp_load_addr, offset, read_size); + case SPLASH_STORAGE_SF: + return splash_sf_read(bmp_load_addr, offset, read_size); + default: + printf("Unknown splash location\n"); + } + + return -EINVAL; +} + +static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr) +{ + struct bmp_header *bmp_hdr; + int res; + size_t bmp_size, bmp_header_size = sizeof(struct bmp_header); + + if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) + goto splash_address_too_high; + + res = splash_storage_read(location, bmp_load_addr, bmp_header_size); + if (res < 0) + return res; + + bmp_hdr = (struct bmp_header *)bmp_load_addr; + bmp_size = le32_to_cpu(bmp_hdr->file_size); + + if (bmp_load_addr + bmp_size >= gd->start_addr_sp) + goto splash_address_too_high; + + return splash_storage_read(location, bmp_load_addr, bmp_size); + +splash_address_too_high: + printf("Error: splashimage address too high. Data overwrites U-Boot and/or placed beyond DRAM boundaries.\n"); + + return -EFAULT; +} + +/** + * select_splash_location - return the splash location based on board support + * and env variable "splashsource". + * + * @locations: An array of supported splash locations. + * @size: Size of splash_locations array. + * + * @return: If a null set of splash locations is given, or + * splashsource env variable is set to unsupported value + * return NULL. + * If splashsource env variable is not defined + * return the first entry in splash_locations as default. + * If splashsource env variable contains a supported value + * return the location selected by splashsource. + */ +static struct splash_location *select_splash_location( + struct splash_location *locations, uint size) +{ + int i; + char *env_splashsource; + + if (!locations || size == 0) + return NULL; + + env_splashsource = getenv("splashsource"); + if (env_splashsource == NULL) + return &locations[0]; + + for (i = 0; i < size; i++) { + if (!strcmp(locations[i].name, env_splashsource)) + return &locations[i]; + } + + printf("splashsource env variable set to unsupported value\n"); + return NULL; +} + +/** + * splash_source_load - load splash image from a supported location. + * + * Select a splash image location based on the value of splashsource environment + * variable and the board supported splash source locations, and load a + * splashimage to the address pointed to by splashimage environment variable. + * + * @locations: An array of supported splash locations. + * @size: Size of splash_locations array. + * + * @return: 0 on success, negative value on failure. + */ +int splash_source_load(struct splash_location *locations, uint size) +{ + struct splash_location *splash_location; + char *env_splashimage_value; + u32 bmp_load_addr; + + env_splashimage_value = getenv("splashimage"); + if (env_splashimage_value == NULL) + return -ENOENT; + + bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16); + if (bmp_load_addr == 0) { + printf("Error: bad splashimage address specified\n"); + return -EFAULT; + } + + splash_location = select_splash_location(locations, size); + if (!splash_location) + return -EINVAL; + + return splash_load_raw(splash_location, bmp_load_addr); +} diff --git a/doc/README.splashprepare b/doc/README.splashprepare index 61b4ec53ec..a0f0f3ca51 100644 --- a/doc/README.splashprepare +++ b/doc/README.splashprepare @@ -6,3 +6,16 @@ common/splash.c. It is called as part of the splash screen display sequence. It gives the board an opportunity to prepare the splash image data before it is processed and sent to the frame buffer by U-Boot. Define your own version to use this feature. + +CONFIG_SPLASH_SOURCE + +Use the splash_source.c library. This library provides facilities to declare +board specific splash image locations, routines for loading splash image from +supported locations, and a way of controlling the selected splash location +using the "splashsource" environment variable. + +splashsource works as follows: +- If splashsource is set to a supported location name as defined by board code, + use that splash location. +- If splashsource is undefined, use the first splash location as default. +- If splashsource is set to an unsupported value, do not load a splash screen. diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index b92ba976e9..1f64495055 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -313,6 +313,7 @@ #define CONFIG_VIDEO_SW_CURSOR #define CONFIG_SPLASH_SCREEN +#define CONFIG_SPLASH_SOURCE #define CONFIG_CMD_BMP #define CONFIG_VIDEO_BMP_RLE8 diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h index 9767512a5c..b2a9f35797 100644 --- a/include/configs/cm_t35.h +++ b/include/configs/cm_t35.h @@ -310,6 +310,7 @@ #define CONFIG_LCD #define CONFIG_SPLASH_SCREEN +#define CONFIG_SPLASH_SOURCE #define CONFIG_CMD_BMP #define CONFIG_BMP_16BPP #define CONFIG_SCF0403_LCD diff --git a/include/splash.h b/include/splash.h index 89ee7b22ec..a60e895423 100644 --- a/include/splash.h +++ b/include/splash.h @@ -22,7 +22,18 @@ #ifndef _SPLASH_H_ #define _SPLASH_H_ +enum splash_storage { + SPLASH_STORAGE_NAND, + SPLASH_STORAGE_SF, +}; +struct splash_location { + char *name; + enum splash_storage storage; + u32 offset; /* offset from start of storage */ +}; + +int splash_source_load(struct splash_location *locations, uint size); int splash_screen_prepare(void); #ifdef CONFIG_SPLASH_SCREEN_ALIGN -- cgit From b558af81281975d032c063ad228a400d8e619ad5 Mon Sep 17 00:00:00 2001 From: Lubomir Popov Date: Fri, 19 Dec 2014 17:34:31 +0200 Subject: ARM: OMAP5: DRA7xx: Add support for power rail grouping On the DRA72x (J6Eco) EVM one PMIC SMPS is powering three SoC core rails. This concept of using one SMPS to supply multiple core domains (in various, although limited combinations, per primary device use case) has now become common and is used by many customer J6/J6Eco designs; it is supported by a number of corresponding PMIC OTP versions. This patch implements correct operation of the core voltages scaling routine by ensuring that each SMPS that is supplying more than one domain shall be written only once, and with the highest voltage of those fused in the SoC (or of those defined in the corresponding header if fuse read is disabled or fails) for the power rails belonging to the group. The patch also replaces some PMIC-related magic numbers with the appropriate definitions. The default OPP_NOM voltages for the DRA7xx SoCs are updated as well, per the latest DMs. Signed-off-by: Lubomir Popov --- arch/arm/cpu/armv7/omap-common/clocks-common.c | 83 ++++++++++++++++++++++++-- arch/arm/cpu/armv7/omap5/hw_data.c | 43 +++++++------ arch/arm/include/asm/arch-omap5/clock.h | 20 ++++++- 3 files changed, 118 insertions(+), 28 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index 8e7411d437..03674e609f 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -437,12 +437,15 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) { u32 offset_code; u32 offset = volt_mv; +#ifndef CONFIG_DRA7XX int ret = 0; +#endif if (!volt_mv) return; pmic->pmic_bus_init(); +#ifndef CONFIG_DRA7XX /* See if we can first get the GPIO if needed */ if (pmic->gpio_en) ret = gpio_request(pmic->gpio, "PMIC_GPIO"); @@ -456,7 +459,7 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) /* Pull the GPIO low to select SET0 register, while we program SET1 */ if (pmic->gpio_en) gpio_direction_output(pmic->gpio, 0); - +#endif /* convert to uV for better accuracy in the calculations */ offset *= 1000; @@ -467,9 +470,10 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code)) printf("Scaling voltage failed for 0x%x\n", vcore_reg); - +#ifndef CONFIG_DRA7XX if (pmic->gpio_en) gpio_direction_output(pmic->gpio, 1); +#endif } static u32 optimize_vcore_voltage(struct volts const *v) @@ -505,13 +509,79 @@ static u32 optimize_vcore_voltage(struct volts const *v) } /* - * Setup the voltages for vdd_mpu, vdd_core, and vdd_iva - * We set the maximum voltages allowed here because Smart-Reflex is not - * enabled in bootloader. Voltage initialization in the kernel will set - * these to the nominal values after enabling Smart-Reflex + * Setup the voltages for the main SoC core power domains. + * We start with the maximum voltages allowed here, as set in the corresponding + * vcores_data struct, and then scale (usually down) to the fused values that + * are retrieved from the SoC. The scaling happens only if the efuse.reg fields + * are initialised. + * Rail grouping is supported for the DRA7xx SoCs only, therefore the code is + * compiled conditionally. Note that the new code writes the scaled (or zeroed) + * values back to the vcores_data struct for eventual reuse. Zero values mean + * that the corresponding rails are not controlled separately, and are not sent + * to the PMIC. */ void scale_vcores(struct vcores_data const *vcores) { +#if defined(CONFIG_DRA7XX) + int i; + struct volts *pv = (struct volts *)vcores; + struct volts *px; + + for (i=0; i<(sizeof(struct vcores_data)/sizeof(struct volts)); i++) { + debug("%d -> ", pv->value); + if (pv->value) { + /* Handle non-empty members only */ + pv->value = optimize_vcore_voltage(pv); + px = (struct volts *)vcores; + while (px < pv) { + /* + * Scan already handled non-empty members to see + * if we have a group and find the max voltage, + * which is set to the first occurance of the + * particular SMPS; the other group voltages are + * zeroed. + */ + if (px->value) { + if ((pv->pmic->i2c_slave_addr == + px->pmic->i2c_slave_addr) && + (pv->addr == px->addr)) { + /* Same PMIC, same SMPS */ + if (pv->value > px->value) + px->value = pv->value; + + pv->value = 0; + } + } + px++; + } + } + debug("%d\n", pv->value); + pv++; + } + + debug("cor: %d\n", vcores->core.value); + do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic); + debug("mpu: %d\n", vcores->mpu.value); + do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic); + /* Configure MPU ABB LDO after scale */ + abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2, + (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl, + (*prcm)->prm_abbldo_mpu_setup, + (*prcm)->prm_abbldo_mpu_ctrl, + (*prcm)->prm_irqstatus_mpu_2, + OMAP_ABB_MPU_TXDONE_MASK, + OMAP_ABB_FAST_OPP); + + /* The .mm member is not used for the DRA7xx */ + + debug("gpu: %d\n", vcores->gpu.value); + do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic); + debug("eve: %d\n", vcores->eve.value); + do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic); + debug("iva: %d\n", vcores->iva.value); + do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic); + /* Might need udelay(1000) here if debug is enabled to see all prints */ +#else u32 val; val = optimize_vcore_voltage(&vcores->core); @@ -540,6 +610,7 @@ void scale_vcores(struct vcores_data const *vcores) val = optimize_vcore_voltage(&vcores->iva); do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic); +#endif } static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode) diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c index 95f16866e6..b9734fea8f 100644 --- a/arch/arm/cpu/armv7/omap5/hw_data.c +++ b/arch/arm/cpu/armv7/omap5/hw_data.c @@ -320,6 +320,7 @@ struct pmic_data palmas = { .pmic_write = omap_vc_bypass_send_value, }; +/* The TPS659038 and TPS65917 are software-compatible, use common struct */ struct pmic_data tps659038 = { .base_offset = PALMAS_SMPS_BASE_VOLT_UV, .step = 10000, /* 10 mV represented in uV */ @@ -394,34 +395,38 @@ struct vcores_data dra752_volts = { }; struct vcores_data dra722_volts = { - .mpu.value = 1000, + .mpu.value = VDD_MPU_DRA72x, .mpu.efuse.reg = STD_FUSE_OPP_VMIN_MPU_NOM, - .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, - .mpu.addr = 0x23, + .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .mpu.addr = TPS65917_REG_ADDR_SMPS1, .mpu.pmic = &tps659038, - .eve.value = 1000, - .eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM, - .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS, - .eve.addr = 0x2f, - .eve.pmic = &tps659038, + .core.value = VDD_CORE_DRA72x, + .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM, + .core.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .core.addr = TPS65917_REG_ADDR_SMPS2, + .core.pmic = &tps659038, - .gpu.value = 1000, + /* + * The DSPEVE, GPU and IVA rails are usually grouped on DRA72x + * designs and powered by TPS65917 SMPS3, as on the J6Eco EVM. + */ + .gpu.value = VDD_GPU_DRA72x, .gpu.efuse.reg = STD_FUSE_OPP_VMIN_GPU_NOM, - .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, - .gpu.addr = 0x2f, + .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .gpu.addr = TPS65917_REG_ADDR_SMPS3, .gpu.pmic = &tps659038, - .core.value = 1000, - .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM, - .core.efuse.reg_bits = DRA752_EFUSE_REGBITS, - .core.addr = 0x27, - .core.pmic = &tps659038, + .eve.value = VDD_EVE_DRA72x, + .eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM, + .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .eve.addr = TPS65917_REG_ADDR_SMPS3, + .eve.pmic = &tps659038, - .iva.value = 1000, + .iva.value = VDD_IVA_DRA72x, .iva.efuse.reg = STD_FUSE_OPP_VMIN_IVA_NOM, - .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS, - .iva.addr = 0x2f, + .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .iva.addr = TPS65917_REG_ADDR_SMPS3, .iva.pmic = &tps659038, }; diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h index 0dc584b8ce..f8e5630bcb 100644 --- a/arch/arm/include/asm/arch-omap5/clock.h +++ b/arch/arm/include/asm/arch-omap5/clock.h @@ -236,13 +236,20 @@ #define VDD_MPU_ES2_LOW 880 #define VDD_MM_ES2_LOW 880 -/* TPS659038 Voltage settings in mv for OPP_NOMINAL */ -#define VDD_MPU_DRA752 1090 +/* DRA74x/75x voltage settings in mv for OPP_NOM per DM */ +#define VDD_MPU_DRA752 1100 #define VDD_EVE_DRA752 1060 #define VDD_GPU_DRA752 1060 -#define VDD_CORE_DRA752 1030 +#define VDD_CORE_DRA752 1060 #define VDD_IVA_DRA752 1060 +/* DRA72x voltage settings in mv for OPP_NOM per DM */ +#define VDD_MPU_DRA72x 1100 +#define VDD_EVE_DRA72x 1060 +#define VDD_GPU_DRA72x 1060 +#define VDD_CORE_DRA72x 1060 +#define VDD_IVA_DRA72x 1060 + /* Efuse register offsets for DRA7xx platform */ #define DRA752_EFUSE_BASE 0x4A002000 #define DRA752_EFUSE_REGBITS 16 @@ -284,6 +291,13 @@ #define TPS659038_REG_ADDR_SMPS7 0x33 #define TPS659038_REG_ADDR_SMPS8 0x37 +/* TPS65917 */ +#define TPS65917_I2C_SLAVE_ADDR 0x58 +#define TPS65917_REG_ADDR_SMPS1 0x23 +#define TPS65917_REG_ADDR_SMPS2 0x27 +#define TPS65917_REG_ADDR_SMPS3 0x2F + + /* TPS */ #define TPS62361_I2C_SLAVE_ADDR 0x60 #define TPS62361_REG_ADDR_SET0 0x0 -- cgit From 6e721bdb541e313528ffebb8c88532b41ae6df7c Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 13 Jan 2015 16:42:53 -0500 Subject: am335x_evm: Enable CONFIG_NAND_OMAP_GPMC_PREFETCH Signed-off-by: Tom Rini --- include/configs/am335x_evm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index 0004750518..d5e84ab46f 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -239,6 +239,7 @@ #define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) /* NAND: driver related configs */ #define CONFIG_NAND_OMAP_GPMC +#define CONFIG_NAND_OMAP_GPMC_PREFETCH #define CONFIG_NAND_OMAP_ELM #define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS #define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ -- cgit From 8dcd1b720e5c44bb4ca6f41181f3b937ae6e08c1 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 15 Jan 2015 10:26:36 +0100 Subject: Nokia RX-51: Use generic board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generic board with #define CONFIG_SYS_GENERIC_BOARD is working fine. There is no visible difference between legacy and generic board code. Signed-off-by: Pali Rohár Acked-by: Pavel Machek --- include/configs/nokia_rx51.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h index 982b689f3c..46fc91e5e1 100644 --- a/include/configs/nokia_rx51.h +++ b/include/configs/nokia_rx51.h @@ -28,6 +28,7 @@ #define CONFIG_OMAP3_RX51 /* working with RX51 */ #define CONFIG_SYS_L2CACHE_OFF /* pretend there is no L2 CACHE */ #define CONFIG_OMAP_COMMON +#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_MACH_TYPE MACH_TYPE_NOKIA_RX51 -- cgit From 168f594765cb4692362e6e552c272c034e7efd88 Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD \\(3ADEV\\)" Date: Fri, 16 Jan 2015 09:09:47 +0100 Subject: omap3: enable GP9 timer and UART2 These are needed for the upcoming Cairo board support. Signed-off-by: Albert ARIBAUD (3ADEV) --- arch/arm/cpu/armv7/omap3/clock.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c index 529ad9a942..006969e780 100644 --- a/arch/arm/cpu/armv7/omap3/clock.c +++ b/arch/arm/cpu/armv7/omap3/clock.c @@ -732,11 +732,20 @@ void per_clocks_enable(void) setbits_le32(&prcm_base->iclken_per, 0x08); /* ICKen GPT2 */ setbits_le32(&prcm_base->fclken_per, 0x08); /* FCKen GPT2 */ + /* Enable GP9 timer. */ + setbits_le32(&prcm_base->clksel_per, 0x80); /* GPT9 = 32kHz clk */ + setbits_le32(&prcm_base->iclken_per, 0x400); /* ICKen GPT9 */ + setbits_le32(&prcm_base->fclken_per, 0x400); /* FCKen GPT9 */ + #ifdef CONFIG_SYS_NS16550 /* Enable UART1 clocks */ setbits_le32(&prcm_base->fclken1_core, 0x00002000); setbits_le32(&prcm_base->iclken1_core, 0x00002000); + /* Enable UART2 clocks */ + setbits_le32(&prcm_base->fclken1_core, 0x00004000); + setbits_le32(&prcm_base->iclken1_core, 0x00004000); + /* UART 3 Clocks */ setbits_le32(&prcm_base->fclken_per, 0x00000800); setbits_le32(&prcm_base->iclken_per, 0x00000800); -- cgit From 03843da5d542b4516666434361c3a2211aa180ed Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD \\(3ADEV\\)" Date: Fri, 16 Jan 2015 09:09:48 +0100 Subject: omap3: make SDRC SHARING setting configurable Signed-off-by: Albert ARIBAUD (3ADEV) --- arch/arm/cpu/armv7/omap3/sdrc.c | 6 +++++- arch/arm/include/asm/arch-omap3/sys_proto.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 7a291318ab..4f15ac9cb5 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -135,6 +135,9 @@ void do_sdrc_init(u32 cs, u32 early) sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; + /* set some default timings */ + timings.sharing = SDRC_SHARING; + /* * When called in the early context this may be SPL and we will * need to set all of the timings. This ends up being board @@ -145,6 +148,7 @@ void do_sdrc_init(u32 cs, u32 early) * setup CS1. */ #ifdef CONFIG_SPL_BUILD + /* set/modify board-specific timings */ get_board_mem_timings(&timings); #endif if (early) { @@ -155,7 +159,7 @@ void do_sdrc_init(u32 cs, u32 early) writel(0, &sdrc_base->sysconfig); /* setup sdrc to ball mux */ - writel(SDRC_SHARING, &sdrc_base->sharing); + writel(timings.sharing, &sdrc_base->sharing); /* Disable Power Down of CKE because of 1 CKE on combo part */ writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 34bd8c509a..bcf92fbe65 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -23,6 +23,7 @@ struct emu_hal_params { /* Board SDRC timing values */ struct board_sdrc_timings { + u32 sharing; u32 mcfg; u32 ctrla; u32 ctrlb; -- cgit From d215b3e5e3e40235b5f644e5b66e2f16d110b117 Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD \\(3ADEV\\)" Date: Fri, 16 Jan 2015 09:09:49 +0100 Subject: omap3: add SDRC settings for Samsung K4X51163PG Signed-off-by: Albert ARIBAUD (3ADEV) --- arch/arm/include/asm/arch-omap3/mem.h | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h index 0b78c1ca60..3ce270c5c9 100644 --- a/arch/arm/include/asm/arch-omap3/mem.h +++ b/arch/arm/include/asm/arch-omap3/mem.h @@ -249,6 +249,49 @@ enum { #define MICRON_RASWIDTH_200 14 #define MICRON_V_MCFG_200(size) MCFG((size), MICRON_RASWIDTH_200) +/* Samsung K4X51163PG - FGC6 (165MHz optimized) 6.06ns - from 2010.90 src */ +#define SAMSUNG_TDAL_165 5 +#define SAMSUNG_TDPL_165 2 +#define SAMSUNG_TRRD_165 2 +#define SAMSUNG_TRCD_165 3 +#define SAMSUNG_TRP_165 3 +#define SAMSUNG_TRAS_165 7 +#define SAMSUNG_TRC_165 10 +#define SAMSUNG_TRFC_165 12 + +#define SAMSUNG_V_ACTIMA_165 \ + ACTIM_CTRLA(SAMSUNG_TRFC_165, SAMSUNG_TRC_165, \ + SAMSUNG_TRAS_165, SAMSUNG_TRP_165, \ + SAMSUNG_TRCD_165, SAMSUNG_TRRD_165, \ + SAMSUNG_TDPL_165, SAMSUNG_TDAL_165) + +#define SAMSUNG_TWTR_165 1 +#define SAMSUNG_TCKE_165 2 +#define SAMSUNG_XSR_165 20 +#define SAMSUNG_TXP_165 5 + +#define SAMSUNG_V_ACTIMB_165 \ + ACTIM_CTRLB(SAMSUNG_TWTR_165, SAMSUNG_TCKE_165, \ + SAMSUNG_TXP_165, SAMSUNG_XSR_165) + +#define SAMSUNG_RASWIDTH_165 14 +#define SAMSUNG_V_MCFG_165(size) \ + V_MCFG_RASWIDTH(SAMSUNG_RASWIDTH_165) | V_MCFG_CASWIDTH_10B | \ + V_MCFG_ADDRMUXLEGACY_FLEX | V_MCFG_RAMSIZE(size) | \ + V_MCFG_BANKALLOCATION_RBC | V_MCFG_RAMTYPE_DDR + +/* TODO: find which register these were taken from */ + +#define SAMSUNG_BL_165 0x2 +#define SAMSUNG_SIL_165 0x0 +#define SAMSUNG_CASL_165 0x3 +#define SAMSUNG_WBST_165 0x0 +#define SAMSUNG_V_MR_165 ((SAMSUNG_WBST_165 << 9) | \ + (SAMSUNG_CASL_165 << 4) | (SAMSUNG_SIL_165 << 3) | \ + (SAMSUNG_BL_165)) + +#define SAMSUNG_SHARING 0x00003700 + /* NUMONYX part of IGEP v2 (165MHz optimized) 6.06ns */ #define NUMONYX_TDAL_165 6 /* Twr/Tck + Trp/tck */ /* 15/6 + 18/6 = 5.5 -> 6 */ -- cgit From 5bfdd1fc971126e4617ac1388b809a83b6ffa0e5 Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD \\(3ADEV\\)" Date: Fri, 16 Jan 2015 09:09:50 +0100 Subject: omap3: mmc: add 1.8v bias setting for MMC1 Signed-off-by: Albert ARIBAUD (3ADEV) --- arch/arm/include/asm/arch-omap3/mmc_host_def.h | 1 + drivers/mmc/omap_hsmmc.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/include/asm/arch-omap3/mmc_host_def.h b/arch/arm/include/asm/arch-omap3/mmc_host_def.h index 0ba621a1b8..9f2896c4b9 100644 --- a/arch/arm/include/asm/arch-omap3/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap3/mmc_host_def.h @@ -51,6 +51,7 @@ typedef struct t2 { #define PBIASLITEPWRDNZ0 (1 << 1) #define PBIASSPEEDCTRL0 (1 << 2) #define PBIASLITEPWRDNZ1 (1 << 9) +#define PBIASLITEVMODE0 (1 << 0) #define CTLPROGIO1SPEEDCTRL (1 << 20) diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index c880cedb0a..dc725cb5b0 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -134,6 +134,10 @@ static unsigned char mmc_board_init(struct mmc *mmc) pbias_lite = readl(&t2_base->pbias_lite); pbias_lite &= ~(PBIASLITEPWRDNZ1 | PBIASLITEPWRDNZ0); +#ifdef CONFIG_TARGET_OMAP3_CAIRO + /* for cairo board, we need to set up 1.8 Volt bias level on MMC1 */ + pbias_lite &= ~PBIASLITEVMODE0; +#endif writel(pbias_lite, &t2_base->pbias_lite); writel(pbias_lite | PBIASLITEPWRDNZ1 | -- cgit From 7bc53efcd65c81d856e18612a1493158b5d9df7c Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD \\(3ADEV\\)" Date: Fri, 16 Jan 2015 09:09:51 +0100 Subject: omap3: add some MUX definitions for upcoming cairo Signed-off-by: Albert ARIBAUD (3ADEV) --- arch/arm/include/asm/arch-omap3/mux.h | 51 +++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/arch-omap3/mux.h b/arch/arm/include/asm/arch-omap3/mux.h index eba4a5c7f0..3277b407d1 100644 --- a/arch/arm/include/asm/arch-omap3/mux.h +++ b/arch/arm/include/asm/arch-omap3/mux.h @@ -15,6 +15,12 @@ * PTU - Pull type Up * DIS - Pull type selection is inactive * EN - Pull type selection is active + * SB_LOW - Standby mode configuration: Output low-level + * SB_HI - Standby mode configuration: Output high-level + * SB_HIZ - Standby mode configuration: Output hi-impedence + * SB_PD - Standby mode pull-down enabled + * SB_PU - Standby mode pull-up enabled + * WKEN - Wakeup input enabled * M0 - Mode 0 */ @@ -26,6 +32,13 @@ #define EN (1 << 3) #define DIS (0 << 3) +#define SB_LOW (1 << 9) +#define SB_HI (5 << 9) +#define SB_HIZ (2 << 9) +#define SB_PD (1 << 12) +#define SB_PU (3 << 12) +#define WKEN (1 << 14) + #define M0 0 #define M1 1 #define M2 2 @@ -36,8 +49,8 @@ #define M7 7 /* - * To get the actual address the offset has to added - * with OMAP34XX_CTRL_BASE to get the actual address + * To get the actual address the offset has to be added + * to OMAP34XX_CTRL_BASE */ /*SDRC*/ @@ -78,6 +91,33 @@ #define CONTROL_PADCONF_SDRC_DQS1 0x0074 #define CONTROL_PADCONF_SDRC_DQS2 0x0076 #define CONTROL_PADCONF_SDRC_DQS3 0x0078 +#define CONTROL_PADCONF_SDRC_BA0 0x05A0 +#define CONTROL_PADCONF_SDRC_BA1 0x05A2 +#define CONTROL_PADCONF_SDRC_A0 0x05A4 +#define CONTROL_PADCONF_SDRC_A1 0x05A6 +#define CONTROL_PADCONF_SDRC_A2 0x05A8 +#define CONTROL_PADCONF_SDRC_A3 0x05AA +#define CONTROL_PADCONF_SDRC_A4 0x05AC +#define CONTROL_PADCONF_SDRC_A5 0x05AE +#define CONTROL_PADCONF_SDRC_A6 0x05B0 +#define CONTROL_PADCONF_SDRC_A7 0x05B2 +#define CONTROL_PADCONF_SDRC_A8 0x05B4 +#define CONTROL_PADCONF_SDRC_A9 0x05B6 +#define CONTROL_PADCONF_SDRC_A10 0x05B8 +#define CONTROL_PADCONF_SDRC_A11 0x05BA +#define CONTROL_PADCONF_SDRC_A12 0x05BC +#define CONTROL_PADCONF_SDRC_A13 0x05BE +#define CONTROL_PADCONF_SDRC_A14 0x05C0 +#define CONTROL_PADCONF_SDRC_NCS0 0x05C2 +#define CONTROL_PADCONF_SDRC_NCS1 0x05C4 +#define CONTROL_PADCONF_SDRC_NCLK 0x05C6 +#define CONTROL_PADCONF_SDRC_NRAS 0x05C8 +#define CONTROL_PADCONF_SDRC_NCAS 0x05CA +#define CONTROL_PADCONF_SDRC_NWE 0x05CC +#define CONTROL_PADCONF_SDRC_DM0 0x05CE +#define CONTROL_PADCONF_SDRC_DM1 0x05D0 +#define CONTROL_PADCONF_SDRC_DM2 0x05D2 +#define CONTROL_PADCONF_SDRC_DM3 0x05D4 /*GPMC*/ #define CONTROL_PADCONF_GPMC_A1 0x007A #define CONTROL_PADCONF_GPMC_A2 0x007C @@ -89,6 +129,7 @@ #define CONTROL_PADCONF_GPMC_A8 0x0088 #define CONTROL_PADCONF_GPMC_A9 0x008A #define CONTROL_PADCONF_GPMC_A10 0x008C +#define CONTROL_PADCONF_GPMC_A11 0x0264 #define CONTROL_PADCONF_GPMC_D0 0x008E #define CONTROL_PADCONF_GPMC_D1 0x0090 #define CONTROL_PADCONF_GPMC_D2 0x0092 @@ -323,6 +364,8 @@ #define CONTROL_PADCONF_ETK_D13_ES2 0x05F6 #define CONTROL_PADCONF_ETK_D14_ES2 0x05F8 #define CONTROL_PADCONF_ETK_D15_ES2 0x05FA +#define CONTROL_PADCONF_JTAG_RTCK 0x0A4E +#define CONTROL_PADCONF_JTAG_TDO 0x0A50 /*Die to Die */ #define CONTROL_PADCONF_D2D_MCAD0 0x01E4 #define CONTROL_PADCONF_D2D_MCAD1 0x01E6 @@ -433,6 +476,10 @@ #define CONTROL_PADCONF_SYS_BOOT8 0x0226 /* AM/DM37xx specific */ +#define CONTROL_PADCONF_GPIO112 0x0134 +#define CONTROL_PADCONF_GPIO113 0x0136 +#define CONTROL_PADCONF_GPIO114 0x0138 +#define CONTROL_PADCONF_GPIO115 0x013A #define CONTROL_PADCONF_GPIO127 0x0A54 #define CONTROL_PADCONF_GPIO126 0x0A56 #define CONTROL_PADCONF_GPIO128 0x0A58 -- cgit From 212324a9d4f505255349bc50b34ec9f912db78d3 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 22 Jan 2015 09:38:10 -0500 Subject: davinci: Do not duplicate setting of gd In f0c3a6c we stopped setting gd in board_init_f, but later had to revert to due problems on certain platforms. As davinci does not look to have these problems, we can drop the setting here and rely upon crt0.S to do it. Cc: Peter Howard Signed-off-by: Tom Rini --- arch/arm/cpu/arm926ejs/davinci/spl.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c index 59b304efcb..49349da179 100644 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ b/arch/arm/cpu/arm926ejs/davinci/spl.c @@ -34,29 +34,14 @@ void putc(char c) } #endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ -void board_init_f(ulong dummy) +void spl_board_init(void) { - /* First, setup our stack pointer. */ - asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); - - /* Second, perform our low-level init. */ #ifdef CONFIG_SOC_DM365 dm36x_lowlevel_init(0); #endif #ifdef CONFIG_SOC_DA8XX arch_cpu_init(); #endif - - /* Third, we clear the BSS. */ - memset(__bss_start, 0, __bss_end - __bss_start); - - /* Finally, setup gd and move to the next step. */ - gd = &gdata; - board_init_r(NULL, 0); -} - -void spl_board_init(void) -{ preloader_console_init(); } -- cgit From f3b4bc458de3285a04c5f60df6372ad5ca79fa60 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 28 Jan 2015 15:01:32 +0100 Subject: OMAP3: igep00x0: Fix boot hang and add support for status LED. Use the STATUS_LED APIs for indicating a boot progress instead of show_boot_progress. This patch also fixes a problem introduced with commit b3f4ca1135 (dm: omap3: Move to driver model for GPIO and serial). After that commit the board doesn't boot. Looks like the problem is the gpio_request call inside the function show_boot_progress. Signed-off-by: Enric Balletbo i Serra --- board/isee/igep00x0/igep00x0.c | 18 +++++------------- board/isee/igep00x0/igep00x0.h | 8 -------- include/configs/omap3_igep00x0.h | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/board/isee/igep00x0/igep00x0.c b/board/isee/igep00x0/igep00x0.c index 47522f8013..693fce741a 100644 --- a/board/isee/igep00x0/igep00x0.c +++ b/board/isee/igep00x0/igep00x0.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include #include @@ -53,21 +54,12 @@ int board_init(void) /* boot param addr */ gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); - return 0; -} - -#if defined(CONFIG_SHOW_BOOT_PROGRESS) && !defined(CONFIG_SPL_BUILD) -void show_boot_progress(int val) -{ - if (val < 0) { - /* something went wrong */ - return; - } +#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) + status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); +#endif - if (!gpio_request(IGEP00X0_GPIO_LED, "")) - gpio_direction_output(IGEP00X0_GPIO_LED, 1); + return 0; } -#endif #ifdef CONFIG_SPL_BUILD /* diff --git a/board/isee/igep00x0/igep00x0.h b/board/isee/igep00x0/igep00x0.h index 181f81f2a1..3c7ff9b148 100644 --- a/board/isee/igep00x0/igep00x0.h +++ b/board/isee/igep00x0/igep00x0.h @@ -7,14 +7,6 @@ #ifndef _IGEP00X0_H_ #define _IGEP00X0_H_ -#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020) -#define IGEP00X0_GPIO_LED 27 -#endif - -#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030) -#define IGEP00X0_GPIO_LED 16 -#endif - const omap3_sysinfo sysinfo = { DDR_STACKED, #if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020) diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h index b2b3750c1e..6295ec505f 100644 --- a/include/configs/omap3_igep00x0.h +++ b/include/configs/omap3_igep00x0.h @@ -29,11 +29,21 @@ #define CONFIG_REVISION_TAG 1 -/* define to enable boot progress via leds */ -#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020) || \ - (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030) -#define CONFIG_SHOW_BOOT_PROGRESS +/* Status LED */ +#define CONFIG_STATUS_LED +#define CONFIG_BOARD_SPECIFIC_LED +#define CONFIG_GPIO_LED +#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020) +#define RED_LED_GPIO 27 +#endif +#if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030) +#define RED_LED_GPIO 16 #endif +#define RED_LED_DEV 0 +#define STATUS_LED_BIT RED_LED_GPIO +#define STATUS_LED_STATE STATUS_LED_ON +#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2) +#define STATUS_LED_BOOT RED_LED_DEV /* GPIO banks */ #define CONFIG_OMAP3_GPIO_3 /* GPIO64 .. 95 is in GPIO bank 3 */ -- cgit From b4b39a7e54fa6f4aa016cf98744aa5659db75d33 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 20 Jan 2015 10:06:18 +0100 Subject: arm, imx6, aristainetos: board updates - use linux display timing settings - change backlight duty cycle 500ns - some defaultenvironment changes - change fit_addr_r to 0x14000000 as needed if MAX_LOCKDEP_SUBCLASSES in linux gets increased. - Environment now at 0xd0000 in nand flash Signed-off-by: Heiko Schocher --- board/aristainetos/aristainetos.c | 8 +- include/configs/aristainetos.h | 167 +++++++++++++++++++++----------------- 2 files changed, 97 insertions(+), 78 deletions(-) diff --git a/board/aristainetos/aristainetos.c b/board/aristainetos/aristainetos.c index 67ac260055..8330bb64bd 100644 --- a/board/aristainetos/aristainetos.c +++ b/board/aristainetos/aristainetos.c @@ -321,8 +321,8 @@ static void enable_lvds(struct display_info_t const *dev) /* enable backlight PWM 3 */ if (pwm_init(2, 0, 0)) goto error; - /* duty cycle 200ns, period: 3000ns */ - if (pwm_config(2, 200, 3000)) + /* duty cycle 500ns, period: 3000ns */ + if (pwm_config(2, 500, 3000)) goto error; if (pwm_enable(2)) goto error; @@ -350,8 +350,8 @@ struct display_info_t const displays[] = { .right_margin = 88, .upper_margin = 10, .lower_margin = 10, - .hsync_len = 25, - .vsync_len = 1, + .hsync_len = 80, + .vsync_len = 25, .sync = 0, .vmode = FB_VMODE_NONINTERLACED } diff --git a/include/configs/aristainetos.h b/include/configs/aristainetos.h index e6a08df4ba..3066fd030e 100644 --- a/include/configs/aristainetos.h +++ b/include/configs/aristainetos.h @@ -1,4 +1,5 @@ /* + * (C) Copyright 2015 * (C) Copyright 2014 * Heiko Schocher, DENX Software Engineering, hs@denx.de. * @@ -24,8 +25,7 @@ #include #define CONFIG_MACH_TYPE 4501 -#define CONFIG_MMCROOT "/dev/mmcblk0p2" -#define CONFIG_DEFAULT_FDT_FILE "aristainetos.dtb" +#define CONFIG_MMCROOT "/dev/mmcblk0p1" #define CONFIG_HOSTNAME aristainetos #define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024) @@ -81,7 +81,6 @@ #define CONFIG_SF_DEFAULT_SPEED 20000000 #define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 #define CONFIG_SYS_SPI_ST_ENABLE_WP_PIN - /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_CONS_INDEX 1 @@ -101,84 +100,108 @@ #define CONFIG_SYS_TEXT_BASE 0x17800000 #define CONFIG_EXTRA_ENV_SETTINGS \ - "uimage=uImage\0" \ - "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ - "fdt_addr_r=0x11000000\0" \ - "kernel_addr_r=0x12000000\0" \ - "kernel_file=uImage\0" \ - "boot_fdt=try\0" \ - "ip_dyn=yes\0" \ + "script=u-boot.scr\0" \ + "fit_file=/boot/system.itb\0" \ + "loadaddr=0x12000000\0" \ + "fit_addr_r=0x14000000\0" \ + "uboot=/boot/u-boot.imx\0" \ + "uboot_sz=d0000\0" \ + "rescue_sys_addr=f0000\0" \ + "rescue_sys_length=f10000\0" \ + "board_type=aristainetos7@1\0" \ + "panel=lb07wv8\0" \ + "splashpos=m,m\0" \ "console=" CONFIG_CONSOLE_DEV "\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ + "mtdids=nand0=gpmi-nand,nor0=spi3.0\0" \ + "mtdparts=mtdparts=spi3.0:832k(u-boot),64k(env),64k(env-red)," \ + "-(rescue-system);gpmi-nand:-(ubi)\0" \ + "addmisc=setenv bootargs ${bootargs} consoleblank=0\0" \ + "addmtd=setenv bootargs ${bootargs} ${mtdparts}\0" \ + "set_fit_default=fdt addr ${fit_addr_r};fdt set /configurations " \ + "default ${board_type}\0" \ + "get_env=mw ${loadaddr} 0 0x20000;" \ + "mmc rescan;" \ + "ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} env.txt;" \ + "env import -t ${loadaddr}\0" \ + "default_env=mw ${loadaddr} 0 0x20000;" \ + "env export -t ${loadaddr} serial# ethaddr eth1addr " \ + "board_type panel;" \ + "env default -a;" \ + "env import -t ${loadaddr}\0" \ + "loadbootscript=" \ + "ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source\0" \ "mmcpart=1\0" \ - "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ + "mmcdev=0\0" \ "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ "mmcargs=setenv bootargs console=${console},${baudrate} " \ "root=${mmcroot}\0" \ - "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${kernel_addr_r} " \ - "${uimage}\0" \ - "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} " \ - "${fdt_file}\0" \ "mmcboot=echo Booting from mmc ...; " \ - "run mmcargs;run loadimage loadfdt fdt_setup;" \ - "bootm ${kernel_addr_r} - ${fdt_addr_r};\0" \ - "rootpath=/opt/eldk-5.5/armv7a-hf/rootfs-sato-sdk\0" \ - "nfsopts=nfsvers=3 nolock rw\0" \ - "netdev=eth0\0" \ - "fdt_setup=fdt addr ${fdt_addr_r};fdt resize;fdt chosen;fdt board\0"\ - "load_fdt=tftp ${fdt_addr_r} ${fdt_file}\0" \ - "load_kernel=tftp ${kernel_addr_r} ${kernel_file}\0" \ - "addmtd=setenv bootargs ${bootargs} ${mtdparts}\0" \ - "get_env=mw ${loadaddr} 0x00000000 0x20000;" \ - "tftp ${loadaddr} /tftpboot/aristainetos/env.txt;" \ - "env import -t ${loadaddr}\0" \ - "addmisc=setenv bootargs ${bootargs} maxcpus=1 loglevel=8\0" \ - "bootargs_defaults=setenv bootargs ${console} ${mtdoops} " \ - "${optargs}\0" \ - "net_args=run bootargs_defaults;setenv bootargs ${bootargs} " \ - "root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} " \ - "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ - "${hostname}:${netdev}:off\0" \ - "net_nfs=run load_kernel load_fdt;run net_args addmtd addmisc;" \ - "run fdt_setup;bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \ - "uboot=/tftpboot/aristainetos/u-boot.imx\0" \ - "load_uboot=tftp ${loadaddr} ${uboot}\0" \ - "uboot_sz=c0000\0" \ - "upd_uboot=mw.b ${loadaddr} 0xff ${uboot_sz};" \ - "mw.b 10200000 0x00 ${uboot_sz};" \ - "run load_uboot;sf probe;sf erase 0 ${uboot_sz};" \ + "run mmcargs addmtd addmisc set_fit_default;" \ + "bootm ${fit_addr_r}\0" \ + "mmc_load_fit=ext2load mmc ${mmcdev}:${mmcpart} ${fit_addr_r} " \ + "${fit_file}\0" \ + "mmc_load_uboot=ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} " \ + "${uboot}\0" \ + "mmc_upd_uboot=mw.b ${loadaddr} 0xff ${uboot_sz};" \ + "setexpr cmp_buf ${loadaddr} + ${uboot_sz};" \ + "setexpr uboot_maxsize ${uboot_sz} - 400;" \ + "mw.b ${cmp_buf} 0x00 ${uboot_sz};" \ + "run mmc_load_uboot;sf probe;sf erase 0 ${uboot_sz};" \ "sf write ${loadaddr} 400 ${filesize};" \ - "sf read 10200000 400 ${uboot_sz};" \ - "cmp.b ${loadaddr} 10200000 bc000\0" \ - "ubi_prep=ubi part ubi 2048;ubifsmount ubi:kernel\0" \ - "load_kernel_ubi=ubifsload ${kernel_addr_r} uImage\0" \ - "load_fdt_ubi=ubifsload ${fdt_addr_r} aristainetos.dtb\0" \ - "ubi_nfs=run ubiprep load_kernel_ubi load_fdt_ubi;" \ - "run net_args addmtd addmisc;run fdt_setup;" \ - "bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \ - "rootfsname=rootfs\0" \ - "ubi_args=run bootargs_defaults;setenv bootargs ${bootargs} " \ - "ubi.mtd=0,2048 root=ubi0:${rootfsname} rootfstype=ubifs " \ - "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ - "${hostname}:${netdev}:off\0" \ - "ubi_ubi=run ubi_prep load_kernel_ubi load_fdt_ubi;" \ - "run bootargs_defaults ubi_args addmtd addmisc;" \ - "run fdt_setup;bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \ - "ubirootfs_file=/tftpboot/aristainetos/rootfs-minimal.ubifs\0" \ - "upd_ubirootfs=run ubi_prep;tftp ${loadaddr} ${ubirootfs_file};" \ - "ubi write ${loadaddr} rootfs ${filesize}\0" \ - "ksz=800000\0" \ - "rootsz=2000000\0" \ - "usersz=8000000\0" \ - "ubi_make=run ubi_prep;ubi create kernel ${ksz};" \ - "ubi create rootfs ${rootsz};ubi create userfs ${usersz}\0" + "sf read ${cmp_buf} 400 ${uboot_sz};" \ + "cmp.b ${loadaddr} ${cmp_buf} ${uboot_maxsize}\0" \ + "ubiargs=setenv bootargs console=${console},${baudrate} " \ + "ubi.mtd=0,2048 root=ubi0:rootfs rootfstype=ubifs\0 " \ + "ubiboot=echo Booting from ubi ...; " \ + "run ubiargs addmtd addmisc set_fit_default;" \ + "bootm ${fit_addr_r}\0" \ + "ubifs_load_fit=sf probe;ubi part ubi 2048;ubifsmount ubi:rootfs;" \ + "ubifsload ${fit_addr_r} /boot/system.itb; " \ + "imi ${fit_addr_r}\0 " \ + "rescueargs=setenv bootargs console=${console},${baudrate} " \ + "root=/dev/ram rw\0 " \ + "rescueboot=echo Booting rescue system from NOR ...; " \ + "run rescueargs addmtd addmisc set_fit_default;" \ + "bootm ${fit_addr_r}\0" \ + "rescue_load_fit=sf probe;sf read ${fit_addr_r} ${rescue_sys_addr} " \ + "${rescue_sys_length}; imi ${fit_addr_r}\0 " #define CONFIG_BOOTCOMMAND \ "mmc dev ${mmcdev};" \ "if mmc rescan; then " \ - "run mmcboot;" \ - "else run ubi_ubi; fi" + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run mmc_load_fit; then " \ + "run mmcboot; " \ + "else " \ + "if run ubifs_load_fit; then " \ + "run ubiboot; " \ + "else " \ + "if run rescue_load_fit; then " \ + "run rescueboot; " \ + "else " \ + "echo RESCUE SYSTEM BOOT " \ + "FAILURE;" \ + "fi; " \ + "fi; " \ + "fi; " \ + "fi; " \ + "else " \ + "if run ubifs_load_fit; then " \ + "run ubiboot; " \ + "else " \ + "if run rescue_load_fit; then " \ + "run rescueboot; " \ + "else " \ + "echo RESCUE SYSTEM BOOT FAILURE;" \ + "fi; " \ + "fi; " \ + "fi" #define CONFIG_ARP_TIMEOUT 200UL @@ -227,8 +250,8 @@ #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE #define CONFIG_ENV_SECT_SIZE (0x010000) -#define CONFIG_ENV_OFFSET (0x0c0000) -#define CONFIG_ENV_OFFSET_REDUND (0x0d0000) +#define CONFIG_ENV_OFFSET (0x0d0000) +#define CONFIG_ENV_OFFSET_REDUND (0x0e0000) #define CONFIG_OF_LIBFDT @@ -289,9 +312,6 @@ #define CONFIG_CMD_UBI #define CONFIG_CMD_UBIFS -#define MTDIDS_DEFAULT "nand0=gpmi-nand" -#define MTDPARTS_DEFAULT "mtdparts=gpmi-nand:-(ubi)" - #define CONFIG_MTD_UBI_FASTMAP #define CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT 1 @@ -321,5 +341,4 @@ #define CONFIG_PWM_IMX #define CONFIG_IMX6_PWM_PER_CLK 66000000 - #endif /* __ARISTAINETOS_CONFIG_H */ -- cgit From 1a1ad8e0903ec916d1e3ef8c18fa335d765a4342 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 5 Jan 2015 18:13:36 +0100 Subject: fs: Add command to retrieve the filesystem type New command to determine the filesystem type of a given partition. Optionally stores the filesystem type in a environment variable. Signed-off-by: Sjoerd Simons Reviewed-by: Stephen Warren --- common/cmd_fs.c | 15 +++++++++++++++ fs/fs.c | 27 +++++++++++++++++++++++++++ include/fs.h | 6 ++++++ 3 files changed, 48 insertions(+) diff --git a/common/cmd_fs.c b/common/cmd_fs.c index 0d9da113bf..e146254f6d 100644 --- a/common/cmd_fs.c +++ b/common/cmd_fs.c @@ -81,3 +81,18 @@ U_BOOT_CMD( " - List files in directory 'directory' of partition 'part' on\n" " device type 'interface' instance 'dev'." ) + +static int do_fstype_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + return do_fs_type(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + fstype, 4, 1, do_fstype_wrapper, + "Look up a filesystem type", + " :\n" + "- print filesystem type\n" + "fstype : \n" + "- set environment variable to filesystem type\n" +); diff --git a/fs/fs.c b/fs/fs.c index ddd751c9cc..483273fe20 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -79,6 +79,7 @@ static inline int fs_uuid_unsupported(char *uuid_str) struct fstype_info { int fstype; + char *name; /* * Is it legal to pass NULL as .probe()'s fs_dev_desc parameter? This * should be false in most cases. For "virtual" filesystems which @@ -105,6 +106,7 @@ static struct fstype_info fstypes[] = { #ifdef CONFIG_FS_FAT { .fstype = FS_TYPE_FAT, + .name = "fat", .null_dev_desc_ok = false, .probe = fat_set_blk_dev, .close = fat_close, @@ -123,6 +125,7 @@ static struct fstype_info fstypes[] = { #ifdef CONFIG_FS_EXT4 { .fstype = FS_TYPE_EXT, + .name = "ext4", .null_dev_desc_ok = false, .probe = ext4fs_probe, .close = ext4fs_close, @@ -141,6 +144,7 @@ static struct fstype_info fstypes[] = { #ifdef CONFIG_SANDBOX { .fstype = FS_TYPE_SANDBOX, + .name = "sandbox", .null_dev_desc_ok = true, .probe = sandbox_fs_set_blk_dev, .close = sandbox_fs_close, @@ -154,6 +158,7 @@ static struct fstype_info fstypes[] = { #endif { .fstype = FS_TYPE_ANY, + .name = "unsupported", .null_dev_desc_ok = true, .probe = fs_probe_unsupported, .close = fs_close_unsupported, @@ -190,6 +195,7 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) if (!relocated) { for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) { + info->name += gd->reloc_off; info->probe += gd->reloc_off; info->close += gd->reloc_off; info->ls += gd->reloc_off; @@ -503,3 +509,24 @@ int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return CMD_RET_SUCCESS; } + +int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fstype_info *info; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY)) + return 1; + + info = fs_get_info(fs_type); + + if (argc == 4) + setenv(argv[3], info->name); + else + printf("%s\n", info->name); + + return CMD_RET_SUCCESS; +} + diff --git a/include/fs.h b/include/fs.h index ffb6ce7ada..fd1e4ab1c0 100644 --- a/include/fs.h +++ b/include/fs.h @@ -109,4 +109,10 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int fstype); +/* + * Determine the type of the specified filesystem and print it. Optionally it is + * possible to store the type directly in env. + */ +int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); + #endif /* _FS_H */ -- cgit From e86df6ef4f392879c0654e91e6c94801911491a9 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 5 Jan 2015 18:13:37 +0100 Subject: part: let list put the list in an environment variable Add an optional third argument to the "part list" command which puts a space seperated list of valid partitions into the given environment variable. This is useful for allowing boot scripts to iterate of all partitions of a device. Signed-off-by: Sjoerd Simons Reviewed-by: Stephen Warren --- common/cmd_part.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/common/cmd_part.c b/common/cmd_part.c index 39e8666b77..c99f52735f 100644 --- a/common/cmd_part.c +++ b/common/cmd_part.c @@ -54,13 +54,31 @@ static int do_part_list(int argc, char * const argv[]) int ret; block_dev_desc_t *desc; - if (argc != 2) + if (argc < 2 || argc > 3) return CMD_RET_USAGE; ret = get_device(argv[0], argv[1], &desc); if (ret < 0) return 1; + if (argc == 3) { + int p; + char str[512] = { 0, }; + disk_partition_t info; + + for (p = 1; p < 128; p++) { + int r = get_partition_info(desc, p, &info); + + if (r == 0) { + char t[5]; + sprintf(t, "%s%d", str[0] ? " " : "", p); + strcat(str, t); + } + } + setenv(argv[2], str); + return 0; + } + print_part(desc); return 0; @@ -87,5 +105,7 @@ U_BOOT_CMD( "part uuid : \n" " - set environment variable to partition UUID\n" "part list \n" - " - print a device's partition table" + " - print a device's partition table\n" + "part list \n" + " - set environment variable to the list of partitions" ); -- cgit From 735b1cfeb2308d9114af1140b703be91b604c09e Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 5 Jan 2015 18:13:38 +0100 Subject: config_distro_bootcmd: Scan all partitions for boot files Not all devices use the convention that the boot scripts are on the first partition. For example on chromebooks it seems common for the first two partitions to be ChromeOS kernel partitions. So instead of just the first partition scan all partitions on a device with a filesystem u-boot can recognize. Signed-off-by: Sjoerd Simons --- include/config_distro_bootcmd.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index becbe3fa7c..676b351017 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -13,7 +13,7 @@ #define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \ "if " #devtypel " dev ${devnum}; then " \ "setenv devtype " #devtypel "; " \ - "run scan_dev_for_boot; " \ + "run scan_dev_for_boot_part; " \ "fi\0" #define BOOTENV_SHARED_BLKDEV(devtypel) \ @@ -155,7 +155,6 @@ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ BOOTENV_BOOT_TARGETS \ - "bootpart=1\0" \ \ "boot_extlinux=" \ "sysboot ${devtype} ${devnum}:${bootpart} any " \ @@ -186,12 +185,21 @@ "done\0" \ \ "scan_dev_for_boot=" \ - "echo Scanning ${devtype} ${devnum}...; " \ + "echo Scanning ${devtype} ${devnum}:${bootpart}...; " \ "for prefix in ${boot_prefixes}; do " \ "run scan_dev_for_extlinux; " \ "run scan_dev_for_scripts; " \ "done\0" \ \ + "scan_dev_for_boot_part=" \ + "part list ${devtype} ${devnum} devplist; " \ + "for bootpart in ${devplist}; do " \ + "if fstype ${devtype} ${devnum}:${bootpart} " \ + "bootfstype; then " \ + "run scan_dev_for_boot; " \ + "fi; " \ + "done\0" \ + \ BOOT_TARGET_DEVICES(BOOTENV_DEV) \ \ "bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ -- cgit From 453c6cc19aaf4f03bbf4ef03493732a39d3780db Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 5 Jan 2015 18:13:39 +0100 Subject: distro_distro_bootcmd: use CONFIG_BOOTCOMMAND instead of setting bootcmd= Move the bootcmd commands into a seperate distro_bootcmd environment variable. Allowing a user to easily launch the distro boot sequence if the default bootcmd did not default to distro boot commands. Also set CONFIG_BOOTCOMMAND to "run distro_bootcmd" if it hasn't been configured yet rather then putting it directly in the environment. This allows boards to make the distro boot commands available without necessarily default to them or to use them as a fallback after running some board specific commands instead. Signed-off-by: Sjoerd Simons Reviewed-by: Stephen Warren --- include/config_distro_bootcmd.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 676b351017..90ab21a727 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -202,9 +202,13 @@ \ BOOT_TARGET_DEVICES(BOOTENV_DEV) \ \ - "bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ + "distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ "for target in ${boot_targets}; do " \ "run bootcmd_${target}; " \ "done\0" +#ifndef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND "run distro_bootcmd" +#endif + #endif /* _CONFIG_CMD_DISTRO_BOOTCMD_H */ -- cgit From c72b65ccdf6784ff85c187198e70a7da3b4b9cf4 Mon Sep 17 00:00:00 2001 From: Pieter Voorthuijsen Date: Mon, 12 Jan 2015 16:23:18 +0100 Subject: common: add cache flush to imxtract function A cache flush is required when an image is extracted that is required on another core. Signed-off-by: Pieter Voorthuijsen --- common/cmd_ximg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index ae2714d372..64b9186d73 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -247,6 +247,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) puts("OK\n"); } + flush_cache(dest, len); + setenv_hex("fileaddr", data); setenv_hex("filesize", len); -- cgit From 5cde9d8e94de759cacf99b08dd373cb18768feba Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:37:33 -0200 Subject: doc: "os" is also mandatory for "ramdisk" FIT image components According to fit_image_print(), the "os" property from "image" node is required also when "type=ramdisk". Signed-off-by: Guilherme Maciel Ferreira --- doc/uImage.FIT/source_file_format.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index b47ce73b83..e62b679ebc 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -166,10 +166,10 @@ the '/images' node should have the following layout: should be set to "none". Conditionally mandatory property: - - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd", - "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix", - "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot", - "rtems", "unity", "integrity". + - os : OS name, mandatory for types "kernel" and "ramdisk". Valid OS names + are: "openbsd", "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", + "solaris", "irix", "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", + "u_boot", "rtems", "unity", "integrity". - arch : Architecture name, mandatory for types: "standalone", "kernel", "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha", "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc", -- cgit From a724b7e0ab28d7b6a2aed1a0b7d46b0e662c2372 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:37:34 -0200 Subject: doc: fix misspellings Signed-off-by: Guilherme Maciel Ferreira --- doc/uImage.FIT/source_file_format.txt | 2 +- doc/uImage.FIT/verified-boot.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index e62b679ebc..427ea498b4 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -159,7 +159,7 @@ the '/images' node should have the following layout: - description : Textual description of the component sub-image - type : Name of component sub-image type, supported types are: "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem", - "flat_dt" and others (see uimage_type in common/images.c). + "flat_dt" and others (see uimage_type in common/image.c). - data : Path to the external file which contains this node's binary data. - compression : Compression used by included data. Supported compressions are "gzip" and "bzip2". If no compression is used compression property diff --git a/doc/uImage.FIT/verified-boot.txt b/doc/uImage.FIT/verified-boot.txt index 3c83fbc2c1..e639e7ae71 100644 --- a/doc/uImage.FIT/verified-boot.txt +++ b/doc/uImage.FIT/verified-boot.txt @@ -64,7 +64,7 @@ software from updatable memory. It is critical that the public key be secure and cannot be tampered with. It can be stored in read-only memory, or perhaps protected by other on-chip -crypto provided by some modern SOCs. If the public key can ben changed, then +crypto provided by some modern SOCs. If the public key can be changed, then the verification is worthless. @@ -87,7 +87,7 @@ affect the whole change. Flattened Image Tree (FIT) -------------------------- -The FIT format is alreay widely used in U-Boot. It is a flattened device +The FIT format is already widely used in U-Boot. It is a flattened device tree (FDT) in a particular format, with images contained within. FITs include hashes to verify images, so it is relatively straightforward to add signatures as well. -- cgit From 44f145fd81f73a5c5adc490b0da91b80a4c7790a Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:39:59 -0200 Subject: linker_lists: fix misspellings Signed-off-by: Guilherme Maciel Ferreira --- include/linker_lists.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linker_lists.h b/include/linker_lists.h index d37fba44dc..940c871281 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -23,7 +23,7 @@ /** * A linker list is constructed by grouping together linker input - * sections, each containning one entry of the list. Each input section + * sections, each containing one entry of the list. Each input section * contains a constant initialized variable which holds the entry's * content. Linker list input sections are constructed from the list * and entry names, plus a prefix which allows grouping all lists @@ -39,7 +39,7 @@ * This ensures uniqueness for both input section and C variable name. * * Note that the names differ only in the first character, "." for the - * setion and "_" for the variable, so that the linker cannot confuse + * section and "_" for the variable, so that the linker cannot confuse * section and symbol names. From now on, both names will be referred * to as * -- cgit From 0ca6691c2ec20ff264d882854c339795579991f5 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:48:05 -0200 Subject: imagetool: move common code to imagetool module The get_type() and verify_print_header() functions have the same code on both dumpimage.c and mkimage.c modules. Signed-off-by: Guilherme Maciel Ferreira --- tools/dumpimage.c | 66 +++----------------------------------------------- tools/imagetool.c | 51 +++++++++++++++++++++++++++++++++++++++ tools/imagetool.h | 31 ++++++++++++++++++++++++ tools/mkimage.c | 72 ++++--------------------------------------------------- 4 files changed, 90 insertions(+), 130 deletions(-) diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 542ee28210..0228e183ab 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -55,67 +55,6 @@ static void dumpimage_register(struct image_type_params *tparams) debug("Registered %s\n", tparams->name); } -/** - * dumpimage_get_type() - find the image type params for a given image type - * - * Scan all registered image types and check the input type_id for each - * supported image type - * - * @return respective image_type_params pointer. If the input type is not - * supported by any of registered image types, returns NULL - */ -static struct image_type_params *dumpimage_get_type(int type) -{ - struct image_type_params *curr; - - for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) { - if (curr->check_image_type) { - if (!curr->check_image_type(type)) - return curr; - } - } - return NULL; -} - -/* - * dumpimage_verify_print_header() - verifies the image header - * - * Scan registered image types and verify the image_header for each - * supported image type. If verification is successful, this prints - * the respective header. - * - * @return 0 on success, negative if input image format does not match with - * any of supported image types - */ -static int dumpimage_verify_print_header(void *ptr, struct stat *sbuf) -{ - int retval = -1; - struct image_type_params *curr; - - for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) { - if (curr->verify_header) { - retval = curr->verify_header((unsigned char *)ptr, - sbuf->st_size, ¶ms); - if (retval != 0) - continue; - /* - * Print the image information if verify is - * successful - */ - if (curr->print_header) { - curr->print_header(ptr); - } else { - fprintf(stderr, - "%s: print_header undefined for %s\n", - params.cmdname, curr->name); - } - break; - } - } - - return retval; -} - /* * dumpimage_extract_datafile - * @@ -203,7 +142,7 @@ int main(int argc, char **argv) usage(); /* set tparams as per input type_id */ - tparams = dumpimage_get_type(params.type); + tparams = imagetool_get_type(params.type, dumpimage_tparams); if (tparams == NULL) { fprintf(stderr, "%s: unsupported type %s\n", params.cmdname, genimg_get_type_name(params.type)); @@ -273,7 +212,8 @@ int main(int argc, char **argv) * Print the image information for matched image type * Returns the error code if not matched */ - retval = dumpimage_verify_print_header(ptr, &sbuf); + retval = imagetool_verify_print_header(ptr, &sbuf, + tparams, ¶ms); } (void)munmap((void *)ptr, sbuf.st_size); diff --git a/tools/imagetool.c b/tools/imagetool.c index 98717bdedd..e4de7af984 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -8,6 +8,8 @@ #include "imagetool.h" +#include + /* * Callback function to register a image type within a tool */ @@ -62,3 +64,52 @@ void register_image_type(struct image_type_params *tparams) { register_func(tparams); } + +struct image_type_params *imagetool_get_type( + int type, + struct image_type_params *tparams) +{ + struct image_type_params *curr; + + for (curr = tparams; curr != NULL; curr = curr->next) { + if (curr->check_image_type) { + if (!curr->check_image_type(type)) + return curr; + } + } + return NULL; +} + +int imagetool_verify_print_header( + void *ptr, + struct stat *sbuf, + struct image_type_params *tparams, + struct image_tool_params *params) +{ + int retval = -1; + struct image_type_params *curr; + + for (curr = tparams; curr != NULL; curr = curr->next) { + if (curr->verify_header) { + retval = curr->verify_header((unsigned char *)ptr, + sbuf->st_size, params); + + if (retval == 0) { + /* + * Print the image information if verify is + * successful + */ + if (curr->print_header) { + curr->print_header(ptr); + } else { + fprintf(stderr, + "%s: print_header undefined for %s\n", + params->cmdname, curr->name); + } + break; + } + } + } + + return retval; +} diff --git a/tools/imagetool.h b/tools/imagetool.h index 8bce059482..eb2750cf69 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -150,6 +150,37 @@ void register_image_tool(imagetool_register_t image_register); */ void register_image_type(struct image_type_params *tparams); +/** + * imagetool_get_type() - find the image type params for a given image type + * + * It scans all registers image type supports + * checks the input type for each supported image type + * + * if successful, + * returns respective image_type_params pointer if success + * if input type_id is not supported by any of image_type_support + * returns NULL + */ +struct image_type_params *imagetool_get_type( + int type, + struct image_type_params *tparams); + +/* + * imagetool_verify_print_header() - verifies the image header + * + * Scan registered image types and verify the image_header for each + * supported image type. If verification is successful, this prints + * the respective header. + * + * @return 0 on success, negative if input image format does not match with + * any of supported image types + */ +int imagetool_verify_print_header( + void *ptr, + struct stat *sbuf, + struct image_type_params *tparams, + struct image_tool_params *params); + /* * There is a c file associated with supported image type low level code * for ex. default_image.c, fit_image.c diff --git a/tools/mkimage.c b/tools/mkimage.c index c70408c9ba..c04a2abee5 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -65,70 +65,6 @@ void mkimage_register (struct image_type_params *tparams) debug ("Registered %s\n", tparams->name); } -/* - * mkimage_get_type - - * - * It scans all registers image type supports - * checks the input type_id for each supported image type - * - * if successful, - * returns respective image_type_params pointer if success - * if input type_id is not supported by any of image_type_support - * returns NULL - */ -struct image_type_params *mkimage_get_type(int type) -{ - struct image_type_params *curr; - - for (curr = mkimage_tparams; curr != NULL; curr = curr->next) { - if (curr->check_image_type) { - if (!curr->check_image_type (type)) - return curr; - } - } - return NULL; -} - -/* - * mkimage_verify_print_header - - * - * It scans mkimage_tparams link list, - * verifies image_header for each supported image type - * if verification is successful, prints respective header - * - * returns negative if input image format does not match with any of - * supported image types - */ -int mkimage_verify_print_header (void *ptr, struct stat *sbuf) -{ - int retval = -1; - struct image_type_params *curr; - - for (curr = mkimage_tparams; curr != NULL; curr = curr->next ) { - if (curr->verify_header) { - retval = curr->verify_header ( - (unsigned char *)ptr, sbuf->st_size, - ¶ms); - - if (retval == 0) { - /* - * Print the image information - * if verify is successful - */ - if (curr->print_header) - curr->print_header (ptr); - else { - fprintf (stderr, - "%s: print_header undefined for %s\n", - params.cmdname, curr->name); - } - break; - } - } - } - return retval; -} - int main (int argc, char **argv) { @@ -279,7 +215,7 @@ NXTARG: ; usage (); /* set tparams as per input type_id */ - tparams = mkimage_get_type(params.type); + tparams = imagetool_get_type(params.type, mkimage_tparams); if (tparams == NULL) { fprintf (stderr, "%s: unsupported type %s\n", params.cmdname, genimg_get_type_name(params.type)); @@ -363,7 +299,8 @@ NXTARG: ; * Print the image information for matched image type * Returns the error code if not matched */ - retval = mkimage_verify_print_header (ptr, &sbuf); + retval = imagetool_verify_print_header(ptr, &sbuf, + tparams, ¶ms); (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); @@ -529,7 +466,8 @@ copy_file (int ifd, const char *datafile, int pad) uint8_t zeros[4096]; int offset = 0; int size; - struct image_type_params *tparams = mkimage_get_type (params.type); + struct image_type_params *tparams = imagetool_get_type(params.type, + mkimage_tparams); if (pad >= sizeof(zeros)) { fprintf(stderr, "%s: Can't pad to %d\n", -- cgit From 067d15607598884e270f3076c721f56d3c4f65e6 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:48:06 -0200 Subject: imagetool: make the image_save_datafile() available to all image types Move the image_save_datafile() function from an U-Multi specific file (default_image.c) to a file common to all image types (image.c). And rename it to genimg_save_datafile(), to make clear it is useful for any image type. Signed-off-by: Guilherme Maciel Ferreira --- common/image.c | 2 +- tools/default_image.c | 28 +--------------------------- tools/imagetool.c | 27 +++++++++++++++++++++++++++ tools/imagetool.h | 17 +++++++++++++++++ 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/common/image.c b/common/image.c index ad7a46d08d..a911aa9b4d 100644 --- a/common/image.c +++ b/common/image.c @@ -756,7 +756,7 @@ int genimg_get_format(const void *img_addr) * genimg_get_image - get image from special storage (if necessary) * @img_addr: image start address * - * genimg_get_image() checks if provided image start adddress is located + * genimg_get_image() checks if provided image start address is located * in a dataflash storage. If so, image is moved to a system RAM memory. * * returns: diff --git a/tools/default_image.c b/tools/default_image.c index 0a0792e503..a92fa8015b 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -117,32 +117,6 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_hcrc(hdr, checksum); } -static int image_save_datafile(struct image_tool_params *params, - ulong file_data, ulong file_len) -{ - int dfd; - const char *datafile = params->outfile; - - dfd = open(datafile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - S_IRUSR | S_IWUSR); - if (dfd < 0) { - fprintf(stderr, "%s: Can't open \"%s\": %s\n", - params->cmdname, datafile, strerror(errno)); - return -1; - } - - if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) { - fprintf(stderr, "%s: Write error on \"%s\": %s\n", - params->cmdname, datafile, strerror(errno)); - close(dfd); - return -1; - } - - close(dfd); - - return 0; -} - static int image_extract_datafile(void *ptr, struct image_tool_params *params) { const image_header_t *hdr = (const image_header_t *)ptr; @@ -170,7 +144,7 @@ static int image_extract_datafile(void *ptr, struct image_tool_params *params) } /* save the "data file" into the file system */ - return image_save_datafile(params, file_data, file_len); + return imagetool_save_datafile(params->outfile, file_data, file_len); } /* diff --git a/tools/imagetool.c b/tools/imagetool.c index e4de7af984..a25b86b36e 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -113,3 +113,30 @@ int imagetool_verify_print_header( return retval; } + +int imagetool_save_datafile( + const char *file_name, + ulong file_data, + ulong file_len) +{ + int dfd; + + dfd = open(file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, + S_IRUSR | S_IWUSR); + if (dfd < 0) { + fprintf(stderr, "Can't open \"%s\": %s\n", + file_name, strerror(errno)); + return -1; + } + + if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) { + fprintf(stderr, "Write error on \"%s\": %s\n", + file_name, strerror(errno)); + close(dfd); + return -1; + } + + close(dfd); + + return 0; +} diff --git a/tools/imagetool.h b/tools/imagetool.h index eb2750cf69..44d9380995 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -181,6 +181,23 @@ int imagetool_verify_print_header( struct image_type_params *tparams, struct image_tool_params *params); +/** + * imagetool_save_datafile - store data into a file + * @file_name: name of the destination file + * @file_data: data to be written + * @file_len: the amount of data to store + * + * imagetool_save_datafile() store file_len bytes of data pointed by file_data + * into the file name by file_name. + * + * returns: + * zero in case of success or a negative value if fail. + */ +int imagetool_save_datafile( + const char *file_name, + ulong file_data, + ulong file_len); + /* * There is a c file associated with supported image type low level code * for ex. default_image.c, fit_image.c -- cgit From a93648d197df48fa46dd55f925ff70468bd81c71 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:48:07 -0200 Subject: imagetool: replace image registration function by linker_lists feature The registration was introduced in commit f86ed6a8d52c99bb2d17d3cac1647edca0c4399c This commit also removes all registration functions, and the member "next" from image_type_params struct Signed-off-by: Guilherme Maciel Ferreira --- tools/Makefile | 2 ++ tools/aisimage.c | 30 +++++++++---------- tools/atmelimage.c | 30 +++++++++---------- tools/default_image.c | 30 +++++++++---------- tools/dumpimage.c | 46 ++++------------------------- tools/fit_image.c | 30 +++++++++---------- tools/gpimage.c | 29 +++++++++---------- tools/imagetool.c | 72 ++++++++-------------------------------------- tools/imagetool.h | 80 +++++++++++++++++++++++++-------------------------- tools/imagetool.lds | 24 ++++++++++++++++ tools/imximage.c | 30 +++++++++---------- tools/kwbimage.c | 30 +++++++++---------- tools/mkimage.c | 44 ++-------------------------- tools/mxsimage.c | 35 +++++++++------------- tools/omapimage.c | 29 +++++++++---------- tools/pblimage.c | 30 +++++++++---------- tools/socfpgaimage.c | 30 +++++++++---------- tools/ublimage.c | 29 +++++++++---------- 18 files changed, 254 insertions(+), 376 deletions(-) create mode 100644 tools/imagetool.lds diff --git a/tools/Makefile b/tools/Makefile index e549f8e63c..cb44456cbd 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -122,6 +122,8 @@ HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage) HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage) HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage) +HOSTLDFLAGS += -T $(srctree)/tools/imagetool.lds + hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl HOSTCFLAGS_mkexynosspl.o := -pedantic diff --git a/tools/aisimage.c b/tools/aisimage.c index 8de370a2e0..9338342cb3 100644 --- a/tools/aisimage.c +++ b/tools/aisimage.c @@ -413,19 +413,17 @@ int aisimage_check_params(struct image_tool_params *params) /* * aisimage parameters */ -static struct image_type_params aisimage_params = { - .name = "TI Davinci AIS Boot Image support", - .header_size = 0, - .hdr = NULL, - .check_image_type = aisimage_check_image_types, - .verify_header = aisimage_verify_header, - .print_header = aisimage_print_header, - .set_header = aisimage_set_header, - .check_params = aisimage_check_params, - .vrec_header = aisimage_generate, -}; - -void init_ais_image_type(void) -{ - register_image_type(&aisimage_params); -} +U_BOOT_IMAGE_TYPE( + aisimage, + "TI Davinci AIS Boot Image support", + 0, + NULL, + aisimage_check_params, + aisimage_verify_header, + aisimage_print_header, + aisimage_set_header, + NULL, + aisimage_check_image_types, + NULL, + aisimage_generate +); diff --git a/tools/atmelimage.c b/tools/atmelimage.c index c8101d2ddc..5b72ac54a6 100644 --- a/tools/atmelimage.c +++ b/tools/atmelimage.c @@ -324,19 +324,17 @@ static int atmel_vrec_header(struct image_tool_params *params, return EXIT_SUCCESS; } -static struct image_type_params atmelimage_params = { - .name = "ATMEL ROM-Boot Image support", - .header_size = 0, - .hdr = NULL, - .check_image_type = atmel_check_image_type, - .verify_header = atmel_verify_header, - .print_header = atmel_print_header, - .set_header = atmel_set_header, - .check_params = atmel_check_params, - .vrec_header = atmel_vrec_header, -}; - -void init_atmel_image_type(void) -{ - register_image_type(&atmelimage_params); -} +U_BOOT_IMAGE_TYPE( + atmelimage, + "ATMEL ROM-Boot Image support", + 0, + NULL, + atmel_check_params, + atmel_verify_header, + atmel_print_header, + atmel_set_header, + NULL, + atmel_check_image_type, + NULL, + atmel_vrec_header +); diff --git a/tools/default_image.c b/tools/default_image.c index a92fa8015b..0b0e076831 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -150,19 +150,17 @@ static int image_extract_datafile(void *ptr, struct image_tool_params *params) /* * Default image type parameters definition */ -static struct image_type_params defimage_params = { - .name = "Default Image support", - .header_size = sizeof(image_header_t), - .hdr = (void*)&header, - .check_image_type = image_check_image_types, - .verify_header = image_verify_header, - .print_header = image_print_contents, - .set_header = image_set_header, - .extract_datafile = image_extract_datafile, - .check_params = image_check_params, -}; - -void init_default_image_type(void) -{ - register_image_type(&defimage_params); -} +U_BOOT_IMAGE_TYPE( + defimage, + "Default Image support", + sizeof(image_header_t), + (void *)&header, + image_check_params, + image_verify_header, + image_print_contents, + image_set_header, + image_extract_datafile, + image_check_image_types, + NULL, + NULL +); diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 0228e183ab..80bf583b39 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -20,41 +20,6 @@ static struct image_tool_params params = { .type = IH_TYPE_KERNEL, }; -/** - * dumpimage_register() - register respective image generation/list support - * - * the input struct image_type_params is checked and appended to the link - * list, if the input structure is already registered, issue an error - * - * @tparams: Image type parameters - */ -static void dumpimage_register(struct image_type_params *tparams) -{ - struct image_type_params **tp; - - if (!tparams) { - fprintf(stderr, "%s: %s: Null input\n", params.cmdname, - __func__); - exit(EXIT_FAILURE); - } - - /* scan the linked list, check for registry and point the last one */ - for (tp = &dumpimage_tparams; *tp != NULL; tp = &(*tp)->next) { - if (!strcmp((*tp)->name, tparams->name)) { - fprintf(stderr, "%s: %s already registered\n", - params.cmdname, tparams->name); - return; - } - } - - /* add input struct entry at the end of link list */ - *tp = tparams; - /* mark input entry as last entry in the link list */ - tparams->next = NULL; - - debug("Registered %s\n", tparams->name); -} - /* * dumpimage_extract_datafile - * @@ -70,8 +35,12 @@ static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf) { int retval = -1; struct image_type_params *curr; + struct image_type_params *start = ll_entry_start( + struct image_type_params, image_type); + struct image_type_params *end = ll_entry_end( + struct image_type_params, image_type); - for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) { + for (curr = start; curr != end; curr++) { if (curr->verify_header) { retval = curr->verify_header((unsigned char *)ptr, sbuf->st_size, ¶ms); @@ -104,9 +73,6 @@ int main(int argc, char **argv) int retval = 0; struct image_type_params *tparams = NULL; - /* Init all image generation/list support */ - register_image_tool(dumpimage_register); - params.cmdname = *argv; while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) { @@ -142,7 +108,7 @@ int main(int argc, char **argv) usage(); /* set tparams as per input type_id */ - tparams = imagetool_get_type(params.type, dumpimage_tparams); + tparams = imagetool_get_type(params.type); if (tparams == NULL) { fprintf(stderr, "%s: unsupported type %s\n", params.cmdname, genimg_get_type_name(params.type)); diff --git a/tools/fit_image.c b/tools/fit_image.c index 3ececf913f..5712842969 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -162,19 +162,17 @@ static int fit_check_params(struct image_tool_params *params) (params->lflag && (params->dflag || params->fflag))); } -static struct image_type_params fitimage_params = { - .name = "FIT Image support", - .header_size = sizeof(image_header_t), - .hdr = (void*)&header, - .verify_header = fit_verify_header, - .print_header = fit_print_contents, - .check_image_type = fit_check_image_types, - .fflag_handle = fit_handle_file, - .set_header = NULL, /* FIT images use DTB header */ - .check_params = fit_check_params, -}; - -void init_fit_image_type (void) -{ - register_image_type(&fitimage_params); -} +U_BOOT_IMAGE_TYPE( + fitimage, + "FIT Image support", + sizeof(image_header_t), + (void *)&header, + fit_check_params, + fit_verify_header, + fit_print_contents, + NULL, + NULL, + fit_check_image_types, + fit_handle_file, + NULL /* FIT images use DTB header */ +); diff --git a/tools/gpimage.c b/tools/gpimage.c index 1cabb5b612..1adc55c5fc 100644 --- a/tools/gpimage.c +++ b/tools/gpimage.c @@ -60,18 +60,17 @@ static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd, /* * gpimage parameters */ -static struct image_type_params gpimage_params = { - .name = "TI KeyStone GP Image support", - .header_size = GPIMAGE_HDR_SIZE, - .hdr = (void *)&gpimage_header, - .check_image_type = gpimage_check_image_types, - .verify_header = gpimage_verify_header, - .print_header = gpimage_print_header, - .set_header = gpimage_set_header, - .check_params = gpimage_check_params, -}; - -void init_gpimage_type(void) -{ - register_image_type(&gpimage_params); -} +U_BOOT_IMAGE_TYPE( + gpimage, + "TI KeyStone GP Image support", + GPIMAGE_HDR_SIZE, + (void *)&gpimage_header, + gpimage_check_params, + gpimage_verify_header, + gpimage_print_header, + gpimage_set_header, + NULL, + gpimage_check_image_types, + NULL, + NULL +); diff --git a/tools/imagetool.c b/tools/imagetool.c index a25b86b36e..9d2819ed68 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -10,68 +10,15 @@ #include -/* - * Callback function to register a image type within a tool - */ -static imagetool_register_t register_func; - -/* - * register_image_tool - - * - * The tool provides its own registration function in order to all image - * types initialize themselves. - */ -void register_image_tool(imagetool_register_t image_register) -{ - /* - * Save the image tool callback function. It will be used to register - * image types within that tool - */ - register_func = image_register; - - /* Init ATMEL ROM Boot Image generation/list support */ - init_atmel_image_type(); - /* Init Freescale PBL Boot image generation/list support */ - init_pbl_image_type(); - /* Init Kirkwood Boot image generation/list support */ - init_kwb_image_type(); - /* Init Freescale imx Boot image generation/list support */ - init_imx_image_type(); - /* Init Freescale mxs Boot image generation/list support */ - init_mxs_image_type(); - /* Init FIT image generation/list support */ - init_fit_image_type(); - /* Init TI OMAP Boot image generation/list support */ - init_omap_image_type(); - /* Init Default image generation/list support */ - init_default_image_type(); - /* Init Davinci UBL support */ - init_ubl_image_type(); - /* Init Davinci AIS support */ - init_ais_image_type(); - /* Init Altera SOCFPGA support */ - init_socfpga_image_type(); - /* Init TI Keystone boot image generation/list support */ - init_gpimage_type(); -} - -/* - * register_image_type - - * - * Register a image type within a tool - */ -void register_image_type(struct image_type_params *tparams) -{ - register_func(tparams); -} - -struct image_type_params *imagetool_get_type( - int type, - struct image_type_params *tparams) +struct image_type_params *imagetool_get_type(int type) { struct image_type_params *curr; + struct image_type_params *start = ll_entry_start( + struct image_type_params, image_type); + struct image_type_params *end = ll_entry_end( + struct image_type_params, image_type); - for (curr = tparams; curr != NULL; curr = curr->next) { + for (curr = start; curr != end; curr++) { if (curr->check_image_type) { if (!curr->check_image_type(type)) return curr; @@ -89,7 +36,12 @@ int imagetool_verify_print_header( int retval = -1; struct image_type_params *curr; - for (curr = tparams; curr != NULL; curr = curr->next) { + struct image_type_params *start = ll_entry_start( + struct image_type_params, image_type); + struct image_type_params *end = ll_entry_end( + struct image_type_params, image_type); + + for (curr = start; curr != end; curr++) { if (curr->verify_header) { retval = curr->verify_header((unsigned char *)ptr, sbuf->st_size, params); diff --git a/tools/imagetool.h b/tools/imagetool.h index 44d9380995..8724cb525f 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -19,6 +19,16 @@ #include #include #include + +/* define __KERNEL__ in order to get the definitions + * required by the linker list. This is probably not + * the best way to do this */ +#ifndef __KERNEL__ +#define __KERNEL__ +#include +#undef __KERNEL__ +#endif /* __KERNEL__ */ + #include "fdt_host.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -127,29 +137,8 @@ struct image_type_params { */ int (*vrec_header) (struct image_tool_params *, struct image_type_params *); - /* pointer to the next registered entry in linked list */ - struct image_type_params *next; }; -/* - * Tool registration function. - */ -typedef void (*imagetool_register_t)(struct image_type_params *); - -/* - * Initializes all image types with the given registration callback - * function. - * An image tool uses this function to initialize all image types. - */ -void register_image_tool(imagetool_register_t image_register); - -/* - * Register a image type within a tool. - * An image type uses this function to register itself within - * all tools. - */ -void register_image_type(struct image_type_params *tparams); - /** * imagetool_get_type() - find the image type params for a given image type * @@ -161,9 +150,7 @@ void register_image_type(struct image_type_params *tparams); * if input type_id is not supported by any of image_type_support * returns NULL */ -struct image_type_params *imagetool_get_type( - int type, - struct image_type_params *tparams); +struct image_type_params *imagetool_get_type(int type); /* * imagetool_verify_print_header() - verifies the image header @@ -201,24 +188,37 @@ int imagetool_save_datafile( /* * There is a c file associated with supported image type low level code * for ex. default_image.c, fit_image.c - * init_xxx_type() is the only function referred by image tool core to avoid - * a single lined header file, you can define them here - * - * Supported image types init functions */ -void init_default_image_type(void); -void init_atmel_image_type(void); -void init_pbl_image_type(void); -void init_ais_image_type(void); -void init_kwb_image_type(void); -void init_imx_image_type(void); -void init_mxs_image_type(void); -void init_fit_image_type(void); -void init_ubl_image_type(void); -void init_omap_image_type(void); -void init_socfpga_image_type(void); -void init_gpimage_type(void); + void pbl_load_uboot(int fd, struct image_tool_params *mparams); +#define U_BOOT_IMAGE_TYPE( \ + _id, \ + _name, \ + _header_size, \ + _header, \ + _check_params, \ + _verify_header, \ + _print_header, \ + _set_header, \ + _extract_datafile, \ + _check_image_type, \ + _fflag_handle, \ + _vrec_header \ + ) \ + ll_entry_declare(struct image_type_params, _id, image_type) = { \ + .name = _name, \ + .header_size = _header_size, \ + .hdr = _header, \ + .check_params = _check_params, \ + .verify_header = _verify_header, \ + .print_header = _print_header, \ + .set_header = _set_header, \ + .extract_datafile = _extract_datafile, \ + .check_image_type = _check_image_type, \ + .fflag_handle = _fflag_handle, \ + .vrec_header = _vrec_header \ + } + #endif /* _IMAGETOOL_H_ */ diff --git a/tools/imagetool.lds b/tools/imagetool.lds new file mode 100644 index 0000000000..7e92b4ac66 --- /dev/null +++ b/tools/imagetool.lds @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011-2012 The Chromium OS Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +SECTIONS +{ + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + __u_boot_sandbox_option_start = .; + _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } + __u_boot_sandbox_option_end = .; + + __bss_start = .; +} + +INSERT BEFORE .data; diff --git a/tools/imximage.c b/tools/imximage.c index 526b7d490d..3d37591886 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -694,19 +694,17 @@ static int imximage_generate(struct image_tool_params *params, /* * imximage parameters */ -static struct image_type_params imximage_params = { - .name = "Freescale i.MX Boot Image support", - .header_size = 0, - .hdr = NULL, - .check_image_type = imximage_check_image_types, - .verify_header = imximage_verify_header, - .print_header = imximage_print_header, - .set_header = imximage_set_header, - .check_params = imximage_check_params, - .vrec_header = imximage_generate, -}; - -void init_imx_image_type(void) -{ - register_image_type(&imximage_params); -} +U_BOOT_IMAGE_TYPE( + imximage, + "Freescale i.MX Boot Image support", + 0, + NULL, + imximage_check_params, + imximage_verify_header, + imximage_print_header, + imximage_set_header, + NULL, + imximage_check_image_types, + NULL, + imximage_generate +); diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 807d46668b..66f459ad6b 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -905,19 +905,17 @@ static int kwbimage_check_params(struct image_tool_params *params) /* * kwbimage type parameters definition */ -static struct image_type_params kwbimage_params = { - .name = "Marvell MVEBU Boot Image support", - .header_size = 0, /* no fixed header size */ - .hdr = NULL, - .vrec_header = kwbimage_generate, - .check_image_type = kwbimage_check_image_types, - .verify_header = kwbimage_verify_header, - .print_header = kwbimage_print_header, - .set_header = kwbimage_set_header, - .check_params = kwbimage_check_params, -}; - -void init_kwb_image_type (void) -{ - register_image_type(&kwbimage_params); -} +U_BOOT_IMAGE_TYPE( + kwbimage, + "Marvell MVEBU Boot Image support", + 0, + NULL, + kwbimage_check_params, + kwbimage_verify_header, + kwbimage_print_header, + kwbimage_set_header, + NULL, + kwbimage_check_image_types, + NULL, + kwbimage_generate +); diff --git a/tools/mkimage.c b/tools/mkimage.c index c04a2abee5..f668487c89 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -29,42 +29,6 @@ struct image_tool_params params = { .imagename2 = "", }; -/* - * mkimage_register - - * - * It is used to register respective image generation/list support to the - * mkimage core - * - * the input struct image_type_params is checked and appended to the link - * list, if the input structure is already registered, error - */ -void mkimage_register (struct image_type_params *tparams) -{ - struct image_type_params **tp; - - if (!tparams) { - fprintf (stderr, "%s: %s: Null input\n", - params.cmdname, __FUNCTION__); - exit (EXIT_FAILURE); - } - - /* scan the linked list, check for registry and point the last one */ - for (tp = &mkimage_tparams; *tp != NULL; tp = &(*tp)->next) { - if (!strcmp((*tp)->name, tparams->name)) { - fprintf (stderr, "%s: %s already registered\n", - params.cmdname, tparams->name); - return; - } - } - - /* add input struct entry at the end of link list */ - *tp = tparams; - /* mark input entry as last entry in the link list */ - tparams->next = NULL; - - debug ("Registered %s\n", tparams->name); -} - int main (int argc, char **argv) { @@ -75,9 +39,6 @@ main (int argc, char **argv) struct image_type_params *tparams = NULL; int pad_len = 0; - /* Init all image generation/list support */ - register_image_tool(mkimage_register); - params.cmdname = *argv; params.addr = params.ep = 0; @@ -215,7 +176,7 @@ NXTARG: ; usage (); /* set tparams as per input type_id */ - tparams = imagetool_get_type(params.type, mkimage_tparams); + tparams = imagetool_get_type(params.type); if (tparams == NULL) { fprintf (stderr, "%s: unsupported type %s\n", params.cmdname, genimg_get_type_name(params.type)); @@ -466,8 +427,7 @@ copy_file (int ifd, const char *datafile, int pad) uint8_t zeros[4096]; int offset = 0; int size; - struct image_type_params *tparams = imagetool_get_type(params.type, - mkimage_tparams); + struct image_type_params *tparams = imagetool_get_type(params.type); if (pad >= sizeof(zeros)) { fprintf(stderr, "%s: Can't pad to %d\n", diff --git a/tools/mxsimage.c b/tools/mxsimage.c index 04beefe05c..98fc64491c 100644 --- a/tools/mxsimage.c +++ b/tools/mxsimage.c @@ -2312,25 +2312,18 @@ fail: /* * mxsimage parameters */ -static struct image_type_params mxsimage_params = { - .name = "Freescale MXS Boot Image support", - .header_size = 0, - .hdr = NULL, - .check_image_type = mxsimage_check_image_types, - .verify_header = mxsimage_verify_header, - .print_header = mxsimage_print_header, - .set_header = mxsimage_set_header, - .check_params = mxsimage_check_params, - .vrec_header = mxsimage_generate, -}; - -void init_mxs_image_type(void) -{ - register_image_type(&mxsimage_params); -} - -#else -void init_mxs_image_type(void) -{ -} +U_BOOT_IMAGE_TYPE( + mxsimage, + "Freescale MXS Boot Image support", + 0, + NULL, + mxsimage_check_params, + mxsimage_verify_header, + mxsimage_print_header, + mxsimage_set_header, + NULL, + mxsimage_check_image_types, + NULL, + mxsimage_generate +); #endif diff --git a/tools/omapimage.c b/tools/omapimage.c index 1e0c164796..7198b3330d 100644 --- a/tools/omapimage.c +++ b/tools/omapimage.c @@ -162,18 +162,17 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, /* * omapimage parameters */ -static struct image_type_params omapimage_params = { - .name = "TI OMAP CH/GP Boot Image support", - .header_size = OMAP_FILE_HDR_SIZE, - .hdr = (void *)&omapimage_header, - .check_image_type = omapimage_check_image_types, - .verify_header = omapimage_verify_header, - .print_header = omapimage_print_header, - .set_header = omapimage_set_header, - .check_params = gpimage_check_params, -}; - -void init_omap_image_type(void) -{ - register_image_type(&omapimage_params); -} +U_BOOT_IMAGE_TYPE( + omapimage, + "TI OMAP CH/GP Boot Image support", + OMAP_FILE_HDR_SIZE, + (void *)&omapimage_header, + gpimage_check_params, + omapimage_verify_header, + omapimage_print_header, + omapimage_set_header, + NULL, + omapimage_check_image_types, + NULL, + NULL +); diff --git a/tools/pblimage.c b/tools/pblimage.c index 2a799ab4b6..d74fde9a44 100644 --- a/tools/pblimage.c +++ b/tools/pblimage.c @@ -308,19 +308,17 @@ int pblimage_check_params(struct image_tool_params *params) }; /* pblimage parameters */ -static struct image_type_params pblimage_params = { - .name = "Freescale PBL Boot Image support", - .header_size = sizeof(struct pbl_header), - .hdr = (void *)&pblimage_header, - .check_image_type = pblimage_check_image_types, - .check_params = pblimage_check_params, - .verify_header = pblimage_verify_header, - .print_header = pblimage_print_header, - .set_header = pblimage_set_header, -}; - -void init_pbl_image_type(void) -{ - pbl_size = 0; - register_image_type(&pblimage_params); -} +U_BOOT_IMAGE_TYPE( + pblimage, + "Freescale PBL Boot Image support", + sizeof(struct pbl_header), + (void *)&pblimage_header, + pblimage_check_params, + pblimage_verify_header, + pblimage_print_header, + pblimage_set_header, + NULL, + pblimage_check_image_types, + NULL, + NULL +); diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c index 917873e7b3..652ae45f81 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -241,19 +241,17 @@ static void socfpgaimage_set_header(void *ptr, struct stat *sbuf, int ifd, sign_buffer(buf, 0, 0, data_size, 0); } -static struct image_type_params socfpgaimage_params = { - .name = "Altera SOCFPGA preloader support", - .vrec_header = socfpgaimage_vrec_header, - .header_size = 0, /* This will be modified by vrec_header() */ - .hdr = (void *)buffer, - .check_image_type = socfpgaimage_check_image_types, - .verify_header = socfpgaimage_verify_header, - .print_header = socfpgaimage_print_header, - .set_header = socfpgaimage_set_header, - .check_params = socfpgaimage_check_params, -}; - -void init_socfpga_image_type(void) -{ - register_image_type(&socfpgaimage_params); -} +U_BOOT_IMAGE_TYPE( + socfpgaimage, + "Altera SOCFPGA preloader support", + 0, /* This will be modified by vrec_header() */ + (void *)buffer, + socfpgaimage_check_params, + socfpgaimage_verify_header, + socfpgaimage_print_header, + socfpgaimage_set_header, + NULL, + socfpgaimage_check_image_types, + NULL, + socfpgaimage_vrec_header +); diff --git a/tools/ublimage.c b/tools/ublimage.c index cbbbe205da..6ed1eef29c 100644 --- a/tools/ublimage.c +++ b/tools/ublimage.c @@ -244,18 +244,17 @@ int ublimage_check_params(struct image_tool_params *params) /* * ublimage parameters */ -static struct image_type_params ublimage_params = { - .name = "Davinci UBL boot support", - .header_size = sizeof(struct ubl_header), - .hdr = (void *)&ublimage_header, - .check_image_type = ublimage_check_image_types, - .verify_header = ublimage_verify_header, - .print_header = ublimage_print_header, - .set_header = ublimage_set_header, - .check_params = ublimage_check_params, -}; - -void init_ubl_image_type(void) -{ - register_image_type(&ublimage_params); -} +U_BOOT_IMAGE_TYPE( + ublimage, + "Davinci UBL boot support", + sizeof(struct ubl_header), + (void *)&ublimage_header, + ublimage_check_params, + ublimage_verify_header, + ublimage_print_header, + ublimage_set_header, + NULL, + ublimage_check_image_types, + NULL, + NULL +); -- cgit From f41f5b7c055865bae32129d005fed073315d589a Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:54:40 -0200 Subject: dumpimage: add 'T' option to explicitly set the image type Some image types, like "KeyStone GP", do not have magic numbers to distinguish them from other image types. Thus, the automatic image type discovery does not work correctly. This patch also fix some integer type mismatches. Signed-off-by: Guilherme Maciel Ferreira --- README | 7 +++-- test/image/test-imagetools.sh | 48 +++++++++++++++-------------- tools/dumpimage.c | 70 +++++++++++++++++++++---------------------- tools/gpimage-common.c | 3 +- tools/mkimage.c | 3 -- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/README b/README index fefa71c0a6..a11e74aff1 100644 --- a/README +++ b/README @@ -5899,9 +5899,10 @@ option performs the converse operation of the mkimage's second form (the "-d" option). Given an image built by mkimage, the dumpimage extracts a "data file" from the image: - tools/dumpimage -i image -p position data_file - -i ==> extract from the 'image' a specific 'data_file', \ - indexed by 'position' + tools/dumpimage -i image -T type -p position data_file + -i ==> extract from the 'image' a specific 'data_file' + -T ==> set image type to 'type' + -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image' Installing a Linux Image: diff --git a/test/image/test-imagetools.sh b/test/image/test-imagetools.sh index 9e299e1e57..8aaaade5a0 100755 --- a/test/image/test-imagetools.sh +++ b/test/image/test-imagetools.sh @@ -13,9 +13,9 @@ # ./test/image/test-imagetools.sh BASEDIR=sandbox -SRCDIR=sandbox/boot +SRCDIR=${BASEDIR}/boot IMAGE_NAME="v1.0-test" -IMAGE=linux.img +IMAGE_MULTI=linux.img DATAFILE0=vmlinuz DATAFILE1=initrd.img DATAFILE2=System.map @@ -34,14 +34,14 @@ cleanup() for file in ${DATAFILES}; do rm -f ${file} ${SRCDIR}/${file} done - rm -f ${IMAGE} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} + rm -f ${IMAGE_MULTI} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} rmdir ${SRCDIR} } # Check that two files are the same assert_equal() { - if ! diff $1 $2; then + if ! diff -u $1 $2; then echo "Failed." cleanup exit 1 @@ -82,35 +82,39 @@ do_cmd_redir() ${cmd} >${redir} } -# Write files into an image -create_image() +# Write files into an multi-file image +create_multi_image() { local files="${SRCDIR}/${DATAFILE0}:${SRCDIR}/${DATAFILE1}" files+=":${SRCDIR}/${DATAFILE2}" - echo -e "\nBuilding image..." + echo -e "\nBuilding multi-file image..." do_cmd ${MKIMAGE} -A x86 -O linux -T multi -n \"${IMAGE_NAME}\" \ - -d ${files} ${IMAGE} + -d ${files} ${IMAGE_MULTI} echo "done." } -# Extract files from an image -extract_image() +# Extract files from an multi-file image +extract_multi_image() { - echo -e "\nExtracting image contents..." - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 0 ${DATAFILE0} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 1 ${DATAFILE1} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2} -o ${TEST_OUT} + echo -e "\nExtracting multi-file image contents..." + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 0 ${DATAFILE0} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 1 ${DATAFILE1} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2} -o ${TEST_OUT} echo "done." } # List the contents of a file +# Args: +# image filename list_image() { + local image="$1" + echo -e "\nListing image contents..." - do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${IMAGE} - do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${IMAGE} + do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${image} + do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${image} echo "done." } @@ -120,16 +124,16 @@ main() create_files - # Compress and extract multifile images, compare the result - create_image - extract_image + # Compress and extract multi-file images, compare the result + create_multi_image + extract_multi_image for file in ${DATAFILES}; do assert_equal ${file} ${SRCDIR}/${file} done assert_equal ${TEST_OUT} ${DATAFILE2} - # List contents and compares output fro tools - list_image + # List contents of multi-file image and compares output from tools + list_image ${IMAGE_MULTI} assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} # Remove files created diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 80bf583b39..8f1527a9e7 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -12,9 +12,6 @@ static void usage(void); -/* image_type_params linked list to maintain registered image types supports */ -static struct image_type_params *dumpimage_tparams; - /* parameters initialized by core will be used by the image type code */ static struct image_tool_params params = { .type = IH_TYPE_KERNEL, @@ -31,33 +28,27 @@ static struct image_tool_params params = { * returns negative if input image format does not match with any of * supported image types */ -static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf) +static int dumpimage_extract_datafile(struct image_type_params *tparams, + void *ptr, struct stat *sbuf) { int retval = -1; - struct image_type_params *curr; - struct image_type_params *start = ll_entry_start( - struct image_type_params, image_type); - struct image_type_params *end = ll_entry_end( - struct image_type_params, image_type); - - for (curr = start; curr != end; curr++) { - if (curr->verify_header) { - retval = curr->verify_header((unsigned char *)ptr, - sbuf->st_size, ¶ms); - if (retval != 0) - continue; - /* - * Extract the file from the image - * if verify is successful - */ - if (curr->extract_datafile) { - curr->extract_datafile(ptr, ¶ms); - } else { - fprintf(stderr, - "%s: extract_datafile undefined for %s\n", - params.cmdname, curr->name); - break; - } + + if (tparams->verify_header) { + retval = tparams->verify_header((unsigned char *)ptr, + sbuf->st_size, ¶ms); + if (retval != 0) + return -1; + /* + * Extract the file from the image + * if verify is successful + */ + if (tparams->extract_datafile) { + retval = tparams->extract_datafile(ptr, ¶ms); + } else { + fprintf(stderr, + "%s: extract_datafile undefined for %s\n", + params.cmdname, tparams->name); + return -2; } } @@ -75,7 +66,7 @@ int main(int argc, char **argv) params.cmdname = *argv; - while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) { + while ((opt = getopt(argc, argv, "li:o:T:p:V")) != -1) { switch (opt) { case 'l': params.lflag = 1; @@ -87,6 +78,12 @@ int main(int argc, char **argv) case 'o': params.outfile = optarg; break; + case 'T': + params.type = genimg_get_type_id(optarg); + if (params.type < 0) { + usage(); + } + break; case 'p': params.pflag = strtoul(optarg, &ptr, 10); if (*ptr) { @@ -101,6 +98,7 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); default: usage(); + break; } } @@ -110,7 +108,7 @@ int main(int argc, char **argv) /* set tparams as per input type_id */ tparams = imagetool_get_type(params.type); if (tparams == NULL) { - fprintf(stderr, "%s: unsupported type %s\n", + fprintf(stderr, "%s: unsupported type: %s\n", params.cmdname, genimg_get_type_name(params.type)); exit(EXIT_FAILURE); } @@ -147,7 +145,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - if ((unsigned)sbuf.st_size < tparams->header_size) { + if ((uint32_t)sbuf.st_size < tparams->header_size) { fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n", params.cmdname, params.imagefile); @@ -172,7 +170,8 @@ int main(int argc, char **argv) * Extract the data files from within the matched * image type. Returns the error code if not matched */ - retval = dumpimage_extract_datafile(ptr, &sbuf); + retval = dumpimage_extract_datafile(tparams, ptr, + &sbuf); } else { /* * Print the image information for matched image type @@ -199,9 +198,10 @@ static void usage(void) " -l ==> list image header information\n", params.cmdname); fprintf(stderr, - " %s -i image [-p position] [-o outfile] data_file\n" - " -i ==> extract from the 'image' a specific 'data_file'" - ", indexed by 'position' (starting at 0)\n", + " %s -i image -T type [-p position] [-o outfile] data_file\n" + " -i ==> extract from the 'image' a specific 'data_file'\n" + " -T ==> set image type to 'type'\n" + " -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'\n", params.cmdname); fprintf(stderr, " %s -V ==> print version information and exit\n", diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c index b343a3aa8b..5ad52be437 100644 --- a/tools/gpimage-common.c +++ b/tools/gpimage-common.c @@ -32,7 +32,8 @@ void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr) int gph_verify_header(struct gp_header *gph, int be) { - uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr; + uint32_t gph_size = gph->size; + uint32_t gph_load_addr = gph->load_addr; if (be) to_be32(&gph_size, &gph_load_addr); diff --git a/tools/mkimage.c b/tools/mkimage.c index f668487c89..5ccd951048 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -15,9 +15,6 @@ static void copy_file(int, const char *, int); static void usage(void); -/* image_type_params link list to maintain registered image type supports */ -struct image_type_params *mkimage_tparams = NULL; - /* parameters initialized by core will be used by the image type code */ struct image_tool_params params = { .os = IH_OS_LINUX, -- cgit From 67f946cd18ce56a7caf6195834334a585a669056 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:54:41 -0200 Subject: dumpimage: replace the term "datafile" by "subimage" Signed-off-by: Guilherme Maciel Ferreira --- tools/default_image.c | 6 +++--- tools/dumpimage.c | 12 ++++++------ tools/imagetool.c | 2 +- tools/imagetool.h | 17 +++++++++-------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/tools/default_image.c b/tools/default_image.c index 0b0e076831..2298f91624 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -117,7 +117,7 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_hcrc(hdr, checksum); } -static int image_extract_datafile(void *ptr, struct image_tool_params *params) +static int image_extract_subimage(void *ptr, struct image_tool_params *params) { const image_header_t *hdr = (const image_header_t *)ptr; ulong file_data; @@ -144,7 +144,7 @@ static int image_extract_datafile(void *ptr, struct image_tool_params *params) } /* save the "data file" into the file system */ - return imagetool_save_datafile(params->outfile, file_data, file_len); + return imagetool_save_subimage(params->outfile, file_data, file_len); } /* @@ -159,7 +159,7 @@ U_BOOT_IMAGE_TYPE( image_verify_header, image_print_contents, image_set_header, - image_extract_datafile, + image_extract_subimage, image_check_image_types, NULL, NULL diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 8f1527a9e7..75a5d4762c 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -18,7 +18,7 @@ static struct image_tool_params params = { }; /* - * dumpimage_extract_datafile - + * dumpimage_extract_subimage - * * It scans all registered image types, * verifies image_header for each supported image type @@ -28,7 +28,7 @@ static struct image_tool_params params = { * returns negative if input image format does not match with any of * supported image types */ -static int dumpimage_extract_datafile(struct image_type_params *tparams, +static int dumpimage_extract_subimage(struct image_type_params *tparams, void *ptr, struct stat *sbuf) { int retval = -1; @@ -42,11 +42,11 @@ static int dumpimage_extract_datafile(struct image_type_params *tparams, * Extract the file from the image * if verify is successful */ - if (tparams->extract_datafile) { - retval = tparams->extract_datafile(ptr, ¶ms); + if (tparams->extract_subimage) { + retval = tparams->extract_subimage(ptr, ¶ms); } else { fprintf(stderr, - "%s: extract_datafile undefined for %s\n", + "%s: extract_subimage undefined for %s\n", params.cmdname, tparams->name); return -2; } @@ -170,7 +170,7 @@ int main(int argc, char **argv) * Extract the data files from within the matched * image type. Returns the error code if not matched */ - retval = dumpimage_extract_datafile(tparams, ptr, + retval = dumpimage_extract_subimage(tparams, ptr, &sbuf); } else { /* diff --git a/tools/imagetool.c b/tools/imagetool.c index 9d2819ed68..148e4662b7 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -66,7 +66,7 @@ int imagetool_verify_print_header( return retval; } -int imagetool_save_datafile( +int imagetool_save_subimage( const char *file_name, ulong file_data, ulong file_len) diff --git a/tools/imagetool.h b/tools/imagetool.h index 8724cb525f..f35dec71c7 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -110,14 +110,15 @@ struct image_type_params { void (*set_header) (void *, struct stat *, int, struct image_tool_params *); /* - * This function is used by the command to retrieve a data file from - * the image (i.e. dumpimage -i -p ). + * This function is used by the command to retrieve a component + * (sub-image) from the image (i.e. dumpimage -i -p + * ). * Thus the code to extract a file from an image must be put here. * * Returns 0 if the file was successfully retrieved from the image, * or a negative value on error. */ - int (*extract_datafile) (void *, struct image_tool_params *); + int (*extract_subimage)(void *, struct image_tool_params *); /* * Some image generation support for ex (default image type) supports * more than one type_ids, this callback function is used to check @@ -169,18 +170,18 @@ int imagetool_verify_print_header( struct image_tool_params *params); /** - * imagetool_save_datafile - store data into a file + * imagetool_save_subimage - store data into a file * @file_name: name of the destination file * @file_data: data to be written * @file_len: the amount of data to store * - * imagetool_save_datafile() store file_len bytes of data pointed by file_data + * imagetool_save_subimage() store file_len bytes of data pointed by file_data * into the file name by file_name. * * returns: * zero in case of success or a negative value if fail. */ -int imagetool_save_datafile( +int imagetool_save_subimage( const char *file_name, ulong file_data, ulong file_len); @@ -202,7 +203,7 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); _verify_header, \ _print_header, \ _set_header, \ - _extract_datafile, \ + _extract_subimage, \ _check_image_type, \ _fflag_handle, \ _vrec_header \ @@ -215,7 +216,7 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); .verify_header = _verify_header, \ .print_header = _print_header, \ .set_header = _set_header, \ - .extract_datafile = _extract_datafile, \ + .extract_subimage = _extract_subimage, \ .check_image_type = _check_image_type, \ .fflag_handle = _fflag_handle, \ .vrec_header = _vrec_header \ -- cgit From 39931f966adaeadd66dc7a905f7dddb93f66bac3 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:54:42 -0200 Subject: dumpimage: fit: extract FIT images The dumpimage is able to extract components contained in a FIT image: $ ./dumpimage -T flat_dt -i CONTAINER.ITB -p INDEX FILE The CONTAINER.ITB is a regular FIT container file. The INDEX is the poisition of the sub-image to be retrieved, and FILE is the file (path+name) to save the extracted sub-image. For example, given the following kernel.its to build a kernel.itb: /dts-v1/; / { ... images { kernel@1 { description = "Kernel 2.6.32-34"; data = /incbin/("/boot/vmlinuz-2.6.32-34-generic"); type = "kernel"; arch = "ppc"; os = "linux"; compression = "gzip"; load = <00000000>; entry = <00000000>; hash@1 { algo = "md5"; }; }; ... }; ... }; The dumpimage can extract the 'kernel@1' node through the following command: $ ./dumpimage -T flat_dt -i kernel.itb -p 0 kernel Extracted: Image 0 (kernel@1) Description: Kernel 2.6.32-34 Created: Wed Oct 22 15:50:26 2014 Type: Kernel Image Compression: gzip compressed Data Size: 4040128 Bytes = 3945.44 kB = 3.85 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: md5 Hash value: 22352ad39bdc03e2e50f9cc28c1c3652 Which results in the file 'kernel' being exactly the same as '/boot/vmlinuz-2.6.32-34-generic'. Signed-off-by: Guilherme Maciel Ferreira --- common/image-fit.c | 30 +++++++++++++- include/image.h | 1 + test/image/test-imagetools.sh | 83 +++++++++++++++++++++++++++++++++++++- tools/fit_image.c | 93 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 204 insertions(+), 3 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index 1589ee3e4f..b47d11024f 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -112,6 +112,33 @@ static void fit_get_debug(const void *fit, int noffset, fdt_strerror(err)); } +/** + * fit_get_subimage_count - get component (sub-image) count + * @fit: pointer to the FIT format image header + * @images_noffset: offset of images node + * + * returns: + * number of image components + */ +int fit_get_subimage_count(const void *fit, int images_noffset) +{ + int noffset; + int ndepth; + int count = 0; + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + count++; + } + } + + return count; +} + #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) /** * fit_print_contents - prints out the contents of the FIT format image @@ -423,7 +450,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) } } } -#endif + +#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */ /** * fit_get_desc - get node description property diff --git a/include/image.h b/include/image.h index ee3afe3567..d8618962fb 100644 --- a/include/image.h +++ b/include/image.h @@ -751,6 +751,7 @@ int fit_parse_conf(const char *spec, ulong addr_curr, int fit_parse_subimage(const char *spec, ulong addr_curr, ulong *addr, const char **image_name); +int fit_get_subimage_count(const void *fit, int images_noffset); void fit_print_contents(const void *fit); void fit_image_print(const void *fit, int noffset, const char *p); diff --git a/test/image/test-imagetools.sh b/test/image/test-imagetools.sh index 8aaaade5a0..952f975af1 100755 --- a/test/image/test-imagetools.sh +++ b/test/image/test-imagetools.sh @@ -16,6 +16,8 @@ BASEDIR=sandbox SRCDIR=${BASEDIR}/boot IMAGE_NAME="v1.0-test" IMAGE_MULTI=linux.img +IMAGE_FIT_ITS=linux.its +IMAGE_FIT_ITB=linux.itb DATAFILE0=vmlinuz DATAFILE1=initrd.img DATAFILE2=System.map @@ -34,7 +36,10 @@ cleanup() for file in ${DATAFILES}; do rm -f ${file} ${SRCDIR}/${file} done - rm -f ${IMAGE_MULTI} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} + rm -f ${IMAGE_MULTI} + rm -f ${DUMPIMAGE_LIST} + rm -f ${MKIMAGE_LIST} + rm -f ${TEST_OUT} rmdir ${SRCDIR} } @@ -105,6 +110,70 @@ extract_multi_image() echo "done." } +# Write files into a FIT image +create_fit_image() +{ + echo " \ + /dts-v1/; \ + / { \ + description = \"FIT image\"; \ + #address-cells = <1>; \ + \ + images { \ + kernel@1 { \ + description = \"kernel\"; \ + data = /incbin/(\"${DATAFILE0}\"); \ + type = \"kernel\"; \ + arch = \"sandbox\"; \ + os = \"linux\"; \ + compression = \"gzip\"; \ + load = <0x40000>; \ + entry = <0x8>; \ + }; \ + ramdisk@1 { \ + description = \"filesystem\"; \ + data = /incbin/(\"${DATAFILE1}\"); \ + type = \"ramdisk\"; \ + arch = \"sandbox\"; \ + os = \"linux\"; \ + compression = \"none\"; \ + load = <0x80000>; \ + entry = <0x16>; \ + }; \ + fdt@1 { \ + description = \"device tree\"; \ + data = /incbin/(\"${DATAFILE2}\"); \ + type = \"flat_dt\"; \ + arch = \"sandbox\"; \ + compression = \"none\"; \ + }; \ + }; \ + configurations { \ + default = \"conf@1\"; \ + conf@1 { \ + kernel = \"kernel@1\"; \ + fdt = \"fdt@1\"; \ + }; \ + }; \ + }; \ + " > ${IMAGE_FIT_ITS} + + echo -e "\nBuilding FIT image..." + do_cmd ${MKIMAGE} -f ${IMAGE_FIT_ITS} ${IMAGE_FIT_ITB} + echo "done." +} + +# Extract files from a FIT image +extract_fit_image() +{ + echo -e "\nExtracting FIT image contents..." + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 0 ${DATAFILE0} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 1 ${DATAFILE1} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2} -o ${TEST_OUT} + echo "done." +} + # List the contents of a file # Args: # image filename @@ -136,6 +205,18 @@ main() list_image ${IMAGE_MULTI} assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} + # Compress and extract FIT images, compare the result + create_fit_image + extract_fit_image + for file in ${DATAFILES}; do + assert_equal ${file} ${SRCDIR}/${file} + done + assert_equal ${TEST_OUT} ${DATAFILE2} + + # List contents of FIT image and compares output from tools + list_image ${IMAGE_FIT_ITB} + assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} + # Remove files created cleanup diff --git a/tools/fit_image.c b/tools/fit_image.c index 5712842969..eb2a25eeac 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -155,6 +155,97 @@ err_system: return -1; } +/** + * fit_image_extract - extract a FIT component image + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @file_name: name of the file to store the FIT sub-image + * + * returns: + * zero in case of success or a negative value if fail. + */ +static int fit_image_extract( + const void *fit, + int image_noffset, + const char *file_name) +{ + const void *file_data; + size_t file_size = 0; + + /* get the "data" property of component at offset "image_noffset" */ + fit_image_get_data(fit, image_noffset, &file_data, &file_size); + + /* save the "file_data" into the file specified by "file_name" */ + return imagetool_save_subimage(file_name, (ulong) file_data, file_size); +} + +/** + * fit_extract_contents - retrieve a sub-image component from the FIT image + * @ptr: pointer to the FIT format image header + * @params: command line parameters + * + * returns: + * zero in case of success or a negative value if fail. + */ +static int fit_extract_contents(void *ptr, struct image_tool_params *params) +{ + int images_noffset; + int noffset; + int ndepth; + const void *fit = ptr; + int count = 0; + const char *p; + + /* Indent string is defined in header image.h */ + p = IMAGE_INDENT_STRING; + + if (!fit_check_format(fit)) { + printf("Bad FIT image format\n"); + return -1; + } + + /* Find images parent node offset */ + images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror(images_noffset)); + return -1; + } + + /* Avoid any overrun */ + count = fit_get_subimage_count(fit, images_noffset); + if ((params->pflag < 0) || (count <= params->pflag)) { + printf("No such component at '%d'\n", params->pflag); + return -1; + } + + /* Process its subnodes, extract the desired component from image */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + if (params->pflag == count) { + printf("Extracted:\n%s Image %u (%s)\n", p, + count, fit_get_name(fit, noffset, NULL)); + + fit_image_print(fit, noffset, p); + + return fit_image_extract(fit, noffset, + params->outfile); + } + + count++; + } + } + + return 0; +} + static int fit_check_params(struct image_tool_params *params) { return ((params->dflag && (params->fflag || params->lflag)) || @@ -171,7 +262,7 @@ U_BOOT_IMAGE_TYPE( fit_verify_header, fit_print_contents, NULL, - NULL, + fit_extract_contents, fit_check_image_types, fit_handle_file, NULL /* FIT images use DTB header */ -- cgit From 2662179998e4f7c2c67f00527c3af5123816bd49 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Thu, 15 Jan 2015 02:54:43 -0200 Subject: tools: do not print error messages in verify_header() functions default_image.c and socfpgaimage.c are the only image modules that print error messages during header verification. The verify_header() is used to query if a given image file is processed by the image format. Thus, if the image format can't handle the file, it must simply return an error. Otherwise we pollute the screen with errors messages until we find the image format that handle a given image file. Signed-off-by: Guilherme Maciel Ferreira --- tools/default_image.c | 17 ++++++++--------- tools/socfpgaimage.c | 6 ++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tools/default_image.c b/tools/default_image.c index 2298f91624..cf5c0d4393 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -15,6 +15,8 @@ */ #include "imagetool.h" +#include "mkimage.h" + #include #include @@ -53,9 +55,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, memcpy(hdr, ptr, sizeof(image_header_t)); if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { - fprintf(stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - params->cmdname, params->imagefile); + debug("%s: Bad Magic Number: \"%s\" is no valid image\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADMAGIC; } @@ -66,9 +67,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */ if (crc32(0, data, len) != checksum) { - fprintf(stderr, - "%s: ERROR: \"%s\" has bad header checksum!\n", - params->cmdname, params->imagefile); + debug("%s: ERROR: \"%s\" has bad header checksum!\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADSTATE; } @@ -77,9 +77,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, checksum = be32_to_cpu(hdr->ih_dcrc); if (crc32(0, data, len) != checksum) { - fprintf(stderr, - "%s: ERROR: \"%s\" has corrupted data!\n", - params->cmdname, params->imagefile); + debug("%s: ERROR: \"%s\" has corrupted data!\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADSTRUCTURE; } return 0; diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c index 652ae45f81..8fe91fe80e 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -33,6 +33,8 @@ #include "pbl_crc32.h" #include "imagetool.h" +#include "mkimage.h" + #include #define HEADER_OFFSET 0x40 @@ -133,12 +135,12 @@ static int verify_buffer(const uint8_t *buf) len = verify_header(buf + HEADER_OFFSET); if (len < 0) { - fprintf(stderr, "Invalid header\n"); + debug("Invalid header\n"); return -1; } if (len < HEADER_OFFSET || len > PADDED_SIZE) { - fprintf(stderr, "Invalid header length (%i)\n", len); + debug("Invalid header length (%i)\n", len); return -1; } -- cgit From e3046ba4daa4a4e5b7aedd9a1aa3b8d72e5ad559 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 15 Jan 2015 09:53:13 +0100 Subject: common: bootm: Document fake bootm sub-command Fake option is enabled only when CONFIG_TRACE is enabled in common/bootm.c:do_boot_states(). Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- common/cmd_bootm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 67233600b1..48199bfff3 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -185,6 +185,9 @@ static char bootm_help_text[] = "\tcmdline - OS specific command line processing/setup\n" "\tbdt - OS specific bd_t processing\n" "\tprep - OS specific prep before relocation or go\n" +#if defined(CONFIG_TRACE) + "\tfake - OS specific fake start without go\n" +#endif "\tgo - start OS"; #endif -- cgit From b6036bcd2ac27b3497ec16a63456eb4ed2b23e9f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jan 2015 12:44:35 +0900 Subject: i2c: add CONFIG_DM_I2C to Kconfig Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Acked-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index e69de29bb2..96715d0eed 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -0,0 +1,6 @@ +config DM_I2C + bool "Enable Driver Model for I2C drivers" + depends on DM + help + If you want to use driver model for I2C drivers, say Y. + To use legacy I2C drivers, say N. -- cgit From 26f820f3f149ffb2577592eae50d2bdb04e5203f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jan 2015 12:44:36 +0900 Subject: i2c: UniPhier: add driver for UniPhier i2c controller This commit adds on-chip I2C driver used on some old Panasonic UniPhier SoCs. Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Acked-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/Kconfig | 8 ++ drivers/i2c/Makefile | 1 + drivers/i2c/i2c-uniphier.c | 239 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 drivers/i2c/i2c-uniphier.c diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 96715d0eed..6a479efd7c 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -4,3 +4,11 @@ config DM_I2C help If you want to use driver model for I2C drivers, say Y. To use legacy I2C drivers, say N. + +config SYS_I2C_UNIPHIER + bool "UniPhier I2C driver" + depends on ARCH_UNIPHIER && DM_I2C + default y + help + Support for Panasonic UniPhier I2C controller driver. This I2C + controller is used on PH1-LD4, PH1-sLD8 or older UniPhier SoCs. diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 6f3c86c038..e2fcd24ef3 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -31,4 +31,5 @@ obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o +obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c new file mode 100644 index 0000000000..bdac1f9079 --- /dev/null +++ b/drivers/i2c/i2c-uniphier.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct uniphier_i2c_regs { + u32 dtrm; /* data transmission */ +#define I2C_DTRM_STA (1 << 10) +#define I2C_DTRM_STO (1 << 9) +#define I2C_DTRM_NACK (1 << 8) +#define I2C_DTRM_RD (1 << 0) + u32 drec; /* data reception */ +#define I2C_DREC_STS (1 << 12) +#define I2C_DREC_LRB (1 << 11) +#define I2C_DREC_LAB (1 << 9) + u32 myad; /* slave address */ + u32 clk; /* clock frequency control */ + u32 brst; /* bus reset */ +#define I2C_BRST_FOEN (1 << 1) +#define I2C_BRST_BRST (1 << 0) + u32 hold; /* hold time control */ + u32 bsts; /* bus status monitor */ + u32 noise; /* noise filter control */ + u32 setup; /* setup time control */ +}; + +#define IOBUS_FREQ 100000000 + +struct uniphier_i2c_dev { + struct uniphier_i2c_regs __iomem *regs; /* register base */ + unsigned long input_clk; /* master clock (Hz) */ + unsigned long wait_us; /* wait for every byte transfer (us) */ +}; + +static int uniphier_i2c_probe(struct udevice *dev) +{ + fdt_addr_t addr; + fdt_size_t size; + struct uniphier_i2c_dev *priv = dev_get_priv(dev); + + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size); + + priv->regs = map_sysmem(addr, size); + + if (!priv->regs) + return -ENOMEM; + + priv->input_clk = IOBUS_FREQ; + + /* deassert reset */ + writel(0x3, &priv->regs->brst); + + return 0; +} + +static int uniphier_i2c_remove(struct udevice *dev) +{ + struct uniphier_i2c_dev *priv = dev_get_priv(dev); + + unmap_sysmem(priv->regs); + + return 0; +} + +static int uniphier_i2c_child_pre_probe(struct udevice *dev) +{ + struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); + + if (dev->of_offset == -1) + return 0; + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, + i2c_chip); +} + +static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm) +{ + writel(dtrm, &dev->regs->dtrm); + + /* + * This controller only provides interruption to inform the completion + * of each byte transfer. (No status register to poll it.) + * Unfortunately, U-Boot does not have a good support of interrupt. + * Wait for a while. + */ + udelay(dev->wait_us); + + return readl(&dev->regs->drec); +} + +static int send_byte(struct uniphier_i2c_dev *dev, u32 dtrm, bool *stop) +{ + int ret = 0; + u32 drec; + + drec = send_and_recv_byte(dev, dtrm); + + if (drec & I2C_DREC_LAB) { + debug("uniphier_i2c: bus arbitration failed\n"); + *stop = false; + ret = -EREMOTEIO; + } + if (drec & I2C_DREC_LRB) { + debug("uniphier_i2c: slave did not return ACK\n"); + ret = -EREMOTEIO; + } + return ret; +} + +static int uniphier_i2c_transmit(struct uniphier_i2c_dev *dev, uint addr, + uint len, const u8 *buf, bool *stop) +{ + int ret; + + debug("%s: addr = %x, len = %d\n", __func__, addr, len); + + ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK | addr << 1, stop); + if (ret < 0) + goto fail; + + while (len--) { + ret = send_byte(dev, I2C_DTRM_NACK | *buf++, stop); + if (ret < 0) + goto fail; + } + +fail: + if (*stop) + writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm); + + return ret; +} + +static int uniphier_i2c_receive(struct uniphier_i2c_dev *dev, uint addr, + uint len, u8 *buf, bool *stop) +{ + int ret; + + debug("%s: addr = %x, len = %d\n", __func__, addr, len); + + ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK | + I2C_DTRM_RD | addr << 1, stop); + if (ret < 0) + goto fail; + + while (len--) + *buf++ = send_and_recv_byte(dev, len ? 0 : I2C_DTRM_NACK); + +fail: + if (*stop) + writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm); + + return ret; +} + +static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, + int nmsgs) +{ + int ret = 0; + struct uniphier_i2c_dev *dev = dev_get_priv(bus); + bool stop; + + for (; nmsgs > 0; nmsgs--, msg++) { + /* If next message is read, skip the stop condition */ + stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true; + + if (msg->flags & I2C_M_RD) + ret = uniphier_i2c_receive(dev, msg->addr, msg->len, + msg->buf, &stop); + else + ret = uniphier_i2c_transmit(dev, msg->addr, msg->len, + msg->buf, &stop); + + if (ret < 0) + break; + } + + return ret; +} + +static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) +{ + struct uniphier_i2c_dev *priv = dev_get_priv(bus); + + /* max supported frequency is 400 kHz */ + if (speed > 400000) + return -EINVAL; + + /* bus reset: make sure the bus is idle when change the frequency */ + writel(0x1, &priv->regs->brst); + + writel((priv->input_clk / speed / 2 << 16) | (priv->input_clk / speed), + &priv->regs->clk); + + writel(0x3, &priv->regs->brst); + + /* + * Theoretically, each byte can be transferred in + * 1000000 * 9 / speed usec. For safety, wait more than double. + */ + priv->wait_us = 20000000 / speed; + + return 0; +} + + +static const struct dm_i2c_ops uniphier_i2c_ops = { + .xfer = uniphier_i2c_xfer, + .set_bus_speed = uniphier_i2c_set_bus_speed, +}; + +static const struct udevice_id uniphier_i2c_of_match[] = { + { .compatible = "panasonic,uniphier-i2c" }, + {}, +}; + +U_BOOT_DRIVER(uniphier_i2c) = { + .name = "uniphier-i2c", + .id = UCLASS_I2C, + .of_match = uniphier_i2c_of_match, + .probe = uniphier_i2c_probe, + .remove = uniphier_i2c_remove, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .child_pre_probe = uniphier_i2c_child_pre_probe, + .priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev), + .ops = &uniphier_i2c_ops, +}; -- cgit From 238bd0b8ce525c3b2c9ddf9f8326a99b58ef4a73 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jan 2015 12:44:37 +0900 Subject: i2c: UniPhier: add driver for UniPhier FIFO-builtin i2c controller This commit adds on-chip I2C driver used on newer SoCs of Panasonic UniPhier platform. Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Acked-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/Kconfig | 8 + drivers/i2c/Makefile | 1 + drivers/i2c/i2c-uniphier-f.c | 379 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 388 insertions(+) create mode 100644 drivers/i2c/i2c-uniphier-f.c diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 6a479efd7c..202ea5d679 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -12,3 +12,11 @@ config SYS_I2C_UNIPHIER help Support for Panasonic UniPhier I2C controller driver. This I2C controller is used on PH1-LD4, PH1-sLD8 or older UniPhier SoCs. + +config SYS_I2C_UNIPHIER_F + bool "UniPhier FIFO-builtin I2C driver" + depends on ARCH_UNIPHIER && DM_I2C + default y + help + Support for Panasonic UniPhier FIFO-builtin I2C controller driver. + This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs. diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index e2fcd24ef3..0e4c9f466a 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -32,4 +32,5 @@ obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o +obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c new file mode 100644 index 0000000000..b0d30f76c6 --- /dev/null +++ b/drivers/i2c/i2c-uniphier-f.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct uniphier_fi2c_regs { + u32 cr; /* control register */ +#define I2C_CR_MST (1 << 3) /* master mode */ +#define I2C_CR_STA (1 << 2) /* start condition */ +#define I2C_CR_STO (1 << 1) /* stop condition */ +#define I2C_CR_NACK (1 << 0) /* not ACK */ + u32 dttx; /* send FIFO (write-only) */ +#define dtrx dttx /* receive FIFO (read-only) */ +#define I2C_DTTX_CMD (1 << 8) /* send command (slave addr) */ +#define I2C_DTTX_RD (1 << 0) /* read */ + u32 __reserved; /* no register at offset 0x08 */ + u32 slad; /* slave address */ + u32 cyc; /* clock cycle control */ + u32 lctl; /* clock low period control */ + u32 ssut; /* restart/stop setup time control */ + u32 dsut; /* data setup time control */ + u32 intr; /* interrupt status */ + u32 ie; /* interrupt enable */ + u32 ic; /* interrupt clear */ +#define I2C_INT_TE (1 << 9) /* TX FIFO empty */ +#define I2C_INT_RB (1 << 4) /* received specified bytes */ +#define I2C_INT_NA (1 << 2) /* no answer */ +#define I2C_INT_AL (1 << 1) /* arbitration lost */ + u32 sr; /* status register */ +#define I2C_SR_DB (1 << 12) /* device busy */ +#define I2C_SR_BB (1 << 8) /* bus busy */ +#define I2C_SR_RFF (1 << 3) /* Rx FIFO full */ +#define I2C_SR_RNE (1 << 2) /* Rx FIFO not empty */ +#define I2C_SR_TNF (1 << 1) /* Tx FIFO not full */ +#define I2C_SR_TFE (1 << 0) /* Tx FIFO empty */ + u32 __reserved2; /* no register at offset 0x30 */ + u32 rst; /* reset control */ +#define I2C_RST_TBRST (1 << 2) /* clear Tx FIFO */ +#define I2C_RST_RBRST (1 << 1) /* clear Rx FIFO */ +#define I2C_RST_RST (1 << 0) /* forcible bus reset */ + u32 bm; /* bus monitor */ + u32 noise; /* noise filter control */ + u32 tbc; /* Tx byte count setting */ + u32 rbc; /* Rx byte count setting */ + u32 tbcm; /* Tx byte count monitor */ + u32 rbcm; /* Rx byte count monitor */ + u32 brst; /* bus reset */ +#define I2C_BRST_FOEN (1 << 1) /* normal operation */ +#define I2C_BRST_RSCLO (1 << 0) /* release SCL low fixing */ +}; + +#define FIOCLK 50000000 + +struct uniphier_fi2c_dev { + struct uniphier_fi2c_regs __iomem *regs; /* register base */ + unsigned long fioclk; /* internal operation clock */ + unsigned long timeout; /* time out (us) */ +}; + +static int poll_status(u32 __iomem *reg, u32 flag) +{ + int wait = 1000000; /* 1 sec is long enough */ + + while (readl(reg) & flag) { + if (wait-- < 0) + return -EREMOTEIO; + udelay(1); + } + + return 0; +} + +static int reset_bus(struct uniphier_fi2c_regs __iomem *regs) +{ + int ret; + + /* bus forcible reset */ + writel(I2C_RST_RST, ®s->rst); + ret = poll_status(®s->rst, I2C_RST_RST); + if (ret < 0) + debug("error: fail to reset I2C controller\n"); + + return ret; +} + +static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs) +{ + int ret; + + ret = poll_status(®s->sr, I2C_SR_DB); + if (ret < 0) { + debug("error: device busy too long. reset...\n"); + ret = reset_bus(regs); + } + + return ret; +} + +static int uniphier_fi2c_probe(struct udevice *dev) +{ + fdt_addr_t addr; + fdt_size_t size; + struct uniphier_fi2c_dev *priv = dev_get_priv(dev); + int ret; + + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", + &size); + + priv->regs = map_sysmem(addr, size); + + if (!priv->regs) + return -ENOMEM; + + priv->fioclk = FIOCLK; + + /* bus forcible reset */ + ret = reset_bus(priv->regs); + if (ret < 0) + return ret; + + writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &priv->regs->brst); + + return 0; +} + +static int uniphier_fi2c_remove(struct udevice *dev) +{ + struct uniphier_fi2c_dev *priv = dev_get_priv(dev); + + unmap_sysmem(priv->regs); + + return 0; +} + +static int uniphier_fi2c_child_pre_probe(struct udevice *dev) +{ + struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); + + if (dev->of_offset == -1) + return 0; + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, + i2c_chip); +} + +static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags, + bool *stop) +{ + u32 irq; + unsigned long wait = dev->timeout; + int ret = -EREMOTEIO; + + do { + udelay(1); + irq = readl(&dev->regs->intr); + } while (!(irq & flags) && wait--); + + if (wait < 0) { + debug("error: time out\n"); + return ret; + } + + if (irq & I2C_INT_AL) { + debug("error: arbitration lost\n"); + *stop = false; + return ret; + } + + if (irq & I2C_INT_NA) { + debug("error: no answer\n"); + return ret; + } + + return 0; +} + +static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret) +{ + int ret; + + debug("stop condition\n"); + writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr); + + ret = poll_status(&dev->regs->sr, I2C_SR_DB); + if (ret < 0) + debug("error: device busy after operation\n"); + + return old_ret ? old_ret : ret; +} + +static int uniphier_fi2c_transmit(struct uniphier_fi2c_dev *dev, uint addr, + uint len, const u8 *buf, bool *stop) +{ + int ret; + const u32 irq_flags = I2C_INT_TE | I2C_INT_NA | I2C_INT_AL; + struct uniphier_fi2c_regs __iomem *regs = dev->regs; + + debug("%s: addr = %x, len = %d\n", __func__, addr, len); + + writel(I2C_DTTX_CMD | addr << 1, ®s->dttx); + + writel(irq_flags, ®s->ie); + writel(irq_flags, ®s->ic); + + debug("start condition\n"); + writel(I2C_CR_MST | I2C_CR_STA, ®s->cr); + + ret = wait_for_irq(dev, irq_flags, stop); + if (ret < 0) + goto error; + + while (len--) { + debug("sending %x\n", *buf); + writel(*buf++, ®s->dttx); + + writel(irq_flags, ®s->ic); + + ret = wait_for_irq(dev, irq_flags, stop); + if (ret < 0) + goto error; + } + +error: + writel(irq_flags, ®s->ic); + + if (*stop) + ret = issue_stop(dev, ret); + + return ret; +} + +static int uniphier_fi2c_receive(struct uniphier_fi2c_dev *dev, uint addr, + uint len, u8 *buf, bool *stop) +{ + int ret = 0; + const u32 irq_flags = I2C_INT_RB | I2C_INT_NA | I2C_INT_AL; + struct uniphier_fi2c_regs __iomem *regs = dev->regs; + + debug("%s: addr = %x, len = %d\n", __func__, addr, len); + + /* + * In case 'len == 0', only the slave address should be sent + * for probing, which is covered by the transmit function. + */ + if (len == 0) + return uniphier_fi2c_transmit(dev, addr, len, buf, stop); + + writel(I2C_DTTX_CMD | I2C_DTTX_RD | addr << 1, ®s->dttx); + + writel(0, ®s->rbc); + writel(irq_flags, ®s->ie); + writel(irq_flags, ®s->ic); + + debug("start condition\n"); + writel(I2C_CR_MST | I2C_CR_STA | (len == 1 ? I2C_CR_NACK : 0), + ®s->cr); + + while (len--) { + ret = wait_for_irq(dev, irq_flags, stop); + if (ret < 0) + goto error; + + *buf++ = readl(®s->dtrx); + debug("received %x\n", *(buf - 1)); + + if (len == 1) + writel(I2C_CR_MST | I2C_CR_NACK, ®s->cr); + + writel(irq_flags, ®s->ic); + } + +error: + writel(irq_flags, ®s->ic); + + if (*stop) + ret = issue_stop(dev, ret); + + return ret; +} + +static int uniphier_fi2c_xfer(struct udevice *bus, struct i2c_msg *msg, + int nmsgs) +{ + int ret; + struct uniphier_fi2c_dev *dev = dev_get_priv(bus); + bool stop; + + ret = check_device_busy(dev->regs); + if (ret < 0) + return ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + /* If next message is read, skip the stop condition */ + stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true; + + if (msg->flags & I2C_M_RD) + ret = uniphier_fi2c_receive(dev, msg->addr, msg->len, + msg->buf, &stop); + else + ret = uniphier_fi2c_transmit(dev, msg->addr, msg->len, + msg->buf, &stop); + + if (ret < 0) + break; + } + + return ret; +} + +static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed) +{ + int ret; + unsigned int clk_count; + struct uniphier_fi2c_dev *dev = dev_get_priv(bus); + struct uniphier_fi2c_regs __iomem *regs = dev->regs; + + /* max supported frequency is 400 kHz */ + if (speed > 400000) + return -EINVAL; + + ret = check_device_busy(dev->regs); + if (ret < 0) + return ret; + + /* make sure the bus is idle when changing the frequency */ + writel(I2C_BRST_RSCLO, ®s->brst); + + clk_count = dev->fioclk / speed; + + writel(clk_count, ®s->cyc); + writel(clk_count / 2, ®s->lctl); + writel(clk_count / 2, ®s->ssut); + writel(clk_count / 16, ®s->dsut); + + writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, ®s->brst); + + /* + * Theoretically, each byte can be transferred in + * 1000000 * 9 / speed usec. + * This time out value is long enough. + */ + dev->timeout = 100000000L / speed; + + return 0; +} + +static const struct dm_i2c_ops uniphier_fi2c_ops = { + .xfer = uniphier_fi2c_xfer, + .set_bus_speed = uniphier_fi2c_set_bus_speed, +}; + +static const struct udevice_id uniphier_fi2c_of_match[] = { + { .compatible = "panasonic,uniphier-fi2c" }, + {}, +}; + +U_BOOT_DRIVER(uniphier_fi2c) = { + .name = "uniphier-fi2c", + .id = UCLASS_I2C, + .of_match = uniphier_fi2c_of_match, + .probe = uniphier_fi2c_probe, + .remove = uniphier_fi2c_remove, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .child_pre_probe = uniphier_fi2c_child_pre_probe, + .priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev), + .ops = &uniphier_fi2c_ops, +}; -- cgit From 3bf447655b7ecc4b2e6e4ef9ee8cb1b59fc521d9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jan 2015 12:44:38 +0900 Subject: ARM: UniPhier: enable I2C for UniPhier SoCs Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- configs/ph1_ld4_defconfig | 2 ++ configs/ph1_pro4_defconfig | 2 ++ configs/ph1_sld8_defconfig | 2 ++ 3 files changed, 6 insertions(+) diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index 2e9dd00c1d..86b4b15724 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y CONFIG_CMD_LOADS=y CONFIG_CMD_FLASH=y CONFIG_CMD_NAND=y +CONFIG_CMD_I2C=y CONFIG_CMD_USB=y CONFIG_CMD_ECHO=y CONFIG_CMD_ITEST=y @@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_DM_I2C=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 5dca64bf88..242bcf9263 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y CONFIG_CMD_LOADS=y CONFIG_CMD_FLASH=y CONFIG_CMD_NAND=y +CONFIG_CMD_I2C=y CONFIG_CMD_USB=y CONFIG_CMD_ECHO=y CONFIG_CMD_ITEST=y @@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_DM_I2C=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 2a6e334506..8e95f17e6d 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y CONFIG_CMD_LOADS=y CONFIG_CMD_FLASH=y CONFIG_CMD_NAND=y +CONFIG_CMD_I2C=y CONFIG_CMD_USB=y CONFIG_CMD_ECHO=y CONFIG_CMD_ITEST=y @@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8 CONFIG_DM_SERIAL=y CONFIG_UNIPHIER_SERIAL=y +CONFIG_DM_I2C=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y -- cgit From 233e42a985ce1e2ed2c33fbc2bee525a5cacdda9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jan 2015 12:44:39 +0900 Subject: ARM: UniPhier: enable CONFIG_I2C_EEPROM Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- include/configs/uniphier.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 5a53c506c3..9ad47f6933 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -43,6 +43,9 @@ #define CONFIG_SDRAM1_SIZE 0x10000000 #endif +#define CONFIG_I2C_EEPROM +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 + /* * Support card address map */ -- cgit From 5468461d1ea05ff99cf206939293480cc86fd2ec Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 20 Dec 2014 03:34:23 +0900 Subject: cmd_i2c: change variable type for 10bit addressing support To store 10bit chip address, the variable type should not be uchar, but uint. Signed-off-by: Masahiro Yamada Cc: Heiko Schocher Cc: Simon Glass Acked-by: Simon Glass Acked-by: Heiko Schocher --- common/cmd_i2c.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 22db1bb47c..f65ab616b0 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -83,12 +83,12 @@ DECLARE_GLOBAL_DATA_PTR; /* Display values from last command. * Memory modify remembered values are different from display memory. */ -static uchar i2c_dp_last_chip; +static uint i2c_dp_last_chip; static uint i2c_dp_last_addr; static uint i2c_dp_last_alen; static uint i2c_dp_last_length = 0x10; -static uchar i2c_mm_last_chip; +static uint i2c_mm_last_chip; static uint i2c_mm_last_addr; static uint i2c_mm_last_alen; @@ -282,7 +282,7 @@ static int i2c_report_err(int ret, enum i2c_err_op op) */ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint devaddr, length; int alen; u_char *memaddr; @@ -335,7 +335,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint devaddr, length; int alen; u_char *memaddr; @@ -444,7 +444,7 @@ static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc, */ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint addr, length; int alen; int j, nbytes, linebytes; @@ -563,7 +563,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; uchar byte; @@ -649,7 +649,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; int count; @@ -734,7 +734,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] static int mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; ulong data; @@ -957,7 +957,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv */ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; int alen; uint addr; uint length; @@ -1085,7 +1085,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { enum { unknown, EDO, SDRAM, DDR2 } type; - u_char chip; + uint chip; u_char data[128]; u_char cksum; int j; @@ -1563,7 +1563,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) #if defined(CONFIG_I2C_EDID) int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - u_char chip; + uint chip; struct edid1_info edid; int ret; #ifdef CONFIG_DM_I2C -- cgit From 0365ffcc0bd6335afb0c866423f3fe401b28ffaa Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 14 Jan 2015 17:07:05 +0900 Subject: generic-board: show model name in board_init_f() too The common/board_r.c has show_model_r() to display the model name if the DTB has a "model" property. It sounds useful to have a similar function in common/board_f.c too because most of the boards show their board name before relocation. Instead of implementing the same function in both common/board_f.c and common/board_r.c, let's split it up into common/show_board_info.c. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- common/Makefile | 2 ++ common/board_f.c | 2 +- common/board_info.c | 35 +++++++++++++++++++++++++++++++++++ common/board_r.c | 18 +----------------- include/common.h | 13 +++++++------ 5 files changed, 46 insertions(+), 24 deletions(-) create mode 100644 common/board_info.c diff --git a/common/Makefile b/common/Makefile index 94554f2939..9579ab4c98 100644 --- a/common/Makefile +++ b/common/Makefile @@ -27,6 +27,8 @@ endif # boards obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o +obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o +obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o # core command obj-y += cmd_boot.o diff --git a/common/board_f.c b/common/board_f.c index 215108ba06..79531377a7 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -894,7 +894,7 @@ static init_fnc_t init_sequence_f[] = { prt_mpc5xxx_clks, #endif /* CONFIG_MPC5xxx */ #if defined(CONFIG_DISPLAY_BOARDINFO) - checkboard, /* display board info */ + show_board_info, #endif INIT_FUNC_WATCHDOG_INIT #if defined(CONFIG_MISC_INIT_F) diff --git a/common/board_info.c b/common/board_info.c new file mode 100644 index 0000000000..42d0641294 --- /dev/null +++ b/common/board_info.c @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +int __weak checkboard(void) +{ + printf("Board: Unknown\n"); + return 0; +} + +/* + * If the root node of the DTB has a "model" property, show it. + * If CONFIG_OF_CONTROL is disabled or the "model" property is missing, + * fall back to checkboard(). + */ +int show_board_info(void) +{ +#ifdef CONFIG_OF_CONTROL + DECLARE_GLOBAL_DATA_PTR; + const char *model; + + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + + if (model) { + printf("Model: %s\n", model); + return 0; + } +#endif + + return checkboard(); +} diff --git a/common/board_r.c b/common/board_r.c index a301cc226f..68a9448b55 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -476,22 +476,6 @@ static int initr_api(void) } #endif -#ifdef CONFIG_DISPLAY_BOARDINFO_LATE -static int show_model_r(void) -{ - /* Put this here so it appears on the LCD, now it is ready */ -# ifdef CONFIG_OF_CONTROL - const char *model; - - model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Model: %s\n", model ? model : ""); -# else - checkboard(); -# endif - return 0; -} -#endif - /* enable exceptions */ #ifdef CONFIG_ARM static int initr_enable_interrupts(void) @@ -801,7 +785,7 @@ init_fnc_t init_sequence_r[] = { #endif console_init_r, /* fully init console as a device */ #ifdef CONFIG_DISPLAY_BOARDINFO_LATE - show_model_r, + show_board_info, #endif #ifdef CONFIG_ARCH_MISC_INIT arch_misc_init, /* miscellaneous arch-dependent init */ diff --git a/include/common.h b/include/common.h index 4b3e0d3bbd..97c8f79fc7 100644 --- a/include/common.h +++ b/include/common.h @@ -228,12 +228,13 @@ int run_command_list(const char *cmd, int len, int flag); extern char console_buffer[]; /* arch/$(ARCH)/lib/board.c */ -void board_init_f(ulong); -void board_init_r (gd_t *, ulong) __attribute__ ((noreturn)); -int checkboard (void); -int checkflash (void); -int checkdram (void); -int last_stage_init(void); +void board_init_f(ulong); +void board_init_r(gd_t *, ulong) __attribute__ ((noreturn)); +int checkboard(void); +int show_board_info(void); +int checkflash(void); +int checkdram(void); +int last_stage_init(void); extern ulong monitor_flash_len; int mac_read_from_eeprom(void); extern u8 __dtb_dt_begin[]; /* embedded device tree blob */ -- cgit From 9f4cd0200cae9821f9ae7994b86ec7a2023bbcd0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:23 -0700 Subject: dm: gpio: Bring in GPIO device tree binding Add the binding file that we are about to support. Signed-off-by: Simon Glass --- doc/device-tree-bindings/gpio/gpio.txt | 211 +++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 doc/device-tree-bindings/gpio/gpio.txt diff --git a/doc/device-tree-bindings/gpio/gpio.txt b/doc/device-tree-bindings/gpio/gpio.txt new file mode 100644 index 0000000000..b9bd1d64cf --- /dev/null +++ b/doc/device-tree-bindings/gpio/gpio.txt @@ -0,0 +1,211 @@ +Specifying GPIO information for devices +============================================ + +1) gpios property +----------------- + +Nodes that makes use of GPIOs should specify them using one or more +properties, each containing a 'gpio-list': + + gpio-list ::= [gpio-list] + single-gpio ::= + gpio-phandle : phandle to gpio controller node + gpio-specifier : Array of #gpio-cells specifying specific gpio + (controller specific) + +GPIO properties should be named "[-]gpios", with being the purpose +of this GPIO for the device. While a non-existent is considered valid +for compatibility reasons (resolving to the "gpios" property), it is not allowed +for new bindings. + +GPIO properties can contain one or more GPIO phandles, but only in exceptional +cases should they contain more than one. If your device uses several GPIOs with +distinct functions, reference each of them under its own property, giving it a +meaningful name. The only case where an array of GPIOs is accepted is when +several GPIOs serve the same function (e.g. a parallel data line). + +The exact purpose of each gpios property must be documented in the device tree +binding of the device. + +The following example could be used to describe GPIO pins used as device enable +and bit-banged data signals: + + gpio1: gpio1 { + gpio-controller + #gpio-cells = <2>; + }; + gpio2: gpio2 { + gpio-controller + #gpio-cells = <1>; + }; + [...] + + enable-gpios = <&gpio2 2>; + data-gpios = <&gpio1 12 0>, + <&gpio1 13 0>, + <&gpio1 14 0>, + <&gpio1 15 0>; + +Note that gpio-specifier length is controller dependent. In the +above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2 +only uses one. + +gpio-specifier may encode: bank, pin position inside the bank, +whether pin is open-drain and whether pin is logically inverted. +Exact meaning of each specifier cell is controller specific, and must +be documented in the device tree binding for the device. Use the macros +defined in include/dt-bindings/gpio/gpio.h whenever possible: + +Example of a node using GPIOs: + + node { + enable-gpios = <&qe_pio_e 18 GPIO_ACTIVE_HIGH>; + }; + +GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes +GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller. + +1.1) GPIO specifier best practices +---------------------------------- + +A gpio-specifier should contain a flag indicating the GPIO polarity; active- +high or active-low. If it does, the follow best practices should be followed: + +The gpio-specifier's polarity flag should represent the physical level at the +GPIO controller that achieves (or represents, for inputs) a logically asserted +value at the device. The exact definition of logically asserted should be +defined by the binding for the device. If the board inverts the signal between +the GPIO controller and the device, then the gpio-specifier will represent the +opposite physical level than the signal at the device's pin. + +When the device's signal polarity is configurable, the binding for the +device must either: + +a) Define a single static polarity for the signal, with the expectation that +any software using that binding would statically program the device to use +that signal polarity. + +The static choice of polarity may be either: + +a1) (Preferred) Dictated by a binding-specific DT property. + +or: + +a2) Defined statically by the DT binding itself. + +In particular, the polarity cannot be derived from the gpio-specifier, since +that would prevent the DT from separately representing the two orthogonal +concepts of configurable signal polarity in the device, and possible board- +level signal inversion. + +or: + +b) Pick a single option for device signal polarity, and document this choice +in the binding. The gpio-specifier should represent the polarity of the signal +(at the GPIO controller) assuming that the device is configured for this +particular signal polarity choice. If software chooses to program the device +to generate or receive a signal of the opposite polarity, software will be +responsible for correctly interpreting (inverting) the GPIO signal at the GPIO +controller. + +2) gpio-controller nodes +------------------------ + +Every GPIO controller node must contain both an empty "gpio-controller" +property, and a #gpio-cells integer property, which indicates the number of +cells in a gpio-specifier. + +Example of two SOC GPIO banks defined as gpio-controller nodes: + + qe_pio_a: gpio-controller@1400 { + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + #gpio-cells = <2>; + }; + + qe_pio_e: gpio-controller@1460 { + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + #gpio-cells = <2>; + }; + +2.1) gpio- and pin-controller interaction +----------------------------------------- + +Some or all of the GPIOs provided by a GPIO controller may be routed to pins +on the package via a pin controller. This allows muxing those pins between +GPIO and other functions. + +It is useful to represent which GPIOs correspond to which pins on which pin +controllers. The gpio-ranges property described below represents this, and +contains information structures as follows: + + gpio-range-list ::= [gpio-range-list] + single-gpio-range ::= | + numeric-gpio-range ::= + + named-gpio-range ::= '<0 0>' + gpio-phandle : phandle to pin controller node. + gpio-base : Base GPIO ID in the GPIO controller + pinctrl-base : Base pinctrl pin ID in the pin controller + count : The number of GPIOs/pins in this range + +The "pin controller node" mentioned above must conform to the bindings +described in ../pinctrl/pinctrl-bindings.txt. + +In case named gpio ranges are used (ranges with both and + set to 0), the property gpio-ranges-group-names contains one string +for every single-gpio-range in gpio-ranges: + gpiorange-names-list ::= [gpiorange-names-list] + gpiorange-name : Name of the pingroup associated to the GPIO range in + the respective pin controller. + +Elements of gpiorange-names-list corresponding to numeric ranges contain +the empty string. Elements of gpiorange-names-list corresponding to named +ranges contain the name of a pin group defined in the respective pin +controller. The number of pins/GPIOs in the range is the number of pins in +that pin group. + +Previous versions of this binding required all pin controller nodes that +were referenced by any gpio-ranges property to contain a property named +#gpio-range-cells with value <3>. This requirement is now deprecated. +However, that property may still exist in older device trees for +compatibility reasons, and would still be required even in new device +trees that need to be compatible with older software. + +Example 1: + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>; + }; + +Here, a single GPIO controller has GPIOs 0..9 routed to pin controller +pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's +pins 50..59. + +Example 2: + + gpio_pio_i: gpio-controller@14B0 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1480 0x18>; + gpio-controller; + gpio-ranges = <&pinctrl1 0 20 10>, + <&pinctrl2 10 0 0>, + <&pinctrl1 15 0 10>, + <&pinctrl2 25 0 0>; + gpio-ranges-group-names = "", + "foo", + "", + "bar"; + }; + +Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO +ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2 +are named "foo" and "bar". -- cgit From 35ea1bfde30a541188ffd24cdf9b3ba79b0e4684 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:24 -0700 Subject: dm: exynos: Bring in GPIO device tree binding At present the exynos GPIO driver does not fully support the existing device tree binding, but add the binding file to cover the existing partial support. Signed-off-by: Simon Glass --- doc/device-tree-bindings/gpio/gpio-samsung.txt | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 doc/device-tree-bindings/gpio/gpio-samsung.txt diff --git a/doc/device-tree-bindings/gpio/gpio-samsung.txt b/doc/device-tree-bindings/gpio/gpio-samsung.txt new file mode 100644 index 0000000000..5375625e8c --- /dev/null +++ b/doc/device-tree-bindings/gpio/gpio-samsung.txt @@ -0,0 +1,41 @@ +Samsung Exynos4 GPIO Controller + +Required properties: +- compatible: Compatible property value should be "samsung,exynos4-gpio>". + +- reg: Physical base address of the controller and length of memory mapped + region. + +- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes + should be the following with values derived from the SoC user manual. + <[phandle of the gpio controller node] + [pin number within the gpio controller] + [mux function] + [flags and pull up/down] + [drive strength]> + + Values for gpio specifier: + - Pin number: is a value between 0 to 7. + - Flags and Pull Up/Down: 0 - Pull Up/Down Disabled. + 1 - Pull Down Enabled. + 3 - Pull Up Enabled. + Bit 16 (0x00010000) - Input is active low. + - Drive Strength: 0 - 1x, + 1 - 3x, + 2 - 2x, + 3 - 4x + +- gpio-controller: Specifies that the node is a gpio controller. +- #address-cells: should be 1. +- #size-cells: should be 1. + +Example: + + gpa0: gpio-controller@11400000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "samsung,exynos4-gpio"; + reg = <0x11400000 0x20>; + #gpio-cells = <4>; + gpio-controller; + }; -- cgit From 5cfc662c496a0e52301a9379f91755b1f8fbf368 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:25 -0700 Subject: dm: tegra: Bring in GPIO device tree binding At present the tegra GPIO driver does not fully support the existing device tree binding, but add the binding file to cover the existing partial support. Signed-off-by: Simon Glass --- .../gpio/nvidia,tegra20-gpio.txt | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt diff --git a/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt b/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt new file mode 100644 index 0000000000..023c9526e5 --- /dev/null +++ b/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt @@ -0,0 +1,40 @@ +NVIDIA Tegra GPIO controller + +Required properties: +- compatible : "nvidia,tegra-gpio" +- reg : Physical base address and length of the controller's registers. +- interrupts : The interrupt outputs from the controller. For Tegra20, + there should be 7 interrupts specified, and for Tegra30, there should + be 8 interrupts specified. +- #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted) +- gpio-controller : Marks the device node as a GPIO controller. +- #interrupt-cells : Should be 2. + The first cell is the GPIO number. + The second cell is used to specify flags: + bits[3:0] trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. + Valid combinations are 1, 2, 3, 4, 8. +- interrupt-controller : Marks the device node as an interrupt controller. + +Example: + +gpio: gpio@6000d000 { + compatible = "nvidia,tegra20-gpio"; + reg = < 0x6000d000 0x1000 >; + interrupts = < 0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 >; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; +}; -- cgit From 57068a7aeb19fee06933986926eaea3cf0128f16 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:26 -0700 Subject: dm: fdt: Add a function to decode phandles with arguments For GPIOs and other functions we want to look up a phandle and then decode a list of arguments for that phandle. Each phandle can have a different number of arguments, specified by a property in the target node. This is the "#gpio-cells" property for GPIOs. Add a function to provide this feature, taken modified from Linux 3.18. Signed-off-by: Simon Glass --- include/fdtdec.h | 53 ++++++++++++++++++++++++ lib/fdtdec.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) diff --git a/include/fdtdec.h b/include/fdtdec.h index 8c2bd21b2d..8cf88dd10b 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -178,6 +178,59 @@ enum fdt_compat_id { COMPAT_COUNT, }; +#define MAX_PHANDLE_ARGS 16 +struct fdtdec_phandle_args { + int node; + int args_count; + uint32_t args[MAX_PHANDLE_ARGS]; +}; + +/** + * fdtdec_parse_phandle_with_args() - Find a node pointed by phandle in a list + * + * This function is useful to parse lists of phandles and their arguments. + * + * Example: + * + * phandle1: node1 { + * #list-cells = <2>; + * } + * + * phandle2: node2 { + * #list-cells = <1>; + * } + * + * node3 { + * list = <&phandle1 1 2 &phandle2 3>; + * } + * + * To get a device_node of the `node2' node you may call this: + * fdtdec_parse_phandle_with_args(blob, node3, "list", "#list-cells", 0, 1, + * &args); + * + * (This function is a modified version of __of_parse_phandle_with_args() from + * Linux 3.18) + * + * @blob: Pointer to device tree + * @src_node: Offset of device tree node containing a list + * @list_name: property name that contains a list + * @cells_name: property name that specifies the phandles' arguments count, + * or NULL to use @cells_count + * @cells_count: Cell count to use if @cells_name is NULL + * @index: index of a phandle to parse out + * @out_args: optional pointer to output arguments structure (will be filled) + * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if + * @list_name does not exist, a phandle was not found, @cells_name + * could not be found, the arguments were truncated or there were too + * many arguments. + * + */ +int fdtdec_parse_phandle_with_args(const void *blob, int src_node, + const char *list_name, + const char *cells_name, + int cell_count, int index, + struct fdtdec_phandle_args *out_args); + /* GPIOs are numbered from 0 */ enum { FDT_GPIO_NONE = -1U, /* an invalid GPIO used to end our list */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index e989241b70..57e0edca99 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -679,6 +679,130 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name) return cell != NULL; } +int fdtdec_parse_phandle_with_args(const void *blob, int src_node, + const char *list_name, + const char *cells_name, + int cell_count, int index, + struct fdtdec_phandle_args *out_args) +{ + const __be32 *list, *list_end; + int rc = 0, size, cur_index = 0; + uint32_t count = 0; + int node = -1; + int phandle; + + /* Retrieve the phandle list property */ + list = fdt_getprop(blob, src_node, list_name, &size); + if (!list) + return -ENOENT; + list_end = list + size / sizeof(*list); + + /* Loop over the phandles until all the requested entry is found */ + while (list < list_end) { + rc = -EINVAL; + count = 0; + + /* + * If phandle is 0, then it is an empty entry with no + * arguments. Skip forward to the next entry. + */ + phandle = be32_to_cpup(list++); + if (phandle) { + /* + * Find the provider node and parse the #*-cells + * property to determine the argument length. + * + * This is not needed if the cell count is hard-coded + * (i.e. cells_name not set, but cell_count is set), + * except when we're going to return the found node + * below. + */ + if (cells_name || cur_index == index) { + node = fdt_node_offset_by_phandle(blob, + phandle); + if (!node) { + debug("%s: could not find phandle\n", + fdt_get_name(blob, src_node, + NULL)); + goto err; + } + } + + if (cells_name) { + count = fdtdec_get_int(blob, node, cells_name, + -1); + if (count == -1) { + debug("%s: could not get %s for %s\n", + fdt_get_name(blob, src_node, + NULL), + cells_name, + fdt_get_name(blob, node, + NULL)); + goto err; + } + } else { + count = cell_count; + } + + /* + * Make sure that the arguments actually fit in the + * remaining property data length + */ + if (list + count > list_end) { + debug("%s: arguments longer than property\n", + fdt_get_name(blob, src_node, NULL)); + goto err; + } + } + + /* + * All of the error cases above bail out of the loop, so at + * this point, the parsing is successful. If the requested + * index matches, then fill the out_args structure and return, + * or return -ENOENT for an empty entry. + */ + rc = -ENOENT; + if (cur_index == index) { + if (!phandle) + goto err; + + if (out_args) { + int i; + + if (count > MAX_PHANDLE_ARGS) { + debug("%s: too many arguments %d\n", + fdt_get_name(blob, src_node, + NULL), count); + count = MAX_PHANDLE_ARGS; + } + out_args->node = node; + out_args->args_count = count; + for (i = 0; i < count; i++) { + out_args->args[i] = + be32_to_cpup(list++); + } + } + + /* Found it! return success */ + return 0; + } + + node = -1; + list += count; + cur_index++; + } + + /* + * Result will be one of: + * -ENOENT : index is for empty phandle + * -EINVAL : parsing error on data + * [1..n] : Number of phandle (count mode; when index = -1) + */ + rc = index < 0 ? cur_index : -ENOENT; + err: + return rc; +} + /** * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no * terminating item. -- cgit From ae7123f876357a81fc4c393239a378f1058cad5e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:27 -0700 Subject: dm: gpio: Add a native driver model API So far driver model's GPIO uclass just implements the existing GPIO API. This has some limitations: - it requires manual device tree munging to support GPIOs in device tree (fdtdec_get_gpio() and friends) - it does not understand polarity - it is somewhat slower since we must scan for the GPIO device each time - Global GPIO numbering can change if other GPIO drivers are probed - it requires extra steps to set the GPIO direction and value The new functions have a dm_ prefix where necessary to avoid name conflicts but we can remove that when it is no-longer needed. The new struct gpio_desc holds all required information about the GPIO. For now this is intended to be stored by the client requesting the GPIO, but in future it might be brought into the uclass in some way. With these changes the old GPIO API still works, and uses the driver model API underneath. Signed-off-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 218 ++++++++++++++++++++++++++++++--------------- include/asm-generic/gpio.h | 16 ++++ 2 files changed, 163 insertions(+), 71 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 255700ab18..2f3c36b48f 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -13,14 +13,16 @@ /** * gpio_to_device() - Convert global GPIO number to device, number - * gpio: The numeric representation of the GPIO * * Convert the GPIO number to an entry in the list of GPIOs * or GPIO blocks registered with the GPIO controller. Returns * entry on success, NULL on error. + * + * @gpio: The numeric representation of the GPIO + * @desc: Returns description (desc->flags will always be 0) + * @return 0 if found, -ENOENT if not found */ -static int gpio_to_device(unsigned int gpio, struct udevice **devp, - unsigned int *offset) +static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) { struct gpio_dev_priv *uc_priv; struct udevice *dev; @@ -32,14 +34,15 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp, uc_priv = dev->uclass_priv; if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) { - *devp = dev; - *offset = gpio - uc_priv->gpio_base; + desc->dev = dev; + desc->offset = gpio - uc_priv->gpio_base; + desc->flags = 0; return 0; } } /* No such GPIO */ - return ret ? ret : -EINVAL; + return ret ? ret : -ENOENT; } int gpio_lookup_name(const char *name, struct udevice **devp, @@ -88,6 +91,31 @@ int gpio_lookup_name(const char *name, struct udevice **devp, return 0; } +static int dm_gpio_request(struct gpio_desc *desc, const char *label) +{ + struct udevice *dev = desc->dev; + struct gpio_dev_priv *uc_priv; + char *str; + int ret; + + uc_priv = dev->uclass_priv; + if (uc_priv->name[desc->offset]) + return -EBUSY; + str = strdup(label); + if (!str) + return -ENOMEM; + if (gpio_get_ops(dev)->request) { + ret = gpio_get_ops(dev)->request(dev, desc->offset, label); + if (ret) { + free(str); + return ret; + } + } + uc_priv->name[desc->offset] = str; + + return 0; +} + /** * gpio_request() - [COMPAT] Request GPIO * gpio: GPIO number @@ -102,32 +130,14 @@ int gpio_lookup_name(const char *name, struct udevice **devp, */ int gpio_request(unsigned gpio, const char *label) { - struct gpio_dev_priv *uc_priv; - unsigned int offset; - struct udevice *dev; - char *str; + struct gpio_desc desc; int ret; - ret = gpio_to_device(gpio, &dev, &offset); + ret = gpio_to_device(gpio, &desc); if (ret) return ret; - uc_priv = dev->uclass_priv; - if (uc_priv->name[offset]) - return -EBUSY; - str = strdup(label); - if (!str) - return -ENOMEM; - if (gpio_get_ops(dev)->request) { - ret = gpio_get_ops(dev)->request(dev, offset, label); - if (ret) { - free(str); - return ret; - } - } - uc_priv->name[offset] = str; - - return 0; + return dm_gpio_request(&desc, label); } /** @@ -151,25 +161,11 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...) return gpio_request(gpio, buf); } -/** - * gpio_free() - [COMPAT] Relinquish GPIO - * gpio: GPIO number - * - * This function implements the API that's compatible with current - * GPIO API used in U-Boot. The request is forwarded to particular - * GPIO driver. Returns 0 on success, negative value on error. - */ -int gpio_free(unsigned gpio) +int _dm_gpio_free(struct udevice *dev, uint offset) { struct gpio_dev_priv *uc_priv; - unsigned int offset; - struct udevice *dev; int ret; - ret = gpio_to_device(gpio, &dev, &offset); - if (ret) - return ret; - uc_priv = dev->uclass_priv; if (!uc_priv->name[offset]) return -ENXIO; @@ -185,15 +181,35 @@ int gpio_free(unsigned gpio) return 0; } -static int check_reserved(struct udevice *dev, unsigned offset, - const char *func) +/** + * gpio_free() - [COMPAT] Relinquish GPIO + * gpio: GPIO number + * + * This function implements the API that's compatible with current + * GPIO API used in U-Boot. The request is forwarded to particular + * GPIO driver. Returns 0 on success, negative value on error. + */ +int gpio_free(unsigned gpio) { - struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct gpio_desc desc; + int ret; + + ret = gpio_to_device(gpio, &desc); + if (ret) + return ret; + + return _dm_gpio_free(desc.dev, desc.offset); +} - if (!uc_priv->name[offset]) { +static int check_reserved(struct gpio_desc *desc, const char *func) +{ + struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv; + + if (!uc_priv->name[desc->offset]) { printf("%s: %s: error: gpio %s%d not reserved\n", - dev->name, func, - uc_priv->bank_name ? uc_priv->bank_name : "", offset); + desc->dev->name, func, + uc_priv->bank_name ? uc_priv->bank_name : "", + desc->offset); return -EBUSY; } @@ -210,16 +226,17 @@ static int check_reserved(struct udevice *dev, unsigned offset, */ int gpio_direction_input(unsigned gpio) { - unsigned int offset; - struct udevice *dev; + struct gpio_desc desc; int ret; - ret = gpio_to_device(gpio, &dev, &offset); + ret = gpio_to_device(gpio, &desc); + if (ret) + return ret; + ret = check_reserved(&desc, "dir_input"); if (ret) return ret; - ret = check_reserved(dev, offset, "dir_input"); - return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset); + return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset); } /** @@ -233,17 +250,81 @@ int gpio_direction_input(unsigned gpio) */ int gpio_direction_output(unsigned gpio, int value) { - unsigned int offset; - struct udevice *dev; + struct gpio_desc desc; int ret; - ret = gpio_to_device(gpio, &dev, &offset); + ret = gpio_to_device(gpio, &desc); + if (ret) + return ret; + ret = check_reserved(&desc, "dir_output"); + if (ret) + return ret; + + return gpio_get_ops(desc.dev)->direction_output(desc.dev, + desc.offset, value); +} + +int dm_gpio_get_value(struct gpio_desc *desc) +{ + int value; + int ret; + + ret = check_reserved(desc, "get_value"); if (ret) return ret; - ret = check_reserved(dev, offset, "dir_output"); - return ret ? ret : - gpio_get_ops(dev)->direction_output(dev, offset, value); + value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset); + + return desc->flags & GPIOD_ACTIVE_LOW ? !value : value; +} + +int dm_gpio_set_value(struct gpio_desc *desc, int value) +{ + int ret; + + ret = check_reserved(desc, "set_value"); + if (ret) + return ret; + + if (desc->flags & GPIOD_ACTIVE_LOW) + value = !value; + gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value); + return 0; +} + +int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) +{ + struct udevice *dev = desc->dev; + struct dm_gpio_ops *ops = gpio_get_ops(dev); + int ret; + + ret = check_reserved(desc, "set_dir"); + if (ret) + return ret; + + if (flags & GPIOD_IS_OUT) { + int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0; + + if (flags & GPIOD_ACTIVE_LOW) + value = !value; + ret = ops->direction_output(dev, desc->offset, value); + } else if (flags & GPIOD_IS_IN) { + ret = ops->direction_input(dev, desc->offset); + } + if (ret) + return ret; + /* + * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in + * futures + */ + desc->flags = flags; + + return 0; +} + +int dm_gpio_set_dir(struct gpio_desc *desc) +{ + return dm_gpio_set_dir_flags(desc, desc->flags); } /** @@ -257,16 +338,14 @@ int gpio_direction_output(unsigned gpio, int value) */ int gpio_get_value(unsigned gpio) { - unsigned int offset; - struct udevice *dev; int ret; - ret = gpio_to_device(gpio, &dev, &offset); + struct gpio_desc desc; + + ret = gpio_to_device(gpio, &desc); if (ret) return ret; - ret = check_reserved(dev, offset, "get_value"); - - return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset); + return dm_gpio_get_value(&desc); } /** @@ -280,16 +359,13 @@ int gpio_get_value(unsigned gpio) */ int gpio_set_value(unsigned gpio, int value) { - unsigned int offset; - struct udevice *dev; + struct gpio_desc desc; int ret; - ret = gpio_to_device(gpio, &dev, &offset); + ret = gpio_to_device(gpio, &desc); if (ret) return ret; - ret = check_reserved(dev, offset, "set_value"); - - return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value); + return dm_gpio_set_value(&desc, value); } const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 36a36c64b8..a827a56f5e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -95,6 +95,22 @@ enum gpio_func_t { struct udevice; +struct gpio_desc { + struct udevice *dev; /* Device, NULL for invalid GPIO */ + unsigned long flags; +#define GPIOD_REQUESTED (1 << 0) /* Requested/claimed */ +#define GPIOD_IS_OUT (1 << 1) /* GPIO is an output */ +#define GPIOD_IS_IN (1 << 2) /* GPIO is an output */ +#define GPIOD_ACTIVE_LOW (1 << 3) /* value has active low */ +#define GPIOD_IS_OUT_ACTIVE (1 << 4) /* set output active */ + + uint offset; /* GPIO offset within the device */ + /* + * We could consider adding the GPIO label in here. Possibly we could + * use this structure for internal GPIO information. + */ +}; + /** * gpio_get_status() - get the current GPIO status as a string * -- cgit From 0dac4d51f50e9252dbc00075cf65eeba57017926 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:28 -0700 Subject: dm: gpio: Add a driver GPIO translation method Only the GPIO driver knows about the full GPIO device tree binding used by a device. Add a method to allow the driver to provide this information to the uclass, including the GPIO offset within the device and flags such as the polarity. Signed-off-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 16 ++++++++++++++++ include/asm-generic/gpio.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 2f3c36b48f..0a4d9e4217 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,21 @@ int gpio_lookup_name(const char *name, struct udevice **devp, return 0; } +int gpio_find_and_xlate(struct gpio_desc *desc, + struct fdtdec_phandle_args *args) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + + /* Use the first argument as the offset by default */ + if (args->args_count > 0) + desc->offset = args->args[0]; + else + desc->offset = -1; + desc->flags = 0; + + return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0; +} + static int dm_gpio_request(struct gpio_desc *desc, const char *label) { struct udevice *dev = desc->dev; diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a827a56f5e..c08c96340a 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -171,6 +171,8 @@ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep); int gpio_requestf(unsigned gpio, const char *fmt, ...) __attribute__ ((format (__printf__, 2, 3))); +struct fdtdec_phandle_args; + /** * struct struct dm_gpio_ops - Driver model GPIO operations * @@ -214,6 +216,33 @@ struct dm_gpio_ops { * @return current function - GPIOF_... */ int (*get_function)(struct udevice *dev, unsigned offset); + + /** + * xlate() - Translate phandle arguments into a GPIO description + * + * This function should set up the fields in desc according to the + * information in the arguments. The uclass will have set up: + * + * @desc->dev to @dev + * @desc->flags to 0 + * @desc->offset to the value of the first argument in args, if any, + * otherwise -1 (which is invalid) + * + * This method is optional so if the above defaults suit it can be + * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag + * in desc->flags. + * + * Note that @dev is passed in as a parameter to follow driver model + * uclass conventions, even though it is already available as + * desc->dev. + * + * @dev: GPIO device + * @desc: Place to put GPIO description + * @args: Arguments provided in descripion + * @return 0 if OK, -ve on error + */ + int (*xlate)(struct udevice *dev, struct gpio_desc *desc, + struct fdtdec_phandle_args *args); }; /** -- cgit From 3669e0e759118fed3d371e2427b4b47d3969bfd0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:29 -0700 Subject: dm: gpio: Add better functions to request GPIOs At present U-Boot sort-of supports the standard way of reading GPIOs from device tree nodes, but the support is incomplete, a bit clunky and only works for GPIO bindings where #gpio-cells is 2. Add new functions to request GPIOs, taking full account of the device tree binding. These permit requesting a GPIO with a simple call like: gpio_request_by_name(dev, "cd-gpios", 0, &desc, GPIOD_IS_IN); This will request the GPIO, looking at the device's node which might be this, for example: cd-gpios = <&gpio TEGRA_GPIO(B, 3) GPIO_ACTIVE_LOW>; The GPIO will be set to input mode in this case and polarity will be honoured by the GPIO calls. It is also possible to request and free a list of GPIOs. Signed-off-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 166 ++++++++++++++++++++++++++++++++++++- drivers/gpio/sandbox.c | 20 +++++ include/asm-generic/gpio.h | 199 +++++++++++++++++++++++++++++++++++++++++++++ test/dm/gpio.c | 69 +++++++++++++++- test/dm/test.dts | 11 ++- 5 files changed, 461 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 0a4d9e4217..a69bbd2002 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -12,6 +12,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /** * gpio_to_device() - Convert global GPIO number to device, number * @@ -92,8 +94,8 @@ int gpio_lookup_name(const char *name, struct udevice **devp, return 0; } -int gpio_find_and_xlate(struct gpio_desc *desc, - struct fdtdec_phandle_args *args) +static int gpio_find_and_xlate(struct gpio_desc *desc, + struct fdtdec_phandle_args *args) { struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); @@ -132,6 +134,17 @@ static int dm_gpio_request(struct gpio_desc *desc, const char *label) return 0; } +static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...) +{ + va_list args; + char buf[40]; + + va_start(args, fmt); + vscnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + return dm_gpio_request(desc, buf); +} + /** * gpio_request() - [COMPAT] Request GPIO * gpio: GPIO number @@ -501,6 +514,155 @@ unsigned gpio_get_values_as_int(const int *gpio_num_array) return vector; } +static int _gpio_request_by_name_nodev(const void *blob, int node, + const char *list_name, int index, + struct gpio_desc *desc, int flags, + bool add_index) +{ + struct fdtdec_phandle_args args; + int ret; + + desc->dev = NULL; + desc->offset = 0; + ret = fdtdec_parse_phandle_with_args(blob, node, list_name, + "#gpio-cells", 0, index, &args); + if (ret) { + debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__); + goto err; + } + + ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node, + &desc->dev); + if (ret) { + debug("%s: uclass_get_device_by_of_offset failed\n", __func__); + goto err; + } + ret = gpio_find_and_xlate(desc, &args); + if (ret) { + debug("%s: gpio_find_and_xlate failed\n", __func__); + goto err; + } + ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s", + fdt_get_name(blob, node, NULL), + list_name, index); + if (ret) { + debug("%s: dm_gpio_requestf failed\n", __func__); + goto err; + } + ret = dm_gpio_set_dir_flags(desc, flags | desc->flags); + if (ret) { + debug("%s: dm_gpio_set_dir failed\n", __func__); + goto err; + } + + return 0; +err: + debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n", + __func__, fdt_get_name(blob, node, NULL), list_name, index, ret); + return ret; +} + +int gpio_request_by_name_nodev(const void *blob, int node, + const char *list_name, int index, + struct gpio_desc *desc, int flags) +{ + return _gpio_request_by_name_nodev(blob, node, list_name, index, desc, + flags, index > 0); +} + +int gpio_request_by_name(struct udevice *dev, const char *list_name, int index, + struct gpio_desc *desc, int flags) +{ + /* + * This isn't ideal since we don't use dev->name in the debug() + * calls in gpio_request_by_name(), but we can do this until + * gpio_request_by_name_nodev() can be dropped. + */ + return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset, + list_name, index, desc, flags); +} + +int gpio_request_list_by_name_nodev(const void *blob, int node, + const char *list_name, + struct gpio_desc *desc, int max_count, + int flags) +{ + int count; + int ret; + + for (count = 0; ; count++) { + if (count >= max_count) { + ret = -ENOSPC; + goto err; + } + ret = _gpio_request_by_name_nodev(blob, node, list_name, count, + &desc[count], flags, true); + if (ret == -ENOENT) + break; + else if (ret) + goto err; + } + + /* We ran out of GPIOs in the list */ + return count; + +err: + gpio_free_list_nodev(desc, count - 1); + + return ret; +} + +int gpio_request_list_by_name(struct udevice *dev, const char *list_name, + struct gpio_desc *desc, int max_count, + int flags) +{ + /* + * This isn't ideal since we don't use dev->name in the debug() + * calls in gpio_request_by_name(), but we can do this until + * gpio_request_list_by_name_nodev() can be dropped. + */ + return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset, + list_name, desc, max_count, + flags); +} + +int gpio_get_list_count(struct udevice *dev, const char *list_name) +{ + int ret; + + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, + list_name, "#gpio-cells", 0, -1, + NULL); + if (ret) { + debug("%s: Node '%s', property '%s', GPIO count failed: %d\n", + __func__, dev->name, list_name, ret); + } + + return ret; +} + +int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc) +{ + /* For now, we don't do any checking of dev */ + return _dm_gpio_free(desc->dev, desc->offset); +} + +int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count) +{ + int i; + + /* For now, we don't do any checking of dev */ + for (i = 0; i < count; i++) + dm_gpio_free(dev, &desc[i]); + + return 0; +} + +int gpio_free_list_nodev(struct gpio_desc *desc, int count) +{ + return gpio_free_list(NULL, desc, count); +} + /* We need to renumber the GPIOs when any driver is probed/removed */ static int gpio_renumber(struct udevice *removed_dev) { diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index 53c80d5be6..d564c252c7 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -8,6 +8,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -130,12 +131,31 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_INPUT; } +static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, + struct fdtdec_phandle_args *args) +{ + desc->offset = args->args[0]; + if (args->args_count < 2) + return 0; + if (args->args[1] & GPIO_ACTIVE_LOW) + desc->flags |= GPIOD_ACTIVE_LOW; + if (args->args[1] & 2) + desc->flags |= GPIOD_IS_IN; + if (args->args[1] & 4) + desc->flags |= GPIOD_IS_OUT; + if (args->args[1] & 8) + desc->flags |= GPIOD_IS_OUT_ACTIVE; + + return 0; +} + static const struct dm_gpio_ops gpio_sandbox_ops = { .direction_input = sb_gpio_direction_input, .direction_output = sb_gpio_direction_output, .get_value = sb_gpio_get_value, .set_value = sb_gpio_set_value, .get_function = sb_gpio_get_function, + .xlate = sb_gpio_xlate, }; static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index c08c96340a..26534150f1 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -111,6 +111,18 @@ struct gpio_desc { */ }; +/** + * dm_gpio_is_valid() - Check if a GPIO is gpio_is_valie + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return true if valid, false if not + */ +static inline bool dm_gpio_is_valid(struct gpio_desc *desc) +{ + return desc->dev != NULL; +} + /** * gpio_get_status() - get the current GPIO status as a string * @@ -313,4 +325,191 @@ int gpio_lookup_name(const char *name, struct udevice **devp, */ unsigned gpio_get_values_as_int(const int *gpio_list); +/** + * gpio_request_by_name() - Locate and request a GPIO by name + * + * This operates by looking up the given list name in the device (device + * tree property) and requesting the GPIO for use. The property must exist + * in @dev's node. + * + * Use @flags to specify whether the GPIO should be an input or output. In + * principle this can also come from the device tree binding but most + * bindings don't provide this information. Specifically, when the GPIO uclass + * calls the xlate() method, it can return default flags, which are then + * ORed with this @flags. + * + * If we find that requesting the GPIO is not always needed we could add a + * new function or a new GPIOD_NO_REQUEST flag. + * + * At present driver model has no reference counting so if one device + * requests a GPIO which subsequently is unbound, the @desc->dev pointer + * will be invalid. However this will only happen if the GPIO device is + * unbound, not if it is removed, so this seems like a reasonable limitation + * for now. There is no real use case for unbinding drivers in normal + * operation. + * + * The device tree binding is doc/device-tree-bindings/gpio/gpio.txt in + * generate terms and each specific device may add additional details in + * a binding file in the same directory. + * + * @dev: Device requesting the GPIO + * @list_name: Name of GPIO list (e.g. "board-id-gpios") + * @index: Index number of the GPIO in that list use request (0=first) + * @desc: Returns GPIO description information. If there is no such + * GPIO, dev->dev will be NULL. + * @flags: Indicates the GPIO input/output settings (GPIOD_...) + * @return 0 if OK, -ENOENT if the GPIO does not exist, -EINVAL if there is + * something wrong with the list, or other -ve for another error (e.g. + * -EBUSY if a GPIO was already requested) + */ +int gpio_request_by_name(struct udevice *dev, const char *list_name, + int index, struct gpio_desc *desc, int flags); + +/** + * gpio_request_list_by_name() - Request a list of GPIOs + * + * Reads all the GPIOs from a list and requetss them. See + * gpio_request_by_name() for additional details. Lists should not be + * misused to hold unrelated or optional GPIOs. They should only be used + * for things like parallel data lines. A zero phandle terminates the list + * the list. + * + * This function will either succeed, and request all GPIOs in the list, or + * fail and request none (it will free already-requested GPIOs in case of + * an error part-way through). + * + * @dev: Device requesting the GPIO + * @list_name: Name of GPIO list (e.g. "board-id-gpios") + * @desc_list: Returns a list of GPIO description information + * @max_count: Maximum number of GPIOs to return (@desc_list must be at least + * this big) + * @flags: Indicates the GPIO input/output settings (GPIOD_...) + * @return number of GPIOs requested, or -ve on error + */ +int gpio_request_list_by_name(struct udevice *dev, const char *list_name, + struct gpio_desc *desc_list, int max_count, + int flags); + +/** + * gpio_get_list_count() - Returns the number of GPIOs in a list + * + * Counts the GPIOs in a list. See gpio_request_by_name() for additional + * details. + * + * @dev: Device requesting the GPIO + * @list_name: Name of GPIO list (e.g. "board-id-gpios") + * @return number of GPIOs (0 for an empty property) or -ENOENT if the list + * does not exist + */ +int gpio_get_list_count(struct udevice *dev, const char *list_name); + +/** + * gpio_request_by_name_nodev() - request GPIOs without a device + * + * This is a version of gpio_request_list_by_name() that does not use a + * device. Avoid it unless the caller is not yet using driver model + */ +int gpio_request_by_name_nodev(const void *blob, int node, + const char *list_name, + int index, struct gpio_desc *desc, int flags); + +/** + * gpio_request_list_by_name_nodev() - request GPIOs without a device + * + * This is a version of gpio_request_list_by_name() that does not use a + * device. Avoid it unless the caller is not yet using driver model + */ +int gpio_request_list_by_name_nodev(const void *blob, int node, + const char *list_name, + struct gpio_desc *desc_list, int max_count, + int flags); + +/** + * dm_gpio_free() - Free a single GPIO + * + * This frees a single GPIOs previously returned from gpio_request_by_name(). + * + * @dev: Device which requested the GPIO + * @desc: GPIO to free + * @return 0 if OK, -ve on error + */ +int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc); + +/** + * gpio_free_list() - Free a list of GPIOs + * + * This frees a list of GPIOs previously returned from + * gpio_request_list_by_name(). + * + * @dev: Device which requested the GPIOs + * @desc: List of GPIOs to free + * @count: Number of GPIOs in the list + * @return 0 if OK, -ve on error + */ +int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count); + +/** + * gpio_free_list_nodev() - free GPIOs without a device + * + * This is a version of gpio_free_list() that does not use a + * device. Avoid it unless the caller is not yet using driver model + */ +int gpio_free_list_nodev(struct gpio_desc *desc, int count); + +/** + * dm_gpio_get_value() - Get the value of a GPIO + * + * This is the driver model version of the existing gpio_get_value() function + * and should be used instead of that. + * + * For now, these functions have a dm_ prefix since they conflict with + * existing names. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return GPIO value (0 for inactive, 1 for active) or -ve on error + */ +int dm_gpio_get_value(struct gpio_desc *desc); + +int dm_gpio_set_value(struct gpio_desc *desc, int value); + +/** + * dm_gpio_set_dir() - Set the direction for a GPIO + * + * This sets up the direction according tot the provided flags. It will do + * nothing unless the direction is actually specified. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return 0 if OK, -ve on error + */ +int dm_gpio_set_dir(struct gpio_desc *desc); + +/** + * dm_gpio_set_dir_flags() - Set direction using specific flags + * + * This is like dm_gpio_set_dir() except that the flags value is provided + * instead of being used from desc->flags. This is needed because in many + * cases the GPIO description does not include direction information. + * Note that desc->flags is updated by this function. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @flags: New flags to use + * @return 0 if OK, -ve on error, in which case desc->flags is not updated + */ +int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags); + +/** + * gpio_get_number() - Get the global GPIO number of a GPIO + * + * This should only be used for debugging or interest. It returns the nummber + * that should be used for gpio_get_value() etc. to access this GPIO. + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @return GPIO number, or -ve if not found + */ +int gpio_get_number(struct gpio_desc *desc); + #endif /* _ASM_GENERIC_GPIO_H_ */ diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 94bd0d99dc..b29daf1af4 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -174,5 +174,72 @@ static int dm_test_gpio_leak(struct dm_test_state *dms) return 0; } - DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we can find GPIOs using phandles */ +static int dm_test_gpio_phandles(struct dm_test_state *dms) +{ + struct gpio_desc desc, desc_list[8], desc_list2[8]; + struct udevice *dev, *gpio_a, *gpio_b; + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_asserteq_str("a-test", dev->name); + + ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b)); + ut_asserteq_str("base-gpios", gpio_a->name); + ut_asserteq(true, !!device_active(gpio_a)); + ut_asserteq_ptr(gpio_a, desc.dev); + ut_asserteq(4, desc.offset); + /* GPIOF_INPUT is the sandbox GPIO driver default */ + ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL)); + ut_assertok(dm_gpio_free(dev, &desc)); + + ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc, + 0)); + ut_asserteq_ptr(NULL, desc.dev); + ut_asserteq(desc.offset, 0); + ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc, + 0)); + + /* Last GPIO is ignord as it comes after <0> */ + ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, + ARRAY_SIZE(desc_list), 0)); + ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios", + desc_list2, + ARRAY_SIZE(desc_list2), + 0)); + ut_assertok(gpio_free_list(dev, desc_list, 3)); + ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list, + ARRAY_SIZE(desc_list), + GPIOD_IS_OUT | + GPIOD_IS_OUT_ACTIVE)); + ut_asserteq_ptr(gpio_a, desc_list[0].dev); + ut_asserteq(1, desc_list[0].offset); + ut_asserteq_ptr(gpio_a, desc_list[1].dev); + ut_asserteq(4, desc_list[1].offset); + ut_asserteq_ptr(gpio_b, desc_list[2].dev); + ut_asserteq(5, desc_list[2].offset); + ut_asserteq(1, dm_gpio_get_value(desc_list)); + ut_assertok(gpio_free_list(dev, desc_list, 3)); + + ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list, + ARRAY_SIZE(desc_list), 0)); + /* This was set to output previously, so still will be */ + ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL)); + + /* Active low should invert the input value */ + ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL)); + ut_asserteq(1, dm_gpio_get_value(&desc_list[2])); + + ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL)); + ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL)); + ut_asserteq(0, dm_gpio_get_value(&desc_list[4])); + ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL)); + ut_asserteq(1, dm_gpio_get_value(&desc_list[5])); + + + return 0; +} +DM_TEST(dm_test_gpio_phandles, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test.dts b/test/dm/test.dts index fb0272a59c..33f2c00747 100644 --- a/test/dm/test.dts +++ b/test/dm/test.dts @@ -22,6 +22,11 @@ ping-expect = <0>; ping-add = <0>; u-boot,dm-pre-reloc; + test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>, + <0>, <&gpio_a 12>; + test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>, + <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>, + <&gpio_b 9 0xc 3 2 1>; }; junk { @@ -83,12 +88,16 @@ gpio_a: base-gpios { compatible = "sandbox,gpio"; + gpio-controller; + #gpio-cells = <1>; gpio-bank-name = "a"; num-gpios = <20>; }; - extra-gpios { + gpio_b: extra-gpios { compatible = "sandbox,gpio"; + gpio-controller; + #gpio-cells = <5>; gpio-bank-name = "b"; num-gpios = <10>; }; -- cgit From 5d1c17e9a5803af9c65966e469437735ac29659e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:30 -0700 Subject: dm: gpio: Mark the old GPIO API deprecated Add a deprecation notice to each function so that it is more obvious that we are moving GPIOs to driver model. Signed-off-by: Simon Glass --- include/asm-generic/gpio.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 26534150f1..3b96b8209a 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -10,6 +10,15 @@ /* * Generic GPIO API for U-Boot * + * -- + * NB: This is deprecated. Please use the driver model functions instead: + * + * - gpio_request_by_name() + * - dm_gpio_get_value() etc. + * + * For now we need a dm_ prefix on some functions to avoid name collision. + * -- + * * GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined * by the SOC/architecture. * @@ -26,6 +35,7 @@ */ /** + * @deprecated Please use driver model instead * Request a GPIO. This should be called before any of the other functions * are used on this GPIO. * @@ -39,6 +49,7 @@ int gpio_request(unsigned gpio, const char *label); /** + * @deprecated Please use driver model instead * Stop using the GPIO. This function should not alter pin configuration. * * @param gpio GPIO number @@ -47,6 +58,7 @@ int gpio_request(unsigned gpio, const char *label); int gpio_free(unsigned gpio); /** + * @deprecated Please use driver model instead * Make a GPIO an input. * * @param gpio GPIO number @@ -55,6 +67,7 @@ int gpio_free(unsigned gpio); int gpio_direction_input(unsigned gpio); /** + * @deprecated Please use driver model instead * Make a GPIO an output, and set its value. * * @param gpio GPIO number @@ -64,6 +77,7 @@ int gpio_direction_input(unsigned gpio); int gpio_direction_output(unsigned gpio, int value); /** + * @deprecated Please use driver model instead * Get a GPIO's value. This will work whether the GPIO is an input * or an output. * @@ -73,6 +87,7 @@ int gpio_direction_output(unsigned gpio, int value); int gpio_get_value(unsigned gpio); /** + * @deprecated Please use driver model instead * Set an output GPIO's value. The GPIO must already be an output or * this function may have no effect. * @@ -134,6 +149,8 @@ static inline bool dm_gpio_is_valid(struct gpio_desc *desc) * which means this is GPIO bank b, offset 4, currently set to input, current * value 1, [x] means that it is requested and the owner is 'sdmmc_cd' * + * TODO(sjg@chromium.org): This should use struct gpio_desc + * * @dev: Device to check * @offset: Offset of device GPIO to check * @buf: Place to put string @@ -146,6 +163,8 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize); * * Note this returns GPIOF_UNUSED if the GPIO is not requested. * + * TODO(sjg@chromium.org): This should use struct gpio_desc + * * @dev: Device to check * @offset: Offset of device GPIO to check * @namep: If non-NULL, this is set to the nane given when the GPIO @@ -163,6 +182,8 @@ int gpio_get_function(struct udevice *dev, int offset, const char **namep); * Note this does not return GPIOF_UNUSED - it will always return the GPIO * driver's view of a pin function, even if it is not correctly set up. * + * TODO(sjg@chromium.org): This should use struct gpio_desc + * * @dev: Device to check * @offset: Offset of device GPIO to check * @namep: If non-NULL, this is set to the nane given when the GPIO -- cgit From a02af4aeece40e93bc7d79cd5dc912409efb7020 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:31 -0700 Subject: dm: demo: Add a simple GPIO demonstration Add a new 'demo light' command which uses GPIOs to control imaginary lights. Each light is assigned a bit number in the overall value. This provides an example driver for using the new GPIO API. Signed-off-by: Simon Glass --- arch/sandbox/dts/sandbox.dts | 11 ++++++- common/cmd_demo.c | 29 +++++++++++++++++- drivers/demo/demo-shape.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ drivers/demo/demo-uclass.c | 20 +++++++++++++ include/dm-demo.h | 4 +++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 11748aec79..4c63e4f9ed 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -19,6 +19,7 @@ colour = "cyan"; sides = <3>; character = <83>; + light-gpios = <&gpio_a 2>, <&gpio_b 6 0>; }; square { compatible = "demo-shape"; @@ -126,7 +127,7 @@ 0x070b0067 0x070c0069>; }; - gpio_a: gpios { + gpio_a: gpios@0 { gpio-controller; compatible = "sandbox,gpio"; #gpio-cells = <1>; @@ -134,6 +135,14 @@ num-gpios = <20>; }; + gpio_b: gpios@1 { + gpio-controller; + compatible = "sandbox,gpio"; + #gpio-cells = <2>; + gpio-bank-name = "b"; + num-gpios = <10>; + }; + i2c@0 { #address-cells = <1>; #size-cells = <0>; diff --git a/common/cmd_demo.c b/common/cmd_demo.c index 652c61c707..bcb34d9045 100644 --- a/common/cmd_demo.c +++ b/common/cmd_demo.c @@ -39,6 +39,26 @@ static int do_demo_status(cmd_tbl_t *cmdtp, int flag, int argc, return 0; } +static int do_demo_light(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int light; + int ret; + + if (argc) { + light = simple_strtoul(argv[0], NULL, 16); + ret = demo_set_light(demo_dev, light); + } else { + ret = demo_get_light(demo_dev); + if (ret >= 0) { + printf("Light: %x\n", ret); + ret = 0; + } + } + + return ret; +} + int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct udevice *dev; @@ -61,6 +81,7 @@ int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static cmd_tbl_t demo_commands[] = { U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", ""), U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", ""), + U_BOOT_CMD_MKENT(light, 2, 1, do_demo_light, "", ""), U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", ""), }; @@ -86,6 +107,10 @@ static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return cmd_process_error(cmdtp, ret); argc--; argv++; + } else { + demo_dev = NULL; + if (demo_cmd->cmd != do_demo_list) + return CMD_RET_USAGE; } ret = demo_cmd->cmd(demo_cmd, flag, argc, argv); @@ -98,5 +123,7 @@ U_BOOT_CMD( "Driver model (dm) demo operations", "list List available demo devices\n" "demo hello [] Say hello\n" - "demo status Get demo device status" + "demo light [] Set or get the lights\n" + "demo status Get demo device status\n" + "demo list List available demo devices" ); diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c index 3fa9c59947..d908736cff 100644 --- a/drivers/demo/demo-shape.c +++ b/drivers/demo/demo-shape.c @@ -11,6 +11,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -20,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR; struct shape_data { int num_chars; /* Number of non-space characters output so far */ + struct gpio_desc gpio_desc[8]; + int gpio_count; }; /* Crazy little function to draw shapes on the console */ @@ -89,9 +92,52 @@ static int shape_status(struct udevice *dev, int *status) return 0; } +static int set_light(struct udevice *dev, int light) +{ + struct shape_data *priv = dev_get_priv(dev); + struct gpio_desc *desc; + int ret; + int i; + + desc = priv->gpio_desc; + for (i = 0; i < priv->gpio_count; i++, desc++) { + uint mask = 1 << i; + + ret = dm_gpio_set_value(desc, light & mask); + if (ret < 0) + return ret; + } + + return 0; +} + +static int get_light(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + struct gpio_desc *desc; + uint value = 0; + int ret; + int i; + + desc = priv->gpio_desc; + for (i = 0; i < priv->gpio_count; i++, desc++) { + uint mask = 1 << i; + + ret = dm_gpio_get_value(desc); + if (ret < 0) + return ret; + if (ret) + value |= mask; + } + + return value; +} + static const struct demo_ops shape_ops = { .hello = shape_hello, .status = shape_status, + .get_light = get_light, + .set_light = set_light, }; static int shape_ofdata_to_platdata(struct udevice *dev) @@ -111,6 +157,29 @@ static int shape_ofdata_to_platdata(struct udevice *dev) return 0; } +static int dm_shape_probe(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + int ret; + + ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc, + ARRAY_SIZE(priv->gpio_desc), + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret < 0) + return ret; + priv->gpio_count = ret; + debug("%s: %d GPIOs\n", __func__, priv->gpio_count); + + return 0; +} + +static int dm_shape_remove(struct udevice *dev) +{ + struct shape_data *priv = dev_get_priv(dev); + + return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count); +} + static const struct udevice_id demo_shape_id[] = { { "demo-shape", 0 }, { }, @@ -122,6 +191,8 @@ U_BOOT_DRIVER(demo_shape_drv) = { .id = UCLASS_DEMO, .ofdata_to_platdata = shape_ofdata_to_platdata, .ops = &shape_ops, + .probe = dm_shape_probe, + .remove = dm_shape_remove, .priv_auto_alloc_size = sizeof(struct shape_data), .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata), }; diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c index f6510d602c..725f06898f 100644 --- a/drivers/demo/demo-uclass.c +++ b/drivers/demo/demo-uclass.c @@ -43,6 +43,26 @@ int demo_status(struct udevice *dev, int *status) return ops->status(dev, status); } +int demo_get_light(struct udevice *dev) +{ + const struct demo_ops *ops = device_get_ops(dev); + + if (!ops->get_light) + return -ENOSYS; + + return ops->get_light(dev); +} + +int demo_set_light(struct udevice *dev, int light) +{ + const struct demo_ops *ops = device_get_ops(dev); + + if (!ops->set_light) + return -ENOSYS; + + return ops->set_light(dev, light); +} + int demo_parse_dt(struct udevice *dev) { struct dm_demo_pdata *pdata = dev_get_platdata(dev); diff --git a/include/dm-demo.h b/include/dm-demo.h index a24fec6658..03722d0c14 100644 --- a/include/dm-demo.h +++ b/include/dm-demo.h @@ -25,10 +25,14 @@ struct dm_demo_pdata { struct demo_ops { int (*hello)(struct udevice *dev, int ch); int (*status)(struct udevice *dev, int *status); + int (*set_light)(struct udevice *dev, int light); + int (*get_light)(struct udevice *dev); }; int demo_hello(struct udevice *dev, int ch); int demo_status(struct udevice *dev, int *status); +int demo_set_light(struct udevice *dev, int light); +int demo_get_light(struct udevice *dev); int demo_list(void); int demo_parse_dt(struct udevice *dev); -- cgit From 32f8a19f6d9aa551dc64868fac4b662c088dfb1f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:32 -0700 Subject: dm: cros_ec: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- drivers/misc/cros_ec.c | 24 ++++++------------------ include/cros_ec.h | 3 ++- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 9b4effb2fb..7b20ffcfa2 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -606,10 +606,10 @@ int cros_ec_reboot(struct cros_ec_dev *dev, enum ec_reboot_cmd cmd, int cros_ec_interrupt_pending(struct cros_ec_dev *dev) { /* no interrupt support : always poll */ - if (!fdt_gpio_isvalid(&dev->ec_int)) + if (!dm_gpio_is_valid(&dev->ec_int)) return -ENOENT; - return !gpio_get_value(dev->ec_int.gpio); + return dm_gpio_get_value(&dev->ec_int); } int cros_ec_info(struct cros_ec_dev *dev, struct ec_response_mkbp_info *info) @@ -1072,7 +1072,8 @@ static int cros_ec_decode_fdt(const void *blob, int node, return -1; } - fdtdec_decode_gpio(blob, node, "ec-interrupt", &dev->ec_int); + gpio_request_by_name_nodev(blob, node, "ec-interrupt", 0, &dev->ec_int, + GPIOD_IS_IN); dev->optimise_flash_write = fdtdec_get_bool(blob, node, "optimise-flash-write"); *devp = dev; @@ -1090,17 +1091,11 @@ int cros_ec_register(struct udevice *dev) char id[MSG_BYTES]; cdev->dev = dev; - fdtdec_decode_gpio(blob, node, "ec-interrupt", &cdev->ec_int); + gpio_request_by_name(dev, "ec-interrupt", 0, &cdev->ec_int, + GPIOD_IS_IN); cdev->optimise_flash_write = fdtdec_get_bool(blob, node, "optimise-flash-write"); - /* we will poll the EC interrupt line */ - fdtdec_setup_gpio(&cdev->ec_int); - if (fdt_gpio_isvalid(&cdev->ec_int)) { - gpio_request(cdev->ec_int.gpio, "cros-ec-irq"); - gpio_direction_input(cdev->ec_int.gpio); - } - if (cros_ec_check_version(cdev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; @@ -1184,13 +1179,6 @@ int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp) } #endif - /* we will poll the EC interrupt line */ - fdtdec_setup_gpio(&dev->ec_int); - if (fdt_gpio_isvalid(&dev->ec_int)) { - gpio_request(dev->ec_int.gpio, "cros-ec-irq"); - gpio_direction_input(dev->ec_int.gpio); - } - if (cros_ec_check_version(dev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; diff --git a/include/cros_ec.h b/include/cros_ec.h index 9e13146ecb..8457c80c5e 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifndef CONFIG_DM_CROS_EC /* Which interface is the device on? */ @@ -39,7 +40,7 @@ struct cros_ec_dev { unsigned int bus_num; /* Bus number (for I2C) */ unsigned int max_frequency; /* Maximum interface frequency */ #endif - struct fdt_gpio_state ec_int; /* GPIO used as EC interrupt line */ + struct gpio_desc ec_int; /* GPIO used as EC interrupt line */ int protocol_version; /* Protocol version to use */ int optimise_flash_write; /* Don't write erased flash blocks */ -- cgit From 838aa5c94adc0da95c858ef70271078fd18dc4c9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:33 -0700 Subject: dm: tegra: Add a GPIO translation function This deals with the polarity bit and selecting the correct bank device given a GPIO number. Signed-off-by: Simon Glass --- drivers/gpio/tegra_gpio.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 88f7ef5bf0..43928b8812 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -21,6 +21,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -251,6 +252,22 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_INPUT; } +static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, + struct fdtdec_phandle_args *args) +{ + int gpio, port, ret; + + gpio = args->args[0]; + port = gpio / TEGRA_GPIOS_PER_PORT; + ret = device_get_child(dev, port, &desc->dev); + if (ret) + return ret; + desc->offset = gpio % TEGRA_GPIOS_PER_PORT; + desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; + + return 0; +} + static const struct dm_gpio_ops gpio_tegra_ops = { .request = tegra_gpio_request, .direction_input = tegra_gpio_direction_input, @@ -258,6 +275,7 @@ static const struct dm_gpio_ops gpio_tegra_ops = { .get_value = tegra_gpio_get_value, .set_value = tegra_gpio_set_value, .get_function = tegra_gpio_get_function, + .xlate = tegra_gpio_xlate, }; /** -- cgit From 1d08b4b7439f6538d37eb603cee83842bad23bc5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:34 -0700 Subject: dm: exynos: Add a GPIO translation function This deals with the polarity bit. It also changes the GPIO devices so that the correct device tree node is linked to each one. This allows us to use the new uclass phandle functionality to implement a proper GPIO binding. Signed-off-by: Simon Glass --- drivers/gpio/s5p_gpio.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 6c41a42c17..0a245ba18a 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -13,6 +13,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -275,12 +276,22 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_FUNC; } +static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, + struct fdtdec_phandle_args *args) +{ + desc->offset = args->args[0]; + desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; + + return 0; +} + static const struct dm_gpio_ops gpio_exynos_ops = { .direction_input = exynos_gpio_direction_input, .direction_output = exynos_gpio_direction_output, .get_value = exynos_gpio_get_value, .set_value = exynos_gpio_set_value, .get_function = exynos_gpio_get_function, + .xlate = exynos_gpio_xlate, }; static int gpio_exynos_probe(struct udevice *dev) @@ -342,7 +353,7 @@ static int gpio_exynos_bind(struct udevice *parent) plat->bank_name, plat, -1, &dev); if (ret) return ret; - dev->of_offset = parent->of_offset; + dev->of_offset = node; } return 0; -- cgit From 04072cba1983fd8b3140b1b97e3d544359d178a0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:35 -0700 Subject: dm: tegra: video: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- arch/arm/include/asm/arch-tegra20/display.h | 9 ++--- drivers/video/tegra.c | 54 +++++++++++------------------ 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/arch/arm/include/asm/arch-tegra20/display.h b/arch/arm/include/asm/arch-tegra20/display.h index a04c84e54b..6feeda3ba8 100644 --- a/arch/arm/include/asm/arch-tegra20/display.h +++ b/arch/arm/include/asm/arch-tegra20/display.h @@ -10,6 +10,7 @@ #include #include +#include /* This holds information about a window which can be displayed */ struct disp_ctl_win { @@ -72,10 +73,10 @@ struct fdt_panel_config { int pwm_channel; /* PWM channel to use for backlight */ enum lcd_cache_t cache_type; - struct fdt_gpio_state backlight_en; /* GPIO for backlight enable */ - struct fdt_gpio_state lvds_shutdown; /* GPIO for lvds shutdown */ - struct fdt_gpio_state backlight_vdd; /* GPIO for backlight vdd */ - struct fdt_gpio_state panel_vdd; /* GPIO for panel vdd */ + struct gpio_desc backlight_en; /* GPIO for backlight enable */ + struct gpio_desc lvds_shutdown; /* GPIO for lvds shutdown */ + struct gpio_desc backlight_vdd; /* GPIO for backlight vdd */ + struct gpio_desc panel_vdd; /* GPIO for panel vdd */ /* * Panel required timings * Timing 1: delay between panel_vdd-rise and data-rise diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c index 57cb0074e2..b8f3431f24 100644 --- a/drivers/video/tegra.c +++ b/drivers/video/tegra.c @@ -149,14 +149,18 @@ static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config) FDT_LCD_CACHE_WRITE_BACK_FLUSH); /* These GPIOs are all optional */ - fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-enable-gpios", - &config->backlight_en); - fdtdec_decode_gpio(blob, display_node, "nvidia,lvds-shutdown-gpios", - &config->lvds_shutdown); - fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios", - &config->backlight_vdd); - fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios", - &config->panel_vdd); + gpio_request_by_name_nodev(blob, display_node, + "nvidia,backlight-enable-gpios", 0, + &config->backlight_en, GPIOD_IS_OUT); + gpio_request_by_name_nodev(blob, display_node, + "nvidia,lvds-shutdown-gpios", 0, + &config->lvds_shutdown, GPIOD_IS_OUT); + gpio_request_by_name_nodev(blob, display_node, + "nvidia,backlight-vdd-gpios", 0, + &config->backlight_vdd, GPIOD_IS_OUT); + gpio_request_by_name_nodev(blob, display_node, + "nvidia,panel-vdd-gpios", 0, + &config->panel_vdd, GPIOD_IS_OUT); return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings", config->panel_timings, FDT_LCD_TIMINGS); @@ -196,36 +200,18 @@ static int handle_stage(const void *blob) */ funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); - - fdtdec_setup_gpio(&config.panel_vdd); - fdtdec_setup_gpio(&config.lvds_shutdown); - fdtdec_setup_gpio(&config.backlight_vdd); - fdtdec_setup_gpio(&config.backlight_en); - - /* - * TODO: If fdt includes output flag we can omit this code - * since fdtdec_setup_gpio will do it for us. - */ - if (fdt_gpio_isvalid(&config.panel_vdd)) - gpio_direction_output(config.panel_vdd.gpio, 0); - if (fdt_gpio_isvalid(&config.lvds_shutdown)) - gpio_direction_output(config.lvds_shutdown.gpio, 0); - if (fdt_gpio_isvalid(&config.backlight_vdd)) - gpio_direction_output(config.backlight_vdd.gpio, 0); - if (fdt_gpio_isvalid(&config.backlight_en)) - gpio_direction_output(config.backlight_en.gpio, 0); break; case STAGE_PANEL_VDD: - if (fdt_gpio_isvalid(&config.panel_vdd)) - gpio_direction_output(config.panel_vdd.gpio, 1); + if (dm_gpio_is_valid(&config.panel_vdd)) + dm_gpio_set_value(&config.panel_vdd, 1); break; case STAGE_LVDS: - if (fdt_gpio_isvalid(&config.lvds_shutdown)) - gpio_set_value(config.lvds_shutdown.gpio, 1); + if (dm_gpio_is_valid(&config.lvds_shutdown)) + dm_gpio_set_value(&config.lvds_shutdown, 1); break; case STAGE_BACKLIGHT_VDD: - if (fdt_gpio_isvalid(&config.backlight_vdd)) - gpio_set_value(config.backlight_vdd.gpio, 1); + if (dm_gpio_is_valid(&config.backlight_vdd)) + dm_gpio_set_value(&config.backlight_vdd, 1); break; case STAGE_PWM: /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */ @@ -235,8 +221,8 @@ static int handle_stage(const void *blob) pwm_enable(config.pwm_channel, 32768, 0xdf, 1); break; case STAGE_BACKLIGHT_EN: - if (fdt_gpio_isvalid(&config.backlight_en)) - gpio_set_value(config.backlight_en.gpio, 1); + if (dm_gpio_is_valid(&config.backlight_en)) + dm_gpio_set_value(&config.backlight_en, 1); break; case STAGE_DONE: break; -- cgit From b0265d56fe24a757638a2a0ca76ec1400f43d348 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:36 -0700 Subject: dm: tegra: nand: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- drivers/mtd/nand/tegra_nand.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c index 163cf29a39..b660f3b206 100644 --- a/drivers/mtd/nand/tegra_nand.c +++ b/drivers/mtd/nand/tegra_nand.c @@ -79,7 +79,7 @@ enum { struct fdt_nand { struct nand_ctlr *reg; int enabled; /* 1 to enable, 0 to disable */ - struct fdt_gpio_state wp_gpio; /* write-protect GPIO */ + struct gpio_desc wp_gpio; /* write-protect GPIO */ s32 width; /* bit width, normally 8 */ u32 timing[FDT_NAND_TIMING_COUNT]; }; @@ -945,8 +945,8 @@ static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config) config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg"); config->enabled = fdtdec_get_is_enabled(blob, node); config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8); - err = fdtdec_decode_gpio(blob, node, "nvidia,wp-gpios", - &config->wp_gpio); + err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0, + &config->wp_gpio, GPIOD_IS_OUT); if (err) return err; err = fdtdec_get_int_array(blob, node, "nvidia,timing", @@ -1009,8 +1009,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum) /* Adjust timing for NAND device */ setup_timing(config->timing, info->reg); - fdtdec_setup_gpio(&config->wp_gpio); - gpio_direction_output(config->wp_gpio.gpio, 1); + dm_gpio_set_value(&config->wp_gpio, 1); our_mtd = &nand_info[devnum]; our_mtd->priv = nand; -- cgit From 9762a415c8ed1d2e7cb7d202a29a3c2133184808 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:37 -0700 Subject: dm: zynq: Remove inline gpio functions These functions serve no useful purpose, and conflict with the generic API. Drop them. Signed-off-by: Simon Glass --- arch/arm/include/asm/arch-zynq/gpio.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h index 2dbba756d7..a26ae87293 100644 --- a/arch/arm/include/asm/arch-zynq/gpio.h +++ b/arch/arm/include/asm/arch-zynq/gpio.h @@ -7,19 +7,4 @@ #ifndef _ZYNQ_GPIO_H #define _ZYNQ_GPIO_H -inline int gpio_get_value(unsigned gpio) -{ - return 0; -} - -inline int gpio_set_value(unsigned gpio, int val) -{ - return 0; -} - -inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - #endif /* _ZYNQ_GPIO_H */ -- cgit From 0347960b8732b8d8506c9123c217b503666a4ad8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:38 -0700 Subject: dm: mmc: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- arch/arm/include/asm/arch-pantheon/gpio.h | 0 arch/arm/include/asm/arch-tegra/tegra_mmc.h | 7 +++--- drivers/mmc/s5p_sdhci.c | 20 +++++++--------- drivers/mmc/tegra_mmc.c | 36 +++++++++++------------------ include/sdhci.h | 6 ++--- 5 files changed, 28 insertions(+), 41 deletions(-) create mode 100644 arch/arm/include/asm/arch-pantheon/gpio.h diff --git a/arch/arm/include/asm/arch-pantheon/gpio.h b/arch/arm/include/asm/arch-pantheon/gpio.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h index 84e7b5553d..a20bdaa618 100644 --- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h +++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h @@ -10,6 +10,7 @@ #define __TEGRA_MMC_H_ #include +#include /* for mmc_config definition */ #include @@ -134,9 +135,9 @@ struct mmc_host { int enabled; /* 1 to enable, 0 to disable */ int width; /* Bus Width, 1, 4 or 8 */ enum periph_id mmc_id; /* Peripheral ID: PERIPH_ID_... */ - struct fdt_gpio_state cd_gpio; /* Change Detect GPIO */ - struct fdt_gpio_state pwr_gpio; /* Power GPIO */ - struct fdt_gpio_state wp_gpio; /* Write Protect GPIO */ + struct gpio_desc cd_gpio; /* Change Detect GPIO */ + struct gpio_desc pwr_gpio; /* Power GPIO */ + struct gpio_desc wp_gpio; /* Write Protect GPIO */ unsigned int version; /* SDHCI spec. version */ unsigned int clock; /* Current clock (MHz) */ struct mmc_config cfg; /* mmc configuration */ diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index a5d34876bb..3899372e0e 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -102,17 +102,14 @@ struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS]; static int do_sdhci_init(struct sdhci_host *host) { - char str[20]; int dev_id, flag; int err = 0; flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; dev_id = host->index + PERIPH_ID_SDMMC0; - if (fdt_gpio_isvalid(&host->pwr_gpio)) { - sprintf(str, "sdhci%d_power", host->index & 0xf); - gpio_request(host->pwr_gpio.gpio, str); - gpio_direction_output(host->pwr_gpio.gpio, 1); + if (dm_gpio_is_valid(&host->pwr_gpio)) { + dm_gpio_set_value(&host->pwr_gpio, 1); err = exynos_pinmux_config(dev_id, flag); if (err) { debug("MMC not configured\n"); @@ -120,11 +117,8 @@ static int do_sdhci_init(struct sdhci_host *host) } } - if (fdt_gpio_isvalid(&host->cd_gpio)) { - sprintf(str, "sdhci%d_cd", host->index & 0xf); - gpio_request(host->cd_gpio.gpio, str); - gpio_direction_input(host->cd_gpio.gpio); - if (gpio_get_value(host->cd_gpio.gpio)) + if (dm_gpio_is_valid(&host->cd_gpio)) { + if (dm_gpio_get_value(&host->cd_gpio)) return -ENODEV; err = exynos_pinmux_config(dev_id, flag); @@ -166,8 +160,10 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) } host->ioaddr = (void *)base; - fdtdec_decode_gpio(blob, node, "pwr-gpios", &host->pwr_gpio); - fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); + gpio_request_by_name_nodev(blob, node, "pwr-gpios", 0, &host->pwr_gpio, + GPIOD_IS_OUT); + gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, + GPIOD_IS_IN); return 0; } diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 2bd36b0ee7..2cd8cf10ae 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -515,8 +515,8 @@ static int tegra_mmc_getcd(struct mmc *mmc) debug("tegra_mmc_getcd called\n"); - if (fdt_gpio_isvalid(&host->cd_gpio)) - return fdtdec_get_gpio(&host->cd_gpio); + if (dm_gpio_is_valid(&host->cd_gpio)) + return dm_gpio_get_value(&host->cd_gpio); return 1; } @@ -531,7 +531,6 @@ static const struct mmc_ops tegra_mmc_ops = { static int do_mmc_init(int dev_index) { struct mmc_host *host; - char gpusage[12]; /* "SD/MMCn PWR" or "SD/MMCn CD" */ struct mmc *mmc; /* DT should have been read & host config filled in */ @@ -539,27 +538,15 @@ static int do_mmc_init(int dev_index) if (!host->enabled) return -1; - debug(" do_mmc_init: index %d, bus width %d " - "pwr_gpio %d cd_gpio %d\n", - dev_index, host->width, - host->pwr_gpio.gpio, host->cd_gpio.gpio); + debug(" do_mmc_init: index %d, bus width %d pwr_gpio %d cd_gpio %d\n", + dev_index, host->width, gpio_get_number(&host->pwr_gpio), + gpio_get_number(&host->cd_gpio)); host->clock = 0; clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000); - if (fdt_gpio_isvalid(&host->pwr_gpio)) { - sprintf(gpusage, "SD/MMC%d PWR", dev_index); - gpio_request(host->pwr_gpio.gpio, gpusage); - gpio_direction_output(host->pwr_gpio.gpio, 1); - debug(" Power GPIO name = %s\n", host->pwr_gpio.name); - } - - if (fdt_gpio_isvalid(&host->cd_gpio)) { - sprintf(gpusage, "SD/MMC%d CD", dev_index); - gpio_request(host->cd_gpio.gpio, gpusage); - gpio_direction_input(host->cd_gpio.gpio); - debug(" CD GPIO name = %s\n", host->cd_gpio.name); - } + if (dm_gpio_is_valid(&host->pwr_gpio)) + dm_gpio_set_value(&host->pwr_gpio, 1); memset(&host->cfg, 0, sizeof(host->cfg)); @@ -626,9 +613,12 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host) debug("%s: no sdmmc width found\n", __func__); /* These GPIOs are optional */ - fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); - fdtdec_decode_gpio(blob, node, "wp-gpios", &host->wp_gpio); - fdtdec_decode_gpio(blob, node, "power-gpios", &host->pwr_gpio); + gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, + GPIOD_IS_IN); + gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio, + GPIOD_IS_IN); + gpio_request_by_name_nodev(blob, node, "power-gpios", 0, + &host->pwr_gpio, GPIOD_IS_OUT); debug("%s: found controller at %p, width = %d, periph_id = %d\n", __func__, host->reg, host->width, host->mmc_id); diff --git a/include/sdhci.h b/include/sdhci.h index aa4a0e9654..23893b5740 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -12,7 +12,7 @@ #include #include -#include +#include /* * Controller registers @@ -246,8 +246,8 @@ struct sdhci_host { int index; int bus_width; - struct fdt_gpio_state pwr_gpio; /* Power GPIO */ - struct fdt_gpio_state cd_gpio; /* Card Detect GPIO */ + struct gpio_desc pwr_gpio; /* Power GPIO */ + struct gpio_desc cd_gpio; /* Card Detect GPIO */ void (*set_control_reg)(struct sdhci_host *host); void (*set_clock)(int dev_index, unsigned int div); -- cgit From 46927e1ef40682656d69cbe18abf327e2f842a23 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:39 -0700 Subject: dm: usb: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- drivers/usb/host/ehci-exynos.c | 10 +++++----- drivers/usb/host/ehci-tegra.c | 38 ++++++++++++++++++-------------------- drivers/usb/host/xhci-exynos5.c | 10 +++++----- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 6fdbf5724f..f3c077d82e 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR; struct exynos_ehci { struct exynos_usb_phy *usb; struct ehci_hccr *hcd; - struct fdt_gpio_state vbus_gpio; + struct gpio_desc vbus_gpio; }; static struct exynos_ehci exynos; @@ -61,7 +61,8 @@ static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos) exynos->hcd = (struct ehci_hccr *)addr; /* Vbus gpio */ - fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio); + gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0, + &exynos->vbus_gpio, GPIOD_IS_OUT); depth = 0; node = fdtdec_next_compatible_subnode(blob, node, @@ -236,9 +237,8 @@ int ehci_hcd_init(int index, enum usb_init_type init, #ifdef CONFIG_OF_CONTROL /* setup the Vbus gpio here */ - if (fdt_gpio_isvalid(&ctx->vbus_gpio) && - !fdtdec_setup_gpio(&ctx->vbus_gpio)) - gpio_direction_output(ctx->vbus_gpio.gpio, 1); + if (dm_gpio_is_valid(&ctx->vbus_gpio)) + dm_gpio_set_value(&ctx->vbus_gpio, 1); #endif setup_usb_phy(ctx->usb); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 5f0a98e8b8..b5ad1e35e5 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -72,8 +72,8 @@ struct fdt_usb { enum usb_init_type init_type; enum dr_mode dr_mode; /* dual role mode */ enum periph_id periph_id;/* peripheral id */ - struct fdt_gpio_state vbus_gpio; /* GPIO for vbus enable */ - struct fdt_gpio_state phy_reset_gpio; /* GPIO to reset ULPI phy */ + struct gpio_desc vbus_gpio; /* GPIO for vbus enable */ + struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */ }; static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */ @@ -252,17 +252,14 @@ static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init) return; } - if (fdt_gpio_isvalid(&config->vbus_gpio)) { + if (dm_gpio_is_valid(&config->vbus_gpio)) { int vbus_value; - fdtdec_setup_gpio(&config->vbus_gpio); + vbus_value = (init == USB_INIT_HOST); + dm_gpio_set_value(&config->vbus_gpio, vbus_value); - vbus_value = (init == USB_INIT_HOST) ^ - !!(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW); - gpio_direction_output(config->vbus_gpio.gpio, vbus_value); - - debug("set_up_vbus: GPIO %d %d\n", config->vbus_gpio.gpio, - vbus_value); + debug("set_up_vbus: GPIO %d %d\n", + gpio_get_number(&config->vbus_gpio), vbus_value); } } @@ -360,7 +357,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config, * mux must be switched to actually use a_sess_vld threshold. */ if (config->dr_mode == DR_MODE_OTG && - fdt_gpio_isvalid(&config->vbus_gpio)) + dm_gpio_is_valid(&config->vbus_gpio)) clrsetbits_le32(&usbctlr->usb1_legacy_ctrl, VBUS_SENSE_CTL_MASK, VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); @@ -569,11 +566,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config, clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CONFIG_ULPI_REF_CLK); /* reset ULPI phy */ - if (fdt_gpio_isvalid(&config->phy_reset_gpio)) { - fdtdec_setup_gpio(&config->phy_reset_gpio); - gpio_direction_output(config->phy_reset_gpio.gpio, 0); + if (dm_gpio_is_valid(&config->phy_reset_gpio)) { + dm_gpio_set_value(&config->phy_reset_gpio, 0); mdelay(5); - gpio_set_value(config->phy_reset_gpio.gpio, 1); + dm_gpio_set_value(&config->phy_reset_gpio, 1); } /* Reset the usb controller */ @@ -685,14 +681,16 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) debug("%s: Missing/invalid peripheral ID\n", __func__); return -FDT_ERR_NOTFOUND; } - fdtdec_decode_gpio(blob, node, "nvidia,vbus-gpio", &config->vbus_gpio); - fdtdec_decode_gpio(blob, node, "nvidia,phy-reset-gpio", - &config->phy_reset_gpio); + gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0, + &config->vbus_gpio, GPIOD_IS_OUT); + gpio_request_by_name_nodev(blob, node, "nvidia,phy-reset-gpio", 0, + &config->phy_reset_gpio, GPIOD_IS_OUT); debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, " "vbus=%d, phy_reset=%d, dr_mode=%d\n", config->enabled, config->has_legacy_mode, config->utmi, - config->ulpi, config->periph_id, config->vbus_gpio.gpio, - config->phy_reset_gpio.gpio, config->dr_mode); + config->ulpi, config->periph_id, + gpio_get_number(&config->vbus_gpio), + gpio_get_number(&config->phy_reset_gpio), config->dr_mode); return 0; } diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index b4946a3f1c..a77c8bc919 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -40,7 +40,7 @@ struct exynos_xhci { struct exynos_usb3_phy *usb3_phy; struct xhci_hccr *hcd; struct dwc3 *dwc3_reg; - struct fdt_gpio_state vbus_gpio; + struct gpio_desc vbus_gpio; }; static struct exynos_xhci exynos; @@ -69,7 +69,8 @@ static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos) exynos->hcd = (struct xhci_hccr *)addr; /* Vbus gpio */ - fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio); + gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0, + &exynos->vbus_gpio, GPIOD_IS_OUT); depth = 0; node = fdtdec_next_compatible_subnode(blob, node, @@ -298,9 +299,8 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor) #ifdef CONFIG_OF_CONTROL /* setup the Vbus gpio here */ - if (fdt_gpio_isvalid(&ctx->vbus_gpio) && - !fdtdec_setup_gpio(&ctx->vbus_gpio)) - gpio_direction_output(ctx->vbus_gpio.gpio, 1); + if (dm_gpio_is_valid(&ctx->vbus_gpio)) + dm_gpio_set_value(&ctx->vbus_gpio, 1); #endif ret = exynos_xhci_core_init(ctx); -- cgit From 050fb909b630344c5541ff60459fdb06189a8228 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:40 -0700 Subject: dm: spi: Remove use of fdtdec GPIO support These functions are going away, so use the new uclass support instead. Signed-off-by: Simon Glass --- drivers/spi/soft_spi.c | 62 +++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 558803618a..423c98d1a5 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -21,10 +21,10 @@ DECLARE_GLOBAL_DATA_PTR; struct soft_spi_platdata { - struct fdt_gpio_state cs; - struct fdt_gpio_state sclk; - struct fdt_gpio_state mosi; - struct fdt_gpio_state miso; + struct gpio_desc cs; + struct gpio_desc sclk; + struct gpio_desc mosi; + struct gpio_desc miso; int spi_delay_us; }; @@ -35,9 +35,8 @@ struct soft_spi_priv { static int soft_spi_scl(struct udevice *dev, int bit) { struct soft_spi_platdata *plat = dev->platdata; - struct soft_spi_priv *priv = dev_get_priv(dev); - gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL ? bit : !bit); + dm_gpio_set_value(&plat->sclk, bit); return 0; } @@ -46,7 +45,7 @@ static int soft_spi_sda(struct udevice *dev, int bit) { struct soft_spi_platdata *plat = dev->platdata; - gpio_set_value(plat->mosi.gpio, bit); + dm_gpio_set_value(&plat->mosi, bit); return 0; } @@ -54,11 +53,10 @@ static int soft_spi_sda(struct udevice *dev, int bit) static int soft_spi_cs_activate(struct udevice *dev) { struct soft_spi_platdata *plat = dev->platdata; - struct soft_spi_priv *priv = dev_get_priv(dev); - gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH)); - gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL); - gpio_set_value(plat->cs.gpio, priv->mode & SPI_CS_HIGH); + dm_gpio_set_value(&plat->cs, 0); + dm_gpio_set_value(&plat->sclk, 0); + dm_gpio_set_value(&plat->cs, 1); return 0; } @@ -66,9 +64,8 @@ static int soft_spi_cs_activate(struct udevice *dev) static int soft_spi_cs_deactivate(struct udevice *dev) { struct soft_spi_platdata *plat = dev->platdata; - struct soft_spi_priv *priv = dev_get_priv(dev); - gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH)); + dm_gpio_set_value(&plat->cs, 0); return 0; } @@ -109,7 +106,6 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen, uchar tmpdout = 0; const u8 *txd = dout; u8 *rxd = din; - int cpol = priv->mode & SPI_CPOL; int cpha = priv->mode & SPI_CPHA; unsigned int j; @@ -137,19 +133,19 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen, } if (!cpha) - soft_spi_scl(dev, !cpol); + soft_spi_scl(dev, 0); soft_spi_sda(dev, tmpdout & 0x80); udelay(plat->spi_delay_us); if (cpha) - soft_spi_scl(dev, !cpol); + soft_spi_scl(dev, 0); else - soft_spi_scl(dev, cpol); + soft_spi_scl(dev, 1); tmpdin <<= 1; - tmpdin |= gpio_get_value(plat->miso.gpio); + tmpdin |= dm_gpio_get_value(&plat->miso); tmpdout <<= 1; udelay(plat->spi_delay_us); if (cpha) - soft_spi_scl(dev, cpol); + soft_spi_scl(dev, 1); } /* * If the number of bits isn't a multiple of 8, shift the last @@ -205,11 +201,6 @@ static int soft_spi_ofdata_to_platdata(struct udevice *dev) const void *blob = gd->fdt_blob; int node = dev->of_offset; - if (fdtdec_decode_gpio(blob, node, "cs-gpio", &plat->cs) || - fdtdec_decode_gpio(blob, node, "sclk-gpio", &plat->sclk) || - fdtdec_decode_gpio(blob, node, "mosi-gpio", &plat->mosi) || - fdtdec_decode_gpio(blob, node, "miso-gpio", &plat->miso)) - return -EINVAL; plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0); return 0; @@ -219,16 +210,19 @@ static int soft_spi_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parentdata(dev); struct soft_spi_platdata *plat = dev->platdata; - - gpio_request(plat->cs.gpio, "soft_spi_cs"); - gpio_request(plat->sclk.gpio, "soft_spi_sclk"); - gpio_request(plat->mosi.gpio, "soft_spi_mosi"); - gpio_request(plat->miso.gpio, "soft_spi_miso"); - - gpio_direction_output(plat->sclk.gpio, slave->mode & SPI_CPOL); - gpio_direction_output(plat->mosi.gpio, 1); - gpio_direction_input(plat->miso.gpio); - gpio_direction_output(plat->cs.gpio, !(slave->mode & SPI_CS_HIGH)); + int cs_flags, clk_flags; + + cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW; + clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0; + if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs, + GPIOD_IS_OUT | cs_flags) || + gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk, + GPIOD_IS_OUT | clk_flags) || + gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) || + gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso, + GPIOD_IS_IN)) + return -EINVAL; return 0; } -- cgit From 2b2b50bc8748bf1ddb2d96da7157f9eecbe24961 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:41 -0700 Subject: dm: tegra: dts: Use TEGRA_GPIO() macro for all GPIOs This new method is much easier and matches the kernel. Signed-off-by: Simon Glass --- arch/arm/dts/tegra114-dalmore.dts | 5 ++--- arch/arm/dts/tegra124-jetson-tk1.dts | 9 +++++---- arch/arm/dts/tegra124-venice2.dts | 9 +++++---- arch/arm/dts/tegra20-colibri_t20_iris.dts | 10 +++++----- arch/arm/dts/tegra20-harmony.dts | 28 ++++++++++++++++------------ arch/arm/dts/tegra20-medcom-wide.dts | 9 ++++++--- arch/arm/dts/tegra20-paz00.dts | 18 +++++++++++------- arch/arm/dts/tegra20-seaboard.dts | 22 +++++++++++++--------- arch/arm/dts/tegra20-tamonten.dtsi | 9 +++++---- arch/arm/dts/tegra20-tec.dts | 9 ++++++--- arch/arm/dts/tegra20-trimslice.dts | 8 ++++---- arch/arm/dts/tegra20-ventana.dts | 18 +++++++++++------- arch/arm/dts/tegra20-whistler.dts | 2 +- arch/arm/dts/tegra30-apalis.dts | 10 +++++----- arch/arm/dts/tegra30-beaver.dts | 10 +++++----- arch/arm/dts/tegra30-cardhu.dts | 8 ++++---- arch/arm/dts/tegra30-colibri.dts | 6 +++--- arch/arm/dts/tegra30-tamonten.dtsi | 4 ++-- 18 files changed, 109 insertions(+), 85 deletions(-) diff --git a/arch/arm/dts/tegra114-dalmore.dts b/arch/arm/dts/tegra114-dalmore.dts index 81ad212e71..51ff266d76 100644 --- a/arch/arm/dts/tegra114-dalmore.dts +++ b/arch/arm/dts/tegra114-dalmore.dts @@ -57,7 +57,7 @@ }; sdhci@78000400 { - cd-gpios = <&gpio 170 1>; /* gpio PV2 */ + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; bus-width = <4>; status = "okay"; }; @@ -68,8 +68,7 @@ }; usb@7d008000 { - /* SPDIF_IN: USB_VBUS_EN1 */ - nvidia,vbus-gpio = <&gpio 86 0>; + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>; status = "okay"; }; }; diff --git a/arch/arm/dts/tegra124-jetson-tk1.dts b/arch/arm/dts/tegra124-jetson-tk1.dts index 51fef54d57..e7b66d81a4 100644 --- a/arch/arm/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/dts/tegra124-jetson-tk1.dts @@ -303,8 +303,9 @@ sdhci@700b0400 { status = "okay"; - cd-gpios = <&gpio 170 1>; /* gpio PV2 */ - power-gpios = <&gpio 136 0>; /* gpio PR0 */ + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>; + wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -316,12 +317,12 @@ usb@7d000000 { status = "okay"; dr_mode = "otg"; - nvidia,vbus-gpio = <&gpio 108 0>; /* gpio PN4, USB_VBUS_EN0 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; }; usb@7d008000 { status = "okay"; - nvidia,vbus-gpio = <&gpio 109 0>; /* gpio PN5, USB_VBUS_EN1 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>; }; regulators { diff --git a/arch/arm/dts/tegra124-venice2.dts b/arch/arm/dts/tegra124-venice2.dts index f7ccfc5ddd..9e93cf90c7 100644 --- a/arch/arm/dts/tegra124-venice2.dts +++ b/arch/arm/dts/tegra124-venice2.dts @@ -72,8 +72,9 @@ sdhci@700b0400 { status = "okay"; - cd-gpios = <&gpio 170 0>; /* gpio PV2 */ - power-gpios = <&gpio 136 0>; /* gpio PR0 */ + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>; + wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>; bus-width = <4>; }; @@ -85,11 +86,11 @@ usb@7d000000 { status = "okay"; dr_mode = "otg"; - nvidia,vbus-gpio = <&gpio 108 0>; /* gpio PN4, USB_VBUS_EN0 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; }; usb@7d008000 { status = "okay"; - nvidia,vbus-gpio = <&gpio 109 0>; /* gpio PN5, USB_VBUS_EN1 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm/dts/tegra20-colibri_t20_iris.dts b/arch/arm/dts/tegra20-colibri_t20_iris.dts index 7cf08f4101..3131b9201b 100644 --- a/arch/arm/dts/tegra20-colibri_t20_iris.dts +++ b/arch/arm/dts/tegra20-colibri_t20_iris.dts @@ -22,16 +22,16 @@ }; usb@c5004000 { - nvidia,phy-reset-gpio = <&gpio 169 0>; /* PV1 */ - nvidia,vbus-gpio = <&gpio 217 0>; /* PBB1 */ + nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>; + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>; }; usb@c5008000 { - nvidia,vbus-gpio = <&gpio 178 1>; /* PW2 low-active */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; }; nand-controller@70008000 { - nvidia,wp-gpios = <&gpio 144 0>; /* PS0 */ + nvidia,wp-gpios = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_HIGH>; nvidia,width = <8>; nvidia,timing = <15 100 25 80 25 10 15 10 100>; @@ -43,7 +43,7 @@ sdhci@c8000600 { status = "okay"; - cd-gpios = <&gpio 23 1>; /* gpio PC7 */ + cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; bus-width = <4>; }; }; diff --git a/arch/arm/dts/tegra20-harmony.dts b/arch/arm/dts/tegra20-harmony.dts index 982a14c61c..e6e42295e2 100644 --- a/arch/arm/dts/tegra20-harmony.dts +++ b/arch/arm/dts/tegra20-harmony.dts @@ -37,7 +37,7 @@ }; nand-controller@70008000 { - nvidia,wp-gpios = <&gpio 23 0>; /* PC7 */ + nvidia,wp-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>; nvidia,width = <8>; nvidia,timing = <26 100 20 80 20 10 12 10 70>; nand@0 { @@ -67,22 +67,22 @@ }; usb@c5004000 { - nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ + nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) 0>; }; sdhci@c8000200 { status = "okay"; - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 155 0>; /* gpio PT3 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; sdhci@c8000600 { status = "okay"; - cd-gpios = <&gpio 58 1>; /* gpio PH2 */ - wp-gpios = <&gpio 59 0>; /* gpio PH3 */ - power-gpios = <&gpio 70 0>; /* gpio PI6 */ + cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>; bus-width = <8>; }; @@ -100,10 +100,14 @@ vsyncx-active-high; nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 0 0>; - nvidia,backlight-enable-gpios = <&gpio 13 0>; /* PB5 */ - nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,panel-vdd-gpios = <&gpio 22 0>; /* PC6 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; + nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <0 0 200 0 0>; }; }; diff --git a/arch/arm/dts/tegra20-medcom-wide.dts b/arch/arm/dts/tegra20-medcom-wide.dts index be2ed42dbd..b6b57abdef 100644 --- a/arch/arm/dts/tegra20-medcom-wide.dts +++ b/arch/arm/dts/tegra20-medcom-wide.dts @@ -73,9 +73,12 @@ nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 0 500000>; - nvidia,backlight-enable-gpios = <&gpio 13 0>; /* PB5 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <0 0 0 0>; }; }; diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts index 9d735b5e6b..16381c3a4c 100644 --- a/arch/arm/dts/tegra20-paz00.dts +++ b/arch/arm/dts/tegra20-paz00.dts @@ -61,9 +61,9 @@ sdhci@c8000000 { status = "okay"; - cd-gpios = <&gpio 173 1>; /* gpio PV5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 169 0>; /* gpio PV1 */ + cd-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -86,10 +86,14 @@ hsync-active-high; nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 0 0>; - nvidia,backlight-enable-gpios = <&gpio 164 0>; /* PU4 */ - nvidia,lvds-shutdown-gpios = <&gpio 102 0>; /* PM6 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,panel-vdd-gpios = <&gpio 4 0>; /* PA4 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(U, 4) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(M, 6) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; + nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(A, 4) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <400 4 203 17 15>; }; }; diff --git a/arch/arm/dts/tegra20-seaboard.dts b/arch/arm/dts/tegra20-seaboard.dts index 43b9911c89..10f399284a 100644 --- a/arch/arm/dts/tegra20-seaboard.dts +++ b/arch/arm/dts/tegra20-seaboard.dts @@ -65,7 +65,7 @@ }; nand-controller@70008000 { - nvidia,wp-gpios = <&gpio 59 0>; /* PH3 */ + nvidia,wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; nvidia,width = <8>; nvidia,timing = <26 100 20 80 20 10 12 10 70>; nand@0 { @@ -151,7 +151,7 @@ }; usb@c5000000 { - nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>; dr_mode = "otg"; }; @@ -161,9 +161,9 @@ sdhci@c8000400 { status = "okay"; - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 70 0>; /* gpio PI6 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -186,10 +186,14 @@ hsync-active-high; nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 2 0>; - nvidia,backlight-enable-gpios = <&gpio 28 0>; /* PD4 */ - nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,panel-vdd-gpios = <&gpio 22 0>; /* PC6 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(D, 4) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; + nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <400 4 203 17 15>; }; }; diff --git a/arch/arm/dts/tegra20-tamonten.dtsi b/arch/arm/dts/tegra20-tamonten.dtsi index f379622c94..78449e6133 100644 --- a/arch/arm/dts/tegra20-tamonten.dtsi +++ b/arch/arm/dts/tegra20-tamonten.dtsi @@ -14,7 +14,8 @@ pll-supply = <&hdmi_pll_reg>; nvidia,ddc-i2c-bus = <&hdmi_ddc>; - nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */ + nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) + GPIO_ACTIVE_HIGH>; }; }; @@ -280,7 +281,7 @@ }; nand-controller@70008000 { - nvidia,wp-gpios = <&gpio 23 0>; /* PC7 */ + nvidia,wp-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>; nvidia,width = <8>; nvidia,timing = <26 100 20 80 20 10 12 10 70>; @@ -476,8 +477,8 @@ }; sdhci@c8000600 { - cd-gpios = <&gpio 58 1>; /* gpio PH2 */ - wp-gpios = <&gpio 59 0>; /* gpio PH3 */ + cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; bus-width = <4>; status = "okay"; }; diff --git a/arch/arm/dts/tegra20-tec.dts b/arch/arm/dts/tegra20-tec.dts index e99bd447c1..94ba6dc2d4 100644 --- a/arch/arm/dts/tegra20-tec.dts +++ b/arch/arm/dts/tegra20-tec.dts @@ -73,9 +73,12 @@ nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 0 500000>; - nvidia,backlight-enable-gpios = <&gpio 13 0>; /* PB5 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <0 0 0 0>; }; }; diff --git a/arch/arm/dts/tegra20-trimslice.dts b/arch/arm/dts/tegra20-trimslice.dts index 1637cbd58e..27b118f212 100644 --- a/arch/arm/dts/tegra20-trimslice.dts +++ b/arch/arm/dts/tegra20-trimslice.dts @@ -62,7 +62,7 @@ }; usb@c5000000 { - nvidia,vbus-gpio = <&gpio 170 0>; /* PV2 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; }; usb@c5004000 { @@ -76,8 +76,8 @@ sdhci@c8000600 { status = "okay"; - cd-gpios = <&gpio 121 1>; /* gpio PP1 */ - wp-gpios = <&gpio 122 0>; /* gpio PP2 */ + cd-gpios = <&gpio TEGRA_GPIO(P, 1) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -111,7 +111,7 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - gpio = <&gpio TEGRA_GPIO(V, 2) 0>; + gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; regulator-always-on; regulator-boot-on; }; diff --git a/arch/arm/dts/tegra20-ventana.dts b/arch/arm/dts/tegra20-ventana.dts index 6812203918..939e567d13 100644 --- a/arch/arm/dts/tegra20-ventana.dts +++ b/arch/arm/dts/tegra20-ventana.dts @@ -61,9 +61,9 @@ sdhci@c8000400 { status = "okay"; - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 70 0>; /* gpio PI6 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -86,10 +86,14 @@ vsync-active-high; nvidia,bits-per-pixel = <16>; nvidia,pwm = <&pwm 2 0>; - nvidia,backlight-enable-gpios = <&gpio 28 0>; /* PD4 */ - nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */ - nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */ - nvidia,panel-vdd-gpios = <&gpio 22 0>; /* PC6 */ + nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(D, 4) + GPIO_ACTIVE_HIGH>; + nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2) + GPIO_ACTIVE_HIGH>; + nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0) + GPIO_ACTIVE_HIGH>; + nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6) + GPIO_ACTIVE_HIGH>; nvidia,panel-timings = <0 0 200 0 0>; }; }; diff --git a/arch/arm/dts/tegra20-whistler.dts b/arch/arm/dts/tegra20-whistler.dts index 4fd2496dbc..c4a28eb427 100644 --- a/arch/arm/dts/tegra20-whistler.dts +++ b/arch/arm/dts/tegra20-whistler.dts @@ -66,7 +66,7 @@ sdhci@c8000400 { status = "okay"; - wp-gpios = <&gpio 173 0>; /* gpio PV5 */ + wp-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_HIGH>; bus-width = <8>; }; diff --git a/arch/arm/dts/tegra30-apalis.dts b/arch/arm/dts/tegra30-apalis.dts index 5bad3e7769..15db0f275b 100644 --- a/arch/arm/dts/tegra30-apalis.dts +++ b/arch/arm/dts/tegra30-apalis.dts @@ -243,13 +243,13 @@ sdhci@78000000 { status = "okay"; bus-width = <4>; - cd-gpios = <&gpio 229 1>; /* PCC5, SD1_CD# */ + cd-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_HIGH>; }; sdhci@78000400 { status = "okay"; bus-width = <8>; - cd-gpios = <&gpio 171 1>; /* PV3, MMC1_CD# */ + cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; }; sdhci@78000600 { @@ -262,20 +262,20 @@ usb@7d000000 { status = "okay"; dr_mode = "peripheral"; - nvidia,vbus-gpio = <&gpio 157 0>; /* PT5, USBO1_EN */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>; }; /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */ usb@7d004000 { status = "okay"; - nvidia,vbus-gpio = <&gpio 233 0>; /* PDD1, USBH_EN */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>; phy_type = "utmi"; }; /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */ usb@7d008000 { status = "okay"; - nvidia,vbus-gpio = <&gpio 233 0>; /* PDD1, USBH_EN */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>; }; regulators { diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts index 5903af6838..ae836363ab 100644 --- a/arch/arm/dts/tegra30-beaver.dts +++ b/arch/arm/dts/tegra30-beaver.dts @@ -196,9 +196,9 @@ sdhci@78000000 { status = "okay"; - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 155 0>; /* gpio PT3 */ - power-gpios = <&gpio 31 0>; /* gpio PD7 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -210,11 +210,11 @@ usb@7d000000 { status = "okay"; dr_mode = "otg"; - nvidia,vbus-gpio = <&gpio 238 0>; /* gpio DD6, PEX_L1_CLKREQ */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>; }; usb@7d008000 { - nvidia,vbus-gpio = <&gpio 236 0>; /* PDD4 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/dts/tegra30-cardhu.dts b/arch/arm/dts/tegra30-cardhu.dts index e13d0fb467..23ca141df2 100644 --- a/arch/arm/dts/tegra30-cardhu.dts +++ b/arch/arm/dts/tegra30-cardhu.dts @@ -185,9 +185,9 @@ sdhci@78000000 { status = "okay"; - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 155 0>; /* gpio PT3 */ - power-gpios = <&gpio 31 0>; /* gpio PD7 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; @@ -197,7 +197,7 @@ }; usb@7d008000 { - nvidia,vbus-gpio = <&gpio 236 0>; /* PDD4 */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/dts/tegra30-colibri.dts b/arch/arm/dts/tegra30-colibri.dts index 37b6abd52f..6cd1902f11 100644 --- a/arch/arm/dts/tegra30-colibri.dts +++ b/arch/arm/dts/tegra30-colibri.dts @@ -64,7 +64,7 @@ sdhci@78000200 { status = "okay"; bus-width = <4>; - cd-gpios = <&gpio 23 1>; /* PC7, MMCD */ + cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; }; sdhci@78000600 { @@ -83,12 +83,12 @@ usb@7d004000 { status = "okay"; phy_type = "utmi"; - nvidia,vbus-gpio = <&gpio 234 0>; /* PDD2, VBUS_LAN */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>; }; /* EHCI instance 2: USB3_DP/N -> USBH_P/N */ usb@7d008000 { status = "okay"; - nvidia,vbus-gpio = <&gpio 178 1>; /* PW2, USBH_PEN */ + nvidia,vbus-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/dts/tegra30-tamonten.dtsi b/arch/arm/dts/tegra30-tamonten.dtsi index c73afef34a..8eff627f3d 100644 --- a/arch/arm/dts/tegra30-tamonten.dtsi +++ b/arch/arm/dts/tegra30-tamonten.dtsi @@ -55,8 +55,8 @@ /* SD slot on the base board */ sdhci@78000400 { - cd-gpios = <&gpio 69 1>; /* gpio PI5 */ - wp-gpios = <&gpio 67 0>; /* gpio PI3 */ + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(I, 3) GPIO_ACTIVE_HIGH>; bus-width = <4>; }; -- cgit From 6f755eb66bbbdf1186b3aaae245ac9fc255def46 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:42 -0700 Subject: dm: exynos: dts: Use GPIO bank phandles for GPIOs U-Boot now supports using GPIOs using bank phandles instead of global numbers. Update the exynos device tree files to use this. Signed-off-by: Simon Glass Acked-by: Minkyu Kang --- arch/arm/dts/exynos4.dtsi | 7 ------- arch/arm/dts/exynos4210-origen.dts | 2 +- arch/arm/dts/exynos4210-trats.dts | 4 ++-- arch/arm/dts/exynos4210-universal_c210.dts | 12 ++++++------ arch/arm/dts/exynos4412-odroid.dts | 2 +- arch/arm/dts/exynos4412-trats2.dts | 6 +++--- arch/arm/dts/exynos5.dtsi | 4 +--- arch/arm/dts/exynos5250-smdk5250.dts | 2 +- arch/arm/dts/exynos5250-snow.dts | 10 +++++----- arch/arm/dts/exynos5420-peach-pit.dts | 8 ++++---- arch/arm/dts/exynos5422-odroidxu3.dts | 2 +- arch/arm/dts/exynos5800-peach-pi.dts | 10 +++++----- 12 files changed, 30 insertions(+), 39 deletions(-) diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi index 77fad48fb4..3c983edeb2 100644 --- a/arch/arm/dts/exynos4.dtsi +++ b/arch/arm/dts/exynos4.dtsi @@ -143,11 +143,4 @@ interrupts = <0 131 0>; }; - gpio: gpio { - gpio-controller; - #gpio-cells = <2>; - - interrupt-controller; - #interrupt-cells = <2>; - }; }; diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts index dd2476c1a3..3f87761584 100644 --- a/arch/arm/dts/exynos4210-origen.dts +++ b/arch/arm/dts/exynos4210-origen.dts @@ -36,7 +36,7 @@ sdhci@12530000 { samsung,bus-width = <4>; samsung,timing = <1 2 3>; - cd-gpios = <&gpio 0xA2 0>; + cd-gpios = <&gpk2 2 0>; }; sdhci@12540000 { diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts index 8c7a2c3a78..36d02df3b0 100644 --- a/arch/arm/dts/exynos4210-trats.dts +++ b/arch/arm/dts/exynos4210-trats.dts @@ -101,7 +101,7 @@ sdhci@12510000 { samsung,bus-width = <8>; samsung,timing = <1 3 3>; - pwr-gpios = <&gpio 146 0>; + pwr-gpios = <&gpk0 2 0>; }; sdhci@12520000 { @@ -111,7 +111,7 @@ sdhci@12530000 { samsung,bus-width = <4>; samsung,timing = <1 2 3>; - cd-gpios = <&gpio 284 0>; + cd-gpios = <&gpx3 4 0>; }; sdhci@12540000 { diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts index 808c3f7cc3..16948c9342 100644 --- a/arch/arm/dts/exynos4210-universal_c210.dts +++ b/arch/arm/dts/exynos4210-universal_c210.dts @@ -24,7 +24,7 @@ sdhci@12510000 { samsung,bus-width = <8>; samsung,timing = <1 3 3>; - pwr-gpios = <&gpio 146 0>; + pwr-gpios = <&gpk0 2 0>; }; sdhci@12520000 { @@ -34,7 +34,7 @@ sdhci@12530000 { samsung,bus-width = <4>; samsung,timing = <1 2 3>; - cd-gpios = <&gpio 284 0>; + cd-gpios = <&gpx3 4 0>; }; sdhci@12540000 { @@ -43,10 +43,10 @@ soft-spi { compatible = "u-boot,soft-spi"; - cs-gpio = <&gpio 235 0>; /* Y43 */ - sclk-gpio = <&gpio 225 0>; /* Y31 */ - mosi-gpio = <&gpio 227 0>; /* Y33 */ - miso-gpio = <&gpio 224 0>; /* Y30 */ + cs-gpio = <&gpy4 3 0>; + sclk-gpio = <&gpy3 1 0>; + mosi-gpio = <&gpy3 3 0>; + miso-gpio = <&gpy3 0 0>; spi-delay-us = <1>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index c78efec649..29ad6ab20f 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -51,7 +51,7 @@ sdhci@12530000 { samsung,bus-width = <4>; samsung,timing = <1 2 3>; - cd-gpios = <&gpio 122 0>; + cd-gpios = <&gpk2 2 0>; }; sdhci@12540000 { diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts index 60e4515a7e..dd238df13f 100644 --- a/arch/arm/dts/exynos4412-trats2.dts +++ b/arch/arm/dts/exynos4412-trats2.dts @@ -416,7 +416,7 @@ sdhci@12510000 { samsung,bus-width = <8>; samsung,timing = <1 3 3>; - pwr-gpios = <&gpio 0x6a 0>; + pwr-gpios = <&gpk0 4 0>; status = "disabled"; }; @@ -427,7 +427,7 @@ sdhci@12530000 { samsung,bus-width = <4>; samsung,timing = <1 2 3>; - cd-gpios = <&gpio 0x7a 0>; + cd-gpios = <&gpk2 2 0>; }; sdhci@12540000 { @@ -437,7 +437,7 @@ dwmmc@12550000 { samsung,bus-width = <8>; samsung,timing = <2 1 0>; - pwr-gpios = <&gpio 0x6a 0>; + pwr-gpios = <&gpk0 4 0>; fifoth_val = <0x203f0040>; bus_hz = <400000000>; div = <0x3>; diff --git a/arch/arm/dts/exynos5.dtsi b/arch/arm/dts/exynos5.dtsi index e53906892c..238acb80a2 100644 --- a/arch/arm/dts/exynos5.dtsi +++ b/arch/arm/dts/exynos5.dtsi @@ -6,6 +6,7 @@ */ #include "skeleton.dtsi" +#include / { compatible = "samsung,exynos5"; @@ -247,7 +248,4 @@ u-boot,dm-pre-reloc; id = <3>; }; - - gpio: gpio { - }; }; diff --git a/arch/arm/dts/exynos5250-smdk5250.dts b/arch/arm/dts/exynos5250-smdk5250.dts index 885040920c..9273562bc5 100644 --- a/arch/arm/dts/exynos5250-smdk5250.dts +++ b/arch/arm/dts/exynos5250-smdk5250.dts @@ -146,6 +146,6 @@ }; ehci@12110000 { - samsung,vbus-gpio = <&gpio 0x316 0>; /* X26 */ + samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index bac501516f..649e4bd0d2 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -44,7 +44,7 @@ reg = <0x1e>; compatible = "google,cros-ec"; i2c-max-frequency = <100000>; - ec-interrupt = <&gpio 182 1>; + ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; }; power-regulator@48 { @@ -68,7 +68,7 @@ reg = <0>; compatible = "google,cros-ec"; spi-max-frequency = <5000000>; - ec-interrupt = <&gpio 182 1>; + ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; optimise-flash-write; status = "disabled"; }; @@ -76,7 +76,7 @@ sound@3830000 { samsung,codec-type = "max98095"; - codec-enable-gpio = <&gpio 0xb7 0>; + codec-enable-gpio = <&gpx1 7 GPIO_ACTIVE_HIGH>; }; sound@12d60000 { @@ -131,11 +131,11 @@ }; ehci@12110000 { - samsung,vbus-gpio = <&gpio 0xb1 0>; /* X11 */ + samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>; }; xhci@12000000 { - samsung,vbus-gpio = <&gpio 0xbf 0>; /* X27 */ + samsung,vbus-gpio = <&gpx2 7 GPIO_ACTIVE_HIGH>; }; tmu@10060000 { diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts index d1d87350be..b801de9787 100644 --- a/arch/arm/dts/exynos5420-peach-pit.dts +++ b/arch/arm/dts/exynos5420-peach-pit.dts @@ -17,7 +17,7 @@ "google,peach", "samsung,exynos5420", "samsung,exynos5"; config { - google,bad-wake-gpios = <&gpio 0x56 0>; /* gpx0-6 */ + google,bad-wake-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>; hwid = "PIT TEST A-A 7848"; lazy-init = <1>; }; @@ -108,7 +108,7 @@ spi-half-duplex; spi-max-timeout-ms = <1100>; spi-frame-header = <0xec>; - ec-interrupt = <&gpio 93 1>; /* GPX1_5 */ + ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>; /* * This describes the flash memory within the EC. Note @@ -124,11 +124,11 @@ }; xhci@12000000 { - samsung,vbus-gpio = <&gpio 0x40 0>; /* H00 */ + samsung,vbus-gpio = <&gph0 0 GPIO_ACTIVE_HIGH>; }; xhci@12400000 { - samsung,vbus-gpio = <&gpio 0x41 0>; /* H01 */ + samsung,vbus-gpio = <&gph0 1 GPIO_ACTIVE_HIGH>; }; fimd@14400000 { diff --git a/arch/arm/dts/exynos5422-odroidxu3.dts b/arch/arm/dts/exynos5422-odroidxu3.dts index 79a7acd7df..8f4663733c 100644 --- a/arch/arm/dts/exynos5422-odroidxu3.dts +++ b/arch/arm/dts/exynos5422-odroidxu3.dts @@ -32,7 +32,7 @@ }; ehci@12110000 { - samsung,vbus-gpio = <&gpio 0x66 0>; /* X26 */ + samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; }; serial@12C20000 { diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts index e7c380f83b..e4bc100995 100644 --- a/arch/arm/dts/exynos5800-peach-pi.dts +++ b/arch/arm/dts/exynos5800-peach-pi.dts @@ -17,7 +17,7 @@ "google,peach", "samsung,exynos5800", "samsung,exynos5"; config { - google,bad-wake-gpios = <&gpio 0x56 0>; /* gpx0-6 */ + google,bad-wake-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>; hwid = "PIT TEST A-A 7848"; lazy-init = <1>; }; @@ -32,7 +32,7 @@ mem-manuf = "samsung"; mem-type = "ddr3"; clock-frequency = <800000000>; - arm-frequency = <1700000000>; + arm-frequency = <900000000>; }; tmu@10060000 { @@ -102,7 +102,7 @@ spi-half-duplex; spi-max-timeout-ms = <1100>; spi-frame-header = <0xec>; - ec-interrupt = <&gpio 93 1>; /* GPX1_5 */ + ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>; /* * This describes the flash memory within the EC. Note @@ -118,11 +118,11 @@ }; xhci@12000000 { - samsung,vbus-gpio = <&gpio 0x40 0>; /* H00 */ + samsung,vbus-gpio = <&gph0 0 GPIO_ACTIVE_HIGH>; }; xhci@12400000 { - samsung,vbus-gpio = <&gpio 0x41 0>; /* H01 */ + samsung,vbus-gpio = <&gph0 1 GPIO_ACTIVE_HIGH>; }; fimd@14400000 { -- cgit From 009067c3b756de0f94f4a0d03718873614e756f1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 5 Jan 2015 20:05:43 -0700 Subject: dm: fdt: Remove the old GPIO functions Now that we support device tree GPIO bindings directly in the driver model GPIO uclass we can remove these functions. Signed-off-by: Simon Glass --- include/fdtdec.h | 77 --------------------------------------------- lib/fdtdec.c | 95 -------------------------------------------------------- 2 files changed, 172 deletions(-) diff --git a/include/fdtdec.h b/include/fdtdec.h index 8cf88dd10b..b02f1edb1d 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -231,39 +231,6 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node, int cell_count, int index, struct fdtdec_phandle_args *out_args); -/* GPIOs are numbered from 0 */ -enum { - FDT_GPIO_NONE = -1U, /* an invalid GPIO used to end our list */ - - FDT_GPIO_ACTIVE_LOW = 1 << 0, /* input is active low (else high) */ -}; - -/* This is the state of a GPIO pin as defined by the fdt */ -struct fdt_gpio_state { - const char *name; /* name of the fdt property defining this */ - uint gpio; /* GPIO number, or FDT_GPIO_NONE if none */ - u8 flags; /* FDT_GPIO_... flags */ -}; - -/* This tells us whether a fdt_gpio_state record is valid or not */ -#define fdt_gpio_isvalid(x) ((x)->gpio != FDT_GPIO_NONE) - -/** - * Read the GPIO taking into account the polarity of the pin. - * - * @param gpio pointer to the decoded gpio - * @return value of the gpio if successful, < 0 if unsuccessful - */ -int fdtdec_get_gpio(struct fdt_gpio_state *gpio); - -/** - * Write the GPIO taking into account the polarity of the pin. - * - * @param gpio pointer to the decoded gpio - * @return 0 if successful - */ -int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val); - /** * Find the next numbered alias for a peripheral. This is used to enumerate * all the peripherals of a certain type. @@ -644,50 +611,6 @@ const u32 *fdtdec_locate_array(const void *blob, int node, */ int fdtdec_get_bool(const void *blob, int node, const char *prop_name); -/** - * Decode a single GPIOs from an FDT. - * - * If the property is not found, then the GPIO structure will still be - * initialised, with gpio set to FDT_GPIO_NONE. This makes it easy to - * provide optional GPIOs. - * - * @param blob FDT blob to use - * @param node Node to look at - * @param prop_name Node property name - * @param gpio gpio elements to fill from FDT - * @return 0 if ok, -FDT_ERR_NOTFOUND if the property is missing. - */ -int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name, - struct fdt_gpio_state *gpio); - -/** - * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no - * terminating item. - * - * @param blob FDT blob to use - * @param node Node to look at - * @param prop_name Node property name - * @param gpio Array of gpio elements to fill from FDT. This will be - * untouched if either 0 or an error is returned - * @param max_count Maximum number of elements allowed - * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would - * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing. - */ -int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name, - struct fdt_gpio_state *gpio, int max_count); - -/** - * Set up a GPIO pin according to the provided gpio information. At present this - * just requests the GPIO. - * - * If the gpio is FDT_GPIO_NONE, no action is taken. This makes it easy to - * deal with optional GPIOs. - * - * @param gpio GPIO info to use for set up - * @return 0 if all ok or gpio was FDT_GPIO_NONE; -1 on error - */ -int fdtdec_setup_gpio(struct fdt_gpio_state *gpio); - /** * Look in the FDT for a config item with the given name and return its value * as a 32-bit integer. The property must have at least 4 bytes of data. The diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 57e0edca99..623c5fcd6d 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -803,101 +803,6 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node, return rc; } -/** - * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no - * terminating item. - * - * @param blob FDT blob to use - * @param node Node to look at - * @param prop_name Node property name - * @param gpio Array of gpio elements to fill from FDT. This will be - * untouched if either 0 or an error is returned - * @param max_count Maximum number of elements allowed - * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would - * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing. - */ -int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name, - struct fdt_gpio_state *gpio, int max_count) -{ - const struct fdt_property *prop; - const u32 *cell; - const char *name; - int len, i; - - debug("%s: %s\n", __func__, prop_name); - assert(max_count > 0); - prop = fdt_get_property(blob, node, prop_name, &len); - if (!prop) { - debug("%s: property '%s' missing\n", __func__, prop_name); - return -FDT_ERR_NOTFOUND; - } - - /* We will use the name to tag the GPIO */ - name = fdt_string(blob, fdt32_to_cpu(prop->nameoff)); - cell = (u32 *)prop->data; - len /= sizeof(u32) * 3; /* 3 cells per GPIO record */ - if (len > max_count) { - debug(" %s: too many GPIOs / cells for " - "property '%s'\n", __func__, prop_name); - return -FDT_ERR_BADLAYOUT; - } - - /* Read out the GPIO data from the cells */ - for (i = 0; i < len; i++, cell += 3) { - gpio[i].gpio = fdt32_to_cpu(cell[1]); - gpio[i].flags = fdt32_to_cpu(cell[2]); - gpio[i].name = name; - } - - return len; -} - -int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name, - struct fdt_gpio_state *gpio) -{ - int err; - - debug("%s: %s\n", __func__, prop_name); - gpio->gpio = FDT_GPIO_NONE; - gpio->name = NULL; - err = fdtdec_decode_gpios(blob, node, prop_name, gpio, 1); - return err == 1 ? 0 : err; -} - -int fdtdec_get_gpio(struct fdt_gpio_state *gpio) -{ - int val; - - if (!fdt_gpio_isvalid(gpio)) - return -1; - - val = gpio_get_value(gpio->gpio); - return gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val; -} - -int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val) -{ - if (!fdt_gpio_isvalid(gpio)) - return -1; - - val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val; - return gpio_set_value(gpio->gpio, val); -} - -int fdtdec_setup_gpio(struct fdt_gpio_state *gpio) -{ - /* - * Return success if there is no GPIO defined. This is used for - * optional GPIOs) - */ - if (!fdt_gpio_isvalid(gpio)) - return 0; - - if (gpio_request(gpio->gpio, gpio->name)) - return -1; - return 0; -} - int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, u8 *array, int count) { -- cgit From a08d643dbd855df837724a582babc55e82bd03b7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 15 Jan 2015 09:19:36 -0700 Subject: dm: Drop gpio.h header from fdtdec.c Since GPIO support has now moved to the driver model uclass, we can drop this include. Signed-off-by: Simon Glass --- lib/fdtdec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 623c5fcd6d..3cfa50a6d5 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -11,8 +11,6 @@ #include #include -#include - DECLARE_GLOBAL_DATA_PTR; /* -- cgit From f9a4c2da72d04e13b05deecb800f232d2948eb85 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 12 Jan 2015 18:02:07 -0700 Subject: dm: i2c: Rename driver model I2C functions to permit compatibility Add a dm_ prefix to driver model I2C functions so that we can keep the old ones around. This is a little unfortunate, but on reflection it is too difficult to change the API. We can undo this rename when most boards and drivers are converted to use driver model for I2C. Signed-off-by: Simon Glass --- board/avionic-design/common/tamonten-ng.c | 2 +- board/nvidia/cardhu/cardhu.c | 8 ++--- board/nvidia/dalmore/dalmore.c | 6 ++-- board/nvidia/whistler/whistler.c | 10 +++--- board/toradex/apalis_t30/apalis_t30.c | 6 ++-- common/cmd_i2c.c | 28 ++++++++------- common/exports.c | 3 +- drivers/i2c/i2c-uclass.c | 9 ++--- drivers/power/as3722.c | 4 +-- drivers/power/tps6586x.c | 4 +-- include/i2c.h | 19 +++++----- test/dm/i2c.c | 60 +++++++++++++++---------------- 12 files changed, 82 insertions(+), 77 deletions(-) diff --git a/board/avionic-design/common/tamonten-ng.c b/board/avionic-design/common/tamonten-ng.c index 86a0844273..bca91831e0 100644 --- a/board/avionic-design/common/tamonten-ng.c +++ b/board/avionic-design/common/tamonten-ng.c @@ -60,7 +60,7 @@ void pmu_write(uchar reg, uchar data) debug("%s: Cannot find PMIC I2C chip\n", __func__); return; } - i2c_write(dev, reg, &data, 1); + dm_i2c_write(dev, reg, &data, 1); } /* diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c index 95c4ff2509..fc31d29140 100644 --- a/board/nvidia/cardhu/cardhu.c +++ b/board/nvidia/cardhu/cardhu.c @@ -57,7 +57,7 @@ void board_sdmmc_voltage_init(void) reg = 0x32; for (i = 0; i < MAX_I2C_RETRY; ++i) { - if (i2c_write(dev, reg, data_buffer, 1)) + if (dm_i2c_write(dev, reg, data_buffer, 1)) udelay(100); } @@ -66,7 +66,7 @@ void board_sdmmc_voltage_init(void) reg = 0x67; for (i = 0; i < MAX_I2C_RETRY; ++i) { - if (i2c_write(dev, reg, data_buffer, 1)) + if (dm_i2c_write(dev, reg, data_buffer, 1)) udelay(100); } } @@ -104,7 +104,7 @@ int tegra_pcie_board_init(void) data[0] = 0x15; addr = 0x30; - err = i2c_write(dev, addr, data, 1); + err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set VDD supply\n"); return err; @@ -121,7 +121,7 @@ int tegra_pcie_board_init(void) data[0] = 0x15; addr = 0x31; - err = i2c_write(dev, addr, data, 1); + err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set AVDD supply\n"); return err; diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c index 2a737468dd..c0991c57a9 100644 --- a/board/nvidia/dalmore/dalmore.c +++ b/board/nvidia/dalmore/dalmore.c @@ -65,7 +65,7 @@ void board_sdmmc_voltage_init(void) data_buffer[0] = 0x31; reg = 0x61; - ret = i2c_write(dev, reg, data_buffer, 1); + ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: PMU i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); @@ -74,7 +74,7 @@ void board_sdmmc_voltage_init(void) data_buffer[0] = 0x01; reg = 0x60; - ret = i2c_write(dev, reg, data_buffer, 1); + ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: PMU i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); @@ -88,7 +88,7 @@ void board_sdmmc_voltage_init(void) debug("%s: Cannot find charger I2C chip\n", __func__); return; } - ret = i2c_write(dev, reg, data_buffer, 1); + ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: BAT i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); diff --git a/board/nvidia/whistler/whistler.c b/board/nvidia/whistler/whistler.c index 3114b20be0..ad6ea091df 100644 --- a/board/nvidia/whistler/whistler.c +++ b/board/nvidia/whistler/whistler.c @@ -33,15 +33,15 @@ void pin_mux_mmc(void) return; } val = 0x29; - ret = i2c_write(dev, 0x46, &val, 1); + ret = dm_i2c_write(dev, 0x46, &val, 1); if (ret) printf("i2c_write 0 0x3c 0x46 failed: %d\n", ret); val = 0x00; - ret = i2c_write(dev, 0x45, &val, 1); + ret = dm_i2c_write(dev, 0x45, &val, 1); if (ret) printf("i2c_write 0 0x3c 0x45 failed: %d\n", ret); val = 0x1f; - ret = i2c_write(dev, 0x44, &val, 1); + ret = dm_i2c_write(dev, 0x44, &val, 1); if (ret) printf("i2c_write 0 0x3c 0x44 failed: %d\n", ret); @@ -70,11 +70,11 @@ void pin_mux_usb(void) return; } val = 0x03; - ret = i2c_write(dev, 2, &val, 1); + ret = dm_i2c_write(dev, 2, &val, 1); if (ret) printf("i2c_write 0 0x20 2 failed: %d\n", ret); val = 0xfc; - ret = i2c_write(dev, 6, &val, 1); + ret = dm_i2c_write(dev, 6, &val, 1); if (ret) printf("i2c_write 0 0x20 6 failed: %d\n", ret); } diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c index 5d2c024e89..1c4b4c1cd4 100644 --- a/board/toradex/apalis_t30/apalis_t30.c +++ b/board/toradex/apalis_t30/apalis_t30.c @@ -51,7 +51,7 @@ int tegra_pcie_board_init(void) data[0] = 0x27; addr = 0x25; - err = i2c_write(dev, addr, data, 1); + err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set VDD supply\n"); return err; @@ -61,7 +61,7 @@ int tegra_pcie_board_init(void) data[0] = 0x0D; addr = 0x24; - err = i2c_write(dev, addr, data, 1); + err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to enable VDD supply\n"); return err; @@ -71,7 +71,7 @@ int tegra_pcie_board_init(void) data[0] = 0x0D; addr = 0x35; - err = i2c_write(dev, addr, data, 1); + err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set AVDD supply\n"); return err; diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index f65ab616b0..1e500fbf2c 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -133,7 +133,7 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; #ifdef CONFIG_DM_I2C static struct udevice *i2c_cur_bus; -static int i2c_set_bus_num(unsigned int busnum) +static int cmd_i2c_set_bus_num(unsigned int busnum) { struct udevice *bus; int ret; @@ -323,7 +323,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv if (!ret && alen != -1) ret = i2c_set_chip_offset_len(dev, alen); if (!ret) - ret = i2c_read(dev, devaddr, memaddr, length); + ret = dm_i2c_read(dev, devaddr, memaddr, length); #else ret = i2c_read(chip, devaddr, alen, memaddr, length); #endif @@ -381,7 +381,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ while (length-- > 0) { #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, devaddr++, memaddr++, 1); + ret = dm_i2c_write(dev, devaddr++, memaddr++, 1); #else ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); #endif @@ -513,7 +513,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, linebuf, linebytes); + ret = dm_i2c_read(dev, addr, linebuf, linebytes); #else ret = i2c_read(chip, addr, alen, linebuf, linebytes); #endif @@ -611,7 +611,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] while (count-- > 0) { #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, addr++, &byte, 1); + ret = dm_i2c_write(dev, addr++, &byte, 1); #else ret = i2c_write(chip, addr++, alen, &byte, 1); #endif @@ -698,7 +698,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] err = 0; while (count-- > 0) { #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, &byte, 1); + ret = dm_i2c_read(dev, addr, &byte, 1); #else ret = i2c_read(chip, addr, alen, &byte, 1); #endif @@ -793,7 +793,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg do { printf("%08lx:", addr); #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, (uchar *)&data, size); + ret = dm_i2c_read(dev, addr, (uchar *)&data, size); #else ret = i2c_read(chip, addr, alen, (uchar *)&data, size); #endif @@ -841,8 +841,8 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg */ bootretry_reset_cmd_timeout(); #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, addr, (uchar *)&data, - size); + ret = dm_i2c_write(dev, addr, (uchar *)&data, + size); #else ret = i2c_write(chip, addr, alen, (uchar *)&data, size); @@ -917,7 +917,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv continue; #endif #ifdef CONFIG_DM_I2C - ret = i2c_probe(bus, j, 0, &dev); + ret = dm_i2c_probe(bus, j, 0, &dev); #else ret = i2c_probe(j); #endif @@ -1010,7 +1010,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ while (1) { #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, bytes, length); + ret = dm_i2c_read(dev, addr, bytes, length); #else ret = i2c_read(chip, addr, alen, bytes, length); #endif @@ -1579,7 +1579,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) #ifdef CONFIG_DM_I2C ret = i2c_get_cur_bus_chip(chip, &dev); if (!ret) - ret = i2c_read(dev, 0, (uchar *)&edid, sizeof(edid)); + ret = dm_i2c_read(dev, 0, (uchar *)&edid, sizeof(edid)); #else ret = i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)); #endif @@ -1696,7 +1696,11 @@ static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, } #endif printf("Setting bus to %d\n", bus_no); +#ifdef CONFIG_DM_I2C + ret = cmd_i2c_set_bus_num(bus_no); +#else ret = i2c_set_bus_num(bus_no); +#endif if (ret) printf("Failure changing bus number (%d)\n", ret); } diff --git a/common/exports.c b/common/exports.c index 88fcfc8cb6..459e18cb09 100644 --- a/common/exports.c +++ b/common/exports.c @@ -23,7 +23,8 @@ unsigned long get_version(void) # define install_hdlr irq_install_handler # define free_hdlr irq_free_handler #endif -#ifndef CONFIG_CMD_I2C +#if !defined(CONFIG_CMD_I2C) || \ + (defined(CONFIG_DM_I2C) && !defined(CONFIG_DM_I2C_COMPAT)) # define i2c_write dummy # define i2c_read dummy #endif diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 005bf8662f..25f2c18cf4 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -100,7 +100,7 @@ static int i2c_write_bytewise(struct udevice *dev, uint offset, return 0; } -int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) +int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) { struct dm_i2c_chip *chip = dev_get_parentdata(dev); struct udevice *bus = dev_get_parent(dev); @@ -130,7 +130,8 @@ int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) return ops->xfer(bus, msg, msg_count); } -int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len) +int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, + int len) { struct dm_i2c_chip *chip = dev_get_parentdata(dev); struct udevice *bus = dev_get_parent(dev); @@ -303,8 +304,8 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp) return 0; } -int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, - struct udevice **devp) +int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, + struct udevice **devp) { int ret; diff --git a/drivers/power/as3722.c b/drivers/power/as3722.c index 4c6de79cd6..3aafdc9670 100644 --- a/drivers/power/as3722.c +++ b/drivers/power/as3722.c @@ -31,7 +31,7 @@ static int as3722_read(struct udevice *pmic, u8 reg, u8 *value) { int err; - err = i2c_read(pmic, reg, value, 1); + err = dm_i2c_read(pmic, reg, value, 1); if (err < 0) return err; @@ -42,7 +42,7 @@ static int as3722_write(struct udevice *pmic, u8 reg, u8 value) { int err; - err = i2c_write(pmic, reg, &value, 1); + err = dm_i2c_write(pmic, reg, &value, 1); if (err < 0) return err; diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c index 29bab4cc00..865098386d 100644 --- a/drivers/power/tps6586x.c +++ b/drivers/power/tps6586x.c @@ -37,7 +37,7 @@ static int tps6586x_read(int reg) int retval = -1; for (i = 0; i < MAX_I2C_RETRY; ++i) { - if (!i2c_read(tps6586x_dev, reg, &data, 1)) { + if (!dm_i2c_read(tps6586x_dev, reg, &data, 1)) { retval = (int)data; goto exit; } @@ -60,7 +60,7 @@ static int tps6586x_write(int reg, uchar *data, uint len) int retval = -1; for (i = 0; i < MAX_I2C_RETRY; ++i) { - if (!i2c_write(tps6586x_dev, reg, data, len)) { + if (!dm_i2c_write(tps6586x_dev, reg, data, len)) { retval = 0; goto exit; } diff --git a/include/i2c.h b/include/i2c.h index 9c6a60cf9a..30d53c8a9d 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -75,7 +75,7 @@ struct dm_i2c_bus { }; /** - * i2c_read() - read bytes from an I2C chip + * dm_i2c_read() - read bytes from an I2C chip * * To obtain an I2C device (called a 'chip') given the I2C bus address you * can use i2c_get_chip(). To obtain a bus by bus number use @@ -91,13 +91,12 @@ struct dm_i2c_bus { * * @return 0 on success, -ve on failure */ -int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, - int len); +int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len); /** - * i2c_write() - write bytes to an I2C chip + * dm_i2c_write() - write bytes to an I2C chip * - * See notes for i2c_read() above. + * See notes for dm_i2c_read() above. * * @dev: Chip to write to * @offset: Offset within chip to start writing @@ -106,11 +105,11 @@ int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, * * @return 0 on success, -ve on failure */ -int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, - int len); +int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, + int len); /** - * i2c_probe() - probe a particular chip address + * dm_i2c_probe() - probe a particular chip address * * This can be useful to check for the existence of a chip on the bus. * It is typically implemented by writing the chip address to the bus @@ -122,8 +121,8 @@ int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, * @devp: Returns the device found, or NULL if none * @return 0 if a chip was found at that address, -ve if not */ -int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, - struct udevice **devp); +int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, + struct udevice **devp); /** * i2c_set_bus_speed() - set the speed of a bus diff --git a/test/dm/i2c.c b/test/dm/i2c.c index a53e28dbe5..4823b0c648 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -35,8 +35,8 @@ static int dm_test_i2c_find(struct dm_test_state *dms) * remove the emulation and the slave device. */ ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_probe(bus, chip, 0, &dev)); - ut_asserteq(-ENODEV, i2c_probe(bus, no_chip, 0, &dev)); + ut_assertok(dm_i2c_probe(bus, chip, 0, &dev)); + ut_asserteq(-ENODEV, dm_i2c_probe(bus, no_chip, 0, &dev)); ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus)); return 0; @@ -50,10 +50,10 @@ static int dm_test_i2c_read_write(struct dm_test_state *dms) ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(i2c_get_chip(bus, chip, &dev)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf))); - ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0AB\0", sizeof(buf))); return 0; @@ -68,11 +68,11 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(i2c_get_chip(bus, chip, &dev)); ut_assertok(i2c_set_bus_speed(bus, 100000)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(i2c_set_bus_speed(bus, 400000)); ut_asserteq(400000, i2c_get_bus_speed(bus)); - ut_assertok(i2c_read(dev, 0, buf, 5)); - ut_asserteq(-EINVAL, i2c_write(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); + ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5)); return 0; } @@ -86,7 +86,7 @@ static int dm_test_i2c_offset_len(struct dm_test_state *dms) ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(i2c_get_chip(bus, chip, &dev)); ut_assertok(i2c_set_chip_offset_len(dev, 1)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); /* This is not supported by the uclass */ ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5)); @@ -100,7 +100,7 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms) struct udevice *bus, *dev; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev)); + ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev)); return 0; } @@ -114,7 +114,7 @@ static int dm_test_i2c_bytewise(struct dm_test_state *dms) ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(i2c_get_chip(bus, chip, &dev)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf))); /* Tell the EEPROM to only read/write one register at a time */ @@ -123,34 +123,34 @@ static int dm_test_i2c_bytewise(struct dm_test_state *dms) sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE); /* Now we only get the first byte - the rest will be 0xff */ - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf))); /* If we do a separate transaction for each byte, it works */ ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf))); /* This will only write A */ ut_assertok(i2c_set_chip_flags(dev, 0)); - ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf))); /* Check that the B was ignored */ ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0A\0\0\0", sizeof(buf))); /* Now write it again with the new flags, it should work */ ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS)); - ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf))); ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS | DM_I2C_CHIP_RD_ADDRESS)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0AB\0\0", sizeof(buf))); /* Restore defaults */ @@ -170,42 +170,42 @@ static int dm_test_i2c_offset(struct dm_test_state *dms) ut_assertok(i2c_get_chip_for_busnum(busnum, chip, &dev)); /* Do a transfer so we can find the emulator */ - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom)); /* Offset length 0 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 0); ut_assertok(i2c_set_chip_offset_len(dev, 0)); - ut_assertok(i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf))); /* Offset length 1 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 1); ut_assertok(i2c_set_chip_offset_len(dev, 1)); - ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0, buf, 5)); + ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf))); /* Offset length 2 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(i2c_write(dev, 0x210, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0x210, buf, 5)); + ut_assertok(dm_i2c_write(dev, 0x210, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x210, buf, 5)); ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); /* Offset length 3 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(i2c_write(dev, 0x410, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0x410, buf, 5)); + ut_assertok(dm_i2c_write(dev, 0x410, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x410, buf, 5)); ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); /* Offset length 4 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(i2c_write(dev, 0x420, (uint8_t *)"AB", 2)); - ut_assertok(i2c_read(dev, 0x420, buf, 5)); + ut_assertok(dm_i2c_write(dev, 0x420, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x420, buf, 5)); ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); /* Restore defaults */ -- cgit From 73845350b6281a7afeeb279475e6eb613d7a89f9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 12 Jan 2015 18:02:08 -0700 Subject: dm: i2c: Add a compatbility layer For boards which use multiple I2C devices, or for SOCs which support multiple boards, we might want to convert these to driver model at different times. At present this is difficult because we need to either use CONFIG_DM_I2C for a board or not. Add a compatibility layer which implements the old API, thus allowing a board to move to driver model for I2C without requiring that everything it uses is moved in the same commit. Signed-off-by: Simon Glass --- Makefile | 7 +++ drivers/i2c/Makefile | 1 + drivers/i2c/i2c-uclass-compat.c | 98 +++++++++++++++++++++++++++++++++++++++++ include/i2c.h | 59 +++++++++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 drivers/i2c/i2c-uclass-compat.c diff --git a/Makefile b/Makefile index ea5ae8fac7..9b406c8447 100644 --- a/Makefile +++ b/Makefile @@ -776,6 +776,13 @@ ifneq ($(CONFIG_SYS_GENERIC_BOARD),y) @echo "See doc/README.generic-board for further information" @echo "====================================================" endif +ifeq ($(CONFIG_DM_I2C_COMPAT),y) + @echo "===================== WARNING ======================" + @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove" + @echo "(possibly in a subsequent patch in your series)" + @echo "before sending patches to the mailing list." + @echo "====================================================" +endif PHONY += dtbs dtbs dts/dt.dtb: checkdtc u-boot diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 0e4c9f466a..774bc94a4a 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-$(CONFIG_DM_I2C) += i2c-uclass.o +obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c new file mode 100644 index 0000000000..c29fc89e04 --- /dev/null +++ b/drivers/i2c/i2c-uclass-compat.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static int cur_busnum; + +static int i2c_compat_get_device(uint chip_addr, int alen, + struct udevice **devp) +{ + struct dm_i2c_chip *chip; + int ret; + + ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); + if (ret) + return ret; + chip = dev_get_parentdata(*devp); + if (chip->offset_len != alen) { + printf("Requested alen %d does not match chip offset_len %d\n", + alen, chip->offset_len); + return -EADDRNOTAVAIL; + } + + return 0; +} + +int i2c_probe(uint8_t chip_addr) +{ + struct udevice *bus, *dev; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, cur_busnum, &bus); + if (ret) { + debug("Cannot find I2C bus %d: err=%d\n", cur_busnum, ret); + return ret; + } + + if (!bus) + return -ENOENT; + + return dm_i2c_probe(bus, chip_addr, 0, &dev); +} + +int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len) +{ + struct udevice *dev; + int ret; + + ret = i2c_compat_get_device(chip_addr, alen, &dev); + if (ret) + return ret; + + return dm_i2c_read(dev, addr, buffer, len); +} + +int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len) +{ + struct udevice *dev; + int ret; + + ret = i2c_compat_get_device(chip_addr, alen, &dev); + if (ret) + return ret; + + return dm_i2c_write(dev, addr, buffer, len); +} + +int i2c_get_bus_num_fdt(int node) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus); + if (ret) + return ret; + + return bus->seq; +} + +unsigned int i2c_get_bus_num(void) +{ + return cur_busnum; +} + +int i2c_set_bus_num(unsigned int bus) +{ + cur_busnum = bus; + + return 0; +} diff --git a/include/i2c.h b/include/i2c.h index 30d53c8a9d..47529f4b28 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -184,6 +184,65 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len); */ int i2c_deblock(struct udevice *bus); +#ifdef CONFIG_DM_I2C_COMPAT +/** + * i2c_probe() - Compatibility function for driver model + * + * Calls dm_i2c_probe() on the current bus + */ +int i2c_probe(uint8_t chip_addr); + +/** + * i2c_read() - Compatibility function for driver model + * + * Calls dm_i2c_read() with the device corresponding to @chip_addr, and offset + * set to @addr. @alen must match the current setting for the device. + */ +int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len); + +/** + * i2c_write() - Compatibility function for driver model + * + * Calls dm_i2c_write() with the device corresponding to @chip_addr, and offset + * set to @addr. @alen must match the current setting for the device. + */ +int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len); + +/** + * i2c_get_bus_num_fdt() - Compatibility function for driver model + * + * @return the bus number associated with the given device tree node + */ +int i2c_get_bus_num_fdt(int node); + +/** + * i2c_get_bus_num() - Compatibility function for driver model + * + * @return the 'current' bus number + */ +unsigned int i2c_get_bus_num(void); + +/** + * i2c_set_bus_num(): Compatibility function for driver model + * + * Sets the 'current' bus + */ +int i2c_set_bus_num(unsigned int bus); + +static inline void I2C_SET_BUS(unsigned int bus) +{ + i2c_set_bus_num(bus); +} + +static inline unsigned int I2C_GET_BUS(void) +{ + return i2c_get_bus_num(); +} + +#endif + /* * Not all of these flags are implemented in the U-Boot API */ -- cgit From 25ab4b0303f2df5e6b94ed92e37875a7c98f4de3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:26:55 -0700 Subject: dm: i2c: Provide an offset length parameter where needed Rather than assuming that the chip offset length is 1, allow it to be provided. This allows chips that don't use the default offset length to be used (at present they are only supported by the command line 'i2c' command which sets the offset length explicitly). Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- arch/arm/cpu/tegra20-common/pmu.c | 2 +- board/avionic-design/common/tamonten-ng.c | 2 +- board/nvidia/cardhu/cardhu.c | 4 ++-- board/nvidia/dalmore/dalmore.c | 4 ++-- board/nvidia/whistler/whistler.c | 4 ++-- board/toradex/apalis_t30/apalis_t30.c | 2 +- common/cmd_i2c.c | 2 +- drivers/i2c/i2c-uclass.c | 16 +++++++++------- drivers/i2c/sandbox_i2c.c | 2 +- drivers/power/as3722.c | 2 +- include/i2c.h | 8 ++++++-- test/dm/i2c.c | 10 +++++----- 12 files changed, 32 insertions(+), 26 deletions(-) diff --git a/arch/arm/cpu/tegra20-common/pmu.c b/arch/arm/cpu/tegra20-common/pmu.c index 36a76a24d9..a774246a27 100644 --- a/arch/arm/cpu/tegra20-common/pmu.c +++ b/arch/arm/cpu/tegra20-common/pmu.c @@ -52,7 +52,7 @@ int pmu_set_nominal(void) debug("%s: Cannot find DVC I2C bus\n", __func__); return ret; } - ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, &dev); + ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find DVC I2C chip\n", __func__); return ret; diff --git a/board/avionic-design/common/tamonten-ng.c b/board/avionic-design/common/tamonten-ng.c index bca91831e0..1704627112 100644 --- a/board/avionic-design/common/tamonten-ng.c +++ b/board/avionic-design/common/tamonten-ng.c @@ -55,7 +55,7 @@ void pmu_write(uchar reg, uchar data) struct udevice *dev; int ret; - ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, &dev); + ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c index fc31d29140..1540526a61 100644 --- a/board/nvidia/cardhu/cardhu.c +++ b/board/nvidia/cardhu/cardhu.c @@ -46,7 +46,7 @@ void board_sdmmc_voltage_init(void) int ret; int i; - ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev); + ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; @@ -94,7 +94,7 @@ int tegra_pcie_board_init(void) u8 addr, data[1]; int err; - err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev); + err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("failed to find PMU bus\n"); return err; diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c index c0991c57a9..d7c1a695ff 100644 --- a/board/nvidia/dalmore/dalmore.c +++ b/board/nvidia/dalmore/dalmore.c @@ -55,7 +55,7 @@ void board_sdmmc_voltage_init(void) uchar reg, data_buffer[1]; int ret; - ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev); + ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; @@ -83,7 +83,7 @@ void board_sdmmc_voltage_init(void) data_buffer[0] = 0x03; reg = 0x14; - ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, &dev); + ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find charger I2C chip\n", __func__); return; diff --git a/board/nvidia/whistler/whistler.c b/board/nvidia/whistler/whistler.c index ad6ea091df..3476f1159f 100644 --- a/board/nvidia/whistler/whistler.c +++ b/board/nvidia/whistler/whistler.c @@ -27,7 +27,7 @@ void pin_mux_mmc(void) int ret; /* Turn on MAX8907B LDO12 to 2.8V for J40 power */ - ret = i2c_get_chip_for_busnum(0, 0x3c, &dev); + ret = i2c_get_chip_for_busnum(0, 0x3c, 1, &dev); if (ret) { printf("%s: Cannot find MAX8907B I2C chip\n", __func__); return; @@ -64,7 +64,7 @@ void pin_mux_usb(void) */ /* Turn on TAC6416's GPIO 0+1 for USB1/3's VBUS */ - ret = i2c_get_chip_for_busnum(0, 0x20, &dev); + ret = i2c_get_chip_for_busnum(0, 0x20, 1, &dev); if (ret) { printf("%s: Cannot find TAC6416 I2C chip\n", __func__); return; diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c index 1c4b4c1cd4..624421496a 100644 --- a/board/toradex/apalis_t30/apalis_t30.c +++ b/board/toradex/apalis_t30/apalis_t30.c @@ -42,7 +42,7 @@ int tegra_pcie_board_init(void) u8 addr, data[1]; int err; - err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev); + err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return err; diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 1e500fbf2c..7c3ad00fdf 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -168,7 +168,7 @@ static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) if (ret) return ret; - return i2c_get_chip(bus, chip_addr, devp); + return i2c_get_chip(bus, chip_addr, 1, devp); } #endif diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 25f2c18cf4..24e5ec68f2 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -220,7 +220,7 @@ static int i2c_probe_chip(struct udevice *bus, uint chip_addr, return ops->xfer(bus, msg, 1); } -static int i2c_bind_driver(struct udevice *bus, uint chip_addr, +static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len, struct udevice **devp) { struct dm_i2c_chip chip; @@ -238,7 +238,7 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr, /* Tell the device what we know about it */ memset(&chip, '\0', sizeof(chip)); chip.chip_addr = chip_addr; - chip.offset_len = 1; /* we assume */ + chip.offset_len = offset_len; ret = device_probe_child(dev, &chip); debug("%s: device_probe_child: ret=%d\n", __func__, ret); if (ret) @@ -254,7 +254,8 @@ err_bind: return ret; } -int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp) +int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len, + struct udevice **devp) { struct udevice *dev; @@ -281,10 +282,11 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp) } } debug("not found\n"); - return i2c_bind_driver(bus, chip_addr, devp); + return i2c_bind_driver(bus, chip_addr, offset_len, devp); } -int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp) +int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len, + struct udevice **devp) { struct udevice *bus; int ret; @@ -294,7 +296,7 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp) debug("Cannot find I2C bus %d\n", busnum); return ret; } - ret = i2c_get_chip(bus, chip_addr, devp); + ret = i2c_get_chip(bus, chip_addr, offset_len, devp); if (ret) { debug("Cannot find I2C chip %02x on bus %d\n", chip_addr, busnum); @@ -319,7 +321,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, return ret; /* The chip was found, see if we have a driver, and probe it */ - ret = i2c_get_chip(bus, chip_addr, devp); + ret = i2c_get_chip(bus, chip_addr, 1, devp); debug("%s: i2c_get_chip: ret=%d\n", __func__, ret); return ret; diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index f0e9f51a1f..e2f6c3b9bb 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -60,7 +60,7 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, if (msg->addr == SANDBOX_I2C_TEST_ADDR) return 0; - ret = i2c_get_chip(bus, msg->addr, &dev); + ret = i2c_get_chip(bus, msg->addr, 1, &dev); if (ret) return ret; diff --git a/drivers/power/as3722.c b/drivers/power/as3722.c index 3aafdc9670..a60bb5f83f 100644 --- a/drivers/power/as3722.c +++ b/drivers/power/as3722.c @@ -242,7 +242,7 @@ int as3722_init(struct udevice **devp) const unsigned int address = 0x40; int err; - err = i2c_get_chip_for_busnum(bus, address, &pmic); + err = i2c_get_chip_for_busnum(bus, address, 1, &pmic); if (err) return err; err = as3722_read_id(pmic, &id, &revision); diff --git a/include/i2c.h b/include/i2c.h index 47529f4b28..76090b7a93 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -388,10 +388,12 @@ struct dm_i2c_ops { * * @bus: Bus to examine * @chip_addr: Chip address for the new device + * @offset_len: Length of a register offset in bytes (normally 1) * @devp: Returns pointer to new device if found or -ENODEV if not * found */ -int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp); +int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len, + struct udevice **devp); /** * i2c_get_chip() - get a device to use to access a chip on a bus number @@ -401,10 +403,12 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp); * * @busnum: Bus number to examine * @chip_addr: Chip address for the new device + * @offset_len: Length of a register offset in bytes (normally 1) * @devp: Returns pointer to new device if found or -ENODEV if not * found */ -int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp); +int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len, + struct udevice **devp); /** * i2c_chip_ofdata_to_platdata() - Decode standard I2C platform data diff --git a/test/dm/i2c.c b/test/dm/i2c.c index 4823b0c648..ef88372d56 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -49,7 +49,7 @@ static int dm_test_i2c_read_write(struct dm_test_state *dms) uint8_t buf[5]; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_get_chip(bus, chip, &dev)); + ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf))); ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); @@ -66,7 +66,7 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) uint8_t buf[5]; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_get_chip(bus, chip, &dev)); + ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(i2c_set_bus_speed(bus, 100000)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(i2c_set_bus_speed(bus, 400000)); @@ -84,7 +84,7 @@ static int dm_test_i2c_offset_len(struct dm_test_state *dms) uint8_t buf[5]; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_get_chip(bus, chip, &dev)); + ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(i2c_set_chip_offset_len(dev, 1)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); @@ -113,7 +113,7 @@ static int dm_test_i2c_bytewise(struct dm_test_state *dms) uint8_t buf[5]; ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); - ut_assertok(i2c_get_chip(bus, chip, &dev)); + ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf))); @@ -167,7 +167,7 @@ static int dm_test_i2c_offset(struct dm_test_state *dms) struct udevice *dev; uint8_t buf[5]; - ut_assertok(i2c_get_chip_for_busnum(busnum, chip, &dev)); + ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev)); /* Do a transfer so we can find the emulator */ ut_assertok(dm_i2c_read(dev, 0, buf, 5)); -- cgit From 22cc069160dc77972b70d45c0d2558e20e9ee766 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:26:56 -0700 Subject: dm: Don't run tests if U-Boot cannot be built There is no point in running the tests if U-Boot cannot be built. Abort in this case. Signed-off-by: Simon Glass --- test/dm/test-dm.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh index bb99677ece..8ebc39297c 100755 --- a/test/dm/test-dm.sh +++ b/test/dm/test-dm.sh @@ -1,9 +1,14 @@ #!/bin/sh +die() { + echo $1 + exit 1 +} + NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor) dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb -make O=sandbox sandbox_config -make O=sandbox -s -j${NUM_CPUS} +make O=sandbox sandbox_config || die "Cannot configure U-Boot" +make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot" dd if=/dev/zero of=spi.bin bs=1M count=2 ./sandbox/u-boot -d test/dm/test.dtb -c "dm test" rm spi.bin -- cgit From 040b69af7209d8fe0742352f4a72719df8dda9a5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:26:57 -0700 Subject: dm: core: Improve comments for uclass_first/next_device() Mention that the devices are probed ready for use. Signed-off-by: Simon Glass --- include/dm/uclass.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dm/uclass.h b/include/dm/uclass.h index f6ec6d7e9f..2577ae6489 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -141,6 +141,8 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node, /** * uclass_first_device() - Get the first device in a uclass * + * The device returned is probed if necessary, and ready for use + * * @id: Uclass ID to look up * @devp: Returns pointer to the first device in that uclass, or NULL if none * @return 0 if OK (found or not found), -1 on error @@ -150,6 +152,8 @@ int uclass_first_device(enum uclass_id id, struct udevice **devp); /** * uclass_next_device() - Get the next device in a uclass * + * The device returned is probed if necessary, and ready for use + * * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the same uclass, or NULL if none * @return 0 if OK (found or not found), -1 on error -- cgit From 2f3b95dbc78ce96b0f9f471e688db66223988419 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:26:58 -0700 Subject: dm: core: Set device tree node for root device The root device corresponds to the root device tree node, so set this up. Also add a few notes to the documentation. Signed-off-by: Simon Glass --- doc/driver-model/README.txt | 4 ++++ drivers/core/root.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index eafa825ab4..40415698cf 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -363,6 +363,10 @@ can leave out platdata_auto_alloc_size. In this case you can use malloc in your ofdata_to_platdata (or probe) method to allocate the required memory, and you should free it in the remove method. +The driver model tree is intended to mirror that of the device tree. The +root driver is at device tree offset 0 (the root node, '/'), and its +children are the children of the root node. + Declaring Uclasses ------------------ diff --git a/drivers/core/root.c b/drivers/core/root.c index 47b3acfbe9..a5b0a61501 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -49,6 +49,9 @@ int dm_init(void) ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); if (ret) return ret; +#ifdef CONFIG_OF_CONTROL + DM_ROOT_NON_CONST->of_offset = 0; +#endif ret = device_probe(DM_ROOT_NON_CONST); if (ret) return ret; -- cgit From 72ebfe86fac2ca0a0e1af9fe1eaa3a634e3e17a1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:26:59 -0700 Subject: dm: core: Tidy up error handling in device_bind() Make the error handling more standard to make it easier to build on top of it. Also correct a bug in the error path where there is no parent. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index 963b16f26f..eca8edac26 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -81,18 +81,13 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, ret = uclass_bind_device(dev); if (ret) - goto fail_bind; + goto fail_uclass_bind; /* if we fail to bind we remove device from successors and free it */ if (drv->bind) { ret = drv->bind(dev); - if (ret) { - if (uclass_unbind_device(dev)) { - dm_warn("Failed to unbind dev '%s' on error path\n", - dev->name); - } + if (ret) goto fail_bind; - } } if (parent) dm_dbg("Bound device %s to %s\n", dev->name, parent->name); @@ -101,8 +96,15 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, return 0; fail_bind: - list_del(&dev->sibling_node); + if (uclass_unbind_device(dev)) { + dm_warn("Failed to unbind dev '%s' on error path\n", + dev->name); + } +fail_uclass_bind: + if (parent) + list_del(&dev->sibling_node); free(dev); + return ret; } -- cgit From f8a85449ef3e0963add728815771ccc09aa99875 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:00 -0700 Subject: dm: core: Allocate platform data when binding a device When using allocated platform data, allocate it when we bind the device. This makes it possible to fill in this information before the device is probed. This fits with the platform data model (when not using device tree), since platform data exists at bind-time. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device-remove.c | 8 ++++---- drivers/core/device.c | 22 +++++++++++++--------- test/dm/test-fdt.c | 4 ++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 8fc6b71084..2c8257752b 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -88,6 +88,10 @@ int device_unbind(struct udevice *dev) if (ret) return ret; + if (dev->flags & DM_FLAG_ALLOC_PDATA) { + free(dev->platdata); + dev->platdata = NULL; + } ret = uclass_unbind_device(dev); if (ret) return ret; @@ -111,10 +115,6 @@ void device_free(struct udevice *dev) free(dev->priv); dev->priv = NULL; } - if (dev->flags & DM_FLAG_ALLOC_PDATA) { - free(dev->platdata); - dev->platdata = NULL; - } size = dev->uclass->uc_drv->per_device_auto_alloc_size; if (size) { free(dev->uclass_priv); diff --git a/drivers/core/device.c b/drivers/core/device.c index eca8edac26..366cffed89 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -72,8 +72,14 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, #else dev->req_seq = -1; #endif - if (!dev->platdata && drv->platdata_auto_alloc_size) + if (!dev->platdata && drv->platdata_auto_alloc_size) { dev->flags |= DM_FLAG_ALLOC_PDATA; + dev->platdata = calloc(1, drv->platdata_auto_alloc_size); + if (!dev->platdata) { + ret = -ENOMEM; + goto fail_alloc1; + } + } /* put dev into parent's successor list */ if (parent) @@ -103,6 +109,11 @@ fail_bind: fail_uclass_bind: if (parent) list_del(&dev->sibling_node); + if (dev->flags & DM_FLAG_ALLOC_PDATA) { + free(dev->platdata); + dev->platdata = NULL; + } +fail_alloc1: free(dev); return ret; @@ -139,7 +150,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv) drv = dev->driver; assert(drv); - /* Allocate private data and platdata if requested */ + /* Allocate private data if requested */ if (drv->priv_auto_alloc_size) { dev->priv = calloc(1, drv->priv_auto_alloc_size); if (!dev->priv) { @@ -148,13 +159,6 @@ int device_probe_child(struct udevice *dev, void *parent_priv) } } /* Allocate private data if requested */ - if (dev->flags & DM_FLAG_ALLOC_PDATA) { - dev->platdata = calloc(1, drv->platdata_auto_alloc_size); - if (!dev->platdata) { - ret = -ENOMEM; - goto fail; - } - } size = dev->uclass->uc_drv->per_device_auto_alloc_size; if (size) { dev->uclass_priv = calloc(1, size); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index cd2c38995e..dc4ebf9ada 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -143,12 +143,12 @@ static int dm_test_fdt(struct dm_test_state *dms) /* These are num_devices compatible root-level device tree nodes */ ut_asserteq(num_devices, list_count_items(&uc->dev_head)); - /* Each should have no platdata / priv */ + /* Each should have platform data but no private data */ for (i = 0; i < num_devices; i++) { ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); ut_assert(!ret); ut_assert(!dev_get_priv(dev)); - ut_assert(!dev->platdata); + ut_assert(dev->platdata); } ut_assertok(dm_check_devices(dms, num_devices)); -- cgit From cdc133bde9dd221319b9cf7fd99fcb4da8ba195c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:01 -0700 Subject: dm: core: Allow parents to have platform data for their children For buses it is common for parents to need to know the address of the child on the bus, the bus speed to use for that child, and other information. This can be provided in platform data attached to each child. Add driver model support for this, including auto-allocation which can be requested using a new property to specify the size of the data. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device-remove.c | 4 +++ drivers/core/device.c | 30 ++++++++++++++-- include/dm/device.h | 19 +++++++++++ test/dm/bus.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 2c8257752b..56c358a0ec 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -92,6 +92,10 @@ int device_unbind(struct udevice *dev) free(dev->platdata); dev->platdata = NULL; } + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } ret = uclass_unbind_device(dev); if (ret) return ret; diff --git a/drivers/core/device.c b/drivers/core/device.c index 366cffed89..ee97cc84ff 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -80,6 +80,18 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, goto fail_alloc1; } } + if (parent) { + int size = parent->driver->per_child_platdata_auto_alloc_size; + + if (size) { + dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA; + dev->parent_platdata = calloc(1, size); + if (!dev->parent_platdata) { + ret = -ENOMEM; + goto fail_alloc2; + } + } + } /* put dev into parent's successor list */ if (parent) @@ -107,8 +119,12 @@ fail_bind: dev->name); } fail_uclass_bind: - if (parent) - list_del(&dev->sibling_node); + list_del(&dev->sibling_node); + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } +fail_alloc2: if (dev->flags & DM_FLAG_ALLOC_PDATA) { free(dev->platdata); dev->platdata = NULL; @@ -247,6 +263,16 @@ void *dev_get_platdata(struct udevice *dev) return dev->platdata; } +void *dev_get_parent_platdata(struct udevice *dev) +{ + if (!dev) { + dm_warn("%s: null device", __func__); + return NULL; + } + + return dev->parent_platdata; +} + void *dev_get_priv(struct udevice *dev) { if (!dev) { diff --git a/include/dm/device.h b/include/dm/device.h index 13598a15b6..096d84b7b6 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -26,6 +26,9 @@ struct driver_info; /* DM should init this device prior to relocation */ #define DM_FLAG_PRE_RELOC (1 << 2) +/* DM is responsible for allocating and freeing parent_platdata */ +#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3) + /** * struct udevice - An instance of a driver * @@ -46,6 +49,7 @@ struct driver_info; * @driver: The driver used by this device * @name: Name of device, typically the FDT node name * @platdata: Configuration data for this device + * @parent_platdata: The parent bus's configuration data for this device * @of_offset: Device tree node offset for this device (- for none) * @of_id: Pointer to the udevice_id structure which created the device * @parent: Parent of this device, or NULL for the top level device @@ -65,6 +69,7 @@ struct udevice { struct driver *driver; const char *name; void *platdata; + void *parent_platdata; int of_offset; const struct udevice_id *of_id; struct udevice *parent; @@ -146,6 +151,9 @@ struct udevice_id { * device_probe_child() pass it in. So far the use case for allocating it * is SPI, but I found that unsatisfactory. Since it is here I will leave it * until things are clearer. + * @per_child_platdata_auto_alloc_size: A bus likes to store information about + * its children. If non-zero this is the size of this data, to be allocated + * in the child's parent_platdata pointer. * @ops: Driver-specific operations. This is typically a list of function * pointers defined by the driver, to implement driver functions required by * the uclass. @@ -165,6 +173,7 @@ struct driver { int priv_auto_alloc_size; int platdata_auto_alloc_size; int per_child_auto_alloc_size; + int per_child_platdata_auto_alloc_size; const void *ops; /* driver-specific operations */ uint32_t flags; }; @@ -183,6 +192,16 @@ struct driver { */ void *dev_get_platdata(struct udevice *dev); +/** + * dev_get_parent_platdata() - Get the parent platform data for a device + * + * This checks that dev is not NULL, but no other checks for now + * + * @dev Device to check + * @return parent's platform data, or NULL if none + */ +void *dev_get_parent_platdata(struct udevice *dev); + /** * dev_get_parentdata() - Get the parent data for a device * diff --git a/test/dm/bus.c b/test/dm/bus.c index abbaccff50..63c8a9f738 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -9,11 +9,16 @@ #include #include #include +#include #include #include DECLARE_GLOBAL_DATA_PTR; +struct dm_test_parent_platdata { + int count; +}; + enum { FLAG_CHILD_PROBED = 10, FLAG_CHILD_REMOVED = -7, @@ -62,6 +67,8 @@ U_BOOT_DRIVER(testbus_drv) = { .priv_auto_alloc_size = sizeof(struct dm_test_priv), .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data), + .per_child_platdata_auto_alloc_size = + sizeof(struct dm_test_parent_platdata), .child_pre_probe = testbus_child_pre_probe, .child_post_remove = testbus_child_post_remove, }; @@ -271,3 +278,77 @@ static int dm_test_bus_parent_ops(struct dm_test_state *dms) return 0; } DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that the bus can store platform data about each child */ +static int dm_test_bus_parent_platdata(struct dm_test_state *dms) +{ + struct dm_test_parent_platdata *plat; + struct udevice *bus, *dev; + int child_count; + + /* Check that the bus has no children */ + ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); + device_find_first_child(bus, &dev); + ut_asserteq_ptr(NULL, dev); + + ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); + + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + /* Check that platform data is allocated */ + plat = dev_get_parent_platdata(dev); + ut_assert(plat != NULL); + + /* + * Check that it is not affected by the device being + * probed/removed + */ + plat->count++; + ut_asserteq(1, plat->count); + device_probe(dev); + device_remove(dev); + + ut_asserteq_ptr(plat, dev_get_parent_platdata(dev)); + ut_asserteq(1, plat->count); + ut_assertok(device_probe(dev)); + child_count++; + } + ut_asserteq(3, child_count); + + /* Removing the bus should also have no effect (it is still bound) */ + device_remove(bus); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + /* Check that platform data is allocated */ + plat = dev_get_parent_platdata(dev); + ut_assert(plat != NULL); + ut_asserteq(1, plat->count); + child_count++; + } + ut_asserteq(3, child_count); + + /* Unbind all the children */ + do { + device_find_first_child(bus, &dev); + if (dev) + device_unbind(dev); + } while (dev); + + /* Now the child platdata should be removed and re-added */ + device_probe(bus); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + /* Check that platform data is allocated */ + plat = dev_get_parent_platdata(dev); + ut_assert(plat != NULL); + ut_asserteq(0, plat->count); + child_count++; + } + ut_asserteq(3, child_count); + + return 0; +} +DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit From ba8da9dc43ac8ae3351345df12dc7f9d1cd07ae0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:02 -0700 Subject: dm: core: Allow uclasses to specify platdata for a device's children In many cases the child platform data for a device's children is defined by the uclass rather than the individual devices. For example, a SPI bus needs to know the chip select and speed for each of its children. It makes sense to allow this information to be defined the SPI uclass rather than each individual driver. If the device provides a size value for its child platdata, then use it. Failng that, fall back to that provided by the uclass. Reviewed-by: Masahiro Yamada Signed-off-by: Simon Glass --- drivers/core/device.c | 4 ++++ include/dm/uclass.h | 5 +++++ test/dm/bus.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/core/device.c b/drivers/core/device.c index ee97cc84ff..2f33b0e6a3 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -83,6 +83,10 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, if (parent) { int size = parent->driver->per_child_platdata_auto_alloc_size; + if (!size) { + size = parent->uclass->uc_drv-> + per_child_platdata_auto_alloc_size; + } if (size) { dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA; dev->parent_platdata = calloc(1, size); diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 2577ae6489..7d92d34bec 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -60,6 +60,10 @@ struct udevice; * @per_device_auto_alloc_size: Each device can hold private data owned * by the uclass. If required this will be automatically allocated if this * value is non-zero. + * @per_child_platdata_auto_alloc_size: A bus likes to store information about + * its children. If non-zero this is the size of this data, to be allocated + * in the child device's parent_platdata pointer. This value is only used as + * a falback if this member is 0 in the driver. * @ops: Uclass operations, providing the consistent interface to devices * within the uclass. */ @@ -74,6 +78,7 @@ struct uclass_driver { int (*destroy)(struct uclass *class); int priv_auto_alloc_size; int per_device_auto_alloc_size; + int per_child_platdata_auto_alloc_size; const void *ops; }; diff --git a/test/dm/bus.c b/test/dm/bus.c index 63c8a9f738..26b8293037 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -279,8 +279,7 @@ static int dm_test_bus_parent_ops(struct dm_test_state *dms) } DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -/* Test that the bus can store platform data about each child */ -static int dm_test_bus_parent_platdata(struct dm_test_state *dms) +static int test_bus_parent_platdata(struct dm_test_state *dms) { struct dm_test_parent_platdata *plat; struct udevice *bus, *dev; @@ -351,4 +350,33 @@ static int dm_test_bus_parent_platdata(struct dm_test_state *dms) return 0; } + +/* Test that the bus can store platform data about each child */ +static int dm_test_bus_parent_platdata(struct dm_test_state *dms) +{ + return test_bus_parent_platdata(dms); +} DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* As above but the size is controlled by the uclass */ +static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms) +{ + struct udevice *bus; + int size; + int ret; + + /* Set the driver size to 0 so that the uclass size is used */ + ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); + size = bus->driver->per_child_platdata_auto_alloc_size; + bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size; + bus->driver->per_child_platdata_auto_alloc_size = 0; + ret = test_bus_parent_platdata(dms); + if (ret) + return ret; + bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0; + bus->driver->per_child_platdata_auto_alloc_size = size; + + return 0; +} +DM_TEST(dm_test_bus_parent_platdata_uclass, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit From 0118ce79577f9b0881f99a6e4f8a79cd5014cb87 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:03 -0700 Subject: dm: core: Add a post_bind method for parents Allow parent drivers to be called when a new child is bound to them. This allows a bus to set up information it needs for that child. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device.c | 12 ++++++++++++ include/dm/device.h | 2 ++ test/dm/bus.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/drivers/core/device.c b/drivers/core/device.c index 2f33b0e6a3..365676b912 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -111,12 +111,24 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, if (ret) goto fail_bind; } + if (parent && parent->driver->child_post_bind) { + ret = parent->driver->child_post_bind(dev); + if (ret) + goto fail_child_post_bind; + } + if (parent) dm_dbg("Bound device %s to %s\n", dev->name, parent->name); *devp = dev; return 0; +fail_child_post_bind: + if (drv->unbind && drv->unbind(dev)) { + dm_warn("unbind() method failed on dev '%s' on error path\n", + dev->name); + } + fail_bind: if (uclass_unbind_device(dev)) { dm_warn("Failed to unbind dev '%s' on error path\n", diff --git a/include/dm/device.h b/include/dm/device.h index 096d84b7b6..50f1b4f508 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -132,6 +132,7 @@ struct udevice_id { * @remove: Called to remove a device, i.e. de-activate it * @unbind: Called to unbind a device from its driver * @ofdata_to_platdata: Called before probe to decode device tree data + * @child_post_bind: Called after a new child has been bound * @child_pre_probe: Called before a child device is probed. The device has * memory allocated but it has not yet been probed. * @child_post_remove: Called after a child device is removed. The device @@ -168,6 +169,7 @@ struct driver { int (*remove)(struct udevice *dev); int (*unbind)(struct udevice *dev); int (*ofdata_to_platdata)(struct udevice *dev); + int (*child_post_bind)(struct udevice *dev); int (*child_pre_probe)(struct udevice *dev); int (*child_post_remove)(struct udevice *dev); int priv_auto_alloc_size; diff --git a/test/dm/bus.c b/test/dm/bus.c index 26b8293037..e18a6f7249 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -17,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; struct dm_test_parent_platdata { int count; + int bind_flag; }; enum { @@ -31,6 +32,16 @@ static int testbus_drv_probe(struct udevice *dev) return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); } +static int testbus_child_post_bind(struct udevice *dev) +{ + struct dm_test_parent_platdata *plat; + + plat = dev_get_parent_platdata(dev); + plat->bind_flag = 1; + + return 0; +} + static int testbus_child_pre_probe(struct udevice *dev) { struct dm_test_parent_data *parent_data = dev_get_parentdata(dev); @@ -64,6 +75,7 @@ U_BOOT_DRIVER(testbus_drv) = { .of_match = testbus_ids, .id = UCLASS_TEST_BUS, .probe = testbus_drv_probe, + .child_post_bind = testbus_child_post_bind, .priv_auto_alloc_size = sizeof(struct dm_test_priv), .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data), @@ -380,3 +392,26 @@ static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms) } DM_TEST(dm_test_bus_parent_platdata_uclass, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that the child post_bind method is called */ +static int dm_test_bus_child_post_bind(struct dm_test_state *dms) +{ + struct dm_test_parent_platdata *plat; + struct udevice *bus, *dev; + int child_count; + + ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + /* Check that platform data is allocated */ + plat = dev_get_parent_platdata(dev); + ut_assert(plat != NULL); + ut_asserteq(1, plat->bind_flag); + child_count++; + } + ut_asserteq(3, child_count); + + return 0; +} +DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit From b367053102e597eb21b0a5e86c63e8d10f368cb0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:04 -0700 Subject: dm: core: Add a function to get a device's uclass ID This is useful to check which uclass a device is in. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device.c | 5 +++++ include/dm/device.h | 8 ++++++++ test/dm/core.c | 11 +++++++++++ 3 files changed, 24 insertions(+) diff --git a/drivers/core/device.c b/drivers/core/device.c index 365676b912..2606d18717 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -438,3 +438,8 @@ ulong dev_get_of_data(struct udevice *dev) { return dev->of_id->data; } + +enum uclass_id device_get_uclass_id(struct udevice *dev) +{ + return dev->uclass->uc_drv->id; +} diff --git a/include/dm/device.h b/include/dm/device.h index 50f1b4f508..81afa8c628 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -245,6 +245,14 @@ struct udevice *dev_get_parent(struct udevice *child); */ ulong dev_get_of_data(struct udevice *dev); +/* + * device_get_uclass_id() - return the uclass ID of a device + * + * @dev: Device to check + * @return uclass ID for the device + */ +enum uclass_id device_get_uclass_id(struct udevice *dev); + /** * device_get_child() - Get the child of a device by index * diff --git a/test/dm/core.c b/test/dm/core.c index ff5c2a749c..eccda0974d 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -598,3 +598,14 @@ static int dm_test_uclass_before_ready(struct dm_test_state *dms) } DM_TEST(dm_test_uclass_before_ready, 0); + +static int dm_test_device_get_uclass_id(struct dm_test_state *dms) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev)); + ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev)); + + return 0; +} +DM_TEST(dm_test_device_get_uclass_id, DM_TESTF_SCAN_PDATA); -- cgit From 9cc36a2b89ebe5148d69d521745c1e1d26365c3a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:05 -0700 Subject: dm: core: Add a flag to control sequence numbering At present we try to use the 'reg' property and device tree aliases to give devices a sequence number. The 'reg' property is often actually a memory address, so the sequence numbers thus-obtained are not useful. It would be better if the devices were just sequentially numbered in that case. In fact neither I2C nor SPI use this feature, so drop it. Some devices need us to look up an alias to number them within the uclass. Add a flag to control this, so it is not done unless it is needed. Adjust the tests to test this new behaviour. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- doc/driver-model/README.txt | 51 +++++++++++------------------------------- drivers/core/device.c | 28 +++++++++++------------ drivers/i2c/i2c-uclass.c | 1 + drivers/serial/serial-uclass.c | 1 + drivers/spi/spi-uclass.c | 1 + include/dm/uclass.h | 5 +++++ test/dm/bus.c | 3 ++- test/dm/test-fdt.c | 9 ++++---- test/dm/test.dts | 16 +++++++++++++ 9 files changed, 57 insertions(+), 58 deletions(-) diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index 40415698cf..0c1292bf12 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -388,12 +388,12 @@ Device Sequence Numbers U-Boot numbers devices from 0 in many situations, such as in the command line for I2C and SPI buses, and the device names for serial ports (serial0, serial1, ...). Driver model supports this numbering and permits devices -to be locating by their 'sequence'. This numbering unique identifies a +to be locating by their 'sequence'. This numbering uniquely identifies a device in its uclass, so no two devices within a particular uclass can have the same sequence number. Sequence numbers start from 0 but gaps are permitted. For example, a board -may have I2C buses 0, 1, 4, 5 but no 2 or 3. The choice of how devices are +may have I2C buses 1, 4, 5 but no 0, 2 or 3. The choice of how devices are numbered is up to a particular board, and may be set by the SoC in some cases. While it might be tempting to automatically renumber the devices where there are gaps in the sequence, this can lead to confusion and is @@ -403,7 +403,7 @@ Each device can request a sequence number. If none is required then the device will be automatically allocated the next available sequence number. To specify the sequence number in the device tree an alias is typically -used. +used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set. aliases { serial2 = "/serial@22230000"; @@ -413,43 +413,18 @@ This indicates that in the uclass called "serial", the named node ("/serial@22230000") will be given sequence number 2. Any command or driver which requests serial device 2 will obtain this device. -Some devices represent buses where the devices on the bus are numbered or -addressed. For example, SPI typically numbers its slaves from 0, and I2C -uses a 7-bit address. In these cases the 'reg' property of the subnode is -used, for example: +More commonly you can use node references, which expand to the full path: -{ - aliases { - spi2 = "/spi@22300000"; - }; - - spi@22300000 { - #address-cells = <1>; - #size-cells = <1>; - spi-flash@0 { - reg = <0>; - ... - } - eeprom@1 { - reg = <1>; - }; - }; - -In this case we have a SPI bus with two slaves at 0 and 1. The SPI bus -itself is numbered 2. So we might access the SPI flash with: - - sf probe 2:0 - -and the eeprom with - - sspi 2:1 32 ef - -These commands simply need to look up the 2nd device in the SPI uclass to -find the right SPI bus. Then, they look at the children of that bus for the -right sequence number (0 or 1 in this case). +aliases { + serial2 = &serial_2; +}; +... +serial_2: serial@22230000 { +... +}; -Typically the alias method is used for top-level nodes and the 'reg' method -is used only for buses. +The alias resolves to the same string in this case, but this version is +easier to read. Device sequence numbers are resolved when a device is probed. Before then the sequence number is only a request which may or may not be honoured, diff --git a/drivers/core/device.c b/drivers/core/device.c index 2606d18717..f78b78a299 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -53,24 +53,22 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, dev->driver = drv; dev->uclass = uc; - /* - * For some devices, such as a SPI or I2C bus, the 'reg' property - * is a reasonable indicator of the sequence number. But if there is - * an alias, we use that in preference. In any case, this is just - * a 'requested' sequence, and will be resolved (and ->seq updated) - * when the device is probed. - */ dev->seq = -1; + dev->req_seq = -1; #ifdef CONFIG_OF_CONTROL - dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1); - if (!IS_ERR_VALUE(dev->req_seq)) - dev->req_seq &= INT_MAX; - if (uc->uc_drv->name && of_offset != -1) { - fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset, - &dev->req_seq); + /* + * Some devices, such as a SPI bus, I2C bus and serial ports are + * numbered using aliases. + * + * This is just a 'requested' sequence, and will be + * resolved (and ->seq updated) when the device is probed. + */ + if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { + if (uc->uc_drv->name && of_offset != -1) { + fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, + of_offset, &dev->req_seq); + } } -#else - dev->req_seq = -1; #endif if (!dev->platdata && drv->platdata_auto_alloc_size) { dev->flags |= DM_FLAG_ALLOC_PDATA; diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 24e5ec68f2..94b49dfe52 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -453,6 +453,7 @@ int i2c_post_bind(struct udevice *dev) UCLASS_DRIVER(i2c) = { .id = UCLASS_I2C, .name = "i2c", + .flags = DM_UC_FLAG_SEQ_ALIAS, .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), .post_bind = i2c_post_bind, .post_probe = i2c_post_probe, diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index d1b5777cec..9131a8f93d 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -297,6 +297,7 @@ static int serial_pre_remove(struct udevice *dev) UCLASS_DRIVER(serial) = { .id = UCLASS_SERIAL, .name = "serial", + .flags = DM_UC_FLAG_SEQ_ALIAS, .post_probe = serial_post_probe, .pre_remove = serial_pre_remove, .per_device_auto_alloc_size = sizeof(struct serial_dev_priv), diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 7a57bceb26..35756ad784 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -344,6 +344,7 @@ int spi_ofdata_to_platdata(const void *blob, int node, UCLASS_DRIVER(spi) = { .id = UCLASS_SPI, .name = "spi", + .flags = DM_UC_FLAG_SEQ_ALIAS, .post_bind = spi_post_bind, .post_probe = spi_post_probe, .per_device_auto_alloc_size = sizeof(struct dm_spi_bus), diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 7d92d34bec..9000b22c38 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -40,6 +40,9 @@ struct uclass { struct udevice; +/* Members of this uclass sequence themselves with aliases */ +#define DM_UC_FLAG_SEQ_ALIAS (1 << 0) + /** * struct uclass_driver - Driver for the uclass * @@ -66,6 +69,7 @@ struct udevice; * a falback if this member is 0 in the driver. * @ops: Uclass operations, providing the consistent interface to devices * within the uclass. + * @flags: Flags for this uclass (DM_UC_...) */ struct uclass_driver { const char *name; @@ -80,6 +84,7 @@ struct uclass_driver { int per_device_auto_alloc_size; int per_child_platdata_auto_alloc_size; const void *ops; + uint32_t flags; }; /* Declare a new uclass_driver */ diff --git a/test/dm/bus.c b/test/dm/bus.c index e18a6f7249..972c449790 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -88,12 +88,13 @@ U_BOOT_DRIVER(testbus_drv) = { UCLASS_DRIVER(testbus) = { .name = "testbus", .id = UCLASS_TEST_BUS, + .flags = DM_UC_FLAG_SEQ_ALIAS, }; /* Test that we can probe for children */ static int dm_test_bus_children(struct dm_test_state *dms) { - int num_devices = 4; + int num_devices = 6; struct udevice *bus; struct uclass *uc; diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index dc4ebf9ada..dfcb3af61b 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -89,6 +89,7 @@ int testfdt_ping(struct udevice *dev, int pingval, int *pingret) UCLASS_DRIVER(testfdt) = { .name = "testfdt", .id = UCLASS_TEST_FDT, + .flags = DM_UC_FLAG_SEQ_ALIAS, }; int dm_check_devices(struct dm_test_state *dms, int num_devices) @@ -128,7 +129,7 @@ int dm_check_devices(struct dm_test_state *dms, int num_devices) /* Test that FDT-based binding works correctly */ static int dm_test_fdt(struct dm_test_state *dms) { - const int num_devices = 4; + const int num_devices = 6; struct udevice *dev; struct uclass *uc; int ret; @@ -184,7 +185,7 @@ static int dm_test_fdt_uclass_seq(struct dm_test_state *dms) ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev)); ut_asserteq_str("b-test", dev->name); - ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, true, &dev)); + ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev)); ut_asserteq_str("a-test", dev->name); ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5, @@ -220,11 +221,11 @@ static int dm_test_fdt_uclass_seq(struct dm_test_state *dms) ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); - ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 1, &dev)); + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev)); /* But now that it is probed, we can find it */ ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); - ut_asserteq_str("a-test", dev->name); + ut_asserteq_str("f-test", dev->name); return 0; } diff --git a/test/dm/test.dts b/test/dm/test.dts index 33f2c00747..84024a44a3 100644 --- a/test/dm/test.dts +++ b/test/dm/test.dts @@ -8,7 +8,15 @@ aliases { console = &uart0; + i2c0 = "/i2c@0"; + spi0 = "/spi@0"; testfdt6 = "/e-test"; + testbus3 = "/some-bus"; + testfdt0 = "/some-bus/c-test@0"; + testfdt1 = "/some-bus/c-test@1"; + testfdt3 = "/b-test"; + testfdt5 = "/some-bus/c-test@5"; + testfdt8 = "/a-test"; }; uart0: serial { @@ -86,6 +94,14 @@ compatible = "google,another-fdt-test"; }; + f-test { + compatible = "denx,u-boot-fdt-test"; + }; + + g-test { + compatible = "denx,u-boot-fdt-test"; + }; + gpio_a: base-gpios { compatible = "sandbox,gpio"; gpio-controller; -- cgit From dac8db2ce66944828e441cccf25703b262a256cd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:06 -0700 Subject: dm: core: Allow uclasses to specify private data for a device's children In many cases the per-child private data for a device's children is defined by the uclass rather than the individual driver. For example, a SPI bus needs to store information about each of its children, but all SPI drivers store the same information. It makes sense to allow the uclass to define this data. If the driver provides a size value for its per-child private data, then use it. Failng that, fall back to that provided by the uclass. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device-remove.c | 4 ++++ drivers/core/device.c | 4 ++++ include/dm/uclass.h | 4 ++++ test/dm/bus.c | 31 +++++++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 56c358a0ec..3a5f48df7a 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -126,6 +126,10 @@ void device_free(struct udevice *dev) } if (dev->parent) { size = dev->parent->driver->per_child_auto_alloc_size; + if (!size) { + size = dev->parent->uclass->uc_drv-> + per_child_auto_alloc_size; + } if (size) { free(dev->parent_priv); dev->parent_priv = NULL; diff --git a/drivers/core/device.c b/drivers/core/device.c index f78b78a299..78bc460d35 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -201,6 +201,10 @@ int device_probe_child(struct udevice *dev, void *parent_priv) /* Ensure all parents are probed */ if (dev->parent) { size = dev->parent->driver->per_child_auto_alloc_size; + if (!size) { + size = dev->parent->uclass->uc_drv-> + per_child_auto_alloc_size; + } if (size) { dev->parent_priv = calloc(1, size); if (!dev->parent_priv) { diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 9000b22c38..ac6c85072c 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -63,6 +63,9 @@ struct udevice; * @per_device_auto_alloc_size: Each device can hold private data owned * by the uclass. If required this will be automatically allocated if this * value is non-zero. + * @per_child_auto_alloc_size: Each child device (of a parent in this + * uclass) can hold parent data for the device/uclass. This value is only + * used as a falback if this member is 0 in the driver. * @per_child_platdata_auto_alloc_size: A bus likes to store information about * its children. If non-zero this is the size of this data, to be allocated * in the child device's parent_platdata pointer. This value is only used as @@ -82,6 +85,7 @@ struct uclass_driver { int (*destroy)(struct uclass *class); int priv_auto_alloc_size; int per_device_auto_alloc_size; + int per_child_auto_alloc_size; int per_child_platdata_auto_alloc_size; const void *ops; uint32_t flags; diff --git a/test/dm/bus.c b/test/dm/bus.c index 972c449790..e909697062 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -192,7 +192,7 @@ DM_TEST(dm_test_bus_children_iterators, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); /* Test that the bus can store data about each child */ -static int dm_test_bus_parent_data(struct dm_test_state *dms) +static int test_bus_parent_data(struct dm_test_state *dms) { struct dm_test_parent_data *parent_data; struct udevice *bus, *dev; @@ -251,9 +251,36 @@ static int dm_test_bus_parent_data(struct dm_test_state *dms) return 0; } - +/* Test that the bus can store data about each child */ +static int dm_test_bus_parent_data(struct dm_test_state *dms) +{ + return test_bus_parent_data(dms); +} DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +/* As above but the size is controlled by the uclass */ +static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms) +{ + struct udevice *bus; + int size; + int ret; + + /* Set the driver size to 0 so that the uclass size is used */ + ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); + size = bus->driver->per_child_auto_alloc_size; + bus->uclass->uc_drv->per_child_auto_alloc_size = size; + bus->driver->per_child_auto_alloc_size = 0; + ret = test_bus_parent_data(dms); + if (ret) + return ret; + bus->uclass->uc_drv->per_child_auto_alloc_size = 0; + bus->driver->per_child_auto_alloc_size = size; + + return 0; +} +DM_TEST(dm_test_bus_parent_data_uclass, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + /* Test that the bus ops are called when a child is probed/removed */ static int dm_test_bus_parent_ops(struct dm_test_state *dms) { -- cgit From 19a25f672c6aa1a9a9b94c0ffbfda3e8246d1a19 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:07 -0700 Subject: dm: spi: Move the per-child data size to the uclass This is common to all SPI drivers and specifies a structure used by the uclass. It makes more sense to define it in the uclass. Reviewed-by: Masahiro Yamada Signed-off-by: Simon Glass --- drivers/spi/cadence_qspi.c | 1 - drivers/spi/designware_spi.c | 1 - drivers/spi/exynos_spi.c | 1 - drivers/spi/sandbox_spi.c | 1 - drivers/spi/soft_spi.c | 1 - drivers/spi/spi-uclass.c | 1 + drivers/spi/tegra114_spi.c | 1 - drivers/spi/tegra20_sflash.c | 1 - drivers/spi/tegra20_slink.c | 1 - 9 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 98ae3b808f..a75fc46e95 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -340,6 +340,5 @@ U_BOOT_DRIVER(cadence_spi) = { .ofdata_to_platdata = cadence_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct cadence_spi_platdata), .priv_auto_alloc_size = sizeof(struct cadence_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = cadence_spi_probe, }; diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 700f616ad7..2624844d52 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -421,6 +421,5 @@ U_BOOT_DRIVER(dw_spi) = { .ofdata_to_platdata = dw_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct dw_spi_platdata), .priv_auto_alloc_size = sizeof(struct dw_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = dw_spi_probe, }; diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index f078973531..a46d8c1876 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -425,6 +425,5 @@ U_BOOT_DRIVER(exynos_spi) = { .ofdata_to_platdata = exynos_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata), .priv_auto_alloc_size = sizeof(struct exynos_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = exynos_spi_probe, }; diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index e717424db8..bad56603ba 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -160,6 +160,5 @@ U_BOOT_DRIVER(spi_sandbox) = { .name = "spi_sandbox", .id = UCLASS_SPI, .of_match = sandbox_spi_ids, - .per_child_auto_alloc_size = sizeof(struct spi_slave), .ops = &sandbox_spi_ops, }; diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 423c98d1a5..9f7d80ee4d 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -240,7 +240,6 @@ U_BOOT_DRIVER(soft_spi) = { .ofdata_to_platdata = soft_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct soft_spi_platdata), .priv_auto_alloc_size = sizeof(struct soft_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = soft_spi_probe, .child_pre_probe = soft_spi_child_pre_probe, }; diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 35756ad784..e5dfb300fa 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -348,6 +348,7 @@ UCLASS_DRIVER(spi) = { .post_bind = spi_post_bind, .post_probe = spi_post_probe, .per_device_auto_alloc_size = sizeof(struct dm_spi_bus), + .per_child_auto_alloc_size = sizeof(struct spi_slave), }; UCLASS_DRIVER(spi_generic) = { diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 2d97625fba..53ff9ea221 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -407,6 +407,5 @@ U_BOOT_DRIVER(tegra114_spi) = { .ofdata_to_platdata = tegra114_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata), .priv_auto_alloc_size = sizeof(struct tegra114_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = tegra114_spi_probe, }; diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c index 7d0d0f37fc..78c74cdf37 100644 --- a/drivers/spi/tegra20_sflash.c +++ b/drivers/spi/tegra20_sflash.c @@ -348,6 +348,5 @@ U_BOOT_DRIVER(tegra20_sflash) = { .ofdata_to_platdata = tegra20_sflash_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata), .priv_auto_alloc_size = sizeof(struct tegra20_sflash_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = tegra20_sflash_probe, }; diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 213fa5f793..597d6ad5cc 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -361,6 +361,5 @@ U_BOOT_DRIVER(tegra30_spi) = { .ofdata_to_platdata = tegra30_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata), .priv_auto_alloc_size = sizeof(struct tegra30_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = tegra30_spi_probe, }; -- cgit From 081f2fcbd9a95ba10677065359791f8fea3f8c58 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:08 -0700 Subject: dm: core: Allow the uclass to set up a device's child after binding For buses, after a child is bound, allow the uclass to perform some processing. This can be used to figure out the address of the child (e.g. the chip select for SPI slaves) so that it is ready to be probed. This avoids bus drivers having to repeat the same process, which really should be done by the uclass, since it is common. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/uclass.c | 21 ++++++++++++++++----- include/dm/uclass.h | 2 ++ test/dm/bus.c | 26 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 901b06ed2b..a5445518f5 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -319,18 +319,29 @@ int uclass_bind_device(struct udevice *dev) int ret; uc = dev->uclass; - list_add_tail(&dev->uclass_node, &uc->dev_head); + if (dev->parent) { + struct uclass_driver *uc_drv = dev->parent->uclass->uc_drv; + + if (uc_drv->child_post_bind) { + ret = uc_drv->child_post_bind(dev); + if (ret) + goto err; + } + } if (uc->uc_drv->post_bind) { ret = uc->uc_drv->post_bind(dev); - if (ret) { - list_del(&dev->uclass_node); - return ret; - } + if (ret) + goto err; } return 0; +err: + /* There is no need to undo the parent's post_bind call */ + list_del(&dev->uclass_node); + + return ret; } int uclass_unbind_device(struct udevice *dev) diff --git a/include/dm/uclass.h b/include/dm/uclass.h index ac6c85072c..5c5b8f4208 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -55,6 +55,7 @@ struct udevice; * @pre_unbind: Called before a device is unbound from this uclass * @post_probe: Called after a new device is probed * @pre_remove: Called before a device is removed + * @child_post_bind: Called after a child is bound to a device in this uclass * @init: Called to set up the uclass * @destroy: Called to destroy the uclass * @priv_auto_alloc_size: If non-zero this is the size of the private data @@ -81,6 +82,7 @@ struct uclass_driver { int (*pre_unbind)(struct udevice *dev); int (*post_probe)(struct udevice *dev); int (*pre_remove)(struct udevice *dev); + int (*child_post_bind)(struct udevice *dev); int (*init)(struct uclass *class); int (*destroy)(struct uclass *class); int priv_auto_alloc_size; diff --git a/test/dm/bus.c b/test/dm/bus.c index e909697062..c123ed7931 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -18,6 +18,7 @@ DECLARE_GLOBAL_DATA_PTR; struct dm_test_parent_platdata { int count; int bind_flag; + int uclass_bind_flag; }; enum { @@ -38,6 +39,7 @@ static int testbus_child_post_bind(struct udevice *dev) plat = dev_get_parent_platdata(dev); plat->bind_flag = 1; + plat->uclass_bind_flag = 2; return 0; } @@ -443,3 +445,27 @@ static int dm_test_bus_child_post_bind(struct dm_test_state *dms) return 0; } DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that the child post_bind method is called */ +static int dm_test_bus_child_post_bind_uclass(struct dm_test_state *dms) +{ + struct dm_test_parent_platdata *plat; + struct udevice *bus, *dev; + int child_count; + + ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + /* Check that platform data is allocated */ + plat = dev_get_parent_platdata(dev); + ut_assert(plat != NULL); + ut_asserteq(2, plat->uclass_bind_flag); + child_count++; + } + ut_asserteq(3, child_count); + + return 0; +} +DM_TEST(dm_test_bus_child_post_bind_uclass, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit From 1603bf3cc189da65362b83b85831e094a2fe8516 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:09 -0700 Subject: dm: sandbox: sf: Tidy up the error handling in sandbox_sf_probe() Use a single exit point when we have an error and add debugging there. Signed-off-by: Simon Glass --- drivers/mtd/spi/sandbox.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 3024b988fe..106dda9ccc 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -141,8 +141,10 @@ static int sandbox_sf_probe(struct udevice *dev) assert(bus->seq != -1); if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) spec = state->spi[bus->seq][cs].spec; - if (!spec) - return -ENOENT; + if (!spec) { + ret = -ENOENT; + goto error; + } file = strchr(spec, ':'); if (!file) { @@ -196,6 +198,7 @@ static int sandbox_sf_probe(struct udevice *dev) return 0; error: + debug("%s: Got error %d\n", __func__, ret); return ret; } -- cgit From 83c7e434c9dd3ca81f8b763e23c1881b973bcf2f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:10 -0700 Subject: dm: core: Allow uclass to set up a device's child before it is probed Some buses need to set up their devices before they can be used. This setup may well be common to all buses in a particular uclass. Support a common pre-probe method for the uclass, called before any bus devices are probed. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/device.c | 4 ++++ drivers/core/uclass.c | 13 +++++++++++++ include/dm/test.h | 3 +++ include/dm/uclass-internal.h | 11 +++++++++++ include/dm/uclass.h | 1 + test/dm/bus.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 7 +++++++ 7 files changed, 85 insertions(+) diff --git a/drivers/core/device.c b/drivers/core/device.c index 78bc460d35..b73d3b8961 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -227,6 +227,10 @@ int device_probe_child(struct udevice *dev, void *parent_priv) } dev->seq = seq; + ret = uclass_pre_probe_child(dev); + if (ret) + goto fail; + if (dev->parent && dev->parent->driver->child_pre_probe) { ret = dev->parent->driver->child_pre_probe(dev); if (ret) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index a5445518f5..289a5d2d53 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -391,6 +391,19 @@ int uclass_resolve_seq(struct udevice *dev) return seq; } +int uclass_pre_probe_child(struct udevice *dev) +{ + struct uclass_driver *uc_drv; + + if (!dev->parent) + return 0; + uc_drv = dev->parent->uclass->uc_drv; + if (uc_drv->child_pre_probe) + return uc_drv->child_pre_probe(dev); + + return 0; +} + int uclass_post_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv = dev->uclass->uc_drv; diff --git a/include/dm/test.h b/include/dm/test.h index f08c05da81..707c69e07f 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -67,6 +67,8 @@ enum { struct dm_test_priv { int ping_total; int op_count[DM_TEST_OP_COUNT]; + int uclass_flag; + int uclass_total; }; /** @@ -88,6 +90,7 @@ struct dm_test_uclass_priv { * * @sum: Test value used to check parent data works correctly * @flag: Used to track calling of parent operations + * @uclass_flag: Used to track calling of parent operations by uclass */ struct dm_test_parent_data { int sum; diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index f718f37aff..f2f254a825 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -43,6 +43,17 @@ int uclass_bind_device(struct udevice *dev); */ int uclass_unbind_device(struct udevice *dev); +/** + * uclass_pre_probe_child() - Deal with a child that is about to be probed + * + * Perform any pre-processing that is needed by the uclass before it can be + * probed. + * + * @dev: Pointer to the device + * #return 0 on success, -ve on error + */ +int uclass_pre_probe_child(struct udevice *dev); + /** * uclass_post_probe_device() - Deal with a device that has just been probed * diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 5c5b8f4208..d6c40c60dd 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -83,6 +83,7 @@ struct uclass_driver { int (*post_probe)(struct udevice *dev); int (*pre_remove)(struct udevice *dev); int (*child_post_bind)(struct udevice *dev); + int (*child_pre_probe)(struct udevice *dev); int (*init)(struct uclass *class); int (*destroy)(struct uclass *class); int priv_auto_alloc_size; diff --git a/test/dm/bus.c b/test/dm/bus.c index c123ed7931..faffe6a385 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -53,6 +53,15 @@ static int testbus_child_pre_probe(struct udevice *dev) return 0; } +static int testbus_child_pre_probe_uclass(struct udevice *dev) +{ + struct dm_test_priv *priv = dev_get_priv(dev); + + priv->uclass_flag++; + + return 0; +} + static int testbus_child_post_remove(struct udevice *dev) { struct dm_test_parent_data *parent_data = dev_get_parentdata(dev); @@ -91,6 +100,7 @@ UCLASS_DRIVER(testbus) = { .name = "testbus", .id = UCLASS_TEST_BUS, .flags = DM_UC_FLAG_SEQ_ALIAS, + .child_pre_probe = testbus_child_pre_probe_uclass, }; /* Test that we can probe for children */ @@ -469,3 +479,39 @@ static int dm_test_bus_child_post_bind_uclass(struct dm_test_state *dms) } DM_TEST(dm_test_bus_child_post_bind_uclass, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* + * Test that the bus' uclass' child_pre_probe() is called before the + * device's probe() method + */ +static int dm_test_bus_child_pre_probe_uclass(struct dm_test_state *dms) +{ + struct udevice *bus, *dev; + int child_count; + + /* + * See testfdt_drv_probe() which effectively checks that the uclass + * flag is set before that method is called + */ + ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); + for (device_find_first_child(bus, &dev), child_count = 0; + dev; + device_find_next_child(&dev)) { + struct dm_test_priv *priv = dev_get_priv(dev); + + /* Check that things happened in the right order */ + ut_asserteq_ptr(NULL, priv); + ut_assertok(device_probe(dev)); + + priv = dev_get_priv(dev); + ut_assert(priv != NULL); + ut_asserteq(1, priv->uclass_flag); + ut_asserteq(1, priv->uclass_total); + child_count++; + } + ut_asserteq(3, child_count); + + return 0; +} +DM_TEST(dm_test_bus_child_pre_probe_uclass, + DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index dfcb3af61b..b8ee9599a2 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -51,6 +51,13 @@ static int testfdt_drv_probe(struct udevice *dev) priv->ping_total += DM_TEST_START_TOTAL; + /* + * If this device is on a bus, the uclass_flag will be set before + * calling this function. This is used by + * dm_test_bus_child_pre_probe_uclass(). + */ + priv->uclass_total += priv->uclass_flag; + return 0; } -- cgit From 440714eeb8938e9710d1b2bba17c6c0af7c2cf69 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:11 -0700 Subject: dm: spi: Set up the spi_slave device pointer in child_pre_probe() At present we use struct spi_slave as our device pointer in a lot of places to avoid changing the old SPI API. At some point this will go away. But for now, it is better if the SPI uclass sets up this pointer, rather than relying on passing it into the device when it is probed. We can use the new uclass child_pre_probe() method to do this. Signed-off-by: Simon Glass --- drivers/spi/spi-uclass.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index e5dfb300fa..2c134eb39f 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -108,6 +108,15 @@ int spi_post_probe(struct udevice *dev) return 0; } +int spi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parentdata(dev); + + slave->dev = dev; + + return 0; +} + int spi_chip_select(struct udevice *dev) { struct spi_slave *slave = dev_get_parentdata(dev); @@ -347,6 +356,7 @@ UCLASS_DRIVER(spi) = { .flags = DM_UC_FLAG_SEQ_ALIAS, .post_bind = spi_post_bind, .post_probe = spi_post_probe, + .child_pre_probe = spi_child_pre_probe, .per_device_auto_alloc_size = sizeof(struct dm_spi_bus), .per_child_auto_alloc_size = sizeof(struct spi_slave), }; -- cgit From d0cff03e187cc1de3d6b477b92c376aae27c95e8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:12 -0700 Subject: dm: spi: Move slave details to child platdata At present we go through various contortions to store the SPI slave's chip select in its private data. This only exists when the slave is active so must be set up when it is probed. Until the device is probed we don't actually know what chip select it will appear on. However, now that we can support per-child platform data, we can use that instead. This allows us to set up the chip select when the child is bound, and avoid the messy contortions. Unfortunately this is a fairly large change and it seems to be difficult to break it down further. Signed-off-by: Simon Glass --- drivers/misc/cros_ec_spi.c | 19 ----------- drivers/mtd/spi/sandbox.c | 5 +++ drivers/mtd/spi/sf_probe.c | 3 +- drivers/spi/soft_spi.c | 9 ----- drivers/spi/spi-uclass.c | 83 +++++++++++++++++++++++++++------------------- include/spi.h | 42 +++++++++++++++++------ test/dm/spi.c | 6 ++-- 7 files changed, 91 insertions(+), 76 deletions(-) diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c index e6dba298b1..25a5a0468e 100644 --- a/drivers/misc/cros_ec_spi.c +++ b/drivers/misc/cros_ec_spi.c @@ -202,25 +202,6 @@ int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob) #ifdef CONFIG_DM_CROS_EC int cros_ec_probe(struct udevice *dev) { - struct spi_slave *slave = dev_get_parentdata(dev); - int ret; - - /* - * TODO(sjg@chromium.org) - * - * This is really horrible at present. It is an artifact of removing - * the child_pre_probe() method for SPI. Everything here could go in - * an automatic function, except that spi_get_bus_and_cs() wants to - * set it up manually and call device_probe_child(). - * - * The solution may be to re-enable the child_pre_probe() method for - * SPI and have it do nothing if the child is already passed in via - * device_probe_child(). - */ - slave->dev = dev; - ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave); - if (ret) - return ret; return cros_ec_register(dev); } diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 106dda9ccc..d576d31243 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -590,6 +590,11 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs, void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs) { + struct udevice *dev; + + dev = state->spi[busnum][cs].emul; + device_remove(dev); + device_unbind(dev); state->spi[busnum][cs].emul = NULL; } diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index ce9987fd1a..4103723859 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -481,11 +481,12 @@ int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parentdata(dev); + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_flash *flash; flash = dev->uclass_priv; flash->dev = dev; - debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs); + debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs); return spi_flash_probe_slave(slave, flash); } diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 9f7d80ee4d..6ae45f5377 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -179,14 +179,6 @@ static int soft_spi_set_mode(struct udevice *dev, unsigned int mode) return 0; } -static int soft_spi_child_pre_probe(struct udevice *dev) -{ - struct spi_slave *slave = dev_get_parentdata(dev); - - slave->dev = dev; - return spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave); -} - static const struct dm_spi_ops soft_spi_ops = { .claim_bus = soft_spi_claim_bus, .release_bus = soft_spi_release_bus, @@ -241,5 +233,4 @@ U_BOOT_DRIVER(soft_spi) = { .platdata_auto_alloc_size = sizeof(struct soft_spi_platdata), .priv_auto_alloc_size = sizeof(struct soft_spi_priv), .probe = soft_spi_probe, - .child_pre_probe = soft_spi_child_pre_probe, }; diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 2c134eb39f..63a6217cc6 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -98,11 +98,21 @@ int spi_post_bind(struct udevice *dev) return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); } -int spi_post_probe(struct udevice *dev) +int spi_child_post_bind(struct udevice *dev) { - struct dm_spi_bus *spi = dev->uclass_priv; + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); - spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + if (dev->of_offset == -1) + return 0; + + return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat); +} + +int spi_post_probe(struct udevice *bus) +{ + struct dm_spi_bus *spi = bus->uclass_priv; + + spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset, "spi-max-frequency", 0); return 0; @@ -110,18 +120,29 @@ int spi_post_probe(struct udevice *dev) int spi_child_pre_probe(struct udevice *dev) { + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); struct spi_slave *slave = dev_get_parentdata(dev); + /* + * This is needed because we pass struct spi_slave around the place + * instead slave->dev (a struct udevice). So we have to have some + * way to access the slave udevice given struct spi_slave. Once we + * change the SPI API to use udevice instead of spi_slave, we can + * drop this. + */ slave->dev = dev; + slave->max_hz = plat->max_hz; + slave->mode = plat->mode; + return 0; } int spi_chip_select(struct udevice *dev) { - struct spi_slave *slave = dev_get_parentdata(dev); + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); - return slave ? slave->cs : -ENOENT; + return plat ? plat->cs : -ENOENT; } int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) @@ -130,17 +151,11 @@ int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev)) { - struct spi_slave store; - struct spi_slave *slave = dev_get_parentdata(dev); + struct dm_spi_slave_platdata *plat; - if (!slave) { - slave = &store; - spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - slave); - } - debug("%s: slave=%p, cs=%d\n", __func__, slave, - slave ? slave->cs : -1); - if (slave && slave->cs == cs) { + plat = dev_get_parent_platdata(dev); + debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs); + if (plat->cs == cs) { *devp = dev; return 0; } @@ -224,7 +239,6 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, struct udevice **busp, struct spi_slave **devp) { struct udevice *bus, *dev; - struct spi_slave *slave; bool created = false; int ret; @@ -241,11 +255,17 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, * SPI flash chip - we will bind to the correct driver. */ if (ret == -ENODEV && drv_name) { + struct dm_spi_slave_platdata *plat; + debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", __func__, dev_name, busnum, cs, drv_name); ret = device_bind_driver(bus, drv_name, dev_name, &dev); if (ret) return ret; + plat = dev_get_parent_platdata(dev); + plat->cs = cs; + plat->max_hz = speed; + plat->mode = mode; created = true; } else if (ret) { printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs, @@ -254,23 +274,13 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, } if (!device_active(dev)) { - slave = (struct spi_slave *)calloc(1, - sizeof(struct spi_slave)); - if (!slave) { - ret = -ENOMEM; - goto err; - } + struct spi_slave *slave; - ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - slave); + ret = device_probe(dev); if (ret) goto err; - slave->cs = cs; + slave = dev_get_parentdata(dev); slave->dev = dev; - ret = device_probe_child(dev, slave); - free(slave); - if (ret) - goto err; } ret = spi_set_speed_mode(bus, speed, mode); @@ -284,6 +294,8 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, return 0; err: + debug("%s: Error path, credted=%d, device '%s'\n", __func__, + created, dev->name); if (created) { device_remove(dev); device_unbind(dev); @@ -330,13 +342,13 @@ void spi_free_slave(struct spi_slave *slave) slave->dev = NULL; } -int spi_ofdata_to_platdata(const void *blob, int node, - struct spi_slave *spi) +int spi_slave_ofdata_to_platdata(const void *blob, int node, + struct dm_spi_slave_platdata *plat) { int mode = 0; - spi->cs = fdtdec_get_int(blob, node, "reg", -1); - spi->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0); + plat->cs = fdtdec_get_int(blob, node, "reg", -1); + plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0); if (fdtdec_get_bool(blob, node, "spi-cpol")) mode |= SPI_CPOL; if (fdtdec_get_bool(blob, node, "spi-cpha")) @@ -345,7 +357,7 @@ int spi_ofdata_to_platdata(const void *blob, int node, mode |= SPI_CS_HIGH; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; - spi->mode = mode; + plat->mode = mode; return 0; } @@ -359,6 +371,9 @@ UCLASS_DRIVER(spi) = { .child_pre_probe = spi_child_pre_probe, .per_device_auto_alloc_size = sizeof(struct dm_spi_bus), .per_child_auto_alloc_size = sizeof(struct spi_slave), + .per_child_platdata_auto_alloc_size = + sizeof(struct dm_spi_slave_platdata), + .child_post_bind = spi_child_post_bind, }; UCLASS_DRIVER(spi_generic) = { diff --git a/include/spi.h b/include/spi.h index ec17bd0bcc..c58e453559 100644 --- a/include/spi.h +++ b/include/spi.h @@ -56,20 +56,42 @@ #define SPI_DEFAULT_WORDLEN 8 #ifdef CONFIG_DM_SPI +/* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */ struct dm_spi_bus { uint max_hz; }; +/** + * struct dm_spi_platdata - platform data for all SPI slaves + * + * This describes a SPI slave, a child device of the SPI bus. To obtain this + * struct from a spi_slave, use dev_get_parent_platdata(dev) or + * dev_get_parent_platdata(slave->dev). + * + * This data is immuatable. Each time the device is probed, @max_hz and @mode + * will be copied to struct spi_slave. + * + * @cs: Chip select number (0..n-1) + * @max_hz: Maximum bus speed that this slave can tolerate + * @mode: SPI mode to use for this device (see SPI mode flags) + */ +struct dm_spi_slave_platdata { + unsigned int cs; + uint max_hz; + uint mode; +}; + #endif /* CONFIG_DM_SPI */ /** * struct spi_slave - Representation of a SPI slave * * For driver model this is the per-child data used by the SPI bus. It can - * be accessed using dev_get_parentdata() on the slave device. Each SPI - * driver should define this child data in its U_BOOT_DRIVER() definition: - * - * .per_child_auto_alloc_size = sizeof(struct spi_slave), + * be accessed using dev_get_parentdata() on the slave device. The SPI uclass + * sets uip per_child_auto_alloc_size to sizeof(struct spi_slave), and the + * driver should not override it. Two platform data fields (max_hz and mode) + * are copied into this structure to provide an initial value. This allows + * them to be changed, since we should never change platform data in drivers. * * If not using driver model, drivers are expected to extend this with * controller-specific data. @@ -97,8 +119,8 @@ struct spi_slave { uint mode; #else unsigned int bus; -#endif unsigned int cs; +#endif u8 op_mode_rx; u8 op_mode_tx; unsigned int wordlen; @@ -545,16 +567,16 @@ int spi_chip_select(struct udevice *slave); int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp); /** - * spi_ofdata_to_platdata() - decode standard SPI platform data + * spi_slave_ofdata_to_platdata() - decode standard SPI platform data * - * This decodes the speed and mode from a device tree node and puts it into - * the spi_slave structure. + * This decodes the speed and mode for a slave from a device tree node * * @blob: Device tree blob * @node: Node offset to read from - * @spi: Place to put the decoded information + * @plat: Place to put the decoded information */ -int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi); +int spi_slave_ofdata_to_platdata(const void *blob, int node, + struct dm_spi_slave_platdata *plat); /** * spi_cs_info() - Check information on a chip select diff --git a/test/dm/spi.c b/test/dm/spi.c index 61b5b2548c..c7ee65207b 100644 --- a/test/dm/spi.c +++ b/test/dm/spi.c @@ -36,7 +36,6 @@ static int dm_test_spi_find(struct dm_test_state *dms) ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus)); ut_assertok(spi_cs_info(bus, cs, &info)); of_offset = info.dev->of_offset; - sandbox_sf_unbind_emul(state_get_current(), busnum, cs); device_remove(info.dev); device_unbind(info.dev); @@ -45,7 +44,7 @@ static int dm_test_spi_find(struct dm_test_state *dms) * reports that CS 0 is present */ ut_assertok(spi_cs_info(bus, cs, &info)); - ut_asserteq_ptr(info.dev, NULL); + ut_asserteq_ptr(NULL, info.dev); /* This finds nothing because we removed the device */ ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev)); @@ -62,8 +61,9 @@ static int dm_test_spi_find(struct dm_test_state *dms) ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode, "spi_flash_std", "name", &bus, &slave)); + sandbox_sf_unbind_emul(state_get_current(), busnum, cs); ut_assertok(spi_cs_info(bus, cs, &info)); - ut_asserteq_ptr(info.dev, NULL); + ut_asserteq_ptr(NULL, info.dev); /* Add the emulation and try again */ ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset, -- cgit From e6f66ec0e757b49d39885303a94784a342803dd2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:13 -0700 Subject: dm: i2c: Move slave details to child platdata At present we go through various contortions to store the I2C's chip address in its private data. This only exists when the chip is active so must be set up when it is probed. Until the device is probed we don't actually record what address it will appear on. However, now that we can support per-child platform data, we can use that instead. This allows us to set up the address when the child is bound, and avoid the messy contortions. Unfortunately this is a fairly large change and it seems to be difficult to break it down further. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/i2c/i2c-uclass-compat.c | 2 +- drivers/i2c/i2c-uclass.c | 54 ++++++++++++++++++++++++----------------- drivers/i2c/i2c-uniphier-f.c | 12 --------- drivers/i2c/i2c-uniphier.c | 12 --------- drivers/i2c/sandbox_i2c.c | 28 +++++---------------- drivers/i2c/tegra_i2c.c | 18 -------------- include/i2c.h | 4 +-- 7 files changed, 41 insertions(+), 89 deletions(-) diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index c29fc89e04..11239da2b9 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -20,7 +20,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); if (ret) return ret; - chip = dev_get_parentdata(*devp); + chip = dev_get_parent_platdata(*devp); if (chip->offset_len != alen) { printf("Requested alen %d does not match chip offset_len %d\n", alen, chip->offset_len); diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 94b49dfe52..393cd6f583 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -50,7 +50,7 @@ static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset, static int i2c_read_bytewise(struct udevice *dev, uint offset, uint8_t *buffer, int len) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[2], *ptr; @@ -79,7 +79,7 @@ static int i2c_read_bytewise(struct udevice *dev, uint offset, static int i2c_write_bytewise(struct udevice *dev, uint offset, const uint8_t *buffer, int len) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[1]; @@ -102,7 +102,7 @@ static int i2c_write_bytewise(struct udevice *dev, uint offset, int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[2], *ptr; @@ -133,7 +133,7 @@ int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct udevice *bus = dev_get_parent(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); struct i2c_msg msg[1]; @@ -223,7 +223,7 @@ static int i2c_probe_chip(struct udevice *bus, uint chip_addr, static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len, struct udevice **devp) { - struct dm_i2c_chip chip; + struct dm_i2c_chip *chip; char name[30], *str; struct udevice *dev; int ret; @@ -236,11 +236,11 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len, goto err_bind; /* Tell the device what we know about it */ - memset(&chip, '\0', sizeof(chip)); - chip.chip_addr = chip_addr; - chip.offset_len = offset_len; - ret = device_probe_child(dev, &chip); - debug("%s: device_probe_child: ret=%d\n", __func__, ret); + chip = dev_get_parent_platdata(dev); + chip->chip_addr = chip_addr; + chip->offset_len = offset_len; + ret = device_probe(dev); + debug("%s: device_probe: ret=%d\n", __func__, ret); if (ret) goto err_probe; @@ -248,6 +248,10 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len, return 0; err_probe: + /* + * If the device failed to probe, unbind it. There is nothing there + * on the bus so we don't want to leave it lying around + */ device_unbind(dev); err_bind: free(str); @@ -263,15 +267,9 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len, bus->name, chip_addr); for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev)) { - struct dm_i2c_chip store; - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); int ret; - if (!chip) { - chip = &store; - i2c_chip_ofdata_to_platdata(gd->fdt_blob, - dev->of_offset, chip); - } if (chip->chip_addr == chip_addr) { ret = device_probe(dev); debug("found, ret=%d\n", ret); @@ -367,7 +365,7 @@ int i2c_get_bus_speed(struct udevice *bus) int i2c_set_chip_flags(struct udevice *dev, uint flags) { struct udevice *bus = dev->parent; - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); struct dm_i2c_ops *ops = i2c_get_ops(bus); int ret; @@ -383,7 +381,7 @@ int i2c_set_chip_flags(struct udevice *dev, uint flags) int i2c_get_chip_flags(struct udevice *dev, uint *flagsp) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); *flagsp = chip->flags; @@ -392,7 +390,7 @@ int i2c_get_chip_flags(struct udevice *dev, uint *flagsp) int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len) { - struct dm_i2c_chip *chip = dev_get_parentdata(dev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); if (offset_len > I2C_MAX_OFFSET_LEN) return -EINVAL; @@ -444,19 +442,31 @@ static int i2c_post_probe(struct udevice *dev) return i2c_set_bus_speed(dev, i2c->speed_hz); } -int i2c_post_bind(struct udevice *dev) +static int i2c_post_bind(struct udevice *dev) { /* Scan the bus for devices */ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); } +static int i2c_child_post_bind(struct udevice *dev) +{ + struct dm_i2c_chip *plat = dev_get_parent_platdata(dev); + + if (dev->of_offset == -1) + return 0; + + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat); +} + UCLASS_DRIVER(i2c) = { .id = UCLASS_I2C, .name = "i2c", .flags = DM_UC_FLAG_SEQ_ALIAS, - .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), .post_bind = i2c_post_bind, .post_probe = i2c_post_probe, + .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), + .per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip), + .child_post_bind = i2c_child_post_bind, }; UCLASS_DRIVER(i2c_generic) = { diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c index b0d30f76c6..6707edd9ef 100644 --- a/drivers/i2c/i2c-uniphier-f.c +++ b/drivers/i2c/i2c-uniphier-f.c @@ -145,16 +145,6 @@ static int uniphier_fi2c_remove(struct udevice *dev) return 0; } -static int uniphier_fi2c_child_pre_probe(struct udevice *dev) -{ - struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); - - if (dev->of_offset == -1) - return 0; - return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - i2c_chip); -} - static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags, bool *stop) { @@ -372,8 +362,6 @@ U_BOOT_DRIVER(uniphier_fi2c) = { .of_match = uniphier_fi2c_of_match, .probe = uniphier_fi2c_probe, .remove = uniphier_fi2c_remove, - .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), - .child_pre_probe = uniphier_fi2c_child_pre_probe, .priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev), .ops = &uniphier_fi2c_ops, }; diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c index bdac1f9079..64a9ed81d2 100644 --- a/drivers/i2c/i2c-uniphier.c +++ b/drivers/i2c/i2c-uniphier.c @@ -75,16 +75,6 @@ static int uniphier_i2c_remove(struct udevice *dev) return 0; } -static int uniphier_i2c_child_pre_probe(struct udevice *dev) -{ - struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); - - if (dev->of_offset == -1) - return 0; - return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - i2c_chip); -} - static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm) { writel(dtrm, &dev->regs->dtrm); @@ -232,8 +222,6 @@ U_BOOT_DRIVER(uniphier_i2c) = { .of_match = uniphier_i2c_of_match, .probe = uniphier_i2c_probe, .remove = uniphier_i2c_remove, - .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), - .child_pre_probe = uniphier_i2c_child_pre_probe, .priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev), .ops = &uniphier_i2c_ops, }; diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index e2f6c3b9bb..a943aa6382 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -25,24 +25,24 @@ struct dm_sandbox_i2c_emul_priv { static int get_emul(struct udevice *dev, struct udevice **devp, struct dm_i2c_ops **opsp) { - struct dm_i2c_chip *priv; + struct dm_i2c_chip *plat; int ret; *devp = NULL; *opsp = NULL; - priv = dev_get_parentdata(dev); - if (!priv->emul) { + plat = dev_get_parent_platdata(dev); + if (!plat->emul) { ret = dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); if (ret) return ret; - ret = device_get_child(dev, 0, &priv->emul); + ret = device_get_child(dev, 0, &plat->emul); if (ret) return ret; } - *devp = priv->emul; - *opsp = i2c_get_ops(priv->emul); + *devp = plat->emul; + *opsp = i2c_get_ops(plat->emul); return 0; } @@ -82,20 +82,6 @@ static const struct dm_i2c_ops sandbox_i2c_ops = { .xfer = sandbox_i2c_xfer, }; -static int sandbox_i2c_child_pre_probe(struct udevice *dev) -{ - struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); - - /* Ignore our test address */ - if (i2c_chip->chip_addr == SANDBOX_I2C_TEST_ADDR) - return 0; - if (dev->of_offset == -1) - return 0; - - return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - i2c_chip); -} - static const struct udevice_id sandbox_i2c_ids[] = { { .compatible = "sandbox,i2c" }, { } @@ -105,7 +91,5 @@ U_BOOT_DRIVER(i2c_sandbox) = { .name = "i2c_sandbox", .id = UCLASS_I2C, .of_match = sandbox_i2c_ids, - .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), - .child_pre_probe = sandbox_i2c_child_pre_probe, .ops = &sandbox_i2c_ops, }; diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index 87290c3127..f4142870b3 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -484,21 +484,6 @@ static const struct dm_i2c_ops tegra_i2c_ops = { .set_bus_speed = tegra_i2c_set_bus_speed, }; -static int tegra_i2c_child_pre_probe(struct udevice *dev) -{ - struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev); - - if (dev->of_offset == -1) - return 0; - return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, - i2c_chip); -} - -static int tegra_i2c_ofdata_to_platdata(struct udevice *dev) -{ - return 0; -} - static const struct udevice_id tegra_i2c_ids[] = { { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, { .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD }, @@ -510,10 +495,7 @@ U_BOOT_DRIVER(i2c_tegra) = { .name = "i2c_tegra", .id = UCLASS_I2C, .of_match = tegra_i2c_ids, - .ofdata_to_platdata = tegra_i2c_ofdata_to_platdata, .probe = tegra_i2c_probe, - .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), - .child_pre_probe = tegra_i2c_child_pre_probe, .priv_auto_alloc_size = sizeof(struct i2c_bus), .ops = &tegra_i2c_ops, }; diff --git a/include/i2c.h b/include/i2c.h index 76090b7a93..95d6f28771 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -39,8 +39,8 @@ enum dm_i2c_chip_flags { * An I2C chip is a device on the I2C bus. It sits at a particular address * and normally supports 7-bit or 10-bit addressing. * - * To obtain this structure, use dev_get_parentdata(dev) where dev is the - * chip to examine. + * To obtain this structure, use dev_get_parent_platdata(dev) where dev is + * the chip to examine. * * @chip_addr: Chip address on bus * @offset_len: Length of offset in bytes. A single byte offset can -- cgit From dedff1a0007525b16737328ca714cd4330100618 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:14 -0700 Subject: dm: tegra: Drop unused COMPAT features for I2C, SPI These have moved to driver model so we don't need the fdtdec support. Signed-off-by: Simon Glass --- include/fdtdec.h | 6 ------ lib/fdtdec.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/include/fdtdec.h b/include/fdtdec.h index b02f1edb1d..965c5bae87 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -115,9 +115,6 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA20_USB, /* Tegra20 USB port */ COMPAT_NVIDIA_TEGRA30_USB, /* Tegra30 USB port */ COMPAT_NVIDIA_TEGRA114_USB, /* Tegra114 USB port */ - COMPAT_NVIDIA_TEGRA114_I2C, /* Tegra114 I2C w/single clock source */ - COMPAT_NVIDIA_TEGRA20_I2C, /* Tegra20 i2c */ - COMPAT_NVIDIA_TEGRA20_DVC, /* Tegra20 dvc (really just i2c) */ COMPAT_NVIDIA_TEGRA20_EMC, /* Tegra20 memory controller */ COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */ COMPAT_NVIDIA_TEGRA20_KBC, /* Tegra20 Keyboard */ @@ -127,9 +124,6 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA124_SDMMC, /* Tegra124 SDMMC controller */ COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */ COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */ - COMPAT_NVIDIA_TEGRA20_SFLASH, /* Tegra 2 SPI flash controller */ - COMPAT_NVIDIA_TEGRA20_SLINK, /* Tegra 2 SPI SLINK controller */ - COMPAT_NVIDIA_TEGRA114_SPI, /* Tegra 114 SPI controller */ COMPAT_NVIDIA_TEGRA124_PCIE, /* Tegra 124 PCIe controller */ COMPAT_NVIDIA_TEGRA30_PCIE, /* Tegra 30 PCIe controller */ COMPAT_NVIDIA_TEGRA20_PCIE, /* Tegra 20 PCIe controller */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 3cfa50a6d5..21c263690b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -24,9 +24,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"), COMPAT(NVIDIA_TEGRA30_USB, "nvidia,tegra30-ehci"), COMPAT(NVIDIA_TEGRA114_USB, "nvidia,tegra114-ehci"), - COMPAT(NVIDIA_TEGRA114_I2C, "nvidia,tegra114-i2c"), - COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"), - COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"), COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"), COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"), COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"), @@ -36,9 +33,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"), COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"), COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"), - COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"), - COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"), - COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"), COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"), COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"), COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"), -- cgit From b9749eb5e4660fa6ec85c9a16acdbf3dd6609046 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:15 -0700 Subject: dm: exynos: Drop unused COMPAT features for SPI This has moved to driver model so we don't need the fdtdec support. Signed-off-by: Simon Glass Acked-by: Minkyu Kang --- include/fdtdec.h | 1 - lib/fdtdec.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/fdtdec.h b/include/fdtdec.h index 965c5bae87..231eed7892 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -134,7 +134,6 @@ enum fdt_compat_id { COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */ COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */ - COMPAT_SAMSUNG_EXYNOS_SPI, /* Exynos SPI */ COMPAT_GOOGLE_CROS_EC, /* Google CROS_EC Protocol */ COMPAT_GOOGLE_CROS_EC_KEYB, /* Google CROS_EC Keyboard */ COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 21c263690b..5bf8f29b13 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -42,7 +42,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), - COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"), COMPAT(GOOGLE_CROS_EC, "google,cros-ec"), COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"), COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), -- cgit From 94f7afdf7e9909204d0005196db47cca2a28e4cb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:16 -0700 Subject: dm: core: Ignore disabled devices when binding We don't want to bind devices which should never be used. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/core/root.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/core/root.c b/drivers/core/root.c index a5b0a61501..73e3c7228e 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -92,6 +93,10 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, if (pre_reloc_only && !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) continue; + if (!fdtdec_get_is_enabled(blob, offset)) { + dm_dbg(" - ignoring disabled device\n"); + continue; + } err = lists_bind_fdt(parent, blob, offset, NULL); if (err && !ret) ret = err; -- cgit From 8bbb38b15fd585a9d51f8ee064ce17e535d8025e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:17 -0700 Subject: dm: cros_ec: Don't require protocol 3 support I2C is now deprecated on ARM platforms and there are no devices that use it with the v3 protocol. We can't require v3 support if we want to support I2C. Adjust the error handling to suit. Signed-off-by: Simon Glass --- drivers/misc/cros_ec.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 7b20ffcfa2..5846e76c49 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -154,7 +154,9 @@ static int prepare_proto3_response_buffer(struct cros_ec_dev *dev, int din_len) * @param dev CROS-EC device * @param dinp Returns pointer to response data * @param din_len Maximum size of response in bytes - * @return number of bytes of response data, or <0 if error + * @return number of bytes of response data, or <0 if error. Note that error + * codes can be from errno.h or -ve EC_RES_INVALID_CHECKSUM values (and they + * overlap!) */ static int handle_proto3_response(struct cros_ec_dev *dev, uint8_t **dinp, int din_len) @@ -228,7 +230,7 @@ static int send_command_proto3(struct cros_ec_dev *dev, #ifdef CONFIG_DM_CROS_EC ops = dm_cros_ec_get_ops(dev->dev); - rv = ops->packet(dev->dev, out_bytes, in_bytes); + rv = ops->packet ? ops->packet(dev->dev, out_bytes, in_bytes) : -ENOSYS; #else switch (dev->interface) { #ifdef CONFIG_CROS_EC_SPI @@ -320,7 +322,7 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, * If not NULL, it will be updated to point to the data * and will always be double word aligned (64-bits) * @param din_len Maximum size of response in bytes - * @return number of bytes in response, or -1 on error + * @return number of bytes in response, or -ve on error */ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, const void *dout, int dout_len, uint8_t **dinp, @@ -387,7 +389,7 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, * It not NULL, it is a place for ec_command() to copy the * data to. * @param din_len Maximum size of response in bytes - * @return number of bytes in response, or -1 on error + * @return number of bytes in response, or -ve on error */ static int ec_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, const void *dout, int dout_len, -- cgit From b2568f0d57e45bfc9a87f94030a8bf61f6c479a1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:19 -0700 Subject: dm: cros_ec_spi: Remove old pre-driver-model code This is no-longer needed since all platforms use SPI for cros_ec. Signed-off-by: Simon Glass --- drivers/misc/cros_ec_spi.c | 51 ++-------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c index 25a5a0468e..9359c56e87 100644 --- a/drivers/misc/cros_ec_spi.c +++ b/drivers/misc/cros_ec_spi.c @@ -21,14 +21,9 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_DM_CROS_EC int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes) { struct cros_ec_dev *dev = udev->uclass_priv; -#else -int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes) -{ -#endif struct spi_slave *slave = dev_get_parentdata(dev->dev); int rv; @@ -67,18 +62,11 @@ int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes) * @param din_len Maximum size of response in bytes * @return number of bytes in response, or -1 on error */ -#ifdef CONFIG_DM_CROS_EC int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { struct cros_ec_dev *dev = udev->uclass_priv; -#else -int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len) -{ -#endif struct spi_slave *slave = dev_get_parentdata(dev->dev); int in_bytes = din_len + 4; /* status, length, checksum, trailer */ uint8_t *out; @@ -166,46 +154,12 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, return len; } -#ifndef CONFIG_DM_CROS_EC -int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob) -{ - /* Decode interface-specific FDT params */ - dev->max_frequency = fdtdec_get_int(blob, dev->node, - "spi-max-frequency", 500000); - dev->cs = fdtdec_get_int(blob, dev->node, "reg", 0); - - return 0; -} - -/** - * Initialize SPI protocol. - * - * @param dev CROS_EC device - * @param blob Device tree blob - * @return 0 if ok, -1 on error - */ -int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob) -{ - int ret; - - ret = spi_setup_slave_fdt(blob, dev->node, dev->parent_node, - &slave); - if (ret) { - debug("%s: Could not setup SPI slave\n", __func__); - return ret; - } - - return 0; -} -#endif - -#ifdef CONFIG_DM_CROS_EC -int cros_ec_probe(struct udevice *dev) +static int cros_ec_probe(struct udevice *dev) { return cros_ec_register(dev); } -struct dm_cros_ec_ops cros_ec_ops = { +static struct dm_cros_ec_ops cros_ec_ops = { .packet = cros_ec_spi_packet, .command = cros_ec_spi_command, }; @@ -222,4 +176,3 @@ U_BOOT_DRIVER(cros_ec_spi) = { .probe = cros_ec_probe, .ops = &cros_ec_ops, }; -#endif -- cgit From 2017aaef8c383c910e791bf0f87fa4d6b78f5945 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:20 -0700 Subject: dm: Update documentation for new bus features Now that we have new bus features, update README.txt and the SPI docs to explain these. Signed-off-by: Simon Glass --- doc/driver-model/README.txt | 36 ++++++++++++++++++++++++++---------- doc/driver-model/spi-howto.txt | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index 0c1292bf12..f83264d615 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -441,11 +441,18 @@ access to other devices. Example of buses include SPI and I2C. Typically the bus provides some sort of transport or translation that makes it possible to talk to the devices on the bus. -Driver model provides a few useful features to help with implementing -buses. Firstly, a bus can request that its children store some 'parent -data' which can be used to keep track of child state. Secondly, the bus can -define methods which are called when a child is probed or removed. This is -similar to the methods the uclass driver provides. +Driver model provides some useful features to help with implementing buses. +Firstly, a bus can request that its children store some 'parent data' which +can be used to keep track of child state. Secondly, the bus can define +methods which are called when a child is probed or removed. This is similar +to the methods the uclass driver provides. Thirdly, per-child platform data +can be provided to specify things like the child's address on the bus. This +persists across child probe()/remove() cycles. + +For consistency and ease of implementation, the bus uclass can specify the +per-child platform data, so that it can be the same for all children of buses +in that uclass. There are also uclass methods which can be called when +children are bound and probed. Here an explanation of how a bus fits with a uclass may be useful. Consider a USB bus with several devices attached to it, each from a different (made @@ -460,15 +467,23 @@ Each of the devices is connected to a different address on the USB bus. The bus device wants to store this address and some other information such as the bus speed for each device. -To achieve this, the bus device can use dev->parent_priv in each of its -three children. This can be auto-allocated if the bus driver has a non-zero -value for per_child_auto_alloc_size. If not, then the bus device can -allocate the space itself before the child device is probed. +To achieve this, the bus device can use dev->parent_platdata in each of its +three children. This can be auto-allocated if the bus driver (or bus uclass) +has a non-zero value for per_child_platdata_auto_alloc_size. If not, then +the bus device or uclass can allocate the space itself before the child +device is probed. Also the bus driver can define the child_pre_probe() and child_post_remove() methods to allow it to do some processing before the child is activated or after it is deactivated. +Similarly the bus uclass can define the child_post_bind() method to obtain +the per-child platform data from the device tree and set it up for the child. +The bus uclass can also provide a child_pre_probe() method. Very often it is +the bus uclass that controls these features, since it avoids each driver +having to do the same processing. Of course the driver can still tweak and +override these activities. + Note that the information that controls this behaviour is in the bus's driver, not the child's. In fact it is possible that child has no knowledge that it is connected to a bus. The same child device may even be used on two @@ -495,7 +510,8 @@ bus device, regardless of its own views on the matter. The uclass for the device can also contain data private to that uclass. But note that each device on the bus may be a memeber of a different uclass, and this data has nothing to do with the child data for each child -on the bus. +on the bus. It is the bus' uclass that controls the child with respect to +the bus. Driver Lifecycle diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt index 719dbd5cdd..5bc29ad65c 100644 --- a/doc/driver-model/spi-howto.txt +++ b/doc/driver-model/spi-howto.txt @@ -3,7 +3,8 @@ How to port a SPI driver to driver model Here is a rough step-by-step guide. It is based around converting the exynos SPI driver to driver model (DM) and the example code is based -around U-Boot v2014.10-rc2 (commit be9f643). +around U-Boot v2014.10-rc2 (commit be9f643). This has been updated for +v2015.04. It is quite long since it includes actual code examples. @@ -262,8 +263,8 @@ U_BOOT_DEVICE(board_spi0) = { .platdata = &platdata_spi0, }; -You will unfortunately need to put the struct into a header file in this -case so that your board file can use it. +You will unfortunately need to put the struct definition into a header file +in this case so that your board file can use it. 9. Add the device private data @@ -592,3 +593,36 @@ board. You can use 'tools/patman/patman' to prepare, check and send patches for your work. See the README for details. + +20. A little note about SPI uclass features: + +The SPI uclass keeps some information about each device 'dev' on the bus: + + struct dm_spi_slave_platdata - this is device_get_parent_platdata(dev) + This is where the chip select number is stored, along with + the default bus speed and mode. It is automatically read + from the device tree in spi_child_post_bind(). It must not + be changed at run-time after being set up because platform + data is supposed to be immutable at run-time. + struct spi_slave - this is device_get_parentdata(dev) + Already mentioned above. It holds run-time information about + the device. + +There are also some SPI uclass methods that get called behind the scenes: + + spi_post_bind() - called when a new bus is bound + This scans the device tree for devices on the bus, and binds + each one. This in turn causes spi_child_post_bind() to be + called for each, which reads the device tree information + into the parent (per-child) platform data. + spi_child_post_bind() - called when a new child is bound + As mentioned above this reads the device tree information + into the per-child platform data + spi_child_pre_probe() - called before a new child is probed + This sets up the mode and speed in struct spi_slave by + copying it from the parent's platform data for this child. + It also sets the 'dev' pointer, needed to permit passing + 'struct spi_slave' around the place without needing a + separate 'struct udevice' pointer. + +The above housekeeping makes it easier to write your SPI driver. -- cgit From 49cad54788a64a296567abadcd736fdbe47cc3a3 Mon Sep 17 00:00:00 2001 From: Martin Dorwig Date: Mon, 26 Jan 2015 15:22:54 -0700 Subject: Export redesign this is an atempt to make the export of functions typesafe. I replaced the jumptable void ** by a struct (jt_funcs) with function pointers. The EXPORT_FUNC macro now has 3 fixed parameters and one variadic parameter The first is the name of the exported function, the rest of the parameters are used to format a functionpointer in the jumptable, the EXPORT_FUNC macros are expanded three times, 1. to declare the members of the struct 2. to initialize the structmember pointers 3. to call the functions in stubs.c Signed-off-by: Martin Dorwig Acked-by: Simon Glass Signed-off-by: Simon Glass (resending to the list since my tweaks are not quite trivial) --- arch/blackfin/cpu/cpu.c | 3 +- board/BuS/eb_cpux9k2/cpux9k2.c | 2 +- common/cmd_load.c | 2 +- common/console.c | 20 ++++---- common/exports.c | 29 ++---------- doc/README.standalone | 41 +++++++++++----- examples/standalone/stubs.c | 64 +++++++++++++------------ include/_exports.h | 99 +++++++++++++++++++++++++++------------ include/asm-generic/global_data.h | 2 +- include/exports.h | 22 +++++---- 10 files changed, 163 insertions(+), 121 deletions(-) diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index b7f118801d..91aa5cc89c 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -24,6 +24,7 @@ #include "cpu.h" #include "initcode.h" +#include "exports.h" ulong bfin_poweron_retx; DECLARE_GLOBAL_DATA_PTR; @@ -121,7 +122,7 @@ static void display_global_data(void) printf(" |-ram_size: %lx\n", gd->ram_size); printf(" |-env_addr: %lx\n", gd->env_addr); printf(" |-env_valid: %lx\n", gd->env_valid); - printf(" |-jt(%p): %p\n", gd->jt, *(gd->jt)); + printf(" |-jt(%p): %p\n", gd->jt, gd->jt->get_version); printf(" \\-bd: %p\n", gd->bd); printf(" |-bi_boot_params: %lx\n", bd->bi_boot_params); printf(" |-bi_memstart: %lx\n", bd->bi_memstart); diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c index 5e4778e978..76ad7c443b 100644 --- a/board/BuS/eb_cpux9k2/cpux9k2.c +++ b/board/BuS/eb_cpux9k2/cpux9k2.c @@ -98,7 +98,7 @@ int misc_init_r(void) puts("Error: invalid MAC at EEPROM\n"); } } - gd->jt[XF_do_reset] = (void *) do_reset; + gd->jt->do_reset = do_reset; #ifdef CONFIG_STATUS_LED status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING); diff --git a/common/cmd_load.c b/common/cmd_load.c index f6e522cbb3..d043e6d7bc 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -222,7 +222,7 @@ static int read_record(char *buf, ulong len) } /* Check for the console hangup (if any different from serial) */ - if (gd->jt[XF_getc] != getc) { + if (gd->jt->getc != getc) { if (ctrlc()) { return (-1); } diff --git a/common/console.c b/common/console.c index fc1963b2a9..3f25e76fe7 100644 --- a/common/console.c +++ b/common/console.c @@ -125,13 +125,13 @@ static int console_setfile(int file, struct stdio_dev * dev) */ switch (file) { case stdin: - gd->jt[XF_getc] = getc; - gd->jt[XF_tstc] = tstc; + gd->jt->getc = getc; + gd->jt->tstc = tstc; break; case stdout: - gd->jt[XF_putc] = putc; - gd->jt[XF_puts] = puts; - gd->jt[XF_printf] = printf; + gd->jt->putc = putc; + gd->jt->puts = puts; + gd->jt->printf = printf; break; } break; @@ -758,11 +758,11 @@ int console_init_r(void) #endif /* set default handlers at first */ - gd->jt[XF_getc] = serial_getc; - gd->jt[XF_tstc] = serial_tstc; - gd->jt[XF_putc] = serial_putc; - gd->jt[XF_puts] = serial_puts; - gd->jt[XF_printf] = serial_printf; + gd->jt->getc = serial_getc; + gd->jt->tstc = serial_tstc; + gd->jt->putc = serial_putc; + gd->jt->puts = serial_puts; + gd->jt->printf = serial_printf; /* stdin stdout and stderr are in environment */ /* scan for it */ diff --git a/common/exports.c b/common/exports.c index 459e18cb09..333107c74c 100644 --- a/common/exports.c +++ b/common/exports.c @@ -1,6 +1,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -13,34 +14,10 @@ unsigned long get_version(void) return XF_VERSION; } -/* Reuse _exports.h with a little trickery to avoid bitrot */ -#define EXPORT_FUNC(sym) gd->jt[XF_##sym] = (void *)sym; - -#if !defined(CONFIG_X86) && !defined(CONFIG_PPC) -# define install_hdlr dummy -# define free_hdlr dummy -#else /* kludge for non-standard function naming */ -# define install_hdlr irq_install_handler -# define free_hdlr irq_free_handler -#endif -#if !defined(CONFIG_CMD_I2C) || \ - (defined(CONFIG_DM_I2C) && !defined(CONFIG_DM_I2C_COMPAT)) -# define i2c_write dummy -# define i2c_read dummy -#endif -#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI) -# define spi_init dummy -# define spi_setup_slave dummy -# define spi_free_slave dummy -#endif -#ifndef CONFIG_CMD_SPI -# define spi_claim_bus dummy -# define spi_release_bus dummy -# define spi_xfer dummy -#endif +#define EXPORT_FUNC(f, a, x, ...) gd->jt->x = f; void jumptable_init(void) { - gd->jt = malloc(XF_MAX * sizeof(void *)); + gd->jt = malloc(sizeof(struct jt_funcs)); #include <_exports.h> } diff --git a/doc/README.standalone b/doc/README.standalone index e3000efcc6..659a12f6cb 100644 --- a/doc/README.standalone +++ b/doc/README.standalone @@ -5,18 +5,18 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications: table is allocated and initialized in the jumptable_init() routine (common/exports.c). Other routines may also modify the jump table, however. The jump table can be accessed as the 'jt' field of the - 'global_data' structure. The slot numbers for the jump table are + 'global_data' structure. The struct members for the jump table are defined in the header. E.g., to substitute the malloc() and free() functions that will be available to standalone applications, one should do the following: DECLARE_GLOBAL_DATA_PTR; - gd->jt[XF_malloc] = my_malloc; - gd->jt[XF_free] = my_free; + gd->jt->malloc = my_malloc; + gd->jt->free = my_free; - Note that the pointers to the functions all have 'void *' type and - thus the compiler cannot perform type checks on these assignments. + Note that the pointers to the functions are real function pointers + so the compiler can perform type checks on these assignments. 2. The pointer to the jump table is passed to the application in a machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II @@ -65,27 +65,46 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications: => tftp 0x40000 hello_world.bin => go 0x40004 -5. To export some additional function foobar(), the following steps +5. To export some additional function long foobar(int i,char c), the following steps should be undertaken: - Append the following line at the end of the include/_exports.h file: - EXPORT_FUNC(foobar) + EXPORT_FUNC(foobar, long, foobar, int, char) + + Parameters to EXPORT_FUNC: + - the first parameter is the function that is exported (default implementation) + - the second parameter is the return value type + - the third parameter is the name of the member in struct jt_funcs + this is also the name that the standalone application will used. + the rest of the parameters are the function arguments - Add the prototype for this function to the include/exports.h file: - void foobar(void); + long foobar(int i, char c); + + Initialization with the default implementation is done in jumptable_init() + + You can override the default implementation using: - - Add the initialization of the jump table slot wherever - appropriate (most likely, to the jumptable_init() function): + gd->jt->foobar = another_foobar; - gd->jt[XF_foobar] = foobar; + The signature of another_foobar must then match the declaration of foobar. - Increase the XF_VERSION value by one in the include/exports.h file + - If you want to export a function which depends on a CONFIG_XXX + use 2 lines like this: + #ifdef CONFIG_FOOBAR + EXPORT_FUNC(foobar, long, foobar, int, char) + #else + EXPORT_FUNC(dummy, void, foobar, void) + #endif + + 6. The code for exporting the U-Boot functions to applications is mostly machine-independent. The only places written in assembly language are stub functions that perform the jump through the jump diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index 0bf690e73d..920a0a9cf3 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -2,6 +2,8 @@ #include #include +#define FO(x) offsetof(struct jt_funcs, x) + #if defined(CONFIG_X86) /* * x86 does not have a dedicated register to store the pointer to @@ -10,23 +12,23 @@ * from flash memory. The global_data address is passed as argv[-1] * to the application program. */ -static void **jt; +static struct jt_funcs *jt; gd_t *global_data; -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " movl %0, %%eax\n" \ " movl jt, %%ecx\n" \ " jmp *(%%ecx, %%eax)\n" \ - : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx"); + : : "i"(FO(x)) : "eax", "ecx"); #elif defined(CONFIG_PPC) /* * r2 holds the pointer to the global_data, r11 is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ @@ -34,33 +36,33 @@ gd_t *global_data; " lwz %%r11, %1(%%r11)\n" \ " mtctr %%r11\n" \ " bctr\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r11"); #elif defined(CONFIG_ARM) #ifdef CONFIG_ARM64 /* * x18 holds the pointer to the global_data, x9 is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " ldr x9, [x18, %0]\n" \ " ldr x9, [x9, %1]\n" \ " br x9\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x9"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x9"); #else /* * r9 holds the pointer to the global_data, ip is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " ldr ip, [r9, %0]\n" \ " ldr pc, [ip, %1]\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip"); #endif #elif defined(CONFIG_MIPS) /* @@ -70,19 +72,19 @@ gd_t *global_data; * it; however, GCC/mips generates an additional `nop' after each asm * statement */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " lw $25, %0($26)\n" \ " lw $25, %1($25)\n" \ " jr $25\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9"); #elif defined(CONFIG_NIOS2) /* * gp holds the pointer to the global_data, r8 is call-clobbered */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ @@ -92,13 +94,13 @@ gd_t *global_data; " ldw r8, 0(r8)\n" \ " ldw r8, %1(r8)\n" \ " jmp r8\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "gp"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "gp"); #elif defined(CONFIG_M68K) /* * d7 holds the pointer to the global_data, a0 is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ @@ -108,50 +110,50 @@ gd_t *global_data; " adda.l %1, %%a0\n" \ " move.l (%%a0), %%a0\n" \ " jmp (%%a0)\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "a0"); #elif defined(CONFIG_MICROBLAZE) /* * r31 holds the pointer to the global_data. r5 is a call-clobbered. */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " lwi r5, r31, %0\n" \ " lwi r5, r5, %1\n" \ " bra r5\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r5"); #elif defined(CONFIG_BLACKFIN) /* * P3 holds the pointer to the global_data, P0 is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl _" #x "\n_" \ #x ":\n" \ " P0 = [P3 + %0]\n" \ " P0 = [P0 + %1]\n" \ " JUMP (P0)\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "P0"); #elif defined(CONFIG_AVR32) /* * r6 holds the pointer to the global_data. r8 is call clobbered. */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile( \ " .globl\t" #x "\n" \ #x ":\n" \ " ld.w r8, r6[%0]\n" \ " ld.w pc, r8[%1]\n" \ : \ - : "i"(offsetof(gd_t, jt)), "i"(XF_ ##x) \ + : "i"(offsetof(gd_t, jt)), "i"(FO(x)) \ : "r8"); #elif defined(CONFIG_SH) /* * r13 holds the pointer to the global_data. r1 is a call clobbered. */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .align 2\n" \ " .globl " #x "\n" \ @@ -164,12 +166,12 @@ gd_t *global_data; " jmp @r1\n" \ " nop\n" \ " nop\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1", "r2"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r1", "r2"); #elif defined(CONFIG_SPARC) /* * g7 holds the pointer to the global_data. g1 is call clobbered. */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile( \ " .globl\t" #x "\n" \ #x ":\n" \ @@ -179,26 +181,26 @@ gd_t *global_data; " ld [%%g1 + %1], %%g1\n" \ " jmp %%g1\n" \ " nop\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "g1" ); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "g1"); #elif defined(CONFIG_NDS32) /* * r16 holds the pointer to the global_data. gp is call clobbered. * not support reduced register (16 GPR). */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ " lwi $r16, [$gp + (%0)]\n" \ " lwi $r16, [$r16 + (%1)]\n" \ " jr $r16\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "$r16"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16"); #elif defined(CONFIG_OPENRISC) /* * r10 holds the pointer to the global_data, r13 is a call-clobbered * register */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile ( \ " .globl " #x "\n" \ #x ":\n" \ @@ -206,12 +208,12 @@ gd_t *global_data; " l.lwz r13, %1(r13)\n" \ " l.jr r13\n" \ " l.nop\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r13"); #elif defined(CONFIG_ARC) /* * r25 holds the pointer to the global_data. r10 is call clobbered. */ -#define EXPORT_FUNC(x) \ +#define EXPORT_FUNC(f, a, x, ...) \ asm volatile( \ " .align 4\n" \ " .globl " #x "\n" \ @@ -219,7 +221,7 @@ gd_t *global_data; " ld r10, [r25, %0]\n" \ " ld r10, [r10, %1]\n" \ " j [r10]\n" \ - : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r10"); + : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r10"); #else /*" addi $sp, $sp, -24\n" \ " br $r16\n" \*/ diff --git a/include/_exports.h b/include/_exports.h index 349a3c5522..594470328e 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -1,32 +1,73 @@ /* - * You do not need to use #ifdef around functions that may not exist + * You need to use #ifdef around functions that may not exist * in the final configuration (such as i2c). + * use a dummyfunction as first parameter to EXPORT_FUNC. + * As an example see the CONFIG_CMD_I2C section below */ -EXPORT_FUNC(get_version) -EXPORT_FUNC(getc) -EXPORT_FUNC(tstc) -EXPORT_FUNC(putc) -EXPORT_FUNC(puts) -EXPORT_FUNC(printf) -EXPORT_FUNC(install_hdlr) -EXPORT_FUNC(free_hdlr) -EXPORT_FUNC(malloc) -EXPORT_FUNC(free) -EXPORT_FUNC(udelay) -EXPORT_FUNC(get_timer) -EXPORT_FUNC(vprintf) -EXPORT_FUNC(do_reset) -EXPORT_FUNC(getenv) -EXPORT_FUNC(setenv) -EXPORT_FUNC(simple_strtoul) -EXPORT_FUNC(strict_strtoul) -EXPORT_FUNC(simple_strtol) -EXPORT_FUNC(strcmp) -EXPORT_FUNC(i2c_write) -EXPORT_FUNC(i2c_read) -EXPORT_FUNC(spi_init) -EXPORT_FUNC(spi_setup_slave) -EXPORT_FUNC(spi_free_slave) -EXPORT_FUNC(spi_claim_bus) -EXPORT_FUNC(spi_release_bus) -EXPORT_FUNC(spi_xfer) +#ifndef EXPORT_FUNC +#define EXPORT_FUNC(a, b, c, ...) +#endif + EXPORT_FUNC(get_version, unsigned long, get_version, void) + EXPORT_FUNC(getc, int, getc, void) + EXPORT_FUNC(tstc, int, tstc, void) + EXPORT_FUNC(putc, void, putc, const char) + EXPORT_FUNC(puts, void, puts, const char *) + EXPORT_FUNC(printf, int, printf, const char*, ...) +#if defined(CONFIG_X86) || defined(CONFIG_PPC) + EXPORT_FUNC(irq_install_handler, void, install_hdlr, + int, interrupt_handler_t, void*) + + EXPORT_FUNC(irq_free_handler, void, free_hdlr, int) +#else + EXPORT_FUNC(dummy, void, install_hdlr, void) + EXPORT_FUNC(dummy, void, free_hdlr, void) +#endif + EXPORT_FUNC(malloc, void *, malloc, size_t) + EXPORT_FUNC(free, void, free, void *) + EXPORT_FUNC(udelay, void, udelay, unsigned long) + EXPORT_FUNC(get_timer, unsigned long, get_timer, unsigned long) + EXPORT_FUNC(vprintf, int, vprintf, const char *, va_list) + EXPORT_FUNC(do_reset, int, do_reset, cmd_tbl_t *, + int , int , char * const []) + EXPORT_FUNC(getenv, char *, getenv, const char*) + EXPORT_FUNC(setenv, int, setenv, const char *, const char *) + EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul, + const char *, char **, unsigned int) + EXPORT_FUNC(strict_strtoul, int, strict_strtoul, + const char *, unsigned int , unsigned long *) + EXPORT_FUNC(simple_strtol, long, simple_strtol, + const char *, char **, unsigned int) + EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct) +#if defined(CONFIG_CMD_I2C) && \ + (!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT)) + EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int) + EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int) +#else + EXPORT_FUNC(dummy, void, i2c_write, void) + EXPORT_FUNC(dummy, void, i2c_read, void) +#endif + +#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI) + EXPORT_FUNC(dummy, void, spi_init, void) + EXPORT_FUNC(dummy, void, spi_setup_slave, void) + EXPORT_FUNC(dummy, void, spi_free_slave, void) +#else + EXPORT_FUNC(spi_init, void, spi_init, void) + EXPORT_FUNC(spi_setup_slave, struct spi_slave *, spi_setup_slave, + unsigned int, unsigned int, unsigned int, unsigned int) + EXPORT_FUNC(spi_free_slave, void, spi_free_slave, struct spi_slave *) +#endif +#ifndef CONFIG_CMD_SPI + EXPORT_FUNC(dummy, void, spi_claim_bus, void) + EXPORT_FUNC(dummy, void, spi_release_bus, void) + EXPORT_FUNC(dummy, void, spi_xfer, void) +#else + EXPORT_FUNC(spi_claim_bus, int, spi_claim_bus, struct spi_slave *) + EXPORT_FUNC(spi_release_bus, void, spi_release_bus, struct spi_slave *) + EXPORT_FUNC(spi_xfer, int, spi_xfer, struct spi_slave *, + unsigned int, const void *, void *, unsigned long) +#endif + EXPORT_FUNC(ustrtoul, unsigned long, ustrtoul, + const char *, char **, unsigned int) + EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull, + const char *, char **, unsigned int) diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 3d14d5f117..6747619b1c 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -73,7 +73,7 @@ typedef struct global_data { const void *fdt_blob; /* Our device tree, NULL if none */ void *new_fdt; /* Relocated FDT */ unsigned long fdt_size; /* Space reserved for relocated FDT */ - void **jt; /* jump table */ + struct jt_funcs *jt; /* jump table */ char env_buf[32]; /* buffer for getenv() before reloc. */ #ifdef CONFIG_TRACE void *trace_buff; /* The trace buffer */ diff --git a/include/exports.h b/include/exports.h index 41d5085e16..205affe72d 100644 --- a/include/exports.h +++ b/include/exports.h @@ -3,6 +3,8 @@ #ifndef __ASSEMBLY__ +struct spi_slave; + /* These are declarations of exported functions available in C code */ unsigned long get_version(void); int getc(void); @@ -10,22 +12,23 @@ int tstc(void); void putc(const char); void puts(const char*); int printf(const char* fmt, ...); -void install_hdlr(int, void (*interrupt_handler_t)(void *), void*); +void install_hdlr(int, interrupt_handler_t, void*); void free_hdlr(int); void *malloc(size_t); void free(void*); void __udelay(unsigned long); unsigned long get_timer(unsigned long); int vprintf(const char *, va_list); -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base); +unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base); int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); char *getenv (const char *name); int setenv (const char *varname, const char *varvalue); -long simple_strtol(const char *cp,char **endp,unsigned int base); -int strcmp(const char * cs,const char * ct); +long simple_strtol(const char *cp, char **endp, unsigned int base); +int strcmp(const char *cs, const char *ct); unsigned long ustrtoul(const char *cp, char **endp, unsigned int base); unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base); -#if defined(CONFIG_CMD_I2C) +#if defined(CONFIG_CMD_I2C) && \ + (!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT)) int i2c_write (uchar, uint, int , uchar* , int); int i2c_read (uchar, uint, int , uchar* , int); #endif @@ -34,15 +37,14 @@ void app_startup(char * const *); #endif /* ifndef __ASSEMBLY__ */ -enum { -#define EXPORT_FUNC(x) XF_ ## x , +struct jt_funcs { +#define EXPORT_FUNC(impl, res, func, ...) res(*func)(__VA_ARGS__); #include <_exports.h> #undef EXPORT_FUNC - - XF_MAX }; -#define XF_VERSION 6 + +#define XF_VERSION 7 #if defined(CONFIG_X86) extern gd_t *global_data; -- cgit From fc2f4246b4b3b750e8c5aa08440ec5e1c952088e Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:50 +0530 Subject: rsa: Split the rsa-verify to separate the modular exponentiation Public exponentiation which is required in rsa verify functionality is tightly integrated with verification code in rsa_verify.c. The patch splits the file into twp separating the modular exponentiation. 1. rsa-verify.c - The file parses device tree keys node to fill a keyprop structure. The keyprop structure can then be converted to implementation specific format. (struct rsa_pub_key for sw implementation) - The parsed device tree node is then passed to a generic rsa_mod_exp function. 2. rsa-mod-exp.c Move the software specific functions related to modular exponentiation from rsa-verify.c to this file. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- include/u-boot/rsa-mod-exp.h | 43 ++++++ lib/rsa/Makefile | 2 +- lib/rsa/rsa-mod-exp.c | 303 +++++++++++++++++++++++++++++++++++++++ lib/rsa/rsa-verify.c | 329 ++++++++----------------------------------- tools/Makefile | 3 +- 5 files changed, 404 insertions(+), 276 deletions(-) create mode 100644 include/u-boot/rsa-mod-exp.h create mode 100644 lib/rsa/rsa-mod-exp.c diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h new file mode 100644 index 0000000000..59cd9ea2d8 --- /dev/null +++ b/include/u-boot/rsa-mod-exp.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Ruchika Gupta. + * + * SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _RSA_MOD_EXP_H +#define _RSA_MOD_EXP_H + +#include +#include + +/** + * struct key_prop - holder for a public key properties + * + * The struct has pointers to modulus (Typically called N), + * The inverse, R^2, exponent. These can be typecasted and + * used as byte arrays or converted to the required format + * as per requirement of RSA implementation. + */ +struct key_prop { + const void *rr; /* R^2 can be treated as byte array */ + const void *modulus; /* modulus as byte array */ + const void *public_exponent; /* public exponent as byte array */ + uint32_t n0inv; /* -1 / modulus[0] mod 2^32 */ + int num_bits; /* Key length in bits */ + uint32_t exp_len; /* Exponent length in number of uint8_t */ +}; + +/** + * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw + * + * Operation: out[] = sig ^ exponent % modulus + * + * @sig: RSA PKCS1.5 signature + * @sig_len: Length of signature in number of bytes + * @node: Node with RSA key elements like modulus, exponent, R^2, n0inv + * @out: Result in form of byte array + */ +int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len, + struct key_prop *node, uint8_t *out); + +#endif diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index a5a96cb680..cc25b3ce6d 100644 --- a/lib/rsa/Makefile +++ b/lib/rsa/Makefile @@ -7,4 +7,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o +obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c new file mode 100644 index 0000000000..4a6de2b932 --- /dev/null +++ b/lib/rsa/rsa-mod-exp.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2013, Google Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef USE_HOSTCC +#include +#include +#include +#include +#include +#include +#include +#else +#include "fdt_host.h" +#include "mkimage.h" +#include +#endif +#include +#include + +#define UINT64_MULT32(v, multby) (((uint64_t)(v)) * ((uint32_t)(multby))) + +#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a) +#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a)) + +/* Default public exponent for backward compatibility */ +#define RSA_DEFAULT_PUBEXP 65537 + +/** + * subtract_modulus() - subtract modulus from the given value + * + * @key: Key containing modulus to subtract + * @num: Number to subtract modulus from, as little endian word array + */ +static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[]) +{ + int64_t acc = 0; + uint i; + + for (i = 0; i < key->len; i++) { + acc += (uint64_t)num[i] - key->modulus[i]; + num[i] = (uint32_t)acc; + acc >>= 32; + } +} + +/** + * greater_equal_modulus() - check if a value is >= modulus + * + * @key: Key containing modulus to check + * @num: Number to check against modulus, as little endian word array + * @return 0 if num < modulus, 1 if num >= modulus + */ +static int greater_equal_modulus(const struct rsa_public_key *key, + uint32_t num[]) +{ + int i; + + for (i = (int)key->len - 1; i >= 0; i--) { + if (num[i] < key->modulus[i]) + return 0; + if (num[i] > key->modulus[i]) + return 1; + } + + return 1; /* equal */ +} + +/** + * montgomery_mul_add_step() - Perform montgomery multiply-add step + * + * Operation: montgomery result[] += a * b[] / n0inv % modulus + * + * @key: RSA key + * @result: Place to put result, as little endian word array + * @a: Multiplier + * @b: Multiplicand, as little endian word array + */ +static void montgomery_mul_add_step(const struct rsa_public_key *key, + uint32_t result[], const uint32_t a, const uint32_t b[]) +{ + uint64_t acc_a, acc_b; + uint32_t d0; + uint i; + + acc_a = (uint64_t)a * b[0] + result[0]; + d0 = (uint32_t)acc_a * key->n0inv; + acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a; + for (i = 1; i < key->len; i++) { + acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i]; + acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] + + (uint32_t)acc_a; + result[i - 1] = (uint32_t)acc_b; + } + + acc_a = (acc_a >> 32) + (acc_b >> 32); + + result[i - 1] = (uint32_t)acc_a; + + if (acc_a >> 32) + subtract_modulus(key, result); +} + +/** + * montgomery_mul() - Perform montgomery mutitply + * + * Operation: montgomery result[] = a[] * b[] / n0inv % modulus + * + * @key: RSA key + * @result: Place to put result, as little endian word array + * @a: Multiplier, as little endian word array + * @b: Multiplicand, as little endian word array + */ +static void montgomery_mul(const struct rsa_public_key *key, + uint32_t result[], uint32_t a[], const uint32_t b[]) +{ + uint i; + + for (i = 0; i < key->len; ++i) + result[i] = 0; + for (i = 0; i < key->len; ++i) + montgomery_mul_add_step(key, result, a[i], b); +} + +/** + * num_pub_exponent_bits() - Number of bits in the public exponent + * + * @key: RSA key + * @num_bits: Storage for the number of public exponent bits + */ +static int num_public_exponent_bits(const struct rsa_public_key *key, + int *num_bits) +{ + uint64_t exponent; + int exponent_bits; + const uint max_bits = (sizeof(exponent) * 8); + + exponent = key->exponent; + exponent_bits = 0; + + if (!exponent) { + *num_bits = exponent_bits; + return 0; + } + + for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits) + if (!(exponent >>= 1)) { + *num_bits = exponent_bits; + return 0; + } + + return -EINVAL; +} + +/** + * is_public_exponent_bit_set() - Check if a bit in the public exponent is set + * + * @key: RSA key + * @pos: The bit position to check + */ +static int is_public_exponent_bit_set(const struct rsa_public_key *key, + int pos) +{ + return key->exponent & (1ULL << pos); +} + +/** + * pow_mod() - in-place public exponentiation + * + * @key: RSA key + * @inout: Big-endian word array containing value and result + */ +static int pow_mod(const struct rsa_public_key *key, uint32_t *inout) +{ + uint32_t *result, *ptr; + uint i; + int j, k; + + /* Sanity check for stack size - key->len is in 32-bit words */ + if (key->len > RSA_MAX_KEY_BITS / 32) { + debug("RSA key words %u exceeds maximum %d\n", key->len, + RSA_MAX_KEY_BITS / 32); + return -EINVAL; + } + + uint32_t val[key->len], acc[key->len], tmp[key->len]; + uint32_t a_scaled[key->len]; + result = tmp; /* Re-use location. */ + + /* Convert from big endian byte array to little endian word array. */ + for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--) + val[i] = get_unaligned_be32(ptr); + + if (0 != num_public_exponent_bits(key, &k)) + return -EINVAL; + + if (k < 2) { + debug("Public exponent is too short (%d bits, minimum 2)\n", + k); + return -EINVAL; + } + + if (!is_public_exponent_bit_set(key, 0)) { + debug("LSB of RSA public exponent must be set.\n"); + return -EINVAL; + } + + /* the bit at e[k-1] is 1 by definition, so start with: C := M */ + montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */ + /* retain scaled version for intermediate use */ + memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0])); + + for (j = k - 2; j > 0; --j) { + montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */ + + if (is_public_exponent_bit_set(key, j)) { + /* acc = tmp * val / R mod n */ + montgomery_mul(key, acc, tmp, a_scaled); + } else { + /* e[j] == 0, copy tmp back to acc for next operation */ + memcpy(acc, tmp, key->len * sizeof(acc[0])); + } + } + + /* the bit at e[0] is always 1 */ + montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */ + montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */ + memcpy(result, acc, key->len * sizeof(result[0])); + + /* Make sure result < mod; result is at most 1x mod too large. */ + if (greater_equal_modulus(key, result)) + subtract_modulus(key, result); + + /* Convert to bigendian byte array */ + for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++) + put_unaligned_be32(result[i], ptr); + return 0; +} + +static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len) +{ + int i; + + for (i = 0; i < len; i++) + dst[i] = fdt32_to_cpu(src[len - 1 - i]); +} + +int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len, + struct key_prop *prop, uint8_t *out) +{ + struct rsa_public_key key; + int ret; + + if (!prop) { + debug("%s: Skipping invalid prop", __func__); + return -EBADF; + } + key.n0inv = prop->n0inv; + key.len = prop->num_bits; + + if (!prop->public_exponent) + key.exponent = RSA_DEFAULT_PUBEXP; + else + key.exponent = + fdt64_to_cpu(*((uint64_t *)(prop->public_exponent))); + + if (!key.len || !prop->modulus || !prop->rr) { + debug("%s: Missing RSA key info", __func__); + return -EFAULT; + } + + /* Sanity check for stack size */ + if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) { + debug("RSA key bits %u outside allowed range %d..%d\n", + key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS); + return -EFAULT; + } + key.len /= sizeof(uint32_t) * 8; + uint32_t key1[key.len], key2[key.len]; + + key.modulus = key1; + key.rr = key2; + rsa_convert_big_endian(key.modulus, (uint32_t *)prop->modulus, key.len); + rsa_convert_big_endian(key.rr, (uint32_t *)prop->rr, key.len); + if (!key.modulus || !key.rr) { + debug("%s: Out of memory", __func__); + return -ENOMEM; + } + + uint32_t buf[sig_len / sizeof(uint32_t)]; + + memcpy(buf, sig, sig_len); + + ret = pow_mod(&key, buf); + if (ret) + return ret; + + memcpy(out, buf, sig_len); + + return 0; +} diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 4ef19b66f4..f8bc086fd7 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -17,230 +17,26 @@ #include "mkimage.h" #include #endif +#include #include -#include -#include - -#define UINT64_MULT32(v, multby) (((uint64_t)(v)) * ((uint32_t)(multby))) - -#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a) -#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a)) /* Default public exponent for backward compatibility */ #define RSA_DEFAULT_PUBEXP 65537 /** - * subtract_modulus() - subtract modulus from the given value - * - * @key: Key containing modulus to subtract - * @num: Number to subtract modulus from, as little endian word array - */ -static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[]) -{ - int64_t acc = 0; - uint i; - - for (i = 0; i < key->len; i++) { - acc += (uint64_t)num[i] - key->modulus[i]; - num[i] = (uint32_t)acc; - acc >>= 32; - } -} - -/** - * greater_equal_modulus() - check if a value is >= modulus - * - * @key: Key containing modulus to check - * @num: Number to check against modulus, as little endian word array - * @return 0 if num < modulus, 1 if num >= modulus - */ -static int greater_equal_modulus(const struct rsa_public_key *key, - uint32_t num[]) -{ - int i; - - for (i = (int)key->len - 1; i >= 0; i--) { - if (num[i] < key->modulus[i]) - return 0; - if (num[i] > key->modulus[i]) - return 1; - } - - return 1; /* equal */ -} - -/** - * montgomery_mul_add_step() - Perform montgomery multiply-add step - * - * Operation: montgomery result[] += a * b[] / n0inv % modulus + * rsa_verify_key() - Verify a signature against some data using RSA Key * - * @key: RSA key - * @result: Place to put result, as little endian word array - * @a: Multiplier - * @b: Multiplicand, as little endian word array - */ -static void montgomery_mul_add_step(const struct rsa_public_key *key, - uint32_t result[], const uint32_t a, const uint32_t b[]) -{ - uint64_t acc_a, acc_b; - uint32_t d0; - uint i; - - acc_a = (uint64_t)a * b[0] + result[0]; - d0 = (uint32_t)acc_a * key->n0inv; - acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a; - for (i = 1; i < key->len; i++) { - acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i]; - acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] + - (uint32_t)acc_a; - result[i - 1] = (uint32_t)acc_b; - } - - acc_a = (acc_a >> 32) + (acc_b >> 32); - - result[i - 1] = (uint32_t)acc_a; - - if (acc_a >> 32) - subtract_modulus(key, result); -} - -/** - * montgomery_mul() - Perform montgomery mutitply - * - * Operation: montgomery result[] = a[] * b[] / n0inv % modulus - * - * @key: RSA key - * @result: Place to put result, as little endian word array - * @a: Multiplier, as little endian word array - * @b: Multiplicand, as little endian word array - */ -static void montgomery_mul(const struct rsa_public_key *key, - uint32_t result[], uint32_t a[], const uint32_t b[]) -{ - uint i; - - for (i = 0; i < key->len; ++i) - result[i] = 0; - for (i = 0; i < key->len; ++i) - montgomery_mul_add_step(key, result, a[i], b); -} - -/** - * num_pub_exponent_bits() - Number of bits in the public exponent - * - * @key: RSA key - * @num_bits: Storage for the number of public exponent bits - */ -static int num_public_exponent_bits(const struct rsa_public_key *key, - int *num_bits) -{ - uint64_t exponent; - int exponent_bits; - const uint max_bits = (sizeof(exponent) * 8); - - exponent = key->exponent; - exponent_bits = 0; - - if (!exponent) { - *num_bits = exponent_bits; - return 0; - } - - for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits) - if (!(exponent >>= 1)) { - *num_bits = exponent_bits; - return 0; - } - - return -EINVAL; -} - -/** - * is_public_exponent_bit_set() - Check if a bit in the public exponent is set - * - * @key: RSA key - * @pos: The bit position to check - */ -static int is_public_exponent_bit_set(const struct rsa_public_key *key, - int pos) -{ - return key->exponent & (1ULL << pos); -} - -/** - * pow_mod() - in-place public exponentiation + * Verify a RSA PKCS1.5 signature against an expected hash using + * the RSA Key properties in prop structure. * - * @key: RSA key - * @inout: Big-endian word array containing value and result + * @prop: Specifies key + * @sig: Signature + * @sig_len: Number of bytes in signature + * @hash: Pointer to the expected hash + * @algo: Checksum algo structure having information on RSA padding etc. + * @return 0 if verified, -ve on error */ -static int pow_mod(const struct rsa_public_key *key, uint32_t *inout) -{ - uint32_t *result, *ptr; - uint i; - int j, k; - - /* Sanity check for stack size - key->len is in 32-bit words */ - if (key->len > RSA_MAX_KEY_BITS / 32) { - debug("RSA key words %u exceeds maximum %d\n", key->len, - RSA_MAX_KEY_BITS / 32); - return -EINVAL; - } - - uint32_t val[key->len], acc[key->len], tmp[key->len]; - uint32_t a_scaled[key->len]; - result = tmp; /* Re-use location. */ - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--) - val[i] = get_unaligned_be32(ptr); - - if (0 != num_public_exponent_bits(key, &k)) - return -EINVAL; - - if (k < 2) { - debug("Public exponent is too short (%d bits, minimum 2)\n", - k); - return -EINVAL; - } - - if (!is_public_exponent_bit_set(key, 0)) { - debug("LSB of RSA public exponent must be set.\n"); - return -EINVAL; - } - - /* the bit at e[k-1] is 1 by definition, so start with: C := M */ - montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */ - /* retain scaled version for intermediate use */ - memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0])); - - for (j = k - 2; j > 0; --j) { - montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */ - - if (is_public_exponent_bit_set(key, j)) { - /* acc = tmp * val / R mod n */ - montgomery_mul(key, acc, tmp, a_scaled); - } else { - /* e[j] == 0, copy tmp back to acc for next operation */ - memcpy(acc, tmp, key->len * sizeof(acc[0])); - } - } - - /* the bit at e[0] is always 1 */ - montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */ - montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */ - memcpy(result, acc, key->len * sizeof(result[0])); - - /* Make sure result < mod; result is at most 1x mod too large. */ - if (greater_equal_modulus(key, result)) - subtract_modulus(key, result); - - /* Convert to bigendian byte array */ - for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++) - put_unaligned_be32(result[i], ptr); - return 0; -} - -static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig, +static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, const uint32_t sig_len, const uint8_t *hash, struct checksum_algo *algo) { @@ -248,10 +44,10 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig, int pad_len; int ret; - if (!key || !sig || !hash || !algo) + if (!prop || !sig || !hash || !algo) return -EIO; - if (sig_len != (key->len * sizeof(uint32_t))) { + if (sig_len != (prop->num_bits / 8)) { debug("Signature is of incorrect length %d\n", sig_len); return -EINVAL; } @@ -265,13 +61,13 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig, return -EINVAL; } - uint32_t buf[sig_len / sizeof(uint32_t)]; - - memcpy(buf, sig, sig_len); + uint8_t buf[sig_len]; - ret = pow_mod(key, buf); - if (ret) + ret = rsa_mod_exp_sw(sig, sig_len, prop, buf); + if (ret) { + debug("Error in Modular exponentation\n"); return ret; + } padding = algo->rsa_padding; pad_len = algo->pad_len - algo->checksum_len; @@ -291,72 +87,57 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig, return 0; } -static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len) -{ - int i; - - for (i = 0; i < len; i++) - dst[i] = fdt32_to_cpu(src[len - 1 - i]); -} - +/** + * rsa_verify_with_keynode() - Verify a signature against some data using + * information in node with prperties of RSA Key like modulus, exponent etc. + * + * Parse sign-node and fill a key_prop structure with properties of the + * key. Verify a RSA PKCS1.5 signature against an expected hash using + * the properties parsed + * + * @info: Specifies key and FIT information + * @hash: Pointer to the expected hash + * @sig: Signature + * @sig_len: Number of bytes in signature + * @node: Node having the RSA Key properties + * @return 0 if verified, -ve on error + */ static int rsa_verify_with_keynode(struct image_sign_info *info, - const void *hash, uint8_t *sig, uint sig_len, int node) + const void *hash, uint8_t *sig, + uint sig_len, int node) { const void *blob = info->fdt_blob; - struct rsa_public_key key; - const void *modulus, *rr; - const uint64_t *public_exponent; + struct key_prop prop; int length; - int ret; + int ret = 0; if (node < 0) { debug("%s: Skipping invalid node", __func__); return -EBADF; } - if (!fdt_getprop(blob, node, "rsa,n0-inverse", NULL)) { - debug("%s: Missing rsa,n0-inverse", __func__); - return -EFAULT; - } - key.len = fdtdec_get_int(blob, node, "rsa,num-bits", 0); - key.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0); - public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length); - if (!public_exponent || length < sizeof(*public_exponent)) - key.exponent = RSA_DEFAULT_PUBEXP; - else - key.exponent = fdt64_to_cpu(*public_exponent); - modulus = fdt_getprop(blob, node, "rsa,modulus", NULL); - rr = fdt_getprop(blob, node, "rsa,r-squared", NULL); - if (!key.len || !modulus || !rr) { - debug("%s: Missing RSA key info", __func__); - return -EFAULT; - } - /* Sanity check for stack size */ - if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) { - debug("RSA key bits %u outside allowed range %d..%d\n", - key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS); + prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0); + + prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0); + + prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length); + if (!prop.public_exponent || length < sizeof(uint64_t)) + prop.public_exponent = NULL; + + prop.exp_len = sizeof(uint64_t); + + prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL); + + prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL); + + if (!prop.num_bits || !prop.modulus) { + debug("%s: Missing RSA key info", __func__); return -EFAULT; } - key.len /= sizeof(uint32_t) * 8; - uint32_t key1[key.len], key2[key.len]; - - key.modulus = key1; - key.rr = key2; - rsa_convert_big_endian(key.modulus, modulus, key.len); - rsa_convert_big_endian(key.rr, rr, key.len); - if (!key.modulus || !key.rr) { - debug("%s: Out of memory", __func__); - return -ENOMEM; - } - debug("key length %d\n", key.len); - ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum); - if (ret) { - printf("%s: RSA failed to verify: %d\n", __func__, ret); - return ret; - } + ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum); - return 0; + return ret; } int rsa_verify(struct image_sign_info *info, diff --git a/tools/Makefile b/tools/Makefile index e549f8e63c..46b90b2861 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -60,7 +60,8 @@ FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o LIBFDT_OBJS := $(addprefix lib/libfdt/, \ fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o) RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \ - rsa-sign.o rsa-verify.o rsa-checksum.o) + rsa-sign.o rsa-verify.o rsa-checksum.o \ + rsa-mod-exp.o) # common objs for dumpimage and mkimage dumpimage-mkimage-objs := aisimage.o \ -- cgit From c4beb22fcd8cf57569a8045c8e04cea0dbbfd763 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:51 +0530 Subject: FIT: Modify option FIT_SIGNATURE in Kconfig For FIT signature based approach to work, RSA library needs to be selected. The FIT_SIGNATURE option in Kconfig is modified to automatically select RSA. Selecting RSA compiles the RSA library required for image verification. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- Kconfig | 3 ++- lib/Kconfig | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Kconfig b/Kconfig index 4157da3c68..fed488fdaf 100644 --- a/Kconfig +++ b/Kconfig @@ -116,8 +116,9 @@ config FIT_VERBOSE depends on FIT config FIT_SIGNATURE - bool "Enabel signature verification of FIT uImages" + bool "Enable signature verification of FIT uImages" depends on FIT + select RSA help This option enables signature verification of FIT uImages, using a hash signed and verified using RSA. diff --git a/lib/Kconfig b/lib/Kconfig index 8460439d8e..79b91b7747 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -27,4 +27,11 @@ config SYS_HZ get_timer() must operate in milliseconds and this option must be set to 1000. +config RSA + bool "Use RSA Library" + help + RSA support. This enables the RSA algorithm used for FIT image + verification in U-Boot. + See doc/uImage.FIT/signature.txt for more details. + endmenu -- cgit From 31d2b4fd90f9305aad2e79872067e6c0243267de Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:52 +0530 Subject: DM: crypto/rsa_mod_exp: Add rsa Modular Exponentiation DM driver Add a new rsa uclass for performing modular exponentiation and implement the software driver basing on this uclass. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- drivers/crypto/Makefile | 1 + drivers/crypto/rsa_mod_exp/Kconfig | 5 ++++ drivers/crypto/rsa_mod_exp/Makefile | 7 ++++++ drivers/crypto/rsa_mod_exp/mod_exp_sw.c | 39 +++++++++++++++++++++++++++++ drivers/crypto/rsa_mod_exp/mod_exp_uclass.c | 31 +++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/u-boot/rsa-mod-exp.h | 34 ++++++++++++++++++++++++- 7 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/rsa_mod_exp/Kconfig create mode 100644 drivers/crypto/rsa_mod_exp/Makefile create mode 100644 drivers/crypto/rsa_mod_exp/mod_exp_sw.c create mode 100644 drivers/crypto/rsa_mod_exp/mod_exp_uclass.c diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 7b79237181..fb8c10b38c 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -6,4 +6,5 @@ # obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o +obj-y += rsa_mod_exp/ obj-y += fsl/ diff --git a/drivers/crypto/rsa_mod_exp/Kconfig b/drivers/crypto/rsa_mod_exp/Kconfig new file mode 100644 index 0000000000..6dcb39a8d3 --- /dev/null +++ b/drivers/crypto/rsa_mod_exp/Kconfig @@ -0,0 +1,5 @@ +config DM_MOD_EXP + bool "Enable Driver Model for RSA Modular Exponentiation" + depends on DM + help + If you want to use driver model for RSA Modular Exponentiation, say Y. diff --git a/drivers/crypto/rsa_mod_exp/Makefile b/drivers/crypto/rsa_mod_exp/Makefile new file mode 100644 index 0000000000..915b751dbe --- /dev/null +++ b/drivers/crypto/rsa_mod_exp/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_RSA) += mod_exp_uclass.o mod_exp_sw.o diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c new file mode 100644 index 0000000000..dc6c064b4e --- /dev/null +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2014 Freescale Semiconductor, Inc. + * Author: Ruchika Gupta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, + struct key_prop *prop, uint8_t *out) +{ + int ret = 0; + + ret = rsa_mod_exp_sw(sig, sig_len, prop, out); + if (ret) { + debug("%s: RSA failed to verify: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct mod_exp_ops mod_exp_ops_sw = { + .mod_exp = mod_exp_sw, +}; + +U_BOOT_DRIVER(mod_exp_sw) = { + .name = "mod_exp_sw", + .id = UCLASS_MOD_EXP, + .ops = &mod_exp_ops_sw, +}; + +U_BOOT_DEVICE(mod_exp_sw) = { + .name = "mod_exp_sw", +}; diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c b/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c new file mode 100644 index 0000000000..266f09484f --- /dev/null +++ b/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2014 Freescale Semiconductor, Inc + * Author: Ruchika Gupta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, + struct key_prop *node, uint8_t *out) +{ + const struct mod_exp_ops *ops = device_get_ops(dev); + + if (!ops->mod_exp) + return -ENOSYS; + + return ops->mod_exp(dev, sig, sig_len, node, out); +} + +UCLASS_DRIVER(mod_exp) = { + .id = UCLASS_MOD_EXP, + .name = "rsa_mod_exp", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index f17c3c2b38..91bb90dcfb 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -33,6 +33,7 @@ enum uclass_id { UCLASS_I2C, /* I2C bus */ UCLASS_I2C_GENERIC, /* Generic I2C device */ UCLASS_I2C_EEPROM, /* I2C EEPROM device */ + UCLASS_MOD_EXP, /* RSA Mod Exp device */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h index 59cd9ea2d8..fce445a082 100644 --- a/include/u-boot/rsa-mod-exp.h +++ b/include/u-boot/rsa-mod-exp.h @@ -35,9 +35,41 @@ struct key_prop { * @sig: RSA PKCS1.5 signature * @sig_len: Length of signature in number of bytes * @node: Node with RSA key elements like modulus, exponent, R^2, n0inv - * @out: Result in form of byte array + * @out: Result in form of byte array of len equal to sig_len */ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len, struct key_prop *node, uint8_t *out); +int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, + struct key_prop *node, uint8_t *out); + +/** + * struct struct mod_exp_ops - Driver model for RSA Modular Exponentiation + * operations + * + * The uclass interface is implemented by all crypto devices which use + * driver model. + */ +struct mod_exp_ops { + /** + * Perform Modular Exponentiation + * + * Operation: out[] = sig ^ exponent % modulus + * + * @dev: RSA Device + * @sig: RSA PKCS1.5 signature + * @sig_len: Length of signature in number of bytes + * @node: Node with RSA key elements like modulus, exponent, + * R^2, n0inv + * @out: Result in form of byte array of len equal to sig_len + * + * This function computes exponentiation over the signature. + * Returns: 0 if exponentiation is successful, or a negative value + * if it wasn't. + */ + int (*mod_exp)(struct udevice *dev, const uint8_t *sig, + uint32_t sig_len, struct key_prop *node, + uint8_t *outp); +}; + #endif -- cgit From 11a9662ba9ed40829fd10acb3a0c75d148159921 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:53 +0530 Subject: configs: Move CONFIG_FIT_SIGNATURE to defconfig For the platforms which use,CONFIG_FIT_SIGNATURE, the required configs are moved to the platform's defconfig file. Selecting CONFIG_FIT_SIGNATURE using defconfig automatically resolves the dependencies for signature verification. The RSA library gets automatically selected and user does not have to define CONFIG_RSA manually. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- configs/ids8313_defconfig | 2 ++ configs/sandbox_defconfig | 3 +++ configs/zynq_microzed_defconfig | 3 +++ configs/zynq_zc70x_defconfig | 3 +++ configs/zynq_zc770_xm010_defconfig | 3 +++ configs/zynq_zc770_xm012_defconfig | 3 +++ configs/zynq_zc770_xm013_defconfig | 3 +++ configs/zynq_zed_defconfig | 3 +++ configs/zynq_zybo_defconfig | 3 +++ include/configs/am335x_evm.h | 4 ++-- include/configs/ids8313.h | 3 --- include/configs/sandbox.h | 3 --- include/configs/zynq-common.h | 6 ------ 13 files changed, 28 insertions(+), 14 deletions(-) diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig index 1c665aab94..8479cd42f7 100644 --- a/configs/ids8313_defconfig +++ b/configs/ids8313_defconfig @@ -1,4 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xFFF00000" CONFIG_PPC=y CONFIG_MPC83xx=y +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y CONFIG_TARGET_IDS8313=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 47d8400ace..0111f25224 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -1,3 +1,6 @@ CONFIG_OF_CONTROL=y CONFIG_OF_HOSTFILE=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index 9588849bb5..b9a6fe522a 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -3,4 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_MICROZED=y CONFIG_OF_CONTROL=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed" diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index cf507308e9..dc8aa84992 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -4,3 +4,6 @@ CONFIG_SPL=y +S:CONFIG_TARGET_ZYNQ_ZC70X=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index 8bb405d180..2f5fa8c59a 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index 0ba5da589e..a92d495dfe 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 13f8112a1b..3a02f750c6 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -5,3 +5,6 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index eb057fae35..1d816f68c4 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -4,3 +4,6 @@ CONFIG_SPL=y +S:CONFIG_TARGET_ZYNQ_ZED=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index 12311cd83b..9183629bfb 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -4,3 +4,6 @@ CONFIG_SPL=y +S:CONFIG_TARGET_ZYNQ_ZYBO=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index 0004750518..f9bc23b407 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -23,8 +23,8 @@ # define CONFIG_TIMESTAMP # define CONFIG_LZO # ifdef CONFIG_ENABLE_VBOOT -# define CONFIG_FIT_SIGNATURE -# define CONFIG_RSA +# define CONFIG_FIT_SIGNATURE +# define CONFIG_RSA # endif #endif diff --git a/include/configs/ids8313.h b/include/configs/ids8313.h index f08483487d..2384864eb0 100644 --- a/include/configs/ids8313.h +++ b/include/configs/ids8313.h @@ -575,12 +575,9 @@ #define CONFIG_VERSION_VARIABLE -#define CONFIG_FIT -#define CONFIG_FIT_SIGNATURE #define CONFIG_IMAGE_FORMAT_LEGACY #define CONFIG_CMD_FDT #define CONFIG_CMD_HASH -#define CONFIG_RSA #define CONFIG_SHA1 #define CONFIG_SHA256 diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 657f751f3c..6fd29b9c73 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -41,9 +41,6 @@ #define CONFIG_OF_LIBFDT #define CONFIG_LMB -#define CONFIG_FIT -#define CONFIG_FIT_SIGNATURE -#define CONFIG_RSA #define CONFIG_CMD_FDT #define CONFIG_ANDROID_BOOT_IMAGE diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 2d28e89dd3..864528a5ea 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -276,17 +276,11 @@ #define CONFIG_OF_LIBFDT /* FIT support */ -#define CONFIG_FIT -#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ #define CONFIG_IMAGE_FORMAT_LEGACY /* enable also legacy image format */ /* FDT support */ #define CONFIG_DISPLAY_BOARDINFO_LATE -/* RSA support */ -#define CONFIG_FIT_SIGNATURE -#define CONFIG_RSA - /* Extend size of kernel image for uncompression */ #define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024) -- cgit From c937ff6dc2ee3fcd8f97087427fe8ba5086852c4 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:54 +0530 Subject: lib/rsa: Modify rsa to use DM driver Modify rsa_verify to use the rsa driver of DM library .The tools will continue to use the same RSA sw library. CONFIG_RSA is now dependent on CONFIG_DM. All configurations which enable FIT based signatures have been modified to enable CONFIG_DM by default. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- README | 7 ++++++- configs/am335x_boneblack_vboot_defconfig | 4 ++++ configs/ids8313_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/zynq_microzed_defconfig | 1 + configs/zynq_zc70x_defconfig | 1 + configs/zynq_zc770_xm010_defconfig | 1 + configs/zynq_zc770_xm012_defconfig | 1 + configs/zynq_zc770_xm013_defconfig | 1 + configs/zynq_zed_defconfig | 1 + configs/zynq_zybo_defconfig | 1 + include/configs/am335x_evm.h | 6 ++---- include/configs/sandbox.h | 1 - lib/rsa/rsa-verify.c | 14 ++++++++++++++ 14 files changed, 35 insertions(+), 6 deletions(-) diff --git a/README b/README index fefa71c0a6..cac7978afa 100644 --- a/README +++ b/README @@ -3176,8 +3176,13 @@ CBFS (Coreboot Filesystem) support This enables the RSA algorithm used for FIT image verification in U-Boot. See doc/uImage.FIT/signature.txt for more information. + The Modular Exponentiation algorithm in RSA is implemented using + driver model. So CONFIG_DM needs to be enabled by default for this + library to function. + The signing part is build into mkimage regardless of this - option. + option. The software based modular exponentiation is built into + mkimage irrespective of this option. - bootcount support: CONFIG_BOOTCOUNT_LIMIT diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index 5837a0a4da..51bf370364 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -4,3 +4,7 @@ CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT" +S:CONFIG_TARGET_AM335X_EVM=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig index 8479cd42f7..0950ec8b77 100644 --- a/configs/ids8313_defconfig +++ b/configs/ids8313_defconfig @@ -4,3 +4,4 @@ CONFIG_MPC83xx=y CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_TARGET_IDS8313=y +CONFIG_DM=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 0111f25224..660063ebf3 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -3,4 +3,5 @@ CONFIG_OF_HOSTFILE=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index b9a6fe522a..8b985fe5a4 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -6,4 +6,5 @@ CONFIG_OF_CONTROL=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed" diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index dc8aa84992..cceb32199d 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index 2f5fa8c59a..2935c0dff7 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index a92d495dfe..0401739652 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 3a02f750c6..a95970a917 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -8,3 +8,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 1d816f68c4..0fbc41ab8a 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index 9183629bfb..4e66760750 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -7,3 +7,4 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y +CONFIG_DM=y diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index f9bc23b407..76ce7deb95 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -19,13 +19,11 @@ #include #ifndef CONFIG_SPL_BUILD +#ifndef CONFIG_FIT # define CONFIG_FIT +#endif # define CONFIG_TIMESTAMP # define CONFIG_LZO -# ifdef CONFIG_ENABLE_VBOOT -# define CONFIG_FIT_SIGNATURE -# define CONFIG_RSA -# endif #endif #define CONFIG_SYS_BOOTM_LEN (16 << 20) diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 6fd29b9c73..e9d3f3226b 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -23,7 +23,6 @@ #define CONFIG_BOOTSTAGE #define CONFIG_BOOTSTAGE_REPORT -#define CONFIG_DM #define CONFIG_CMD_DEMO #define CONFIG_CMD_DM #define CONFIG_DM_DEMO diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index f8bc086fd7..da45daffd3 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -12,6 +12,7 @@ #include #include #include +#include #else #include "fdt_host.h" #include "mkimage.h" @@ -43,6 +44,9 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, const uint8_t *padding; int pad_len; int ret; +#if !defined(USE_HOSTCC) + struct udevice *mod_exp_dev; +#endif if (!prop || !sig || !hash || !algo) return -EIO; @@ -63,7 +67,17 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, uint8_t buf[sig_len]; +#if !defined(USE_HOSTCC) + ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); + if (ret) { + printf("RSA: Can't find Modular Exp implementation\n"); + return -EINVAL; + } + + ret = rsa_mod_exp(mod_exp_dev, sig, sig_len, prop, buf); +#else ret = rsa_mod_exp_sw(sig, sig_len, prop, buf); +#endif if (ret) { debug("Error in Modular exponentation\n"); return ret; -- cgit From 34276478f7b7a0fea9c76e365a477962910ef770 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:55 +0530 Subject: DM: crypto/fsl - Add Freescale rsa DM driver Driver added for RSA Modular Exponentiation using Freescale Hardware Accelerator CAAM. The driver uses UCLASS_MOD_EXP Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- drivers/crypto/Kconfig | 1 + drivers/crypto/fsl/Kconfig | 6 +++++ drivers/crypto/fsl/Makefile | 1 + drivers/crypto/fsl/fsl_rsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++ drivers/crypto/fsl/jobdesc.c | 28 ++++++++++++++++++++ drivers/crypto/fsl/jobdesc.h | 5 ++++ drivers/crypto/fsl/rsa_caam.h | 28 ++++++++++++++++++++ 7 files changed, 129 insertions(+) create mode 100644 drivers/crypto/fsl/Kconfig create mode 100644 drivers/crypto/fsl/fsl_rsa.c create mode 100644 drivers/crypto/fsl/rsa_caam.h diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e69de29bb2..bd26a2bcfa 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -0,0 +1 @@ +source drivers/crypto/fsl/Kconfig diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig new file mode 100644 index 0000000000..86b2f2f7ac --- /dev/null +++ b/drivers/crypto/fsl/Kconfig @@ -0,0 +1,6 @@ +config FSL_CAAM + bool "Freescale Crypto Driver Support" + help + Enables the Freescale's Cryptographic Accelerator and Assurance + Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses + Job Ring as interface to communicate with CAAM. diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index 067d0a917b..c0cf64229e 100644 --- a/drivers/crypto/fsl/Makefile +++ b/drivers/crypto/fsl/Makefile @@ -9,3 +9,4 @@ obj-y += sec.o obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o obj-$(CONFIG_CMD_BLOB) += fsl_blob.o +obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o diff --git a/drivers/crypto/fsl/fsl_rsa.c b/drivers/crypto/fsl/fsl_rsa.c new file mode 100644 index 0000000000..cf1c4c1d45 --- /dev/null +++ b/drivers/crypto/fsl/fsl_rsa.c @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2014 Freescale Semiconductor, Inc. + * Author: Ruchika Gupta + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include "jobdesc.h" +#include "desc.h" +#include "jr.h" +#include "rsa_caam.h" +#include + +int fsl_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, + struct key_prop *prop, uint8_t *out) +{ + uint32_t keylen; + struct pk_in_params pkin; + uint32_t desc[MAX_CAAM_DESCSIZE]; + int ret; + + /* Length in bytes */ + keylen = prop->num_bits / 8; + + pkin.a = sig; + pkin.a_siz = sig_len; + pkin.n = prop->modulus; + pkin.n_siz = keylen; + pkin.e = prop->public_exponent; + pkin.e_siz = prop->exp_len; + + inline_cnstr_jobdesc_pkha_rsaexp(desc, &pkin, out, sig_len); + + ret = run_descriptor_jr(desc); + if (ret) { + debug("%s: RSA failed to verify: %d\n", __func__, ret); + return -EFAULT; + } + + return 0; +} + +static const struct mod_exp_ops fsl_mod_exp_ops = { + .mod_exp = fsl_mod_exp, +}; + +U_BOOT_DRIVER(fsl_rsa_mod_exp) = { + .name = "fsl_rsa_mod_exp", + .id = UCLASS_MOD_EXP, + .ops = &fsl_mod_exp_ops, +}; + +U_BOOT_DEVICE(fsl_rsa) = { + .name = "fsl_rsa_mod_exp", +}; diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c index 1386baec0f..cc0dcede7b 100644 --- a/drivers/crypto/fsl/jobdesc.c +++ b/drivers/crypto/fsl/jobdesc.c @@ -11,6 +11,7 @@ #include #include "desc_constr.h" #include "jobdesc.h" +#include "rsa_caam.h" #define KEY_BLOB_SIZE 32 #define MAC_SIZE 16 @@ -123,3 +124,30 @@ void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc) append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG | OP_ALG_RNG4_SK); } + +/* Change key size to bytes form bits in calling function*/ +void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc, + struct pk_in_params *pkin, uint8_t *out, + uint32_t out_siz) +{ + dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out; + + dma_addr_e = virt_to_phys((void *)pkin->e); + dma_addr_a = virt_to_phys((void *)pkin->a); + dma_addr_n = virt_to_phys((void *)pkin->n); + dma_addr_out = virt_to_phys((void *)out); + + init_job_desc(desc, 0); + append_key(desc, dma_addr_e, pkin->e_siz, KEY_DEST_PKHA_E | CLASS_1); + + append_fifo_load(desc, dma_addr_a, + pkin->a_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_A); + + append_fifo_load(desc, dma_addr_n, + pkin->n_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_N); + + append_operation(desc, OP_TYPE_PK | OP_ALG_PK | OP_ALG_PKMODE_MOD_EXPO); + + append_fifo_store(desc, dma_addr_out, out_siz, + LDST_CLASS_1_CCB | FIFOST_TYPE_PKHA_B); +} diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h index 3cf7226de2..84b3edd6e2 100644 --- a/drivers/crypto/fsl/jobdesc.h +++ b/drivers/crypto/fsl/jobdesc.h @@ -10,6 +10,7 @@ #include #include +#include "rsa_caam.h" #define KEY_IDNFR_SZ_BYTES 16 @@ -26,4 +27,8 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr, uint32_t out_sz); void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc); + +void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc, + struct pk_in_params *pkin, uint8_t *out, + uint32_t out_siz); #endif diff --git a/drivers/crypto/fsl/rsa_caam.h b/drivers/crypto/fsl/rsa_caam.h new file mode 100644 index 0000000000..4ff87efc5b --- /dev/null +++ b/drivers/crypto/fsl/rsa_caam.h @@ -0,0 +1,28 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __RSA_CAAM_H +#define __RSA_CAAM_H + +#include + +/** + * struct pk_in_params - holder for input to PKHA block in CAAM + * These parameters are required to perform Modular Exponentiation + * using PKHA Block in CAAM + */ +struct pk_in_params { + const uint8_t *e; /* public exponent as byte array */ + uint32_t e_siz; /* size of e[] in number of bytes */ + const uint8_t *n; /* modulus as byte array */ + uint32_t n_siz; /* size of n[] in number of bytes */ + const uint8_t *a; /* Signature as byte array */ + uint32_t a_siz; /* size of a[] in number of bytes */ + uint8_t *b; /* Result exp. modulus in number of bytes */ + uint32_t b_siz; /* size of b[] in number of bytes */ +}; + +#endif -- cgit From d9f23c7fe20fced0a84713d5084a6d2896463257 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:56 +0530 Subject: lib/rsa: Add Kconfig for devices supporting RSA Modular Exponentiation Kconfig option added for devices which support RSA Verification. 1. RSA_SOFTWARE_EXP Enables driver for supporting RSA Modular Exponentiation in Software 2. RSA_FREESCALE_EXP Enables driver for supporting RSA Modular Exponentiation using Freescale specific driver The above drivers use RSA uclass Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass Signed-off-by: Simon Glass (Removed duplicate line in Kconfig comment) Change-Id: I7663c4d5350e2bfc3dfa2696f70ef777d6ccc6f6 --- lib/Kconfig | 7 +------ lib/rsa/Kconfig | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 lib/rsa/Kconfig diff --git a/lib/Kconfig b/lib/Kconfig index 79b91b7747..a1f30a2c4e 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -27,11 +27,6 @@ config SYS_HZ get_timer() must operate in milliseconds and this option must be set to 1000. -config RSA - bool "Use RSA Library" - help - RSA support. This enables the RSA algorithm used for FIT image - verification in U-Boot. - See doc/uImage.FIT/signature.txt for more details. +source lib/rsa/Kconfig endmenu diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig new file mode 100644 index 0000000000..1268a1b2db --- /dev/null +++ b/lib/rsa/Kconfig @@ -0,0 +1,27 @@ +config RSA + bool "Use RSA Library" + select RSA_FREESCALE_EXP if FSL_CAAM + select RSA_SOFTWARE_EXP if !RSA_FREESCALE_EXP + help + RSA support. This enables the RSA algorithm used for FIT image + verification in U-Boot. + See doc/uImage.FIT/signature.txt for more details. + +if RSA +config RSA_SOFTWARE_EXP + bool "Enable driver for RSA Modular Exponentiation in software" + depends on DM && RSA + help + Enables driver for modular exponentiation in software. This is a RSA + algorithm used in FIT image verification. It required RSA Key as + input. + See doc/uImage.FIT/signature.txt for more details. + +config RSA_FREESCALE_EXP + bool "Enable RSA Modular Exponentiation with FSL crypto accelerator" + depends on DM && RSA && FSL_CAAM + help + Enables driver for RSA modular exponentiation using Freescale cryptographic + accelerator - CAAM. + +endif -- cgit From 46fe2c04443f3d777791910da21649bb3ddf878f Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:57 +0530 Subject: hash: Add function to find hash_algo struct with progressive hash The hash_algo structure has some implementations in which progressive hash API's are not defined. These are basically the hardware based implementations of SHA. An API is added to find the algo which has progressive hash API's defined. This can then be integrated with RSA checksum library which uses Progressive Hash API's. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- common/hash.c | 33 ++++++++++++++++++++++++--------- include/hash.h | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/common/hash.c b/common/hash.c index aceabc5cad..c4d8c3a041 100644 --- a/common/hash.c +++ b/common/hash.c @@ -20,7 +20,7 @@ #include #include -#ifdef CONFIG_CMD_SHA1SUM +#ifdef CONFIG_SHA1 static int hash_init_sha1(struct hash_algo *algo, void **ctxp) { sha1_context *ctx = malloc(sizeof(sha1_context)); @@ -125,12 +125,7 @@ static struct hash_algo hash_algo[] = { CHUNKSZ_SHA256, }, #endif - /* - * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise - * it bloats the code for boards which use SHA1 but not the 'hash' - * or 'sha1sum' commands. - */ -#ifdef CONFIG_CMD_SHA1SUM +#ifdef CONFIG_SHA1 { "sha1", SHA1_SUM_LEN, @@ -140,7 +135,6 @@ static struct hash_algo hash_algo[] = { hash_update_sha1, hash_finish_sha1, }, -#define MULTI_HASH #endif #ifdef CONFIG_SHA256 { @@ -152,7 +146,6 @@ static struct hash_algo hash_algo[] = { hash_update_sha256, hash_finish_sha256, }, -#define MULTI_HASH #endif { "crc32", @@ -165,6 +158,10 @@ static struct hash_algo hash_algo[] = { }, }; +#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM) +#define MULTI_HASH +#endif + #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH) #define MULTI_HASH #endif @@ -311,6 +308,24 @@ int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) return -EPROTONOSUPPORT; } +int hash_progressive_lookup_algo(const char *algo_name, + struct hash_algo **algop) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { + if (!strcmp(algo_name, hash_algo[i].name)) { + if (hash_algo[i].hash_init) { + *algop = &hash_algo[i]; + return 0; + } + } + } + + debug("Unknown hash algorithm '%s'\n", algo_name); + return -EPROTONOSUPPORT; +} + void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) { int i; diff --git a/include/hash.h b/include/hash.h index d8ec4f08e1..c0a7ebc6a6 100644 --- a/include/hash.h +++ b/include/hash.h @@ -127,6 +127,20 @@ int hash_block(const char *algo_name, const void *data, unsigned int len, */ int hash_lookup_algo(const char *algo_name, struct hash_algo **algop); +/** + * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash support + * + * The function returns the pointer to the struct or -EPROTONOSUPPORT if the + * algorithm is not available with progressive hash support. + * + * @algo_name: Hash algorithm to look up + * @algop: Pointer to the hash_algo struct if found + * + * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm. + */ +int hash_progressive_lookup_algo(const char *algo_name, + struct hash_algo **algop); + /** * hash_show() - Print out a hash algorithm and value * -- cgit From 2dd90027196175d0bcea411c933927d73994588d Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:58 +0530 Subject: Use hash.c in mkimage Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass --- common/hash.c | 81 +++++++++++++++++++++++++++++++++------------------------- include/hash.h | 34 ++++++++++++------------ tools/Makefile | 1 + 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/common/hash.c b/common/hash.c index c4d8c3a041..d154d029e9 100644 --- a/common/hash.c +++ b/common/hash.c @@ -10,15 +10,24 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#ifndef USE_HOSTCC #include #include #include #include +#include +#include +#else +#include "mkimage.h" +#include +#include +#endif /* !USE_HOSTCC*/ + #include +#include #include #include -#include -#include +#include #ifdef CONFIG_SHA1 static int hash_init_sha1(struct hash_algo *algo, void **ctxp) @@ -173,6 +182,40 @@ static struct hash_algo hash_algo[] = { #define multi_hash() 0 #endif +int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { + if (!strcmp(algo_name, hash_algo[i].name)) { + *algop = &hash_algo[i]; + return 0; + } + } + + debug("Unknown hash algorithm '%s'\n", algo_name); + return -EPROTONOSUPPORT; +} + +int hash_progressive_lookup_algo(const char *algo_name, + struct hash_algo **algop) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { + if (!strcmp(algo_name, hash_algo[i].name)) { + if (hash_algo[i].hash_init) { + *algop = &hash_algo[i]; + return 0; + } + } + } + + debug("Unknown hash algorithm '%s'\n", algo_name); + return -EPROTONOSUPPORT; +} + +#ifndef USE_HOSTCC /** * store_result: Store the resulting sum to an address or variable * @@ -293,39 +336,6 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, return 0; } -int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { - if (!strcmp(algo_name, hash_algo[i].name)) { - *algop = &hash_algo[i]; - return 0; - } - } - - debug("Unknown hash algorithm '%s'\n", algo_name); - return -EPROTONOSUPPORT; -} - -int hash_progressive_lookup_algo(const char *algo_name, - struct hash_algo **algop) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { - if (!strcmp(algo_name, hash_algo[i].name)) { - if (hash_algo[i].hash_init) { - *algop = &hash_algo[i]; - return 0; - } - } - } - - debug("Unknown hash algorithm '%s'\n", algo_name); - return -EPROTONOSUPPORT; -} - void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) { int i; @@ -439,3 +449,4 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, return 0; } +#endif diff --git a/include/hash.h b/include/hash.h index c0a7ebc6a6..f4eb100de0 100644 --- a/include/hash.h +++ b/include/hash.h @@ -17,7 +17,6 @@ enum { HASH_FLAG_ENV = 1 << 1, /* Allow env vars */ }; -#ifndef USE_HOSTCC #if defined(CONFIG_SHA1SUM_VERIFY) || defined(CONFIG_CRC32_VERIFY) #define CONFIG_HASH_VERIFY #endif @@ -77,6 +76,7 @@ struct hash_algo { int size); }; +#ifndef USE_HOSTCC /** * hash_command: Process a hash command for a particular algorithm * @@ -114,6 +114,23 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int hash_block(const char *algo_name, const void *data, unsigned int len, uint8_t *output, int *output_size); +/** + * hash_show() - Print out a hash algorithm and value + * + * You will get a message like this (without a newline at the end): + * + * "sha1 for 9eb3337c ... 9eb3338f ==> 7942ef1df479fd3130f716eb9613d107dab7e257" + * + * @algo: Algorithm used for hash + * @addr: Address of data that was hashed + * @len: Length of data that was hashed + * @output: Hash value to display + */ +void hash_show(struct hash_algo *algo, ulong addr, ulong len, + uint8_t *output); + +#endif /* !USE_HOSTCC */ + /** * hash_lookup_algo() - Look up the hash_algo struct for an algorithm * @@ -141,19 +158,4 @@ int hash_lookup_algo(const char *algo_name, struct hash_algo **algop); int hash_progressive_lookup_algo(const char *algo_name, struct hash_algo **algop); -/** - * hash_show() - Print out a hash algorithm and value - * - * You will get a message like this (without a newline at the end): - * - * "sha1 for 9eb3337c ... 9eb3338f ==> 7942ef1df479fd3130f716eb9613d107dab7e257" - * - * @algo: Algorithm used for hash - * @addr: Address of data that was hashed - * @len: Length of data that was hashed - * @output: Hash value to display - */ -void hash_show(struct hash_algo *algo, ulong addr, ulong len, - uint8_t *output); -#endif /* !USE_HOSTCC */ #endif diff --git a/tools/Makefile b/tools/Makefile index 46b90b2861..ea76a3e7d9 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -91,6 +91,7 @@ dumpimage-mkimage-objs := aisimage.o \ socfpgaimage.o \ lib/sha1.o \ lib/sha256.o \ + common/hash.o \ ublimage.o \ $(LIBFDT_OBJS) \ $(RSA_OBJS-y) -- cgit From b37b46f042ccfcfb97a9ef8b8a568812640a2a70 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Fri, 23 Jan 2015 16:01:59 +0530 Subject: rsa: Use checksum algorithms from struct hash_algo Currently the hash functions used in RSA are called directly from the sha1 and sha256 libraries. Change the RSA checksum library to use the progressive hash API's registered with struct hash_algo. This will allow the checksum library to use the hardware accelerated progressive hash API's once available. Signed-off-by: Ruchika Gupta CC: Simon Glass Acked-by: Simon Glass Signed-off-by: Simon Glass (Fixed build error in am335x_boneblack_vboot due to duplicate CONFIG_DM) Change-Id: Ic44279432f88d4e8594c6e94feb1cfcae2443a54 --- common/image-sig.c | 6 ++--- include/configs/ti_am335x_common.h | 2 ++ include/image.h | 5 ++-- include/u-boot/rsa-checksum.h | 17 ++++++++++--- lib/rsa/rsa-checksum.c | 50 +++++++++++++++++++++++--------------- lib/rsa/rsa-verify.c | 7 +++++- 6 files changed, 57 insertions(+), 30 deletions(-) diff --git a/common/image-sig.c b/common/image-sig.c index 8601edaca3..2c9f0cdf7a 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -38,7 +38,7 @@ struct checksum_algo checksum_algos[] = { #if IMAGE_ENABLE_SIGN EVP_sha1, #endif - sha1_calculate, + hash_calculate, padding_sha1_rsa2048, }, { @@ -48,7 +48,7 @@ struct checksum_algo checksum_algos[] = { #if IMAGE_ENABLE_SIGN EVP_sha256, #endif - sha256_calculate, + hash_calculate, padding_sha256_rsa2048, }, { @@ -58,7 +58,7 @@ struct checksum_algo checksum_algos[] = { #if IMAGE_ENABLE_SIGN EVP_sha256, #endif - sha256_calculate, + hash_calculate, padding_sha256_rsa4096, } diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 5ed86d9365..598526bf95 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -20,7 +20,9 @@ #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC #ifndef CONFIG_SPL_BUILD +#ifndef CONFIG_DM # define CONFIG_DM +#endif # define CONFIG_CMD_DM # define CONFIG_DM_GPIO # define CONFIG_DM_SERIAL diff --git a/include/image.h b/include/image.h index ee3afe3567..dcbc72fc1e 100644 --- a/include/image.h +++ b/include/image.h @@ -927,8 +927,9 @@ struct checksum_algo { #if IMAGE_ENABLE_SIGN const EVP_MD *(*calculate_sign)(void); #endif - void (*calculate)(const struct image_region region[], - int region_count, uint8_t *checksum); + int (*calculate)(const char *name, + const struct image_region region[], + int region_count, uint8_t *checksum); const uint8_t *rsa_padding; }; diff --git a/include/u-boot/rsa-checksum.h b/include/u-boot/rsa-checksum.h index c996fb3e4c..3c69d85ecb 100644 --- a/include/u-boot/rsa-checksum.h +++ b/include/u-boot/rsa-checksum.h @@ -16,9 +16,18 @@ extern const uint8_t padding_sha256_rsa4096[]; extern const uint8_t padding_sha256_rsa2048[]; extern const uint8_t padding_sha1_rsa2048[]; -void sha256_calculate(const struct image_region region[], int region_count, - uint8_t *checksum); -void sha1_calculate(const struct image_region region[], int region_count, - uint8_t *checksum); +/** + * hash_calculate() - Calculate hash over the data + * + * @name: Name of algorithm to be used for hash calculation + * @region: Array having info of regions over which hash needs to be calculated + * @region_count: Number of regions in the region array + * @checksum: Buffer contanining the output hash + * + * @return 0 if OK, < 0 if error + */ +int hash_calculate(const char *name, + const struct image_region region[], int region_count, + uint8_t *checksum); #endif diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c index 8d8b59f779..68d9d651b0 100644 --- a/lib/rsa/rsa-checksum.c +++ b/lib/rsa/rsa-checksum.c @@ -10,12 +10,13 @@ #include #include #include +#include #else #include "fdt_host.h" -#endif -#include #include #include +#endif +#include /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */ @@ -136,28 +137,37 @@ const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = { 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; -void sha1_calculate(const struct image_region region[], int region_count, - uint8_t *checksum) +int hash_calculate(const char *name, + const struct image_region region[], + int region_count, uint8_t *checksum) { - sha1_context ctx; + struct hash_algo *algo; + int ret = 0; + void *ctx; uint32_t i; i = 0; - sha1_starts(&ctx); - for (i = 0; i < region_count; i++) - sha1_update(&ctx, region[i].data, region[i].size); - sha1_finish(&ctx, checksum); -} + ret = hash_progressive_lookup_algo(name, &algo); + if (ret) + return ret; -void sha256_calculate(const struct image_region region[], int region_count, - uint8_t *checksum) -{ - sha256_context ctx; - uint32_t i; - i = 0; + ret = algo->hash_init(algo, &ctx); + if (ret) + return ret; + + for (i = 0; i < region_count - 1; i++) { + ret = algo->hash_update(algo, ctx, region[i].data, + region[i].size, 0); + if (ret) + return ret; + } + + ret = algo->hash_update(algo, ctx, region[i].data, region[i].size, 1); + if (ret) + return ret; + ret = algo->hash_finish(algo, ctx, checksum, algo->digest_size); + if (ret) + return ret; - sha256_starts(&ctx); - for (i = 0; i < region_count; i++) - sha256_update(&ctx, region[i].data, region[i].size); - sha256_finish(&ctx, checksum); + return 0; } diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index da45daffd3..60126d2288 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -184,7 +184,12 @@ int rsa_verify(struct image_sign_info *info, } /* Calculate checksum with checksum-algorithm */ - info->algo->checksum->calculate(region, region_count, hash); + ret = info->algo->checksum->calculate(info->algo->checksum->name, + region, region_count, hash); + if (ret < 0) { + debug("%s: Error in checksum calculation\n", __func__); + return -EINVAL; + } /* See if we must use a particular key */ if (info->required_keynode != -1) { -- cgit From 18a7f6aa2dcac7e78436cba148b25779f25f5c16 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:28 +0100 Subject: dm: i2c-uclass-compat: fix missed argument This patch fixes build error for CONFIG_DM_I2C_COMPAT. In i2c_get_chip_for_busnum() call, one of argument was missed, which was offset_len. Now it is set to 'alen' as previous. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass --- drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 11239da2b9..841ce0510c 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -17,7 +17,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, struct dm_i2c_chip *chip; int ret; - ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); + ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp); if (ret) return ret; chip = dev_get_parent_platdata(*devp); -- cgit From 480d49eb0e21e346da9d8bb2e82a6c4778b39049 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:29 +0100 Subject: arndale: config: disable max77686 support There is no MAX77686 pmic on this board, so the driver support should be removed. Signed-off-by: Przemyslaw Marczak Cc: Minkyu Kang --- include/configs/arndale.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/configs/arndale.h b/include/configs/arndale.h index d68993bb1f..3ad4a9ba91 100644 --- a/include/configs/arndale.h +++ b/include/configs/arndale.h @@ -51,8 +51,6 @@ /* PMIC */ #define CONFIG_PMIC #define CONFIG_POWER_I2C -#define CONFIG_POWER_MAX77686 - #define CONFIG_PREBOOT -- cgit From 8c94a83883c61f9685304078b42bb686498ea60a Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:30 +0100 Subject: exynos5250: config: disable max77686 driver This PMIC is not common for all Exynos5250 based boards, so should be romoved from common config. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Simon Glass Cc: Minkyu Kang --- include/configs/exynos5250-common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h index 671431397f..ae0e5ff47b 100644 --- a/include/configs/exynos5250-common.h +++ b/include/configs/exynos5250-common.h @@ -28,9 +28,6 @@ #define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK -/* PMIC */ -#define CONFIG_POWER_MAX77686 - /* Sound */ #define CONFIG_CMD_SOUND #ifdef CONFIG_CMD_SOUND -- cgit From ba1b4b1a0beb6350b9e36addc1fd4803e39eab0b Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:31 +0100 Subject: smdk5250: config: enable max77686 driver support This commit enable support for the above driver, which was disabled in common config. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Simon Glass Cc: Minkyu Kang --- include/configs/smdk5250.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 83953728dd..3b06d305db 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -18,6 +18,8 @@ #include +/* PMIC */ +#define CONFIG_POWER_MAX77686 #define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R -- cgit From 8fd10a8dbfbb83ecddbacf052aac2c2023446aeb Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:32 +0100 Subject: exynos4: dts: add missing i2c properties This patch modify i2c nodes in exynos4.dtsi with: - adding proper interrupts arrays for each i2c node, which allows to decode periph id - add reg address for each i2c node for i2c driver internal use Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Minkyu Kang Cc: Lukasz Majewski --- arch/arm/dts/exynos4.dtsi | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi index 3c983edeb2..7de227cc01 100644 --- a/arch/arm/dts/exynos4.dtsi +++ b/arch/arm/dts/exynos4.dtsi @@ -51,56 +51,64 @@ #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <0 0 0>; + reg = <0x13860000 0x100>; + interrupts = <0 56 0>; }; i2c@13870000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <1 1 0>; + reg = <0x13870000 0x100>; + interrupts = <1 57 0>; }; i2c@13880000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <2 2 0>; + reg = <0x13880000 0x100>; + interrupts = <2 58 0>; }; i2c@13890000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <3 3 0>; + reg = <0x13890000 0x100>; + interrupts = <3 59 0>; }; i2c@138a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <4 4 0>; + reg = <0x138a0000 0x100>; + interrupts = <4 60 0>; }; i2c@138b0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <5 5 0>; + reg = <0x138b0000 0x100>; + interrupts = <5 61 0>; }; i2c@138c0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <6 6 0>; + reg = <0x138c0000 0x100>; + interrupts = <6 62 0>; }; i2c@138d0000 { #address-cells = <1>; #size-cells = <0>; compatible = "samsung,s3c2440-i2c"; - interrupts = <7 7 0>; + reg = <0x138d0000 0x100>; + interrupts = <7 63 0>; }; sdhci@12510000 { -- cgit From 232a02cf016c7b51b880ed38bffe65369252339d Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:33 +0100 Subject: arndale: dts: add missing i2c aliases Without this alias setting, the seq numbers of the i2c devices are wrong. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Simon Glass Cc: Minkyu Kang --- arch/arm/dts/exynos5250-arndale.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/dts/exynos5250-arndale.dts b/arch/arm/dts/exynos5250-arndale.dts index 202f2ea6ed..21c0a214ea 100644 --- a/arch/arm/dts/exynos5250-arndale.dts +++ b/arch/arm/dts/exynos5250-arndale.dts @@ -15,6 +15,14 @@ compatible = "samsung,arndale", "samsung,exynos5250"; aliases { + i2c0 = "/i2c@12c60000"; + i2c1 = "/i2c@12c70000"; + i2c2 = "/i2c@12c80000"; + i2c3 = "/i2c@12c90000"; + i2c4 = "/i2c@12ca0000"; + i2c5 = "/i2c@12cb0000"; + i2c6 = "/i2c@12cc0000"; + i2c7 = "/i2c@12cd0000"; serial0 = "/serial@12C20000"; console = "/serial@12C20000"; }; -- cgit From fda0e27bfd7dd8ea5fefaa00c932903e1fe82a16 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:34 +0100 Subject: exynos5: pinmux: check flag for i2c config Some versions of Exynos5 supports High-Speed I2C, on few interfaces, this change allows support this. The new flag is: PINMUX_FLAG_HS_MODE Signed-off-by: Przemyslaw Marczak Cc: Simon Glass Cc: Akshay Saraswat Cc: Minkyu Kang Acked-by: Simon Glass --- arch/arm/cpu/armv7/exynos/pinmux.c | 27 +++++++++++++++++++-------- arch/arm/include/asm/arch-exynos/pinmux.h | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 94d0297051..be43e224fa 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags) static void exynos5_i2c_config(int peripheral, int flags) { + int func01, func23; + + /* High-Speed I2C */ + if (flags & PINMUX_FLAG_HS_MODE) { + func01 = 4; + func23 = 4; + } else { + func01 = 2; + func23 = 3; + } + switch (peripheral) { case PERIPH_ID_I2C0: - gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C1: - gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2)); - gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); break; case PERIPH_ID_I2C2: - gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C3: - gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3)); - gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); break; case PERIPH_ID_I2C4: gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3)); diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h index 0b91ef658c..d0ae7575da 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -23,6 +23,9 @@ enum { /* Flags for SROM controller */ PINMUX_FLAG_BANK = 3 << 0, /* bank number (0-3) */ PINMUX_FLAG_16BIT = 1 << 2, /* 16-bit width */ + + /* Flags for I2C */ + PINMUX_FLAG_HS_MODE = 1 << 1, /* I2C High Speed Mode */ }; /** -- cgit From 8dfcbaa681667bd72ad1c6213ef548b7a372ff65 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:36 +0100 Subject: dm: i2c: s3c24x0: adjust to dm-i2c api This commit adjusts the s3c24x0 driver to new i2c api based on driver-model. The driver supports standard and high-speed i2c as previous. Tested on Trats2, Odroid U3, Arndale, Odroid XU3 Signed-off-by: Przemyslaw Marczak Tested-by: Simon Glass Cc: Simon Glass Cc: Heiko Schocher Cc: Minkyu Kang Acked-by: Simon Glass --- drivers/i2c/s3c24x0_i2c.c | 237 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 194 insertions(+), 43 deletions(-) diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index fd328f0549..0dd1abcf80 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -9,8 +9,9 @@ * as they seem to have the same I2C controller inside. * The different address mapping is handled by the s3c24xx.h files below. */ - #include +#include +#include #include #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) #include @@ -121,13 +122,23 @@ #define CONFIG_MAX_I2C_NUM 1 #endif +DECLARE_GLOBAL_DATA_PTR; + /* * For SPL boot some boards need i2c before SDRAM is initialised so force * variables to live in SRAM */ +#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] __attribute__((section(".data"))); +#endif + +enum exynos_i2c_type { + EXYNOS_I2C_STD, + EXYNOS_I2C_HS, +}; +#ifdef CONFIG_SYS_I2C /** * Get a pointer to the given bus index * @@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) debug("Undefined bus: %d\n", bus_idx); return NULL; } +#endif #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) static int GetI2CSDA(void) @@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); } +#ifdef CONFIG_SYS_I2C static struct s3c24x0_i2c *get_base_i2c(int bus) { #ifdef CONFIG_EXYNOS4 @@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus) return s3c24x0_get_base_i2c(); #endif } +#endif static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) { @@ -326,7 +340,7 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus) return 0; } } - return -1; + return -EINVAL; } static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus) @@ -398,18 +412,20 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) hsi2c_ch_init(i2c_bus); } +#ifdef CONFIG_SYS_I2C static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { struct s3c24x0_i2c *i2c; struct s3c24x0_i2c_bus *bus; - #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); #endif ulong start_time = get_timer(0); - /* By default i2c channel 0 is the current bus */ i2c = get_base_i2c(adap->hwadapnr); + bus = &i2c_bus[adap->hwadapnr]; + if (!bus) + return; /* * In case the previous transfer is still going, wait to give it a @@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) #endif } #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ + i2c_ch_init(i2c, speed, slaveadd); - bus = &i2c_bus[adap->hwadapnr]; bus->active = true; bus->regs = i2c; } +#endif /* CONFIG_SYS_I2C */ /* * Poll the appropriate bit of the fifo status register until the interface is @@ -698,20 +715,27 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c, return rv; } +#ifdef CONFIG_SYS_I2C static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, - unsigned int speed) + unsigned int speed) +#else +static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +#endif { struct s3c24x0_i2c_bus *i2c_bus; +#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); if (!i2c_bus) - return -1; - + return -EFAULT; +#else + i2c_bus = dev_get_priv(dev); +#endif i2c_bus->clock_frequency = speed; if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EFAULT; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, @@ -721,17 +745,6 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, return 0; } -#ifdef CONFIG_EXYNOS5 -static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) -{ - /* This will override the speed selected in the fdt for that port */ - debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); - if (i2c_set_bus_speed(speed)) - printf("i2c_init: failed to init bus %d for speed = %d\n", - adap->hwadapnr, speed); -} -#endif - /* * cmd_type is 0 for write, 1 for read. * @@ -844,15 +857,23 @@ bailout: return result; } +#ifdef CONFIG_SYS_I2C static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) +#else +static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) +#endif { struct s3c24x0_i2c_bus *i2c_bus; uchar buf[1]; int ret; +#ifdef CONFIG_SYS_I2C i2c_bus = get_bus(adap->hwadapnr); if (!i2c_bus) - return -1; + return -EFAULT; +#else + i2c_bus = dev_get_priv(dev); +#endif buf[0] = 0; /* @@ -871,6 +892,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) return ret != I2C_OK; } +#ifdef CONFIG_SYS_I2C static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int alen, uchar *buffer, int len) { @@ -878,9 +900,13 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret; + i2c_bus = get_bus(adap->hwadapnr); + if (!i2c_bus) + return -EFAULT; + if (alen > 4) { debug("I2C read: addr len %d not supported\n", alen); - return 1; + return -EADDRNOTAVAIL; } if (alen > 0) { @@ -906,10 +932,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len); @@ -921,7 +943,7 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (i2c_bus->is_highspeed) exynos5_i2c_reset(i2c_bus); debug("I2c read failed %d\n", ret); - return 1; + return -EIO; } return 0; } @@ -933,9 +955,13 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, uchar xaddr[4]; int ret; + i2c_bus = get_bus(adap->hwadapnr); + if (!i2c_bus) + return -EFAULT; + if (alen > 4) { debug("I2C write: addr len %d not supported\n", alen); - return 1; + return -EINVAL; } if (alen > 0) { @@ -960,10 +986,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - i2c_bus = get_bus(adap->hwadapnr); - if (!i2c_bus) - return -1; - if (i2c_bus->is_highspeed) ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], alen, buffer, len, true); @@ -985,7 +1007,7 @@ static void process_nodes(const void *blob, int node_list[], int count, int is_highspeed) { struct s3c24x0_i2c_bus *bus; - int i; + int i, flags; for (i = 0; i < count; i++) { int node = node_list[i]; @@ -997,12 +1019,15 @@ static void process_nodes(const void *blob, int node_list[], int count, bus->active = true; bus->is_highspeed = is_highspeed; - if (is_highspeed) + if (is_highspeed) { + flags = PINMUX_FLAG_HS_MODE; bus->hsregs = (struct exynos5_hsi2c *) fdtdec_get_addr(blob, node, "reg"); - else + } else { + flags = 0; bus->regs = (struct s3c24x0_i2c *) fdtdec_get_addr(blob, node, "reg"); + } bus->id = pinmux_decode_periph_id(blob, node); bus->clock_frequency = fdtdec_get_int(blob, node, @@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count, CONFIG_SYS_I2C_S3C24X0_SPEED); bus->node = node; bus->bus_num = i; - exynos_pinmux_config(bus->id, 0); + exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, flags); /* Mark position as used */ node_list[i] = -1; @@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob) COMPAT_SAMSUNG_EXYNOS5_I2C, node_list, CONFIG_MAX_I2C_NUM); process_nodes(blob, node_list, count, 1); - } int i2c_get_bus_num_fdt(int node) @@ -1046,7 +1070,7 @@ int i2c_get_bus_num_fdt(int node) } debug("%s: Can't find any matched I2C bus\n", __func__); - return -1; + return -EINVAL; } int i2c_reset_port_fdt(const void *blob, int node) @@ -1057,18 +1081,18 @@ int i2c_reset_port_fdt(const void *blob, int node) bus = i2c_get_bus_num_fdt(node); if (bus < 0) { debug("could not get bus for node %d\n", node); - return -1; + return bus; } i2c_bus = get_bus(bus); if (!i2c_bus) { - debug("get_bus() failed for node node %d\n", node); - return -1; + debug("get_bus() failed for node %d\n", node); + return -EFAULT; } if (i2c_bus->is_highspeed) { if (hsi2c_get_clk_details(i2c_bus)) - return -1; + return -EINVAL; hsi2c_ch_init(i2c_bus); } else { i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, @@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node) return 0; } -#endif +#endif /* CONFIG_OF_CONTROL */ + +#ifdef CONFIG_EXYNOS5 +static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{ + /* This will override the speed selected in the fdt for that port */ + debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); + if (i2c_set_bus_speed(speed)) + error("i2c_init: failed to init bus for speed = %d", speed); +} +#endif /* CONFIG_EXYNOS5 */ /* * Register s3c24x0 i2c adapters @@ -1247,3 +1281,120 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, CONFIG_SYS_I2C_S3C24X0_SPEED, CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) #endif +#endif /* CONFIG_SYS_I2C */ + +#ifdef CONFIG_DM_I2C +static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len, bool end_with_repeated_start) +{ + int ret; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0, + buffer, len, true); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int i2c_read_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip, + uchar *buffer, int len) +{ + int ret; + + if (i2c_bus->is_highspeed) { + ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len); + if (ret) + exynos5_i2c_reset(i2c_bus); + } else { + ret = i2c_transfer(i2c_bus->regs, I2C_READ, + chip << 1, 0, 0, buffer, len); + } + + return ret != I2C_OK; +} + +static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + int ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_read_data(i2c_bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_write_data(i2c_bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); + int node, flags; + + i2c_bus->is_highspeed = dev->of_id->data; + node = dev->of_offset; + + if (i2c_bus->is_highspeed) { + flags = PINMUX_FLAG_HS_MODE; + i2c_bus->hsregs = (struct exynos5_hsi2c *) + fdtdec_get_addr(blob, node, "reg"); + } else { + flags = 0; + i2c_bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + } + + i2c_bus->id = pinmux_decode_periph_id(blob, node); + + i2c_bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", + CONFIG_SYS_I2C_S3C24X0_SPEED); + i2c_bus->node = node; + i2c_bus->bus_num = dev->seq; + + exynos_pinmux_config(i2c_bus->id, flags); + + i2c_bus->active = true; + + return 0; +} + +static const struct dm_i2c_ops s3c_i2c_ops = { + .xfer = s3c24x0_i2c_xfer, + .probe_chip = s3c24x0_i2c_probe, + .set_bus_speed = s3c24x0_i2c_set_bus_speed, +}; + +static const struct udevice_id s3c_i2c_ids[] = { + { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD }, + { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS }, + { } +}; + +U_BOOT_DRIVER(i2c_s3c) = { + .name = "i2c_s3c", + .id = UCLASS_I2C, + .of_match = s3c_i2c_ids, + .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), + .ops = &s3c_i2c_ops, +}; +#endif /* CONFIG_DM_I2C */ -- cgit From 55df43c941ce8c667c477b849c2b413b51f89b58 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:37 +0100 Subject: odroid u3: dts: add missing i2c aliases This change fixes i2c bus numbering for Odroid U3. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Minkyu Kang --- arch/arm/dts/exynos4412-odroid.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index 29ad6ab20f..00a2917596 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -16,6 +16,13 @@ aliases { i2c0 = "/i2c@13860000"; + i2c1 = "/i2c@13870000"; + i2c2 = "/i2c@13880000"; + i2c3 = "/i2c@13890000"; + i2c4 = "/i2c@138a0000"; + i2c5 = "/i2c@138b0000"; + i2c6 = "/i2c@138c0000"; + i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13810000"; mmc2 = "sdhci@12530000"; -- cgit From 47b37958f6f0f0fafba53480d1ef13143dd0244b Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:38 +0100 Subject: odroid u3: enable dm i2c support This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when the dm pmic framework will be finished. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Minkyu Kang --- board/samsung/odroid/odroid.c | 14 +------------- include/configs/odroid.h | 5 ++--- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index b7d23817e1..e3517f2eb2 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -415,15 +415,6 @@ static int pmic_init_max77686(void) return 0; } -#ifdef CONFIG_SYS_I2C_INIT_BOARD -static void board_init_i2c(void) -{ - /* I2C_0 */ - if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) - debug("I2C%d not configured\n", (I2C_0)); -} -#endif - int exynos_early_init_f(void) { board_clock_init(); @@ -444,10 +435,7 @@ int exynos_init(void) int exynos_power_init(void) { -#ifdef CONFIG_SYS_I2C_INIT_BOARD - board_init_i2c(); -#endif - pmic_init(I2C_0); + pmic_init(0); pmic_init_max77686(); return 0; diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 807e96bbaa..9d5dbdce36 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -177,12 +177,11 @@ /* I2C */ #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -#define CONFIG_MAX_I2C_NUM 8 -#define CONFIG_SYS_I2C_INIT_BOARD /* POWER */ #define CONFIG_POWER -- cgit From 189d80166b31db55b99190be3164c8d3348b57fc Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:39 +0100 Subject: exynos5: enable dm i2c This patch enables CONFIG_DM_I2C and also CONFIG_DM_I2C_COMPAT. The last one should be removed when all the i2c peripheral drivers will use dm i2c framework. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass Cc: Akshay Saraswat Cc: Minkyu Kang Cc: Simon Glass --- include/configs/exynos5-common.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index ad63f3c549..0ba39a23dd 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -126,12 +126,11 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE) /* I2C */ -#define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_SYS_I2C +#define CONFIG_DM_I2C +#define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C -#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0 -#define CONFIG_I2C_MULTI_BUS +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */ #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0 #define CONFIG_I2C_EDID -- cgit From 7132b9fd68a1c76bf557d56dd62756a6607cf761 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 20:29:37 -0700 Subject: dm: i2c: dts: Support an offset-len device tree property Since U-Boot can support different offset lengths (0-4 bytes), add a device tree property to specify this. This avoids hard-coding it in the driver. Signed-off-by: Simon Glass --- doc/device-tree-bindings/i2c/i2c.txt | 28 ++++++++++++++++++++++++++++ drivers/i2c/i2c-uclass.c | 3 ++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 doc/device-tree-bindings/i2c/i2c.txt diff --git a/doc/device-tree-bindings/i2c/i2c.txt b/doc/device-tree-bindings/i2c/i2c.txt new file mode 100644 index 0000000000..ea918dd61d --- /dev/null +++ b/doc/device-tree-bindings/i2c/i2c.txt @@ -0,0 +1,28 @@ +U-Boot I2C +---------- + +U-Boot's I2C model has the concept of an offset within a chip (I2C target +device). The offset can be up to 4 bytes long, but is normally 1 byte, +meaning that offsets from 0 to 255 are supported by the chip. This often +corresponds to register numbers. + +Apart from the controller-specific I2C bindings, U-Boot supports a special +property which allows the chip offset length to be selected. + +Optional properties: +- u-boot,i2c-offset-len - length of chip offset in bytes. If omitted the + default value of 1 is used. + + +Example +------- + +i2c4: i2c@12ca0000 { + cros-ec@1e { + reg = <0x1e>; + compatible = "google,cros-ec"; + i2c-max-frequency = <100000>; + u-boot,i2c-offset-len = <0>; + ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 393cd6f583..eafa457845 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -420,7 +420,8 @@ int i2c_deblock(struct udevice *bus) int i2c_chip_ofdata_to_platdata(const void *blob, int node, struct dm_i2c_chip *chip) { - chip->offset_len = 1; /* default */ + chip->offset_len = fdtdec_get_int(gd->fdt_blob, node, + "u-boot,i2c-offset-len", 1); chip->flags = 0; chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1); if (chip->chip_addr == -1) { -- cgit From bd768264fb6d8f91727ed6cad9c3a09c8021cbc5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 20:29:38 -0700 Subject: dm: exynos: dts: Set the offset length for cros_ec The EC has no concept of offset, so use a value of 0. Signed-off-by: Simon Glass --- arch/arm/dts/exynos5250-snow.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 649e4bd0d2..7d8be69d73 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -44,6 +44,7 @@ reg = <0x1e>; compatible = "google,cros-ec"; i2c-max-frequency = <100000>; + u-boot,i2c-offset-len = <0>; ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; }; -- cgit From d744d5613639088246b27edb9ce91ccbd663e5a5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 20:29:39 -0700 Subject: dm: i2c: Add two more I2C init functions to the compatibility layer These functions are useful in case the board calls them. Also fix a missing parameter caused by applying the wrong patch (actually I failed to send v2 and applied v1 by mistake). Signed-off-by: Simon Glass --- drivers/i2c/i2c-uclass-compat.c | 14 ++++++++++++-- include/i2c.h | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 841ce0510c..223f238f4b 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -22,8 +22,8 @@ static int i2c_compat_get_device(uint chip_addr, int alen, return ret; chip = dev_get_parent_platdata(*devp); if (chip->offset_len != alen) { - printf("Requested alen %d does not match chip offset_len %d\n", - alen, chip->offset_len); + printf("I2C chip %x: requested alen %d does not match chip offset_len %d\n", + chip_addr, alen, chip->offset_len); return -EADDRNOTAVAIL; } @@ -96,3 +96,13 @@ int i2c_set_bus_num(unsigned int bus) return 0; } + +void i2c_init(int speed, int slaveaddr) +{ + /* Nothing to do here - the init happens through driver model */ +} + +void board_i2c_init(const void *blob) +{ + /* Nothing to do here - the init happens through driver model */ +} diff --git a/include/i2c.h b/include/i2c.h index 95d6f28771..27fe00f173 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -225,7 +225,7 @@ int i2c_get_bus_num_fdt(int node); unsigned int i2c_get_bus_num(void); /** - * i2c_set_bus_num(): Compatibility function for driver model + * i2c_set_bus_num() - Compatibility function for driver model * * Sets the 'current' bus */ @@ -241,6 +241,21 @@ static inline unsigned int I2C_GET_BUS(void) return i2c_get_bus_num(); } +/** + * i2c_init() - Compatibility function for driver model + * + * This function does nothing. + */ +void i2c_init(int speed, int slaveaddr); + +/** + * board_i2c_init() - Compatibility function for driver model + * + * @param blob Device tree blbo + * @return the number of I2C bus + */ +void board_i2c_init(const void *blob); + #endif /* -- cgit From 85df958ce267c602a4ec5f1e41f336c5a8d3b441 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 20:29:40 -0700 Subject: dm: cros_ec: Convert cros_ec_i2c over to driver model Move this driver to use driver model and update the snow configuration to match. Signed-off-by: Simon Glass --- drivers/misc/cros_ec_i2c.c | 82 ++++++++++++++++------------------------------ include/configs/snow.h | 1 + 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c index 513cdb1cb0..f9bc9750d4 100644 --- a/drivers/misc/cros_ec_i2c.c +++ b/drivers/misc/cros_ec_i2c.c @@ -14,6 +14,7 @@ */ #include +#include #include #include @@ -23,11 +24,11 @@ #define debug_trace(fmt, b...) #endif -int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len) +static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, + int cmd_version, const uint8_t *dout, + int dout_len, uint8_t **dinp, int din_len) { - int old_bus = 0; + struct cros_ec_dev *dev = udev->uclass_priv; /* version8, cmd8, arglen8, out8[dout_len], csum8 */ int out_bytes = dout_len + 4; /* response8, arglen8, in8[din_len], checksum8 */ @@ -37,8 +38,6 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, uint8_t *in_ptr; int len, csum, ret; - old_bus = i2c_get_bus_num(); - /* * Sanity-check I/O sizes given transaction overhead in internal * buffers. @@ -86,36 +85,24 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, *ptr++ = (uint8_t) cros_ec_calc_checksum(dev->dout, dout_len + 3); - /* Set to the proper i2c bus */ - if (i2c_set_bus_num(dev->bus_num)) { - debug("%s: Cannot change to I2C bus %d\n", __func__, - dev->bus_num); - return -1; - } - /* Send output data */ cros_ec_dump_data("out", -1, dev->dout, out_bytes); - ret = i2c_write(dev->addr, 0, 0, dev->dout, out_bytes); + ret = dm_i2c_write(udev, 0, dev->dout, out_bytes); if (ret) { - debug("%s: Cannot complete I2C write to 0x%x\n", - __func__, dev->addr); + debug("%s: Cannot complete I2C write to %s\n", __func__, + udev->name); ret = -1; } if (!ret) { - ret = i2c_read(dev->addr, 0, 0, in_ptr, in_bytes); + ret = dm_i2c_read(udev, 0, in_ptr, in_bytes); if (ret) { - debug("%s: Cannot complete I2C read from 0x%x\n", - __func__, dev->addr); + debug("%s: Cannot complete I2C read from %s\n", + __func__, udev->name); ret = -1; } } - /* Return to original bus number */ - i2c_set_bus_num(old_bus); - if (ret) - return ret; - if (*in_ptr != EC_RES_SUCCESS) { debug("%s: Received bad result code %d\n", __func__, *in_ptr); return -(int)*in_ptr; @@ -142,35 +129,24 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, return din_len; } -int cros_ec_i2c_decode_fdt(struct cros_ec_dev *dev, const void *blob) +static int cros_ec_probe(struct udevice *dev) { - /* Decode interface-specific FDT params */ - dev->max_frequency = fdtdec_get_int(blob, dev->node, - "i2c-max-frequency", 100000); - dev->bus_num = i2c_get_bus_num_fdt(dev->parent_node); - if (dev->bus_num == -1) { - debug("%s: Failed to read bus number\n", __func__); - return -1; - } - dev->addr = fdtdec_get_int(blob, dev->node, "reg", -1); - if (dev->addr == -1) { - debug("%s: Failed to read device address\n", __func__); - return -1; - } - - return 0; + return cros_ec_register(dev); } -/** - * Initialize I2C protocol. - * - * @param dev CROS_EC device - * @param blob Device tree blob - * @return 0 if ok, -1 on error - */ -int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob) -{ - i2c_init(dev->max_frequency, dev->addr); - - return 0; -} +static struct dm_cros_ec_ops cros_ec_ops = { + .command = cros_ec_i2c_command, +}; + +static const struct udevice_id cros_ec_ids[] = { + { .compatible = "google,cros-ec" }, + { } +}; + +U_BOOT_DRIVER(cros_ec_i2c) = { + .name = "cros_ec", + .id = UCLASS_CROS_EC, + .of_match = cros_ec_ids, + .probe = cros_ec_probe, + .ops = &cros_ec_ops, +}; diff --git a/include/configs/snow.h b/include/configs/snow.h index 7eaa58697e..ce6676eae7 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -22,6 +22,7 @@ #define CONFIG_CROS_EC_I2C /* Support CROS_EC over I2C */ #define CONFIG_POWER_TPS65090_I2C +#define CONFIG_DM_CROS_EC #define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R -- cgit From a39b1cb7f0ff6be3f39c25b9ec625de2a352da9e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:04:08 +0000 Subject: MIPS: use asm.h macros in mips32 start.S Where the mips32 & mips64 implementations of start.S differ in terms of access sizes & offsets, use the appropriate macros from asm.h to abstract those differences away. This is in preparation for sharing a single copy of start.S between mips32 & mips64. The exception to this is loads of immediates to be written to the cop0 Config register, which is a 32bit register on mips64 and therefore constants written to it can be loaded as such. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 116 +++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 55 deletions(-) diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 36b92cc687..227af6d9a3 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -98,8 +99,8 @@ _start: reset: /* Clear watch registers */ - mtc0 zero, CP0_WATCHLO - mtc0 zero, CP0_WATCHHI + MTC0 zero, CP0_WATCHLO + MTC0 zero, CP0_WATCHHI /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE @@ -116,21 +117,26 @@ reset: mtc0 t0, CP0_CONFIG #endif - /* Initialize $gp */ + /* + * Initialize $gp, force pointer sized alignment of bal instruction to + * forbid the compiler to put nop's between bal and _gp. This is + * required to keep _gp and ra aligned to 8 byte. + */ + .align PTRLOG bal 1f nop - .word _gp + PTR _gp 1: - lw gp, 0(ra) + PTR_L gp, 0(ra) #ifndef CONFIG_SKIP_LOWLEVEL_INIT /* Initialize any external memory */ - la t9, lowlevel_init + PTR_LA t9, lowlevel_init jalr t9 nop /* Initialize caches... */ - la t9, mips_cache_reset + PTR_LA t9, mips_cache_reset jalr t9 nop @@ -140,15 +146,15 @@ reset: #endif /* Set up temporary stack */ - li t0, -16 - li t1, CONFIG_SYS_INIT_SP_ADDR + PTR_LI t0, -16 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR and sp, t1, t0 # force 16 byte alignment - sub sp, sp, GD_SIZE # reserve space for gd + PTR_SUB sp, sp, GD_SIZE # reserve space for gd and sp, sp, t0 # force 16 byte alignment move k0, sp # save gd pointer #ifdef CONFIG_SYS_MALLOC_F_LEN - li t2, CONFIG_SYS_MALLOC_F_LEN - sub sp, sp, t2 # reserve space for early malloc + PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN + PTR_SUB sp, sp, t2 # reserve space for early malloc and sp, sp, t0 # force 16 byte alignment #endif move fp, sp @@ -158,14 +164,14 @@ reset: 1: sw zero, 0(t0) blt t0, t1, 1b - addi t0, 4 + PTR_ADDI t0, 4 #ifdef CONFIG_SYS_MALLOC_F_LEN - addu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset + PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset sw sp, 0(t0) #endif - la t9, board_init_f + PTR_LA t9, board_init_f jr t9 move ra, zero @@ -188,14 +194,14 @@ relocate_code: move s0, a1 # save gd in s0 move s2, a2 # save destination address in s2 - li t0, CONFIG_SYS_MONITOR_BASE - sub s1, s2, t0 # s1 <-- relocation offset + PTR_LI t0, CONFIG_SYS_MONITOR_BASE + PTR_SUB s1, s2, t0 # s1 <-- relocation offset - la t3, in_ram - lw t2, -12(t3) # t2 <-- __image_copy_end + PTR_LA t3, in_ram + PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end move t1, a2 - add gp, s1 # adjust gp + PTR_ADD gp, s1 # adjust gp /* * t0 = source address @@ -205,26 +211,26 @@ relocate_code: 1: lw t3, 0(t0) sw t3, 0(t1) - addu t0, 4 + PTR_ADDU t0, 4 blt t0, t2, 1b - addu t1, 4 + PTR_ADDU t1, 4 /* If caches were enabled, we would have to flush them here. */ - sub a1, t1, s2 # a1 <-- size - la t9, flush_cache + PTR_SUB a1, t1, s2 # a1 <-- size + PTR_LA t9, flush_cache jalr t9 move a0, s2 # a0 <-- destination address /* Jump to where we've relocated ourselves */ - addi t0, s2, in_ram - _start + PTR_ADDI t0, s2, in_ram - _start jr t0 nop - .word __rel_dyn_end - .word __rel_dyn_start - .word __image_copy_end - .word _GLOBAL_OFFSET_TABLE_ - .word num_got_entries + PTR __rel_dyn_end + PTR __rel_dyn_start + PTR __image_copy_end + PTR _GLOBAL_OFFSET_TABLE_ + PTR num_got_entries in_ram: /* @@ -233,46 +239,46 @@ in_ram: * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object * generated by GNU ld. Skip these reserved entries from relocation. */ - lw t3, -4(t0) # t3 <-- num_got_entries - lw t8, -8(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ - add t8, s1 # t8 now holds relocated _G_O_T_ - addi t8, t8, 8 # skipping first two entries - li t2, 2 + PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries + PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ + PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries + PTR_LI t2, 2 1: - lw t1, 0(t8) + PTR_L t1, 0(t8) beqz t1, 2f - add t1, s1 - sw t1, 0(t8) + PTR_ADD t1, s1 + PTR_S t1, 0(t8) 2: - addi t2, 1 + PTR_ADDI t2, 1 blt t2, t3, 1b - addi t8, 4 + PTR_ADDI t8, PTRSIZE /* Update dynamic relocations */ - lw t1, -16(t0) # t1 <-- __rel_dyn_start - lw t2, -20(t0) # t2 <-- __rel_dyn_end + PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start + PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end b 2f # skip first reserved entry - addi t1, 8 + PTR_ADDI t1, 2 * PTRSIZE 1: lw t8, -4(t1) # t8 <-- relocation info - li t3, 3 + PTR_LI t3, 3 bne t8, t3, 2f # skip non R_MIPS_REL32 entries nop - lw t3, -8(t1) # t3 <-- location to fix up in FLASH + PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH - lw t8, 0(t3) # t8 <-- original pointer - add t8, s1 # t8 <-- adjusted pointer + PTR_L t8, 0(t3) # t8 <-- original pointer + PTR_ADD t8, s1 # t8 <-- adjusted pointer - add t3, s1 # t3 <-- location to fix up in RAM - sw t8, 0(t3) + PTR_ADD t3, s1 # t3 <-- location to fix up in RAM + PTR_S t8, 0(t3) 2: blt t1, t2, 1b - addi t1, 8 # each rel.dyn entry is 8 bytes + PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes /* * Clear BSS @@ -280,17 +286,17 @@ in_ram: * GOT is now relocated. Thus __bss_start and __bss_end can be * accessed directly via $gp. */ - la t1, __bss_start # t1 <-- __bss_start - la t2, __bss_end # t2 <-- __bss_end + PTR_LA t1, __bss_start # t1 <-- __bss_start + PTR_LA t2, __bss_end # t2 <-- __bss_end 1: - sw zero, 0(t1) + PTR_S zero, 0(t1) blt t1, t2, 1b - addi t1, 4 + PTR_ADDI t1, PTRSIZE move a0, s0 # a0 <-- gd move a1, s2 - la t9, board_init_r + PTR_LA t9, board_init_r jr t9 move ra, zero -- cgit From ab0d002677185e6a1bcaf92f507d140b96bb1053 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:04:09 +0000 Subject: MIPS: handle mips64 relocs in mips32 start.S In preparation for sharing a single copy of start.S between mips32 & mips64, handle mips64 relocations in the mips32 start.S when built for mips64. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 227af6d9a3..699c59a7d8 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -21,6 +21,21 @@ CONFIG_SYS_INIT_SP_OFFSET) #endif +#ifdef CONFIG_32BIT +# define MIPS_RELOC 3 +#endif + +#ifdef CONFIG_64BIT +# ifdef CONFIG_SYS_LITTLE_ENDIAN +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) +# else +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) +# endif +# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) +#endif + /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using @@ -264,8 +279,8 @@ in_ram: 1: lw t8, -4(t1) # t8 <-- relocation info - PTR_LI t3, 3 - bne t8, t3, 2f # skip non R_MIPS_REL32 entries + PTR_LI t3, MIPS_RELOC + bne t8, t3, 2f # skip non-MIPS_RELOC entries nop PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH -- cgit From f1c64a08106db5ce87b6afe76785e2d4fddcff63 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Thu, 29 Jan 2015 10:04:10 +0000 Subject: MIPS: handle mips64 ST0_KX bit in mips32 start.S In preparation for sharing a single copy of start.S between mips32 & mips64, handle setting the KX bit of the cop0 Status register when the mips32 start.S is built for mips64. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 699c59a7d8..3b5b622abe 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -23,6 +23,7 @@ #ifdef CONFIG_32BIT # define MIPS_RELOC 3 +# define STATUS_SET 0 #endif #ifdef CONFIG_64BIT @@ -34,6 +35,7 @@ ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) # endif # define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) +# define STATUS_SET ST0_KX #endif /* @@ -120,7 +122,7 @@ reset: /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE - setup_c0_status 0 0 + setup_c0_status STATUS_SET 0 /* Init Timer */ mtc0 zero, CP0_COUNT -- cgit From d9a4a6223cc13fb43cbe291a00beeed1c847ed87 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Thu, 29 Jan 2015 14:47:01 +0100 Subject: MIPS: move au1x00 SoC code to arch/mips/mach-au1x00 Move all au1x00 code out of arch/mips/cpu/mips32 to allow unification of CPU code in a later patch. The reorganization of the SoC specific header files will be done in a later patch series. Signed-off-by: Daniel Schwierzeck Cc: Paul Burton --- arch/mips/Makefile | 2 + arch/mips/cpu/mips32/Makefile | 2 - arch/mips/cpu/mips32/au1x00/Makefile | 8 - arch/mips/cpu/mips32/au1x00/au1x00_eth.c | 296 ----- arch/mips/cpu/mips32/au1x00/au1x00_ide.c | 15 - arch/mips/cpu/mips32/au1x00/au1x00_serial.c | 131 -- arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c | 1609 ------------------------- arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h | 416 ------- arch/mips/cpu/mips32/au1x00/config.mk | 8 - arch/mips/cpu/mips32/cpu.c | 8 - arch/mips/mach-au1x00/Makefile | 8 + arch/mips/mach-au1x00/au1x00_eth.c | 302 +++++ arch/mips/mach-au1x00/au1x00_ide.c | 15 + arch/mips/mach-au1x00/au1x00_serial.c | 131 ++ arch/mips/mach-au1x00/au1x00_usb_ohci.c | 1609 +++++++++++++++++++++++++ arch/mips/mach-au1x00/au1x00_usb_ohci.h | 416 +++++++ arch/mips/mach-au1x00/config.mk | 8 + 17 files changed, 2491 insertions(+), 2493 deletions(-) delete mode 100644 arch/mips/cpu/mips32/au1x00/Makefile delete mode 100644 arch/mips/cpu/mips32/au1x00/au1x00_eth.c delete mode 100644 arch/mips/cpu/mips32/au1x00/au1x00_ide.c delete mode 100644 arch/mips/cpu/mips32/au1x00/au1x00_serial.c delete mode 100644 arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c delete mode 100644 arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h delete mode 100644 arch/mips/cpu/mips32/au1x00/config.mk create mode 100644 arch/mips/mach-au1x00/Makefile create mode 100644 arch/mips/mach-au1x00/au1x00_eth.c create mode 100644 arch/mips/mach-au1x00/au1x00_ide.c create mode 100644 arch/mips/mach-au1x00/au1x00_serial.c create mode 100644 arch/mips/mach-au1x00/au1x00_usb_ohci.c create mode 100644 arch/mips/mach-au1x00/au1x00_usb_ohci.h create mode 100644 arch/mips/mach-au1x00/config.mk diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 0a9e7e614b..ff01bfef20 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -8,3 +8,5 @@ head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/ libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/ libs-y += arch/mips/lib/ + +libs-$(CONFIG_SOC_AU1X00) += arch/mips/mach-au1x00/ diff --git a/arch/mips/cpu/mips32/Makefile b/arch/mips/cpu/mips32/Makefile index 19d316ab75..cb4db9c71b 100644 --- a/arch/mips/cpu/mips32/Makefile +++ b/arch/mips/cpu/mips32/Makefile @@ -7,5 +7,3 @@ extra-y = start.o obj-y = cpu.o interrupts.o time.o - -obj-$(CONFIG_SOC_AU1X00) += au1x00/ diff --git a/arch/mips/cpu/mips32/au1x00/Makefile b/arch/mips/cpu/mips32/au1x00/Makefile deleted file mode 100644 index c5643e713b..0000000000 --- a/arch/mips/cpu/mips32/au1x00/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2011 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o au1x00_ide.o diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_eth.c b/arch/mips/cpu/mips32/au1x00/au1x00_eth.c deleted file mode 100644 index 4770f563aa..0000000000 --- a/arch/mips/cpu/mips32/au1x00/au1x00_eth.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Only eth0 supported for now - * - * (C) Copyright 2003 - * Thomas.Lange@corelatus.se - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include - -#if defined(CONFIG_SYS_DISCOVER_PHY) -#error "PHY not supported yet" -/* We just assume that we are running 100FD for now */ -/* We all use switches, right? ;-) */ -#endif - -/* I assume ethernet behaves like au1000 */ - -#ifdef CONFIG_SOC_AU1000 -/* Base address differ between cpu:s */ -#define ETH0_BASE AU1000_ETH0_BASE -#define MAC0_ENABLE AU1000_MAC0_ENABLE -#else -#ifdef CONFIG_SOC_AU1100 -#define ETH0_BASE AU1100_ETH0_BASE -#define MAC0_ENABLE AU1100_MAC0_ENABLE -#else -#ifdef CONFIG_SOC_AU1500 -#define ETH0_BASE AU1500_ETH0_BASE -#define MAC0_ENABLE AU1500_MAC0_ENABLE -#else -#ifdef CONFIG_SOC_AU1550 -#define ETH0_BASE AU1550_ETH0_BASE -#define MAC0_ENABLE AU1550_MAC0_ENABLE -#else -#error "No valid cpu set" -#endif -#endif -#endif -#endif - -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_CMD_MII) -#include -#endif - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 -#define PKT_MAXBUF_SIZE 1518 - -static char txbuf[DBUF_LENGTH]; - -static int next_tx; -static int next_rx; - -/* 4 rx and 4 tx fifos */ -#define NO_OF_FIFOS 4 - -typedef struct{ - u32 status; - u32 addr; - u32 len; /* Only used for tx */ - u32 not_used; -} mac_fifo_t; - -mac_fifo_t mac_fifo[NO_OF_FIFOS]; - -#define MAX_WAIT 1000 - -#if defined(CONFIG_CMD_MII) -int au1x00_miiphy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short * value) -{ - volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); - volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); - u32 mii_control; - unsigned int timedout = 20; - - while (*mii_control_reg & MAC_MII_BUSY) { - udelay(1000); - if (--timedout == 0) { - printf("au1x00_eth: miiphy_read busy timeout!!\n"); - return -1; - } - } - - mii_control = MAC_SET_MII_SELECT_REG(reg) | - MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ; - - *mii_control_reg = mii_control; - - timedout = 20; - while (*mii_control_reg & MAC_MII_BUSY) { - udelay(1000); - if (--timedout == 0) { - printf("au1x00_eth: miiphy_read busy timeout!!\n"); - return -1; - } - } - *value = *mii_data_reg; - return 0; -} - -int au1x00_miiphy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); - volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); - u32 mii_control; - unsigned int timedout = 20; - - while (*mii_control_reg & MAC_MII_BUSY) { - udelay(1000); - if (--timedout == 0) { - printf("au1x00_eth: miiphy_write busy timeout!!\n"); - return -1; - } - } - - mii_control = MAC_SET_MII_SELECT_REG(reg) | - MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE; - - *mii_data_reg = value; - *mii_control_reg = mii_control; - return 0; -} -#endif - -static int au1x00_send(struct eth_device *dev, void *packet, int length) -{ - volatile mac_fifo_t *fifo_tx = - (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS); - int i; - int res; - - /* tx fifo should always be idle */ - fifo_tx[next_tx].len = length; - fifo_tx[next_tx].addr = (virt_to_phys(packet))|TX_DMA_ENABLE; - au_sync(); - - udelay(1); - i=0; - while(!(fifo_tx[next_tx].addr&TX_T_DONE)){ - if(i>MAX_WAIT){ - printf("TX timeout\n"); - break; - } - udelay(1); - i++; - } - - /* Clear done bit */ - fifo_tx[next_tx].addr = 0; - fifo_tx[next_tx].len = 0; - au_sync(); - - res = fifo_tx[next_tx].status; - - next_tx++; - if(next_tx>=NO_OF_FIFOS){ - next_tx=0; - } - return(res); -} - -static int au1x00_recv(struct eth_device* dev){ - volatile mac_fifo_t *fifo_rx = - (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS); - - int length; - u32 status; - - for(;;){ - if(!(fifo_rx[next_rx].addr&RX_T_DONE)){ - /* Nothing has been received */ - return(-1); - } - - status = fifo_rx[next_rx].status; - - length = status&0x3FFF; - - if(status&RX_ERROR){ - printf("Rx error 0x%x\n", status); - } - else{ - /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[next_rx], length - 4); - } - - fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE; - - next_rx++; - if(next_rx>=NO_OF_FIFOS){ - next_rx=0; - } - } /* for */ - - return(0); /* Does anyone use this? */ -} - -static int au1x00_init(struct eth_device* dev, bd_t * bd){ - - volatile u32 *macen = (volatile u32*)MAC0_ENABLE; - volatile u32 *mac_ctrl = (volatile u32*)(ETH0_BASE+MAC_CONTROL); - volatile u32 *mac_addr_high = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_HIGH); - volatile u32 *mac_addr_low = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_LOW); - volatile u32 *mac_mcast_high = (volatile u32*)(ETH0_BASE+MAC_MCAST_HIGH); - volatile u32 *mac_mcast_low = (volatile u32*)(ETH0_BASE+MAC_MCAST_LOW); - volatile mac_fifo_t *fifo_tx = - (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS); - volatile mac_fifo_t *fifo_rx = - (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS); - int i; - - next_tx = TX_GET_DMA_BUFFER(fifo_tx[0].addr); - next_rx = RX_GET_DMA_BUFFER(fifo_rx[0].addr); - - /* We have to enable clocks before releasing reset */ - *macen = MAC_EN_CLOCK_ENABLE; - udelay(10); - - /* Enable MAC0 */ - /* We have to release reset before accessing registers */ - *macen = MAC_EN_CLOCK_ENABLE|MAC_EN_RESET0| - MAC_EN_RESET1|MAC_EN_RESET2; - udelay(10); - - for(i=0;ienetaddr - *mac_addr_high = (ea[5] << 8) | (ea[4] ) ; - *mac_addr_low = (ea[3] << 24) | (ea[2] << 16) | - (ea[1] << 8) | (ea[0] ) ; -#undef ea - *mac_mcast_low = 0; - *mac_mcast_high = 0; - - /* Make sure the MAC buffer is in the correct endian mode */ -#ifdef __LITTLE_ENDIAN - *mac_ctrl = MAC_FULL_DUPLEX; - udelay(1); - *mac_ctrl = MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE; -#else - *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX; - udelay(1); - *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE; -#endif - - return(1); -} - -static void au1x00_halt(struct eth_device* dev){ - volatile u32 *macen = (volatile u32*)MAC0_ENABLE; - - /* Put MAC0 in reset */ - *macen = 0; -} - -int au1x00_enet_initialize(bd_t *bis){ - struct eth_device* dev; - - if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) { - puts ("malloc failed\n"); - return -1; - } - - memset(dev, 0, sizeof *dev); - - sprintf(dev->name, "Au1X00 ethernet"); - dev->iobase = 0; - dev->priv = 0; - dev->init = au1x00_init; - dev->halt = au1x00_halt; - dev->send = au1x00_send; - dev->recv = au1x00_recv; - - eth_register(dev); - -#if defined(CONFIG_CMD_MII) - miiphy_register(dev->name, - au1x00_miiphy_read, au1x00_miiphy_write); -#endif - - return 1; -} diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_ide.c b/arch/mips/cpu/mips32/au1x00/au1x00_ide.c deleted file mode 100644 index ba0b35df5d..0000000000 --- a/arch/mips/cpu/mips32/au1x00/au1x00_ide.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * (C) Copyright 2000-2011 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -/* AU1X00 swaps data in big-endian mode, enforce little-endian function */ -void ide_input_swap_data(int dev, ulong *sect_buf, int words) -{ - ide_input_data(dev, sect_buf, words); -} diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_serial.c b/arch/mips/cpu/mips32/au1x00/au1x00_serial.c deleted file mode 100644 index 046350826a..0000000000 --- a/arch/mips/cpu/mips32/au1x00/au1x00_serial.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * AU1X00 UART support - * - * Hardcoded to UART 0 for now - * Speed and options also hardcoded to 115200 8N1 - * - * Copyright (c) 2003 Thomas.Lange@corelatus.se - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/****************************************************************************** -* -* serial_init - initialize a channel -* -* This routine initializes the number of data bits, parity -* and set the selected baud rate. Interrupts are disabled. -* Set the modem control signals if the option is selected. -* -* RETURNS: N/A -*/ - -static int au1x00_serial_init(void) -{ - volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR); - volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE); - - /* Enable clocks first */ - *uart_enable = UART_EN_CE; - - /* Then release reset */ - /* Must release reset before setting other regs */ - *uart_enable = UART_EN_CE|UART_EN_E; - - /* Activate fifos, reset tx and rx */ - /* Set tx trigger level to 12 */ - *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR| - UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12; - - serial_setbrg(); - - return 0; -} - - -static void au1x00_serial_setbrg(void) -{ - volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK); - volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR); - volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL; - int sd; - int divisorx2; - - /* sd is system clock divisor */ - /* see section 10.4.5 in au1550 datasheet */ - sd = (*sys_powerctrl & 0x03) + 2; - - /* calulate 2x baudrate and round */ - divisorx2 = ((CONFIG_SYS_MIPS_TIMER_FREQ/(sd * 16 * CONFIG_BAUDRATE))); - - if (divisorx2 & 0x01) - divisorx2 = divisorx2 + 1; - - *uart_clk = divisorx2 / 2; - - /* Set parity, stop bits and word length to 8N1 */ - *uart_lcr = UART_LCR_WLEN8; -} - -static void au1x00_serial_putc(const char c) -{ - volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); - volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX); - - if (c == '\n') - au1x00_serial_putc('\r'); - - /* Wait for fifo to shift out some bytes */ - while((*uart_lsr&UART_LSR_THRE)==0); - - *uart_tx = (u32)c; -} - -static int au1x00_serial_getc(void) -{ - volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX); - char c; - - while (!serial_tstc()); - - c = (*uart_rx&0xFF); - return c; -} - -static int au1x00_serial_tstc(void) -{ - volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); - - if(*uart_lsr&UART_LSR_DR){ - /* Data in rfifo */ - return(1); - } - return 0; -} - -static struct serial_device au1x00_serial_drv = { - .name = "au1x00_serial", - .start = au1x00_serial_init, - .stop = NULL, - .setbrg = au1x00_serial_setbrg, - .putc = au1x00_serial_putc, - .puts = default_serial_puts, - .getc = au1x00_serial_getc, - .tstc = au1x00_serial_tstc, -}; - -void au1x00_serial_initialize(void) -{ - serial_register(&au1x00_serial_drv); -} - -__weak struct serial_device *default_serial_console(void) -{ - return &au1x00_serial_drv; -} diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c deleted file mode 100644 index 74bdb77303..0000000000 --- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB on the AU1x00. - * - * (C) Copyright 2003 - * Gary Jennejohn, DENX Software Engineering - * - * SPDX-License-Identifier: GPL-2.0+ - * Note: Part of this code has been derived from linux - * - */ -/* - * IMPORTANT NOTES - * 1 - this driver is intended for use with USB Mass Storage Devices - * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! - */ - -#include - -#ifdef CONFIG_USB_OHCI - -/* #include no PCI on the AU1x00 */ - -#include -#include -#include -#include -#include -#include "au1x00_usb_ohci.h" - -#define OHCI_USE_NPS /* force NoPowerSwitching mode */ -#define OHCI_VERBOSE_DEBUG /* not always helpful */ -#define OHCI_FILL_TRACE - -#define USBH_ENABLE_BE (1<<0) -#define USBH_ENABLE_C (1<<1) -#define USBH_ENABLE_E (1<<2) -#define USBH_ENABLE_CE (1<<3) -#define USBH_ENABLE_RD (1<<4) - -#ifdef __LITTLE_ENDIAN -#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) -#else -#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE) -#endif - - -/* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE - -#undef readl -#undef writel - -#define readl(a) au_readl((long)(a)) -#define writel(v,a) au_writel((v),(int)(a)) - -#define DEBUG -#ifdef DEBUG -#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) -#else -#define dbg(format, arg...) do {} while(0) -#endif /* DEBUG */ -#define err(format, arg...) printf("ERROR: " format "\n", ## arg) -#define SHOW_INFO -#ifdef SHOW_INFO -#define info(format, arg...) printf("INFO: " format "\n", ## arg) -#else -#define info(format, arg...) do {} while(0) -#endif - -#define m16_swap(x) swap_16(x) -#define m32_swap(x) swap_32(x) - -/* global ohci_t */ -static ohci_t gohci; -/* this must be aligned to a 256 byte boundary */ -struct ohci_hcca ghcca[1]; -/* a pointer to the aligned storage */ -struct ohci_hcca *phcca; -/* this allocates EDs for all possible endpoints */ -struct ohci_device ohci_dev; -/* urb_priv */ -urb_priv_t urb_priv; -/* RHSC flag */ -int got_rhsc; -/* device which was disconnected */ -struct usb_device *devgone; - -/*-------------------------------------------------------------------------*/ - -/* AMD-756 (D2 rev) reports corrupt register contents in some cases. - * The erratum (#4) description is incorrect. AMD's workaround waits - * till some bits (mostly reserved) are clear; ok for all revs. - */ -#define OHCI_QUIRK_AMD756 0xabcd -#define read_roothub(hc, register, mask) ({ \ - u32 temp = readl (&hc->regs->roothub.register); \ - if (hc->flags & OHCI_QUIRK_AMD756) \ - while (temp & mask) \ - temp = readl (&hc->regs->roothub.register); \ - temp; }) - -static u32 roothub_a (struct ohci *hc) - { return read_roothub (hc, a, 0xfc0fe000); } -static inline u32 roothub_b (struct ohci *hc) - { return readl (&hc->regs->roothub.b); } -static inline u32 roothub_status (struct ohci *hc) - { return readl (&hc->regs->roothub.status); } -static u32 roothub_portstatus (struct ohci *hc, int i) - { return read_roothub (hc, portstatus [i], 0xffe0fce0); } - - -/* forward declaration */ -static int hc_interrupt (void); -static void -td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, - int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval); - -/*-------------------------------------------------------------------------* - * URB support functions - *-------------------------------------------------------------------------*/ - -/* free HCD-private data associated with this URB */ - -static void urb_free_priv (urb_priv_t * urb) -{ - int i; - int last; - struct td * td; - - last = urb->length - 1; - if (last >= 0) { - for (i = 0; i <= last; i++) { - td = urb->td[i]; - if (td) { - td->usb_dev = NULL; - urb->td[i] = NULL; - } - } - } -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -static int sohci_get_current_frame_number (struct usb_device * dev); - -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header */ - -static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer, - int transfer_len, struct devrequest * setup, char * str, int small) -{ - urb_priv_t * purb = &urb_priv; - - dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", - str, - sohci_get_current_frame_number (dev), - usb_pipedevice (pipe), - usb_pipeendpoint (pipe), - usb_pipeout (pipe)? 'O': 'I', - usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): - (usb_pipecontrol (pipe)? "CTRL": "BULK"), - purb->actual_length, - transfer_len, dev->status); -#ifdef OHCI_VERBOSE_DEBUG - if (!small) { - int i, len; - - if (usb_pipecontrol (pipe)) { - printf (__FILE__ ": cmd(8):"); - for (i = 0; i < 8 ; i++) - printf (" %02x", ((__u8 *) setup) [i]); - printf ("\n"); - } - if (transfer_len > 0 && buffer) { - printf (__FILE__ ": data(%d/%d):", - purb->actual_length, - transfer_len); - len = usb_pipeout (pipe)? - transfer_len: purb->actual_length; - for (i = 0; i < 16 && i < len; i++) - printf (" %02x", ((__u8 *) buffer) [i]); - printf ("%s\n", i < len? "...": ""); - } - } -#endif -} - -/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ -void ep_print_int_eds (ohci_t *ohci, char * str) { - int i, j; - __u32 * ed_p; - for (i= 0; i < 32; i++) { - j = 5; - ed_p = &(ohci->hcca->int_table [i]); - if (*ed_p == 0) - continue; - printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); - while (*ed_p != 0 && j--) { - ed_t *ed = (ed_t *)m32_swap(ed_p); - printf (" ed: %4x;", ed->hwINFO); - ed_p = &ed->hwNextED; - } - printf ("\n"); - } -} - -static void ohci_dump_intr_mask (char *label, __u32 mask) -{ - dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", - label, - mask, - (mask & OHCI_INTR_MIE) ? " MIE" : "", - (mask & OHCI_INTR_OC) ? " OC" : "", - (mask & OHCI_INTR_RHSC) ? " RHSC" : "", - (mask & OHCI_INTR_FNO) ? " FNO" : "", - (mask & OHCI_INTR_UE) ? " UE" : "", - (mask & OHCI_INTR_RD) ? " RD" : "", - (mask & OHCI_INTR_SF) ? " SF" : "", - (mask & OHCI_INTR_WDH) ? " WDH" : "", - (mask & OHCI_INTR_SO) ? " SO" : "" - ); -} - -static void maybe_print_eds (char *label, __u32 value) -{ - ed_t *edp = (ed_t *)value; - - if (value) { - dbg ("%s %08x", label, value); - dbg ("%08x", edp->hwINFO); - dbg ("%08x", edp->hwTailP); - dbg ("%08x", edp->hwHeadP); - dbg ("%08x", edp->hwNextED); - } -} - -static char * hcfs2string (int state) -{ - switch (state) { - case OHCI_USB_RESET: return "reset"; - case OHCI_USB_RESUME: return "resume"; - case OHCI_USB_OPER: return "operational"; - case OHCI_USB_SUSPEND: return "suspend"; - } - return "?"; -} - -/* dump control and status registers */ -static void ohci_dump_status (ohci_t *controller) -{ - struct ohci_regs *regs = controller->regs; - __u32 temp; - - temp = readl (®s->revision) & 0xff; - if (temp != 0x10) - dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); - - temp = readl (®s->control); - dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, - (temp & OHCI_CTRL_RWE) ? " RWE" : "", - (temp & OHCI_CTRL_RWC) ? " RWC" : "", - (temp & OHCI_CTRL_IR) ? " IR" : "", - hcfs2string (temp & OHCI_CTRL_HCFS), - (temp & OHCI_CTRL_BLE) ? " BLE" : "", - (temp & OHCI_CTRL_CLE) ? " CLE" : "", - (temp & OHCI_CTRL_IE) ? " IE" : "", - (temp & OHCI_CTRL_PLE) ? " PLE" : "", - temp & OHCI_CTRL_CBSR - ); - - temp = readl (®s->cmdstatus); - dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, - (temp & OHCI_SOC) >> 16, - (temp & OHCI_OCR) ? " OCR" : "", - (temp & OHCI_BLF) ? " BLF" : "", - (temp & OHCI_CLF) ? " CLF" : "", - (temp & OHCI_HCR) ? " HCR" : "" - ); - - ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); - ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); - - maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); - - maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); - maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); - - maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); - maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); - - maybe_print_eds ("donehead", readl (®s->donehead)); -} - -static void ohci_dump_roothub (ohci_t *controller, int verbose) -{ - __u32 temp, ndp, i; - - temp = roothub_a (controller); - ndp = (temp & RH_A_NDP); - - if (verbose) { - dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, - ((temp & RH_A_POTPGT) >> 24) & 0xff, - (temp & RH_A_NOCP) ? " NOCP" : "", - (temp & RH_A_OCPM) ? " OCPM" : "", - (temp & RH_A_DT) ? " DT" : "", - (temp & RH_A_NPS) ? " NPS" : "", - (temp & RH_A_PSM) ? " PSM" : "", - ndp - ); - temp = roothub_b (controller); - dbg ("roothub.b: %08x PPCM=%04x DR=%04x", - temp, - (temp & RH_B_PPCM) >> 16, - (temp & RH_B_DR) - ); - temp = roothub_status (controller); - dbg ("roothub.status: %08x%s%s%s%s%s%s", - temp, - (temp & RH_HS_CRWE) ? " CRWE" : "", - (temp & RH_HS_OCIC) ? " OCIC" : "", - (temp & RH_HS_LPSC) ? " LPSC" : "", - (temp & RH_HS_DRWE) ? " DRWE" : "", - (temp & RH_HS_OCI) ? " OCI" : "", - (temp & RH_HS_LPS) ? " LPS" : "" - ); - } - - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", - i, - temp, - (temp & RH_PS_PRSC) ? " PRSC" : "", - (temp & RH_PS_OCIC) ? " OCIC" : "", - (temp & RH_PS_PSSC) ? " PSSC" : "", - (temp & RH_PS_PESC) ? " PESC" : "", - (temp & RH_PS_CSC) ? " CSC" : "", - - (temp & RH_PS_LSDA) ? " LSDA" : "", - (temp & RH_PS_PPS) ? " PPS" : "", - (temp & RH_PS_PRS) ? " PRS" : "", - (temp & RH_PS_POCI) ? " POCI" : "", - (temp & RH_PS_PSS) ? " PSS" : "", - - (temp & RH_PS_PES) ? " PES" : "", - (temp & RH_PS_CCS) ? " CCS" : "" - ); - } -} - -static void ohci_dump (ohci_t *controller, int verbose) -{ - dbg ("OHCI controller usb-%s state", controller->slot_name); - - /* dumps some of the state we know about */ - ohci_dump_status (controller); - if (verbose) - ep_print_int_eds (controller, "hcca"); - dbg ("hcca frame #%04x", controller->hcca->frame_no); - ohci_dump_roothub (controller, 1); -} - - -#endif /* DEBUG */ - -/*-------------------------------------------------------------------------* - * Interface functions (URB) - *-------------------------------------------------------------------------*/ - -/* get a transfer request */ - -int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - ohci_t *ohci; - ed_t * ed; - urb_priv_t *purb_priv; - int i, size = 0; - - ohci = &gohci; - - /* when controller's hung, permit only roothub cleanup attempts - * such as powering down ports */ - if (ohci->disabled) { - err("sohci_submit_job: EPIPE"); - return -1; - } - - /* every endpoint has a ed, locate and fill it */ - if (!(ed = ep_add_ed (dev, pipe))) { - err("sohci_submit_job: ENOMEM"); - return -1; - } - - /* for the private part of the URB we need the number of TDs (size) */ - switch (usb_pipetype (pipe)) { - case PIPE_BULK: /* one TD for every 4096 Byte */ - size = (transfer_len - 1) / 4096 + 1; - break; - case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ - size = (transfer_len == 0)? 2: - (transfer_len - 1) / 4096 + 3; - break; - } - - if (size >= (N_URB_TD - 1)) { - err("need %d TDs, only have %d", size, N_URB_TD); - return -1; - } - purb_priv = &urb_priv; - purb_priv->pipe = pipe; - - /* fill the private part of the URB */ - purb_priv->length = size; - purb_priv->ed = ed; - purb_priv->actual_length = 0; - - /* allocate the TDs */ - /* note that td[0] was allocated in ep_add_ed */ - for (i = 0; i < size; i++) { - purb_priv->td[i] = td_alloc (dev); - if (!purb_priv->td[i]) { - purb_priv->length = i; - urb_free_priv (purb_priv); - err("sohci_submit_job: ENOMEM"); - return -1; - } - } - - if (ed->state == ED_NEW || (ed->state & ED_DEL)) { - urb_free_priv (purb_priv); - err("sohci_submit_job: EINVAL"); - return -1; - } - - /* link the ed into a chain if is not already */ - if (ed->state != ED_OPER) - ep_link (ohci, ed); - - /* fill the TDs and link it to the ed */ - td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -#ifdef DEBUG -/* tell us the current USB frame number */ - -static int sohci_get_current_frame_number (struct usb_device *usb_dev) -{ - ohci_t *ohci = &gohci; - - return m16_swap (ohci->hcca->frame_no); -} -#endif - -/*-------------------------------------------------------------------------* - * ED handling functions - *-------------------------------------------------------------------------*/ - -/* link an ed into one of the HC chains */ - -static int ep_link (ohci_t *ohci, ed_t *edi) -{ - volatile ed_t *ed = edi; - - ed->state = ED_OPER; - - switch (ed->type) { - case PIPE_CONTROL: - ed->hwNextED = 0; - if (ohci->ed_controltail == NULL) { - writel ((long)ed, &ohci->regs->ed_controlhead); - } else { - ohci->ed_controltail->hwNextED = m32_swap (ed); - } - ed->ed_prev = ohci->ed_controltail; - if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_controltail = edi; - break; - - case PIPE_BULK: - ed->hwNextED = 0; - if (ohci->ed_bulktail == NULL) { - writel ((long)ed, &ohci->regs->ed_bulkhead); - } else { - ohci->ed_bulktail->hwNextED = m32_swap (ed); - } - ed->ed_prev = ohci->ed_bulktail; - if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && - !ohci->ed_rm_list[1] && !ohci->sleeping) { - ohci->hc_control |= OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - ohci->ed_bulktail = edi; - break; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* unlink an ed from one of the HC chains. - * just the link to the ed is unlinked. - * the link from the ed still points to another operational ed or 0 - * so the HC can eventually finish the processing of the unlinked ed */ - -static int ep_unlink (ohci_t *ohci, ed_t *ed) -{ - ed->hwINFO |= m32_swap (OHCI_ED_SKIP); - - switch (ed->type) { - case PIPE_CONTROL: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_CLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_controltail == ed) { - ohci->ed_controltail = ed->ed_prev; - } else { - ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - - case PIPE_BULK: - if (ed->ed_prev == NULL) { - if (!ed->hwNextED) { - ohci->hc_control &= ~OHCI_CTRL_BLE; - writel (ohci->hc_control, &ohci->regs->control); - } - writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); - } else { - ed->ed_prev->hwNextED = ed->hwNextED; - } - if (ohci->ed_bulktail == ed) { - ohci->ed_bulktail = ed->ed_prev; - } else { - ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; - } - break; - } - ed->state = ED_UNLINK; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, - * but the USB stack is a little bit stateless so we do it at every transaction - * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK - * in all other cases the state is left unchanged - * the ed info fields are setted anyway even though most of them should not change */ - -static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe) -{ - td_t *td; - ed_t *ed_ret; - volatile ed_t *ed; - - ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | - (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; - - if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { - err("ep_add_ed: pending delete"); - /* pending delete request */ - return NULL; - } - - if (ed->state == ED_NEW) { - ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */ - /* dummy td; end of td list for ed */ - td = td_alloc (usb_dev); - ed->hwTailP = m32_swap (td); - ed->hwHeadP = ed->hwTailP; - ed->state = ED_UNLINK; - ed->type = usb_pipetype (pipe); - ohci_dev.ed_cnt++; - } - - ed->hwINFO = m32_swap (usb_pipedevice (pipe) - | usb_pipeendpoint (pipe) << 7 - | (usb_pipeisoc (pipe)? 0x8000: 0) - | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) - | (usb_dev->speed == USB_SPEED_LOW) << 13 - | usb_maxpacket (usb_dev, pipe) << 16); - - return ed_ret; -} - -/*-------------------------------------------------------------------------* - * TD handling functions - *-------------------------------------------------------------------------*/ - -/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ - -static void td_fill (ohci_t *ohci, unsigned int info, - void *data, int len, - struct usb_device *dev, int index, urb_priv_t *urb_priv) -{ - volatile td_t *td, *td_pt; -#ifdef OHCI_FILL_TRACE - int i; -#endif - - if (index > urb_priv->length) { - err("index > length"); - return; - } - /* use this td as the next dummy */ - td_pt = urb_priv->td [index]; - td_pt->hwNextTD = 0; - - /* fill the old dummy TD */ - td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf); - - td->ed = urb_priv->ed; - td->next_dl_td = NULL; - td->index = index; - td->data = (__u32)data; -#ifdef OHCI_FILL_TRACE - if (1 || (usb_pipebulk(urb_priv->pipe) && - usb_pipeout(urb_priv->pipe))) { - for (i = 0; i < len; i++) - printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]); - } -#endif - if (!len) - data = 0; - - td->hwINFO = m32_swap (info); - td->hwCBP = m32_swap (data); - if (data) - td->hwBE = m32_swap (data + len - 1); - else - td->hwBE = 0; - td->hwNextTD = m32_swap (td_pt); - td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000); - - /* append to queue */ - td->ed->hwTailP = td->hwNextTD; -} - -/*-------------------------------------------------------------------------*/ - -/* prepare all TDs of a transfer */ - -#define kseg_to_phys(x) ((void *)((__u32)(x) - 0x80000000)) - -static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval) -{ - ohci_t *ohci = &gohci; - int data_len = transfer_len; - void *data; - int cnt = 0; - __u32 info = 0; - unsigned int toggle = 0; - - /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ - if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { - toggle = TD_T_TOGGLE; - } else { - toggle = TD_T_DATA0; - usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); - } - urb->td_cnt = 0; - if (data_len) - data = kseg_to_phys(buffer); - else - data = 0; - - switch (usb_pipetype (pipe)) { - case PIPE_BULK: - info = usb_pipeout (pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; - while(data_len > 4096) { - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); - data += 4096; data_len -= 4096; cnt++; - } - info = usb_pipeout (pipe)? - TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; - td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); - cnt++; - - if (!ohci->sleeping) - writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ - break; - - case PIPE_CONTROL: - info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (ohci, info, kseg_to_phys(setup), 8, dev, cnt++, urb); - if (data_len > 0) { - info = usb_pipeout (pipe)? - TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; - /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (ohci, info, data, data_len, dev, cnt++, urb); - } - info = usb_pipeout (pipe)? - TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (ohci, info, data, 0, dev, cnt++, urb); - if (!ohci->sleeping) - writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ - break; - } - if (urb->length != cnt) - dbg("TD LENGTH %d != CNT %d", urb->length, cnt); -} - -/*-------------------------------------------------------------------------* - * Done List handling functions - *-------------------------------------------------------------------------*/ - - -/* calculate the transfer length and update the urb */ - -static void dl_transfer_length(td_t * td) -{ - __u32 tdINFO, tdBE, tdCBP; - urb_priv_t *lurb_priv = &urb_priv; - - tdINFO = m32_swap (td->hwINFO); - tdBE = m32_swap (td->hwBE); - tdCBP = m32_swap (td->hwCBP); - - - if (!(usb_pipecontrol(lurb_priv->pipe) && - ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { - if (tdBE != 0) { - if (td->hwCBP == 0) - lurb_priv->actual_length += tdBE - td->data + 1; - else - lurb_priv->actual_length += tdCBP - td->data; - } - } -} - -/*-------------------------------------------------------------------------*/ - -/* replies to the request have to be on a FIFO basis so - * we reverse the reversed done-list */ - -static td_t * dl_reverse_done_list (ohci_t *ohci) -{ - __u32 td_list_hc; - td_t *td_rev = NULL; - td_t *td_list = NULL; - urb_priv_t *lurb_priv = NULL; - - td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0; - ohci->hcca->done_head = 0; - - while (td_list_hc) { - td_list = (td_t *)td_list_hc; - - if (TD_CC_GET (m32_swap (td_list->hwINFO))) { - lurb_priv = &urb_priv; - dbg(" USB-error/status: %x : %p", - TD_CC_GET (m32_swap (td_list->hwINFO)), td_list); - if (td_list->ed->hwHeadP & m32_swap (0x1)) { - if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { - td_list->ed->hwHeadP = - (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) | - (td_list->ed->hwHeadP & m32_swap (0x2)); - lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; - } else - td_list->ed->hwHeadP &= m32_swap (0xfffffff2); - } - } - - td_list->next_dl_td = td_rev; - td_rev = td_list; - td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0; - } - return td_list; -} - -/*-------------------------------------------------------------------------*/ - -/* td done list */ -static int dl_done_list (ohci_t *ohci, td_t *td_list) -{ - td_t *td_list_next = NULL; - ed_t *ed; - int cc = 0; - int stat = 0; - /* urb_t *urb; */ - urb_priv_t *lurb_priv; - __u32 tdINFO, edHeadP, edTailP; - - while (td_list) { - td_list_next = td_list->next_dl_td; - - lurb_priv = &urb_priv; - tdINFO = m32_swap (td_list->hwINFO); - - ed = td_list->ed; - - dl_transfer_length(td_list); - - /* error code of transfer */ - cc = TD_CC_GET (tdINFO); - if (cc != 0) { - dbg("ConditionCode %#x", cc); - stat = cc_to_error[cc]; - } - - if (ed->state != ED_NEW) { - edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0; - edTailP = m32_swap (ed->hwTailP); - - /* unlink eds if they are not busy */ - if ((edHeadP == edTailP) && (ed->state == ED_OPER)) - ep_unlink (ohci, ed); - } - - td_list = td_list_next; - } - return stat; -} - -/*-------------------------------------------------------------------------* - * Virtual Root Hub - *-------------------------------------------------------------------------*/ - -#include - -/* Hub class-specific descriptor is constructed dynamically */ - - -/*-------------------------------------------------------------------------*/ - -#define OK(x) len = (x); break -#ifdef DEBUG -#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} -#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} -#else -#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) -#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) -#endif -#define RD_RH_STAT roothub_status(&gohci) -#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1) - -/* request to virtual root hub */ - -int rh_check_port_status(ohci_t *controller) -{ - __u32 temp, ndp, i; - int res; - - res = -1; - temp = roothub_a (controller); - ndp = (temp & RH_A_NDP); - for (i = 0; i < ndp; i++) { - temp = roothub_portstatus (controller, i); - /* check for a device disconnect */ - if (((temp & (RH_PS_PESC | RH_PS_CSC)) == - (RH_PS_PESC | RH_PS_CSC)) && - ((temp & RH_PS_CCS) == 0)) { - res = i; - break; - } - } - return res; -} - -static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, struct devrequest *cmd) -{ - void * data = buffer; - int leni = transfer_len; - int len = 0; - int stat = 0; - __u32 datab[4]; - __u8 *data_buf = (__u8 *)datab; - __u16 bmRType_bReq; - __u16 wValue; - __u16 wIndex; - __u16 wLength; - -#ifdef DEBUG -urb_priv.actual_length = 0; -pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); -#else - mdelay(1); -#endif - if (usb_pipeint(pipe)) { - info("Root-Hub submit IRQ: NOT implemented"); - return 0; - } - - bmRType_bReq = cmd->requesttype | (cmd->request << 8); - wValue = m16_swap (cmd->value); - wIndex = m16_swap (cmd->index); - wLength = m16_swap (cmd->length); - - info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", - dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(__u16 *) data_buf = m16_swap (1); OK (2); - case RH_GET_STATUS | RH_INTERFACE: - *(__u16 *) data_buf = m16_swap (0); OK (2); - case RH_GET_STATUS | RH_ENDPOINT: - *(__u16 *) data_buf = m16_swap (0); OK (2); - case RH_GET_STATUS | RH_CLASS: - *(__u32 *) data_buf = m32_swap ( - RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); - OK (4); - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4); - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case RH_C_HUB_LOCAL_POWER: - OK(0); - case (RH_C_HUB_OVER_CURRENT): - WR_RH_STAT(RH_HS_OCIC); OK (0); - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_POCI); OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); - case (RH_C_PORT_CONNECTION): - WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); - case (RH_C_PORT_ENABLE): - WR_RH_PORTSTAT (RH_PS_PESC); OK (0); - case (RH_C_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); - case (RH_C_PORT_OVER_CURRENT): - WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); - case (RH_C_PORT_RESET): - WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); - } - break; - - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); - case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PRS); - OK (0); - case (RH_PORT_POWER): - WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); - case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ - if (RD_RH_PORTSTAT & RH_PS_CCS) - WR_RH_PORTSTAT (RH_PS_PES ); - OK (0); - } - break; - - case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_dev_des), - wLength)); - data_buf = root_hub_dev_des; OK(len); - case (0x02): /* configuration descriptor */ - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_config_des), - wLength)); - data_buf = root_hub_config_des; OK(len); - case (0x03): /* string descriptors */ - if(wValue==0x0300) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index0), - wLength)); - data_buf = root_hub_str_index0; - OK(len); - } - if(wValue==0x0301) { - len = min_t(unsigned int, - leni, - min_t(unsigned int, - sizeof (root_hub_str_index1), - wLength)); - data_buf = root_hub_str_index1; - OK(len); - } - default: - stat = USB_ST_STALLED; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - { - __u32 temp = roothub_a (&gohci); - - data_buf [0] = 9; /* min length; */ - data_buf [1] = 0x29; - data_buf [2] = temp & RH_A_NDP; - data_buf [3] = 0; - if (temp & RH_A_PSM) /* per-port power switching? */ - data_buf [3] |= 0x1; - if (temp & RH_A_NOCP) /* no overcurrent reporting? */ - data_buf [3] |= 0x10; - else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ - data_buf [3] |= 0x8; - - /* corresponds to data_buf[4-7] */ - datab [1] = 0; - data_buf [5] = (temp & RH_A_POTPGT) >> 24; - temp = roothub_b (&gohci); - data_buf [7] = temp & RH_B_DR; - if (data_buf [2] < 7) { - data_buf [8] = 0xff; - } else { - data_buf [0] += 2; - data_buf [8] = (temp & RH_B_DR) >> 8; - data_buf [10] = data_buf [9] = 0xff; - } - - len = min_t(unsigned int, leni, - min_t(unsigned int, data_buf [0], wLength)); - OK (len); - } - - case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); - - case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); - - default: - dbg ("unsupported root hub command"); - stat = USB_ST_STALLED; - } - -#ifdef DEBUG - ohci_dump_roothub (&gohci, 1); -#else - mdelay(1); -#endif - - len = min_t(int, len, leni); - if (data != data_buf) - memcpy (data, data_buf, len); - dev->act_len = len; - dev->status = stat; - -#ifdef DEBUG - if (transfer_len) - urb_priv.actual_length = transfer_len; - pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); -#else - mdelay(1); -#endif - - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/* common code for handling submit messages - used for all but root hub */ -/* accesses. */ -int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup, int interval) -{ - int stat = 0; - int maxsize = usb_maxpacket(dev, pipe); - int timeout; - - /* device pulled? Shortcut the action. */ - if (devgone == dev) { - dev->status = USB_ST_CRC_ERR; - return 0; - } - -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); -#else - mdelay(1); -#endif - if (!maxsize) { - err("submit_common_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - - if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) { - err("sohci_submit_job failed"); - return -1; - } - - mdelay(10); - /* ohci_dump_status(&gohci); */ - - /* allow more time for a BULK device to react - some are slow */ -#define BULK_TO 5000 /* timeout in milliseconds */ - if (usb_pipebulk(pipe)) - timeout = BULK_TO; - else - timeout = 100; - - timeout *= 4; - /* wait for it to complete */ - for (;;) { - /* check whether the controller is done */ - stat = hc_interrupt(); - if (stat < 0) { - stat = USB_ST_CRC_ERR; - break; - } - if (stat >= 0 && stat != 0xff) { - /* 0xff is returned for an SF-interrupt */ - break; - } - if (--timeout) { - udelay(250); /* mdelay(1); */ - } else { - err("CTL:TIMEOUT "); - stat = USB_ST_CRC_ERR; - break; - } - } - /* we got an Root Hub Status Change interrupt */ - if (got_rhsc) { -#ifdef DEBUG - ohci_dump_roothub (&gohci, 1); -#endif - got_rhsc = 0; - /* abuse timeout */ - timeout = rh_check_port_status(&gohci); - if (timeout >= 0) { -#if 0 /* this does nothing useful, but leave it here in case that changes */ - /* the called routine adds 1 to the passed value */ - usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); -#endif - /* - * XXX - * This is potentially dangerous because it assumes - * that only one device is ever plugged in! - */ - devgone = dev; - } - } - - dev->status = stat; - dev->act_len = transfer_len; - -#ifdef DEBUG - pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); -#else - mdelay(1); -#endif - - /* free TDs in urb_priv */ - urb_free_priv (&urb_priv); - return 0; -} - -/* submit routines called from usb.c */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len) -{ - info("submit_bulk_msg"); - return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); -} - -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup) -{ - int maxsize = usb_maxpacket(dev, pipe); - - info("submit_control_msg"); -#ifdef DEBUG - urb_priv.actual_length = 0; - pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); -#else - mdelay(1); -#endif - if (!maxsize) { - err("submit_control_message: pipesize for pipe %lx is zero", - pipe); - return -1; - } - if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { - gohci.rh.dev = dev; - /* root hub - redirect */ - return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, - setup); - } - - return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); -} - -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval) -{ - info("submit_int_msg"); - return -1; -} - -/*-------------------------------------------------------------------------* - * HC functions - *-------------------------------------------------------------------------*/ - -/* reset the HC and BUS */ - -static int hc_reset (ohci_t *ohci) -{ - int timeout = 30; - int smm_timeout = 50; /* 0,5 sec */ - - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ - info("USB HC TakeOver from SMM"); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { - mdelay (10); - if (--smm_timeout == 0) { - err("USB HC TakeOver failed!"); - return -1; - } - } - } - - /* Disable HC interrupts */ - writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); - - dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", - ohci->slot_name, - readl (&ohci->regs->control)); - - /* Reset USB (needed by some controllers) */ - writel (0, &ohci->regs->control); - - /* HC Reset requires max 10 us delay */ - writel (OHCI_HCR, &ohci->regs->cmdstatus); - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { - if (--timeout == 0) { - err("USB HC reset timed out!"); - return -1; - } - udelay (1); - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* Start an OHCI controller, set the BUS operational - * enable interrupts - * connect the virtual root hub */ - -static int hc_start (ohci_t * ohci) -{ - __u32 mask; - unsigned int fminterval; - - ohci->disabled = 1; - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - - writel (0, &ohci->regs->ed_controlhead); - writel (0, &ohci->regs->ed_bulkhead); - - writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ - - fminterval = 0x2edf; - writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); - fminterval |= ((((fminterval - 210) * 6) / 7) << 16); - writel (fminterval, &ohci->regs->fminterval); - writel (0x628, &ohci->regs->lsthresh); - - /* start controller operations */ - ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; - ohci->disabled = 0; - writel (ohci->hc_control, &ohci->regs->control); - - /* disable all interrupts */ - mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | - OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | - OHCI_INTR_OC | OHCI_INTR_MIE); - writel (mask, &ohci->regs->intrdisable); - /* clear all interrupts */ - mask &= ~OHCI_INTR_MIE; - writel (mask, &ohci->regs->intrstatus); - /* Choose the interrupts we care about now - but w/o MIE */ - mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; - writel (mask, &ohci->regs->intrenable); - -#ifdef OHCI_USE_NPS - /* required for AMD-756 and some Mac platforms */ - writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, - &ohci->regs->roothub.a); - writel (RH_HS_LPSC, &ohci->regs->roothub.status); -#endif /* OHCI_USE_NPS */ - - /* POTPGT delay is bits 24-31, in 2 ms units. */ - mdelay ((roothub_a (ohci) >> 23) & 0x1fe); - - /* connect the virtual root hub */ - ohci->rh.devnum = 0; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -/* an interrupt happens */ - -static int -hc_interrupt (void) -{ - ohci_t *ohci = &gohci; - struct ohci_regs *regs = ohci->regs; - int ints; - int stat = -1; - - if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) { - ints = OHCI_INTR_WDH; - } else { - ints = readl (®s->intrstatus); - } - - /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ - - if (ints & OHCI_INTR_RHSC) { - got_rhsc = 1; - } - - if (ints & OHCI_INTR_UE) { - ohci->disabled++; - err ("OHCI Unrecoverable Error, controller usb-%s disabled", - ohci->slot_name); - /* e.g. due to PCI Master/Target Abort */ - -#ifdef DEBUG - ohci_dump (ohci, 1); -#else - mdelay(1); -#endif - /* FIXME: be optimistic, hope that bug won't repeat often. */ - /* Make some non-interrupt context restart the controller. */ - /* Count and limit the retries though; either hardware or */ - /* software errors can go forever... */ - hc_reset (ohci); - return -1; - } - - if (ints & OHCI_INTR_WDH) { - mdelay(1); - writel (OHCI_INTR_WDH, ®s->intrdisable); - stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); - writel (OHCI_INTR_WDH, ®s->intrenable); - } - - if (ints & OHCI_INTR_SO) { - dbg("USB Schedule overrun\n"); - writel (OHCI_INTR_SO, ®s->intrenable); - stat = -1; - } - - /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ - if (ints & OHCI_INTR_SF) { - unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1; - mdelay(1); - writel (OHCI_INTR_SF, ®s->intrdisable); - if (ohci->ed_rm_list[frame] != NULL) - writel (OHCI_INTR_SF, ®s->intrenable); - stat = 0xff; - } - - writel (ints, ®s->intrstatus); - return stat; -} - -/*-------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ - -/* De-allocate all resources.. */ - -static void hc_release_ohci (ohci_t *ohci) -{ - dbg ("USB HC release ohci usb-%s", ohci->slot_name); - - if (!ohci->disabled) - hc_reset (ohci); -} - -/*-------------------------------------------------------------------------*/ - -#define __read_32bit_c0_register(source, sel) \ -({ int __res; \ - if (sel == 0) \ - __asm__ __volatile__( \ - "mfc0\t%0, " #source "\n\t" \ - : "=r" (__res)); \ - else \ - __asm__ __volatile__( \ - ".set\tmips32\n\t" \ - "mfc0\t%0, " #source ", " #sel "\n\t" \ - ".set\tmips0\n\t" \ - : "=r" (__res)); \ - __res; \ -}) - -#define read_c0_prid() __read_32bit_c0_register($15, 0) - -/* - * low level initalisation routine, called from usb.c - */ -static char ohci_inited = 0; - -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) -{ - u32 pin_func; - u32 sys_freqctrl, sys_clksrc; - u32 prid = read_c0_prid(); - - dbg("in usb_lowlevel_init\n"); - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD clocks */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - - switch (prid & 0x000000FF) { - case 0x00: /* DA */ - case 0x01: /* HA */ - case 0x02: /* HB */ - /* CPU core freq to 48MHz to slow it way down... */ - au_writel(4, SYS_CPUPLL); - - /* - * Setup 48MHz FREQ2 from CPUPLL for USB Host - */ - /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ - sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* CPU core freq to 384MHz */ - au_writel(0x20, SYS_CPUPLL); - - printf("Au1000: 48MHz OHCI workaround enabled\n"); - break; - - default: /* HC and newer */ - /* FREQ2 = aux/2 = 48 MHz */ - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - break; - } - - /* - * Route 48MHz FREQ2 into USB Host and/or Device - */ - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); - au_writel(sys_clksrc, SYS_CLKSRC); - - /* configure pins GPIO[14:9] as GPIO */ - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); - - au_writel(pin_func, SYS_PINFUNC); - au_writel(0x2800, SYS_TRIOUTCLR); - au_writel(0x0030, SYS_OUTPUTCLR); - - dbg("OHCI board setup complete\n"); - - /* enable host controller */ - au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); - udelay(1000); - au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG); - udelay(1000); - - /* wait for reset complete (read register twice; see au1500 errata) */ - while (au_readl(USB_HOST_CONFIG), - !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) - udelay(1000); - - dbg("OHCI clock running\n"); - - memset (&gohci, 0, sizeof (ohci_t)); - memset (&urb_priv, 0, sizeof (urb_priv_t)); - - /* align the storage */ - if ((__u32)&ghcca[0] & 0xff) { - err("HCCA not aligned!!"); - return -1; - } - phcca = &ghcca[0]; - info("aligned ghcca %p", phcca); - memset(&ohci_dev, 0, sizeof(struct ohci_device)); - if ((__u32)&ohci_dev.ed[0] & 0x7) { - err("EDs not aligned!!"); - return -1; - } - memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1)); - if ((__u32)gtd & 0x7) { - err("TDs not aligned!!"); - return -1; - } - ptd = gtd; - gohci.hcca = phcca; - memset (phcca, 0, sizeof (struct ohci_hcca)); - - gohci.disabled = 1; - gohci.sleeping = 0; - gohci.irq = -1; - gohci.regs = (struct ohci_regs *)(USB_OHCI_BASE | 0xA0000000); - - gohci.flags = 0; - gohci.slot_name = "au1x00"; - - dbg("OHCI revision: 0x%08x\n" - " RH: a: 0x%08x b: 0x%08x\n", - readl(&gohci.regs->revision), - readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b)); - - if (hc_reset (&gohci) < 0) - goto errout; - - /* FIXME this is a second HC reset; why?? */ - writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control); - mdelay (10); - - if (hc_start (&gohci) < 0) - goto errout; - -#ifdef DEBUG - ohci_dump (&gohci, 1); -#else - mdelay(1); -#endif - ohci_inited = 1; - return 0; - - errout: - err("OHCI initialization error\n"); - hc_release_ohci (&gohci); - /* Initialization failed */ - au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); - return -1; -} - -int usb_lowlevel_stop(int index) -{ - /* this gets called really early - before the controller has */ - /* even been initialized! */ - if (!ohci_inited) - return 0; - /* TODO release any interrupts, etc. */ - /* call hc_release_ohci() here ? */ - hc_reset (&gohci); - /* may not want to do this */ - /* Disable clock */ - au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); - return 0; -} - -#endif /* CONFIG_USB_OHCI */ diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h deleted file mode 100644 index bb9f351099..0000000000 --- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * URB OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2001 David Brownell - * - * usb-ohci.h - */ - - -static int cc_to_error[16] = { - -/* mapping of the OHCI CC status to error codes */ - /* No Error */ 0, - /* CRC Error */ USB_ST_CRC_ERR, - /* Bit Stuff */ USB_ST_BIT_ERR, - /* Data Togg */ USB_ST_CRC_ERR, - /* Stall */ USB_ST_STALLED, - /* DevNotResp */ -1, - /* PIDCheck */ USB_ST_BIT_ERR, - /* UnExpPID */ USB_ST_BIT_ERR, - /* DataOver */ USB_ST_BUF_ERR, - /* DataUnder */ USB_ST_BUF_ERR, - /* reservd */ -1, - /* reservd */ -1, - /* BufferOver */ USB_ST_BUF_ERR, - /* BuffUnder */ USB_ST_BUF_ERR, - /* Not Access */ -1, - /* Not Access */ -1 -}; - -/* ED States */ - -#define ED_NEW 0x00 -#define ED_UNLINK 0x01 -#define ED_OPER 0x02 -#define ED_DEL 0x04 -#define ED_URB_DEL 0x08 - -/* usb_ohci_ed */ -struct ed { - __u32 hwINFO; - __u32 hwTailP; - __u32 hwHeadP; - __u32 hwNextED; - - struct ed *ed_prev; - __u8 int_period; - __u8 int_branch; - __u8 int_load; - __u8 int_interval; - __u8 state; - __u8 type; - __u16 last_iso; - struct ed *ed_rm_list; - - struct usb_device *usb_dev; - __u32 unused[3]; -} __attribute__((aligned(16))); -typedef struct ed ed_t; - - -/* TD info field */ -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_R 0x00040000 -#define TD_DI 0x00E00000 -#define TD_DI_SET(X) (((X) & 0x07)<< 21) -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_ISO 0x00010000 -#define TD_DEL 0x00020000 - -/* CC Codes */ -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEM 0x03 -#define TD_CC_STALL 0x04 -#define TD_DEVNOTRESP 0x05 -#define TD_PIDCHECKFAIL 0x06 -#define TD_UNEXPECTEDPID 0x07 -#define TD_DATAOVERRUN 0x08 -#define TD_DATAUNDERRUN 0x09 -#define TD_BUFFEROVERRUN 0x0C -#define TD_BUFFERUNDERRUN 0x0D -#define TD_NOTACCESSED 0x0F - - -#define MAXPSW 1 - -struct td { - __u32 hwINFO; - __u32 hwCBP; /* Current Buffer Pointer */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ - - __u16 hwPSW[MAXPSW]; - __u8 unused; - __u8 index; - struct ed *ed; - struct td *next_dl_td; - struct usb_device *usb_dev; - int transfer_len; - __u32 data; - - __u32 unused2[2]; -} __attribute__((aligned(32))); -typedef struct td td_t; - -#define OHCI_ED_SKIP (1 << 14) - -/* - * The HCCA (Host Controller Communications Area) is a 256 byte - * structure defined in the OHCI spec. that the host controller is - * told the base address of. It must be 256-byte aligned. - */ - -#define NUM_INTS 32 /* part of the OHCI standard */ -struct ohci_hcca { - __u32 int_table[NUM_INTS]; /* Interrupt ED table */ - __u16 frame_no; /* current frame number */ - __u16 pad1; /* set to 0 on each frame_no change */ - __u32 done_head; /* info returned for an interrupt */ - u8 reserved_for_hc[116]; -} __attribute__((aligned(256))); - - -/* - * Maximum number of root hub ports. - */ -#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ - -/* - * This is the structure of the OHCI controller's memory mapped I/O - * region. This is Memory Mapped I/O. You must use the readl() and - * writel() macros defined in asm/io.h to access these!! - */ -struct ohci_regs { - /* control and status registers */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; - /* memory pointers */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; - /* frame counters */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; - /* Root hub ports */ - struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; - __u32 portstatus[MAX_ROOT_PORTS]; - } roothub; -} __attribute__((aligned(32))); - - -/* OHCI CONTROL AND STATUS REGISTER MASKS */ - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_CLF (1 << 1) /* control list filled */ -#define OHCI_BLF (1 << 2) /* bulk list filled */ -#define OHCI_OCR (1 << 3) /* ownership change request */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - - -/* Virtual Root HUB */ -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void *dev; /* was urb */ - void *int_addr; - int send; - int interval; -}; - -/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ - -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 - -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - - -/* OHCI ROOT HUB REGISTER MASKS */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status*/ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -/* urb */ -#define N_URB_TD 48 -typedef struct -{ - ed_t *ed; - __u16 length; /* number of tds associated with this request */ - __u16 td_cnt; /* number of tds already serviced */ - int state; - unsigned long pipe; - int actual_length; - td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ -} urb_priv_t; -#define URB_DEL 1 - -/* - * This is the full ohci controller description - * - * Note how the "proper" USB information is just - * a subset of what the full implementation needs. (Linus) - */ - - -typedef struct ohci { - struct ohci_hcca *hcca; /* hcca */ - /*dma_addr_t hcca_dma;*/ - - int irq; - int disabled; /* e.g. got a UE, we're hung */ - int sleeping; - unsigned long flags; /* for HC bugs */ - - struct ohci_regs *regs; /* OHCI controller's memory */ - - ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ - ed_t *ed_bulktail; /* last endpoint of bulk list */ - ed_t *ed_controltail; /* last endpoint of control list */ - int intrstatus; - __u32 hc_control; /* copy of the hc control reg */ - struct usb_device *dev[32]; - struct virt_root_hub rh; - - const char *slot_name; -} ohci_t; - -#define NUM_EDS 8 /* num of preallocated endpoint descriptors */ - -struct ohci_device { - ed_t ed[NUM_EDS]; - int ed_cnt; -}; - -/* hcd */ -/* endpoint */ -static int ep_link(ohci_t * ohci, ed_t * ed); -static int ep_unlink(ohci_t * ohci, ed_t * ed); -static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe); - -/*-------------------------------------------------------------------------*/ - -/* we need more TDs than EDs */ -#define NUM_TD 64 - -/* +1 so we can align the storage */ -td_t gtd[NUM_TD+1]; -/* pointers to aligned storage */ -td_t *ptd; - -/* TDs ... */ -static inline struct td * -td_alloc (struct usb_device *usb_dev) -{ - int i; - struct td *td; - - td = NULL; - for (i = 0; i < NUM_TD; i++) { - if (ptd[i].usb_dev == NULL) { - td = &ptd[i]; - td->usb_dev = usb_dev; - break; - } - } - return td; -} - -static inline void -ed_free (struct ed *ed) -{ - ed->usb_dev = NULL; -} diff --git a/arch/mips/cpu/mips32/au1x00/config.mk b/arch/mips/cpu/mips32/au1x00/config.mk deleted file mode 100644 index 5c89129d8c..0000000000 --- a/arch/mips/cpu/mips32/au1x00/config.mk +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2011 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -PLATFORM_CPPFLAGS += -mtune=4kc diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 8e1cc4e1fe..07deca86f7 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -32,11 +32,3 @@ void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) write_c0_index(index); tlb_write_indexed(); } - -int cpu_eth_init(bd_t *bis) -{ -#ifdef CONFIG_SOC_AU1X00 - au1x00_enet_initialize(bis); -#endif - return 0; -} diff --git a/arch/mips/mach-au1x00/Makefile b/arch/mips/mach-au1x00/Makefile new file mode 100644 index 0000000000..c5643e713b --- /dev/null +++ b/arch/mips/mach-au1x00/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2011 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o au1x00_ide.o diff --git a/arch/mips/mach-au1x00/au1x00_eth.c b/arch/mips/mach-au1x00/au1x00_eth.c new file mode 100644 index 0000000000..39c5b6bc4a --- /dev/null +++ b/arch/mips/mach-au1x00/au1x00_eth.c @@ -0,0 +1,302 @@ +/* Only eth0 supported for now + * + * (C) Copyright 2003 + * Thomas.Lange@corelatus.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +#if defined(CONFIG_SYS_DISCOVER_PHY) +#error "PHY not supported yet" +/* We just assume that we are running 100FD for now */ +/* We all use switches, right? ;-) */ +#endif + +/* I assume ethernet behaves like au1000 */ + +#ifdef CONFIG_SOC_AU1000 +/* Base address differ between cpu:s */ +#define ETH0_BASE AU1000_ETH0_BASE +#define MAC0_ENABLE AU1000_MAC0_ENABLE +#else +#ifdef CONFIG_SOC_AU1100 +#define ETH0_BASE AU1100_ETH0_BASE +#define MAC0_ENABLE AU1100_MAC0_ENABLE +#else +#ifdef CONFIG_SOC_AU1500 +#define ETH0_BASE AU1500_ETH0_BASE +#define MAC0_ENABLE AU1500_MAC0_ENABLE +#else +#ifdef CONFIG_SOC_AU1550 +#define ETH0_BASE AU1550_ETH0_BASE +#define MAC0_ENABLE AU1550_MAC0_ENABLE +#else +#error "No valid cpu set" +#endif +#endif +#endif +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CMD_MII) +#include +#endif + +/* Ethernet Transmit and Receive Buffers */ +#define DBUF_LENGTH 1520 +#define PKT_MAXBUF_SIZE 1518 + +static char txbuf[DBUF_LENGTH]; + +static int next_tx; +static int next_rx; + +/* 4 rx and 4 tx fifos */ +#define NO_OF_FIFOS 4 + +typedef struct{ + u32 status; + u32 addr; + u32 len; /* Only used for tx */ + u32 not_used; +} mac_fifo_t; + +mac_fifo_t mac_fifo[NO_OF_FIFOS]; + +#define MAX_WAIT 1000 + +#if defined(CONFIG_CMD_MII) +int au1x00_miiphy_read(const char *devname, unsigned char addr, + unsigned char reg, unsigned short * value) +{ + volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); + volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); + u32 mii_control; + unsigned int timedout = 20; + + while (*mii_control_reg & MAC_MII_BUSY) { + udelay(1000); + if (--timedout == 0) { + printf("au1x00_eth: miiphy_read busy timeout!!\n"); + return -1; + } + } + + mii_control = MAC_SET_MII_SELECT_REG(reg) | + MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_READ; + + *mii_control_reg = mii_control; + + timedout = 20; + while (*mii_control_reg & MAC_MII_BUSY) { + udelay(1000); + if (--timedout == 0) { + printf("au1x00_eth: miiphy_read busy timeout!!\n"); + return -1; + } + } + *value = *mii_data_reg; + return 0; +} + +int au1x00_miiphy_write(const char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); + volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); + u32 mii_control; + unsigned int timedout = 20; + + while (*mii_control_reg & MAC_MII_BUSY) { + udelay(1000); + if (--timedout == 0) { + printf("au1x00_eth: miiphy_write busy timeout!!\n"); + return -1; + } + } + + mii_control = MAC_SET_MII_SELECT_REG(reg) | + MAC_SET_MII_SELECT_PHY(addr) | MAC_MII_WRITE; + + *mii_data_reg = value; + *mii_control_reg = mii_control; + return 0; +} +#endif + +static int au1x00_send(struct eth_device *dev, void *packet, int length) +{ + volatile mac_fifo_t *fifo_tx = + (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS); + int i; + int res; + + /* tx fifo should always be idle */ + fifo_tx[next_tx].len = length; + fifo_tx[next_tx].addr = (virt_to_phys(packet))|TX_DMA_ENABLE; + au_sync(); + + udelay(1); + i=0; + while(!(fifo_tx[next_tx].addr&TX_T_DONE)){ + if(i>MAX_WAIT){ + printf("TX timeout\n"); + break; + } + udelay(1); + i++; + } + + /* Clear done bit */ + fifo_tx[next_tx].addr = 0; + fifo_tx[next_tx].len = 0; + au_sync(); + + res = fifo_tx[next_tx].status; + + next_tx++; + if(next_tx>=NO_OF_FIFOS){ + next_tx=0; + } + return(res); +} + +static int au1x00_recv(struct eth_device* dev){ + volatile mac_fifo_t *fifo_rx = + (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS); + + int length; + u32 status; + + for(;;){ + if(!(fifo_rx[next_rx].addr&RX_T_DONE)){ + /* Nothing has been received */ + return(-1); + } + + status = fifo_rx[next_rx].status; + + length = status&0x3FFF; + + if(status&RX_ERROR){ + printf("Rx error 0x%x\n", status); + } + else{ + /* Pass the packet up to the protocol layers. */ + NetReceive(NetRxPackets[next_rx], length - 4); + } + + fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE; + + next_rx++; + if(next_rx>=NO_OF_FIFOS){ + next_rx=0; + } + } /* for */ + + return(0); /* Does anyone use this? */ +} + +static int au1x00_init(struct eth_device* dev, bd_t * bd){ + + volatile u32 *macen = (volatile u32*)MAC0_ENABLE; + volatile u32 *mac_ctrl = (volatile u32*)(ETH0_BASE+MAC_CONTROL); + volatile u32 *mac_addr_high = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_HIGH); + volatile u32 *mac_addr_low = (volatile u32*)(ETH0_BASE+MAC_ADDRESS_LOW); + volatile u32 *mac_mcast_high = (volatile u32*)(ETH0_BASE+MAC_MCAST_HIGH); + volatile u32 *mac_mcast_low = (volatile u32*)(ETH0_BASE+MAC_MCAST_LOW); + volatile mac_fifo_t *fifo_tx = + (volatile mac_fifo_t*)(MAC0_TX_DMA_ADDR+MAC_TX_BUFF0_STATUS); + volatile mac_fifo_t *fifo_rx = + (volatile mac_fifo_t*)(MAC0_RX_DMA_ADDR+MAC_RX_BUFF0_STATUS); + int i; + + next_tx = TX_GET_DMA_BUFFER(fifo_tx[0].addr); + next_rx = RX_GET_DMA_BUFFER(fifo_rx[0].addr); + + /* We have to enable clocks before releasing reset */ + *macen = MAC_EN_CLOCK_ENABLE; + udelay(10); + + /* Enable MAC0 */ + /* We have to release reset before accessing registers */ + *macen = MAC_EN_CLOCK_ENABLE|MAC_EN_RESET0| + MAC_EN_RESET1|MAC_EN_RESET2; + udelay(10); + + for(i=0;ienetaddr + *mac_addr_high = (ea[5] << 8) | (ea[4] ) ; + *mac_addr_low = (ea[3] << 24) | (ea[2] << 16) | + (ea[1] << 8) | (ea[0] ) ; +#undef ea + *mac_mcast_low = 0; + *mac_mcast_high = 0; + + /* Make sure the MAC buffer is in the correct endian mode */ +#ifdef __LITTLE_ENDIAN + *mac_ctrl = MAC_FULL_DUPLEX; + udelay(1); + *mac_ctrl = MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE; +#else + *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX; + udelay(1); + *mac_ctrl = MAC_BIG_ENDIAN|MAC_FULL_DUPLEX|MAC_RX_ENABLE|MAC_TX_ENABLE; +#endif + + return(1); +} + +static void au1x00_halt(struct eth_device* dev){ + volatile u32 *macen = (volatile u32*)MAC0_ENABLE; + + /* Put MAC0 in reset */ + *macen = 0; +} + +int au1x00_enet_initialize(bd_t *bis){ + struct eth_device* dev; + + if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) { + puts ("malloc failed\n"); + return -1; + } + + memset(dev, 0, sizeof *dev); + + sprintf(dev->name, "Au1X00 ethernet"); + dev->iobase = 0; + dev->priv = 0; + dev->init = au1x00_init; + dev->halt = au1x00_halt; + dev->send = au1x00_send; + dev->recv = au1x00_recv; + + eth_register(dev); + +#if defined(CONFIG_CMD_MII) + miiphy_register(dev->name, + au1x00_miiphy_read, au1x00_miiphy_write); +#endif + + return 1; +} + +int cpu_eth_init(bd_t *bis) +{ + au1x00_enet_initialize(bis); + return 0; +} diff --git a/arch/mips/mach-au1x00/au1x00_ide.c b/arch/mips/mach-au1x00/au1x00_ide.c new file mode 100644 index 0000000000..ba0b35df5d --- /dev/null +++ b/arch/mips/mach-au1x00/au1x00_ide.c @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +/* AU1X00 swaps data in big-endian mode, enforce little-endian function */ +void ide_input_swap_data(int dev, ulong *sect_buf, int words) +{ + ide_input_data(dev, sect_buf, words); +} diff --git a/arch/mips/mach-au1x00/au1x00_serial.c b/arch/mips/mach-au1x00/au1x00_serial.c new file mode 100644 index 0000000000..046350826a --- /dev/null +++ b/arch/mips/mach-au1x00/au1x00_serial.c @@ -0,0 +1,131 @@ +/* + * AU1X00 UART support + * + * Hardcoded to UART 0 for now + * Speed and options also hardcoded to 115200 8N1 + * + * Copyright (c) 2003 Thomas.Lange@corelatus.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/****************************************************************************** +* +* serial_init - initialize a channel +* +* This routine initializes the number of data bits, parity +* and set the selected baud rate. Interrupts are disabled. +* Set the modem control signals if the option is selected. +* +* RETURNS: N/A +*/ + +static int au1x00_serial_init(void) +{ + volatile u32 *uart_fifoctl = (volatile u32*)(UART0_ADDR+UART_FCR); + volatile u32 *uart_enable = (volatile u32*)(UART0_ADDR+UART_ENABLE); + + /* Enable clocks first */ + *uart_enable = UART_EN_CE; + + /* Then release reset */ + /* Must release reset before setting other regs */ + *uart_enable = UART_EN_CE|UART_EN_E; + + /* Activate fifos, reset tx and rx */ + /* Set tx trigger level to 12 */ + *uart_fifoctl = UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR| + UART_FCR_CLEAR_XMIT|UART_FCR_T_TRIGGER_12; + + serial_setbrg(); + + return 0; +} + + +static void au1x00_serial_setbrg(void) +{ + volatile u32 *uart_clk = (volatile u32*)(UART0_ADDR+UART_CLK); + volatile u32 *uart_lcr = (volatile u32*)(UART0_ADDR+UART_LCR); + volatile u32 *sys_powerctrl = (u32 *)SYS_POWERCTRL; + int sd; + int divisorx2; + + /* sd is system clock divisor */ + /* see section 10.4.5 in au1550 datasheet */ + sd = (*sys_powerctrl & 0x03) + 2; + + /* calulate 2x baudrate and round */ + divisorx2 = ((CONFIG_SYS_MIPS_TIMER_FREQ/(sd * 16 * CONFIG_BAUDRATE))); + + if (divisorx2 & 0x01) + divisorx2 = divisorx2 + 1; + + *uart_clk = divisorx2 / 2; + + /* Set parity, stop bits and word length to 8N1 */ + *uart_lcr = UART_LCR_WLEN8; +} + +static void au1x00_serial_putc(const char c) +{ + volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); + volatile u32 *uart_tx = (volatile u32*)(UART0_ADDR+UART_TX); + + if (c == '\n') + au1x00_serial_putc('\r'); + + /* Wait for fifo to shift out some bytes */ + while((*uart_lsr&UART_LSR_THRE)==0); + + *uart_tx = (u32)c; +} + +static int au1x00_serial_getc(void) +{ + volatile u32 *uart_rx = (volatile u32*)(UART0_ADDR+UART_RX); + char c; + + while (!serial_tstc()); + + c = (*uart_rx&0xFF); + return c; +} + +static int au1x00_serial_tstc(void) +{ + volatile u32 *uart_lsr = (volatile u32*)(UART0_ADDR+UART_LSR); + + if(*uart_lsr&UART_LSR_DR){ + /* Data in rfifo */ + return(1); + } + return 0; +} + +static struct serial_device au1x00_serial_drv = { + .name = "au1x00_serial", + .start = au1x00_serial_init, + .stop = NULL, + .setbrg = au1x00_serial_setbrg, + .putc = au1x00_serial_putc, + .puts = default_serial_puts, + .getc = au1x00_serial_getc, + .tstc = au1x00_serial_tstc, +}; + +void au1x00_serial_initialize(void) +{ + serial_register(&au1x00_serial_drv); +} + +__weak struct serial_device *default_serial_console(void) +{ + return &au1x00_serial_drv; +} diff --git a/arch/mips/mach-au1x00/au1x00_usb_ohci.c b/arch/mips/mach-au1x00/au1x00_usb_ohci.c new file mode 100644 index 0000000000..74bdb77303 --- /dev/null +++ b/arch/mips/mach-au1x00/au1x00_usb_ohci.c @@ -0,0 +1,1609 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB on the AU1x00. + * + * (C) Copyright 2003 + * Gary Jennejohn, DENX Software Engineering + * + * SPDX-License-Identifier: GPL-2.0+ + * Note: Part of this code has been derived from linux + * + */ +/* + * IMPORTANT NOTES + * 1 - this driver is intended for use with USB Mass Storage Devices + * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! + */ + +#include + +#ifdef CONFIG_USB_OHCI + +/* #include no PCI on the AU1x00 */ + +#include +#include +#include +#include +#include +#include "au1x00_usb_ohci.h" + +#define OHCI_USE_NPS /* force NoPowerSwitching mode */ +#define OHCI_VERBOSE_DEBUG /* not always helpful */ +#define OHCI_FILL_TRACE + +#define USBH_ENABLE_BE (1<<0) +#define USBH_ENABLE_C (1<<1) +#define USBH_ENABLE_E (1<<2) +#define USBH_ENABLE_CE (1<<3) +#define USBH_ENABLE_RD (1<<4) + +#ifdef __LITTLE_ENDIAN +#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) +#else +#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE) +#endif + + +/* For initializing controller (mask in an HCFS mode too) */ +#define OHCI_CONTROL_INIT \ + (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE + +#undef readl +#undef writel + +#define readl(a) au_readl((long)(a)) +#define writel(v,a) au_writel((v),(int)(a)) + +#define DEBUG +#ifdef DEBUG +#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) +#else +#define dbg(format, arg...) do {} while(0) +#endif /* DEBUG */ +#define err(format, arg...) printf("ERROR: " format "\n", ## arg) +#define SHOW_INFO +#ifdef SHOW_INFO +#define info(format, arg...) printf("INFO: " format "\n", ## arg) +#else +#define info(format, arg...) do {} while(0) +#endif + +#define m16_swap(x) swap_16(x) +#define m32_swap(x) swap_32(x) + +/* global ohci_t */ +static ohci_t gohci; +/* this must be aligned to a 256 byte boundary */ +struct ohci_hcca ghcca[1]; +/* a pointer to the aligned storage */ +struct ohci_hcca *phcca; +/* this allocates EDs for all possible endpoints */ +struct ohci_device ohci_dev; +/* urb_priv */ +urb_priv_t urb_priv; +/* RHSC flag */ +int got_rhsc; +/* device which was disconnected */ +struct usb_device *devgone; + +/*-------------------------------------------------------------------------*/ + +/* AMD-756 (D2 rev) reports corrupt register contents in some cases. + * The erratum (#4) description is incorrect. AMD's workaround waits + * till some bits (mostly reserved) are clear; ok for all revs. + */ +#define OHCI_QUIRK_AMD756 0xabcd +#define read_roothub(hc, register, mask) ({ \ + u32 temp = readl (&hc->regs->roothub.register); \ + if (hc->flags & OHCI_QUIRK_AMD756) \ + while (temp & mask) \ + temp = readl (&hc->regs->roothub.register); \ + temp; }) + +static u32 roothub_a (struct ohci *hc) + { return read_roothub (hc, a, 0xfc0fe000); } +static inline u32 roothub_b (struct ohci *hc) + { return readl (&hc->regs->roothub.b); } +static inline u32 roothub_status (struct ohci *hc) + { return readl (&hc->regs->roothub.status); } +static u32 roothub_portstatus (struct ohci *hc, int i) + { return read_roothub (hc, portstatus [i], 0xffe0fce0); } + + +/* forward declaration */ +static int hc_interrupt (void); +static void +td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, + int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval); + +/*-------------------------------------------------------------------------* + * URB support functions + *-------------------------------------------------------------------------*/ + +/* free HCD-private data associated with this URB */ + +static void urb_free_priv (urb_priv_t * urb) +{ + int i; + int last; + struct td * td; + + last = urb->length - 1; + if (last >= 0) { + for (i = 0; i <= last; i++) { + td = urb->td[i]; + if (td) { + td->usb_dev = NULL; + urb->td[i] = NULL; + } + } + } +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +static int sohci_get_current_frame_number (struct usb_device * dev); + +/* debug| print the main components of an URB + * small: 0) header + data packets 1) just header */ + +static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer, + int transfer_len, struct devrequest * setup, char * str, int small) +{ + urb_priv_t * purb = &urb_priv; + + dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", + str, + sohci_get_current_frame_number (dev), + usb_pipedevice (pipe), + usb_pipeendpoint (pipe), + usb_pipeout (pipe)? 'O': 'I', + usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): + (usb_pipecontrol (pipe)? "CTRL": "BULK"), + purb->actual_length, + transfer_len, dev->status); +#ifdef OHCI_VERBOSE_DEBUG + if (!small) { + int i, len; + + if (usb_pipecontrol (pipe)) { + printf (__FILE__ ": cmd(8):"); + for (i = 0; i < 8 ; i++) + printf (" %02x", ((__u8 *) setup) [i]); + printf ("\n"); + } + if (transfer_len > 0 && buffer) { + printf (__FILE__ ": data(%d/%d):", + purb->actual_length, + transfer_len); + len = usb_pipeout (pipe)? + transfer_len: purb->actual_length; + for (i = 0; i < 16 && i < len; i++) + printf (" %02x", ((__u8 *) buffer) [i]); + printf ("%s\n", i < len? "...": ""); + } + } +#endif +} + +/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ +void ep_print_int_eds (ohci_t *ohci, char * str) { + int i, j; + __u32 * ed_p; + for (i= 0; i < 32; i++) { + j = 5; + ed_p = &(ohci->hcca->int_table [i]); + if (*ed_p == 0) + continue; + printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); + while (*ed_p != 0 && j--) { + ed_t *ed = (ed_t *)m32_swap(ed_p); + printf (" ed: %4x;", ed->hwINFO); + ed_p = &ed->hwNextED; + } + printf ("\n"); + } +} + +static void ohci_dump_intr_mask (char *label, __u32 mask) +{ + dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", + label, + mask, + (mask & OHCI_INTR_MIE) ? " MIE" : "", + (mask & OHCI_INTR_OC) ? " OC" : "", + (mask & OHCI_INTR_RHSC) ? " RHSC" : "", + (mask & OHCI_INTR_FNO) ? " FNO" : "", + (mask & OHCI_INTR_UE) ? " UE" : "", + (mask & OHCI_INTR_RD) ? " RD" : "", + (mask & OHCI_INTR_SF) ? " SF" : "", + (mask & OHCI_INTR_WDH) ? " WDH" : "", + (mask & OHCI_INTR_SO) ? " SO" : "" + ); +} + +static void maybe_print_eds (char *label, __u32 value) +{ + ed_t *edp = (ed_t *)value; + + if (value) { + dbg ("%s %08x", label, value); + dbg ("%08x", edp->hwINFO); + dbg ("%08x", edp->hwTailP); + dbg ("%08x", edp->hwHeadP); + dbg ("%08x", edp->hwNextED); + } +} + +static char * hcfs2string (int state) +{ + switch (state) { + case OHCI_USB_RESET: return "reset"; + case OHCI_USB_RESUME: return "resume"; + case OHCI_USB_OPER: return "operational"; + case OHCI_USB_SUSPEND: return "suspend"; + } + return "?"; +} + +/* dump control and status registers */ +static void ohci_dump_status (ohci_t *controller) +{ + struct ohci_regs *regs = controller->regs; + __u32 temp; + + temp = readl (®s->revision) & 0xff; + if (temp != 0x10) + dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); + + temp = readl (®s->control); + dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, + (temp & OHCI_CTRL_RWE) ? " RWE" : "", + (temp & OHCI_CTRL_RWC) ? " RWC" : "", + (temp & OHCI_CTRL_IR) ? " IR" : "", + hcfs2string (temp & OHCI_CTRL_HCFS), + (temp & OHCI_CTRL_BLE) ? " BLE" : "", + (temp & OHCI_CTRL_CLE) ? " CLE" : "", + (temp & OHCI_CTRL_IE) ? " IE" : "", + (temp & OHCI_CTRL_PLE) ? " PLE" : "", + temp & OHCI_CTRL_CBSR + ); + + temp = readl (®s->cmdstatus); + dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, + (temp & OHCI_SOC) >> 16, + (temp & OHCI_OCR) ? " OCR" : "", + (temp & OHCI_BLF) ? " BLF" : "", + (temp & OHCI_CLF) ? " CLF" : "", + (temp & OHCI_HCR) ? " HCR" : "" + ); + + ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); + ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); + + maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); + + maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); + maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); + + maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); + maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); + + maybe_print_eds ("donehead", readl (®s->donehead)); +} + +static void ohci_dump_roothub (ohci_t *controller, int verbose) +{ + __u32 temp, ndp, i; + + temp = roothub_a (controller); + ndp = (temp & RH_A_NDP); + + if (verbose) { + dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, + ((temp & RH_A_POTPGT) >> 24) & 0xff, + (temp & RH_A_NOCP) ? " NOCP" : "", + (temp & RH_A_OCPM) ? " OCPM" : "", + (temp & RH_A_DT) ? " DT" : "", + (temp & RH_A_NPS) ? " NPS" : "", + (temp & RH_A_PSM) ? " PSM" : "", + ndp + ); + temp = roothub_b (controller); + dbg ("roothub.b: %08x PPCM=%04x DR=%04x", + temp, + (temp & RH_B_PPCM) >> 16, + (temp & RH_B_DR) + ); + temp = roothub_status (controller); + dbg ("roothub.status: %08x%s%s%s%s%s%s", + temp, + (temp & RH_HS_CRWE) ? " CRWE" : "", + (temp & RH_HS_OCIC) ? " OCIC" : "", + (temp & RH_HS_LPSC) ? " LPSC" : "", + (temp & RH_HS_DRWE) ? " DRWE" : "", + (temp & RH_HS_OCI) ? " OCI" : "", + (temp & RH_HS_LPS) ? " LPS" : "" + ); + } + + for (i = 0; i < ndp; i++) { + temp = roothub_portstatus (controller, i); + dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", + i, + temp, + (temp & RH_PS_PRSC) ? " PRSC" : "", + (temp & RH_PS_OCIC) ? " OCIC" : "", + (temp & RH_PS_PSSC) ? " PSSC" : "", + (temp & RH_PS_PESC) ? " PESC" : "", + (temp & RH_PS_CSC) ? " CSC" : "", + + (temp & RH_PS_LSDA) ? " LSDA" : "", + (temp & RH_PS_PPS) ? " PPS" : "", + (temp & RH_PS_PRS) ? " PRS" : "", + (temp & RH_PS_POCI) ? " POCI" : "", + (temp & RH_PS_PSS) ? " PSS" : "", + + (temp & RH_PS_PES) ? " PES" : "", + (temp & RH_PS_CCS) ? " CCS" : "" + ); + } +} + +static void ohci_dump (ohci_t *controller, int verbose) +{ + dbg ("OHCI controller usb-%s state", controller->slot_name); + + /* dumps some of the state we know about */ + ohci_dump_status (controller); + if (verbose) + ep_print_int_eds (controller, "hcca"); + dbg ("hcca frame #%04x", controller->hcca->frame_no); + ohci_dump_roothub (controller, 1); +} + + +#endif /* DEBUG */ + +/*-------------------------------------------------------------------------* + * Interface functions (URB) + *-------------------------------------------------------------------------*/ + +/* get a transfer request */ + +int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, int interval) +{ + ohci_t *ohci; + ed_t * ed; + urb_priv_t *purb_priv; + int i, size = 0; + + ohci = &gohci; + + /* when controller's hung, permit only roothub cleanup attempts + * such as powering down ports */ + if (ohci->disabled) { + err("sohci_submit_job: EPIPE"); + return -1; + } + + /* every endpoint has a ed, locate and fill it */ + if (!(ed = ep_add_ed (dev, pipe))) { + err("sohci_submit_job: ENOMEM"); + return -1; + } + + /* for the private part of the URB we need the number of TDs (size) */ + switch (usb_pipetype (pipe)) { + case PIPE_BULK: /* one TD for every 4096 Byte */ + size = (transfer_len - 1) / 4096 + 1; + break; + case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ + size = (transfer_len == 0)? 2: + (transfer_len - 1) / 4096 + 3; + break; + } + + if (size >= (N_URB_TD - 1)) { + err("need %d TDs, only have %d", size, N_URB_TD); + return -1; + } + purb_priv = &urb_priv; + purb_priv->pipe = pipe; + + /* fill the private part of the URB */ + purb_priv->length = size; + purb_priv->ed = ed; + purb_priv->actual_length = 0; + + /* allocate the TDs */ + /* note that td[0] was allocated in ep_add_ed */ + for (i = 0; i < size; i++) { + purb_priv->td[i] = td_alloc (dev); + if (!purb_priv->td[i]) { + purb_priv->length = i; + urb_free_priv (purb_priv); + err("sohci_submit_job: ENOMEM"); + return -1; + } + } + + if (ed->state == ED_NEW || (ed->state & ED_DEL)) { + urb_free_priv (purb_priv); + err("sohci_submit_job: EINVAL"); + return -1; + } + + /* link the ed into a chain if is not already */ + if (ed->state != ED_OPER) + ep_link (ohci, ed); + + /* fill the TDs and link it to the ed */ + td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +/* tell us the current USB frame number */ + +static int sohci_get_current_frame_number (struct usb_device *usb_dev) +{ + ohci_t *ohci = &gohci; + + return m16_swap (ohci->hcca->frame_no); +} +#endif + +/*-------------------------------------------------------------------------* + * ED handling functions + *-------------------------------------------------------------------------*/ + +/* link an ed into one of the HC chains */ + +static int ep_link (ohci_t *ohci, ed_t *edi) +{ + volatile ed_t *ed = edi; + + ed->state = ED_OPER; + + switch (ed->type) { + case PIPE_CONTROL: + ed->hwNextED = 0; + if (ohci->ed_controltail == NULL) { + writel ((long)ed, &ohci->regs->ed_controlhead); + } else { + ohci->ed_controltail->hwNextED = m32_swap (ed); + } + ed->ed_prev = ohci->ed_controltail; + if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && + !ohci->ed_rm_list[1] && !ohci->sleeping) { + ohci->hc_control |= OHCI_CTRL_CLE; + writel (ohci->hc_control, &ohci->regs->control); + } + ohci->ed_controltail = edi; + break; + + case PIPE_BULK: + ed->hwNextED = 0; + if (ohci->ed_bulktail == NULL) { + writel ((long)ed, &ohci->regs->ed_bulkhead); + } else { + ohci->ed_bulktail->hwNextED = m32_swap (ed); + } + ed->ed_prev = ohci->ed_bulktail; + if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && + !ohci->ed_rm_list[1] && !ohci->sleeping) { + ohci->hc_control |= OHCI_CTRL_BLE; + writel (ohci->hc_control, &ohci->regs->control); + } + ohci->ed_bulktail = edi; + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* unlink an ed from one of the HC chains. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed */ + +static int ep_unlink (ohci_t *ohci, ed_t *ed) +{ + ed->hwINFO |= m32_swap (OHCI_ED_SKIP); + + switch (ed->type) { + case PIPE_CONTROL: + if (ed->ed_prev == NULL) { + if (!ed->hwNextED) { + ohci->hc_control &= ~OHCI_CTRL_CLE; + writel (ohci->hc_control, &ohci->regs->control); + } + writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if (ohci->ed_controltail == ed) { + ohci->ed_controltail = ed->ed_prev; + } else { + ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; + } + break; + + case PIPE_BULK: + if (ed->ed_prev == NULL) { + if (!ed->hwNextED) { + ohci->hc_control &= ~OHCI_CTRL_BLE; + writel (ohci->hc_control, &ohci->regs->control); + } + writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); + } else { + ed->ed_prev->hwNextED = ed->hwNextED; + } + if (ohci->ed_bulktail == ed) { + ohci->ed_bulktail = ed->ed_prev; + } else { + ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; + } + break; + } + ed->state = ED_UNLINK; + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, + * but the USB stack is a little bit stateless so we do it at every transaction + * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK + * in all other cases the state is left unchanged + * the ed info fields are setted anyway even though most of them should not change */ + +static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe) +{ + td_t *td; + ed_t *ed_ret; + volatile ed_t *ed; + + ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | + (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; + + if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { + err("ep_add_ed: pending delete"); + /* pending delete request */ + return NULL; + } + + if (ed->state == ED_NEW) { + ed->hwINFO = m32_swap (OHCI_ED_SKIP); /* skip ed */ + /* dummy td; end of td list for ed */ + td = td_alloc (usb_dev); + ed->hwTailP = m32_swap (td); + ed->hwHeadP = ed->hwTailP; + ed->state = ED_UNLINK; + ed->type = usb_pipetype (pipe); + ohci_dev.ed_cnt++; + } + + ed->hwINFO = m32_swap (usb_pipedevice (pipe) + | usb_pipeendpoint (pipe) << 7 + | (usb_pipeisoc (pipe)? 0x8000: 0) + | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) + | (usb_dev->speed == USB_SPEED_LOW) << 13 + | usb_maxpacket (usb_dev, pipe) << 16); + + return ed_ret; +} + +/*-------------------------------------------------------------------------* + * TD handling functions + *-------------------------------------------------------------------------*/ + +/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ + +static void td_fill (ohci_t *ohci, unsigned int info, + void *data, int len, + struct usb_device *dev, int index, urb_priv_t *urb_priv) +{ + volatile td_t *td, *td_pt; +#ifdef OHCI_FILL_TRACE + int i; +#endif + + if (index > urb_priv->length) { + err("index > length"); + return; + } + /* use this td as the next dummy */ + td_pt = urb_priv->td [index]; + td_pt->hwNextTD = 0; + + /* fill the old dummy TD */ + td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf); + + td->ed = urb_priv->ed; + td->next_dl_td = NULL; + td->index = index; + td->data = (__u32)data; +#ifdef OHCI_FILL_TRACE + if (1 || (usb_pipebulk(urb_priv->pipe) && + usb_pipeout(urb_priv->pipe))) { + for (i = 0; i < len; i++) + printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]); + } +#endif + if (!len) + data = 0; + + td->hwINFO = m32_swap (info); + td->hwCBP = m32_swap (data); + if (data) + td->hwBE = m32_swap (data + len - 1); + else + td->hwBE = 0; + td->hwNextTD = m32_swap (td_pt); + td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000); + + /* append to queue */ + td->ed->hwTailP = td->hwNextTD; +} + +/*-------------------------------------------------------------------------*/ + +/* prepare all TDs of a transfer */ + +#define kseg_to_phys(x) ((void *)((__u32)(x) - 0x80000000)) + +static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval) +{ + ohci_t *ohci = &gohci; + int data_len = transfer_len; + void *data; + int cnt = 0; + __u32 info = 0; + unsigned int toggle = 0; + + /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ + if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { + toggle = TD_T_TOGGLE; + } else { + toggle = TD_T_DATA0; + usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); + } + urb->td_cnt = 0; + if (data_len) + data = kseg_to_phys(buffer); + else + data = 0; + + switch (usb_pipetype (pipe)) { + case PIPE_BULK: + info = usb_pipeout (pipe)? + TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; + while(data_len > 4096) { + td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); + data += 4096; data_len -= 4096; cnt++; + } + info = usb_pipeout (pipe)? + TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; + td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); + cnt++; + + if (!ohci->sleeping) + writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ + break; + + case PIPE_CONTROL: + info = TD_CC | TD_DP_SETUP | TD_T_DATA0; + td_fill (ohci, info, kseg_to_phys(setup), 8, dev, cnt++, urb); + if (data_len > 0) { + info = usb_pipeout (pipe)? + TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; + /* NOTE: mishandles transfers >8K, some >4K */ + td_fill (ohci, info, data, data_len, dev, cnt++, urb); + } + info = usb_pipeout (pipe)? + TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; + td_fill (ohci, info, data, 0, dev, cnt++, urb); + if (!ohci->sleeping) + writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ + break; + } + if (urb->length != cnt) + dbg("TD LENGTH %d != CNT %d", urb->length, cnt); +} + +/*-------------------------------------------------------------------------* + * Done List handling functions + *-------------------------------------------------------------------------*/ + + +/* calculate the transfer length and update the urb */ + +static void dl_transfer_length(td_t * td) +{ + __u32 tdINFO, tdBE, tdCBP; + urb_priv_t *lurb_priv = &urb_priv; + + tdINFO = m32_swap (td->hwINFO); + tdBE = m32_swap (td->hwBE); + tdCBP = m32_swap (td->hwCBP); + + + if (!(usb_pipecontrol(lurb_priv->pipe) && + ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { + if (tdBE != 0) { + if (td->hwCBP == 0) + lurb_priv->actual_length += tdBE - td->data + 1; + else + lurb_priv->actual_length += tdCBP - td->data; + } + } +} + +/*-------------------------------------------------------------------------*/ + +/* replies to the request have to be on a FIFO basis so + * we reverse the reversed done-list */ + +static td_t * dl_reverse_done_list (ohci_t *ohci) +{ + __u32 td_list_hc; + td_t *td_rev = NULL; + td_t *td_list = NULL; + urb_priv_t *lurb_priv = NULL; + + td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0; + ohci->hcca->done_head = 0; + + while (td_list_hc) { + td_list = (td_t *)td_list_hc; + + if (TD_CC_GET (m32_swap (td_list->hwINFO))) { + lurb_priv = &urb_priv; + dbg(" USB-error/status: %x : %p", + TD_CC_GET (m32_swap (td_list->hwINFO)), td_list); + if (td_list->ed->hwHeadP & m32_swap (0x1)) { + if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { + td_list->ed->hwHeadP = + (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) | + (td_list->ed->hwHeadP & m32_swap (0x2)); + lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; + } else + td_list->ed->hwHeadP &= m32_swap (0xfffffff2); + } + } + + td_list->next_dl_td = td_rev; + td_rev = td_list; + td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0; + } + return td_list; +} + +/*-------------------------------------------------------------------------*/ + +/* td done list */ +static int dl_done_list (ohci_t *ohci, td_t *td_list) +{ + td_t *td_list_next = NULL; + ed_t *ed; + int cc = 0; + int stat = 0; + /* urb_t *urb; */ + urb_priv_t *lurb_priv; + __u32 tdINFO, edHeadP, edTailP; + + while (td_list) { + td_list_next = td_list->next_dl_td; + + lurb_priv = &urb_priv; + tdINFO = m32_swap (td_list->hwINFO); + + ed = td_list->ed; + + dl_transfer_length(td_list); + + /* error code of transfer */ + cc = TD_CC_GET (tdINFO); + if (cc != 0) { + dbg("ConditionCode %#x", cc); + stat = cc_to_error[cc]; + } + + if (ed->state != ED_NEW) { + edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0; + edTailP = m32_swap (ed->hwTailP); + + /* unlink eds if they are not busy */ + if ((edHeadP == edTailP) && (ed->state == ED_OPER)) + ep_unlink (ohci, ed); + } + + td_list = td_list_next; + } + return stat; +} + +/*-------------------------------------------------------------------------* + * Virtual Root Hub + *-------------------------------------------------------------------------*/ + +#include + +/* Hub class-specific descriptor is constructed dynamically */ + + +/*-------------------------------------------------------------------------*/ + +#define OK(x) len = (x); break +#ifdef DEBUG +#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} +#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} +#else +#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status) +#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) +#endif +#define RD_RH_STAT roothub_status(&gohci) +#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1) + +/* request to virtual root hub */ + +int rh_check_port_status(ohci_t *controller) +{ + __u32 temp, ndp, i; + int res; + + res = -1; + temp = roothub_a (controller); + ndp = (temp & RH_A_NDP); + for (i = 0; i < ndp; i++) { + temp = roothub_portstatus (controller, i); + /* check for a device disconnect */ + if (((temp & (RH_PS_PESC | RH_PS_CSC)) == + (RH_PS_PESC | RH_PS_CSC)) && + ((temp & RH_PS_CCS) == 0)) { + res = i; + break; + } + } + return res; +} + +static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, struct devrequest *cmd) +{ + void * data = buffer; + int leni = transfer_len; + int len = 0; + int stat = 0; + __u32 datab[4]; + __u8 *data_buf = (__u8 *)datab; + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + +#ifdef DEBUG +urb_priv.actual_length = 0; +pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); +#else + mdelay(1); +#endif + if (usb_pipeint(pipe)) { + info("Root-Hub submit IRQ: NOT implemented"); + return 0; + } + + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = m16_swap (cmd->value); + wIndex = m16_swap (cmd->index); + wLength = m16_swap (cmd->length); + + info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", + dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); + + switch (bmRType_bReq) { + /* Request Destination: + without flags: Device, + RH_INTERFACE: interface, + RH_ENDPOINT: endpoint, + RH_CLASS means HUB here, + RH_OTHER | RH_CLASS almost ever means HUB_PORT here + */ + + case RH_GET_STATUS: + *(__u16 *) data_buf = m16_swap (1); OK (2); + case RH_GET_STATUS | RH_INTERFACE: + *(__u16 *) data_buf = m16_swap (0); OK (2); + case RH_GET_STATUS | RH_ENDPOINT: + *(__u16 *) data_buf = m16_swap (0); OK (2); + case RH_GET_STATUS | RH_CLASS: + *(__u32 *) data_buf = m32_swap ( + RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); + OK (4); + case RH_GET_STATUS | RH_OTHER | RH_CLASS: + *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4); + + case RH_CLEAR_FEATURE | RH_ENDPOINT: + switch (wValue) { + case (RH_ENDPOINT_STALL): OK (0); + } + break; + + case RH_CLEAR_FEATURE | RH_CLASS: + switch (wValue) { + case RH_C_HUB_LOCAL_POWER: + OK(0); + case (RH_C_HUB_OVER_CURRENT): + WR_RH_STAT(RH_HS_OCIC); OK (0); + } + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_ENABLE): + WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_POCI); OK (0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); + case (RH_C_PORT_CONNECTION): + WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); + case (RH_C_PORT_ENABLE): + WR_RH_PORTSTAT (RH_PS_PESC); OK (0); + case (RH_C_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); + case (RH_C_PORT_OVER_CURRENT): + WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); + case (RH_C_PORT_RESET): + WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): + WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); + case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT (RH_PS_PRS); + OK (0); + case (RH_PORT_POWER): + WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); + case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ + if (RD_RH_PORTSTAT & RH_PS_CCS) + WR_RH_PORTSTAT (RH_PS_PES ); + OK (0); + } + break; + + case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof (root_hub_dev_des), + wLength)); + data_buf = root_hub_dev_des; OK(len); + case (0x02): /* configuration descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof (root_hub_config_des), + wLength)); + data_buf = root_hub_config_des; OK(len); + case (0x03): /* string descriptors */ + if(wValue==0x0300) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof (root_hub_str_index0), + wLength)); + data_buf = root_hub_str_index0; + OK(len); + } + if(wValue==0x0301) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof (root_hub_str_index1), + wLength)); + data_buf = root_hub_str_index1; + OK(len); + } + default: + stat = USB_ST_STALLED; + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + { + __u32 temp = roothub_a (&gohci); + + data_buf [0] = 9; /* min length; */ + data_buf [1] = 0x29; + data_buf [2] = temp & RH_A_NDP; + data_buf [3] = 0; + if (temp & RH_A_PSM) /* per-port power switching? */ + data_buf [3] |= 0x1; + if (temp & RH_A_NOCP) /* no overcurrent reporting? */ + data_buf [3] |= 0x10; + else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ + data_buf [3] |= 0x8; + + /* corresponds to data_buf[4-7] */ + datab [1] = 0; + data_buf [5] = (temp & RH_A_POTPGT) >> 24; + temp = roothub_b (&gohci); + data_buf [7] = temp & RH_B_DR; + if (data_buf [2] < 7) { + data_buf [8] = 0xff; + } else { + data_buf [0] += 2; + data_buf [8] = (temp & RH_B_DR) >> 8; + data_buf [10] = data_buf [9] = 0xff; + } + + len = min_t(unsigned int, leni, + min_t(unsigned int, data_buf [0], wLength)); + OK (len); + } + + case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); + + case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); + + default: + dbg ("unsupported root hub command"); + stat = USB_ST_STALLED; + } + +#ifdef DEBUG + ohci_dump_roothub (&gohci, 1); +#else + mdelay(1); +#endif + + len = min_t(int, len, leni); + if (data != data_buf) + memcpy (data, data_buf, len); + dev->act_len = len; + dev->status = stat; + +#ifdef DEBUG + if (transfer_len) + urb_priv.actual_length = transfer_len; + pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); +#else + mdelay(1); +#endif + + return stat; +} + +/*-------------------------------------------------------------------------*/ + +/* common code for handling submit messages - used for all but root hub */ +/* accesses. */ +int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup, int interval) +{ + int stat = 0; + int maxsize = usb_maxpacket(dev, pipe); + int timeout; + + /* device pulled? Shortcut the action. */ + if (devgone == dev) { + dev->status = USB_ST_CRC_ERR; + return 0; + } + +#ifdef DEBUG + urb_priv.actual_length = 0; + pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +#else + mdelay(1); +#endif + if (!maxsize) { + err("submit_common_message: pipesize for pipe %lx is zero", + pipe); + return -1; + } + + if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) { + err("sohci_submit_job failed"); + return -1; + } + + mdelay(10); + /* ohci_dump_status(&gohci); */ + + /* allow more time for a BULK device to react - some are slow */ +#define BULK_TO 5000 /* timeout in milliseconds */ + if (usb_pipebulk(pipe)) + timeout = BULK_TO; + else + timeout = 100; + + timeout *= 4; + /* wait for it to complete */ + for (;;) { + /* check whether the controller is done */ + stat = hc_interrupt(); + if (stat < 0) { + stat = USB_ST_CRC_ERR; + break; + } + if (stat >= 0 && stat != 0xff) { + /* 0xff is returned for an SF-interrupt */ + break; + } + if (--timeout) { + udelay(250); /* mdelay(1); */ + } else { + err("CTL:TIMEOUT "); + stat = USB_ST_CRC_ERR; + break; + } + } + /* we got an Root Hub Status Change interrupt */ + if (got_rhsc) { +#ifdef DEBUG + ohci_dump_roothub (&gohci, 1); +#endif + got_rhsc = 0; + /* abuse timeout */ + timeout = rh_check_port_status(&gohci); + if (timeout >= 0) { +#if 0 /* this does nothing useful, but leave it here in case that changes */ + /* the called routine adds 1 to the passed value */ + usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); +#endif + /* + * XXX + * This is potentially dangerous because it assumes + * that only one device is ever plugged in! + */ + devgone = dev; + } + } + + dev->status = stat; + dev->act_len = transfer_len; + +#ifdef DEBUG + pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); +#else + mdelay(1); +#endif + + /* free TDs in urb_priv */ + urb_free_priv (&urb_priv); + return 0; +} + +/* submit routines called from usb.c */ +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len) +{ + info("submit_bulk_msg"); + return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup) +{ + int maxsize = usb_maxpacket(dev, pipe); + + info("submit_control_msg"); +#ifdef DEBUG + urb_priv.actual_length = 0; + pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +#else + mdelay(1); +#endif + if (!maxsize) { + err("submit_control_message: pipesize for pipe %lx is zero", + pipe); + return -1; + } + if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { + gohci.rh.dev = dev; + /* root hub - redirect */ + return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, + setup); + } + + return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, int interval) +{ + info("submit_int_msg"); + return -1; +} + +/*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ + +/* reset the HC and BUS */ + +static int hc_reset (ohci_t *ohci) +{ + int timeout = 30; + int smm_timeout = 50; /* 0,5 sec */ + + if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ + writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ + info("USB HC TakeOver from SMM"); + while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { + mdelay (10); + if (--smm_timeout == 0) { + err("USB HC TakeOver failed!"); + return -1; + } + } + } + + /* Disable HC interrupts */ + writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); + + dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", + ohci->slot_name, + readl (&ohci->regs->control)); + + /* Reset USB (needed by some controllers) */ + writel (0, &ohci->regs->control); + + /* HC Reset requires max 10 us delay */ + writel (OHCI_HCR, &ohci->regs->cmdstatus); + while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + if (--timeout == 0) { + err("USB HC reset timed out!"); + return -1; + } + udelay (1); + } + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* Start an OHCI controller, set the BUS operational + * enable interrupts + * connect the virtual root hub */ + +static int hc_start (ohci_t * ohci) +{ + __u32 mask; + unsigned int fminterval; + + ohci->disabled = 1; + + /* Tell the controller where the control and bulk lists are + * The lists are empty now. */ + + writel (0, &ohci->regs->ed_controlhead); + writel (0, &ohci->regs->ed_bulkhead); + + writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ + + fminterval = 0x2edf; + writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); + fminterval |= ((((fminterval - 210) * 6) / 7) << 16); + writel (fminterval, &ohci->regs->fminterval); + writel (0x628, &ohci->regs->lsthresh); + + /* start controller operations */ + ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; + ohci->disabled = 0; + writel (ohci->hc_control, &ohci->regs->control); + + /* disable all interrupts */ + mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | + OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | + OHCI_INTR_OC | OHCI_INTR_MIE); + writel (mask, &ohci->regs->intrdisable); + /* clear all interrupts */ + mask &= ~OHCI_INTR_MIE; + writel (mask, &ohci->regs->intrstatus); + /* Choose the interrupts we care about now - but w/o MIE */ + mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; + writel (mask, &ohci->regs->intrenable); + +#ifdef OHCI_USE_NPS + /* required for AMD-756 and some Mac platforms */ + writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, + &ohci->regs->roothub.a); + writel (RH_HS_LPSC, &ohci->regs->roothub.status); +#endif /* OHCI_USE_NPS */ + + /* POTPGT delay is bits 24-31, in 2 ms units. */ + mdelay ((roothub_a (ohci) >> 23) & 0x1fe); + + /* connect the virtual root hub */ + ohci->rh.devnum = 0; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* an interrupt happens */ + +static int +hc_interrupt (void) +{ + ohci_t *ohci = &gohci; + struct ohci_regs *regs = ohci->regs; + int ints; + int stat = -1; + + if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) { + ints = OHCI_INTR_WDH; + } else { + ints = readl (®s->intrstatus); + } + + /* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ + + if (ints & OHCI_INTR_RHSC) { + got_rhsc = 1; + } + + if (ints & OHCI_INTR_UE) { + ohci->disabled++; + err ("OHCI Unrecoverable Error, controller usb-%s disabled", + ohci->slot_name); + /* e.g. due to PCI Master/Target Abort */ + +#ifdef DEBUG + ohci_dump (ohci, 1); +#else + mdelay(1); +#endif + /* FIXME: be optimistic, hope that bug won't repeat often. */ + /* Make some non-interrupt context restart the controller. */ + /* Count and limit the retries though; either hardware or */ + /* software errors can go forever... */ + hc_reset (ohci); + return -1; + } + + if (ints & OHCI_INTR_WDH) { + mdelay(1); + writel (OHCI_INTR_WDH, ®s->intrdisable); + stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); + writel (OHCI_INTR_WDH, ®s->intrenable); + } + + if (ints & OHCI_INTR_SO) { + dbg("USB Schedule overrun\n"); + writel (OHCI_INTR_SO, ®s->intrenable); + stat = -1; + } + + /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */ + if (ints & OHCI_INTR_SF) { + unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1; + mdelay(1); + writel (OHCI_INTR_SF, ®s->intrdisable); + if (ohci->ed_rm_list[frame] != NULL) + writel (OHCI_INTR_SF, ®s->intrenable); + stat = 0xff; + } + + writel (ints, ®s->intrstatus); + return stat; +} + +/*-------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ + +/* De-allocate all resources.. */ + +static void hc_release_ohci (ohci_t *ohci) +{ + dbg ("USB HC release ohci usb-%s", ohci->slot_name); + + if (!ohci->disabled) + hc_reset (ohci); +} + +/*-------------------------------------------------------------------------*/ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +/* + * low level initalisation routine, called from usb.c + */ +static char ohci_inited = 0; + +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +{ + u32 pin_func; + u32 sys_freqctrl, sys_clksrc; + u32 prid = read_c0_prid(); + + dbg("in usb_lowlevel_init\n"); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + switch (prid & 0x000000FF) { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + /* CPU core freq to 48MHz to slow it way down... */ + au_writel(4, SYS_CPUPLL); + + /* + * Setup 48MHz FREQ2 from CPUPLL for USB Host + */ + /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ + sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* CPU core freq to 384MHz */ + au_writel(0x20, SYS_CPUPLL); + + printf("Au1000: 48MHz OHCI workaround enabled\n"); + break; + + default: /* HC and newer */ + /* FREQ2 = aux/2 = 48 MHz */ + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + break; + } + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* configure pins GPIO[14:9] as GPIO */ + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); + + au_writel(pin_func, SYS_PINFUNC); + au_writel(0x2800, SYS_TRIOUTCLR); + au_writel(0x0030, SYS_OUTPUTCLR); + + dbg("OHCI board setup complete\n"); + + /* enable host controller */ + au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); + udelay(1000); + au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG); + udelay(1000); + + /* wait for reset complete (read register twice; see au1500 errata) */ + while (au_readl(USB_HOST_CONFIG), + !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) + udelay(1000); + + dbg("OHCI clock running\n"); + + memset (&gohci, 0, sizeof (ohci_t)); + memset (&urb_priv, 0, sizeof (urb_priv_t)); + + /* align the storage */ + if ((__u32)&ghcca[0] & 0xff) { + err("HCCA not aligned!!"); + return -1; + } + phcca = &ghcca[0]; + info("aligned ghcca %p", phcca); + memset(&ohci_dev, 0, sizeof(struct ohci_device)); + if ((__u32)&ohci_dev.ed[0] & 0x7) { + err("EDs not aligned!!"); + return -1; + } + memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1)); + if ((__u32)gtd & 0x7) { + err("TDs not aligned!!"); + return -1; + } + ptd = gtd; + gohci.hcca = phcca; + memset (phcca, 0, sizeof (struct ohci_hcca)); + + gohci.disabled = 1; + gohci.sleeping = 0; + gohci.irq = -1; + gohci.regs = (struct ohci_regs *)(USB_OHCI_BASE | 0xA0000000); + + gohci.flags = 0; + gohci.slot_name = "au1x00"; + + dbg("OHCI revision: 0x%08x\n" + " RH: a: 0x%08x b: 0x%08x\n", + readl(&gohci.regs->revision), + readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b)); + + if (hc_reset (&gohci) < 0) + goto errout; + + /* FIXME this is a second HC reset; why?? */ + writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control); + mdelay (10); + + if (hc_start (&gohci) < 0) + goto errout; + +#ifdef DEBUG + ohci_dump (&gohci, 1); +#else + mdelay(1); +#endif + ohci_inited = 1; + return 0; + + errout: + err("OHCI initialization error\n"); + hc_release_ohci (&gohci); + /* Initialization failed */ + au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); + return -1; +} + +int usb_lowlevel_stop(int index) +{ + /* this gets called really early - before the controller has */ + /* even been initialized! */ + if (!ohci_inited) + return 0; + /* TODO release any interrupts, etc. */ + /* call hc_release_ohci() here ? */ + hc_reset (&gohci); + /* may not want to do this */ + /* Disable clock */ + au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); + return 0; +} + +#endif /* CONFIG_USB_OHCI */ diff --git a/arch/mips/mach-au1x00/au1x00_usb_ohci.h b/arch/mips/mach-au1x00/au1x00_usb_ohci.h new file mode 100644 index 0000000000..bb9f351099 --- /dev/null +++ b/arch/mips/mach-au1x00/au1x00_usb_ohci.h @@ -0,0 +1,416 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2001 David Brownell + * + * usb-ohci.h + */ + + +static int cc_to_error[16] = { + +/* mapping of the OHCI CC status to error codes */ + /* No Error */ 0, + /* CRC Error */ USB_ST_CRC_ERR, + /* Bit Stuff */ USB_ST_BIT_ERR, + /* Data Togg */ USB_ST_CRC_ERR, + /* Stall */ USB_ST_STALLED, + /* DevNotResp */ -1, + /* PIDCheck */ USB_ST_BIT_ERR, + /* UnExpPID */ USB_ST_BIT_ERR, + /* DataOver */ USB_ST_BUF_ERR, + /* DataUnder */ USB_ST_BUF_ERR, + /* reservd */ -1, + /* reservd */ -1, + /* BufferOver */ USB_ST_BUF_ERR, + /* BuffUnder */ USB_ST_BUF_ERR, + /* Not Access */ -1, + /* Not Access */ -1 +}; + +/* ED States */ + +#define ED_NEW 0x00 +#define ED_UNLINK 0x01 +#define ED_OPER 0x02 +#define ED_DEL 0x04 +#define ED_URB_DEL 0x08 + +/* usb_ohci_ed */ +struct ed { + __u32 hwINFO; + __u32 hwTailP; + __u32 hwHeadP; + __u32 hwNextED; + + struct ed *ed_prev; + __u8 int_period; + __u8 int_branch; + __u8 int_load; + __u8 int_interval; + __u8 state; + __u8 type; + __u16 last_iso; + struct ed *ed_rm_list; + + struct usb_device *usb_dev; + __u32 unused[3]; +} __attribute__((aligned(16))); +typedef struct ed ed_t; + + +/* TD info field */ +#define TD_CC 0xf0000000 +#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) +#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) +#define TD_EC 0x0C000000 +#define TD_T 0x03000000 +#define TD_T_DATA0 0x02000000 +#define TD_T_DATA1 0x03000000 +#define TD_T_TOGGLE 0x00000000 +#define TD_R 0x00040000 +#define TD_DI 0x00E00000 +#define TD_DI_SET(X) (((X) & 0x07)<< 21) +#define TD_DP 0x00180000 +#define TD_DP_SETUP 0x00000000 +#define TD_DP_IN 0x00100000 +#define TD_DP_OUT 0x00080000 + +#define TD_ISO 0x00010000 +#define TD_DEL 0x00020000 + +/* CC Codes */ +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEM 0x03 +#define TD_CC_STALL 0x04 +#define TD_DEVNOTRESP 0x05 +#define TD_PIDCHECKFAIL 0x06 +#define TD_UNEXPECTEDPID 0x07 +#define TD_DATAOVERRUN 0x08 +#define TD_DATAUNDERRUN 0x09 +#define TD_BUFFEROVERRUN 0x0C +#define TD_BUFFERUNDERRUN 0x0D +#define TD_NOTACCESSED 0x0F + + +#define MAXPSW 1 + +struct td { + __u32 hwINFO; + __u32 hwCBP; /* Current Buffer Pointer */ + __u32 hwNextTD; /* Next TD Pointer */ + __u32 hwBE; /* Memory Buffer End Pointer */ + + __u16 hwPSW[MAXPSW]; + __u8 unused; + __u8 index; + struct ed *ed; + struct td *next_dl_td; + struct usb_device *usb_dev; + int transfer_len; + __u32 data; + + __u32 unused2[2]; +} __attribute__((aligned(32))); +typedef struct td td_t; + +#define OHCI_ED_SKIP (1 << 14) + +/* + * The HCCA (Host Controller Communications Area) is a 256 byte + * structure defined in the OHCI spec. that the host controller is + * told the base address of. It must be 256-byte aligned. + */ + +#define NUM_INTS 32 /* part of the OHCI standard */ +struct ohci_hcca { + __u32 int_table[NUM_INTS]; /* Interrupt ED table */ + __u16 frame_no; /* current frame number */ + __u16 pad1; /* set to 0 on each frame_no change */ + __u32 done_head; /* info returned for an interrupt */ + u8 reserved_for_hc[116]; +} __attribute__((aligned(256))); + + +/* + * Maximum number of root hub ports. + */ +#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */ + +/* + * This is the structure of the OHCI controller's memory mapped I/O + * region. This is Memory Mapped I/O. You must use the readl() and + * writel() macros defined in asm/io.h to access these!! + */ +struct ohci_regs { + /* control and status registers */ + __u32 revision; + __u32 control; + __u32 cmdstatus; + __u32 intrstatus; + __u32 intrenable; + __u32 intrdisable; + /* memory pointers */ + __u32 hcca; + __u32 ed_periodcurrent; + __u32 ed_controlhead; + __u32 ed_controlcurrent; + __u32 ed_bulkhead; + __u32 ed_bulkcurrent; + __u32 donehead; + /* frame counters */ + __u32 fminterval; + __u32 fmremaining; + __u32 fmnumber; + __u32 periodicstart; + __u32 lsthresh; + /* Root hub ports */ + struct ohci_roothub_regs { + __u32 a; + __u32 b; + __u32 status; + __u32 portstatus[MAX_ROOT_PORTS]; + } roothub; +} __attribute__((aligned(32))); + + +/* OHCI CONTROL AND STATUS REGISTER MASKS */ + +/* + * HcControl (control) register masks + */ +#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ +#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ +#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ +#define OHCI_CTRL_CLE (1 << 4) /* control list enable */ +#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ +#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ +#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ +#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ + +/* pre-shifted values for HCFS */ +# define OHCI_USB_RESET (0 << 6) +# define OHCI_USB_RESUME (1 << 6) +# define OHCI_USB_OPER (2 << 6) +# define OHCI_USB_SUSPEND (3 << 6) + +/* + * HcCommandStatus (cmdstatus) register masks + */ +#define OHCI_HCR (1 << 0) /* host controller reset */ +#define OHCI_CLF (1 << 1) /* control list filled */ +#define OHCI_BLF (1 << 2) /* bulk list filled */ +#define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_SOC (3 << 16) /* scheduling overrun count */ + +/* + * masks used with interrupt registers: + * HcInterruptStatus (intrstatus) + * HcInterruptEnable (intrenable) + * HcInterruptDisable (intrdisable) + */ +#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ +#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ +#define OHCI_INTR_SF (1 << 2) /* start frame */ +#define OHCI_INTR_RD (1 << 3) /* resume detect */ +#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ +#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ +#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ +#define OHCI_INTR_OC (1 << 30) /* ownership change */ +#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ + + +/* Virtual Root HUB */ +struct virt_root_hub { + int devnum; /* Address of Root Hub endpoint */ + void *dev; /* was urb */ + void *int_addr; + int send; + int interval; +}; + +/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ + +/* destination of request */ +#define RH_INTERFACE 0x01 +#define RH_ENDPOINT 0x02 +#define RH_OTHER 0x03 + +#define RH_CLASS 0x20 +#define RH_VENDOR 0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP 0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION 0x00 +#define RH_PORT_ENABLE 0x01 +#define RH_PORT_SUSPEND 0x02 +#define RH_PORT_OVER_CURRENT 0x03 +#define RH_PORT_RESET 0x04 +#define RH_PORT_POWER 0x08 +#define RH_PORT_LOW_SPEED 0x09 + +#define RH_C_PORT_CONNECTION 0x10 +#define RH_C_PORT_ENABLE 0x11 +#define RH_C_PORT_SUSPEND 0x12 +#define RH_C_PORT_OVER_CURRENT 0x13 +#define RH_C_PORT_RESET 0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER 0x00 +#define RH_C_HUB_OVER_CURRENT 0x01 + +#define RH_DEVICE_REMOTE_WAKEUP 0x00 +#define RH_ENDPOINT_STALL 0x01 + +#define RH_ACK 0x01 +#define RH_REQ_ERR -1 +#define RH_NACK 0x00 + + +/* OHCI ROOT HUB REGISTER MASKS */ + +/* roothub.portstatus [i] bits */ +#define RH_PS_CCS 0x00000001 /* current connect status */ +#define RH_PS_PES 0x00000002 /* port enable status*/ +#define RH_PS_PSS 0x00000004 /* port suspend status */ +#define RH_PS_POCI 0x00000008 /* port over current indicator */ +#define RH_PS_PRS 0x00000010 /* port reset status */ +#define RH_PS_PPS 0x00000100 /* port power status */ +#define RH_PS_LSDA 0x00000200 /* low speed device attached */ +#define RH_PS_CSC 0x00010000 /* connect status change */ +#define RH_PS_PESC 0x00020000 /* port enable status change */ +#define RH_PS_PSSC 0x00040000 /* port suspend status change */ +#define RH_PS_OCIC 0x00080000 /* over current indicator change */ +#define RH_PS_PRSC 0x00100000 /* port reset status change */ + +/* roothub.status bits */ +#define RH_HS_LPS 0x00000001 /* local power status */ +#define RH_HS_OCI 0x00000002 /* over current indicator */ +#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ +#define RH_HS_LPSC 0x00010000 /* local power status change */ +#define RH_HS_OCIC 0x00020000 /* over current indicator change */ +#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ + +/* roothub.b masks */ +#define RH_B_DR 0x0000ffff /* device removable flags */ +#define RH_B_PPCM 0xffff0000 /* port power control mask */ + +/* roothub.a masks */ +#define RH_A_NDP (0xff << 0) /* number of downstream ports */ +#define RH_A_PSM (1 << 8) /* power switching mode */ +#define RH_A_NPS (1 << 9) /* no power switching */ +#define RH_A_DT (1 << 10) /* device type (mbz) */ +#define RH_A_OCPM (1 << 11) /* over current protection mode */ +#define RH_A_NOCP (1 << 12) /* no over current protection */ +#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ + +/* urb */ +#define N_URB_TD 48 +typedef struct +{ + ed_t *ed; + __u16 length; /* number of tds associated with this request */ + __u16 td_cnt; /* number of tds already serviced */ + int state; + unsigned long pipe; + int actual_length; + td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ +} urb_priv_t; +#define URB_DEL 1 + +/* + * This is the full ohci controller description + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. (Linus) + */ + + +typedef struct ohci { + struct ohci_hcca *hcca; /* hcca */ + /*dma_addr_t hcca_dma;*/ + + int irq; + int disabled; /* e.g. got a UE, we're hung */ + int sleeping; + unsigned long flags; /* for HC bugs */ + + struct ohci_regs *regs; /* OHCI controller's memory */ + + ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ + ed_t *ed_bulktail; /* last endpoint of bulk list */ + ed_t *ed_controltail; /* last endpoint of control list */ + int intrstatus; + __u32 hc_control; /* copy of the hc control reg */ + struct usb_device *dev[32]; + struct virt_root_hub rh; + + const char *slot_name; +} ohci_t; + +#define NUM_EDS 8 /* num of preallocated endpoint descriptors */ + +struct ohci_device { + ed_t ed[NUM_EDS]; + int ed_cnt; +}; + +/* hcd */ +/* endpoint */ +static int ep_link(ohci_t * ohci, ed_t * ed); +static int ep_unlink(ohci_t * ohci, ed_t * ed); +static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe); + +/*-------------------------------------------------------------------------*/ + +/* we need more TDs than EDs */ +#define NUM_TD 64 + +/* +1 so we can align the storage */ +td_t gtd[NUM_TD+1]; +/* pointers to aligned storage */ +td_t *ptd; + +/* TDs ... */ +static inline struct td * +td_alloc (struct usb_device *usb_dev) +{ + int i; + struct td *td; + + td = NULL; + for (i = 0; i < NUM_TD; i++) { + if (ptd[i].usb_dev == NULL) { + td = &ptd[i]; + td->usb_dev = usb_dev; + break; + } + } + return td; +} + +static inline void +ed_free (struct ed *ed) +{ + ed->usb_dev = NULL; +} diff --git a/arch/mips/mach-au1x00/config.mk b/arch/mips/mach-au1x00/config.mk new file mode 100644 index 0000000000..5c89129d8c --- /dev/null +++ b/arch/mips/mach-au1x00/config.mk @@ -0,0 +1,8 @@ +# +# (C) Copyright 2011 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_CPPFLAGS += -mtune=4kc -- cgit From eef88dfb3e16e4631e078f42714dbcef3216e3e1 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Thu, 29 Jan 2015 14:56:20 +0100 Subject: MIPS: unify CPU code in arch/mips/cpu/ Unify and move code in arch/mips/cpu/mips[32|64]/ to arch/mips/cpu/. The CPU specific config.mk files need to remain until CONFIG_STANDALONE_LOAD_ADDR is converted to a global Kconfig symbol. Signed-off-by: Paul Burton Signed-off-by: Daniel Schwierzeck --- arch/mips/Makefile | 6 +- arch/mips/cpu/Makefile | 9 ++ arch/mips/cpu/cpu.c | 38 +++++ arch/mips/cpu/interrupts.c | 22 +++ arch/mips/cpu/mips32/Makefile | 9 -- arch/mips/cpu/mips32/cpu.c | 34 ---- arch/mips/cpu/mips32/interrupts.c | 22 --- arch/mips/cpu/mips32/start.S | 320 -------------------------------------- arch/mips/cpu/mips32/time.c | 19 --- arch/mips/cpu/mips64/Makefile | 9 -- arch/mips/cpu/mips64/cpu.c | 37 ----- arch/mips/cpu/mips64/interrupts.c | 22 --- arch/mips/cpu/mips64/start.S | 291 ---------------------------------- arch/mips/cpu/mips64/time.c | 19 --- arch/mips/cpu/start.S | 320 ++++++++++++++++++++++++++++++++++++++ arch/mips/cpu/time.c | 19 +++ 16 files changed, 410 insertions(+), 786 deletions(-) create mode 100644 arch/mips/cpu/Makefile create mode 100644 arch/mips/cpu/cpu.c create mode 100644 arch/mips/cpu/interrupts.c delete mode 100644 arch/mips/cpu/mips32/Makefile delete mode 100644 arch/mips/cpu/mips32/cpu.c delete mode 100644 arch/mips/cpu/mips32/interrupts.c delete mode 100644 arch/mips/cpu/mips32/start.S delete mode 100644 arch/mips/cpu/mips32/time.c delete mode 100644 arch/mips/cpu/mips64/Makefile delete mode 100644 arch/mips/cpu/mips64/cpu.c delete mode 100644 arch/mips/cpu/mips64/interrupts.c delete mode 100644 arch/mips/cpu/mips64/start.S delete mode 100644 arch/mips/cpu/mips64/time.c create mode 100644 arch/mips/cpu/start.S create mode 100644 arch/mips/cpu/time.c diff --git a/arch/mips/Makefile b/arch/mips/Makefile index ff01bfef20..43f0f5c504 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -2,11 +2,9 @@ # SPDX-License-Identifier: GPL-2.0+ # -head-$(CONFIG_CPU_MIPS32) := arch/mips/cpu/mips32/start.o -head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o +head-y := arch/mips/cpu/start.o -libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/ -libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/ +libs-y += arch/mips/cpu/ libs-y += arch/mips/lib/ libs-$(CONFIG_SOC_AU1X00) += arch/mips/mach-au1x00/ diff --git a/arch/mips/cpu/Makefile b/arch/mips/cpu/Makefile new file mode 100644 index 0000000000..fc6b455c68 --- /dev/null +++ b/arch/mips/cpu/Makefile @@ -0,0 +1,9 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o + +obj-y += time.o +obj-y += interrupts.o +obj-y += cpu.o diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c new file mode 100644 index 0000000000..8d3b2f5c2b --- /dev/null +++ b/arch/mips/cpu/cpu.c @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +void __weak _machine_restart(void) +{ + fprintf(stderr, "*** reset failed ***\n"); + + while (1) + /* NOP */; +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + _machine_restart(); + + return 0; +} + +void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) +{ + write_c0_entrylo0(low0); + write_c0_pagemask(pagemask); + write_c0_entrylo1(low1); + write_c0_entryhi(hi); + write_c0_index(index); + tlb_write_indexed(); +} diff --git a/arch/mips/cpu/interrupts.c b/arch/mips/cpu/interrupts.c new file mode 100644 index 0000000000..275fcf5699 --- /dev/null +++ b/arch/mips/cpu/interrupts.c @@ -0,0 +1,22 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +int interrupt_init(void) +{ + return 0; +} + +void enable_interrupts(void) +{ +} + +int disable_interrupts(void) +{ + return 0; +} diff --git a/arch/mips/cpu/mips32/Makefile b/arch/mips/cpu/mips32/Makefile deleted file mode 100644 index cb4db9c71b..0000000000 --- a/arch/mips/cpu/mips32/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# (C) Copyright 2003-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -extra-y = start.o -obj-y = cpu.o interrupts.o time.o diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c deleted file mode 100644 index 07deca86f7..0000000000 --- a/arch/mips/cpu/mips32/cpu.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -void __attribute__((weak)) _machine_restart(void) -{ -} - -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - _machine_restart(); - - fprintf(stderr, "*** reset failed ***\n"); - return 0; -} - -void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) -{ - write_c0_entrylo0(low0); - write_c0_pagemask(pagemask); - write_c0_entrylo1(low1); - write_c0_entryhi(hi); - write_c0_index(index); - tlb_write_indexed(); -} diff --git a/arch/mips/cpu/mips32/interrupts.c b/arch/mips/cpu/mips32/interrupts.c deleted file mode 100644 index 275fcf5699..0000000000 --- a/arch/mips/cpu/mips32/interrupts.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -int interrupt_init(void) -{ - return 0; -} - -void enable_interrupts(void) -{ -} - -int disable_interrupts(void) -{ - return 0; -} diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S deleted file mode 100644 index 3b5b622abe..0000000000 --- a/arch/mips/cpu/mips32/start.S +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Startup Code for MIPS32 CPU-core - * - * Copyright (c) 2003 Wolfgang Denk - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -#ifndef CONFIG_SYS_MIPS_CACHE_MODE -#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT -#endif - -#ifndef CONFIG_SYS_INIT_SP_ADDR -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ - CONFIG_SYS_INIT_SP_OFFSET) -#endif - -#ifdef CONFIG_32BIT -# define MIPS_RELOC 3 -# define STATUS_SET 0 -#endif - -#ifdef CONFIG_64BIT -# ifdef CONFIG_SYS_LITTLE_ENDIAN -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) -# else -# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) -# endif -# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) -# define STATUS_SET ST0_KX -#endif - - /* - * For the moment disable interrupts, mark the kernel mode and - * set ST0_KX so that the CPU does not spit fire when using - * 64-bit addresses. - */ - .macro setup_c0_status set clr - .set push - mfc0 t0, CP0_STATUS - or t0, ST0_CU0 | \set | 0x1f | \clr - xor t0, 0x1f | \clr - mtc0 t0, CP0_STATUS - .set noreorder - sll zero, 3 # ehb - .set pop - .endm - - .set noreorder - - .globl _start - .text -_start: - /* U-boot entry point */ - b reset - nop - - .org 0x10 -#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG) - /* - * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to - * access external NOR flashes. If the board boots from NOR flash the - * internal BootROM does a blind read at address 0xB0000010 to read the - * initial configuration for that EBU in order to access the flash - * device with correct parameters. This config option is board-specific. - */ - .word CONFIG_SYS_XWAY_EBU_BOOTCFG - .word 0x0 -#elif defined(CONFIG_MALTA) - /* - * Linux expects the Board ID here. - */ - .word 0x00000420 # 0x420 (Malta Board with CoreLV) - .word 0x00000000 -#endif - - .org 0x200 - /* TLB refill, 32 bit task */ -1: b 1b - nop - - .org 0x280 - /* XTLB refill, 64 bit task */ -1: b 1b - nop - - .org 0x300 - /* Cache error exception */ -1: b 1b - nop - - .org 0x380 - /* General exception */ -1: b 1b - nop - - .org 0x400 - /* Catch interrupt exceptions */ -1: b 1b - nop - - .org 0x480 - /* EJTAG debug exception */ -1: b 1b - nop - - .align 4 -reset: - - /* Clear watch registers */ - MTC0 zero, CP0_WATCHLO - MTC0 zero, CP0_WATCHHI - - /* WP(Watch Pending), SW0/1 should be cleared */ - mtc0 zero, CP0_CAUSE - - setup_c0_status STATUS_SET 0 - - /* Init Timer */ - mtc0 zero, CP0_COUNT - mtc0 zero, CP0_COMPARE - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - /* CONFIG0 register */ - li t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG -#endif - - /* - * Initialize $gp, force pointer sized alignment of bal instruction to - * forbid the compiler to put nop's between bal and _gp. This is - * required to keep _gp and ra aligned to 8 byte. - */ - .align PTRLOG - bal 1f - nop - PTR _gp -1: - PTR_L gp, 0(ra) - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - /* Initialize any external memory */ - PTR_LA t9, lowlevel_init - jalr t9 - nop - - /* Initialize caches... */ - PTR_LA t9, mips_cache_reset - jalr t9 - nop - - /* ... and enable them */ - li t0, CONFIG_SYS_MIPS_CACHE_MODE - mtc0 t0, CP0_CONFIG -#endif - - /* Set up temporary stack */ - PTR_LI t0, -16 - PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR - and sp, t1, t0 # force 16 byte alignment - PTR_SUB sp, sp, GD_SIZE # reserve space for gd - and sp, sp, t0 # force 16 byte alignment - move k0, sp # save gd pointer -#ifdef CONFIG_SYS_MALLOC_F_LEN - PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN - PTR_SUB sp, sp, t2 # reserve space for early malloc - and sp, sp, t0 # force 16 byte alignment -#endif - move fp, sp - - /* Clear gd */ - move t0, k0 -1: - sw zero, 0(t0) - blt t0, t1, 1b - PTR_ADDI t0, 4 - -#ifdef CONFIG_SYS_MALLOC_F_LEN - PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset - sw sp, 0(t0) -#endif - - PTR_LA t9, board_init_f - jr t9 - move ra, zero - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * a0 = addr_sp - * a1 = gd - * a2 = destination address - */ - .globl relocate_code - .ent relocate_code -relocate_code: - move sp, a0 # set new stack pointer - move fp, sp - - move s0, a1 # save gd in s0 - move s2, a2 # save destination address in s2 - - PTR_LI t0, CONFIG_SYS_MONITOR_BASE - PTR_SUB s1, s2, t0 # s1 <-- relocation offset - - PTR_LA t3, in_ram - PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end - move t1, a2 - - PTR_ADD gp, s1 # adjust gp - - /* - * t0 = source address - * t1 = target address - * t2 = source end address - */ -1: - lw t3, 0(t0) - sw t3, 0(t1) - PTR_ADDU t0, 4 - blt t0, t2, 1b - PTR_ADDU t1, 4 - - /* If caches were enabled, we would have to flush them here. */ - PTR_SUB a1, t1, s2 # a1 <-- size - PTR_LA t9, flush_cache - jalr t9 - move a0, s2 # a0 <-- destination address - - /* Jump to where we've relocated ourselves */ - PTR_ADDI t0, s2, in_ram - _start - jr t0 - nop - - PTR __rel_dyn_end - PTR __rel_dyn_start - PTR __image_copy_end - PTR _GLOBAL_OFFSET_TABLE_ - PTR num_got_entries - -in_ram: - /* - * Now we want to update GOT. - * - * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object - * generated by GNU ld. Skip these reserved entries from relocation. - */ - PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries - PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ - PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ - PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries - PTR_LI t2, 2 -1: - PTR_L t1, 0(t8) - beqz t1, 2f - PTR_ADD t1, s1 - PTR_S t1, 0(t8) -2: - PTR_ADDI t2, 1 - blt t2, t3, 1b - PTR_ADDI t8, PTRSIZE - - /* Update dynamic relocations */ - PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start - PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end - - b 2f # skip first reserved entry - PTR_ADDI t1, 2 * PTRSIZE - -1: - lw t8, -4(t1) # t8 <-- relocation info - - PTR_LI t3, MIPS_RELOC - bne t8, t3, 2f # skip non-MIPS_RELOC entries - nop - - PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH - - PTR_L t8, 0(t3) # t8 <-- original pointer - PTR_ADD t8, s1 # t8 <-- adjusted pointer - - PTR_ADD t3, s1 # t3 <-- location to fix up in RAM - PTR_S t8, 0(t3) - -2: - blt t1, t2, 1b - PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes - - /* - * Clear BSS - * - * GOT is now relocated. Thus __bss_start and __bss_end can be - * accessed directly via $gp. - */ - PTR_LA t1, __bss_start # t1 <-- __bss_start - PTR_LA t2, __bss_end # t2 <-- __bss_end - -1: - PTR_S zero, 0(t1) - blt t1, t2, 1b - PTR_ADDI t1, PTRSIZE - - move a0, s0 # a0 <-- gd - move a1, s2 - PTR_LA t9, board_init_r - jr t9 - move ra, zero - - .end relocate_code diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/mips32/time.c deleted file mode 100644 index 553da5f4ba..0000000000 --- a/arch/mips/cpu/mips32/time.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -unsigned long notrace timer_read_counter(void) -{ - return read_c0_count(); -} - -ulong notrace get_tbclk(void) -{ - return CONFIG_SYS_MIPS_TIMER_FREQ; -} diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile deleted file mode 100644 index cb4db9c71b..0000000000 --- a/arch/mips/cpu/mips64/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# (C) Copyright 2003-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -extra-y = start.o -obj-y = cpu.o interrupts.o time.o diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c deleted file mode 100644 index 1d32705b74..0000000000 --- a/arch/mips/cpu/mips64/cpu.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -void __attribute__((weak)) _machine_restart(void) -{ - fprintf(stderr, "*** reset failed ***\n"); - - while (1) - /* NOP */; -} - -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - _machine_restart(); - - return 0; -} - -void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) -{ - write_c0_entrylo0(low0); - write_c0_pagemask(pagemask); - write_c0_entrylo1(low1); - write_c0_entryhi(hi); - write_c0_index(index); - tlb_write_indexed(); -} diff --git a/arch/mips/cpu/mips64/interrupts.c b/arch/mips/cpu/mips64/interrupts.c deleted file mode 100644 index 275fcf5699..0000000000 --- a/arch/mips/cpu/mips64/interrupts.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -int interrupt_init(void) -{ - return 0; -} - -void enable_interrupts(void) -{ -} - -int disable_interrupts(void) -{ - return 0; -} diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S deleted file mode 100644 index 471bc1eb66..0000000000 --- a/arch/mips/cpu/mips64/start.S +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Startup Code for MIPS64 CPU-core - * - * Copyright (c) 2003 Wolfgang Denk - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -#ifndef CONFIG_SYS_MIPS_CACHE_MODE -#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT -#endif - -#ifndef CONFIG_SYS_INIT_SP_ADDR -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ - CONFIG_SYS_INIT_SP_OFFSET) -#endif - -#ifdef CONFIG_SYS_LITTLE_ENDIAN -#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) -#else -#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ - ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) -#endif - - /* - * For the moment disable interrupts, mark the kernel mode and - * set ST0_KX so that the CPU does not spit fire when using - * 64-bit addresses. - */ - .macro setup_c0_status set clr - .set push - mfc0 t0, CP0_STATUS - or t0, ST0_CU0 | \set | 0x1f | \clr - xor t0, 0x1f | \clr - mtc0 t0, CP0_STATUS - .set noreorder - sll zero, 3 # ehb - .set pop - .endm - - .set noreorder - - .globl _start - .text -_start: - /* U-boot entry point */ - b reset - nop - - .org 0x200 - /* TLB refill, 32 bit task */ -1: b 1b - nop - - .org 0x280 - /* XTLB refill, 64 bit task */ -1: b 1b - nop - - .org 0x300 - /* Cache error exception */ -1: b 1b - nop - - .org 0x380 - /* General exception */ -1: b 1b - nop - - .org 0x400 - /* Catch interrupt exceptions */ -1: b 1b - nop - - .org 0x480 - /* EJTAG debug exception */ -1: b 1b - nop - - .align 4 -reset: - - /* Clear watch registers */ - dmtc0 zero, CP0_WATCHLO - dmtc0 zero, CP0_WATCHHI - - /* WP(Watch Pending), SW0/1 should be cleared */ - mtc0 zero, CP0_CAUSE - - setup_c0_status ST0_KX 0 - - /* Init Timer */ - mtc0 zero, CP0_COUNT - mtc0 zero, CP0_COMPARE - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - /* CONFIG0 register */ - dli t0, CONF_CM_UNCACHED - mtc0 t0, CP0_CONFIG -#endif - - /* - * Initialize $gp, force 8 byte alignment of bal instruction to forbid - * the compiler to put nop's between bal and _gp. This is required to - * keep _gp and ra aligned to 8 byte. - */ - .align 3 - bal 1f - nop - .dword _gp -1: - ld gp, 0(ra) - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - /* Initialize any external memory */ - dla t9, lowlevel_init - jalr t9 - nop - - /* Initialize caches... */ - dla t9, mips_cache_reset - jalr t9 - nop - - /* ... and enable them */ - dli t0, CONFIG_SYS_MIPS_CACHE_MODE - mtc0 t0, CP0_CONFIG -#endif - - /* Set up temporary stack */ - dli t0, -16 - dli t1, CONFIG_SYS_INIT_SP_ADDR - and sp, t1, t0 # force 16 byte alignment - dsub sp, sp, GD_SIZE # reserve space for gd - and sp, sp, t0 # force 16 byte alignment - move k0, sp # save gd pointer -#ifdef CONFIG_SYS_MALLOC_F_LEN - dli t2, CONFIG_SYS_MALLOC_F_LEN - dsub sp, sp, t2 # reserve space for early malloc - and sp, sp, t0 # force 16 byte alignment -#endif - move fp, sp - - /* Clear gd */ - move t0, k0 -1: - sw zero, 0(t0) - blt t0, t1, 1b - daddi t0, 4 - -#ifdef CONFIG_SYS_MALLOC_F_LEN - daddu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset - sw sp, 0(t0) -#endif - - dla t9, board_init_f - jr t9 - move ra, zero - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * a0 = addr_sp - * a1 = gd - * a2 = destination address - */ - .globl relocate_code - .ent relocate_code -relocate_code: - move sp, a0 # set new stack pointer - move fp, sp - - move s0, a1 # save gd in s0 - move s2, a2 # save destination address in s2 - - dli t0, CONFIG_SYS_MONITOR_BASE - dsub s1, s2, t0 # s1 <-- relocation offset - - dla t3, in_ram - ld t2, -24(t3) # t2 <-- __image_copy_end - move t1, a2 - - dadd gp, s1 # adjust gp - - /* - * t0 = source address - * t1 = target address - * t2 = source end address - */ -1: - lw t3, 0(t0) - sw t3, 0(t1) - daddu t0, 4 - blt t0, t2, 1b - daddu t1, 4 - - /* If caches were enabled, we would have to flush them here. */ - dsub a1, t1, s2 # a1 <-- size - dla t9, flush_cache - jalr t9 - move a0, s2 # a0 <-- destination address - - /* Jump to where we've relocated ourselves */ - daddi t0, s2, in_ram - _start - jr t0 - nop - - .dword __rel_dyn_end - .dword __rel_dyn_start - .dword __image_copy_end - .dword _GLOBAL_OFFSET_TABLE_ - .dword num_got_entries - -in_ram: - /* - * Now we want to update GOT. - * - * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object - * generated by GNU ld. Skip these reserved entries from relocation. - */ - ld t3, -8(t0) # t3 <-- num_got_entries - ld t8, -16(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ - dadd t8, s1 # t8 now holds relocated _G_O_T_ - daddi t8, t8, 16 # skipping first two entries - dli t2, 2 -1: - ld t1, 0(t8) - beqz t1, 2f - dadd t1, s1 - sd t1, 0(t8) -2: - daddi t2, 1 - blt t2, t3, 1b - daddi t8, 8 - - /* Update dynamic relocations */ - ld t1, -32(t0) # t1 <-- __rel_dyn_start - ld t2, -40(t0) # t2 <-- __rel_dyn_end - - b 2f # skip first reserved entry - daddi t1, 16 - -1: - lw t8, -4(t1) # t8 <-- relocation info - - dli t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) - bne t8, t3, 2f # skip non R_MIPS_REL32 entries - nop - - ld t3, -16(t1) # t3 <-- location to fix up in FLASH - - ld t8, 0(t3) # t8 <-- original pointer - dadd t8, s1 # t8 <-- adjusted pointer - - dadd t3, s1 # t3 <-- location to fix up in RAM - sd t8, 0(t3) - -2: - blt t1, t2, 1b - daddi t1, 16 # each rel.dyn entry is 16 bytes - - /* - * Clear BSS - * - * GOT is now relocated. Thus __bss_start and __bss_end can be - * accessed directly via $gp. - */ - dla t1, __bss_start # t1 <-- __bss_start - dla t2, __bss_end # t2 <-- __bss_end - -1: - sd zero, 0(t1) - blt t1, t2, 1b - daddi t1, 8 - - move a0, s0 # a0 <-- gd - move a1, s2 - dla t9, board_init_r - jr t9 - move ra, zero - - .end relocate_code diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c deleted file mode 100644 index 553da5f4ba..0000000000 --- a/arch/mips/cpu/mips64/time.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -unsigned long notrace timer_read_counter(void) -{ - return read_c0_count(); -} - -ulong notrace get_tbclk(void) -{ - return CONFIG_SYS_MIPS_TIMER_FREQ; -} diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S new file mode 100644 index 0000000000..3b5b622abe --- /dev/null +++ b/arch/mips/cpu/start.S @@ -0,0 +1,320 @@ +/* + * Startup Code for MIPS32 CPU-core + * + * Copyright (c) 2003 Wolfgang Denk + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_MIPS_CACHE_MODE +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT +#endif + +#ifndef CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_INIT_SP_OFFSET) +#endif + +#ifdef CONFIG_32BIT +# define MIPS_RELOC 3 +# define STATUS_SET 0 +#endif + +#ifdef CONFIG_64BIT +# ifdef CONFIG_SYS_LITTLE_ENDIAN +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) +# else +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) +# endif +# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) +# define STATUS_SET ST0_KX +#endif + + /* + * For the moment disable interrupts, mark the kernel mode and + * set ST0_KX so that the CPU does not spit fire when using + * 64-bit addresses. + */ + .macro setup_c0_status set clr + .set push + mfc0 t0, CP0_STATUS + or t0, ST0_CU0 | \set | 0x1f | \clr + xor t0, 0x1f | \clr + mtc0 t0, CP0_STATUS + .set noreorder + sll zero, 3 # ehb + .set pop + .endm + + .set noreorder + + .globl _start + .text +_start: + /* U-boot entry point */ + b reset + nop + + .org 0x10 +#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG) + /* + * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to + * access external NOR flashes. If the board boots from NOR flash the + * internal BootROM does a blind read at address 0xB0000010 to read the + * initial configuration for that EBU in order to access the flash + * device with correct parameters. This config option is board-specific. + */ + .word CONFIG_SYS_XWAY_EBU_BOOTCFG + .word 0x0 +#elif defined(CONFIG_MALTA) + /* + * Linux expects the Board ID here. + */ + .word 0x00000420 # 0x420 (Malta Board with CoreLV) + .word 0x00000000 +#endif + + .org 0x200 + /* TLB refill, 32 bit task */ +1: b 1b + nop + + .org 0x280 + /* XTLB refill, 64 bit task */ +1: b 1b + nop + + .org 0x300 + /* Cache error exception */ +1: b 1b + nop + + .org 0x380 + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b + nop + + .org 0x480 + /* EJTAG debug exception */ +1: b 1b + nop + + .align 4 +reset: + + /* Clear watch registers */ + MTC0 zero, CP0_WATCHLO + MTC0 zero, CP0_WATCHHI + + /* WP(Watch Pending), SW0/1 should be cleared */ + mtc0 zero, CP0_CAUSE + + setup_c0_status STATUS_SET 0 + + /* Init Timer */ + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + /* CONFIG0 register */ + li t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG +#endif + + /* + * Initialize $gp, force pointer sized alignment of bal instruction to + * forbid the compiler to put nop's between bal and _gp. This is + * required to keep _gp and ra aligned to 8 byte. + */ + .align PTRLOG + bal 1f + nop + PTR _gp +1: + PTR_L gp, 0(ra) + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + /* Initialize any external memory */ + PTR_LA t9, lowlevel_init + jalr t9 + nop + + /* Initialize caches... */ + PTR_LA t9, mips_cache_reset + jalr t9 + nop + + /* ... and enable them */ + li t0, CONFIG_SYS_MIPS_CACHE_MODE + mtc0 t0, CP0_CONFIG +#endif + + /* Set up temporary stack */ + PTR_LI t0, -16 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 # force 16 byte alignment + PTR_SUB sp, sp, GD_SIZE # reserve space for gd + and sp, sp, t0 # force 16 byte alignment + move k0, sp # save gd pointer +#ifdef CONFIG_SYS_MALLOC_F_LEN + PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN + PTR_SUB sp, sp, t2 # reserve space for early malloc + and sp, sp, t0 # force 16 byte alignment +#endif + move fp, sp + + /* Clear gd */ + move t0, k0 +1: + sw zero, 0(t0) + blt t0, t1, 1b + PTR_ADDI t0, 4 + +#ifdef CONFIG_SYS_MALLOC_F_LEN + PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset + sw sp, 0(t0) +#endif + + PTR_LA t9, board_init_f + jr t9 + move ra, zero + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * a0 = addr_sp + * a1 = gd + * a2 = destination address + */ + .globl relocate_code + .ent relocate_code +relocate_code: + move sp, a0 # set new stack pointer + move fp, sp + + move s0, a1 # save gd in s0 + move s2, a2 # save destination address in s2 + + PTR_LI t0, CONFIG_SYS_MONITOR_BASE + PTR_SUB s1, s2, t0 # s1 <-- relocation offset + + PTR_LA t3, in_ram + PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end + move t1, a2 + + PTR_ADD gp, s1 # adjust gp + + /* + * t0 = source address + * t1 = target address + * t2 = source end address + */ +1: + lw t3, 0(t0) + sw t3, 0(t1) + PTR_ADDU t0, 4 + blt t0, t2, 1b + PTR_ADDU t1, 4 + + /* If caches were enabled, we would have to flush them here. */ + PTR_SUB a1, t1, s2 # a1 <-- size + PTR_LA t9, flush_cache + jalr t9 + move a0, s2 # a0 <-- destination address + + /* Jump to where we've relocated ourselves */ + PTR_ADDI t0, s2, in_ram - _start + jr t0 + nop + + PTR __rel_dyn_end + PTR __rel_dyn_start + PTR __image_copy_end + PTR _GLOBAL_OFFSET_TABLE_ + PTR num_got_entries + +in_ram: + /* + * Now we want to update GOT. + * + * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object + * generated by GNU ld. Skip these reserved entries from relocation. + */ + PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries + PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ + PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries + PTR_LI t2, 2 +1: + PTR_L t1, 0(t8) + beqz t1, 2f + PTR_ADD t1, s1 + PTR_S t1, 0(t8) +2: + PTR_ADDI t2, 1 + blt t2, t3, 1b + PTR_ADDI t8, PTRSIZE + + /* Update dynamic relocations */ + PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start + PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + PTR_ADDI t1, 2 * PTRSIZE + +1: + lw t8, -4(t1) # t8 <-- relocation info + + PTR_LI t3, MIPS_RELOC + bne t8, t3, 2f # skip non-MIPS_RELOC entries + nop + + PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH + + PTR_L t8, 0(t3) # t8 <-- original pointer + PTR_ADD t8, s1 # t8 <-- adjusted pointer + + PTR_ADD t3, s1 # t3 <-- location to fix up in RAM + PTR_S t8, 0(t3) + +2: + blt t1, t2, 1b + PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + PTR_LA t1, __bss_start # t1 <-- __bss_start + PTR_LA t2, __bss_end # t2 <-- __bss_end + +1: + PTR_S zero, 0(t1) + blt t1, t2, 1b + PTR_ADDI t1, PTRSIZE + + move a0, s0 # a0 <-- gd + move a1, s2 + PTR_LA t9, board_init_r + jr t9 + move ra, zero + + .end relocate_code diff --git a/arch/mips/cpu/time.c b/arch/mips/cpu/time.c new file mode 100644 index 0000000000..553da5f4ba --- /dev/null +++ b/arch/mips/cpu/time.c @@ -0,0 +1,19 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +unsigned long notrace timer_read_counter(void) +{ + return read_c0_count(); +} + +ulong notrace get_tbclk(void) +{ + return CONFIG_SYS_MIPS_TIMER_FREQ; +} -- cgit From 89fc8bbf44e2ce6d73e0c71a9e88e477e91bc0db Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 19 Jan 2015 21:32:00 +0800 Subject: cmd: Fix gettime command help Remove the additional ',' and '\n' from the gettime command help. Signed-off-by: Bin Meng --- common/cmd_gettime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/cmd_gettime.c b/common/cmd_gettime.c index 320ff709fa..c48baad9a1 100644 --- a/common/cmd_gettime.c +++ b/common/cmd_gettime.c @@ -35,6 +35,6 @@ static int do_gettime(cmd_tbl_t *cmdtp, int flag, int argc, U_BOOT_CMD( gettime, 1, 1, do_gettime, - "get timer val elapsed,\n", - "get time elapsed from uboot start\n" + "get timer val elapsed", + "get time elapsed from uboot start" ); -- cgit From cc11b39288c402ca14ebf4e4cc15c7a72569034b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 19 Jan 2015 16:39:11 -0700 Subject: distro_bootcmd: read DHCP boot script name from a variable Modify $bootcmd_dhcp to read the downloaded script filename from an environment variable rather than hard-coding it. This allows the user (or another script) to select a different script name if they want, without editing the whole value of $bootcmd_dhcp. Signed-off-by: Stephen Warren --- include/config_distro_bootcmd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 90ab21a727..49674f4537 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -110,7 +110,7 @@ #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \ "bootcmd_dhcp=" \ BOOTENV_RUN_USB_INIT \ - "if dhcp ${scriptaddr} boot.scr.uimg; then " \ + "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \ "source ${scriptaddr}; " \ "fi\0" #define BOOTENV_DEV_NAME_DHCP(devtypeu, devtypel, instance) \ @@ -154,6 +154,7 @@ BOOTENV_SHARED_IDE \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ + "boot_script_dhcp=boot.scr.uimg\0" \ BOOTENV_BOOT_TARGETS \ \ "boot_extlinux=" \ -- cgit From 9561723c76873c5f0d8b96e1aa5072ae68dab20b Mon Sep 17 00:00:00 2001 From: Chris Kuethe Date: Wed, 21 Jan 2015 20:52:33 -0800 Subject: arm: switch armltd vexpress to GENERIC_BOARD only tested tested under QEMU with vexpress_ca9x4 ("-M vexpress-a9") and vexpress_ca15_tc2 ("-M vexpress-a15"). Makes the ugly warning go away. Signed-off-by: Chris Kuethe --- include/configs/vexpress_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index 7e78f8ac8f..2dea921045 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -122,7 +122,7 @@ #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_SYS_L2CACHE_OFF 1 #define CONFIG_INITRD_TAG 1 - +#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_OF_LIBFDT 1 /* Size of malloc() pool */ -- cgit From 06e07f65c7bf5449f2417d8ff08de88bf8c4b8a7 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Thu, 22 Jan 2015 13:21:54 +0800 Subject: drivers/net/e1000.c: fix compile warning under 64bit mode Fix this: warning: cast from pointer to integer of different size Signed-off-by: Minghuan Lian --- drivers/net/e1000.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 6531030463..cd4422215f 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -4927,22 +4927,23 @@ void fill_rx(struct e1000_hw *hw) { struct e1000_rx_desc *rd; - uint32_t flush_start, flush_end; + unsigned long flush_start, flush_end; rx_last = rx_tail; rd = rx_base + rx_tail; rx_tail = (rx_tail + 1) % 8; memset(rd, 0, 16); - rd->buffer_addr = cpu_to_le64((u32)packet); + rd->buffer_addr = cpu_to_le64((unsigned long)packet); /* * Make sure there are no stale data in WB over this area, which * might get written into the memory while the e1000 also writes * into the same memory area. */ - invalidate_dcache_range((u32)packet, (u32)packet + 4096); + invalidate_dcache_range((unsigned long)packet, + (unsigned long)packet + 4096); /* Dump the DMA descriptor into RAM. */ - flush_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1); + flush_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1); flush_end = flush_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); flush_dcache_range(flush_start, flush_end); @@ -4963,7 +4964,7 @@ e1000_configure_tx(struct e1000_hw *hw) unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; - E1000_WRITE_REG(hw, TDBAL, (u32) tx_base); + E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base); E1000_WRITE_REG(hw, TDBAH, 0); E1000_WRITE_REG(hw, TDLEN, 128); @@ -5107,7 +5108,7 @@ e1000_configure_rx(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - E1000_WRITE_REG(hw, RDBAL, (u32) rx_base); + E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base); E1000_WRITE_REG(hw, RDBAH, 0); E1000_WRITE_REG(hw, RDLEN, 128); @@ -5138,14 +5139,14 @@ e1000_poll(struct eth_device *nic) { struct e1000_hw *hw = nic->priv; struct e1000_rx_desc *rd; - uint32_t inval_start, inval_end; + unsigned long inval_start, inval_end; uint32_t len; /* return true if there's an ethernet packet ready to read */ rd = rx_base + rx_last; /* Re-load the descriptor from RAM. */ - inval_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1); + inval_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1); inval_end = inval_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN); invalidate_dcache_range(inval_start, inval_end); @@ -5154,8 +5155,9 @@ e1000_poll(struct eth_device *nic) /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ /* Packet received, make sure the data are re-loaded from RAM. */ len = le32_to_cpu(rd->length); - invalidate_dcache_range((u32)packet, - (u32)packet + roundup(len, ARCH_DMA_MINALIGN)); + invalidate_dcache_range((unsigned long)packet, + (unsigned long)packet + + roundup(len, ARCH_DMA_MINALIGN)); NetReceive((uchar *)packet, len); fill_rx(hw); return 1; @@ -5170,7 +5172,7 @@ static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) struct e1000_hw *hw = nic->priv; struct e1000_tx_desc *txp; int i = 0; - uint32_t flush_start, flush_end; + unsigned long flush_start, flush_end; txp = tx_base + tx_tail; tx_tail = (tx_tail + 1) % 8; @@ -5180,10 +5182,11 @@ static int e1000_transmit(struct eth_device *nic, void *txpacket, int length) txp->upper.data = 0; /* Dump the packet into RAM so e1000 can pick them. */ - flush_dcache_range((u32)nv_packet, - (u32)nv_packet + roundup(length, ARCH_DMA_MINALIGN)); + flush_dcache_range((unsigned long)nv_packet, + (unsigned long)nv_packet + + roundup(length, ARCH_DMA_MINALIGN)); /* Dump the descriptor into RAM as well. */ - flush_start = ((u32)txp) & ~(ARCH_DMA_MINALIGN - 1); + flush_start = ((unsigned long)txp) & ~(ARCH_DMA_MINALIGN - 1); flush_end = flush_start + roundup(sizeof(*txp), ARCH_DMA_MINALIGN); flush_dcache_range(flush_start, flush_end); -- cgit From ef2d17fe21c54adf9f24ee0b32db4ebb56f4eb83 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Thu, 22 Jan 2015 13:21:55 +0800 Subject: drivers/pci/pci_rom.c: fix compile warning under 64bit mode Fix this: drivers/pci/pci_rom.c:95:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] rom_header = (struct pci_rom_header *)rom_address; Signed-off-by: Minghuan Lian --- drivers/pci/pci_rom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index eb7659177b..5729a152e5 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -98,7 +98,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_address | PCI_ROM_ADDRESS_ENABLE); #endif debug("Option ROM address %x\n", rom_address); - rom_header = (struct pci_rom_header *)rom_address; + rom_header = (struct pci_rom_header *)(unsigned long)rom_address; debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", le16_to_cpu(rom_header->signature), -- cgit From ffb4f6f95a0b63a0e8eab81e006a26c9cd99ac5d Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Thu, 22 Jan 2015 11:34:20 -0700 Subject: add README.distro file Add documentation on how to setup a system to use the generic distro configs and boot commands. This spells out what is needed to make a system conformant, but does not limit the board to only the defaults. Signed-off-by: Dennis Gilmore [swarren, added concept, user config, BOOT_TARGET_DEVICES sections. edited the rest] Signed-off-by: Stephen Warren --- doc/README.distro | 341 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 doc/README.distro diff --git a/doc/README.distro b/doc/README.distro new file mode 100644 index 0000000000..dd0f1c7b6a --- /dev/null +++ b/doc/README.distro @@ -0,0 +1,341 @@ +/* + * (C) Copyright 2014 Red Hat Inc. + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +Generic Distro Configuration Concept +==================================== + +Linux distributions are faced with supporting a variety of boot mechanisms, +environments or bootloaders (PC BIOS, EFI, U-Boot, Barebox, ...). This makes +life complicated. Worse, bootloaders such as U-Boot have a configurable set +of features, and each board chooses to enable a different set of features. +Hence, distros typically need to have board-specific knowledge in order to +set up a bootable system. + +This document defines a common set of U-Boot features that are required for +a distro to support the board in a generic fashion. Any board wishing to +allow distros to install and boot in an out-of-the-box fashion should enable +all these features. Linux distros can then create a single set of boot +support/install logic that targets these features. This will allow distros +to install on many boards without the need for board-specific logic. + +In fact, some of these features can be implemented by any bootloader, thus +decoupling distro install/boot logic from any knowledge of the bootloader. + +This model assumes that boards will load boot configuration files from a +regular storage mechanism (eMMC, SD card, USB Disk, SATA disk, etc.) with +a standard partitioning scheme (MBR, GPT). Boards that cannnot support this +storage model are outside the scope of this document, and may still need +board-specific installer/boot-configuration support in a distro. + +To some extent, this model assumes that a board has a separate boot flash +that contains U-Boot, and that the user has somehow installed U-Boot to this +flash before running the distro installer. Even on boards that do not conform +to this aspect of the model, the extent of the board-specific support in the +distro installer logic would be to install a board-specific U-Boot package to +the boot partition partition during installation. This distro-supplied U-Boot +can still implement the same features as on any other board, and hence the +distro's boot configuration file generation logic can still be board-agnostic. + +Locating Bootable Disks +----------------------- + +Typical desktop/server PCs search all (or a user-defined subset of) attached +storage devices for a bootable partition, then load the bootloader or boot +configuration files from there. A U-Boot board port that enables the features +mentioned in this document will search for boot configuration files in the +same way. + +Thus, distros do not need to manipulate any kind of bootloader-specific +configuration data to indicate which storage device the system should boot +from. + +Distros simply need to install the boot configuration files (see next +section) in an ext2/3/4 or FAT partition, mark the partition bootable (via +the MBR bootable flag, or GPT legacy_bios_bootable attribute), and U-Boot (or +any other bootloader) will find those boot files and execute them. This is +conceptually identical to creating a grub2 configuration file on a desktop +PC. + +Note that in the absense of any partition that is explicitly marked bootable, +U-Boot falls back to searching the first valid partition of a disk for boot +configuration files. Other bootloaders are recommended to do the same, since +I believe that partition table bootable flags aren't so commonly used outside +the realm of x86 PCs. + +U-Boot can also search for boot configuration files from a TFTP server. + +Boot Configuration Files +------------------------ + +The standard format for boot configuration files is that of extlinux.conf, as +handled by U-Boot's "syslinux" (disk) or "pxe boot" (network). This is roughly +as specified at: + +http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ + +... with the exceptions that the BootLoaderSpec document: + +* Prescribes a separate configuration per boot menu option, whereas U-Boot + lumps all options into a single extlinux.conf file. Hence, U-Boot searches + for /extlinux/extlinux.conf then /boot/extlinux/extlinux.conf on disk, or + pxelinux.cfg/default over the network. + +* Does not document the fdtdir option, which automatically selects the DTB to + pass to the kernel. + +One example extlinux.conf generated by the Fedora installer is: + +------------------------------------------------------------ +# extlinux.conf generated by anaconda + +ui menu.c32 + +menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options. +menu title Fedora Boot Options. +menu hidden + +timeout 50 +#totaltimeout 9000 + +default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide) + +label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide) + kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl + append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf + fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl + initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img + +label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide) + kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae + append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf + fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae + initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img + +label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc) + kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc + initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img + append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 + fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae +------------------------------------------------------------ + +Another hand-crafted network boot configuration file is: + +------------------------------------------------------------ +TIMEOUT 100 + +MENU TITLE TFTP boot options + +LABEL jetson-tk1-emmc + MENU LABEL ../zImage root on Jetson TK1 eMMC + LINUX ../zImage + FDTDIR ../ + APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b + +LABEL venice2-emmc + MENU LABEL ../zImage root on Venice2 eMMC + LINUX ../zImage + FDTDIR ../ + APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f + +LABEL sdcard + MENU LABEL ../zImage, root on 2GB sdcard + LINUX ../zImage + FDTDIR ../ + APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7 + +LABEL fedora-installer-fk + MENU LABEL Fedora installer w/ Fedora kernel + LINUX fedora-installer/vmlinuz + INITRD fedora-installer/initrd.img.orig + FDTDIR fedora-installer/dtb + APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M +------------------------------------------------------------ + +U-Boot Implementation +===================== + +Enabling the distro options +--------------------------- + +In your board configuration file, include the following: + +------------------------------------------------------------ +#ifndef CONFIG_SPL_BUILD +#include +#include +#endif +------------------------------------------------------------ + +The first of those headers primarily enables a core set of U-Boot features, +such as support for MBR and GPT partitions, ext* and FAT filesystems, booting +raw zImage and initrd (rather than FIT- or uImage-wrapped files), etc. Network +boot support is also enabled here, which is useful in order to boot distro +installers given that distros do not commonly distribute bootable install +media for non-PC targets at present. + +Finally, a few options that are mostly relevant only when using U-Boot- +specific boot.scr scripts are enabled. This enables distros to generate a +U-Boot-specific boot.scr script rather than extlinux.conf as the boot +configuration file. While doing so is fully supported, and + exposes enough parameterization to boot.scr to +allow for board-agnostic boot.scr content, this document recommends that +distros generate extlinux.conf rather than boot.scr. extlinux.conf is intended +to work across multiple bootloaders, whereas boot.scr will only work with +U-Boot. TODO: document the contract between U-Boot and boot.scr re: which +environment variables a generic boot.scr may rely upon. + +The second of those headers sets up the default environment so that $bootcmd +is defined in a way that searches attached disks for boot configuration files, +and executes them if found. + +Required Environment Variables +------------------------------ + +The U-Boot "syslinux" and "pxe boot" commands require a number of environment +variables be set. Default values for these variables are often hard-coded into +CONFIG_EXTRA_ENV_SETTINGS in the board's U-Boot configuration file, so that +the user doesn't have to configure them. + +fdt_addr: + + Mandatory for any system that provides the DTB in HW (e.g. ROM) and wishes + to pass that DTB to Linux, rather than loading a DTB from the boot + filesystem. Prohibited for any other system. + + If specified a DTB to boot the system must be available at the given + address. + +fdt_addr_r: + + Mandatory. The location in RAM where the DTB will be loaded or copied to when + processing the fdtdir/devicetreedir or fdt/devicetree options in + extlinux.conf. + + This is mandatory even when fdt_addr is provided, since extlinux.conf must + always be able to provide a DTB which overrides any copy provided by the HW. + + A size of 1MB for the FDT/DTB seems reasonable. + +ramdisk_addr_r: + + Mandatory. The location in RAM where the initial ramdisk will be loaded to + when processing the initrd option in extlinux.conf. + + It is recommended that this location be highest in RAM out of fdt_addr_, + kernel_addr_r, and ramdisk_addr_r, so that the RAM disk can vary in size + and use any available RAM. + +kernel_addr_r: + + Mandatory. The location in RAM where the kernel will be loaded to when + processing the kernel option in the extlinux.conf. + + The kernel should be located within the first 128M of RAM in order for the + kernel CONFIG_AUTO_ZRELADDR option to work, which is likely enabled on any + distro kernel. Since the kernel will decompress itself to 0x8000 after the + start of RAM, kernel_addr_rshould not overlap that area, or the kernel will + have to copy itself somewhere else first before decompression. + + A size of 16MB for the kernel is likely adequate. + +pxe_addr_r: + + Mandatory. The location in RAM where extlinux.conf will be loaded to prior + to processing. + + A size of 1MB for extlinux.conf is more than adequate. + +scriptaddr: + + Mandatory, if the boot script is boot.scr rather than extlinux.conf. The + location in RAM where boot.scr will be loaded to prior to execution. + + A size of 1MB for extlinux.conf is more than adequate. + +For suggestions on memory locations for ARM systems, you must follow the +guidelines specified in Documentation/arm/Booting in the Linux kernel tree. + +For a commented example of setting these values, please see the definition of +MEM_LAYOUT_ENV_SETTINGS in include/configs/tegra124-common.h. + +Boot Target Configuration +------------------------- + + defines $bootcmd and many helper command variables +that automatically search attached disks for boot configuration files and +execute them. Boards must provide configure so that +it supports the correct set of possible boot device types. To provide this +configuration, simply define macro BOOT_TARGET_DEVICES prior to including +. For example: + +------------------------------------------------------------ +#ifndef CONFIG_SPL_BUILD +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 1) \ + func(MMC, mmc, 0) \ + func(USB, usb, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) +#include +#endif +------------------------------------------------------------ + +Each entry in the macro defines a single boot device (e.g. a specific eMMC +device or SD card) or type of boot device (e.g. USB disk). The parameters to +the func macro (passed in by the internal implementation of the header) are: + +- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE). +- Lower-case disk type (same options as above). +- ID of the specific disk (MMC only) or ignored for other types. + +User Configuration +================== + +Once the user has installed U-Boot, it is expected that the environment will +be reset to the default values in order to enable $bootcmd and friends, as set +up by . After this, various environment variables may +be altered to influence the boot process: + +boot_targets: + + The list of boot locations searched. + + Example: mmc0, mmc1, usb, pxe + + Entries may be removed or re-ordered in this list to affect the boot order. + +boot_prefixes: + + For disk-based booting, the list of directories within a partition that are + searched for boot configuration files (extlinux.conf, boot.scr). + + Example: / /boot/ + + Entries may be removed or re-ordered in this list to affect the set of + directories which are searched. + +boot_scripts: + + The name of U-Boot style boot.scr files that $bootcmd searches for. + + Example: boot.scr.uimg boot.scr + + (Typically we expect extlinux.conf to be used, but execution of boot.scr is + maintained for backwards-compatibility.) + + Entries may be removed or re-ordered in this list to affect the set of + filenames which are supported. + +scan_dev_for_extlinux: + + If you want to disable extlinux.conf on all disks, set the value to something + innocuous, e.g. setenv scan_dev_for_extlinux true. + +scan_dev_for_scripts: + + If you want to disable boot.scr on all disks, set the value to something + innocuous, e.g. setenv scan_dev_for_scripts true. -- cgit From f91afc4d001010a31b53c232b3b1873cb789381e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 23 Jan 2015 11:50:53 +0100 Subject: vexpress64: get rid of CONFIG_SYS_EXTRA_OPTIONS The Versatile Express ARMv8 semihosted FVP platform is still using the legacy CONFIG_SYS_EXTRA_OPTIONS method to configure some compile-time flags. Get rid of this and create a Kconfig entry for the FVP model, and a selectable bool for the semihosting library. The FVP subboard is now modeled as a target choice so we can eventually choose between different ARMv8 versatile express boards (FVP, base model, Juno...) this way. All dependent symbols are updated to reflect this. The 64bit Versatile Express board symbols are renamed VEXPRESS64 so we have some chance to see what is actually going on. Tested on the FVP fast model. Acked-by: Steve Rae Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 14 +++++++++++++- board/armltd/vexpress64/Kconfig | 15 ++++++++++++++- configs/vexpress_aemv8a_defconfig | 2 +- configs/vexpress_aemv8a_semi_defconfig | 4 ++-- include/configs/vexpress_aemv8a.h | 16 ++++++++-------- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5eb1d03cfa..d5399f162d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,13 @@ config SYS_CPU default "sa1100" if CPU_SA1100 default "armv8" if ARM64 +config SEMIHOSTING + bool "support boot from semihosting" + help + In emulated environments, semihosting is a way for + the hosted environment to call out to the emulator to + retrieve files from the host machine. + choice prompt "Target select" @@ -720,10 +727,15 @@ config TEGRA select CPU_ARM720T if SPL_BUILD select CPU_V7 if !SPL_BUILD -config TARGET_VEXPRESS_AEMV8A +config TARGET_VEXPRESS64_AEMV8A bool "Support vexpress_aemv8a" select ARM64 +config TARGET_VEXPRESS64_BASE_FVP + bool "Support Versatile Express ARMv8a FVP BASE model" + select ARM64 + select SEMIHOSTING + config TARGET_LS2085A_EMU bool "Support ls2085a_emu" select ARM64 diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig index 7ebea6317f..80eaa3d3ab 100644 --- a/board/armltd/vexpress64/Kconfig +++ b/board/armltd/vexpress64/Kconfig @@ -1,4 +1,17 @@ -if TARGET_VEXPRESS_AEMV8A +if TARGET_VEXPRESS64_AEMV8A + +config SYS_BOARD + default "vexpress64" + +config SYS_VENDOR + default "armltd" + +config SYS_CONFIG_NAME + default "vexpress_aemv8a" + +endif + +if TARGET_VEXPRESS64_BASE_FVP config SYS_BOARD default "vexpress64" diff --git a/configs/vexpress_aemv8a_defconfig b/configs/vexpress_aemv8a_defconfig index b463a333bc..9f4b876556 100644 --- a/configs/vexpress_aemv8a_defconfig +++ b/configs/vexpress_aemv8a_defconfig @@ -1,3 +1,3 @@ CONFIG_ARM=y -CONFIG_TARGET_VEXPRESS_AEMV8A=y +CONFIG_TARGET_VEXPRESS64_AEMV8A=y CONFIG_DEFAULT_DEVICE_TREE="vexpress64" diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig index 0035ccdaec..26cf7db47f 100644 --- a/configs/vexpress_aemv8a_semi_defconfig +++ b/configs/vexpress_aemv8a_semi_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="SEMIHOSTING,BASE_FVP" +# Semihosted FVP fast model CONFIG_ARM=y -CONFIG_TARGET_VEXPRESS_AEMV8A=y +CONFIG_TARGET_VEXPRESS64_BASE_FVP=y CONFIG_DEFAULT_DEVICE_TREE="vexpress64" diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h index 027d78b591..85894bedf8 100644 --- a/include/configs/vexpress_aemv8a.h +++ b/include/configs/vexpress_aemv8a.h @@ -11,9 +11,9 @@ /* We use generic board for v8 Versatile Express */ #define CONFIG_SYS_GENERIC_BOARD -#ifdef CONFIG_BASE_FVP +#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #ifndef CONFIG_SEMIHOSTING -#error CONFIG_BASE_FVP requires CONFIG_SEMIHOSTING +#error CONFIG_TARGET_VEXPRESS64_BASE_FVP requires CONFIG_SEMIHOSTING #endif #define CONFIG_BOARD_LATE_INIT #define CONFIG_ARMV8_SWITCH_TO_EL1 @@ -21,8 +21,8 @@ #define CONFIG_REMAKE_ELF -#ifndef CONFIG_BASE_FVP -/* Base FVP not using GICv3 yet */ +#ifndef CONFIG_TARGET_VEXPRESS64_BASE_FVP +/* Base FVP and Juno not using GICv3 yet */ #define CONFIG_GICV3 #endif @@ -40,7 +40,7 @@ #define CONFIG_BOOTP_VCI_STRING "U-boot.armv8.vexpress_aemv8a" /* Link Definitions */ -#ifdef CONFIG_BASE_FVP +#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP /* ATF loads u-boot here for BASE_FVP model */ #define CONFIG_SYS_TEXT_BASE 0x88000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) @@ -54,7 +54,7 @@ /* SMP Spin Table Definitions */ -#ifdef CONFIG_BASE_FVP +#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) #else #define CPU_RELEASE_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) @@ -119,7 +119,7 @@ #define GICR_BASE (0x2f100000) #else -#ifdef CONFIG_BASE_FVP +#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #define GICD_BASE (0x2f000000) #define GICC_BASE (0x2c000000) #else @@ -191,7 +191,7 @@ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 /* Initial environment variables */ -#ifdef CONFIG_BASE_FVP +#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #define CONFIG_EXTRA_ENV_SETTINGS \ "kernel_name=uImage\0" \ "kernel_addr_r=0x80000000\0" \ -- cgit From ffc103732c82faa945c85bbb7c5c34c30b6fac72 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 23 Jan 2015 14:41:10 +0100 Subject: vexpress64: support the Juno Development Platform The Juno Development Platform is a physical Versatile Express device with some differences from the emulated semihosting models. The main difference is that the system is split in a SoC and an FPGA where the SoC hosts the serial ports at totally different adresses. Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 4 ++++ board/armltd/vexpress64/Kconfig | 13 +++++++++++++ board/armltd/vexpress64/MAINTAINERS | 5 +++++ configs/vexpress_aemv8a_juno_defconfig | 5 +++++ include/configs/vexpress_aemv8a.h | 19 ++++++++++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 configs/vexpress_aemv8a_juno_defconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d5399f162d..986b4c5d81 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -736,6 +736,10 @@ config TARGET_VEXPRESS64_BASE_FVP select ARM64 select SEMIHOSTING +config TARGET_VEXPRESS64_JUNO + bool "Support Versatile Express Juno Development Platform" + select ARM64 + config TARGET_LS2085A_EMU bool "Support ls2085a_emu" select ARM64 diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig index 80eaa3d3ab..7d5e7bee8b 100644 --- a/board/armltd/vexpress64/Kconfig +++ b/board/armltd/vexpress64/Kconfig @@ -23,3 +23,16 @@ config SYS_CONFIG_NAME default "vexpress_aemv8a" endif + +if TARGET_VEXPRESS64_JUNO + +config SYS_BOARD + default "vexpress64" + +config SYS_VENDOR + default "armltd" + +config SYS_CONFIG_NAME + default "vexpress_aemv8a" + +endif diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS index 66c8dffa16..0ba044d7ff 100644 --- a/board/armltd/vexpress64/MAINTAINERS +++ b/board/armltd/vexpress64/MAINTAINERS @@ -9,3 +9,8 @@ VEXPRESS_AEMV8A_SEMI BOARD M: Linus Walleij S: Maintained F: configs/vexpress_aemv8a_semi_defconfig + +JUNO DEVELOPMENT PLATFORM BOARD +M: Linus Walleij +S: Maintained +F: configs/vexpress_aemv8a_juno_defconfig diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig new file mode 100644 index 0000000000..d28a4286e5 --- /dev/null +++ b/configs/vexpress_aemv8a_juno_defconfig @@ -0,0 +1,5 @@ +# ARM Ltd. Juno Board Reference Design +CONFIG_ARM=y +CONFIG_TARGET_VEXPRESS64_JUNO=y +CONFIG_DEFAULT_DEVICE_TREE="vexpress64" +CONFIG_SHOW_BOOT_PROGRESS=y diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h index 85894bedf8..7fb28a54ba 100644 --- a/include/configs/vexpress_aemv8a.h +++ b/include/configs/vexpress_aemv8a.h @@ -21,7 +21,8 @@ #define CONFIG_REMAKE_ELF -#ifndef CONFIG_TARGET_VEXPRESS64_BASE_FVP +#if !defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP) && \ + !defined(CONFIG_TARGET_VEXPRESS64_JUNO) /* Base FVP and Juno not using GICv3 yet */ #define CONFIG_GICV3 #endif @@ -44,6 +45,9 @@ /* ATF loads u-boot here for BASE_FVP model */ #define CONFIG_SYS_TEXT_BASE 0x88000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000) +#elif CONFIG_TARGET_VEXPRESS64_JUNO +#define CONFIG_SYS_TEXT_BASE 0xe0000000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) #else #define CONFIG_SYS_TEXT_BASE 0x80000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0) @@ -88,10 +92,15 @@ #define V2M_KMI0 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(6)) #define V2M_KMI1 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(7)) +#ifdef CONFIG_TARGET_VEXPRESS64_JUNO +#define V2M_UART0 0x7ff80000 +#define V2M_UART1 0x7ff70000 +#else /* Not Juno */ #define V2M_UART0 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(9)) #define V2M_UART1 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(10)) #define V2M_UART2 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(11)) #define V2M_UART3 (V2M_PA_CS3 + V2M_PERIPH_OFFSET(12)) +#endif #define V2M_WDT (V2M_PA_CS3 + V2M_PERIPH_OFFSET(15)) @@ -122,6 +131,9 @@ #ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP #define GICD_BASE (0x2f000000) #define GICC_BASE (0x2c000000) +#elif CONFIG_TARGET_VEXPRESS64_JUNO +#define GICD_BASE (0x2C010000) +#define GICC_BASE (0x2C02f000) #else #define GICD_BASE (0x2C001000) #define GICC_BASE (0x2C002000) @@ -140,7 +152,11 @@ /* PL011 Serial Configuration */ #define CONFIG_PL011_SERIAL +#ifdef CONFIG_TARGET_VEXPRESS64_JUNO +#define CONFIG_PL011_CLOCK 7273800 +#else #define CONFIG_PL011_CLOCK 24000000 +#endif #define CONFIG_PL01x_PORTS {(void *)CONFIG_SYS_SERIAL0, \ (void *)CONFIG_SYS_SERIAL1} #define CONFIG_CONS_INDEX 0 @@ -161,6 +177,7 @@ #define CONFIG_CMD_ENV #define CONFIG_CMD_FLASH #define CONFIG_CMD_IMI +#define CONFIG_CMD_LOADB #define CONFIG_CMD_MEMORY #define CONFIG_CMD_MII #define CONFIG_CMD_NET -- cgit From 2d73f0d6cd42a0ed9a791d665ddbd3d3bf287801 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 08:52:27 +0100 Subject: fpga: Extend dump description There are missing parameters in help which fpga dump command requires. Signed-off-by: Michal Simek --- common/cmd_fpga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 484a6c6ce0..7f99aabf8a 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -346,7 +346,7 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga, "loadable FPGA image support", "[operation type] [device number] [image address] [image size]\n" "fpga operations:\n" - " dump\t[dev]\t\t\tLoad device to memory buffer\n" + " dump\t[dev] [address] [size]\tLoad device to memory buffer\n" " info\t[dev]\t\t\tlist known device information\n" " load\t[dev] [address] [size]\tLoad device from memory buffer\n" #if defined(CONFIG_CMD_FPGA_LOADP) -- cgit From 0f274f5376f02ccf30327bf3e5c88d26d3ea8827 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 29 Jan 2015 18:03:39 +0800 Subject: ARM: armv7 fix spelling of SCTRL SCTLR is the abbreviation of System Control Register, so we should use SCTLR but not SCTRL. Signed-off-by: Peng Fan --- arch/arm/cpu/armv7/cpu.c | 2 +- arch/arm/cpu/armv7/start.S | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 01cdb7ee76..c56417dd2f 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -53,7 +53,7 @@ int cleanup_before_linux(void) * After D-cache is flushed and before it is disabled there may * be some new valid entries brought into the cache. We are sure * that these lines are not dirty and will not affect our execution. - * (because unwinding the call-stack and setting a bit in CP15 SCTRL + * (because unwinding the call-stack and setting a bit in CP15 SCTLR * is all we did during this. We have not pushed anything on to the * stack. Neither have we affected any static data) * So just invalidate the entire d-cache again to avoid coherency diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index fdc05b942f..70048c10ae 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -52,10 +52,10 @@ reset: * Continue to use ROM code vector only in OMAP4 spl) */ #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) - /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */ - mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register + /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ + mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register bic r0, #CR_V @ V = 0 - mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register + mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register /* Set vector address in CP15 VBAR register */ ldr r0, =_start -- cgit From 7f233c05573fabe8ff1ed7f22c269cdfdfc30529 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 10 Dec 2013 15:21:04 +0200 Subject: net: tsec: Fix NULL access in case init_phy() fails If the PHY is not recognized don't access phydev (NULL) and return 0 to signal failure. Signed-off-by: Claudiu Manoil Signed-off-by: Joe Hershberger --- drivers/net/tsec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 79d656133a..dcdba4ea82 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -597,6 +597,8 @@ static int init_phy(struct eth_device *dev) tsec_configure_serdes(priv); phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); + if (!phydev) + return 0; phydev->supported &= supported; phydev->advertising = phydev->supported; -- cgit From e9efe16da8e7233e59801e80f2770292a7fe4f77 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Thu, 13 Feb 2014 23:13:41 +0900 Subject: Add MS7206SE ethernet support Signed-off-by: Yoshinori Sato Signed-off-by: Joe Hershberger --- drivers/net/smc91111.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/net/smc91111.h b/drivers/net/smc91111.h index d9135cb57d..e19c491cbc 100644 --- a/drivers/net/smc91111.h +++ b/drivers/net/smc91111.h @@ -236,7 +236,36 @@ struct smc91111_priv{ *(__b2 + __i) = SMC_inb((a),(r)); \ }; \ }while(0) - +#elif defined(CONFIG_MS7206SE) +#define SWAB7206(x) ({ word __x = x; ((__x << 8)|(__x >> 8)); }) +#define SMC_inw(a, r) *((volatile word*)((a)->iobase + (r))) +#define SMC_inb(a, r) (*((volatile byte*)((a)->iobase + ((r) ^ 0x01)))) +#define SMC_insw(a, r, b, l) \ + do { \ + int __i; \ + word *__b2 = (word *)(b); \ + for (__i = 0; __i < (l); __i++) { \ + *__b2++ = SWAB7206(SMC_inw(a, r)); \ + } \ + } while (0) +#define SMC_outw(a, d, r) (*((volatile word *)((a)->iobase+(r))) = d) +#define SMC_outb(a, d, r) ({ word __d = (byte)(d); \ + word __w = SMC_inw((a), ((r)&(~1))); \ + if (((r) & 1)) \ + __w = (__w & 0x00ff) | (__d << 8); \ + else \ + __w = (__w & 0xff00) | (__d); \ + SMC_outw((a), __w, ((r)&(~1))); \ + }) +#define SMC_outsw(a, r, b, l) \ + do { \ + int __i; \ + word *__b2 = (word *)(b); \ + for (__i = 0; __i < (l); __i++) { \ + SMC_outw(a, SWAB7206(*__b2), r); \ + __b2++; \ + } \ + } while (0) #else /* if not CONFIG_CPU_PXA25X and not CONFIG_LEON */ #ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */ -- cgit From b7a5b0843812b7bd4a225951ce11e7d14398395c Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Wed, 19 Feb 2014 17:21:59 +0100 Subject: net: phy: micrel: add support for KSZ8895 switch in SMI mode This patch adds a phy driver for the Micrel KSZ8895 switch. As the SoC MAC is directly connected to the switch MAC the link to the switch is always up. But the KSZ8895 switch can be hardwired in three configuration modes : - not configurable with eventually an eeprom-stored configuration - configurable by the mdio/mdc connection (SMI protocol) - configurable by a SPI connection. In not configurable mode, the switch starts automatically, but in the other modes, it must be started programmatically, by writing 1 in configuration register 1. We only support the not configurable and mdio/mdc (aka SMI) modes here. Signed-off-by: Philippe De Muyter Cc: Christian Gmeiner Signed-off-by: Joe Hershberger --- drivers/net/phy/micrel.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 507b9a368b..1815b2900d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -22,6 +22,63 @@ static struct phy_driver KSZ804_driver = { .shutdown = &genphy_shutdown, }; +/** + * KSZ8895 + */ + +static unsigned short smireg_to_phy(unsigned short reg) +{ + return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5); +} + +static unsigned short smireg_to_reg(unsigned short reg) +{ + return reg & 0x1F; +} + +static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val) +{ + phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE, + smireg_to_reg(smireg), val); +} + +#if 0 +static int ksz8895_read_smireg(struct phy_device *phydev, int smireg) +{ + return phydev->bus->read(phydev->bus, smireg_to_phy(smireg), + MDIO_DEVAD_NONE, smireg_to_reg(smireg)); +} +#endif + +int ksz8895_config(struct phy_device *phydev) +{ + /* we are connected directly to the switch without + * dedicated PHY. SCONF1 == 001 */ + phydev->link = 1; + phydev->duplex = DUPLEX_FULL; + phydev->speed = SPEED_100; + + /* Force the switch to start */ + ksz8895_write_smireg(phydev, 1, 1); + + return 0; +} + +static int ksz8895_startup(struct phy_device *phydev) +{ + return 0; +} + +static struct phy_driver ksz8895_driver = { + .name = "Micrel KSZ8895/KSZ8864", + .uid = 0x221450, + .mask = 0xffffe1, + .features = PHY_BASIC_FEATURES, + .config = &ksz8895_config, + .startup = &ksz8895_startup, + .shutdown = &genphy_shutdown, +}; + #ifndef CONFIG_PHY_MICREL_KSZ9021 /* * I can't believe Micrel used the exact same part number @@ -221,5 +278,6 @@ int phy_micrel_init(void) phy_register(&KS8721_driver); #endif phy_register(&ksz9031_driver); + phy_register(&ksz8895_driver); return 0; } -- cgit From 875143f32428b8317a2b890b34a1eeb31cbf8a53 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 13 Jan 2015 17:10:24 +0300 Subject: net/designware: add error message on DMA reset timeout If for some reason DMA module fails to reset user oserves only this: --->--- # dhcp Trying dwmac.e0018000 FAIL --->--- This message makes not much sense. With proposed change error message will be more helpful: --->--- # dhcp Trying dwmac.e0018000 DMA reset timeout FAIL --->--- For example user may do power toggle to recover board functionality. Signed-off-by: Alexey Brodkin Cc: Chin Liang See Cc: Dinh Nguyen Cc: Albert Aribaud Cc: Tom Rini Cc: Wolfgang Denk Cc: Pavel Machek Cc: Joe Hershberger Cc: Ian Campbell Cc: Marek Vasut Reviewed-by: Tom Rini Acked-by: Pavel Machek Acked-by: Joe Hershberger Signed-off-by: Joe Hershberger --- drivers/net/designware.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 9ded8950b8..c03e935e2f 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -236,8 +236,10 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) start = get_timer(0); while (readl(&dma_p->busmode) & DMAMAC_SRST) { - if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) + if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) { + printf("DMA reset timeout\n"); return -1; + } mdelay(100); }; -- cgit From 3b4a7f99c954afad308d9c5a4513c856eb9a84b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 20:21:33 -0700 Subject: sandbox: Correct cros-ec keyboard definition The other boards got updated to the standard binding. Update sandbox as well. Signed-off-by: Simon Glass --- arch/sandbox/dts/sandbox.dts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 11748aec79..68540befa9 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -73,10 +73,8 @@ cros-ec-keyb { compatible = "google,cros-ec-keyb"; - google,key-rows = <8>; - google,key-columns = <13>; - google,repeat-delay-ms = <240>; - google,repeat-rate-ms = <30>; + keypad,num-rows = <8>; + keypad,num-columns = <13>; google,ghost-filter; /* * Keymap entries take the form of 0xRRCCKKKK where -- cgit From 1f32ae95784acee8a2233043aa18bf1b3a4974d7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 20:21:34 -0700 Subject: sandbox: Add a -D option to use a default device tree It is painful to specify the full path to the device tree with the -d option. It is normally kept in the same directory as U-Boot, so provide an option to use this by default. Signed-off-by: Simon Glass --- arch/sandbox/cpu/start.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 42353d80a8..097f29a290 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,25 @@ static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) } SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); +static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state, + const char *arg) +{ + const char *fmt = "%s.dtb"; + char *fname; + int len; + + len = strlen(state->argv[0]) + strlen(fmt) + 1; + fname = os_malloc(len); + if (!fname) + return -ENOMEM; + snprintf(fname, len, fmt, state->argv[0]); + state->fdt_fname = fname; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0, + "Use the default u-boot.dtb control FDT in U-Boot directory"); + static int sandbox_cmdline_cb_interactive(struct sandbox_state *state, const char *arg) { -- cgit From 2181830f11c2bbfea31e5f3f957577a619fc3776 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 26 Jan 2015 11:42:21 -0600 Subject: patman: Make dry-run output match real functionality When run with the --dry-run argument patman prints out information showing what it would do. This information currently doesn't line up with what patman/git send-email really do. Some basic examples: - If an email address is addressed via "Series-cc" and "Patch-cc" patman shows that email address would be CC-ed two times. - If an email address is addressed via "Series-to" and "Patch-cc" patman shows that email address would be sent TO and CC-ed. - If an email address is addressed from a combination of tag aliases, get_maintainer.pl output, "Series-cc", "Patch-cc", etc patman shows that the email address would be CC-ed multiple times. Patman currently does try to send duplicate emails like the --dry-run output shows, but "git send-email" intelligently removes duplicate addresses so this patch shouldn't change the non-dry-run functionality. Change patman's output and email addressing to line up with the "git send-email" logic. This trims down patman's dry-run output and prevents confusion about what patman will do when emails are actually sent. Signed-off-by: Peter Tyser Acked-by: Simon Glass Tested-by: Simon Glass --- tools/patman/gitutil.py | 3 ++- tools/patman/series.py | 21 ++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index cc5a55ab3f..c593070d67 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -392,7 +392,8 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname, "Or do something like this\n" "git config sendemail.to u-boot@lists.denx.de") return - cc = BuildEmailList(series.get('cc'), '--cc', alias, raise_on_error) + cc = BuildEmailList(list(set(series.get('cc')) - set(series.get('to'))), + '--cc', alias, raise_on_error) if self_only: to = BuildEmailList([os.getenv('USER')], '--to', alias, raise_on_error) cc = [] diff --git a/tools/patman/series.py b/tools/patman/series.py index b67f870b7e..60ebc766f7 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -94,6 +94,9 @@ class Series(dict): cmd: The git command we would have run process_tags: Process tags as if they were aliases """ + to_set = set(gitutil.BuildEmailList(self.to)); + cc_set = set(gitutil.BuildEmailList(self.cc)); + col = terminal.Color() print 'Dry run, so not doing much. But I would do this:' print @@ -106,24 +109,16 @@ class Series(dict): commit = self.commits[upto] print col.Color(col.GREEN, ' %s' % args[upto]) cc_list = list(self._generated_cc[commit.patch]) - - # Skip items in To list - if 'to' in self: - try: - map(cc_list.remove, gitutil.BuildEmailList(self.to)) - except ValueError: - pass - - for email in cc_list: + for email in set(cc_list) - to_set - cc_set: if email == None: email = col.Color(col.YELLOW, "" % tag) if email: print ' Cc: ',email print - for item in gitutil.BuildEmailList(self.get('to', '')): + for item in to_set: print 'To:\t ', item - for item in gitutil.BuildEmailList(self.cc): + for item in cc_set - to_set: print 'Cc:\t ', item print 'Version: ', self.get('version') print 'Prefix:\t ', self.get('prefix') @@ -131,7 +126,7 @@ class Series(dict): print 'Cover: %d lines' % len(self.cover) cover_cc = gitutil.BuildEmailList(self.get('cover_cc', '')) all_ccs = itertools.chain(cover_cc, *self._generated_cc.values()) - for email in set(all_ccs): + for email in set(all_ccs) - to_set - cc_set: print ' Cc: ',email if cmd: print 'Git command: %s' % cmd @@ -230,7 +225,7 @@ class Series(dict): if add_maintainers: list += get_maintainer.GetMaintainer(commit.patch) all_ccs += list - print >>fd, commit.patch, ', '.join(list) + print >>fd, commit.patch, ', '.join(set(list)) self._generated_cc[commit.patch] = list if cover_fname: -- cgit From 4b89b8135f4792c456fbffbf7eea8456c3472455 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 25 Sep 2014 14:30:46 -0500 Subject: patman: Check commit_match before stripping leading whitespace True commit lines start at column zero. Anything that is indented is part of the commit message instead. I noticed this by trying to run buildman with commit e3a4facdfc07179ebe017a07b8de6224a935a9f3 as master, which contained a reference to a Linux commit inside the commit message. ProcessLine saw that as a genuite commit line, and thus buildman tried to build it, and died with an exception because that SHA is not present in the U-Boot tree. Signed-off-by: Scott Wood Acked-by: Simon Glass --- tools/patman/patchstream.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index da0488337b..8c3a0ec9ee 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -139,6 +139,9 @@ class PatchStream: # Initially we have no output. Prepare the input line string out = [] line = line.rstrip('\n') + + commit_match = re_commit.match(line) if self.is_log else None + if self.is_log: if line[:4] == ' ': line = line[4:] @@ -146,7 +149,6 @@ class PatchStream: # Handle state transition and skipping blank lines series_tag_match = re_series_tag.match(line) commit_tag_match = re_commit_tag.match(line) - commit_match = re_commit.match(line) if self.is_log else None cover_cc_match = re_cover_cc.match(line) signoff_match = re_signoff.match(line) tag_match = None -- cgit From 9b250ac400603fae55193412107fe3b1d746fa2f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 23 Sep 2014 13:05:59 -0600 Subject: sandbox: Fix README to indicate that vendor name is unset This brings in a additional small fix which was missed in a recent update to the README. Suggested-by: Masahiro Yamada Signed-off-by: Simon Glass Acked-by: Jagannadha Sutradharudu Teki --- board/sandbox/README.sandbox | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox index 5f879f5506..3c0df17845 100644 --- a/board/sandbox/README.sandbox +++ b/board/sandbox/README.sandbox @@ -18,8 +18,8 @@ create unit tests which we can run to test this upper level code. CONFIG_SANDBOX is defined when building a native board. -The chosen vendor and board names are also 'sandbox', so there is a single -board in board/sandbox. +The board name is 'sandbox' but the vendor name is unset, so there is a +single board in board/sandbox. CONFIG_SANDBOX_BIG_ENDIAN should be defined when running on big-endian machines. -- cgit From 3d4de98696d2d906c968008219bb9a65960e7c10 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 3 Oct 2014 20:40:36 -0600 Subject: patman: Explain how to make doc/git-mailrc work Add an explanation for how to set up git so that patman can find the alias file. Fix up the get_maintainers message too. Reported-by: Scott Wood Signed-off-by: Simon Glass --- tools/patman/README | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/patman/README b/tools/patman/README index e466886ed2..7d039e82bc 100644 --- a/tools/patman/README +++ b/tools/patman/README @@ -52,12 +52,15 @@ will get a consistent result each time. How to configure it =================== -For most cases of using patman for U-Boot development, patman will -locate and use the file 'doc/git-mailrc' in your U-Boot directory. -This contains most of the aliases you will need. +For most cases of using patman for U-Boot development, patman can use the +file 'doc/git-mailrc' in your U-Boot directory to supply the email aliases +you need. To make this work, tell git where to find the file by typing +this once: -For Linux the 'scripts/get_maintainer.pl' handles figuring out where -to send patches pretty well. + git config sendemail.aliasesfile doc/git-mailrc + +For both Linux and U-Boot the 'scripts/get_maintainer.pl' handles figuring +out where to send patches pretty well. During the first run patman creates a config file for you by taking the default user name and email address from the global .gitconfig file. -- cgit From ad40610b48bc3e248f5e79d94084427aa6a0b9e2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 23 Jan 2015 15:28:22 +0100 Subject: sunxi: Only enable i2c support in the SPL when needed We do not need i2c support in the SPL when there is no PMIC (some sun4i boards), or when the PMIC is not using i2c such as on sun6i and sun8i. This reduces the SPL size from (e.g.) 21812 to 19260 bytes. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- include/configs/sunxi-common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 4a5cab25d4..6cfd7e1489 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -181,7 +181,10 @@ #define CONFIG_SYS_SPL_MALLOC_SIZE 0x00080000 /* 512 KiB */ /* I2C */ +#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER #define CONFIG_SPL_I2C_SUPPORT +#endif + #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI #define CONFIG_SYS_I2C_SPEED 400000 -- cgit From 046664aedd1da0b964cdf678371b11cce3eb0468 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 23 Jan 2015 16:40:01 +0100 Subject: sunxi: Hyundai_A7HD_defconfig fix USB vbus pin config USB1_VBUS is not used, and USB2_VBUS uses the pin normally used to control USB1_VBUS. Signed-off-by: Hans de Goede --- configs/Hyundai_A7HD_defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/Hyundai_A7HD_defconfig b/configs/Hyundai_A7HD_defconfig index 60eb03ef26..204640ee24 100644 --- a/configs/Hyundai_A7HD_defconfig +++ b/configs/Hyundai_A7HD_defconfig @@ -6,7 +6,8 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" CONFIG_FDTFILE="sun4i-a10-hyundai-a7hd.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PB09" -CONFIG_USB2_VBUS_PIN="" +CONFIG_USB1_VBUS_PIN="" +CONFIG_USB2_VBUS_PIN="PH6" CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:45,ri:274,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_DCLK_PHASE=1 CONFIG_VIDEO_LCD_POWER="PH2" -- cgit From e1a0888ed224cc4c4e019a37b7b0331b11745e4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 25 Jan 2015 11:29:27 +0100 Subject: sunxi: Convert sun5i boards to use auto dram configuration Currently we've separate detailed dram settings for all sun5i boards, this moves them over to using auto dram configuration so that we can get rid of all the per board dram_foo.c files. This has been tested on a A10s-Olinuxino, A13-Olinuxino, A13-OlinuxinoM, mk802-a10s and r7-tv-dongle board. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 9 +++------ board/sunxi/Makefile | 8 +------- board/sunxi/dram_a10s_olinuxino_m.c | 31 ------------------------------- board/sunxi/dram_a13_oli_micro.c | 32 -------------------------------- board/sunxi/dram_a13_olinuxino.c | 31 ------------------------------- board/sunxi/dram_bananapi.c | 31 ------------------------------- board/sunxi/dram_r7dongle.c | 31 ------------------------------- configs/A10s-OLinuXino-M_defconfig | 3 +++ configs/A13-OLinuXinoM_defconfig | 3 +++ configs/A13-OLinuXino_defconfig | 3 +++ configs/Auxtek-T004_defconfig | 3 +++ configs/r7-tv-dongle_defconfig | 3 +++ 12 files changed, 19 insertions(+), 169 deletions(-) delete mode 100644 board/sunxi/dram_a10s_olinuxino_m.c delete mode 100644 board/sunxi/dram_a13_oli_micro.c delete mode 100644 board/sunxi/dram_a13_olinuxino.c delete mode 100644 board/sunxi/dram_bananapi.c delete mode 100644 board/sunxi/dram_r7dongle.c diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 738b55e74a..f48b8c05f8 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -39,16 +39,14 @@ config DRAM_CLK default 360 if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I ---help--- Set the dram clock speed, valid range 240 - 480, must be a multiple - of 24. Note on sun4i / sun5i / sun7i this is only used by boards - which use dram autoconfig. + of 24. config DRAM_ZQ int "sunxi dram zq value" default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I default 127 if MACH_SUN7I ---help--- - Set the dram zq value. Note on sun4i / sun5i / sun7i this is only - used by boards which use dram autoconfig. + Set the dram zq value. if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I config DRAM_EMR1 @@ -56,8 +54,7 @@ config DRAM_EMR1 default 0 if MACH_SUN4I default 4 if MACH_SUN5I || MACH_SUN7I ---help--- - Set the dram controller emr1 value. Note this is only used by boards - which use dram autoconfig. + Set the dram controller emr1 value. endif config SYS_CONFIG_NAME diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 71edb83c5d..43766e0ef4 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -12,11 +12,5 @@ obj-y += board.o obj-$(CONFIG_SUNXI_GMAC) += gmac.o obj-$(CONFIG_SUNXI_AHCI) += ahci.o obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o +obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o -obj-$(CONFIG_TARGET_A10S_OLINUXINO_M) += dram_a10s_olinuxino_m.o -obj-$(CONFIG_TARGET_A13_OLINUXINO) += dram_a13_olinuxino.o -obj-$(CONFIG_TARGET_A13_OLINUXINOM) += dram_a13_oli_micro.o -# This is not a typo, uses the same mem settings as the a10s-olinuxino-m -obj-$(CONFIG_TARGET_AUXTEK_T004) += dram_a10s_olinuxino_m.o -obj-$(CONFIG_TARGET_MK802_A10S) += dram_sun5i_auto.o -obj-$(CONFIG_TARGET_R7DONGLE) += dram_r7dongle.o diff --git a/board/sunxi/dram_a10s_olinuxino_m.c b/board/sunxi/dram_a10s_olinuxino_m.c deleted file mode 100644 index 8900539e7f..0000000000 --- a/board/sunxi/dram_a10s_olinuxino_m.c +++ /dev/null @@ -1,31 +0,0 @@ -/* this file is generated, don't edit it yourself */ - -#include -#include - -static struct dram_para dram_para = { - .clock = 432, - .type = 3, - .rank_num = 1, - .density = 4096, - .io_width = 16, - .bus_width = 16, - .cas = 9, - .zq = 123, - .odt_en = 0, - .size = 512, - .tpr0 = 0x42d899b7, - .tpr1 = 0xa090, - .tpr2 = 0x22a00, - .tpr3 = 0, - .tpr4 = 0, - .tpr5 = 0, - .emr1 = 0x4, - .emr2 = 0x10, - .emr3 = 0, -}; - -unsigned long sunxi_dram_init(void) -{ - return dramc_init(&dram_para); -} diff --git a/board/sunxi/dram_a13_oli_micro.c b/board/sunxi/dram_a13_oli_micro.c deleted file mode 100644 index 8154ea2ca9..0000000000 --- a/board/sunxi/dram_a13_oli_micro.c +++ /dev/null @@ -1,32 +0,0 @@ -/* this file is generated, don't edit it yourself */ - -#include -#include - -static struct dram_para dram_para = { - .clock = 408, - .type = 3, - .rank_num = 1, - .density = 2048, - .io_width = 16, - .bus_width = 16, - .cas = 9, - .zq = 123, - .odt_en = 0, - .size = 256, - .tpr0 = 0x42d899b7, - .tpr1 = 0xa090, - .tpr2 = 0x22a00, - .tpr3 = 0, - .tpr4 = 0, - .tpr5 = 0, - .emr1 = 0, - .emr2 = 0x10, - .emr3 = 0, - -}; - -unsigned long sunxi_dram_init(void) -{ - return dramc_init(&dram_para); -} diff --git a/board/sunxi/dram_a13_olinuxino.c b/board/sunxi/dram_a13_olinuxino.c deleted file mode 100644 index ca96260250..0000000000 --- a/board/sunxi/dram_a13_olinuxino.c +++ /dev/null @@ -1,31 +0,0 @@ -/* this file is generated, don't edit it yourself */ - -#include -#include - -static struct dram_para dram_para = { - .clock = 408, - .type = 3, - .rank_num = 1, - .density = 2048, - .io_width = 8, - .bus_width = 16, - .cas = 9, - .zq = 123, - .odt_en = 0, - .size = 512, - .tpr0 = 0x42d899b7, - .tpr1 = 0xa090, - .tpr2 = 0x22a00, - .tpr3 = 0, - .tpr4 = 0, - .tpr5 = 0, - .emr1 = 0, - .emr2 = 0x10, - .emr3 = 0, -}; - -unsigned long sunxi_dram_init(void) -{ - return dramc_init(&dram_para); -} diff --git a/board/sunxi/dram_bananapi.c b/board/sunxi/dram_bananapi.c deleted file mode 100644 index 0ed7943043..0000000000 --- a/board/sunxi/dram_bananapi.c +++ /dev/null @@ -1,31 +0,0 @@ -/* this file is generated, don't edit it yourself */ - -#include -#include - -static struct dram_para dram_para = { - .clock = 432, - .type = 3, - .rank_num = 1, - .density = 4096, - .io_width = 16, - .bus_width = 32, - .cas = 9, - .zq = 0x7f, - .odt_en = 0, - .size = 1024, - .tpr0 = 0x42d899b7, - .tpr1 = 0xa090, - .tpr2 = 0x22a00, - .tpr3 = 0x0, - .tpr4 = 0x1, - .tpr5 = 0x0, - .emr1 = 0x4, - .emr2 = 0x10, - .emr3 = 0x0, -}; - -unsigned long sunxi_dram_init(void) -{ - return dramc_init(&dram_para); -} diff --git a/board/sunxi/dram_r7dongle.c b/board/sunxi/dram_r7dongle.c deleted file mode 100644 index 59343cb2a5..0000000000 --- a/board/sunxi/dram_r7dongle.c +++ /dev/null @@ -1,31 +0,0 @@ -/* this file is generated, don't edit it yourself */ - -#include -#include - -static struct dram_para dram_para = { - .clock = 384, - .type = 3, - .rank_num = 1, - .density = 2048, - .io_width = 8, - .bus_width = 32, - .cas = 9, - .zq = 123, - .odt_en = 0, - .size = 1024, - .tpr0 = 0x42d899b7, - .tpr1 = 0xa090, - .tpr2 = 0x22a00, - .tpr3 = 0, - .tpr4 = 0, - .tpr5 = 0, - .emr1 = 0x04, - .emr2 = 0x10, - .emr3 = 0, -}; - -unsigned long sunxi_dram_init(void) -{ - return dramc_init(&dram_para); -} diff --git a/configs/A10s-OLinuXino-M_defconfig b/configs/A10s-OLinuXino-M_defconfig index 94fafa6b97..79a27db3e2 100644 --- a/configs/A10s-OLinuXino-M_defconfig +++ b/configs/A10s-OLinuXino-M_defconfig @@ -9,3 +9,6 @@ CONFIG_USB1_VBUS_PIN="PB10" +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y +S:CONFIG_TARGET_A10S_OLINUXINO_M=y ++S:CONFIG_DRAM_CLK=432 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index 1a994180b5..d392ec40b7 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -13,3 +13,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PB2" +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y +S:CONFIG_TARGET_A13_OLINUXINOM=y ++S:CONFIG_DRAM_CLK=408 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=0 diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 7df69517f6..cf205a7b3a 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -13,3 +13,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PB2" +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y +S:CONFIG_TARGET_A13_OLINUXINO=y ++S:CONFIG_DRAM_CLK=408 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=0 diff --git a/configs/Auxtek-T004_defconfig b/configs/Auxtek-T004_defconfig index 7fe9059179..eb1d003d7b 100644 --- a/configs/Auxtek-T004_defconfig +++ b/configs/Auxtek-T004_defconfig @@ -6,3 +6,6 @@ CONFIG_USB1_VBUS_PIN="PG13" +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y +S:CONFIG_TARGET_AUXTEK_T004=y ++S:CONFIG_DRAM_CLK=432 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 diff --git a/configs/r7-tv-dongle_defconfig b/configs/r7-tv-dongle_defconfig index b9fd59c16a..f467d6cf75 100644 --- a/configs/r7-tv-dongle_defconfig +++ b/configs/r7-tv-dongle_defconfig @@ -6,3 +6,6 @@ CONFIG_USB1_VBUS_PIN="PG13" +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y +S:CONFIG_TARGET_R7DONGLE=y ++S:CONFIG_DRAM_CLK=384 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 -- cgit From c13f60d92a1c31c131a53ff8e994e4c8eebb8311 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 25 Jan 2015 12:10:48 +0100 Subject: sunxi: Add a GMAC Transmit Clock Delay Chain Kconfig option And use this to set the GMAC Transmit Clock Delay Chain value on Banana boards, rather then keying of CONFIG_TARGET_FOO. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 ++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 2 ++ board/sunxi/Kconfig | 6 ++++++ board/sunxi/gmac.c | 11 ++--------- configs/Bananapi_defconfig | 1 + configs/Bananapro_defconfig | 1 + 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h index 05fbad3e11..d297ed0f73 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h @@ -305,6 +305,8 @@ struct sunxi_ccm_reg { #define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 #define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2) #define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2) +#define CCM_GMAC_CTRL_RX_CLK_DELAY(x) ((x) << 5) +#define CCM_GMAC_CTRL_TX_CLK_DELAY(x) ((x) << 10) #define CCM_USB_CTRL_PHY0_RST (0x1 << 0) #define CCM_USB_CTRL_PHY1_RST (0x1 << 1) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index e101c54051..8a803851e4 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -243,6 +243,8 @@ struct sunxi_ccm_reg { #define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 #define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2) #define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2) +#define CCM_GMAC_CTRL_RX_CLK_DELAY(x) ((x) << 5) +#define CCM_GMAC_CTRL_TX_CLK_DELAY(x) ((x) << 10) #define MDFS_CLK_DEFAULT 0x81000002 /* PLL6 / 3 */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index f48b8c05f8..15e3d463fc 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -380,4 +380,10 @@ config USB_KEYBOARD Say Y here to add support for using a USB keyboard (typically used in combination with a graphical console). +config GMAC_TX_DELAY + int "GMAC Transmit Clock Delay Chain" + default 0 + ---help--- + Set the GMAC Transmit Clock Delay Chain value. + endif diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index 4e4615e12f..8849132627 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -24,20 +24,13 @@ int sunxi_gmac_initialize(bd_t *bis) #ifdef CONFIG_RGMII setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | CCM_GMAC_CTRL_GPIT_RGMII); + setbits_le32(&ccm->gmac_clk_cfg, + CCM_GMAC_CTRL_TX_CLK_DELAY(CONFIG_GMAC_TX_DELAY)); #else setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII | CCM_GMAC_CTRL_GPIT_MII); #endif - /* - * In order for the gmac nic to work reliable on the Bananapi, we - * need to set bits 10-12 GTXDC "GMAC Transmit Clock Delay Chain" - * of the GMAC clk register to 3. - */ -#if defined CONFIG_TARGET_BANANAPI || defined CONFIG_TARGET_BANANAPRO - setbits_le32(&ccm->gmac_clk_cfg, 0x3 << 10); -#endif - #ifndef CONFIG_MACH_SUN6I /* Configure pin mux settings for GMAC */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig index d94e08e0eb..4cff573503 100644 --- a/configs/Bananapi_defconfig +++ b/configs/Bananapi_defconfig @@ -1,6 +1,7 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI" CONFIG_FDTFILE="sun7i-a20-bananapi.dtb" +CONFIG_GMAC_TX_DELAY=3 +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 02e4f3e9fe..051201994e 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHC CONFIG_FDTFILE="sun7i-a20-bananapro.dtb" CONFIG_USB1_VBUS_PIN="PH0" CONFIG_USB2_VBUS_PIN="PH1" +CONFIG_GMAC_TX_DELAY=3 +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -- cgit From 40d0cdda3e2667260100b75d79a9a53f206a0739 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 25 Jan 2015 12:15:14 +0100 Subject: sunxi: Remove CONFIG_TARGET_FOO for sun5i and sun7i boards CONFIG_TARGET_FOO was only used in board/sunxi/Makefile to select the dram config for sun5i and sun7i boards and in board/sunxi/gmac.c for some special handling of the bananapi/bananapro (both sun7i), all sun5i and sun7i boards have been moved over to using a single dram_sun5i_autoconfig file, and the tx clk delay handling for the Banana boards now has its own Kconfig. IOW nothing is using CONFIG_TARGET_FOO anymore, so remove it. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 82 ------------------------------- configs/A10s-OLinuXino-M_defconfig | 1 - configs/A13-OLinuXinoM_defconfig | 1 - configs/A13-OLinuXino_defconfig | 1 - configs/A20-OLinuXino-Lime2_defconfig | 1 - configs/A20-OLinuXino-Lime_defconfig | 1 - configs/A20-OLinuXino_MICRO_defconfig | 1 - configs/Auxtek-T004_defconfig | 1 - configs/Bananapi_defconfig | 1 - configs/Bananapro_defconfig | 1 - configs/Cubieboard2_defconfig | 1 - configs/Cubietruck_defconfig | 1 - configs/Ippo_q8h_v5_defconfig | 1 - configs/Linksprite_pcDuino3_defconfig | 1 - configs/Linksprite_pcDuino3_fdt_defconfig | 1 - configs/MSI_Primo73_defconfig | 9 +++- configs/Mele_M3_defconfig | 1 - configs/i12-tvbox_defconfig | 1 - configs/mk802_a10s_defconfig | 1 - configs/r7-tv-dongle_defconfig | 1 - 20 files changed, 8 insertions(+), 101 deletions(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 15e3d463fc..4b31dcca20 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -64,88 +64,6 @@ config SYS_CONFIG_NAME default "sun7i" if MACH_SUN7I default "sun8i" if MACH_SUN8I -choice - prompt "Board" - -config TARGET_A10S_OLINUXINO_M - bool "A10S_OLINUXINO_M" - depends on MACH_SUN5I - -config TARGET_A13_OLINUXINOM - bool "A13_OLINUXINOM" - depends on MACH_SUN5I - -config TARGET_A13_OLINUXINO - bool "A13_OLINUXINO" - depends on MACH_SUN5I - -config TARGET_A20_OLINUXINO_L2 - bool "A20_OLINUXINO_L2" - depends on MACH_SUN7I - -config TARGET_A20_OLINUXINO_L - bool "A20_OLINUXINO_L" - depends on MACH_SUN7I - -config TARGET_A20_OLINUXINO_M - bool "A20_OLINUXINO_M" - depends on MACH_SUN7I - -config TARGET_AUXTEK_T004 - bool "AUXTEK_T004" - depends on MACH_SUN5I - -config TARGET_BANANAPI - bool "BANANAPI" - depends on MACH_SUN7I - -config TARGET_BANANAPRO - bool "BANANAPRO" - depends on MACH_SUN7I - -config TARGET_CUBIEBOARD2 - bool "CUBIEBOARD2" - depends on MACH_SUN7I - -config TARGET_CUBIETRUCK - bool "CUBIETRUCK" - depends on MACH_SUN7I - -config TARGET_PCDUINO3 - bool "PCDUINO3" - depends on MACH_SUN7I - -config TARGET_MELE_M3 - bool "MELE_M3" - depends on MACH_SUN7I - -config TARGET_MK802_A10S - bool "MK802_A10S" - depends on MACH_SUN5I - -config TARGET_MSI_PRIMO73 - bool "MSI Primo73 (7\" tablet)" - depends on MACH_SUN7I - ---help--- - The MSI Primo73 is an A20 based tablet, with 1G RAM, 16G NAND, - 1024x600 TN LCD display, mono speaker, 0.3 MP front camera, 2.0 MP - rear camera, 3000 mAh battery, gt911 touchscreen, mma8452 accelerometer - and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons - (both volume buttons are also connected to the UBOOT_SEL pin). The - external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB - OTG and 3.5mm headphone jack. More details are available at - http://linux-sunxi.org/MSI_Primo73 - -config TARGET_I12_TVBOX - bool "I12_TVBOX" - depends on MACH_SUN7I - -config TARGET_R7DONGLE - bool "R7DONGLE" - depends on MACH_SUN5I - -endchoice - config SYS_BOARD default "sunxi" diff --git a/configs/A10s-OLinuXino-M_defconfig b/configs/A10s-OLinuXino-M_defconfig index 79a27db3e2..b5f0a0f782 100644 --- a/configs/A10s-OLinuXino-M_defconfig +++ b/configs/A10s-OLinuXino-M_defconfig @@ -8,7 +8,6 @@ CONFIG_USB1_VBUS_PIN="PB10" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_A10S_OLINUXINO_M=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index d392ec40b7..1c3fc3a3e9 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -12,7 +12,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PB2" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_A13_OLINUXINOM=y +S:CONFIG_DRAM_CLK=408 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=0 diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index cf205a7b3a..0daaaae5b4 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -12,7 +12,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PB2" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_A13_OLINUXINO=y +S:CONFIG_DRAM_CLK=408 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=0 diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index 17fd19da8f..ff94e77200 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun7i-a20-olinuxino-lime2.dtb" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_A20_OLINUXINO_L2=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index c8243a4ae8..5442f645f8 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun7i-a20-olinuxino-lime.dtb" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_A20_OLINUXINO_L=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig index ac94c79086..97a21ee534 100644 --- a/configs/A20-OLinuXino_MICRO_defconfig +++ b/configs/A20-OLinuXino_MICRO_defconfig @@ -8,7 +8,6 @@ CONFIG_VIDEO_VGA=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_A20_OLINUXINO_M=y +S:CONFIG_DRAM_CLK=384 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Auxtek-T004_defconfig b/configs/Auxtek-T004_defconfig index eb1d003d7b..03ec3dbdc4 100644 --- a/configs/Auxtek-T004_defconfig +++ b/configs/Auxtek-T004_defconfig @@ -5,7 +5,6 @@ CONFIG_USB1_VBUS_PIN="PG13" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_AUXTEK_T004=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig index 4cff573503..5aba938276 100644 --- a/configs/Bananapi_defconfig +++ b/configs/Bananapi_defconfig @@ -5,7 +5,6 @@ CONFIG_GMAC_TX_DELAY=3 +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_BANANAPI=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 051201994e..e501b5c95c 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -7,7 +7,6 @@ CONFIG_GMAC_TX_DELAY=3 +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_BANANAPRO=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig index ef5b43aada..7704a0ef81 100644 --- a/configs/Cubieboard2_defconfig +++ b/configs/Cubieboard2_defconfig @@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun7i-a20-cubieboard2.dtb" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_CUBIEBOARD2=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index f51c491af2..b64f84f2b8 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -5,7 +5,6 @@ CONFIG_VIDEO_VGA=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_CUBIETRUCK=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig index c894948d88..4786202e16 100644 --- a/configs/Ippo_q8h_v5_defconfig +++ b/configs/Ippo_q8h_v5_defconfig @@ -11,7 +11,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PH0" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN8I=y -+S:CONFIG_TARGET_IPPO_Q8H_V5=y +S:CONFIG_DRAM_CLK=480 # zq = 0xf777 +S:CONFIG_DRAM_ZQ=63351 diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig index 64e01c8ffd..45d88f3015 100644 --- a/configs/Linksprite_pcDuino3_defconfig +++ b/configs/Linksprite_pcDuino3_defconfig @@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_PCDUINO3=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=122 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig index 49718c798c..3b6dfa6fa6 100644 --- a/configs/Linksprite_pcDuino3_fdt_defconfig +++ b/configs/Linksprite_pcDuino3_fdt_defconfig @@ -8,7 +8,6 @@ CONFIG_OF_SEPARATE=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_PCDUINO3=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=122 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/MSI_Primo73_defconfig b/configs/MSI_Primo73_defconfig index 6628184cb7..c6fb7e65d0 100644 --- a/configs/MSI_Primo73_defconfig +++ b/configs/MSI_Primo73_defconfig @@ -1,3 +1,11 @@ +# The MSI Primo73 is an A20 based tablet, with 1G RAM, 16G NAND, +# 1024x600 TN LCD display, mono speaker, 0.3 MP front camera, 2.0 MP +# rear camera, 3000 mAh battery, gt911 touchscreen, mma8452 accelerometer +# and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons +# (both volume buttons are also connected to the UBOOT_SEL pin). The +# external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB +# OTG and 3.5mm headphone jack. More details are available at +# http://linux-sunxi.org/MSI_Primo73 CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" CONFIG_FDTFILE="sun7i-a20-primo73.dtb" @@ -10,7 +18,6 @@ CONFIG_USB_KEYBOARD=n +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_MSI_PRIMO73=y +S:CONFIG_DRAM_CLK=384 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig index 7f1710adad..723a72a2ef 100644 --- a/configs/Mele_M3_defconfig +++ b/configs/Mele_M3_defconfig @@ -7,7 +7,6 @@ CONFIG_VIDEO_VGA=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_MELE_M3=y +S:CONFIG_DRAM_CLK=384 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig index 65791b7dc1..41192fc73f 100644 --- a/configs/i12-tvbox_defconfig +++ b/configs/i12-tvbox_defconfig @@ -4,7 +4,6 @@ CONFIG_FDTFILE="sun7i-a20-i12-tvbox.dtb" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN7I=y -+S:CONFIG_TARGET_I12_TVBOX=y +S:CONFIG_DRAM_CLK=384 +S:CONFIG_DRAM_ZQ=127 +S:CONFIG_DRAM_EMR1=4 diff --git a/configs/mk802_a10s_defconfig b/configs/mk802_a10s_defconfig index 086e1e4fa8..cafcbaa62e 100644 --- a/configs/mk802_a10s_defconfig +++ b/configs/mk802_a10s_defconfig @@ -5,7 +5,6 @@ CONFIG_USB1_VBUS_PIN="PB10" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_MK802_A10S=y +S:CONFIG_DRAM_CLK=432 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=0 diff --git a/configs/r7-tv-dongle_defconfig b/configs/r7-tv-dongle_defconfig index f467d6cf75..e99e57d505 100644 --- a/configs/r7-tv-dongle_defconfig +++ b/configs/r7-tv-dongle_defconfig @@ -5,7 +5,6 @@ CONFIG_USB1_VBUS_PIN="PG13" +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y +S:CONFIG_MACH_SUN5I=y -+S:CONFIG_TARGET_R7DONGLE=y +S:CONFIG_DRAM_CLK=384 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=4 -- cgit From d35488c7359ac5b6e20d9fe1895360aa7f3122f2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 26 Jan 2015 16:46:43 +0100 Subject: sunxi: rsb: Add sun9i (A80 support) Add support for the A80 to the rsb code. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/rsb.c | 11 +++++++++++ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 +++-- arch/arm/include/asm/arch-sunxi/gpio.h | 9 +++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 1c4b7633f9..48db7442f4 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -15,8 +15,10 @@ obj-y += pinmux.o obj-y += usbc.o obj-$(CONFIG_MACH_SUN6I) += prcm.o obj-$(CONFIG_MACH_SUN8I) += prcm.o +obj-$(CONFIG_MACH_SUN9I) += prcm.o obj-$(CONFIG_MACH_SUN6I) += p2wi.o obj-$(CONFIG_MACH_SUN8I) += rsb.o +obj-$(CONFIG_MACH_SUN9I) += rsb.o obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index b72bb9db51..55e943323f 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -18,12 +18,23 @@ static void rsb_cfg_io(void) { +#ifdef CONFIG_MACH_SUN8I sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL0_R_RSB_SCK); sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL1_R_RSB_SDA); sunxi_gpio_set_pull(SUNXI_GPL(0), 1); sunxi_gpio_set_pull(SUNXI_GPL(1), 1); sunxi_gpio_set_drv(SUNXI_GPL(0), 2); sunxi_gpio_set_drv(SUNXI_GPL(1), 2); +#elif defined CONFIG_MACH_SUN9I + sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN0_R_RSB_SCK); + sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN1_R_RSB_SDA); + sunxi_gpio_set_pull(SUNXI_GPN(0), 1); + sunxi_gpio_set_pull(SUNXI_GPN(1), 1); + sunxi_gpio_set_drv(SUNXI_GPN(0), 2); + sunxi_gpio_set_drv(SUNXI_GPN(1), 2); +#else +#error unsupported MACH_SUNXI +#endif } static void rsb_set_clk(void) diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h index a2a7839c6b..04889c51fa 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h @@ -73,7 +73,6 @@ #define SUNXI_CCM_BASE (REGS_APB0_BASE + 0x0000) #define SUNXI_CCMMODULE_BASE (REGS_APB0_BASE + 0x0400) #define SUNXI_PIO_BASE (REGS_APB0_BASE + 0x0800) -#define SUNXI_R_PIO_BASE (0x08002C00) #define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00) #define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400) #define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) @@ -92,8 +91,10 @@ #define SUNXI_TWI4_BASE (REGS_APB1_BASE + 0x3800) /* RCPUS Module */ -#define SUNXI_RPRCM_BASE (REGS_RCPUS_BASE + 0x1400) +#define SUNXI_PRCM_BASE (REGS_RCPUS_BASE + 0x1400) #define SUNXI_R_UART_BASE (REGS_RCPUS_BASE + 0x2800) +#define SUNXI_R_PIO_BASE (REGS_RCPUS_BASE + 0x2c00) +#define SUNXI_RSB_BASE (REGS_RCPUS_BASE + 0x3400) /* Misc. */ #define SUNXI_BROM_BASE 0xFFFF0000 /* 32K */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 71cc879c2b..f2c247d79f 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -45,9 +45,13 @@ * * sun8i has 1 bank: * PL0 - PL11 + * + * sun9i has 3 banks: + * PL0 - PL9 | PM0 - PM15 | PN0 - PN1 */ #define SUNXI_GPIO_L 11 #define SUNXI_GPIO_M 12 +#define SUNXI_GPIO_N 13 struct sunxi_gpio { u32 cfg[4]; @@ -114,6 +118,7 @@ enum sunxi_gpio_number { SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H), SUNXI_GPIO_L_START = 352, SUNXI_GPIO_M_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_L), + SUNXI_GPIO_N_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_M), SUNXI_GPIO_AXP0_START = 1024, }; @@ -129,6 +134,7 @@ enum sunxi_gpio_number { #define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr)) #define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr)) #define SUNXI_GPM(_nr) (SUNXI_GPIO_M_START + (_nr)) +#define SUNXI_GPN(_nr) (SUNXI_GPIO_N_START + (_nr)) #define SUNXI_GPAXP0(_nr) (SUNXI_GPIO_AXP0_START + (_nr)) @@ -187,6 +193,9 @@ enum sunxi_gpio_number { #define SUN8I_GPL2_R_UART_TX 2 #define SUN8I_GPL3_R_UART_RX 2 +#define SUN9I_GPN0_R_RSB_SCK 3 +#define SUN9I_GPN1_R_RSB_SDA 3 + /* GPIO pin pull-up/down config */ #define SUNXI_GPIO_PULL_DISABLE 0 #define SUNXI_GPIO_PULL_UP 1 -- cgit From 37d46dd3c4f3617b88a5797aab3600d3a4f32bd5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 26 Jan 2015 16:59:12 +0100 Subject: sunxi: rsb: Move rsb_set_device_mode() call to rsb_init() It turns out that the device_mode_data is rsb specific, rather then slave specific, so integrate the rsb_set_device_mode() call into rsb_init(). Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/cpu/armv7/sunxi/rsb.c | 11 ++++++++--- arch/arm/include/asm/arch-sunxi/rsb.h | 4 ++-- drivers/power/axp221.c | 4 +--- include/axp221.h | 1 - 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index 55e943323f..b00befb301 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -16,6 +16,8 @@ #include #include +static int rsb_set_device_mode(void); + static void rsb_cfg_io(void) { #ifdef CONFIG_MACH_SUN8I @@ -53,7 +55,7 @@ static void rsb_set_clk(void) writel((cd_odly << 8) | div, &rsb->ccr); } -void rsb_init(void) +int rsb_init(void) { struct sunxi_rsb_reg * const rsb = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; @@ -65,6 +67,8 @@ void rsb_init(void) writel(RSB_CTRL_SOFT_RST, &rsb->ctrl); rsb_set_clk(); + + return rsb_set_device_mode(); } static int rsb_await_trans(void) @@ -99,13 +103,14 @@ static int rsb_await_trans(void) return ret; } -int rsb_set_device_mode(u32 device_mode_data) +static int rsb_set_device_mode(void) { struct sunxi_rsb_reg * const rsb = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; unsigned long tmo = timer_get_us() + 1000000; - writel(RSB_DMCR_DEVICE_MODE_START | device_mode_data, &rsb->dmcr); + writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA, + &rsb->dmcr); while (readl(&rsb->dmcr) & RSB_DMCR_DEVICE_MODE_START) { if (timer_get_us() > tmo) diff --git a/arch/arm/include/asm/arch-sunxi/rsb.h b/arch/arm/include/asm/arch-sunxi/rsb.h index 95a595ab8d..a8934667c4 100644 --- a/arch/arm/include/asm/arch-sunxi/rsb.h +++ b/arch/arm/include/asm/arch-sunxi/rsb.h @@ -37,6 +37,7 @@ struct sunxi_rsb_reg { #define RSB_STAT_TERR_INT (1 << 1) #define RSB_STAT_LBSY_INT (1 << 2) +#define RSB_DMCR_DEVICE_MODE_DATA 0x7c3e00 #define RSB_DMCR_DEVICE_MODE_START (1 << 31) #define RSB_CMD_BYTE_WRITE 0x4e @@ -46,8 +47,7 @@ struct sunxi_rsb_reg { #define RSB_DEVADDR_RUNTIME_ADDR(x) ((x) << 16) #define RSB_DEVADDR_DEVICE_ADDR(x) ((x) << 0) -void rsb_init(void); -int rsb_set_device_mode(u32 device_mode_data); +int rsb_init(void); int rsb_set_device_address(u16 device_addr, u16 runtime_addr); int rsb_write(const u16 runtime_device_addr, const u8 reg_addr, u8 data); int rsb_read(const u16 runtime_device_addr, const u8 reg_addr, u8 *data); diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index 58bbd45a02..3e07f23c20 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -29,9 +29,7 @@ static int pmic_bus_init(void) #else int ret; - rsb_init(); - - ret = rsb_set_device_mode(AXP223_DEVICE_MODE_DATA); + ret = rsb_init(); if (ret) return ret; diff --git a/include/axp221.h b/include/axp221.h index 6f24a617b6..a20e25c2f8 100644 --- a/include/axp221.h +++ b/include/axp221.h @@ -12,7 +12,6 @@ #define AXP223_DEVICE_ADDR 0x3a3 #define AXP223_RUNTIME_ADDR 0x2d -#define AXP223_DEVICE_MODE_DATA 0x7c3e00 /* Page 0 addresses */ #define AXP221_CHIP_ID 0x03 -- cgit From 11dfef07d99b7148e8e2a9e742254b00846efe7b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 28 Jan 2015 09:31:52 +0100 Subject: sunxi: MAINTAINERS: sort entries alphabetically Keep all entries except for the monster entry at the top alphabetically sorted. Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 743e7f5351..9050059e74 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -34,16 +34,6 @@ F: configs/qt840a_defconfig F: include/configs/sun8i.h F: configs/Ippo_q8h_v1_2_defconfig -CUBIEBOARD2 BOARD -M: Ian Campbell -M: Hans de Goede -S: Maintained -F: include/configs/sun7i.h -F: configs/Cubieboard2_defconfig -F: configs/Cubieboard2_FEL_defconfig -F: configs/Cubietruck_defconfig -F: configs/Cubietruck_FEL_defconfig - A20-OLINUXINO-LIME BOARD M: FUKAUMI Naoki S: Maintained @@ -61,12 +51,22 @@ M: Maxime Ripard S: Maintained F: configs/Colombus_defconfig +CUBIEBOARD2 BOARD +M: Ian Campbell +M: Hans de Goede +S: Maintained +F: include/configs/sun7i.h +F: configs/Cubieboard2_defconfig +F: configs/Cubieboard2_FEL_defconfig +F: configs/Cubietruck_defconfig +F: configs/Cubietruck_FEL_defconfig + GEMEI-G9 TABLET -M: Priit Laes -S: Maintained -F: configs/sunxi_Gemei_G9_defconfig +M: Priit Laes +S: Maintained +F: configs/sunxi_Gemei_G9_defconfig -HUMMINIGBIRD-A31 BOARD +HUMMINGBIRD-A31 BOARD M: Chen-Yu Tsai S: Maintained F: configs/Hummingbird_A31_defconfig @@ -76,16 +76,6 @@ M: Chen-Yu Tsai S: Maintained F: configs/Ippo_q8h_v5_defconfig -MSI-PRIMO73 BOARD -M: Siarhei Siamashka -S: Maintained -F: configs/MSI_Primo73_defconfig - -MSI-PRIMO81 BOARD -M: Siarhei Siamashka -S: Maintained -F: configs/MSI_Primo81_defconfig - LINKSPRITE-PCDUINO BOARD M: Zoltan Herpai S: Maintained @@ -100,3 +90,13 @@ MELE M5 BOARD M: Ian Campbell S: Maintained F: configs/Mele_M5_defconfig + +MSI-PRIMO73 BOARD +M: Siarhei Siamashka +S: Maintained +F: configs/MSI_Primo73_defconfig + +MSI-PRIMO81 BOARD +M: Siarhei Siamashka +S: Maintained +F: configs/MSI_Primo81_defconfig -- cgit From 00f120bd6154095eaddafe75297786874372e075 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Sun, 1 Feb 2015 12:58:58 +0000 Subject: sunxi: Add Linksprite_pcDuino3_Nano board / defconfig This is a low-cost Allwinner A20 board with Arduino-style GPIO headers; it features 1G RAM, 4G NAND flash, 1 micro-SD, 2 USB sockets, 1 micro USB socket for OTG and another for power in, HDMI, SATA, 5V power for SATA devices, gigabit Ethernet, an IR receiver, 3.5mm audio out and a MIPI camera connector. Like the BananaPi, this board needs GMAC_TX_DELAY set to 3 in order for GMAC to work reliably at gigabit speeds. For more details, see: http://linux-sunxi.org/LinkSprite_pcDuino3_Nano Signed-off-by: Adam Sampson Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 5 +++++ configs/Linksprite_pcDuino3_Nano_defconfig | 11 +++++++++++ 2 files changed, 16 insertions(+) create mode 100644 configs/Linksprite_pcDuino3_Nano_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 9050059e74..44f57ad5cc 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -81,6 +81,11 @@ M: Zoltan Herpai S: Maintained F: configs/Linksprite_pcDuino_defconfig +LINKSPRITE-PCDUINO3-NANO BOARD +M: Adam Sampson +S: Maintained +F: configs/Linksprite_pcDuino3_Nano_defconfig + MARSBOARD-A10 BOARD M: Aleksei Mamlin S: Maintained diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig new file mode 100644 index 0000000000..4baba14bf0 --- /dev/null +++ b/configs/Linksprite_pcDuino3_Nano_defconfig @@ -0,0 +1,11 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI" +CONFIG_FDTFILE="sun7i-a20-pcduino3-nano.dtb" +CONFIG_GMAC_TX_DELAY=3 +CONFIG_USB1_VBUS_PIN="PH11" ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN7I=y ++S:CONFIG_DRAM_CLK=408 ++S:CONFIG_DRAM_ZQ=122 ++S:CONFIG_DRAM_EMR1=4 -- cgit From 29dd7d8c20e43af59a8108ca2c77f09d39e48cc3 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Tue, 27 Jan 2015 19:58:46 +0100 Subject: sunxi: TZX-Q8-713B7 support Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 5 +++++ configs/TZX-Q8-713B7_defconfig | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 configs/TZX-Q8-713B7_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 44f57ad5cc..47e2355d40 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -105,3 +105,8 @@ MSI-PRIMO81 BOARD M: Siarhei Siamashka S: Maintained F: configs/MSI_Primo81_defconfig + +TZX-Q8-713B7 BOARD +M: Paul Kocialkowski +S: Maintained +F: configs/TZX-Q8-713B7_defconfig diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig new file mode 100644 index 0000000000..7b7b9ddf8e --- /dev/null +++ b/configs/TZX-Q8-713B7_defconfig @@ -0,0 +1,15 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" +CONFIG_FDTFILE="sun5i-a13-tzx-q8-713b7.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="AXP0-0" +CONFIG_VIDEO_LCD_BL_EN="AXP0-1" +CONFIG_VIDEO_LCD_BL_PWM="PB2" ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN5I=y ++S:CONFIG_DRAM_CLK=408 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 -- cgit From 8d0df9be927eff1be9aef29aa995f6b54900962e Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sun, 4 Jan 2015 21:06:21 +0100 Subject: sunxi: Add Inet 86VS support Signed-off-by: Michal Suchanek Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 6 ++++++ configs/Inet_86VS_defconfig | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 configs/Inet_86VS_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 47e2355d40..faa413cb06 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -71,6 +71,12 @@ M: Chen-Yu Tsai S: Maintained F: configs/Hummingbird_A31_defconfig +INET-86VS BOARD +M: Michal Suchanek +S: Maintained +F: board/sunxi/dram_inet_86vs.c +F: configs/Inet_86VS_defconfig + IPPO-Q8H-V5 BOARD M: Chen-Yu Tsai S: Maintained diff --git a/configs/Inet_86VS_defconfig b/configs/Inet_86VS_defconfig new file mode 100644 index 0000000000..ce9985affe --- /dev/null +++ b/configs/Inet_86VS_defconfig @@ -0,0 +1,15 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun5i-a13-inet-86vs.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="AXP0-0" +CONFIG_VIDEO_LCD_BL_EN="AXP0-1" +CONFIG_VIDEO_LCD_BL_PWM="PB2" ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN5I=y ++S:CONFIG_DRAM_CLK=408 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 -- cgit From fb75d972eaf5c887ada28e73d3e84d52931d4cb0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 25 Jan 2015 15:33:07 +0100 Subject: sunxi: video: Force h/vsync active high when using ext. vga dac on some boards On both my A13-OLinuxIno and my A13-OLinuxIno-Micro, the vga output gives an unstable image when active low v or hsync is used. The problem seems to be specific to the OLinuxIno A13 (normal & micro) boards. I've just looked up the schematics and they use an opendrain driver for the vga sync lines, and with sync pulses it is the logical high->low edge of the pulse which counts for the timing, which with an active low sync is being driven by the pull-up, and that simply seems to not drive it hard enough to get a stable image. So force v and hsync active high on these boards. independent of what the modeline says. This fixes the unstable image. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 10 ++++++++++ configs/A13-OLinuXinoM_defconfig | 1 + configs/A13-OLinuXino_defconfig | 1 + drivers/video/sunxi_display.c | 12 +++++++++--- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4b31dcca20..adbd2b5716 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -185,6 +185,16 @@ config VIDEO_VGA_VIA_LCD LCD interface driving a VGA connector, such as found on the Olimex A13 boards. +config VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH + boolean "Force sync active high for VGA via LCD controller support" + depends on VIDEO_VGA_VIA_LCD + default n + ---help--- + Say Y here if you've a board which uses opendrain drivers for the vga + hsync and vsync signals. Opendrain drivers cannot generate steep enough + positive edges for a stable video output, so on boards with opendrain + drivers the sync signals must always be active high. + config VIDEO_VGA_EXTERNAL_DAC_EN string "LCD panel power enable pin" depends on VIDEO_VGA_VIA_LCD diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index 1c3fc3a3e9..a04f2b3362 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino-micro.dtb" CONFIG_USB1_VBUS_PIN="PG11" CONFIG_VIDEO_HDMI=n CONFIG_VIDEO_VGA_VIA_LCD=y +CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y # For use with the Olimex 7" LCD module, adjust timings for other displays # Set video-mode=sunxi:800x600-24@60,monitor=lcd in the env. to enable CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0" diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 0daaaae5b4..806d5b7bd5 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb" CONFIG_USB1_VBUS_PIN="PG11" CONFIG_VIDEO_HDMI=n CONFIG_VIDEO_VGA_VIA_LCD=y +CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y # For use with the Olimex 7" LCD module, adjust timings for other displays # Set video-mode=sunxi:800x600-24@60,monitor=lcd in the env. to enable CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0" diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index af728b51c7..f5f24fc020 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -645,7 +645,8 @@ static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode) return (delay > 30) ? 30 : delay; } -static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode) +static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, + bool for_ext_vga_dac) { struct sunxi_lcdc_reg * const lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; @@ -719,6 +720,11 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode) val |= SUNXI_LCDC_TCON_HSYNC_MASK; if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) val |= SUNXI_LCDC_TCON_VSYNC_MASK; + +#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH + if (for_ext_vga_dac) + val = 0; +#endif writel(val, &lcdc->tcon0_io_polarity); writel(0, &lcdc->tcon0_io_tristate); @@ -1015,7 +1021,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, hitachi_tx18d42vm_init(); } sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon0_mode_set(mode); + sunxi_lcdc_tcon0_mode_set(mode, false); sunxi_composer_enable(); sunxi_lcdc_enable(); #ifdef CONFIG_VIDEO_LCD_SSD2828 @@ -1033,7 +1039,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, sunxi_vga_enable(); #elif defined CONFIG_VIDEO_VGA_VIA_LCD sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon0_mode_set(mode); + sunxi_lcdc_tcon0_mode_set(mode, true); sunxi_composer_enable(); sunxi_lcdc_enable(); sunxi_vga_external_dac_enable(); -- cgit From d133647af4d4fdaaf2dfb6a9e757c7aebd00a29e Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 1 Feb 2015 00:27:05 +0200 Subject: sunxi: dram: Optionally use standard JEDEC timings for sun[457]i In addition to the current Android magic settings, allow to optionally use DDR3 timing parameters, which are tailored for different clock frequencies and JEDEC speed bins. This should improve reliability and performance. Adding '+S:CONFIG_DRAM_TIMINGS_DDR3_1066F_1333H=y' to the board defconfig allows to use timings, which are calculated for the DDR3-1066F speed bin. A lot of DDR3 chips, which are used in real Allwinner based devices, support DDR3-1066F speed bin timings. And adding '+S:CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y' should work with any DDR3 chips, because this targets the slowest JEDEC speed bins. The vendor magic values are still used by default for DRAM, but board maintainers now have more flexibility in DRAM timings selection. Signed-off-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/Kconfig | 32 ++++++ board/sunxi/dram_sun4i_auto.c | 8 +- board/sunxi/dram_sun5i_auto.c | 8 +- board/sunxi/dram_timings_sun4i.h | 205 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 4 deletions(-) create mode 100644 board/sunxi/dram_timings_sun4i.h diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index adbd2b5716..da4e8ba518 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -55,6 +55,38 @@ config DRAM_EMR1 default 4 if MACH_SUN5I || MACH_SUN7I ---help--- Set the dram controller emr1 value. + +choice + prompt "sunxi dram timings" + default DRAM_TIMINGS_VENDOR_MAGIC + ---help--- + Select the timings of the DDR3 chips. + +config DRAM_TIMINGS_VENDOR_MAGIC + bool "Magic vendor timings from Android" + ---help--- + The same DRAM timings as in the Allwinner boot0 bootloader. + +config DRAM_TIMINGS_DDR3_1066F_1333H + bool "JEDEC DDR3-1333H with down binning to DDR3-1066F" + ---help--- + Use the timings of the standard JEDEC DDR3-1066F speed bin for + DRAM_CLK <= 533MHz and the timings of the DDR3-1333H speed bin + for DRAM_CLK > 533MHz. This covers the majority of DDR3 chips + used in Allwinner A10/A13/A20 devices. In the case of DDR3-1333 + or DDR3-1600 chips, be sure to check the DRAM datasheet to confirm + that down binning to DDR3-1066F is supported (because DDR3-1066F + uses a bit faster timings than DDR3-1333H). + +config DRAM_TIMINGS_DDR3_800E_1066G_1333J + bool "JEDEC DDR3-800E / DDR3-1066G / DDR3-1333J" + ---help--- + Use the timings of the slowest possible JEDEC speed bin for the + selected DRAM_CLK. Depending on the DRAM_CLK value, it may be + DDR3-800E, DDR3-1066G or DDR3-1333J. + +endchoice + endif config SYS_CONFIG_NAME diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index 826bacf94a..ed54150ff4 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -8,18 +8,22 @@ static struct dram_para dram_para = { .density = 0, .io_width = 0, .bus_width = 0, - .cas = 6, .zq = CONFIG_DRAM_ZQ, .odt_en = 0, .size = 0, +#ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC + .cas = 6, .tpr0 = 0x30926692, .tpr1 = 0x1090, .tpr2 = 0x1a0c8, + .emr2 = 0, +#else +# include "dram_timings_sun4i.h" +#endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, - .emr2 = 0, .emr3 = 0, }; diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index e86b08e67b..bd9fd4bd27 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -10,18 +10,22 @@ static struct dram_para dram_para = { .density = 0, .io_width = 0, .bus_width = 0, - .cas = 9, .zq = CONFIG_DRAM_ZQ, .odt_en = 0, .size = 0, +#ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC + .cas = 9, .tpr0 = 0x42d899b7, .tpr1 = 0xa090, .tpr2 = 0x22a00, + .emr2 = 0x10, +#else +# include "dram_timings_sun4i.h" +#endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, - .emr2 = 0x10, .emr3 = 0, }; diff --git a/board/sunxi/dram_timings_sun4i.h b/board/sunxi/dram_timings_sun4i.h new file mode 100644 index 0000000000..29b934da63 --- /dev/null +++ b/board/sunxi/dram_timings_sun4i.h @@ -0,0 +1,205 @@ +/* This file is automatically generated, do not edit */ + +#if defined(CONFIG_DRAM_TIMINGS_DDR3_1066F_1333H) +# if CONFIG_DRAM_CLK <= 360 /* DDR3-1066F @360MHz, timings: 6-5-5-14 */ + .cas = 6, + .tpr0 = 0x268e5590, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 384 /* DDR3-1066F @384MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x288f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 396 /* DDR3-1066F @396MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 408 /* DDR3-1066F @408MHz, timings: 7-6-6-16 */ + .cas = 7, + .tpr0 = 0x2ab06690, + .tpr1 = 0xa0a8, + .tpr2 = 0x22a00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 432 /* DDR3-1066F @432MHz, timings: 7-6-6-17 */ + .cas = 7, + .tpr0 = 0x2cb16690, + .tpr1 = 0xa0b0, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 456 /* DDR3-1066F @456MHz, timings: 7-6-6-18 */ + .cas = 7, + .tpr0 = 0x30b26690, + .tpr1 = 0xa0b8, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 468 /* DDR3-1066F @468MHz, timings: 7-7-7-18 */ + .cas = 7, + .tpr0 = 0x30b27790, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 480 /* DDR3-1066F @480MHz, timings: 7-7-7-18 */ + .cas = 7, + .tpr0 = 0x32b27790, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 504 /* DDR3-1066F @504MHz, timings: 7-7-7-19 */ + .cas = 7, + .tpr0 = 0x34d37790, + .tpr1 = 0xa0d0, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 528 /* DDR3-1066F @528MHz, timings: 7-7-7-20 */ + .cas = 7, + .tpr0 = 0x36d47790, + .tpr1 = 0xa0d8, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 540 /* DDR3-1333H @540MHz, timings: 9-8-8-20 */ + .cas = 9, + .tpr0 = 0x36b488b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2b600, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 552 /* DDR3-1333H @552MHz, timings: 9-8-8-20 */ + .cas = 9, + .tpr0 = 0x38b488b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 576 /* DDR3-1333H @576MHz, timings: 9-8-8-21 */ + .cas = 9, + .tpr0 = 0x3ab588b4, + .tpr1 = 0xa0d0, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 600 /* DDR3-1333H @600MHz, timings: 9-9-9-22 */ + .cas = 9, + .tpr0 = 0x3cb699b4, + .tpr1 = 0xa0d8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 624 /* DDR3-1333H @624MHz, timings: 9-9-9-23 */ + .cas = 9, + .tpr0 = 0x3eb799b4, + .tpr1 = 0xa0e8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 648 /* DDR3-1333H @648MHz, timings: 9-9-9-24 */ + .cas = 9, + .tpr0 = 0x42b899b4, + .tpr1 = 0xa0f0, + .tpr2 = 0x2c200, + .emr2 = 0x10, +# else +# error CONFIG_DRAM_CLK is set too high +# endif +#elif defined(CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J) +# if CONFIG_DRAM_CLK <= 360 /* DDR3-800E @360MHz, timings: 6-6-6-14 */ + .cas = 6, + .tpr0 = 0x268e6690, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 384 /* DDR3-800E @384MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 396 /* DDR3-800E @396MHz, timings: 6-6-6-15 */ + .cas = 6, + .tpr0 = 0x2a8f6690, + .tpr1 = 0xa0a0, + .tpr2 = 0x22a00, + .emr2 = 0x0, +# elif CONFIG_DRAM_CLK <= 408 /* DDR3-1066G @408MHz, timings: 8-7-7-16 */ + .cas = 8, + .tpr0 = 0x2cb07790, + .tpr1 = 0xa0a8, + .tpr2 = 0x22a00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 432 /* DDR3-1066G @432MHz, timings: 8-7-7-17 */ + .cas = 8, + .tpr0 = 0x2eb17790, + .tpr1 = 0xa0b0, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 456 /* DDR3-1066G @456MHz, timings: 8-7-7-18 */ + .cas = 8, + .tpr0 = 0x30b27790, + .tpr1 = 0xa0b8, + .tpr2 = 0x22e00, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 468 /* DDR3-1066G @468MHz, timings: 8-8-8-18 */ + .cas = 8, + .tpr0 = 0x32b28890, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 480 /* DDR3-1066G @480MHz, timings: 8-8-8-18 */ + .cas = 8, + .tpr0 = 0x34b28890, + .tpr1 = 0xa0c0, + .tpr2 = 0x23200, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 504 /* DDR3-1066G @504MHz, timings: 8-8-8-19 */ + .cas = 8, + .tpr0 = 0x36d38890, + .tpr1 = 0xa0d0, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 528 /* DDR3-1066G @528MHz, timings: 8-8-8-20 */ + .cas = 8, + .tpr0 = 0x38d48890, + .tpr1 = 0xa0d8, + .tpr2 = 0x23600, + .emr2 = 0x8, +# elif CONFIG_DRAM_CLK <= 540 /* DDR3-1333J @540MHz, timings: 10-9-9-20 */ + .cas = 10, + .tpr0 = 0x38b499b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2b600, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 552 /* DDR3-1333J @552MHz, timings: 10-9-9-20 */ + .cas = 10, + .tpr0 = 0x3ab499b4, + .tpr1 = 0xa0c8, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 576 /* DDR3-1333J @576MHz, timings: 10-9-9-21 */ + .cas = 10, + .tpr0 = 0x3cb599b4, + .tpr1 = 0xa0d0, + .tpr2 = 0x2ba00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 600 /* DDR3-1333J @600MHz, timings: 10-9-9-22 */ + .cas = 10, + .tpr0 = 0x3eb699b4, + .tpr1 = 0xa0d8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 624 /* DDR3-1333J @624MHz, timings: 10-10-10-23 */ + .cas = 10, + .tpr0 = 0x40b7aab4, + .tpr1 = 0xa0e8, + .tpr2 = 0x2be00, + .emr2 = 0x10, +# elif CONFIG_DRAM_CLK <= 648 /* DDR3-1333J @648MHz, timings: 10-10-10-24 */ + .cas = 10, + .tpr0 = 0x44b8aab4, + .tpr1 = 0xa0f0, + .tpr2 = 0x2c200, + .emr2 = 0x10, +# else +# error CONFIG_DRAM_CLK is set too high +# endif +#else +# error CONFIG_DRAM_TIMINGS_* is not defined +#endif -- cgit From 47e3501a76894f4ba08bc61f33774bd5d39ff464 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 1 Feb 2015 00:27:06 +0200 Subject: sunxi: dram: Support more sun[457]i dram parameters in Kconfig This patch allows to configure all the important DRAM parameters in Kconfig. Signed-off-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/Kconfig | 43 +++++++++++++++++++++++++++++++++++++++++++ board/sunxi/dram_sun4i_auto.c | 6 ++++-- board/sunxi/dram_sun5i_auto.c | 5 ++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index da4e8ba518..4a2158988f 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -41,6 +41,15 @@ config DRAM_CLK Set the dram clock speed, valid range 240 - 480, must be a multiple of 24. +if MACH_SUN5I || MACH_SUN7I +config DRAM_MBUS_CLK + int "sunxi mbus clock speed" + default 300 + ---help--- + Set the mbus clock speed. The maximum on sun5i hardware is 300MHz. + +endif + config DRAM_ZQ int "sunxi dram zq value" default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I @@ -56,6 +65,40 @@ config DRAM_EMR1 ---help--- Set the dram controller emr1 value. +config DRAM_ODT_EN + int "sunxi dram odt_en value" + default 0 + ---help--- + Set the dram controller odt_en parameter. This can be used to + enable/disable the ODT feature. + +config DRAM_TPR3 + hex "sunxi dram tpr3 value" + default 0 + ---help--- + Set the dram controller tpr3 parameter. This parameter configures + the delay on the command lane and also phase shifts, which are + applied for sampling incoming read data. The default value 0 + means that no phase/delay adjustments are necessary. Properly + configuring this parameter increases reliability at high DRAM + clock speeds. + +config DRAM_DQS_GATING_DELAY + hex "sunxi dram dqs_gating_delay value" + default 0 + ---help--- + Set the dram controller dqs_gating_delay parmeter. Each byte + encodes the DQS gating delay for each byte lane. The delay + granularity is 1/4 cycle. For example, the value 0x05060606 + means that the delay is 5 quarter-cycles for one lane (1.25 + cycles) and 6 quarter-cycles (1.5 cycles) for 3 other lanes. + The default value 0 means autodetection. The results of hardware + autodetection are not very reliable and depend on the chip + temperature (sometimes producing different results on cold start + and warm reboot). But the accuracy of hardware autodetection + is usually good enough, unless running at really high DRAM + clocks speeds (up to 600MHz). If unsure, keep as 0. + choice prompt "sunxi dram timings" default DRAM_TIMINGS_VENDOR_MAGIC diff --git a/board/sunxi/dram_sun4i_auto.c b/board/sunxi/dram_sun4i_auto.c index ed54150ff4..09e0c9ae2e 100644 --- a/board/sunxi/dram_sun4i_auto.c +++ b/board/sunxi/dram_sun4i_auto.c @@ -9,7 +9,7 @@ static struct dram_para dram_para = { .io_width = 0, .bus_width = 0, .zq = CONFIG_DRAM_ZQ, - .odt_en = 0, + .odt_en = CONFIG_DRAM_ODT_EN, .size = 0, #ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC .cas = 6, @@ -19,12 +19,14 @@ static struct dram_para dram_para = { .emr2 = 0, #else # include "dram_timings_sun4i.h" + .active_windowing = 1, #endif - .tpr3 = 0, + .tpr3 = CONFIG_DRAM_TPR3, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, + .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, }; unsigned long sunxi_dram_init(void) diff --git a/board/sunxi/dram_sun5i_auto.c b/board/sunxi/dram_sun5i_auto.c index bd9fd4bd27..e52d54c32e 100644 --- a/board/sunxi/dram_sun5i_auto.c +++ b/board/sunxi/dram_sun5i_auto.c @@ -5,13 +5,14 @@ static struct dram_para dram_para = { .clock = CONFIG_DRAM_CLK, + .mbus_clock = CONFIG_DRAM_MBUS_CLK, .type = 3, .rank_num = 1, .density = 0, .io_width = 0, .bus_width = 0, .zq = CONFIG_DRAM_ZQ, - .odt_en = 0, + .odt_en = CONFIG_DRAM_ODT_EN, .size = 0, #ifdef CONFIG_DRAM_TIMINGS_VENDOR_MAGIC .cas = 9, @@ -21,12 +22,14 @@ static struct dram_para dram_para = { .emr2 = 0x10, #else # include "dram_timings_sun4i.h" + .active_windowing = 1, #endif .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = CONFIG_DRAM_EMR1, .emr3 = 0, + .dqs_gating_delay = CONFIG_DRAM_DQS_GATING_DELAY, }; unsigned long sunxi_dram_init(void) -- cgit From 5abdb156bb5c2685744be3620c4bdb1875bd81ce Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 1 Feb 2015 00:42:14 +0200 Subject: sunxi: mmc: Add 'sunxi_' prefix to the static functions This results in a much more readable callgraph, because now they can't be confused with the function having exactly the same name in the generic mmc code. Signed-off-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/mmc/sunxi_mmc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 510479516b..ebfec7cf07 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -215,7 +215,7 @@ static int mmc_config_clock(struct mmc *mmc) return 0; } -static void mmc_set_ios(struct mmc *mmc) +static void sunxi_mmc_set_ios(struct mmc *mmc) { struct sunxi_mmc_host *mmchost = mmc->priv; @@ -237,7 +237,7 @@ static void mmc_set_ios(struct mmc *mmc) writel(0x0, &mmchost->reg->width); } -static int mmc_core_init(struct mmc *mmc) +static int sunxi_mmc_core_init(struct mmc *mmc) { struct sunxi_mmc_host *mmchost = mmc->priv; @@ -298,8 +298,8 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, return 0; } -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) { struct sunxi_mmc_host *mmchost = mmc->priv; unsigned int cmdval = SUNXI_MMC_CMD_START; @@ -432,9 +432,9 @@ static int sunxi_mmc_getcd(struct mmc *mmc) } static const struct mmc_ops sunxi_mmc_ops = { - .send_cmd = mmc_send_cmd, - .set_ios = mmc_set_ios, - .init = mmc_core_init, + .send_cmd = sunxi_mmc_send_cmd, + .set_ios = sunxi_mmc_set_ios, + .init = sunxi_mmc_core_init, .getcd = sunxi_mmc_getcd, }; -- cgit From 112db9407dd338f71200beb0fc99dffa8dcb57a8 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 2 Feb 2015 12:39:29 -0500 Subject: Prepare v2015.04-rc1 Signed-off-by: Tom Rini --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9b406c8447..92faed63fd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2015 -PATCHLEVEL = 01 +PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = # *DOCUMENTATION* -- cgit From cfcf8ea2d7d35c25ef9c7d2a6b8063e7123818b7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:26 -0700 Subject: x86: Enhance the microcode tool to support header files as input Sometimes microcode is delivered as a header file. Allow the tool to support this as well as collecting multiple microcode blocks into a single update. Signed-off-by: Simon Glass Tested-by: Bin Meng --- tools/microcode-tool.py | 90 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 20 deletions(-) diff --git a/tools/microcode-tool.py b/tools/microcode-tool.py index 003716d573..71c2e91566 100755 --- a/tools/microcode-tool.py +++ b/tools/microcode-tool.py @@ -76,6 +76,35 @@ def ParseFile(fname): microcodes[name] = Microcode(name, data) return date, license_text, microcodes +def ParseHeaderFiles(fname_list): + """Parse a list of header files and return the component parts + + Args: + fname_list: List of files to parse + Returns: + date: String containing date from the file's header + license_text: List of text lines for the license file + microcodes: List of Microcode objects from the file + """ + microcodes = {} + license_text = [] + date = '' + name = None + for fname in fname_list: + name = os.path.basename(fname).lower() + name = os.path.splitext(name)[0] + data = [] + with open(fname) as fd: + for line in fd: + line = line.rstrip() + + # Omit anything after the last comma + words = line.split(',')[:-1] + data += [word + ',' for word in words] + microcodes[name] = Microcode(name, data) + return date, license_text, microcodes + + def List(date, microcodes, model): """List the available microcode chunks @@ -129,13 +158,13 @@ def FindMicrocode(microcodes, model): break return found, tried -def CreateFile(date, license_text, mcode, outfile): +def CreateFile(date, license_text, mcodes, outfile): """Create a microcode file in U-Boot's .dtsi format Args: date: String containing date of original microcode file license: List of text lines for the license file - mcode: Microcode object to write + mcodes: Microcode objects to write (normally only 1) outfile: Filename to write to ('-' for stdout) """ out = '''/*%s @@ -159,15 +188,22 @@ intel,processor-flags = <%#x>; data = <%s \t>;''' words = '' - for i in range(len(mcode.words)): - if not (i & 3): - words += '\n' - val = mcode.words[i] - # Change each word so it will be little-endian in the FDT - # This data is needed before RAM is available on some platforms so we - # cannot do an endianness swap on boot. - val = struct.unpack("I", val))[0] - words += '\t%#010x' % val + add_comments = len(mcodes) > 1 + for mcode in mcodes: + if add_comments: + words += '\n/* %s */' % mcode.name + for i in range(len(mcode.words)): + if not (i & 3): + words += '\n' + val = mcode.words[i] + # Change each word so it will be little-endian in the FDT + # This data is needed before RAM is available on some platforms so + # we cannot do an endianness swap on boot. + val = struct.unpack("I", val))[0] + words += '\t%#010x' % val + + # Use the first microcode for the headers + mcode = mcodes[0] # Take care to avoid adding a space before a tab text = '' @@ -187,8 +223,8 @@ data = <%s print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR os.makedirs(MICROCODE_DIR) outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi') - print >> sys.stderr, "Writing microcode for '%s' to '%s'" % ( - mcode.name, outfile) + print >> sys.stderr, "Writing microcode for '%s' to '%s'" % ( + ', '.join([mcode.name for mcode in mcodes]), outfile) with open(outfile, 'w') as fd: print >> fd, out % tuple(args) @@ -198,8 +234,12 @@ def MicrocodeTool(): parser = OptionParser() parser.add_option('-d', '--mcfile', type='string', action='store', help='Name of microcode.dat file') + parser.add_option('-H', '--headerfile', type='string', action='append', + help='Name of .h file containing microcode') parser.add_option('-m', '--model', type='string', action='store', - help='Model name to extract') + help="Model name to extract ('all' for all)") + parser.add_option('-M', '--multiple', type='string', action='store', + help="Allow output of multiple models") parser.add_option('-o', '--outfile', type='string', action='store', help='Filename to use for output (- for stdout), default is' ' %s/.dtsi' % MICROCODE_DIR) @@ -224,9 +264,14 @@ def MicrocodeTool(): if cmd not in commands: parser.error("Unknown command '%s'" % cmd) - if not options.mcfile: - parser.error('You must specify a microcode file') - date, license_text, microcodes = ParseFile(options.mcfile) + if (not not options.mcfile) != (not not options.mcfile): + parser.error("You must specify either header files or a microcode file, not both") + if options.headerfile: + date, license_text, microcodes = ParseHeaderFiles(options.headerfile) + elif options.mcfile: + date, license_text, microcodes = ParseFile(options.mcfile) + else: + parser.error('You must specify a microcode file (or header files)') if cmd == 'list': List(date, microcodes, options.model) @@ -236,16 +281,21 @@ def MicrocodeTool(): if not options.model: parser.error('You must specify a model to create') model = options.model.lower() - mcode_list, tried = FindMicrocode(microcodes, model) + if options.model == 'all': + options.multiple = True + mcode_list = microcodes.values() + tried = [] + else: + mcode_list, tried = FindMicrocode(microcodes, model) if not mcode_list: parser.error("Unknown model '%s' (%s) - try 'list' to list" % (model, ', '.join(tried))) - if len(mcode_list) > 1: + if not options.multiple and len(mcode_list) > 1: parser.error("Ambiguous model '%s' (%s) matched %s - try 'list' " "to list or specify a particular file" % (model, ', '.join(tried), ', '.join([m.name for m in mcode_list]))) - CreateFile(date, license_text, mcode_list[0], options.outfile) + CreateFile(date, license_text, mcode_list, options.outfile) else: parser.error("Unknown command '%s'" % cmd) -- cgit From 250e039da8c7e485dabdc84f0457b2a901757e28 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:27 -0700 Subject: pci: Add a function to find a device by class There is an existing function prototype in the header file but it is not implemented. Implement something similar. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 3 +-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 950a2475c5..e1296cab9e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -236,6 +237,48 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) return -1; } +pci_dev_t pci_find_class(uint find_class, int index) +{ + int bus; + int devnum; + pci_dev_t bdf; + uint32_t class; + + for (bus = 0; bus <= pci_last_busno(); bus++) { + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { + pci_read_config_dword(PCI_BDF(bus, devnum, 0), + PCI_CLASS_REVISION, &class); + if (class >> 16 == 0xffff) + continue; + + for (bdf = PCI_BDF(bus, devnum, 0); + bdf <= PCI_BDF(bus, devnum, + PCI_MAX_PCI_FUNCTIONS - 1); + bdf += PCI_BDF(0, 0, 1)) { + pci_read_config_dword(bdf, PCI_CLASS_REVISION, + &class); + class >>= 8; + + if (class != find_class) + continue; + /* + * Decrement the index. We want to return the + * correct device, so index is 0 for the first + * matching device, 1 for the second, etc. + */ + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; + } + } + } + + return -ENODEV; +} + pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) { struct pci_device_id ids[2] = { {}, {0, 0} }; diff --git a/include/pci.h b/include/pci.h index 4fbb8f6729..004a048d2f 100644 --- a/include/pci.h +++ b/include/pci.h @@ -644,8 +644,7 @@ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index); extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index); -extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code, - int wanted_prog_if, int index); +pci_dev_t pci_find_class(unsigned int find_class, int index); extern int pci_hose_config_device(struct pci_controller *hose, pci_dev_t dev, -- cgit From 34236238359253ef5342843a3cca09dcca939262 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:28 -0700 Subject: x86: pci: Add PCI IDs for Minnowboard Max This board includes a few IDs we have not seen before. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/pci_ids.h b/include/pci_ids.h index 26f4748685..1012abecef 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -1346,6 +1346,7 @@ #define PCI_VENDOR_ID_REALTEK 0x10ec #define PCI_DEVICE_ID_REALTEK_8139 0x8139 +#define PCI_DEVICE_ID_REALTEK_8168 0x8168 #define PCI_VENDOR_ID_XILINX 0x10ee #define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 @@ -2594,6 +2595,10 @@ #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 #define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO 0x0f15 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD 0x0f16 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC 0x0f1c +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA 0x0f23 #define PCI_DEVICE_ID_INTEL_82541ER 0x1078 #define PCI_DEVICE_ID_INTEL_82541GI_LF 0x107c #define PCI_DEVICE_ID_INTEL_82542 0x1000 -- cgit From 82c2566bd3db81f77945f26a9b7546da3567e3b4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:29 -0700 Subject: x86: video: Enable video for Minnowboard Max This board uses a new PCI ID. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/video/vesa_fb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index 3dacafd6bf..3a0fea2584 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -23,6 +23,7 @@ struct pci_device_id vesa_video_ids[] = { { .vendor = 0x1002, .device = 0x5159 }, { .vendor = 0x1002, .device = 0x4752 }, { .vendor = 0x1002, .device = 0x5452 }, + { .vendor = 0x8086, .device = 0x0f31 }, {}, }; -- cgit From 4fd46727e4e5d5cf58bceac0be5a33fa4196435e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:30 -0700 Subject: usb: pci: Use pci_find_class() to find the device Use the new utility function instead of local code. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/usb/host/ehci-pci.c | 53 +-------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 991b19998b..b9eabc5593 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -34,57 +34,6 @@ static struct pci_device_id ehci_pci_ids[] = { {0, 0} }; #else -static pci_dev_t ehci_find_class(int index) -{ - int bus; - int devnum; - pci_dev_t bdf; - uint32_t class; - - for (bus = 0; bus <= pci_last_busno(); bus++) { - for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) { - pci_read_config_dword(PCI_BDF(bus, devnum, 0), - PCI_CLASS_REVISION, &class); - if (class >> 16 == 0xffff) - continue; - - for (bdf = PCI_BDF(bus, devnum, 0); - bdf <= PCI_BDF(bus, devnum, - PCI_MAX_PCI_FUNCTIONS - 1); - bdf += PCI_BDF(0, 0, 1)) { - pci_read_config_dword(bdf, PCI_CLASS_REVISION, - &class); - class >>= 8; - /* - * Here be dragons! In case we have multiple - * PCI EHCI controllers, this function will - * be called multiple times as well. This - * function will scan the PCI busses, always - * starting from bus 0, device 0, function 0, - * until it finds an USB controller. The USB - * stack gives us an 'index' of a controller - * that is currently being registered, which - * is a number, starting from 0 and growing - * in ascending order as controllers are added. - * To avoid probing the same controller in tne - * subsequent runs of this function, we will - * skip 'index - 1' detected controllers and - * report the index'th controller. - */ - if (class != PCI_CLASS_SERIAL_USB_EHCI) - continue; - if (index) { - index--; - continue; - } - /* Return index'th controller. */ - return bdf; - } - } - } - - return -ENODEV; -} #endif /* @@ -102,7 +51,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, #ifdef CONFIG_PCI_EHCI_DEVICE pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE); #else - pdev = ehci_find_class(index); + pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index); #endif if (pdev < 0) { printf("EHCI host controller not found\n"); -- cgit From 316328f59d5bb64ed8ab70b68edb434cae70ee58 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:31 -0700 Subject: usb: pci: Add XHCI driver for PCI Add a driver which locates the available XHCI controllers on the PCI bus and makes them available. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-pci.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 drivers/usb/host/xhci-pci.c diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index c11b551620..66d6e9a6d2 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o +obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o # designware obj-$(CONFIG_USB_DWC2) += dwc2.o diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c new file mode 100644 index 0000000000..361fccebf7 --- /dev/null +++ b/drivers/usb/host/xhci-pci.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, Google, Inc + * Written by Simon Glass + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include + +#include "xhci.h" + +/* + * Create the appropriate control structures to manage a new XHCI host + * controller. + */ +int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr, + struct xhci_hcor **ret_hcor) +{ + struct xhci_hccr *hccr; + struct xhci_hcor *hcor; + pci_dev_t pdev; + uint32_t cmd; + int len; + + pdev = pci_find_class(PCI_CLASS_SERIAL_USB_XHCI, index); + if (pdev < 0) { + printf("XHCI host controller not found\n"); + return -1; + } + + hccr = (struct xhci_hccr *)pci_map_bar(pdev, + PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + len = HC_LENGTH(xhci_readl(&hccr->cr_capbase)); + hcor = (struct xhci_hcor *)((uint32_t)hccr + len); + + debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", + (uint32_t)hccr, (uint32_t)hcor, len); + + *ret_hccr = hccr; + *ret_hcor = hcor; + + /* enable busmaster */ + pci_read_config_dword(pdev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_dword(pdev, PCI_COMMAND, cmd); + + return 0; +} + +/* + * Destroy the appropriate control structures corresponding * to the XHCI host + * controller + */ +void xhci_hcd_stop(int index) +{ +} -- cgit From eea0f11278d9104960dfb1fbfcddfb796a3e0bb5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:32 -0700 Subject: x86: Add an option to enabling building a ROM file Rather than requiring the Makefile to be modified, provide a build option to enable the ROM to be built. We cannot do this by default since it requires binary blobs. Without these the build will fail. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- Makefile | 5 +++-- doc/README.x86 | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 92faed63fd..eea69b1664 100644 --- a/Makefile +++ b/Makefile @@ -729,8 +729,9 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%) endif ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf -# We can't do this yet due to the need for binary blobs -# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom +ifneq ($(BUILD_ROM),) +ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom +endif # enable combined SPL/u-boot/dtb rules for tegra ifneq ($(CONFIG_TEGRA),) diff --git a/doc/README.x86 b/doc/README.x86 index 7df8cc516a..ddfd75e1cd 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -51,9 +51,11 @@ Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a little bit tricky, as generally it requires several binary blobs which are not shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is not turned on by default in the U-Boot source tree. Firstly, you need turn it -on by uncommenting the following line in the main U-Boot Makefile: +on by enabling the ROM build: -# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom +$ export BUILD_ROM=y + +This tells the Makefile to build u-boot.rom as a target. Link-specific instructions: @@ -126,11 +128,11 @@ Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the symbol address of _start (in arch/x86/cpu/start.S). If you want to use ELF as the coreboot payload, change U-Boot configuration to -use CONFIG_OF_EMBED. +use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE. CPU Microcode ------------- -Modern CPU usually requires a special bit stream called microcode [5] to be +Modern CPUs usually require a special bit stream called microcode [5] to be loaded on the processor after power up in order to function properly. U-Boot has already integrated these as hex dumps in the source tree. -- cgit From 2d934e5703b712686c3ec67f6d5eeb137c68805d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:33 -0700 Subject: x86: Rename MMCONF_BASE_ADDRESS and make it common across x86 This setting will be used by more than just ivybridge so make it common. Also rename it to PCIE_ECAM_BASE which is a more descriptive name. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/Kconfig | 14 ++++++++++++++ arch/x86/cpu/ivybridge/sdram.c | 2 +- arch/x86/include/asm/arch-ivybridge/sandybridge.h | 2 +- board/google/chromebook_link/Kconfig | 3 +-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 90e828a26e..928fc60863 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -356,4 +356,18 @@ source "board/google/chromebook_link/Kconfig" source "board/intel/crownbay/Kconfig" +config PCIE_ECAM_BASE + hex + default 0xe0000000 + help + This is the memory-mapped address of PCI configuration space, which + is only available through the Enhanced Configuration Access + Mechanism (ECAM) with PCI Express. It can be set up almost + anywhere. Before it is set up, it is possible to access PCI + configuration space through I/O access, but memory access is more + convenient. Using this, PCI can be scanned and configured. This + should be set to a region that does not conflict with memory + assigned to PCI devices - i.e. the memory and prefetch regions, as + passed to pci_set_region(). + endmenu diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 49634485f3..766b385c25 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -757,7 +757,7 @@ int dram_init(void) .mchbar = DEFAULT_MCHBAR, .dmibar = DEFAULT_DMIBAR, .epbar = DEFAULT_EPBAR, - .pciexbar = CONFIG_MMCONF_BASE_ADDRESS, + .pciexbar = CONFIG_PCIE_ECAM_BASE, .smbusbar = SMBUS_IO_BASE, .wdbbar = 0x4000000, .wdbsize = 0x1000, diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h index cf7457f42d..c9605258b5 100644 --- a/arch/x86/include/asm/arch-ivybridge/sandybridge.h +++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h @@ -43,7 +43,7 @@ #define DEFAULT_EPBAR 0xfed19000 /* 4 KB */ #define DEFAULT_RCBABASE 0xfed1c000 /* 4 KB per PCIe device */ -#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS +#define DEFAULT_PCIEXBAR CONFIG_PCIE_ECAM_BASE /* Device 0:0.0 PCI configuration space (Host Bridge) */ #define EPBAR 0x40 diff --git a/board/google/chromebook_link/Kconfig b/board/google/chromebook_link/Kconfig index 33a31f311f..ea454721c5 100644 --- a/board/google/chromebook_link/Kconfig +++ b/board/google/chromebook_link/Kconfig @@ -22,8 +22,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select MARK_GRAPHICS_MEM_WRCOMB select BOARD_ROMSIZE_KB_8192 -config MMCONF_BASE_ADDRESS - hex +config PCIE_ECAM_BASE default 0xf0000000 config EARLY_POST_CROS_EC -- cgit From bc17d8f4ac41a6a4bcc4b28f1c6216a5a034fa63 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:34 -0700 Subject: x86: video: Allow video ROM execution to fall back to the other method If the BIOS emulator is not available, allow use of native execution if available, and vice versa. This can be controlled by the caller. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/ivybridge/gma.c | 3 ++- drivers/pci/pci_rom.c | 32 +++++++++++++++++++++++++------- drivers/video/vesa_fb.c | 6 +++--- include/pci_rom.h | 15 +++++++++++++-- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c index 6cf9654e02..821ea25019 100644 --- a/arch/x86/cpu/ivybridge/gma.c +++ b/arch/x86/cpu/ivybridge/gma.c @@ -758,7 +758,8 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose, #ifdef CONFIG_VIDEO start = get_timer(0); - ret = pci_run_vga_bios(dev, int15_handler, false); + ret = pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE | + PCI_ROM_ALLOW_FALLBACK); debug("BIOS ran in %lums\n", get_timer(start)); #endif /* Post VBIOS init */ diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 5729a152e5..48c0a77fdd 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -228,11 +228,12 @@ int vbe_get_video_info(struct graphic_device *gdev) #endif } -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) +int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) { struct pci_rom_header *rom, *ram; int vesa_mode = -1; uint16_t class; + bool emulate; int ret; /* Only execute VGA ROMs */ @@ -262,6 +263,29 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE; #endif debug("Selected vesa mode %#x\n", vesa_mode); + + if (exec_method & PCI_ROM_USE_NATIVE) { +#ifdef CONFIG_X86 + emulate = false; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS native execution is only available on x86\n"); + return -ENOSYS; + } + emulate = true; +#endif + } else { +#ifdef CONFIG_BIOSEMU + emulate = true; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); + return -ENOSYS; + } + emulate = false; +#endif + } + if (emulate) { #ifdef CONFIG_BIOSEMU BE_VGAInfo *info; @@ -274,9 +298,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) vesa_mode, &mode_info); if (ret) return ret; -#else - printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); - return -ENOSYS; #endif } else { #ifdef CONFIG_X86 @@ -284,9 +305,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) bios_run_on_x86(dev, (unsigned long)ram, vesa_mode, &mode_info); -#else - printf("BIOS native execution is only available on x86\n"); - return -ENOSYS; #endif } debug("Final vesa mode %#x\n", mode_info.video_mode); diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index 3a0fea2584..9164f8d166 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -42,8 +42,8 @@ void *video_hw_init(void) printf("no card detected\n"); return NULL; } - printf("bdf %x\n", dev); - ret = pci_run_vga_bios(dev, NULL, true); + ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE | + PCI_ROM_ALLOW_FALLBACK); if (ret) { printf("failed to run video BIOS: %d\n", ret); return NULL; @@ -59,7 +59,7 @@ void *video_hw_init(void) sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, bits_per_pixel); printf("%s\n", gdev->modeIdent); - debug("Framex buffer at %x\n", gdev->pciBase); + debug("Frame buffer at %x\n", gdev->pciBase); return (void *)gdev; } diff --git a/include/pci_rom.h b/include/pci_rom.h index 4ba36eb1b7..2f1665d17a 100644 --- a/include/pci_rom.h +++ b/include/pci_rom.h @@ -33,14 +33,25 @@ struct pci_rom_data { uint16_t reserved_2; }; +/* + * Determines which execution method is used and whether we allow falling back + * to the other if the requested method is not available. + */ +enum pci_rom_emul { + PCI_ROM_EMULATE = 0 << 0, + PCI_ROM_USE_NATIVE = 1 << 0, + PCI_ROM_ALLOW_FALLBACK = 1 << 1, +}; + /** * pci_run_vga_bios() - Run the VGA BIOS in an x86 PC * * @dev: Video device containing the BIOS * @int15_handler: Function to call to handle int 0x15 - * @emulate: true to use the x86 emulator, false to run native + * @exec_method: flags from enum pci_rom_emul */ -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate); +int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), + int exec_method); /** * board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects -- cgit From ef565a53ea96761ee8e705c0d56dbf160b672d51 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:35 -0700 Subject: x86: bootstage: Add time measurement for vesa start-up Since we must run a PCI BIOS ROM, and this can take a calamitous amount of time, measure it using bootstage. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/video/vesa_fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index 9164f8d166..47f824a726 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -42,8 +42,10 @@ void *video_hw_init(void) printf("no card detected\n"); return NULL; } + bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE | PCI_ROM_ALLOW_FALLBACK); + bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); if (ret) { printf("failed to run video BIOS: %d\n", ret); return NULL; -- cgit From 1021af4ded2d0961a4ba2ba89851719b098a98b6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:36 -0700 Subject: x86: Move common FSP code into a common location Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/cpu/queensbay/Makefile | 2 +- arch/x86/cpu/queensbay/fsp_configs.c | 2 +- arch/x86/cpu/queensbay/fsp_support.c | 408 --------------------- arch/x86/cpu/queensbay/tnc.c | 2 +- arch/x86/cpu/queensbay/tnc_dram.c | 2 +- arch/x86/cpu/queensbay/tnc_pci.c | 2 +- arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h | 55 --- .../include/asm/arch-queensbay/fsp/fsp_bootmode.h | 24 -- arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h | 154 -------- arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h | 137 ------- arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h | 300 --------------- .../asm/arch-queensbay/fsp/fsp_infoheader.h | 32 -- .../include/asm/arch-queensbay/fsp/fsp_platform.h | 15 - .../include/asm/arch-queensbay/fsp/fsp_support.h | 208 ----------- .../x86/include/asm/arch-queensbay/fsp/fsp_types.h | 82 ----- arch/x86/include/asm/fsp/fsp_api.h | 55 +++ arch/x86/include/asm/fsp/fsp_bootmode.h | 24 ++ arch/x86/include/asm/fsp/fsp_ffs.h | 154 ++++++++ arch/x86/include/asm/fsp/fsp_fv.h | 137 +++++++ arch/x86/include/asm/fsp/fsp_hob.h | 300 +++++++++++++++ arch/x86/include/asm/fsp/fsp_infoheader.h | 32 ++ arch/x86/include/asm/fsp/fsp_platform.h | 15 + arch/x86/include/asm/fsp/fsp_support.h | 208 +++++++++++ arch/x86/include/asm/fsp/fsp_types.h | 82 +++++ arch/x86/lib/Makefile | 1 + arch/x86/lib/cmd_hob.c | 2 +- arch/x86/lib/fsp/Makefile | 7 + arch/x86/lib/fsp/fsp_support.c | 408 +++++++++++++++++++++ 28 files changed, 1429 insertions(+), 1421 deletions(-) delete mode 100644 arch/x86/cpu/queensbay/fsp_support.c delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h delete mode 100644 arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h create mode 100644 arch/x86/include/asm/fsp/fsp_api.h create mode 100644 arch/x86/include/asm/fsp/fsp_bootmode.h create mode 100644 arch/x86/include/asm/fsp/fsp_ffs.h create mode 100644 arch/x86/include/asm/fsp/fsp_fv.h create mode 100644 arch/x86/include/asm/fsp/fsp_hob.h create mode 100644 arch/x86/include/asm/fsp/fsp_infoheader.h create mode 100644 arch/x86/include/asm/fsp/fsp_platform.h create mode 100644 arch/x86/include/asm/fsp/fsp_support.h create mode 100644 arch/x86/include/asm/fsp/fsp_types.h create mode 100644 arch/x86/lib/fsp/Makefile create mode 100644 arch/x86/lib/fsp/fsp_support.c diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile index 2c2ec01ed2..b3e7d87956 100644 --- a/arch/x86/cpu/queensbay/Makefile +++ b/arch/x86/cpu/queensbay/Makefile @@ -5,5 +5,5 @@ # obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o -obj-y += fsp_configs.o fsp_support.o +obj-y += fsp_configs.o obj-$(CONFIG_PCI) += tnc_pci.o diff --git a/arch/x86/cpu/queensbay/fsp_configs.c b/arch/x86/cpu/queensbay/fsp_configs.c index af28e457f6..78bc966bbd 100644 --- a/arch/x86/cpu/queensbay/fsp_configs.c +++ b/arch/x86/cpu/queensbay/fsp_configs.c @@ -6,7 +6,7 @@ */ #include -#include +#include void update_fsp_upd(struct upd_region *fsp_upd) { diff --git a/arch/x86/cpu/queensbay/fsp_support.c b/arch/x86/cpu/queensbay/fsp_support.c deleted file mode 100644 index aed3e2b300..0000000000 --- a/arch/x86/cpu/queensbay/fsp_support.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#include -#include -#include - -/** - * Compares two GUIDs - * - * If the GUIDs are identical then true is returned. - * If there are any bit differences in the two GUIDs, then false is returned. - * - * @guid1: A pointer to a 128 bit GUID. - * @guid2: A pointer to a 128 bit GUID. - * - * @retval true: guid1 and guid2 are identical. - * @retval false: guid1 and guid2 are not identical. - */ -static bool compare_guid(const struct efi_guid *guid1, - const struct efi_guid *guid2) -{ - if (memcmp(guid1, guid2, sizeof(struct efi_guid)) == 0) - return true; - else - return false; -} - -u32 __attribute__((optimize("O0"))) find_fsp_header(void) -{ - /* - * This function may be called before the a stack is established, - * so special care must be taken. First, it cannot declare any local - * variable using stack. Only register variable can be used here. - * Secondly, some compiler version will add prolog or epilog code - * for the C function. If so the function call may not work before - * stack is ready. - * - * GCC 4.8.1 has been verified to be working for the following codes. - */ - volatile register u8 *fsp asm("eax"); - - /* Initalize the FSP base */ - fsp = (u8 *)CONFIG_FSP_ADDR; - - /* Check the FV signature, _FVH */ - if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) { - /* Go to the end of the FV header and align the address */ - fsp += ((struct fv_header *)fsp)->ext_hdr_off; - fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size; - fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8); - } else { - fsp = 0; - } - - /* Check the FFS GUID */ - if (fsp && - ((struct ffs_file_header *)fsp)->name.data1 == FSP_GUID_DATA1 && - ((struct ffs_file_header *)fsp)->name.data2 == FSP_GUID_DATA2 && - ((struct ffs_file_header *)fsp)->name.data3 == FSP_GUID_DATA3 && - ((struct ffs_file_header *)fsp)->name.data4[0] == FSP_GUID_DATA4_0 && - ((struct ffs_file_header *)fsp)->name.data4[1] == FSP_GUID_DATA4_1 && - ((struct ffs_file_header *)fsp)->name.data4[2] == FSP_GUID_DATA4_2 && - ((struct ffs_file_header *)fsp)->name.data4[3] == FSP_GUID_DATA4_3 && - ((struct ffs_file_header *)fsp)->name.data4[4] == FSP_GUID_DATA4_4 && - ((struct ffs_file_header *)fsp)->name.data4[5] == FSP_GUID_DATA4_5 && - ((struct ffs_file_header *)fsp)->name.data4[6] == FSP_GUID_DATA4_6 && - ((struct ffs_file_header *)fsp)->name.data4[7] == FSP_GUID_DATA4_7) { - /* Add the FFS header size to find the raw section header */ - fsp += sizeof(struct ffs_file_header); - } else { - fsp = 0; - } - - if (fsp && - ((struct raw_section *)fsp)->type == EFI_SECTION_RAW) { - /* Add the raw section header size to find the FSP header */ - fsp += sizeof(struct raw_section); - } else { - fsp = 0; - } - - return (u32)fsp; -} - -void fsp_continue(struct shared_data *shared_data, u32 status, void *hob_list) -{ - u32 stack_len; - u32 stack_base; - u32 stack_top; - - post_code(POST_MRC); - - assert(status == 0); - - /* Get the migrated stack in normal memory */ - stack_base = (u32)fsp_get_bootloader_tmp_mem(hob_list, &stack_len); - assert(stack_base != 0); - stack_top = stack_base + stack_len - sizeof(u32); - - /* - * Old stack base is stored at the very end of the stack top, - * use it to calculate the migrated shared data base - */ - shared_data = (struct shared_data *)(stack_base + - ((u32)shared_data - *(u32 *)stack_top)); - - /* The boot loader main function entry */ - fsp_init_done(hob_list); -} - -void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) -{ - struct shared_data shared_data; - fsp_init_f init; - struct fsp_init_params params; - struct fspinit_rtbuf rt_buf; - struct vpd_region *fsp_vpd; - struct fsp_header *fsp_hdr; - struct fsp_init_params *params_ptr; - struct upd_region *fsp_upd; - - fsp_hdr = (struct fsp_header *)find_fsp_header(); - if (fsp_hdr == NULL) { - /* No valid FSP info header was found */ - panic("Invalid FSP header"); - } - - fsp_upd = (struct upd_region *)&shared_data.fsp_upd; - memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf)); - - /* Reserve a gap in stack top */ - rt_buf.common.stack_top = (u32 *)stack_top - 32; - rt_buf.common.boot_mode = boot_mode; - rt_buf.common.upd_data = (struct upd_region *)fsp_upd; - - /* Get VPD region start */ - fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base + - fsp_hdr->cfg_region_off); - - /* Verifify the VPD data region is valid */ - assert((fsp_vpd->img_rev == VPD_IMAGE_REV) && - (fsp_vpd->sign == VPD_IMAGE_ID)); - - /* Copy default data from Flash */ - memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), - sizeof(struct upd_region)); - - /* Verifify the UPD data region is valid */ - assert(fsp_upd->terminator == UPD_TERMINATOR); - - /* Override any UPD setting if required */ - update_fsp_upd(fsp_upd); - - memset(¶ms, 0, sizeof(struct fsp_init_params)); - params.nvs_buf = nvs_buf; - params.rt_buf = (struct fspinit_rtbuf *)&rt_buf; - params.continuation = (fsp_continuation_f)asm_continuation; - - init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init); - params_ptr = ¶ms; - - shared_data.fsp_hdr = fsp_hdr; - shared_data.stack_top = (u32 *)stack_top; - - post_code(POST_PRE_MRC); - - /* - * Use ASM code to ensure the register value in EAX & ECX - * will be passed into BlContinuationFunc - */ - asm volatile ( - "pushl %0;" - "call *%%eax;" - ".global asm_continuation;" - "asm_continuation:;" - "movl %%ebx, %%eax;" /* shared_data */ - "movl 4(%%esp), %%edx;" /* status */ - "movl 8(%%esp), %%ecx;" /* hob_list */ - "jmp fsp_continue;" - : : "m"(params_ptr), "a"(init), "b"(&shared_data) - ); - - /* - * Should never get here. - * Control will continue from fsp_continue. - * This line below is to prevent the compiler from optimizing - * structure intialization. - * - * DO NOT REMOVE! - */ - init(¶ms); -} - -u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase) -{ - fsp_notify_f notify; - struct fsp_notify_params params; - struct fsp_notify_params *params_ptr; - u32 status; - - if (!fsp_hdr) - fsp_hdr = (struct fsp_header *)find_fsp_header(); - - if (fsp_hdr == NULL) { - /* No valid FSP info header */ - panic("Invalid FSP header"); - } - - notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); - params.phase = phase; - params_ptr = ¶ms; - - /* - * Use ASM code to ensure correct parameter is on the stack for - * FspNotify as U-Boot is using different ABI from FSP - */ - asm volatile ( - "pushl %1;" /* push notify phase */ - "call *%%eax;" /* call FspNotify */ - "addl $4, %%esp;" /* clean up the stack */ - : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) - ); - - return status; -} - -u32 fsp_get_usable_lowmem_top(const void *hob_list) -{ - const struct hob_header *hdr; - struct hob_res_desc *res_desc; - phys_addr_t phys_start; - u32 top; - - /* Get the HOB list for processing */ - hdr = hob_list; - - /* * Collect memory ranges */ - top = FSP_LOWMEM_BASE; - while (!end_of_hob(hdr)) { - if (hdr->type == HOB_TYPE_RES_DESC) { - res_desc = (struct hob_res_desc *)hdr; - if (res_desc->type == RES_SYS_MEM) { - phys_start = res_desc->phys_start; - /* Need memory above 1MB to be collected here */ - if (phys_start >= FSP_LOWMEM_BASE && - phys_start < (phys_addr_t)FSP_HIGHMEM_BASE) - top += (u32)(res_desc->len); - } - } - hdr = get_next_hob(hdr); - } - - return top; -} - -u64 fsp_get_usable_highmem_top(const void *hob_list) -{ - const struct hob_header *hdr; - struct hob_res_desc *res_desc; - phys_addr_t phys_start; - u64 top; - - /* Get the HOB list for processing */ - hdr = hob_list; - - /* Collect memory ranges */ - top = FSP_HIGHMEM_BASE; - while (!end_of_hob(hdr)) { - if (hdr->type == HOB_TYPE_RES_DESC) { - res_desc = (struct hob_res_desc *)hdr; - if (res_desc->type == RES_SYS_MEM) { - phys_start = res_desc->phys_start; - /* Need memory above 1MB to be collected here */ - if (phys_start >= (phys_addr_t)FSP_HIGHMEM_BASE) - top += (u32)(res_desc->len); - } - } - hdr = get_next_hob(hdr); - } - - return top; -} - -u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len, - struct efi_guid *guid) -{ - const struct hob_header *hdr; - struct hob_res_desc *res_desc; - - /* Get the HOB list for processing */ - hdr = hob_list; - - /* Collect memory ranges */ - while (!end_of_hob(hdr)) { - if (hdr->type == HOB_TYPE_RES_DESC) { - res_desc = (struct hob_res_desc *)hdr; - if (res_desc->type == RES_MEM_RESERVED) { - if (compare_guid(&res_desc->owner, guid)) { - if (len) - *len = (u32)(res_desc->len); - - return (u64)(res_desc->phys_start); - } - } - } - hdr = get_next_hob(hdr); - } - - return 0; -} - -u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len) -{ - const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID; - u64 length; - u32 base; - - base = (u32)fsp_get_reserved_mem_from_guid(hob_list, - &length, (struct efi_guid *)&guid); - if ((len != 0) && (base != 0)) - *len = (u32)length; - - return base; -} - -u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len) -{ - const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID; - u64 length; - u32 base; - - base = (u32)fsp_get_reserved_mem_from_guid(hob_list, - &length, (struct efi_guid *)&guid); - if ((len != 0) && (base != 0)) - *len = (u32)length; - - return base; -} - -const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list) -{ - const struct hob_header *hdr; - - hdr = hob_list; - - /* Parse the HOB list until end of list or matching type is found */ - while (!end_of_hob(hdr)) { - if (hdr->type == type) - return hdr; - - hdr = get_next_hob(hdr); - } - - return NULL; -} - -const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, - const void *hob_list) -{ - const struct hob_header *hdr; - struct hob_guid *guid_hob; - - hdr = hob_list; - while ((hdr = fsp_get_next_hob(HOB_TYPE_GUID_EXT, - hdr)) != NULL) { - guid_hob = (struct hob_guid *)hdr; - if (compare_guid(guid, &(guid_hob->name))) - break; - hdr = get_next_hob(hdr); - } - - return hdr; -} - -void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, - struct efi_guid *guid) -{ - const struct hob_header *guid_hob; - - guid_hob = fsp_get_next_guid_hob(guid, hob_list); - if (guid_hob == NULL) { - return NULL; - } else { - if (len) - *len = get_guid_hob_data_size(guid_hob); - - return get_guid_hob_data(guid_hob); - } -} - -void *fsp_get_nvs_data(const void *hob_list, u32 *len) -{ - const struct efi_guid guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; - - return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); -} - -void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len) -{ - const struct efi_guid guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID; - - return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); -} diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index 8637cdca2d..f9b3bfaada 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include static void unprotect_spi_flash(void) diff --git a/arch/x86/cpu/queensbay/tnc_dram.c b/arch/x86/cpu/queensbay/tnc_dram.c index df79a39dd8..4c0a7c82ca 100644 --- a/arch/x86/cpu/queensbay/tnc_dram.c +++ b/arch/x86/cpu/queensbay/tnc_dram.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/arch/x86/cpu/queensbay/tnc_pci.c b/arch/x86/cpu/queensbay/tnc_pci.c index 39bff49c8d..9b0b725313 100644 --- a/arch/x86/cpu/queensbay/tnc_pci.c +++ b/arch/x86/cpu/queensbay/tnc_pci.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h deleted file mode 100644 index a9d7156109..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_API_H__ -#define __FSP_API_H__ - -/* - * FspInit continuation function prototype. - * Control will be returned to this callback function after FspInit API call. - */ -typedef void (*fsp_continuation_f)(u32 status, void *hob_list); - -struct fsp_init_params { - /* Non-volatile storage buffer pointer */ - void *nvs_buf; - /* Runtime buffer pointer */ - void *rt_buf; - /* Continuation function address */ - fsp_continuation_f continuation; -}; - -struct common_buf { - /* - * Stack top pointer used by the bootloader. The new stack frame will be - * set up at this location after FspInit API call. - */ - u32 *stack_top; - u32 boot_mode; /* Current system boot mode */ - void *upd_data; /* User platform configuraiton data region */ - u32 reserved[7]; /* Reserved */ -}; - -enum fsp_phase { - /* Notification code for post PCI enuermation */ - INIT_PHASE_PCI = 0x20, - /* Notification code before transfering control to the payload */ - INIT_PHASE_BOOT = 0x40 -}; - -struct fsp_notify_params { - /* Notification phase used for NotifyPhase API */ - enum fsp_phase phase; -}; - -/* FspInit API function prototype */ -typedef u32 (*fsp_init_f)(struct fsp_init_params *params); - -/* FspNotify API function prototype */ -typedef u32 (*fsp_notify_f)(struct fsp_notify_params *params); - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h deleted file mode 100644 index c3f8b49471..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_BOOT_MODE_H__ -#define __FSP_BOOT_MODE_H__ - -/* 0x21 - 0xf..f are reserved */ -#define BOOT_FULL_CONFIG 0x00 -#define BOOT_MINIMAL_CONFIG 0x01 -#define BOOT_NO_CONFIG_CHANGES 0x02 -#define BOOT_FULL_CONFIG_PLUS_DIAG 0x03 -#define BOOT_DEFAULT_SETTINGS 0x04 -#define BOOT_ON_S4_RESUME 0x05 -#define BOOT_ON_S5_RESUME 0x06 -#define BOOT_ON_S2_RESUME 0x10 -#define BOOT_ON_S3_RESUME 0x11 -#define BOOT_ON_FLASH_UPDATE 0x12 -#define BOOT_IN_RECOVERY_MODE 0x20 - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h deleted file mode 100644 index eaec2b490e..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_FFS_H__ -#define __FSP_FFS_H__ - -/* Used to verify the integrity of the file */ -union __packed ffs_integrity { - struct { - /* - * The IntegrityCheck.checksum.header field is an 8-bit - * checksum of the file header. The State and - * IntegrityCheck.checksum.file fields are assumed to be zero - * and the checksum is calculated such that the entire header - * sums to zero. - */ - u8 header; - /* - * If the FFS_ATTRIB_CHECKSUM (see definition below) bit of - * the Attributes field is set to one, the - * IntegrityCheck.checksum.file field is an 8-bit checksum of - * the file data. If the FFS_ATTRIB_CHECKSUM bit of the - * Attributes field is cleared to zero, the - * IntegrityCheck.checksum.file field must be initialized with - * a value of 0xAA. The IntegrityCheck.checksum.file field is - * valid any time the EFI_FILE_DATA_VALID bit is set in the - * State field. - */ - u8 file; - } checksum; - - /* This is the full 16 bits of the IntegrityCheck field */ - u16 checksum16; -}; - -/* - * Each file begins with the header that describe the - * contents and state of the files. - */ -struct __packed ffs_file_header { - /* - * This GUID is the file name. - * It is used to uniquely identify the file. - */ - struct efi_guid name; - /* Used to verify the integrity of the file */ - union ffs_integrity integrity; - /* Identifies the type of file */ - u8 type; - /* Declares various file attribute bits */ - u8 attr; - /* The length of the file in bytes, including the FFS header */ - u8 size[3]; - /* - * Used to track the state of the file throughout the life of - * the file from creation to deletion. - */ - u8 state; -}; - -struct __packed ffs_file_header2 { - /* - * This GUID is the file name. It is used to uniquely identify the file. - * There may be only one instance of a file with the file name GUID of - * Name in any given firmware volume, except if the file type is - * EFI_FV_FILE_TYPE_FFS_PAD. - */ - struct efi_guid name; - /* Used to verify the integrity of the file */ - union ffs_integrity integrity; - /* Identifies the type of file */ - u8 type; - /* Declares various file attribute bits */ - u8 attr; - /* - * The length of the file in bytes, including the FFS header. - * The length of the file data is either - * (size - sizeof(struct ffs_file_header)). This calculation means a - * zero-length file has a size of 24 bytes, which is - * sizeof(struct ffs_file_header). Size is not required to be a - * multiple of 8 bytes. Given a file F, the next file header is located - * at the next 8-byte aligned firmware volume offset following the last - * byte of the file F. - */ - u8 size[3]; - /* - * Used to track the state of the file throughout the life of - * the file from creation to deletion. - */ - u8 state; - /* - * If FFS_ATTRIB_LARGE_FILE is set in attr, then ext_size exists - * and size must be set to zero. - * If FFS_ATTRIB_LARGE_FILE is not set then - * struct ffs_file_header is used. - */ - u32 ext_size; -}; - -/* - * Pseudo type. It is used as a wild card when retrieving sections. - * The section type EFI_SECTION_ALL matches all section types. - */ -#define EFI_SECTION_ALL 0x00 - -/* Encapsulation section Type values */ -#define EFI_SECTION_COMPRESSION 0x01 -#define EFI_SECTION_GUID_DEFINED 0x02 -#define EFI_SECTION_DISPOSABLE 0x03 - -/* Leaf section Type values */ -#define EFI_SECTION_PE32 0x10 -#define EFI_SECTION_PIC 0x11 -#define EFI_SECTION_TE 0x12 -#define EFI_SECTION_DXE_DEPEX 0x13 -#define EFI_SECTION_VERSION 0x14 -#define EFI_SECTION_USER_INTERFACE 0x15 -#define EFI_SECTION_COMPATIBILITY16 0x16 -#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 -#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 -#define EFI_SECTION_RAW 0x19 -#define EFI_SECTION_PEI_DEPEX 0x1B -#define EFI_SECTION_SMM_DEPEX 0x1C - -/* Common section header */ -struct __packed raw_section { - /* - * A 24-bit unsigned integer that contains the total size of - * the section in bytes, including the EFI_COMMON_SECTION_HEADER. - */ - u8 size[3]; - u8 type; -}; - -struct __packed raw_section2 { - /* - * A 24-bit unsigned integer that contains the total size of - * the section in bytes, including the EFI_COMMON_SECTION_HEADER. - */ - u8 size[3]; - u8 type; - /* - * If size is 0xFFFFFF, then ext_size contains the size of - * the section. If size is not equal to 0xFFFFFF, then this - * field does not exist. - */ - u32 ext_size; -}; - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h deleted file mode 100644 index a024451a74..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_FV___ -#define __FSP_FV___ - -/* Value of EFI_FV_FILE_ATTRIBUTES */ -#define EFI_FV_FILE_ATTR_ALIGNMENT 0x0000001F -#define EFI_FV_FILE_ATTR_FIXED 0x00000100 -#define EFI_FV_FILE_ATTR_MEMORY_MAPPED 0x00000200 - -/* Attributes bit definitions */ -#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 -#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 -#define EFI_FVB2_READ_STATUS 0x00000004 -#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 -#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 -#define EFI_FVB2_WRITE_STATUS 0x00000020 -#define EFI_FVB2_LOCK_CAP 0x00000040 -#define EFI_FVB2_LOCK_STATUS 0x00000080 -#define EFI_FVB2_STICKY_WRITE 0x00000200 -#define EFI_FVB2_MEMORY_MAPPED 0x00000400 -#define EFI_FVB2_ERASE_POLARITY 0x00000800 -#define EFI_FVB2_READ_LOCK_CAP 0x00001000 -#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 -#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 -#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 -#define EFI_FVB2_ALIGNMENT 0x001F0000 -#define EFI_FVB2_ALIGNMENT_1 0x00000000 -#define EFI_FVB2_ALIGNMENT_2 0x00010000 -#define EFI_FVB2_ALIGNMENT_4 0x00020000 -#define EFI_FVB2_ALIGNMENT_8 0x00030000 -#define EFI_FVB2_ALIGNMENT_16 0x00040000 -#define EFI_FVB2_ALIGNMENT_32 0x00050000 -#define EFI_FVB2_ALIGNMENT_64 0x00060000 -#define EFI_FVB2_ALIGNMENT_128 0x00070000 -#define EFI_FVB2_ALIGNMENT_256 0x00080000 -#define EFI_FVB2_ALIGNMENT_512 0x00090000 -#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 -#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 -#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 -#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 -#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 -#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 -#define EFI_FVB2_ALIGNMENT_64K 0x00100000 -#define EFI_FVB2_ALIGNMENT_128K 0x00110000 -#define EFI_FVB2_ALIGNMENT_256K 0x00120000 -#define EFI_FVB2_ALIGNMENT_512K 0x00130000 -#define EFI_FVB2_ALIGNMENT_1M 0x00140000 -#define EFI_FVB2_ALIGNMENT_2M 0x00150000 -#define EFI_FVB2_ALIGNMENT_4M 0x00160000 -#define EFI_FVB2_ALIGNMENT_8M 0x00170000 -#define EFI_FVB2_ALIGNMENT_16M 0x00180000 -#define EFI_FVB2_ALIGNMENT_32M 0x00190000 -#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 -#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 -#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 -#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 -#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 -#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 - -struct fv_blkmap_entry { - /* The number of sequential blocks which are of the same size */ - u32 num_blocks; - /* The size of the blocks */ - u32 length; -}; - -/* Describes the features and layout of the firmware volume */ -struct fv_header { - /* - * The first 16 bytes are reserved to allow for the reset vector of - * processors whose reset vector is at address 0. - */ - u8 zero_vec[16]; - /* - * Declares the file system with which the firmware volume - * is formatted. - */ - struct efi_guid fs_guid; - /* - * Length in bytes of the complete firmware volume, including - * the header. - */ - u64 fv_len; - /* Set to EFI_FVH_SIGNATURE */ - u32 sign; - /* - * Declares capabilities and power-on defaults for the firmware - * volume. - */ - u32 attr; - /* Length in bytes of the complete firmware volume header */ - u16 hdr_len; - /* - * A 16-bit checksum of the firmware volume header. - * A valid header sums to zero. - */ - u16 checksum; - /* - * Offset, relative to the start of the header, of the extended - * header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is - * no extended header. - */ - u16 ext_hdr_off; - /* This field must always be set to zero */ - u8 reserved[1]; - /* - * Set to 2. Future versions of this specification may define new - * header fields and will increment the Revision field accordingly. - */ - u8 rev; - /* - * An array of run-length encoded FvBlockMapEntry structures. - * The array is terminated with an entry of {0,0}. - */ - struct fv_blkmap_entry block_map[1]; -}; - -#define EFI_FVH_SIGNATURE SIGNATURE_32('_', 'F', 'V', 'H') - -/* Firmware Volume Header Revision definition */ -#define EFI_FVH_REVISION 0x02 - -/* Extension header pointed by ExtHeaderOffset of volume header */ -struct fv_ext_header { - /* firmware volume name */ - struct efi_guid fv_name; - /* Size of the rest of the extension header including this structure */ - u32 ext_hdr_size; -}; - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h deleted file mode 100644 index 6cca7f5654..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_HOB_H__ -#define __FSP_HOB_H__ - -/* Type of HOB Header */ -#define HOB_TYPE_MEM_ALLOC 0x0002 -#define HOB_TYPE_RES_DESC 0x0003 -#define HOB_TYPE_GUID_EXT 0x0004 -#define HOB_TYPE_UNUSED 0xFFFE -#define HOB_TYPE_EOH 0xFFFF - -/* - * Describes the format and size of the data inside the HOB. - * All HOBs must contain this generic HOB header. - */ -struct hob_header { - u16 type; /* HOB type */ - u16 len; /* HOB length */ - u32 reserved; /* always zero */ -}; - -/* Enumeration of memory types introduced in UEFI */ -enum efi_mem_type { - EFI_RESERVED_MEMORY_TYPE, - /* - * The code portions of a loaded application. - * (Note that UEFI OS loaders are UEFI applications.) - */ - EFI_LOADER_CODE, - /* - * The data portions of a loaded application and - * the default data allocation type used by an application - * to allocate pool memory. - */ - EFI_LOADER_DATA, - /* The code portions of a loaded Boot Services Driver */ - EFI_BOOT_SERVICES_CODE, - /* - * The data portions of a loaded Boot Serves Driver and - * the default data allocation type used by a Boot Services - * Driver to allocate pool memory. - */ - EFI_BOOT_SERVICES_DATA, - /* The code portions of a loaded Runtime Services Driver */ - EFI_RUNTIME_SERVICES_CODE, - /* - * The data portions of a loaded Runtime Services Driver and - * the default data allocation type used by a Runtime Services - * Driver to allocate pool memory. - */ - EFI_RUNTIME_SERVICES_DATA, - /* Free (unallocated) memory */ - EFI_CONVENTIONAL_MEMORY, - /* Memory in which errors have been detected */ - EFI_UNUSABLE_MEMORY, - /* Memory that holds the ACPI tables */ - EFI_ACPI_RECLAIM_MEMORY, - /* Address space reserved for use by the firmware */ - EFI_ACPI_MEMORY_NVS, - /* - * Used by system firmware to request that a memory-mapped IO region - * be mapped by the OS to a virtual address so it can be accessed by - * EFI runtime services. - */ - EFI_MMAP_IO, - /* - * System memory-mapped IO region that is used to translate - * memory cycles to IO cycles by the processor. - */ - EFI_MMAP_IO_PORT, - /* - * Address space reserved by the firmware for code that is - * part of the processor. - */ - EFI_PAL_CODE, - EFI_MAX_MEMORY_TYPE -}; - -/* - * Describes all memory ranges used during the HOB producer phase that - * exist outside the HOB list. This HOB type describes how memory is used, - * not the physical attributes of memory. - */ -struct hob_mem_alloc { - struct hob_header hdr; - /* - * A GUID that defines the memory allocation region's type and purpose, - * as well as other fields within the memory allocation HOB. This GUID - * is used to define the additional data within the HOB that may be - * present for the memory allocation HOB. Type efi_guid is defined in - * InstallProtocolInterface() in the UEFI 2.0 specification. - */ - struct efi_guid name; - /* - * The base address of memory allocated by this HOB. - * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0 - * specification. - */ - phys_addr_t mem_base; - /* The length in bytes of memory allocated by this HOB */ - phys_size_t mem_len; - /* - * Defines the type of memory allocated by this HOB. - * The memory type definition follows the EFI_MEMORY_TYPE definition. - * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0 - * specification. - */ - enum efi_mem_type mem_type; - /* padding */ - u8 reserved[4]; -}; - -/* Value of ResourceType in HOB_RES_DESC */ -#define RES_SYS_MEM 0x00000000 -#define RES_MMAP_IO 0x00000001 -#define RES_IO 0x00000002 -#define RES_FW_DEVICE 0x00000003 -#define RES_MMAP_IO_PORT 0x00000004 -#define RES_MEM_RESERVED 0x00000005 -#define RES_IO_RESERVED 0x00000006 -#define RES_MAX_MEM_TYPE 0x00000007 - -/* - * These types can be ORed together as needed. - * - * The first three enumerations describe settings - * The rest of the settings describe capabilities - */ -#define RES_ATTR_PRESENT 0x00000001 -#define RES_ATTR_INITIALIZED 0x00000002 -#define RES_ATTR_TESTED 0x00000004 -#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 -#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 -#define RES_ATTR_ECC_RESERVED_1 0x00000020 -#define RES_ATTR_ECC_RESERVED_2 0x00000040 -#define RES_ATTR_READ_PROTECTED 0x00000080 -#define RES_ATTR_WRITE_PROTECTED 0x00000100 -#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 -#define RES_ATTR_UNCACHEABLE 0x00000400 -#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 -#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 -#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 -#define RES_ATTR_16_BIT_IO 0x00004000 -#define RES_ATTR_32_BIT_IO 0x00008000 -#define RES_ATTR_64_BIT_IO 0x00010000 -#define RES_ATTR_UNCACHED_EXPORTED 0x00020000 - -/* - * Describes the resource properties of all fixed, nonrelocatable resource - * ranges found on the processor host bus during the HOB producer phase. - */ -struct hob_res_desc { - struct hob_header hdr; - /* - * A GUID representing the owner of the resource. This GUID is - * used by HOB consumer phase components to correlate device - * ownership of a resource. - */ - struct efi_guid owner; - u32 type; - u32 attr; - /* The physical start address of the resource region */ - phys_addr_t phys_start; - /* The number of bytes of the resource region */ - phys_size_t len; -}; - -/* - * Allows writers of executable content in the HOB producer phase to - * maintain and manage HOBs with specific GUID. - */ -struct hob_guid { - struct hob_header hdr; - /* A GUID that defines the contents of this HOB */ - struct efi_guid name; - /* GUID specific data goes here */ -}; - -/** - * get_next_hob() - return a pointer to the next HOB in the HOB list - * - * This macro returns a pointer to HOB that follows the HOB specified by hob - * in the HOB List. - * - * @hdr: A pointer to a HOB. - * - * @return: A pointer to the next HOB in the HOB list. - */ -static inline const struct hob_header *get_next_hob(const struct hob_header *hdr) -{ - return (const struct hob_header *)((u32)hdr + hdr->len); -} - -/** - * end_of_hob() - determine if a HOB is the last HOB in the HOB list - * - * This macro determine if the HOB specified by hob is the last HOB in the - * HOB list. If hob is last HOB in the HOB list, then true is returned. - * Otherwise, false is returned. - * - * @hdr: A pointer to a HOB. - * - * @retval true: The HOB specified by hdr is the last HOB in the HOB list. - * @retval false: The HOB specified by hdr is not the last HOB in the HOB list. - */ -static inline bool end_of_hob(const struct hob_header *hdr) -{ - return hdr->type == HOB_TYPE_EOH; -} - -/** - * get_guid_hob_data() - return a pointer to data buffer from a HOB of - * type HOB_TYPE_GUID_EXT - * - * This macro returns a pointer to the data buffer in a HOB specified by hob. - * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. - * - * @hdr: A pointer to a HOB. - * - * @return: A pointer to the data buffer in a HOB. - */ -static inline void *get_guid_hob_data(const struct hob_header *hdr) -{ - return (void *)((u32)hdr + sizeof(struct hob_guid)); -} - -/** - * get_guid_hob_data_size() - return the size of the data buffer from a HOB - * of type HOB_TYPE_GUID_EXT - * - * This macro returns the size, in bytes, of the data buffer in a HOB - * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. - * - * @hdr: A pointer to a HOB. - * - * @return: The size of the data buffer. - */ -static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) -{ - return hdr->len - sizeof(struct hob_guid); -} - -/* FSP specific GUID HOB definitions */ -#define FSP_GUID_DATA1 0x912740be -#define FSP_GUID_DATA2 0x2284 -#define FSP_GUID_DATA3 0x4734 -#define FSP_GUID_DATA4_0 0xb9 -#define FSP_GUID_DATA4_1 0x71 -#define FSP_GUID_DATA4_2 0x84 -#define FSP_GUID_DATA4_3 0xb0 -#define FSP_GUID_DATA4_4 0x27 -#define FSP_GUID_DATA4_5 0x35 -#define FSP_GUID_DATA4_6 0x3f -#define FSP_GUID_DATA4_7 0x0c - -#define FSP_HEADER_GUID \ - { \ - FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \ - { FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \ - FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \ - FSP_GUID_DATA4_6, FSP_GUID_DATA4_7 } \ - } - -#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ - { \ - 0x721acf02, 0x4d77, 0x4c2a, \ - { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \ - } - -#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \ - { \ - 0xbbcff46c, 0xc8d3, 0x4113, \ - { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \ - } - -#define FSP_HOB_RESOURCE_OWNER_FSP_GUID \ - { \ - 0x69a79759, 0x1373, 0x4367, \ - { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } \ - } - -#define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \ - { \ - 0xd038747c, 0xd00c, 0x4980, \ - { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } \ - } - -#define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \ - { \ - 0x9c7c3aa7, 0x5332, 0x4917, \ - { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } \ - } - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h deleted file mode 100644 index 4a4d627b28..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef _FSP_HEADER_H_ -#define _FSP_HEADER_H_ - -#define FSP_HEADER_OFF 0x94 /* Fixed FSP header offset in the FSP image */ - -struct __packed fsp_header { - u32 sign; /* 'FSPH' */ - u32 hdr_len; /* header length */ - u8 reserved1[3]; - u8 hdr_rev; /* header rev */ - u32 img_rev; /* image rev */ - char img_id[8]; /* signature string */ - u32 img_size; /* image size */ - u32 img_base; /* image base */ - u32 img_attr; /* image attribute */ - u32 cfg_region_off; /* configuration region offset */ - u32 cfg_region_size; /* configuration region size */ - u32 api_num; /* number of API entries */ - u32 fsp_tempram_init; /* tempram_init offset */ - u32 fsp_init; /* fsp_init offset */ - u32 fsp_notify; /* fsp_notify offset */ - u32 reserved2; -}; - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h deleted file mode 100644 index 61286ceb46..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_PLATFORM_H__ -#define __FSP_PLATFORM_H__ - -struct fspinit_rtbuf { - struct common_buf common; /* FSP common runtime data structure */ -}; - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h deleted file mode 100644 index ebdbd03435..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_SUPPORT_H__ -#define __FSP_SUPPORT_H__ - -#include "fsp_types.h" -#include "fsp_fv.h" -#include "fsp_ffs.h" -#include "fsp_api.h" -#include "fsp_hob.h" -#include "fsp_platform.h" -#include "fsp_infoheader.h" -#include "fsp_bootmode.h" -#include "fsp_vpd.h" - -struct shared_data { - struct fsp_header *fsp_hdr; - u32 *stack_top; - struct upd_region fsp_upd; -}; - -#define FSP_LOWMEM_BASE 0x100000UL -#define FSP_HIGHMEM_BASE 0x100000000ULL - -/** - * FSP Continuation assembly helper routine - * - * This routine jumps to the C version of FSP continuation function - */ -void asm_continuation(void); - -/** - * FSP initialization complete - * - * This is the function that indicates FSP initialization is complete and jumps - * back to the bootloader with HOB list pointer as the parameter. - * - * @hob_list: HOB list pointer - */ -void fsp_init_done(void *hob_list); - -/** - * FSP Continuation function - * - * @shared_data: Shared data base before stack migration - * @status: Always 0 - * @hob_list: HOB list pointer - * - * @retval: Never returns - */ -void fsp_continue(struct shared_data *shared_data, u32 status, - void *hob_list); - -/** - * Find FSP header offset in FSP image - * - * @retval: the offset of FSP header. If signature is invalid, returns 0. - */ -u32 find_fsp_header(void); - -/** - * FSP initialization wrapper function. - * - * @stack_top: bootloader stack top address - * @boot_mode: boot mode defined in fsp_bootmode.h - * @nvs_buf: Non-volatile memory buffer pointer - */ -void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf); - -/** - * FSP notification wrapper function - * - * @fsp_hdr: Pointer to FSP information header - * @phase: FSP initialization phase defined in enum fsp_phase - * - * @retval: compatible status code with EFI_STATUS defined in PI spec - */ -u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase); - -/** - * This function retrieves the top of usable low memory. - * - * @hob_list: A HOB list pointer. - * - * @retval: Usable low memory top. - */ -u32 fsp_get_usable_lowmem_top(const void *hob_list); - -/** - * This function retrieves the top of usable high memory. - * - * @hob_list: A HOB list pointer. - * - * @retval: Usable high memory top. - */ -u64 fsp_get_usable_highmem_top(const void *hob_list); - -/** - * This function retrieves a special reserved memory region. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the GUID HOB data buffer length. - * If the GUID HOB is located, the length will be updated. - * @guid: A pointer to the owner guild. - * - * @retval: Reserved region start address. - * 0 if this region does not exist. - */ -u64 fsp_get_reserved_mem_from_guid(const void *hob_list, - u64 *len, struct efi_guid *guid); - -/** - * This function retrieves the FSP reserved normal memory. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the FSP reserved memory length buffer. - * If the GUID HOB is located, the length will be updated. - * @retval: FSP reserved memory base - * 0 if this region does not exist. - */ -u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len); - -/** - * This function retrieves the TSEG reserved normal memory. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the TSEG reserved memory length buffer. - * If the GUID HOB is located, the length will be updated. - * - * @retval NULL: Failed to find the TSEG reserved memory. - * @retval others: TSEG reserved memory base. - */ -u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len); - -/** - * Returns the next instance of a HOB type from the starting HOB. - * - * @type: HOB type to search - * @hob_list: A pointer to the HOB list - * - * @retval: A HOB object with matching type; Otherwise NULL. - */ -const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list); - -/** - * Returns the next instance of the matched GUID HOB from the starting HOB. - * - * @guid: GUID to search - * @hob_list: A pointer to the HOB list - * - * @retval: A HOB object with matching GUID; Otherwise NULL. - */ -const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, - const void *hob_list); - -/** - * This function retrieves a GUID HOB data buffer and size. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the GUID HOB data buffer length. - * If the GUID HOB is located, the length will be updated. - * @guid A pointer to HOB GUID. - * - * @retval NULL: Failed to find the GUID HOB. - * @retval others: GUID HOB data buffer pointer. - */ -void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, - struct efi_guid *guid); - -/** - * This function retrieves FSP Non-volatile Storage HOB buffer and size. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the NVS data buffer length. - * If the HOB is located, the length will be updated. - * - * @retval NULL: Failed to find the NVS HOB. - * @retval others: FSP NVS data buffer pointer. - */ -void *fsp_get_nvs_data(const void *hob_list, u32 *len); - -/** - * This function retrieves Bootloader temporary stack buffer and size. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the bootloader temporary stack length. - * If the HOB is located, the length will be updated. - * - * @retval NULL: Failed to find the bootloader temporary stack HOB. - * @retval others: Bootloader temporary stackbuffer pointer. - */ -void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len); - -/** - * This function overrides the default configurations in the UPD data region. - * - * @fsp_upd: A pointer to the upd_region data strcture - * - * @return: None - */ -void update_fsp_upd(struct upd_region *fsp_upd); - -#endif diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h deleted file mode 100644 index f32d8273a0..0000000000 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2013, Intel Corporation - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: Intel - */ - -#ifndef __FSP_TYPES_H__ -#define __FSP_TYPES_H__ - -/* 128 bit buffer containing a unique identifier value */ -struct efi_guid { - u32 data1; - u16 data2; - u16 data3; - u8 data4[8]; -}; - -/** - * Returns a 16-bit signature built from 2 ASCII characters. - * - * This macro returns a 16-bit value built from the two ASCII characters - * specified by A and B. - * - * @A: The first ASCII character. - * @B: The second ASCII character. - * - * @return: A 16-bit value built from the two ASCII characters specified by - * A and B. - */ -#define SIGNATURE_16(A, B) ((A) | (B << 8)) - -/** - * Returns a 32-bit signature built from 4 ASCII characters. - * - * This macro returns a 32-bit value built from the four ASCII characters - * specified by A, B, C, and D. - * - * @A: The first ASCII character. - * @B: The second ASCII character. - * @C: The third ASCII character. - * @D: The fourth ASCII character. - * - * @return: A 32-bit value built from the two ASCII characters specified by - * A, B, C and D. - */ -#define SIGNATURE_32(A, B, C, D) \ - (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) - -/** - * Returns a 64-bit signature built from 8 ASCII characters. - * - * This macro returns a 64-bit value built from the eight ASCII characters - * specified by A, B, C, D, E, F, G,and H. - * - * @A: The first ASCII character. - * @B: The second ASCII character. - * @C: The third ASCII character. - * @D: The fourth ASCII character. - * @E: The fifth ASCII character. - * @F: The sixth ASCII character. - * @G: The seventh ASCII character. - * @H: The eighth ASCII character. - * - * @return: A 64-bit value built from the two ASCII characters specified by - * A, B, C, D, E, F, G and H. - */ -#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) - -/* - * Define FSP API return status code. - * Compatiable with EFI_STATUS defined in PI Spec. - */ -#define FSP_SUCCESS 0 -#define FSP_INVALID_PARAM 0x80000002 -#define FSP_UNSUPPORTED 0x80000003 -#define FSP_DEVICE_ERROR 0x80000007 -#define FSP_NOT_FOUND 0x8000000E -#define FSP_ALREADY_STARTED 0x80000014 - -#endif diff --git a/arch/x86/include/asm/fsp/fsp_api.h b/arch/x86/include/asm/fsp/fsp_api.h new file mode 100644 index 0000000000..a9d7156109 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_api.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_API_H__ +#define __FSP_API_H__ + +/* + * FspInit continuation function prototype. + * Control will be returned to this callback function after FspInit API call. + */ +typedef void (*fsp_continuation_f)(u32 status, void *hob_list); + +struct fsp_init_params { + /* Non-volatile storage buffer pointer */ + void *nvs_buf; + /* Runtime buffer pointer */ + void *rt_buf; + /* Continuation function address */ + fsp_continuation_f continuation; +}; + +struct common_buf { + /* + * Stack top pointer used by the bootloader. The new stack frame will be + * set up at this location after FspInit API call. + */ + u32 *stack_top; + u32 boot_mode; /* Current system boot mode */ + void *upd_data; /* User platform configuraiton data region */ + u32 reserved[7]; /* Reserved */ +}; + +enum fsp_phase { + /* Notification code for post PCI enuermation */ + INIT_PHASE_PCI = 0x20, + /* Notification code before transfering control to the payload */ + INIT_PHASE_BOOT = 0x40 +}; + +struct fsp_notify_params { + /* Notification phase used for NotifyPhase API */ + enum fsp_phase phase; +}; + +/* FspInit API function prototype */ +typedef u32 (*fsp_init_f)(struct fsp_init_params *params); + +/* FspNotify API function prototype */ +typedef u32 (*fsp_notify_f)(struct fsp_notify_params *params); + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_bootmode.h b/arch/x86/include/asm/fsp/fsp_bootmode.h new file mode 100644 index 0000000000..c3f8b49471 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_bootmode.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_BOOT_MODE_H__ +#define __FSP_BOOT_MODE_H__ + +/* 0x21 - 0xf..f are reserved */ +#define BOOT_FULL_CONFIG 0x00 +#define BOOT_MINIMAL_CONFIG 0x01 +#define BOOT_NO_CONFIG_CHANGES 0x02 +#define BOOT_FULL_CONFIG_PLUS_DIAG 0x03 +#define BOOT_DEFAULT_SETTINGS 0x04 +#define BOOT_ON_S4_RESUME 0x05 +#define BOOT_ON_S5_RESUME 0x06 +#define BOOT_ON_S2_RESUME 0x10 +#define BOOT_ON_S3_RESUME 0x11 +#define BOOT_ON_FLASH_UPDATE 0x12 +#define BOOT_IN_RECOVERY_MODE 0x20 + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_ffs.h b/arch/x86/include/asm/fsp/fsp_ffs.h new file mode 100644 index 0000000000..eaec2b490e --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_ffs.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_FFS_H__ +#define __FSP_FFS_H__ + +/* Used to verify the integrity of the file */ +union __packed ffs_integrity { + struct { + /* + * The IntegrityCheck.checksum.header field is an 8-bit + * checksum of the file header. The State and + * IntegrityCheck.checksum.file fields are assumed to be zero + * and the checksum is calculated such that the entire header + * sums to zero. + */ + u8 header; + /* + * If the FFS_ATTRIB_CHECKSUM (see definition below) bit of + * the Attributes field is set to one, the + * IntegrityCheck.checksum.file field is an 8-bit checksum of + * the file data. If the FFS_ATTRIB_CHECKSUM bit of the + * Attributes field is cleared to zero, the + * IntegrityCheck.checksum.file field must be initialized with + * a value of 0xAA. The IntegrityCheck.checksum.file field is + * valid any time the EFI_FILE_DATA_VALID bit is set in the + * State field. + */ + u8 file; + } checksum; + + /* This is the full 16 bits of the IntegrityCheck field */ + u16 checksum16; +}; + +/* + * Each file begins with the header that describe the + * contents and state of the files. + */ +struct __packed ffs_file_header { + /* + * This GUID is the file name. + * It is used to uniquely identify the file. + */ + struct efi_guid name; + /* Used to verify the integrity of the file */ + union ffs_integrity integrity; + /* Identifies the type of file */ + u8 type; + /* Declares various file attribute bits */ + u8 attr; + /* The length of the file in bytes, including the FFS header */ + u8 size[3]; + /* + * Used to track the state of the file throughout the life of + * the file from creation to deletion. + */ + u8 state; +}; + +struct __packed ffs_file_header2 { + /* + * This GUID is the file name. It is used to uniquely identify the file. + * There may be only one instance of a file with the file name GUID of + * Name in any given firmware volume, except if the file type is + * EFI_FV_FILE_TYPE_FFS_PAD. + */ + struct efi_guid name; + /* Used to verify the integrity of the file */ + union ffs_integrity integrity; + /* Identifies the type of file */ + u8 type; + /* Declares various file attribute bits */ + u8 attr; + /* + * The length of the file in bytes, including the FFS header. + * The length of the file data is either + * (size - sizeof(struct ffs_file_header)). This calculation means a + * zero-length file has a size of 24 bytes, which is + * sizeof(struct ffs_file_header). Size is not required to be a + * multiple of 8 bytes. Given a file F, the next file header is located + * at the next 8-byte aligned firmware volume offset following the last + * byte of the file F. + */ + u8 size[3]; + /* + * Used to track the state of the file throughout the life of + * the file from creation to deletion. + */ + u8 state; + /* + * If FFS_ATTRIB_LARGE_FILE is set in attr, then ext_size exists + * and size must be set to zero. + * If FFS_ATTRIB_LARGE_FILE is not set then + * struct ffs_file_header is used. + */ + u32 ext_size; +}; + +/* + * Pseudo type. It is used as a wild card when retrieving sections. + * The section type EFI_SECTION_ALL matches all section types. + */ +#define EFI_SECTION_ALL 0x00 + +/* Encapsulation section Type values */ +#define EFI_SECTION_COMPRESSION 0x01 +#define EFI_SECTION_GUID_DEFINED 0x02 +#define EFI_SECTION_DISPOSABLE 0x03 + +/* Leaf section Type values */ +#define EFI_SECTION_PE32 0x10 +#define EFI_SECTION_PIC 0x11 +#define EFI_SECTION_TE 0x12 +#define EFI_SECTION_DXE_DEPEX 0x13 +#define EFI_SECTION_VERSION 0x14 +#define EFI_SECTION_USER_INTERFACE 0x15 +#define EFI_SECTION_COMPATIBILITY16 0x16 +#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define EFI_SECTION_RAW 0x19 +#define EFI_SECTION_PEI_DEPEX 0x1B +#define EFI_SECTION_SMM_DEPEX 0x1C + +/* Common section header */ +struct __packed raw_section { + /* + * A 24-bit unsigned integer that contains the total size of + * the section in bytes, including the EFI_COMMON_SECTION_HEADER. + */ + u8 size[3]; + u8 type; +}; + +struct __packed raw_section2 { + /* + * A 24-bit unsigned integer that contains the total size of + * the section in bytes, including the EFI_COMMON_SECTION_HEADER. + */ + u8 size[3]; + u8 type; + /* + * If size is 0xFFFFFF, then ext_size contains the size of + * the section. If size is not equal to 0xFFFFFF, then this + * field does not exist. + */ + u32 ext_size; +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_fv.h b/arch/x86/include/asm/fsp/fsp_fv.h new file mode 100644 index 0000000000..a024451a74 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_fv.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_FV___ +#define __FSP_FV___ + +/* Value of EFI_FV_FILE_ATTRIBUTES */ +#define EFI_FV_FILE_ATTR_ALIGNMENT 0x0000001F +#define EFI_FV_FILE_ATTR_FIXED 0x00000100 +#define EFI_FV_FILE_ATTR_MEMORY_MAPPED 0x00000200 + +/* Attributes bit definitions */ +#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 +#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 +#define EFI_FVB2_READ_STATUS 0x00000004 +#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 +#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 +#define EFI_FVB2_WRITE_STATUS 0x00000020 +#define EFI_FVB2_LOCK_CAP 0x00000040 +#define EFI_FVB2_LOCK_STATUS 0x00000080 +#define EFI_FVB2_STICKY_WRITE 0x00000200 +#define EFI_FVB2_MEMORY_MAPPED 0x00000400 +#define EFI_FVB2_ERASE_POLARITY 0x00000800 +#define EFI_FVB2_READ_LOCK_CAP 0x00001000 +#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 +#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 +#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 +#define EFI_FVB2_ALIGNMENT 0x001F0000 +#define EFI_FVB2_ALIGNMENT_1 0x00000000 +#define EFI_FVB2_ALIGNMENT_2 0x00010000 +#define EFI_FVB2_ALIGNMENT_4 0x00020000 +#define EFI_FVB2_ALIGNMENT_8 0x00030000 +#define EFI_FVB2_ALIGNMENT_16 0x00040000 +#define EFI_FVB2_ALIGNMENT_32 0x00050000 +#define EFI_FVB2_ALIGNMENT_64 0x00060000 +#define EFI_FVB2_ALIGNMENT_128 0x00070000 +#define EFI_FVB2_ALIGNMENT_256 0x00080000 +#define EFI_FVB2_ALIGNMENT_512 0x00090000 +#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 +#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 +#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 +#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 +#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 +#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 +#define EFI_FVB2_ALIGNMENT_64K 0x00100000 +#define EFI_FVB2_ALIGNMENT_128K 0x00110000 +#define EFI_FVB2_ALIGNMENT_256K 0x00120000 +#define EFI_FVB2_ALIGNMENT_512K 0x00130000 +#define EFI_FVB2_ALIGNMENT_1M 0x00140000 +#define EFI_FVB2_ALIGNMENT_2M 0x00150000 +#define EFI_FVB2_ALIGNMENT_4M 0x00160000 +#define EFI_FVB2_ALIGNMENT_8M 0x00170000 +#define EFI_FVB2_ALIGNMENT_16M 0x00180000 +#define EFI_FVB2_ALIGNMENT_32M 0x00190000 +#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 +#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 +#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 +#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 +#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 +#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 + +struct fv_blkmap_entry { + /* The number of sequential blocks which are of the same size */ + u32 num_blocks; + /* The size of the blocks */ + u32 length; +}; + +/* Describes the features and layout of the firmware volume */ +struct fv_header { + /* + * The first 16 bytes are reserved to allow for the reset vector of + * processors whose reset vector is at address 0. + */ + u8 zero_vec[16]; + /* + * Declares the file system with which the firmware volume + * is formatted. + */ + struct efi_guid fs_guid; + /* + * Length in bytes of the complete firmware volume, including + * the header. + */ + u64 fv_len; + /* Set to EFI_FVH_SIGNATURE */ + u32 sign; + /* + * Declares capabilities and power-on defaults for the firmware + * volume. + */ + u32 attr; + /* Length in bytes of the complete firmware volume header */ + u16 hdr_len; + /* + * A 16-bit checksum of the firmware volume header. + * A valid header sums to zero. + */ + u16 checksum; + /* + * Offset, relative to the start of the header, of the extended + * header (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is + * no extended header. + */ + u16 ext_hdr_off; + /* This field must always be set to zero */ + u8 reserved[1]; + /* + * Set to 2. Future versions of this specification may define new + * header fields and will increment the Revision field accordingly. + */ + u8 rev; + /* + * An array of run-length encoded FvBlockMapEntry structures. + * The array is terminated with an entry of {0,0}. + */ + struct fv_blkmap_entry block_map[1]; +}; + +#define EFI_FVH_SIGNATURE SIGNATURE_32('_', 'F', 'V', 'H') + +/* Firmware Volume Header Revision definition */ +#define EFI_FVH_REVISION 0x02 + +/* Extension header pointed by ExtHeaderOffset of volume header */ +struct fv_ext_header { + /* firmware volume name */ + struct efi_guid fv_name; + /* Size of the rest of the extension header including this structure */ + u32 ext_hdr_size; +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_hob.h b/arch/x86/include/asm/fsp/fsp_hob.h new file mode 100644 index 0000000000..6cca7f5654 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_hob.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_HOB_H__ +#define __FSP_HOB_H__ + +/* Type of HOB Header */ +#define HOB_TYPE_MEM_ALLOC 0x0002 +#define HOB_TYPE_RES_DESC 0x0003 +#define HOB_TYPE_GUID_EXT 0x0004 +#define HOB_TYPE_UNUSED 0xFFFE +#define HOB_TYPE_EOH 0xFFFF + +/* + * Describes the format and size of the data inside the HOB. + * All HOBs must contain this generic HOB header. + */ +struct hob_header { + u16 type; /* HOB type */ + u16 len; /* HOB length */ + u32 reserved; /* always zero */ +}; + +/* Enumeration of memory types introduced in UEFI */ +enum efi_mem_type { + EFI_RESERVED_MEMORY_TYPE, + /* + * The code portions of a loaded application. + * (Note that UEFI OS loaders are UEFI applications.) + */ + EFI_LOADER_CODE, + /* + * The data portions of a loaded application and + * the default data allocation type used by an application + * to allocate pool memory. + */ + EFI_LOADER_DATA, + /* The code portions of a loaded Boot Services Driver */ + EFI_BOOT_SERVICES_CODE, + /* + * The data portions of a loaded Boot Serves Driver and + * the default data allocation type used by a Boot Services + * Driver to allocate pool memory. + */ + EFI_BOOT_SERVICES_DATA, + /* The code portions of a loaded Runtime Services Driver */ + EFI_RUNTIME_SERVICES_CODE, + /* + * The data portions of a loaded Runtime Services Driver and + * the default data allocation type used by a Runtime Services + * Driver to allocate pool memory. + */ + EFI_RUNTIME_SERVICES_DATA, + /* Free (unallocated) memory */ + EFI_CONVENTIONAL_MEMORY, + /* Memory in which errors have been detected */ + EFI_UNUSABLE_MEMORY, + /* Memory that holds the ACPI tables */ + EFI_ACPI_RECLAIM_MEMORY, + /* Address space reserved for use by the firmware */ + EFI_ACPI_MEMORY_NVS, + /* + * Used by system firmware to request that a memory-mapped IO region + * be mapped by the OS to a virtual address so it can be accessed by + * EFI runtime services. + */ + EFI_MMAP_IO, + /* + * System memory-mapped IO region that is used to translate + * memory cycles to IO cycles by the processor. + */ + EFI_MMAP_IO_PORT, + /* + * Address space reserved by the firmware for code that is + * part of the processor. + */ + EFI_PAL_CODE, + EFI_MAX_MEMORY_TYPE +}; + +/* + * Describes all memory ranges used during the HOB producer phase that + * exist outside the HOB list. This HOB type describes how memory is used, + * not the physical attributes of memory. + */ +struct hob_mem_alloc { + struct hob_header hdr; + /* + * A GUID that defines the memory allocation region's type and purpose, + * as well as other fields within the memory allocation HOB. This GUID + * is used to define the additional data within the HOB that may be + * present for the memory allocation HOB. Type efi_guid is defined in + * InstallProtocolInterface() in the UEFI 2.0 specification. + */ + struct efi_guid name; + /* + * The base address of memory allocated by this HOB. + * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + phys_addr_t mem_base; + /* The length in bytes of memory allocated by this HOB */ + phys_size_t mem_len; + /* + * Defines the type of memory allocated by this HOB. + * The memory type definition follows the EFI_MEMORY_TYPE definition. + * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + enum efi_mem_type mem_type; + /* padding */ + u8 reserved[4]; +}; + +/* Value of ResourceType in HOB_RES_DESC */ +#define RES_SYS_MEM 0x00000000 +#define RES_MMAP_IO 0x00000001 +#define RES_IO 0x00000002 +#define RES_FW_DEVICE 0x00000003 +#define RES_MMAP_IO_PORT 0x00000004 +#define RES_MEM_RESERVED 0x00000005 +#define RES_IO_RESERVED 0x00000006 +#define RES_MAX_MEM_TYPE 0x00000007 + +/* + * These types can be ORed together as needed. + * + * The first three enumerations describe settings + * The rest of the settings describe capabilities + */ +#define RES_ATTR_PRESENT 0x00000001 +#define RES_ATTR_INITIALIZED 0x00000002 +#define RES_ATTR_TESTED 0x00000004 +#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 +#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 +#define RES_ATTR_ECC_RESERVED_1 0x00000020 +#define RES_ATTR_ECC_RESERVED_2 0x00000040 +#define RES_ATTR_READ_PROTECTED 0x00000080 +#define RES_ATTR_WRITE_PROTECTED 0x00000100 +#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 +#define RES_ATTR_UNCACHEABLE 0x00000400 +#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 +#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 +#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 +#define RES_ATTR_16_BIT_IO 0x00004000 +#define RES_ATTR_32_BIT_IO 0x00008000 +#define RES_ATTR_64_BIT_IO 0x00010000 +#define RES_ATTR_UNCACHED_EXPORTED 0x00020000 + +/* + * Describes the resource properties of all fixed, nonrelocatable resource + * ranges found on the processor host bus during the HOB producer phase. + */ +struct hob_res_desc { + struct hob_header hdr; + /* + * A GUID representing the owner of the resource. This GUID is + * used by HOB consumer phase components to correlate device + * ownership of a resource. + */ + struct efi_guid owner; + u32 type; + u32 attr; + /* The physical start address of the resource region */ + phys_addr_t phys_start; + /* The number of bytes of the resource region */ + phys_size_t len; +}; + +/* + * Allows writers of executable content in the HOB producer phase to + * maintain and manage HOBs with specific GUID. + */ +struct hob_guid { + struct hob_header hdr; + /* A GUID that defines the contents of this HOB */ + struct efi_guid name; + /* GUID specific data goes here */ +}; + +/** + * get_next_hob() - return a pointer to the next HOB in the HOB list + * + * This macro returns a pointer to HOB that follows the HOB specified by hob + * in the HOB List. + * + * @hdr: A pointer to a HOB. + * + * @return: A pointer to the next HOB in the HOB list. + */ +static inline const struct hob_header *get_next_hob(const struct hob_header *hdr) +{ + return (const struct hob_header *)((u32)hdr + hdr->len); +} + +/** + * end_of_hob() - determine if a HOB is the last HOB in the HOB list + * + * This macro determine if the HOB specified by hob is the last HOB in the + * HOB list. If hob is last HOB in the HOB list, then true is returned. + * Otherwise, false is returned. + * + * @hdr: A pointer to a HOB. + * + * @retval true: The HOB specified by hdr is the last HOB in the HOB list. + * @retval false: The HOB specified by hdr is not the last HOB in the HOB list. + */ +static inline bool end_of_hob(const struct hob_header *hdr) +{ + return hdr->type == HOB_TYPE_EOH; +} + +/** + * get_guid_hob_data() - return a pointer to data buffer from a HOB of + * type HOB_TYPE_GUID_EXT + * + * This macro returns a pointer to the data buffer in a HOB specified by hob. + * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return: A pointer to the data buffer in a HOB. + */ +static inline void *get_guid_hob_data(const struct hob_header *hdr) +{ + return (void *)((u32)hdr + sizeof(struct hob_guid)); +} + +/** + * get_guid_hob_data_size() - return the size of the data buffer from a HOB + * of type HOB_TYPE_GUID_EXT + * + * This macro returns the size, in bytes, of the data buffer in a HOB + * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return: The size of the data buffer. + */ +static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) +{ + return hdr->len - sizeof(struct hob_guid); +} + +/* FSP specific GUID HOB definitions */ +#define FSP_GUID_DATA1 0x912740be +#define FSP_GUID_DATA2 0x2284 +#define FSP_GUID_DATA3 0x4734 +#define FSP_GUID_DATA4_0 0xb9 +#define FSP_GUID_DATA4_1 0x71 +#define FSP_GUID_DATA4_2 0x84 +#define FSP_GUID_DATA4_3 0xb0 +#define FSP_GUID_DATA4_4 0x27 +#define FSP_GUID_DATA4_5 0x35 +#define FSP_GUID_DATA4_6 0x3f +#define FSP_GUID_DATA4_7 0x0c + +#define FSP_HEADER_GUID \ + { \ + FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \ + { FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \ + FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \ + FSP_GUID_DATA4_6, FSP_GUID_DATA4_7 } \ + } + +#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ + { \ + 0x721acf02, 0x4d77, 0x4c2a, \ + { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \ + } + +#define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \ + { \ + 0xbbcff46c, 0xc8d3, 0x4113, \ + { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \ + } + +#define FSP_HOB_RESOURCE_OWNER_FSP_GUID \ + { \ + 0x69a79759, 0x1373, 0x4367, \ + { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } \ + } + +#define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \ + { \ + 0xd038747c, 0xd00c, 0x4980, \ + { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } \ + } + +#define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \ + { \ + 0x9c7c3aa7, 0x5332, 0x4917, \ + { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } \ + } + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_infoheader.h b/arch/x86/include/asm/fsp/fsp_infoheader.h new file mode 100644 index 0000000000..4a4d627b28 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_infoheader.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _FSP_HEADER_H_ +#define _FSP_HEADER_H_ + +#define FSP_HEADER_OFF 0x94 /* Fixed FSP header offset in the FSP image */ + +struct __packed fsp_header { + u32 sign; /* 'FSPH' */ + u32 hdr_len; /* header length */ + u8 reserved1[3]; + u8 hdr_rev; /* header rev */ + u32 img_rev; /* image rev */ + char img_id[8]; /* signature string */ + u32 img_size; /* image size */ + u32 img_base; /* image base */ + u32 img_attr; /* image attribute */ + u32 cfg_region_off; /* configuration region offset */ + u32 cfg_region_size; /* configuration region size */ + u32 api_num; /* number of API entries */ + u32 fsp_tempram_init; /* tempram_init offset */ + u32 fsp_init; /* fsp_init offset */ + u32 fsp_notify; /* fsp_notify offset */ + u32 reserved2; +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_platform.h b/arch/x86/include/asm/fsp/fsp_platform.h new file mode 100644 index 0000000000..61286ceb46 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_platform.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_PLATFORM_H__ +#define __FSP_PLATFORM_H__ + +struct fspinit_rtbuf { + struct common_buf common; /* FSP common runtime data structure */ +}; + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h new file mode 100644 index 0000000000..6329cfea66 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_SUPPORT_H__ +#define __FSP_SUPPORT_H__ + +#include "fsp_types.h" +#include "fsp_fv.h" +#include "fsp_ffs.h" +#include "fsp_api.h" +#include "fsp_hob.h" +#include "fsp_platform.h" +#include "fsp_infoheader.h" +#include "fsp_bootmode.h" +#include + +struct shared_data { + struct fsp_header *fsp_hdr; + u32 *stack_top; + struct upd_region fsp_upd; +}; + +#define FSP_LOWMEM_BASE 0x100000UL +#define FSP_HIGHMEM_BASE 0x100000000ULL + +/** + * FSP Continuation assembly helper routine + * + * This routine jumps to the C version of FSP continuation function + */ +void asm_continuation(void); + +/** + * FSP initialization complete + * + * This is the function that indicates FSP initialization is complete and jumps + * back to the bootloader with HOB list pointer as the parameter. + * + * @hob_list: HOB list pointer + */ +void fsp_init_done(void *hob_list); + +/** + * FSP Continuation function + * + * @shared_data: Shared data base before stack migration + * @status: Always 0 + * @hob_list: HOB list pointer + * + * @retval: Never returns + */ +void fsp_continue(struct shared_data *shared_data, u32 status, + void *hob_list); + +/** + * Find FSP header offset in FSP image + * + * @retval: the offset of FSP header. If signature is invalid, returns 0. + */ +u32 find_fsp_header(void); + +/** + * FSP initialization wrapper function. + * + * @stack_top: bootloader stack top address + * @boot_mode: boot mode defined in fsp_bootmode.h + * @nvs_buf: Non-volatile memory buffer pointer + */ +void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf); + +/** + * FSP notification wrapper function + * + * @fsp_hdr: Pointer to FSP information header + * @phase: FSP initialization phase defined in enum fsp_phase + * + * @retval: compatible status code with EFI_STATUS defined in PI spec + */ +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase); + +/** + * This function retrieves the top of usable low memory. + * + * @hob_list: A HOB list pointer. + * + * @retval: Usable low memory top. + */ +u32 fsp_get_usable_lowmem_top(const void *hob_list); + +/** + * This function retrieves the top of usable high memory. + * + * @hob_list: A HOB list pointer. + * + * @retval: Usable high memory top. + */ +u64 fsp_get_usable_highmem_top(const void *hob_list); + +/** + * This function retrieves a special reserved memory region. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid: A pointer to the owner guild. + * + * @retval: Reserved region start address. + * 0 if this region does not exist. + */ +u64 fsp_get_reserved_mem_from_guid(const void *hob_list, + u64 *len, struct efi_guid *guid); + +/** + * This function retrieves the FSP reserved normal memory. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the FSP reserved memory length buffer. + * If the GUID HOB is located, the length will be updated. + * @retval: FSP reserved memory base + * 0 if this region does not exist. + */ +u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len); + +/** + * This function retrieves the TSEG reserved normal memory. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the TSEG reserved memory length buffer. + * If the GUID HOB is located, the length will be updated. + * + * @retval NULL: Failed to find the TSEG reserved memory. + * @retval others: TSEG reserved memory base. + */ +u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len); + +/** + * Returns the next instance of a HOB type from the starting HOB. + * + * @type: HOB type to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching type; Otherwise NULL. + */ +const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list); + +/** + * Returns the next instance of the matched GUID HOB from the starting HOB. + * + * @guid: GUID to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching GUID; Otherwise NULL. + */ +const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, + const void *hob_list); + +/** + * This function retrieves a GUID HOB data buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid A pointer to HOB GUID. + * + * @retval NULL: Failed to find the GUID HOB. + * @retval others: GUID HOB data buffer pointer. + */ +void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, + struct efi_guid *guid); + +/** + * This function retrieves FSP Non-volatile Storage HOB buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the NVS data buffer length. + * If the HOB is located, the length will be updated. + * + * @retval NULL: Failed to find the NVS HOB. + * @retval others: FSP NVS data buffer pointer. + */ +void *fsp_get_nvs_data(const void *hob_list, u32 *len); + +/** + * This function retrieves Bootloader temporary stack buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the bootloader temporary stack length. + * If the HOB is located, the length will be updated. + * + * @retval NULL: Failed to find the bootloader temporary stack HOB. + * @retval others: Bootloader temporary stackbuffer pointer. + */ +void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len); + +/** + * This function overrides the default configurations in the UPD data region. + * + * @fsp_upd: A pointer to the upd_region data strcture + * + * @return: None + */ +void update_fsp_upd(struct upd_region *fsp_upd); + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_types.h b/arch/x86/include/asm/fsp/fsp_types.h new file mode 100644 index 0000000000..f32d8273a0 --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_types.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_TYPES_H__ +#define __FSP_TYPES_H__ + +/* 128 bit buffer containing a unique identifier value */ +struct efi_guid { + u32 data1; + u16 data2; + u16 data3; + u8 data4[8]; +}; + +/** + * Returns a 16-bit signature built from 2 ASCII characters. + * + * This macro returns a 16-bit value built from the two ASCII characters + * specified by A and B. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * + * @return: A 16-bit value built from the two ASCII characters specified by + * A and B. + */ +#define SIGNATURE_16(A, B) ((A) | (B << 8)) + +/** + * Returns a 32-bit signature built from 4 ASCII characters. + * + * This macro returns a 32-bit value built from the four ASCII characters + * specified by A, B, C, and D. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * + * @return: A 32-bit value built from the two ASCII characters specified by + * A, B, C and D. + */ +#define SIGNATURE_32(A, B, C, D) \ + (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) + +/** + * Returns a 64-bit signature built from 8 ASCII characters. + * + * This macro returns a 64-bit value built from the eight ASCII characters + * specified by A, B, C, D, E, F, G,and H. + * + * @A: The first ASCII character. + * @B: The second ASCII character. + * @C: The third ASCII character. + * @D: The fourth ASCII character. + * @E: The fifth ASCII character. + * @F: The sixth ASCII character. + * @G: The seventh ASCII character. + * @H: The eighth ASCII character. + * + * @return: A 64-bit value built from the two ASCII characters specified by + * A, B, C, D, E, F, G and H. + */ +#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ + (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) + +/* + * Define FSP API return status code. + * Compatiable with EFI_STATUS defined in PI Spec. + */ +#define FSP_SUCCESS 0 +#define FSP_INVALID_PARAM 0x80000002 +#define FSP_UNSUPPORTED 0x80000003 +#define FSP_DEVICE_ERROR 0x80000007 +#define FSP_NOT_FOUND 0x8000000E +#define FSP_ALREADY_STARTED 0x80000014 + +#endif diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 32d7b98fa6..c17f7f088b 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -25,6 +25,7 @@ obj-y += string.o obj-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_VIDEO_VGA) += video.o obj-$(CONFIG_CMD_ZBOOT) += zimage.o +obj-$(CONFIG_HAVE_FSP) += fsp/ extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a diff --git a/arch/x86/lib/cmd_hob.c b/arch/x86/lib/cmd_hob.c index a0ef037da1..915746a4f9 100644 --- a/arch/x86/lib/cmd_hob.c +++ b/arch/x86/lib/cmd_hob.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile new file mode 100644 index 0000000000..1b9b0e279a --- /dev/null +++ b/arch/x86/lib/fsp/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c new file mode 100644 index 0000000000..f6ae85a8ba --- /dev/null +++ b/arch/x86/lib/fsp/fsp_support.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#include +#include +#include + +/** + * Compares two GUIDs + * + * If the GUIDs are identical then true is returned. + * If there are any bit differences in the two GUIDs, then false is returned. + * + * @guid1: A pointer to a 128 bit GUID. + * @guid2: A pointer to a 128 bit GUID. + * + * @retval true: guid1 and guid2 are identical. + * @retval false: guid1 and guid2 are not identical. + */ +static bool compare_guid(const struct efi_guid *guid1, + const struct efi_guid *guid2) +{ + if (memcmp(guid1, guid2, sizeof(struct efi_guid)) == 0) + return true; + else + return false; +} + +u32 __attribute__((optimize("O0"))) find_fsp_header(void) +{ + /* + * This function may be called before the a stack is established, + * so special care must be taken. First, it cannot declare any local + * variable using stack. Only register variable can be used here. + * Secondly, some compiler version will add prolog or epilog code + * for the C function. If so the function call may not work before + * stack is ready. + * + * GCC 4.8.1 has been verified to be working for the following codes. + */ + volatile register u8 *fsp asm("eax"); + + /* Initalize the FSP base */ + fsp = (u8 *)CONFIG_FSP_ADDR; + + /* Check the FV signature, _FVH */ + if (((struct fv_header *)fsp)->sign == EFI_FVH_SIGNATURE) { + /* Go to the end of the FV header and align the address */ + fsp += ((struct fv_header *)fsp)->ext_hdr_off; + fsp += ((struct fv_ext_header *)fsp)->ext_hdr_size; + fsp = (u8 *)(((u32)fsp + 7) & 0xFFFFFFF8); + } else { + fsp = 0; + } + + /* Check the FFS GUID */ + if (fsp && + ((struct ffs_file_header *)fsp)->name.data1 == FSP_GUID_DATA1 && + ((struct ffs_file_header *)fsp)->name.data2 == FSP_GUID_DATA2 && + ((struct ffs_file_header *)fsp)->name.data3 == FSP_GUID_DATA3 && + ((struct ffs_file_header *)fsp)->name.data4[0] == FSP_GUID_DATA4_0 && + ((struct ffs_file_header *)fsp)->name.data4[1] == FSP_GUID_DATA4_1 && + ((struct ffs_file_header *)fsp)->name.data4[2] == FSP_GUID_DATA4_2 && + ((struct ffs_file_header *)fsp)->name.data4[3] == FSP_GUID_DATA4_3 && + ((struct ffs_file_header *)fsp)->name.data4[4] == FSP_GUID_DATA4_4 && + ((struct ffs_file_header *)fsp)->name.data4[5] == FSP_GUID_DATA4_5 && + ((struct ffs_file_header *)fsp)->name.data4[6] == FSP_GUID_DATA4_6 && + ((struct ffs_file_header *)fsp)->name.data4[7] == FSP_GUID_DATA4_7) { + /* Add the FFS header size to find the raw section header */ + fsp += sizeof(struct ffs_file_header); + } else { + fsp = 0; + } + + if (fsp && + ((struct raw_section *)fsp)->type == EFI_SECTION_RAW) { + /* Add the raw section header size to find the FSP header */ + fsp += sizeof(struct raw_section); + } else { + fsp = 0; + } + + return (u32)fsp; +} + +void fsp_continue(struct shared_data *shared_data, u32 status, void *hob_list) +{ + u32 stack_len; + u32 stack_base; + u32 stack_top; + + post_code(POST_MRC); + + assert(status == 0); + + /* Get the migrated stack in normal memory */ + stack_base = (u32)fsp_get_bootloader_tmp_mem(hob_list, &stack_len); + assert(stack_base != 0); + stack_top = stack_base + stack_len - sizeof(u32); + + /* + * Old stack base is stored at the very end of the stack top, + * use it to calculate the migrated shared data base + */ + shared_data = (struct shared_data *)(stack_base + + ((u32)shared_data - *(u32 *)stack_top)); + + /* The boot loader main function entry */ + fsp_init_done(hob_list); +} + +void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) +{ + struct shared_data shared_data; + fsp_init_f init; + struct fsp_init_params params; + struct fspinit_rtbuf rt_buf; + struct vpd_region *fsp_vpd; + struct fsp_header *fsp_hdr; + struct fsp_init_params *params_ptr; + struct upd_region *fsp_upd; + + fsp_hdr = (struct fsp_header *)find_fsp_header(); + if (fsp_hdr == NULL) { + /* No valid FSP info header was found */ + panic("Invalid FSP header"); + } + + fsp_upd = (struct upd_region *)&shared_data.fsp_upd; + memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf)); + + /* Reserve a gap in stack top */ + rt_buf.common.stack_top = (u32 *)stack_top - 32; + rt_buf.common.boot_mode = boot_mode; + rt_buf.common.upd_data = (struct upd_region *)fsp_upd; + + /* Get VPD region start */ + fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base + + fsp_hdr->cfg_region_off); + + /* Verifify the VPD data region is valid */ + assert((fsp_vpd->img_rev == VPD_IMAGE_REV) && + (fsp_vpd->sign == VPD_IMAGE_ID)); + + /* Copy default data from Flash */ + memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), + sizeof(struct upd_region)); + + /* Verifify the UPD data region is valid */ + assert(fsp_upd->terminator == UPD_TERMINATOR); + + /* Override any UPD setting if required */ + update_fsp_upd(fsp_upd); + + memset(¶ms, 0, sizeof(struct fsp_init_params)); + params.nvs_buf = nvs_buf; + params.rt_buf = (struct fspinit_rtbuf *)&rt_buf; + params.continuation = (fsp_continuation_f)asm_continuation; + + init = (fsp_init_f)(fsp_hdr->img_base + fsp_hdr->fsp_init); + params_ptr = ¶ms; + + shared_data.fsp_hdr = fsp_hdr; + shared_data.stack_top = (u32 *)stack_top; + + post_code(POST_PRE_MRC); + + /* + * Use ASM code to ensure the register value in EAX & ECX + * will be passed into BlContinuationFunc + */ + asm volatile ( + "pushl %0;" + "call *%%eax;" + ".global asm_continuation;" + "asm_continuation:;" + "movl %%ebx, %%eax;" /* shared_data */ + "movl 4(%%esp), %%edx;" /* status */ + "movl 8(%%esp), %%ecx;" /* hob_list */ + "jmp fsp_continue;" + : : "m"(params_ptr), "a"(init), "b"(&shared_data) + ); + + /* + * Should never get here. + * Control will continue from fsp_continue. + * This line below is to prevent the compiler from optimizing + * structure intialization. + * + * DO NOT REMOVE! + */ + init(¶ms); +} + +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase) +{ + fsp_notify_f notify; + struct fsp_notify_params params; + struct fsp_notify_params *params_ptr; + u32 status; + + if (!fsp_hdr) + fsp_hdr = (struct fsp_header *)find_fsp_header(); + + if (fsp_hdr == NULL) { + /* No valid FSP info header */ + panic("Invalid FSP header"); + } + + notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); + params.phase = phase; + params_ptr = ¶ms; + + /* + * Use ASM code to ensure correct parameter is on the stack for + * FspNotify as U-Boot is using different ABI from FSP + */ + asm volatile ( + "pushl %1;" /* push notify phase */ + "call *%%eax;" /* call FspNotify */ + "addl $4, %%esp;" /* clean up the stack */ + : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) + ); + + return status; +} + +u32 fsp_get_usable_lowmem_top(const void *hob_list) +{ + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + phys_addr_t phys_start; + u32 top; + + /* Get the HOB list for processing */ + hdr = hob_list; + + /* * Collect memory ranges */ + top = FSP_LOWMEM_BASE; + while (!end_of_hob(hdr)) { + if (hdr->type == HOB_TYPE_RES_DESC) { + res_desc = (struct hob_res_desc *)hdr; + if (res_desc->type == RES_SYS_MEM) { + phys_start = res_desc->phys_start; + /* Need memory above 1MB to be collected here */ + if (phys_start >= FSP_LOWMEM_BASE && + phys_start < (phys_addr_t)FSP_HIGHMEM_BASE) + top += (u32)(res_desc->len); + } + } + hdr = get_next_hob(hdr); + } + + return top; +} + +u64 fsp_get_usable_highmem_top(const void *hob_list) +{ + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + phys_addr_t phys_start; + u64 top; + + /* Get the HOB list for processing */ + hdr = hob_list; + + /* Collect memory ranges */ + top = FSP_HIGHMEM_BASE; + while (!end_of_hob(hdr)) { + if (hdr->type == HOB_TYPE_RES_DESC) { + res_desc = (struct hob_res_desc *)hdr; + if (res_desc->type == RES_SYS_MEM) { + phys_start = res_desc->phys_start; + /* Need memory above 1MB to be collected here */ + if (phys_start >= (phys_addr_t)FSP_HIGHMEM_BASE) + top += (u32)(res_desc->len); + } + } + hdr = get_next_hob(hdr); + } + + return top; +} + +u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len, + struct efi_guid *guid) +{ + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + + /* Get the HOB list for processing */ + hdr = hob_list; + + /* Collect memory ranges */ + while (!end_of_hob(hdr)) { + if (hdr->type == HOB_TYPE_RES_DESC) { + res_desc = (struct hob_res_desc *)hdr; + if (res_desc->type == RES_MEM_RESERVED) { + if (compare_guid(&res_desc->owner, guid)) { + if (len) + *len = (u32)(res_desc->len); + + return (u64)(res_desc->phys_start); + } + } + } + hdr = get_next_hob(hdr); + } + + return 0; +} + +u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len) +{ + const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID; + u64 length; + u32 base; + + base = (u32)fsp_get_reserved_mem_from_guid(hob_list, + &length, (struct efi_guid *)&guid); + if ((len != 0) && (base != 0)) + *len = (u32)length; + + return base; +} + +u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len) +{ + const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID; + u64 length; + u32 base; + + base = (u32)fsp_get_reserved_mem_from_guid(hob_list, + &length, (struct efi_guid *)&guid); + if ((len != 0) && (base != 0)) + *len = (u32)length; + + return base; +} + +const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list) +{ + const struct hob_header *hdr; + + hdr = hob_list; + + /* Parse the HOB list until end of list or matching type is found */ + while (!end_of_hob(hdr)) { + if (hdr->type == type) + return hdr; + + hdr = get_next_hob(hdr); + } + + return NULL; +} + +const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, + const void *hob_list) +{ + const struct hob_header *hdr; + struct hob_guid *guid_hob; + + hdr = hob_list; + while ((hdr = fsp_get_next_hob(HOB_TYPE_GUID_EXT, + hdr)) != NULL) { + guid_hob = (struct hob_guid *)hdr; + if (compare_guid(guid, &(guid_hob->name))) + break; + hdr = get_next_hob(hdr); + } + + return hdr; +} + +void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, + struct efi_guid *guid) +{ + const struct hob_header *guid_hob; + + guid_hob = fsp_get_next_guid_hob(guid, hob_list); + if (guid_hob == NULL) { + return NULL; + } else { + if (len) + *len = get_guid_hob_data_size(guid_hob); + + return get_guid_hob_data(guid_hob); + } +} + +void *fsp_get_nvs_data(const void *hob_list, u32 *len) +{ + const struct efi_guid guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; + + return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); +} + +void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len) +{ + const struct efi_guid guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID; + + return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); +} -- cgit From 82196cf34f20c1aeb3f5d3d091b7edfdff37aaad Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:37 -0700 Subject: x86: Adjust the FSP types slightly To avoid casts, find_fsp_header() should return a pointer. Add asmlinkage to two API functions which use that convention. UPD_TERMINATOR is common so move it into a common file. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h | 2 -- arch/x86/include/asm/fsp/fsp_api.h | 6 ++++-- arch/x86/include/asm/fsp/fsp_support.h | 4 +++- arch/x86/lib/fsp/fsp_support.c | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h index bce58b1e69..3c57558d21 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h @@ -10,8 +10,6 @@ #ifndef __VPDHEADER_H__ #define __VPDHEADER_H__ -#define UPD_TERMINATOR 0x55AA - struct __packed upd_region { u64 sign; /* Offset 0x0000 */ u64 reserved; /* Offset 0x0008 */ diff --git a/arch/x86/include/asm/fsp/fsp_api.h b/arch/x86/include/asm/fsp/fsp_api.h index a9d7156109..2d34d138ab 100644 --- a/arch/x86/include/asm/fsp/fsp_api.h +++ b/arch/x86/include/asm/fsp/fsp_api.h @@ -8,6 +8,8 @@ #ifndef __FSP_API_H__ #define __FSP_API_H__ +#include + /* * FspInit continuation function prototype. * Control will be returned to this callback function after FspInit API call. @@ -47,9 +49,9 @@ struct fsp_notify_params { }; /* FspInit API function prototype */ -typedef u32 (*fsp_init_f)(struct fsp_init_params *params); +typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params); /* FspNotify API function prototype */ -typedef u32 (*fsp_notify_f)(struct fsp_notify_params *params); +typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params); #endif diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h index 6329cfea66..c6c7dc0f83 100644 --- a/arch/x86/include/asm/fsp/fsp_support.h +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -26,6 +26,8 @@ struct shared_data { #define FSP_LOWMEM_BASE 0x100000UL #define FSP_HIGHMEM_BASE 0x100000000ULL +#define UPD_TERMINATOR 0x55AA + /** * FSP Continuation assembly helper routine @@ -61,7 +63,7 @@ void fsp_continue(struct shared_data *shared_data, u32 status, * * @retval: the offset of FSP header. If signature is invalid, returns 0. */ -u32 find_fsp_header(void); +struct fsp_header *find_fsp_header(void); /** * FSP initialization wrapper function. diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index f6ae85a8ba..bf3780711f 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -30,7 +30,7 @@ static bool compare_guid(const struct efi_guid *guid1, return false; } -u32 __attribute__((optimize("O0"))) find_fsp_header(void) +struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void) { /* * This function may be called before the a stack is established, @@ -84,7 +84,7 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void) fsp = 0; } - return (u32)fsp; + return (struct fsp_header *)fsp; } void fsp_continue(struct shared_data *shared_data, u32 status, void *hob_list) -- cgit From 7b02bf3c7dc74ab29e5c5f826cc0cfd141e41f2d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:38 -0700 Subject: x86: Make CAR and DRAM FSP code common For now this code seems to be the same for all FSP platforms. Make it common until we see what differences are required. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/cpu/queensbay/Makefile | 2 +- arch/x86/cpu/queensbay/tnc_car.S | 124 -------------------------------------- arch/x86/cpu/queensbay/tnc_dram.c | 81 ------------------------- arch/x86/lib/fsp/Makefile | 2 + arch/x86/lib/fsp/fsp_car.S | 124 ++++++++++++++++++++++++++++++++++++++ arch/x86/lib/fsp/fsp_dram.c | 81 +++++++++++++++++++++++++ 6 files changed, 208 insertions(+), 206 deletions(-) delete mode 100644 arch/x86/cpu/queensbay/tnc_car.S delete mode 100644 arch/x86/cpu/queensbay/tnc_dram.c create mode 100644 arch/x86/lib/fsp/fsp_car.S create mode 100644 arch/x86/lib/fsp/fsp_dram.c diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile index b3e7d87956..d8761fdfbd 100644 --- a/arch/x86/cpu/queensbay/Makefile +++ b/arch/x86/cpu/queensbay/Makefile @@ -4,6 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o obj-y += fsp_configs.o +obj-y += tnc.o topcliff.o obj-$(CONFIG_PCI) += tnc_pci.o diff --git a/arch/x86/cpu/queensbay/tnc_car.S b/arch/x86/cpu/queensbay/tnc_car.S deleted file mode 100644 index 5e09568b85..0000000000 --- a/arch/x86/cpu/queensbay/tnc_car.S +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -.globl car_init -car_init: - /* - * Note: ebp holds the BIST value (built-in self test) so far, but ebp - * will be destroyed through the FSP call, thus we have to test the - * BIST value here before we call into FSP. - */ - test %ebp, %ebp - jz car_init_start - post_code(POST_BIST_FAILURE) - jmp die - -car_init_start: - post_code(POST_CAR_START) - lea find_fsp_header_romstack, %esp - jmp find_fsp_header - -find_fsp_header_ret: - /* EAX points to FSP_INFO_HEADER */ - mov %eax, %ebp - - /* sanity test */ - cmp $CONFIG_FSP_ADDR, %eax - jb die - - /* calculate TempRamInitEntry address */ - mov 0x30(%ebp), %eax - add 0x1c(%ebp), %eax - - /* call FSP TempRamInitEntry to setup temporary stack */ - lea temp_ram_init_romstack, %esp - jmp *%eax - -temp_ram_init_ret: - addl $4, %esp - cmp $0, %eax - jnz car_init_fail - - post_code(POST_CAR_CPU_CACHE) - - /* - * The FSP TempRamInit initializes the ecx and edx registers to - * point to a temporary but writable memory range (Cache-As-RAM). - * ecx: the start of this temporary memory range, - * edx: the end of this range. - */ - - /* stack grows down from top of CAR */ - movl %edx, %esp - - /* - * TODO: - * - * According to FSP architecture spec, the fsp_init() will not return - * to its caller, instead it requires the bootloader to provide a - * so-called continuation function to pass into the FSP as a parameter - * of fsp_init, and fsp_init() will call that continuation function - * directly. - * - * The call to fsp_init() may need to be moved out of the car_init() - * to cpu_init_f() with the help of some inline assembly codes. - * Note there is another issue that fsp_init() will setup another stack - * using the fsp_init parameter stack_top after DRAM is initialized, - * which means any data on the previous stack (on the CAR) gets lost - * (ie: U-Boot global_data). FSP is supposed to support such scenario, - * however it does not work. This should be revisited in the future. - */ - movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax - xorl %edx, %edx - xorl %ecx, %ecx - call fsp_init - -.global fsp_init_done -fsp_init_done: - /* - * We come here from FspInit with eax pointing to the HOB list. - * Save eax to esi temporarily. - */ - movl %eax, %esi - /* - * Re-initialize the ebp (BIST) to zero, as we already reach here - * which means we passed BIST testing before. - */ - xorl %ebp, %ebp - jmp car_init_ret - -car_init_fail: - post_code(POST_CAR_FAILURE) - -die: - hlt - jmp die - hlt - - /* - * The function call before CAR initialization is tricky. It cannot - * be called using the 'call' instruction but only the 'jmp' with - * the help of a handcrafted stack in the ROM. The stack needs to - * contain the function return address as well as the parameters. - */ - .balign 4 -find_fsp_header_romstack: - .long find_fsp_header_ret - - .balign 4 -temp_ram_init_romstack: - .long temp_ram_init_ret - .long temp_ram_init_params -temp_ram_init_params: -_dt_ucode_base_size: - /* These next two fields are filled in by ifdtool */ - .long 0 /* microcode base */ - .long 0 /* microcode size */ - .long CONFIG_SYS_MONITOR_BASE /* code region base */ - .long CONFIG_SYS_MONITOR_LEN /* code region size */ diff --git a/arch/x86/cpu/queensbay/tnc_dram.c b/arch/x86/cpu/queensbay/tnc_dram.c deleted file mode 100644 index 4c0a7c82ca..0000000000 --- a/arch/x86/cpu/queensbay/tnc_dram.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014, Bin Meng - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -int dram_init(void) -{ - phys_size_t ram_size = 0; - const struct hob_header *hdr; - struct hob_res_desc *res_desc; - - hdr = gd->arch.hob_list; - while (!end_of_hob(hdr)) { - if (hdr->type == HOB_TYPE_RES_DESC) { - res_desc = (struct hob_res_desc *)hdr; - if (res_desc->type == RES_SYS_MEM || - res_desc->type == RES_MEM_RESERVED) { - ram_size += res_desc->len; - } - } - hdr = get_next_hob(hdr); - } - - gd->ram_size = ram_size; - post_code(POST_DRAM); - - return 0; -} - -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = 0; - gd->bd->bi_dram[0].size = gd->ram_size; -} - -/* - * This function looks for the highest region of memory lower than 4GB which - * has enough space for U-Boot where U-Boot is aligned on a page boundary. - * It overrides the default implementation found elsewhere which simply - * picks the end of ram, wherever that may be. The location of the stack, - * the relocation address, and how far U-Boot is moved by relocation are - * set in the global data structure. - */ -ulong board_get_usable_ram_top(ulong total_size) -{ - return fsp_get_usable_lowmem_top(gd->arch.hob_list); -} - -unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) -{ - unsigned num_entries = 0; - const struct hob_header *hdr; - struct hob_res_desc *res_desc; - - hdr = gd->arch.hob_list; - - while (!end_of_hob(hdr)) { - if (hdr->type == HOB_TYPE_RES_DESC) { - res_desc = (struct hob_res_desc *)hdr; - entries[num_entries].addr = res_desc->phys_start; - entries[num_entries].size = res_desc->len; - - if (res_desc->type == RES_SYS_MEM) - entries[num_entries].type = E820_RAM; - else if (res_desc->type == RES_MEM_RESERVED) - entries[num_entries].type = E820_RESERVED; - } - hdr = get_next_hob(hdr); - num_entries++; - } - - return num_entries; -} diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile index 1b9b0e279a..3a2bac0636 100644 --- a/arch/x86/lib/fsp/Makefile +++ b/arch/x86/lib/fsp/Makefile @@ -4,4 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += fsp_car.o +obj-y += fsp_dram.o obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S new file mode 100644 index 0000000000..5e09568b85 --- /dev/null +++ b/arch/x86/lib/fsp/fsp_car.S @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +.globl car_init +car_init: + /* + * Note: ebp holds the BIST value (built-in self test) so far, but ebp + * will be destroyed through the FSP call, thus we have to test the + * BIST value here before we call into FSP. + */ + test %ebp, %ebp + jz car_init_start + post_code(POST_BIST_FAILURE) + jmp die + +car_init_start: + post_code(POST_CAR_START) + lea find_fsp_header_romstack, %esp + jmp find_fsp_header + +find_fsp_header_ret: + /* EAX points to FSP_INFO_HEADER */ + mov %eax, %ebp + + /* sanity test */ + cmp $CONFIG_FSP_ADDR, %eax + jb die + + /* calculate TempRamInitEntry address */ + mov 0x30(%ebp), %eax + add 0x1c(%ebp), %eax + + /* call FSP TempRamInitEntry to setup temporary stack */ + lea temp_ram_init_romstack, %esp + jmp *%eax + +temp_ram_init_ret: + addl $4, %esp + cmp $0, %eax + jnz car_init_fail + + post_code(POST_CAR_CPU_CACHE) + + /* + * The FSP TempRamInit initializes the ecx and edx registers to + * point to a temporary but writable memory range (Cache-As-RAM). + * ecx: the start of this temporary memory range, + * edx: the end of this range. + */ + + /* stack grows down from top of CAR */ + movl %edx, %esp + + /* + * TODO: + * + * According to FSP architecture spec, the fsp_init() will not return + * to its caller, instead it requires the bootloader to provide a + * so-called continuation function to pass into the FSP as a parameter + * of fsp_init, and fsp_init() will call that continuation function + * directly. + * + * The call to fsp_init() may need to be moved out of the car_init() + * to cpu_init_f() with the help of some inline assembly codes. + * Note there is another issue that fsp_init() will setup another stack + * using the fsp_init parameter stack_top after DRAM is initialized, + * which means any data on the previous stack (on the CAR) gets lost + * (ie: U-Boot global_data). FSP is supposed to support such scenario, + * however it does not work. This should be revisited in the future. + */ + movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax + xorl %edx, %edx + xorl %ecx, %ecx + call fsp_init + +.global fsp_init_done +fsp_init_done: + /* + * We come here from FspInit with eax pointing to the HOB list. + * Save eax to esi temporarily. + */ + movl %eax, %esi + /* + * Re-initialize the ebp (BIST) to zero, as we already reach here + * which means we passed BIST testing before. + */ + xorl %ebp, %ebp + jmp car_init_ret + +car_init_fail: + post_code(POST_CAR_FAILURE) + +die: + hlt + jmp die + hlt + + /* + * The function call before CAR initialization is tricky. It cannot + * be called using the 'call' instruction but only the 'jmp' with + * the help of a handcrafted stack in the ROM. The stack needs to + * contain the function return address as well as the parameters. + */ + .balign 4 +find_fsp_header_romstack: + .long find_fsp_header_ret + + .balign 4 +temp_ram_init_romstack: + .long temp_ram_init_ret + .long temp_ram_init_params +temp_ram_init_params: +_dt_ucode_base_size: + /* These next two fields are filled in by ifdtool */ + .long 0 /* microcode base */ + .long 0 /* microcode size */ + .long CONFIG_SYS_MONITOR_BASE /* code region base */ + .long CONFIG_SYS_MONITOR_LEN /* code region size */ diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c new file mode 100644 index 0000000000..4c0a7c82ca --- /dev/null +++ b/arch/x86/lib/fsp/fsp_dram.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + phys_size_t ram_size = 0; + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + + hdr = gd->arch.hob_list; + while (!end_of_hob(hdr)) { + if (hdr->type == HOB_TYPE_RES_DESC) { + res_desc = (struct hob_res_desc *)hdr; + if (res_desc->type == RES_SYS_MEM || + res_desc->type == RES_MEM_RESERVED) { + ram_size += res_desc->len; + } + } + hdr = get_next_hob(hdr); + } + + gd->ram_size = ram_size; + post_code(POST_DRAM); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return fsp_get_usable_lowmem_top(gd->arch.hob_list); +} + +unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) +{ + unsigned num_entries = 0; + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + + hdr = gd->arch.hob_list; + + while (!end_of_hob(hdr)) { + if (hdr->type == HOB_TYPE_RES_DESC) { + res_desc = (struct hob_res_desc *)hdr; + entries[num_entries].addr = res_desc->phys_start; + entries[num_entries].size = res_desc->len; + + if (res_desc->type == RES_SYS_MEM) + entries[num_entries].type = E820_RAM; + else if (res_desc->type == RES_MEM_RESERVED) + entries[num_entries].type = E820_RESERVED; + } + hdr = get_next_hob(hdr); + num_entries++; + } + + return num_entries; +} -- cgit From 5848899a1f868fe6ae50027d422f0af5f4e2e95d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 3 Feb 2015 13:51:36 +0900 Subject: ARM: UniPhier: remove dummy gpio.h This dummy header was introduced by commit 630bf80ebb34 (ARM: UniPhier: add dummy gpio.h to enable CONFIG_OF_CONTROL). Thanks to commit a08d643dbd85 (dm: Drop gpio.h header from fdtdec.c), such an ugly workaround is no longer needed. Signed-off-by: Masahiro Yamada --- arch/arm/include/asm/arch-uniphier/gpio.h | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 arch/arm/include/asm/arch-uniphier/gpio.h diff --git a/arch/arm/include/asm/arch-uniphier/gpio.h b/arch/arm/include/asm/arch-uniphier/gpio.h deleted file mode 100644 index 1fc4e19a61..0000000000 --- a/arch/arm/include/asm/arch-uniphier/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Dummy header file to enable CONFIG_OF_CONTROL. - * If CONFIG_OF_CONTROL is enabled, lib/fdtdec.c is compiled. - * It includes via , so those SoCs that enable - * OF_CONTROL must have arch/gpio.h even if GPIO is not supported. - */ -- cgit From 0e063dff5c8a555ad92e26edb5c6358a127d5c8f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:21 +0900 Subject: ARM: UniPhier: use "&&" instead of "; " in commands Run the next command only when the previous one succeeded. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 9ad47f6933..43d2a4c359 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2014 Panasonic Corporation + * Copyright (C) 2012-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -235,11 +235,11 @@ "image_offset=0x00080000\0" \ "image_size=0x00f00000\0" \ "verify=n\0" \ - "norboot=run add_default_bootargs;" \ + "norboot=run add_default_bootargs &&" \ "bootm $image_offset\0" \ - "nandboot=run add_default_bootargs;" \ - "nand read $loadaddr $image_offset $image_size;" \ - "bootm\0" \ + "nandboot=run add_default_bootargs &&" \ + "nand read $loadaddr $image_offset $image_size &&" \ + "bootm\0" \ "add_default_bootargs=setenv bootargs $bootargs" \ " console=ttyS0,$baudrate\0" \ -- cgit From 75bc8e85b5aa44c8f834ec9518c8ca4a7c1d7067 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:22 +0900 Subject: ARM: UniPhier: add environment variable to update images in NAND To boot UniPhier boards with the NAND boot mode, two images (u-boot-spl.bin and u-boot-dtb.img) must be written at the correct offset addresses. TFTP downloading is useful to update such images in the NAND device. We generally do: => nand erase 0 0x100000 => tftpboot u-boot-spl.bin => nand write $loadaddr 0 0x10000 => tftpboot u-boot-dtb.img => nand write $loadaddr 0x10000 0xf0000 It is a tedious and error-prone operation. This commit provides the shorthand: => run nandupdate Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 43d2a4c359..35bea1a72f 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -235,6 +235,11 @@ "image_offset=0x00080000\0" \ "image_size=0x00f00000\0" \ "verify=n\0" \ + "nandupdate=nand erase 0 0x100000 &&" \ + "tftpboot u-boot-spl.bin &&" \ + "nand write $loadaddr 0 0x10000 &&" \ + "tftpboot u-boot-dtb.img &&" \ + "nand write $loadaddr 0x10000 0xf0000\0" \ "norboot=run add_default_bootargs &&" \ "bootm $image_offset\0" \ "nandboot=run add_default_bootargs &&" \ -- cgit From 7168da163880fc60c4e8d00f3d61eb6f009ffe56 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:23 +0900 Subject: ARM: UniPhier: add a simple README file for UniPhier platform Signed-off-by: Masahiro Yamada --- doc/README.uniphier | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 doc/README.uniphier diff --git a/doc/README.uniphier b/doc/README.uniphier new file mode 100644 index 0000000000..aaeb50c4e6 --- /dev/null +++ b/doc/README.uniphier @@ -0,0 +1,85 @@ +U-Boot for UniPhier SoC family +============================== + + +Tested toolchains +----------------- + + (a) Ubuntu packages (CROSS_COMPILE=arm-linux-gnueabi-) + + If you are building U-Boot on Ubuntu, its standard package is recommended. + You can install it as follows: + + $ sudo apt-get install gcc-arm-linux-gnueabi- + + (b) Linaro compilers (CROSS_COMPILE=arm-linux-gnueabihf-) + + You can download pre-built toolchains from: + + http://www.linaro.org/downloads/ + + (c) kernel.org compilers (CROSS_COMPILE=arm-unknown-linux-gnueabi-) + + You can download pre-built toolchains from: + + ftp://www.kernel.org/pub/tools/crosstool/files/bin/ + + +Compile the source +------------------ + +PH1-Pro4: + $ make ph1_pro4_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + +PH1-LD4: + $ make ph1_ld4_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + +PH1-sLD8: + $ make ph1_sld8_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabi- + +You may wish to change the "CROSS_COMPILE=arm-linux-gnueabi-" +to use your favorite compiler. + + +Burn U-Boot images to NAND +-------------------------- + +Write two files to the NAND device as follows: + - spl/u-boot-spl.bin at the offset address 0x00000000 + - u-boot-dtb.img at the offset address 0x00010000 + +If a TFTP server is available, the images can be easily updated. +Just copy the u-boot-spl.bin and u-boot-dtb.img to the TFTP public directory, +and then run the following command at the U-Boot command line: + + => run nandupdate + + +UniPhier specific commands +-------------------------- + + - pinmon (enabled by CONFIG_CMD_PINMON) + shows the boot mode pins that has been latched at the power-on reset + + - ddrphy (enabled by CONFIG_CMD_DDRPHY_DUMP) + shows the DDR PHY parameters set by the PHY training + + +Supported devices +----------------- + + - UART (on-chip) + - NAND + - USB (2.0) + - LAN (on-board SMSC9118) + - I2C + - EEPROM (connected to the on-board I2C bus) + - Support card (SRAM, NOR flash, some peripherals) + + +-- +Masahiro Yamada +Feb. 2015 -- cgit From eb006c83e6179e8ecd2866876fc7056867402b2f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:24 +0900 Subject: MAINTAINERS: claim maintainership of files with "uniphier" pattern The pattern "N: uniphier" can cover - drivers/serial/serial_uniphier.c - drivers/i2c/i2c-uniphier.c - drivers/i2c/i2c-uniphier-f.c - arch/arm/dts/uniphier-* Signed-off-by: Masahiro Yamada --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1f7735922d..74a56ecf4f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -170,7 +170,7 @@ T: git git://git.denx.de/u-boot-uniphier.git F: arch/arm/cpu/armv7/uniphier/ F: arch/arm/include/asm/arch-uniphier/ F: configs/ph1_*_defconfig -F: drivers/serial/serial_uniphier.c +N: uniphier ARM ZYNQ M: Michal Simek -- cgit From a7f2ecf5dcf81c314a00b69527587d4db72c00ce Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:25 +0900 Subject: ARM: UniPhier: move EEPROM device node into a separate DTS This EEPROM chip is installed on the expansion board commonly used on UniPhier platform. To avoid duplicated description, move the EEPROM node to a separate file and include it from other device tree sources. Signed-off-by: Masahiro Yamada --- arch/arm/dts/uniphier-ph1-ld4-ref.dts | 7 ++----- arch/arm/dts/uniphier-ph1-pro4-ref.dts | 7 ++----- arch/arm/dts/uniphier-ph1-sld3-ref.dts | 7 ++----- arch/arm/dts/uniphier-ph1-sld8-ref.dts | 7 ++----- arch/arm/dts/uniphier-ref-daughter.dtsi | 15 +++++++++++++++ 5 files changed, 23 insertions(+), 20 deletions(-) create mode 100644 arch/arm/dts/uniphier-ref-daughter.dtsi diff --git a/arch/arm/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/dts/uniphier-ph1-ld4-ref.dts index 6855878c29..d479be1d4d 100644 --- a/arch/arm/dts/uniphier-ph1-ld4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-ld4-ref.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for UniPhier PH1-LD4 Reference Board * - * Copyright (C) 2014 Panasonic Corporation + * Copyright (C) 2014-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -9,6 +9,7 @@ /dts-v1/; /include/ "uniphier-ph1-ld4.dtsi" +/include/ "uniphier-ref-daughter.dtsi" / { model = "Panasonic UniPhier PH1-LD4 Reference Board"; @@ -46,10 +47,6 @@ &i2c0 { status = "okay"; - eeprom { - compatible = "i2c-eeprom"; - reg = <0x50>; - }; }; &usb0 { diff --git a/arch/arm/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/dts/uniphier-ph1-pro4-ref.dts index 1227b628d1..d9e7a8c52b 100644 --- a/arch/arm/dts/uniphier-ph1-pro4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-pro4-ref.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for UniPhier PH1-Pro4 Reference Board * - * Copyright (C) 2014 Panasonic Corporation + * Copyright (C) 2014-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -9,6 +9,7 @@ /dts-v1/; /include/ "uniphier-ph1-pro4.dtsi" +/include/ "uniphier-ref-daughter.dtsi" / { model = "Panasonic UniPhier PH1-Pro4 Reference Board"; @@ -48,10 +49,6 @@ &i2c0 { status = "okay"; - eeprom { - compatible = "i2c-eeprom"; - reg = <0x50>; - }; }; &usb0 { diff --git a/arch/arm/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/dts/uniphier-ph1-sld3-ref.dts index fefc592589..8a7f90ac78 100644 --- a/arch/arm/dts/uniphier-ph1-sld3-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld3-ref.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for UniPhier PH1-sLD3 Reference Board * - * Copyright (C) 2014 Panasonic Corporation + * Copyright (C) 2014-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -9,6 +9,7 @@ /dts-v1/; /include/ "uniphier-ph1-sld3.dtsi" +/include/ "uniphier-ref-daughter.dtsi" / { model = "Panasonic UniPhier PH1-sLD3 Reference Board"; @@ -45,10 +46,6 @@ &i2c0 { status = "okay"; - eeprom { - compatible = "i2c-eeprom"; - reg = <0x50>; - }; }; &usb0 { diff --git a/arch/arm/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/dts/uniphier-ph1-sld8-ref.dts index 9b6d95c480..0cb9c47b65 100644 --- a/arch/arm/dts/uniphier-ph1-sld8-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld8-ref.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for UniPhier PH1-sLD8 Reference Board * - * Copyright (C) 2014 Panasonic Corporation + * Copyright (C) 2014-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -9,6 +9,7 @@ /dts-v1/; /include/ "uniphier-ph1-sld8.dtsi" +/include/ "uniphier-ref-daughter.dtsi" / { model = "Panasonic UniPhier PH1-sLD8 Reference Board"; @@ -46,10 +47,6 @@ &i2c0 { status = "okay"; - eeprom { - compatible = "i2c-eeprom"; - reg = <0x50>; - }; }; &usb0 { diff --git a/arch/arm/dts/uniphier-ref-daughter.dtsi b/arch/arm/dts/uniphier-ref-daughter.dtsi new file mode 100644 index 0000000000..33dc20547f --- /dev/null +++ b/arch/arm/dts/uniphier-ref-daughter.dtsi @@ -0,0 +1,15 @@ +/* + * Device Tree Source for UniPhier Reference Daughter Board + * + * Copyright (C) 2014-2015 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +&i2c0 { + eeprom { + compatible = "i2c-eeprom"; + reg = <0x50>; + }; +}; -- cgit From aa1cd2cf0914cde392e514e062e03ab617c95a62 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:30:26 +0900 Subject: ARM: UniPhier: set I2C offset length of on-board EEPROM in DTS The EEPROM chips on UniPhier reference daughter boards expect 2-byte offset address. Since 7132b9fd68a1 (dm: i2c: dts: Support an offset-len device tree property), I2C sub-nodes can have "u-boot,i2c-offset-len" property. It is convenient to set the default I2C offset address length in Device Tree, so that we do not have to set it on the command line. Signed-off-by: Masahiro Yamada --- arch/arm/dts/uniphier-ref-daughter.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/dts/uniphier-ref-daughter.dtsi b/arch/arm/dts/uniphier-ref-daughter.dtsi index 33dc20547f..0145b51780 100644 --- a/arch/arm/dts/uniphier-ref-daughter.dtsi +++ b/arch/arm/dts/uniphier-ref-daughter.dtsi @@ -11,5 +11,6 @@ eeprom { compatible = "i2c-eeprom"; reg = <0x50>; + u-boot,i2c-offset-len = <2>; }; }; -- cgit From 84ccd791afd580c35c73be2b395d4a1d3f24200c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:42:54 +0900 Subject: ARM: UniPhier: move pin_init() to board_early_init_f() Currently, I/O pin settings are not necessary for SPL. The board_early_init_f() seems a suitable place to call pin_init(). Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/Makefile | 1 + arch/arm/cpu/armv7/uniphier/board_early_init_f.c | 22 ++++++++++++++++++++++ arch/arm/cpu/armv7/uniphier/board_postclk_init.c | 3 --- arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile | 2 +- arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile | 2 +- arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile | 2 +- include/configs/uniphier.h | 1 + 7 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 arch/arm/cpu/armv7/uniphier/board_early_init_f.c diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index 05462320b5..a681d2d8ea 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -11,6 +11,7 @@ obj-y += cache_uniphier.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o obj-y += dram_init.o obj-$(CONFIG_DRAM_INIT) += ddrphy_training.o +obj-$(CONFIG_BOARD_EARLY_INIT_F) += board_early_init_f.o obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o diff --git a/arch/arm/cpu/armv7/uniphier/board_early_init_f.c b/arch/arm/cpu/armv7/uniphier/board_early_init_f.c new file mode 100644 index 0000000000..d25bbaec08 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/board_early_init_f.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012-2015 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +void pin_init(void); + +int board_early_init_f(void) +{ + led_write(U, 0, , ); + + pin_init(); + + led_write(U, 1, , ); + + return 0; +} diff --git a/arch/arm/cpu/armv7/uniphier/board_postclk_init.c b/arch/arm/cpu/armv7/uniphier/board_postclk_init.c index 89e44bb95b..8deb9f6e08 100644 --- a/arch/arm/cpu/armv7/uniphier/board_postclk_init.c +++ b/arch/arm/cpu/armv7/uniphier/board_postclk_init.c @@ -39,9 +39,6 @@ int board_postclk_init(void) led_write(B, 2, , ); #endif - pin_init(); - - led_write(B, 3, , ); return 0; } diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index 0752906121..af9c86d3b8 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -8,5 +8,5 @@ obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ clkrst_init.o -obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o +obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index 8206e2a354..43949d0331 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -7,5 +7,5 @@ obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o obj-$(CONFIG_SOC_INIT) += sbc_init.o sg_init.o pll_init.o clkrst_init.o -obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o +obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index 0752906121..af9c86d3b8 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -8,5 +8,5 @@ obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ clkrst_init.o -obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o +obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 35bea1a72f..15cb223997 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -95,6 +95,7 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_BOARD_LATE_INIT -- cgit From 35adfc4d259e7985abaffa32cb9578640d09225c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:42:55 +0900 Subject: ARM: UniPhier: move SPL init functions to spl_board_init() Now init functions called from board_postclk_init() and dram_init() are only necessary for SPL. Move them to spl_board_init() for clean-up. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/Makefile | 1 - arch/arm/cpu/armv7/uniphier/board_postclk_init.c | 44 -------------------- arch/arm/cpu/armv7/uniphier/dram_init.c | 23 +---------- arch/arm/cpu/armv7/uniphier/spl.c | 52 +++++++++++++++++++++--- include/configs/uniphier.h | 2 - 5 files changed, 48 insertions(+), 74 deletions(-) delete mode 100644 arch/arm/cpu/armv7/uniphier/board_postclk_init.c diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index a681d2d8ea..86be181cfe 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_SPL_BUILD) += spl.o obj-y += timer.o obj-y += reset.o obj-y += cache_uniphier.o -obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o obj-y += dram_init.o obj-$(CONFIG_DRAM_INIT) += ddrphy_training.o obj-$(CONFIG_BOARD_EARLY_INIT_F) += board_early_init_f.o diff --git a/arch/arm/cpu/armv7/uniphier/board_postclk_init.c b/arch/arm/cpu/armv7/uniphier/board_postclk_init.c deleted file mode 100644 index 8deb9f6e08..0000000000 --- a/arch/arm/cpu/armv7/uniphier/board_postclk_init.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -void __weak bcu_init(void) -{ -}; -void sbc_init(void); -void sg_init(void); -void pll_init(void); -void pin_init(void); -void clkrst_init(void); - -int board_postclk_init(void) -{ -#ifdef CONFIG_SOC_INIT - bcu_init(); - - sbc_init(); - - sg_init(); - - uniphier_board_reset(); - - pll_init(); - - uniphier_board_init(); - - led_write(B, 1, , ); - - clkrst_init(); - - led_write(B, 2, , ); -#endif - - return 0; -} diff --git a/arch/arm/cpu/armv7/uniphier/dram_init.c b/arch/arm/cpu/armv7/uniphier/dram_init.c index 7de657b7af..4b8c938b5e 100644 --- a/arch/arm/cpu/armv7/uniphier/dram_init.c +++ b/arch/arm/cpu/armv7/uniphier/dram_init.c @@ -1,37 +1,16 @@ /* - * Copyright (C) 2012-2014 Panasonic Corporation + * Copyright (C) 2012-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ */ #include -#include - -int umc_init(void); -void enable_dpll_ssc(void); int dram_init(void) { DECLARE_GLOBAL_DATA_PTR; gd->ram_size = CONFIG_SYS_SDRAM_SIZE; -#ifdef CONFIG_DRAM_INIT - led_write(B, 4, , ); - - { - int res; - - res = umc_init(); - if (res < 0) - return res; - } - led_write(B, 5, , ); - - enable_dpll_ssc(); -#endif - - led_write(B, 6, , ); - return 0; } diff --git a/arch/arm/cpu/armv7/uniphier/spl.c b/arch/arm/cpu/armv7/uniphier/spl.c index 40d28adaf3..8a4eafc266 100644 --- a/arch/arm/cpu/armv7/uniphier/spl.c +++ b/arch/arm/cpu/armv7/uniphier/spl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Panasonic Corporation + * Copyright (C) 2013-2015 Panasonic Corporation * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -7,11 +7,53 @@ #include #include +#include +#include +#include + +void __weak bcu_init(void) +{ +}; +void sbc_init(void); +void sg_init(void); +void pll_init(void); +void pin_init(void); +void clkrst_init(void); +int umc_init(void); +void enable_dpll_ssc(void); void spl_board_init(void) { -#if defined(CONFIG_BOARD_POSTCLK_INIT) - board_postclk_init(); -#endif - dram_init(); + bcu_init(); + + sbc_init(); + + sg_init(); + + uniphier_board_reset(); + + pll_init(); + + uniphier_board_init(); + + led_write(L, 0, , ); + + clkrst_init(); + + led_write(L, 1, , ); + + { + int res; + + res = umc_init(); + if (res < 0) { + while (1) + ; + } + } + led_write(L, 2, , ); + + enable_dpll_ssc(); + + led_write(L, 3, , ); } diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 15cb223997..12290ebec6 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -275,8 +275,6 @@ #define CONFIG_SPL_TEXT_BASE 0x00100000 #endif -#define CONFIG_BOARD_POSTCLK_INIT - #ifndef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT #endif -- cgit From 08fda258ee127db50f76d6600cc6bf2268e0a178 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:42:56 +0900 Subject: ARM: UniPhier: revive support card info Since commit 0365ffcc0bd6 (generic-board: show model name in board_init_f() too), the support card information has not been displayed because check_support_card() is invoked only when show_board_info() fails to get the model name from Device Tree. This commit adds misc_init_f() function to call check_support_card() from there. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/Makefile | 1 + arch/arm/cpu/armv7/uniphier/print_misc_info.c | 13 +++++++++++++ include/configs/uniphier.h | 1 + 3 files changed, 15 insertions(+) create mode 100644 arch/arm/cpu/armv7/uniphier/print_misc_info.c diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index 86be181cfe..713a0d74ed 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -12,6 +12,7 @@ obj-y += dram_init.o obj-$(CONFIG_DRAM_INIT) += ddrphy_training.o obj-$(CONFIG_BOARD_EARLY_INIT_F) += board_early_init_f.o obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o +obj-$(CONFIG_MISC_INIT_F) += print_misc_info.o obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o obj-$(CONFIG_UNIPHIER_SMP) += smp.o diff --git a/arch/arm/cpu/armv7/uniphier/print_misc_info.c b/arch/arm/cpu/armv7/uniphier/print_misc_info.c new file mode 100644 index 0000000000..69cfab519f --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/print_misc_info.c @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015 Panasonic Corporation + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +int misc_init_f(void) +{ + return check_support_card(); +} diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 12290ebec6..9420e6b48b 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -95,6 +95,7 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MISC_INIT_F #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_EARLY_INIT_R #define CONFIG_BOARD_LATE_INIT -- cgit From dc4057eb8195e1b89f744ac50a1afd1a03c99395 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:42:57 +0900 Subject: ARM: UniPhier: remove unused checkboard() functions Since commit 0365ffcc0bd6 (generic-board: show model name in board_init_f() too), checkboard() is invoked only when show_board_info() fails to get the model name from Device Tree. It never happens because UniPhier SoCs now only work with CONFIG_OF_CONTROL and all the root nodes of UniPhier device trees have the "model" property. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile | 1 - arch/arm/cpu/armv7/uniphier/ph1-ld4/board_info.c | 16 ---------------- arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile | 1 - arch/arm/cpu/armv7/uniphier/ph1-pro4/board_info.c | 16 ---------------- arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile | 1 - arch/arm/cpu/armv7/uniphier/ph1-sld8/board_info.c | 16 ---------------- 6 files changed, 51 deletions(-) delete mode 100644 arch/arm/cpu/armv7/uniphier/ph1-ld4/board_info.c delete mode 100644 arch/arm/cpu/armv7/uniphier/ph1-pro4/board_info.c delete mode 100644 arch/arm/cpu/armv7/uniphier/ph1-sld8/board_info.c diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index af9c86d3b8..bef1b8ae91 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/board_info.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/board_info.c deleted file mode 100644 index 27d772e8cb..0000000000 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/board_info.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -int checkboard(void) -{ - puts("Board: PH1-LD4 Board\n"); - - return check_support_card(); -} diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index 43949d0331..484e978e2d 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/board_info.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/board_info.c deleted file mode 100644 index 325a4f6160..0000000000 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/board_info.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -int checkboard(void) -{ - puts("Board: PH1-Pro4 Board\n"); - - return check_support_card(); -} diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index af9c86d3b8..bef1b8ae91 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -2,7 +2,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/board_info.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/board_info.c deleted file mode 100644 index 15dc289c01..0000000000 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/board_info.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -int checkboard(void) -{ - puts("Board: PH1-sLD8 Board\n"); - - return check_support_card(); -} -- cgit From 6c45ef4b948abd92f299d4ca1ab99c9cdea6bf8e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:42:58 +0900 Subject: ARM: UniPhier: do not compile unnecessary objects It is true that unused functions are removed from the ELF image by the compiler's garbage collection but relying on it too much does not look nice. Currently, the build is taking more than it should. Refactor the makefiles to compile only files that are really needed. CONFIG_SOC_INIT and CONFIG_DRAM_INIT are no longer needed by the optimization. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/Kconfig | 11 +---------- arch/arm/cpu/armv7/uniphier/Makefile | 24 ++++++++++++++++-------- arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile | 13 ++++++++----- arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile | 12 ++++++++---- arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile | 13 ++++++++----- 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/arch/arm/cpu/armv7/uniphier/Kconfig b/arch/arm/cpu/armv7/uniphier/Kconfig index 0556e4b350..5c5a84fe56 100644 --- a/arch/arm/cpu/armv7/uniphier/Kconfig +++ b/arch/arm/cpu/armv7/uniphier/Kconfig @@ -50,21 +50,12 @@ endchoice config CMD_PINMON bool "Enable boot mode pins monitor command" - depends on !SPL_BUILD default y help The command "pinmon" shows the state of the boot mode pins. The boot mode pins are latched when the system reset is deasserted and determine which device the system should load a boot image from. -config SOC_INIT - bool - default SPL_BUILD - -config DRAM_INIT - bool - default SPL_BUILD - config CMD_DDRPHY_DUMP bool "Enable dump command of DDR PHY parameters" depends on !SPL_BUILD @@ -74,7 +65,7 @@ config CMD_DDRPHY_DUMP choice prompt "DDR3 Frequency select" - depends on DRAM_INIT + depends on SPL_BUILD config DDR_FREQ_1600 bool "DDR3 1600" diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index 713a0d74ed..df418dd3c4 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -2,24 +2,32 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_SPL_BUILD) += lowlevel_init.o init_page_table.o -obj-$(CONFIG_SPL_BUILD) += spl.o +ifdef CONFIG_SPL_BUILD + +obj-y += lowlevel_init.o +obj-y += init_page_table.o +obj-y += spl.o +obj-y += ddrphy_training.o + +else -obj-y += timer.o -obj-y += reset.o -obj-y += cache_uniphier.o -obj-y += dram_init.o -obj-$(CONFIG_DRAM_INIT) += ddrphy_training.o obj-$(CONFIG_BOARD_EARLY_INIT_F) += board_early_init_f.o obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o obj-$(CONFIG_MISC_INIT_F) += print_misc_info.o +obj-y += dram_init.o +obj-y += board_common.o obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o +obj-y += reset.o +obj-y += cache_uniphier.o obj-$(CONFIG_UNIPHIER_SMP) += smp.o obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o -obj-y += board_common.o +endif + +obj-y += timer.o + obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += support_card.o obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += support_card.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index bef1b8ae91..72f46636fd 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -2,10 +2,13 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o -obj-y += boot-mode.o +ifdef CONFIG_SPL_BUILD obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ - clkrst_init.o +obj-y += bcu_init.o sbc_init.o sg_init.o pll_init.o clkrst_init.o \ + pll_spectrum.o umc_init.o ddrphy_init.o +else obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o +obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o +endif + +obj-y += boot-mode.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index 484e978e2d..e330fda1ed 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -2,9 +2,13 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o -obj-y += boot-mode.o +ifdef CONFIG_SPL_BUILD obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-$(CONFIG_SOC_INIT) += sbc_init.o sg_init.o pll_init.o clkrst_init.o +obj-y += sbc_init.o sg_init.o pll_init.o clkrst_init.o \ + pll_spectrum.o umc_init.o ddrphy_init.o +else obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o +obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o +endif + +obj-y += boot-mode.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index bef1b8ae91..72f46636fd 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -2,10 +2,13 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o -obj-y += boot-mode.o +ifdef CONFIG_SPL_BUILD obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o -obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ - clkrst_init.o +obj-y += bcu_init.o sbc_init.o sg_init.o pll_init.o clkrst_init.o \ + pll_spectrum.o umc_init.o ddrphy_init.o +else obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o +obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o +endif + +obj-y += boot-mode.o -- cgit From ee470645d169cd0f47f66be8c8f69e061e3665d4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 14:43:00 +0900 Subject: ARM: UniPhier: enable I2C input pins for PH1-sLD8 To use I2C controllers on PH1-sLD8, the bit 10 (SCL0/SDA0) and bit 11 (SCL1/SDA1) of IECTRL register must be set. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/ph1-sld8/pinctrl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/pinctrl.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/pinctrl.c index 2b6403f88f..5e80335b58 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/pinctrl.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/pinctrl.c @@ -26,6 +26,15 @@ void pin_init(void) sg_set_pinsel(111, 1); /* SBI0 -> RXD3 */ #endif +#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 */ -- cgit From 4431684910217022bad85a0bc931ad9bfb78859f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 20:56:23 +0900 Subject: ARM: UniPhier: refactor pinmon command The return value of get_boot_mode_sel() is used as the index of the boot_device_table[] array. Its type should be "int" rather than "u32". Use only the iterator "i" for the loop in do_pinmon(). Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/cmd_pinmon.c | 15 ++++++--------- arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c | 4 ++-- arch/arm/include/asm/arch-uniphier/boot-device.h | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c index 3561b40a33..d8a6361a46 100644 --- a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c +++ b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c @@ -11,20 +11,17 @@ static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - struct boot_device_info *table; - u32 mode_sel, n = 0; - - mode_sel = get_boot_mode_sel(); + 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 (table = boot_device_table; strlen(table->info); table++) { - printf(" %c %02x %s\n", n == mode_sel ? '*' : ' ', n, - table->info); - n++; - } + for (i = 0; strlen(boot_device_table[i].info); i++) + printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, + boot_device_table[i].info); return 0; } diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c index 33bccff2a5..90d41865e9 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c @@ -48,14 +48,14 @@ struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, ""} }; -u32 get_boot_mode_sel(void) +int get_boot_mode_sel(void) { return (readl(SG_PINMON0) >> 1) & 0x1f; } u32 spl_boot_device(void) { - u32 boot_mode; + int boot_mode; if (boot_is_swapped()) return BOOT_DEVICE_NOR; diff --git a/arch/arm/include/asm/arch-uniphier/boot-device.h b/arch/arm/include/asm/arch-uniphier/boot-device.h index 6987f57669..7a10f1c5b2 100644 --- a/arch/arm/include/asm/arch-uniphier/boot-device.h +++ b/arch/arm/include/asm/arch-uniphier/boot-device.h @@ -8,7 +8,7 @@ #ifndef _ASM_BOOT_DEVICE_H_ #define _ASM_BOOT_DEVICE_H_ -u32 get_boot_mode_sel(void); +int get_boot_mode_sel(void); struct boot_device_info { u32 type; -- cgit From 4e79908044e4ebf186464cf118497458faf0903c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 20:56:24 +0900 Subject: ARM: UniPhier: leave the last element of boot_device_table empty Checking if the pointer is NULL would be easier to know the tail of the boot_device_table[] array. For clarification, add the /* sentinel */ comment. Signed-off-by: Masahiro Yamada --- arch/arm/cpu/armv7/uniphier/cmd_pinmon.c | 2 +- arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c index d8a6361a46..3c1b325976 100644 --- a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c +++ b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c @@ -19,7 +19,7 @@ static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) puts("Boot Mode Pin:\n"); - for (i = 0; strlen(boot_device_table[i].info); i++) + for (i = 0; boot_device_table[i].info; i++) printf(" %c %02x %s\n", i == mode_sel ? '*' : ' ', i, boot_device_table[i].info); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c index 90d41865e9..c31b74badd 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/boot-mode.c @@ -45,7 +45,7 @@ struct boot_device_info boot_device_table[] = { {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, {BOOT_DEVICE_NONE, "Reserved"}, - {BOOT_DEVICE_NONE, ""} + { /* sentinel */ } }; int get_boot_mode_sel(void) -- cgit From 815451e0d12e72ea47b0ca2eb4ac610823bfb40c Mon Sep 17 00:00:00 2001 From: DrEagle Date: Wed, 17 Dec 2014 15:02:44 +0100 Subject: kirkwood: sheevaplug: fix style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gérald Kerma Reviewed-by: Luka Perkov --- include/configs/sheevaplug.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index 21c8bda9f3..3ebc989638 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -51,6 +51,7 @@ #define CONFIG_CMD_NAND #define CONFIG_CMD_PING #define CONFIG_CMD_USB + /* * mv-common.h should be defined after CMD configs since it used them * to enable certain macros -- cgit From 7f30f4b5b285cb91e1e25b5b61a04beabe8c470b Mon Sep 17 00:00:00 2001 From: DrEagle Date: Wed, 17 Dec 2014 15:02:45 +0100 Subject: kirkwood: sheevaplug: fix multiple defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gérald Kerma Reviewed-by: Luka Perkov --- include/configs/sheevaplug.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index 3ebc989638..589655ab19 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -142,6 +142,5 @@ #define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ #define CONFIG_MTD_PARTITIONS #define CONFIG_CMD_MTDPARTS -#define CONFIG_LZO #endif /* _CONFIG_SHEEVAPLUG_H */ -- cgit From 9a5e0a7d5bd0e1758fcc59db524c1695d0dab7e0 Mon Sep 17 00:00:00 2001 From: DrEagle Date: Wed, 17 Dec 2014 15:02:48 +0100 Subject: kirkwood: sheevaplug: add FDT support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LIBFDT feature is required to support new kernels. Signed-off-by: Gérald Kerma Reviewed-by: Luka Perkov --- include/configs/sheevaplug.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index 589655ab19..84029cb399 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -32,6 +32,11 @@ #define CONFIG_LZMA #define CONFIG_LZO +/* + * Enable device tree support + */ +#define CONFIG_OF_LIBFDT + /* * Miscellaneous configurable options */ -- cgit From 1e0b5984f4d985f66ca06ed877dca91bf442fe4d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:49 +0100 Subject: arm: armada-xp: Change built target to include the SPL binary as bin_hdr Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- arch/arm/include/asm/arch-armada-xp/config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/include/asm/arch-armada-xp/config.h b/arch/arm/include/asm/arch-armada-xp/config.h index 00ee775a45..f9fd424609 100644 --- a/arch/arm/include/asm/arch-armada-xp/config.h +++ b/arch/arm/include/asm/arch-armada-xp/config.h @@ -31,7 +31,11 @@ #endif /* CONFIG_SYS_KWD_CONFIG */ /* Add target to build it automatically upon "make" */ +#ifdef CONFIG_SPL +#define CONFIG_BUILD_TARGET "u-boot-spl.kwb" +#else #define CONFIG_BUILD_TARGET "u-boot.kwb" +#endif /* end of 16M scrubbed by training in bootrom */ #define CONFIG_SYS_INIT_SP_ADDR 0x00FF0000 -- cgit From 2f20aa82f470c0f6b5592914b9c4c3fd07bcb722 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:48 +0100 Subject: arm: mvebu: Placeholder bin_hdr file can now be removed With this patchset the Marvell bin_hdr (DDR training) code is intergrated into mainline U-Boot. We can remove the placeholder file again, which was only introduced to make U-Boot compile and link again. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- board/Marvell/db-mv784mp-gp/binary.0 | 17 ----------------- board/maxbcm/binary.0 | 17 ----------------- 2 files changed, 34 deletions(-) delete mode 100644 board/Marvell/db-mv784mp-gp/binary.0 delete mode 100644 board/maxbcm/binary.0 diff --git a/board/Marvell/db-mv784mp-gp/binary.0 b/board/Marvell/db-mv784mp-gp/binary.0 deleted file mode 100644 index 17bfad99dc..0000000000 --- a/board/Marvell/db-mv784mp-gp/binary.0 +++ /dev/null @@ -1,17 +0,0 @@ --------- -WARNING: --------- -This file should contain the bin_hdr generated by the original Marvell -U-Boot implementation. As this is currently not included in this -U-Boot version, we have added this placeholder, so that the U-Boot -image can be generated without errors. - -If you have a known to be working bin_hdr for your board, then you -just need to replace this text file here with the binary header -and recompile U-Boot. - -In a few weeks, mainline U-Boot will get support to generate the -bin_hdr with the DDR training code itself. By implementing this code -as SPL U-Boot. Then this file will not be needed any more and will -get removed. - diff --git a/board/maxbcm/binary.0 b/board/maxbcm/binary.0 deleted file mode 100644 index 17bfad99dc..0000000000 --- a/board/maxbcm/binary.0 +++ /dev/null @@ -1,17 +0,0 @@ --------- -WARNING: --------- -This file should contain the bin_hdr generated by the original Marvell -U-Boot implementation. As this is currently not included in this -U-Boot version, we have added this placeholder, so that the U-Boot -image can be generated without errors. - -If you have a known to be working bin_hdr for your board, then you -just need to replace this text file here with the binary header -and recompile U-Boot. - -In a few weeks, mainline U-Boot will get support to generate the -bin_hdr with the DDR training code itself. By implementing this code -as SPL U-Boot. Then this file will not be needed any more and will -get removed. - -- cgit From e7778ec153e279e451bf7c55c05c76e76b095875 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:47 +0100 Subject: arm: maxbcm: Enable SPL to include DDR training code into U-Boot This patch adds SPL support to the maxbcm MV78460 based board. Including the fixed DDR configuratrion needed for the DDR training code. And the the serdes PHY init code. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- arch/arm/Kconfig | 1 + arch/arm/include/asm/arch-armada-xp/cpu.h | 3 ++ board/maxbcm/kwbimage.cfg | 2 +- board/maxbcm/maxbcm.c | 83 ++++++++++++++++++++++++++++++- configs/maxbcm_defconfig | 5 +- include/configs/maxbcm.h | 47 +++++++++++++++++ 6 files changed, 136 insertions(+), 5 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 986b4c5d81..27b38df344 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -240,6 +240,7 @@ config TARGET_DB_MV784MP_GP config TARGET_MAXBCM bool "Support maxbcm" select CPU_V7 + select SUPPORT_SPL config TARGET_DEVKIT3250 bool "Support devkit3250" diff --git a/arch/arm/include/asm/arch-armada-xp/cpu.h b/arch/arm/include/asm/arch-armada-xp/cpu.h index 6b60c21ceb..43417992b4 100644 --- a/arch/arm/include/asm/arch-armada-xp/cpu.h +++ b/arch/arm/include/asm/arch-armada-xp/cpu.h @@ -96,6 +96,9 @@ struct kwgpio_registers { u32 irq_level; }; +/* Needed for dynamic (board-specific) mbus configuration */ +extern struct mvebu_mbus_state mbus_state; + /* * functions */ diff --git a/board/maxbcm/kwbimage.cfg b/board/maxbcm/kwbimage.cfg index 5a3bc67c1c..cc05792556 100644 --- a/board/maxbcm/kwbimage.cfg +++ b/board/maxbcm/kwbimage.cfg @@ -9,4 +9,4 @@ VERSION 1 BOOT_FROM spi # Binary Header (bin_hdr) with DDR3 training code -BINARY board/maxbcm/binary.0 0000005b 00000068 +BINARY spl/u-boot-spl.bin 0000005b 00000068 diff --git a/board/maxbcm/maxbcm.c b/board/maxbcm/maxbcm.c index 7fc83ee820..a833cc3501 100644 --- a/board/maxbcm/maxbcm.c +++ b/board/maxbcm/maxbcm.c @@ -11,6 +11,9 @@ #include #include +#include "../drivers/ddr/mvebu/ddr3_hw_training.h" +#include "../arch/arm/mvebu-common/serdes/high_speed_env_spec.h" + DECLARE_GLOBAL_DATA_PTR; /* Base addresses for the external device chip selects */ @@ -19,8 +22,84 @@ DECLARE_GLOBAL_DATA_PTR; #define DEV_CS2_BASE 0xe2000000 #define DEV_CS3_BASE 0xe3000000 -/* Needed for dynamic (board-specific) mbus configuration */ -extern struct mvebu_mbus_state mbus_state; +/* DDR3 static configuration */ +MV_DRAM_MC_INIT ddr3_b0_maxbcm[MV_MAX_DDR3_STATIC_SIZE] = { + {0x00001400, 0x7301CC30}, /* DDR SDRAM Configuration Register */ + {0x00001404, 0x30000820}, /* Dunit Control Low Register */ + {0x00001408, 0x5515BAAB}, /* DDR SDRAM Timing (Low) Register */ + {0x0000140C, 0x38DA3F97}, /* DDR SDRAM Timing (High) Register */ + {0x00001410, 0x20100005}, /* DDR SDRAM Address Control Register */ + {0x00001414, 0x0000F3FF}, /* DDR SDRAM Open Pages Control Reg */ + {0x00001418, 0x00000e00}, /* DDR SDRAM Operation Register */ + {0x0000141C, 0x00000672}, /* DDR SDRAM Mode Register */ + {0x00001420, 0x00000004}, /* DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0000F3FF}, /* Dunit Control High Register */ + {0x00001428, 0x0011A940}, /* Dunit Control High Register */ + {0x0000142C, 0x014C5134}, /* Dunit Control High Register */ + {0x0000147C, 0x0000D771}, + + {0x00001494, 0x00010000}, /* DDR SDRAM ODT Control (Low) Reg */ + {0x0000149C, 0x00000001}, /* DDR Dunit ODT Control Register */ + {0x000014A0, 0x00000001}, + {0x000014A8, 0x00000101}, + + /* Recommended Settings from Marvell for 4 x 16 bit devices: */ + {0x000014C0, 0x192424C9}, /* DRAM addr and Ctrl Driving Strenght*/ + {0x000014C4, 0xAAA24C9}, /* DRAM Data and DQS Driving Strenght */ + + /* + * DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the + * training sequence + */ + {0x000200e8, 0x3FFF0E01}, + {0x00020184, 0x3FFFFFE0}, /* Close fast path Window to - 2G */ + + {0x0001504, 0x3FFFFFE1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + {0x0020220, 0x00000007}, /* Reserved */ + + {0x00001538, 0x0000000B}, /* Read Data Sample Delays Register */ + {0x0000153C, 0x0000000B}, /* Read Data Ready Delay Register */ + + {0x000015D0, 0x00000670}, /* MR0 */ + {0x000015D4, 0x00000044}, /* MR1 */ + {0x000015D8, 0x00000018}, /* MR2 */ + {0x000015DC, 0x00000000}, /* MR3 */ + {0x000015E0, 0x00000001}, + {0x000015E4, 0x00203c18}, /* ZQDS Configuration Register */ + {0x000015EC, 0xF800A225}, /* DDR PHY */ + + {0x0, 0x0} +}; + +MV_DRAM_MODES maxbcm_ddr_modes[MV_DDR3_MODES_NUMBER] = { + {"maxbcm_1600-800", 0xB, 0x5, 0x0, A0, ddr3_b0_maxbcm, NULL}, +}; + +extern MV_SERDES_CHANGE_M_PHY serdes_change_m_phy[]; + +/* MAXBCM: SERDES 0-4 PCIE, Serdes 7 = SGMII 0, all others = unconnected */ +MV_BIN_SERDES_CFG maxbcm_serdes_cfg[] = { + { MV_PEX_ROOT_COMPLEX, 0x20011111, 0x00000000, + { PEX_BUS_MODE_X1, PEX_BUS_MODE_X1, PEX_BUS_DISABLED, + PEX_BUS_DISABLED }, + 0x1f, serdes_change_m_phy + } +}; + +MV_DRAM_MODES *ddr3_get_static_ddr_mode(void) +{ + /* Only one mode supported for this board */ + return &maxbcm_ddr_modes[0]; +} + +MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +{ + return &maxbcm_serdes_cfg[0]; +} int board_early_init_f(void) { diff --git a/configs/maxbcm_defconfig b/configs/maxbcm_defconfig index 4bcffd8c2d..219586a27d 100644 --- a/configs/maxbcm_defconfig +++ b/configs/maxbcm_defconfig @@ -1,2 +1,3 @@ -CONFIG_ARM=y -CONFIG_TARGET_MAXBCM=y +CONFIG_SPL=y ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_MAXBCM=y diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 72217bdb57..4e962a3604 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -65,4 +65,51 @@ */ #include "mv-common.h" +/* + * Memory layout while starting into the bin_hdr via the + * BootROM: + * + * 0x4000.4000 - 0x4003.4000 headers space (192KiB) + * 0x4000.4030 bin_hdr start address + * 0x4003.4000 - 0x4004.7c00 BootROM memory allocations (15KiB) + * 0x4007.fffc BootROM stack top + * + * The address space between 0x4007.fffc and 0x400f.fff is not locked in + * L2 cache thus cannot be used. + */ + +/* SPL */ +/* Defines for SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x40004030 +#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030) + +#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10)) +#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10) + +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \ + CONFIG_SPL_BSS_MAX_SIZE) +#define CONFIG_SYS_SPL_MALLOC_SIZE (16 << 10) + +#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10)) +#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4) + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_LDSCRIPT "arch/arm/mvebu-common/u-boot-spl.lds" + +/* SPL related SPI defines */ +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 + +/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */ +#define CONFIG_SYS_MVEBU_DDR +#define CONFIG_DDR_FIXED_SIZE (1 << 20) /* 1GiB */ + #endif /* _CONFIG_DB_MV7846MP_GP_H */ -- cgit From 2554167cc158001cd1befb93e10829fc534bfada Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:46 +0100 Subject: arm: db-mv784mp-gp: Enable SPL to include DDR training code into U-Boot This patch adds SPL support to the db-mv784mp-gp eval board. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- arch/arm/Kconfig | 1 + board/Marvell/db-mv784mp-gp/kwbimage.cfg | 2 +- configs/db-mv784mp-gp_defconfig | 5 ++-- include/configs/db-mv784mp-gp.h | 49 ++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 27b38df344..47806f85da 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -236,6 +236,7 @@ config KIRKWOOD config TARGET_DB_MV784MP_GP bool "Support db-mv784mp-gp" select CPU_V7 + select SUPPORT_SPL config TARGET_MAXBCM bool "Support maxbcm" diff --git a/board/Marvell/db-mv784mp-gp/kwbimage.cfg b/board/Marvell/db-mv784mp-gp/kwbimage.cfg index d7ef4071dd..cc05792556 100644 --- a/board/Marvell/db-mv784mp-gp/kwbimage.cfg +++ b/board/Marvell/db-mv784mp-gp/kwbimage.cfg @@ -9,4 +9,4 @@ VERSION 1 BOOT_FROM spi # Binary Header (bin_hdr) with DDR3 training code -BINARY board/Marvell/db-mv784mp-gp/binary.0 0000005b 00000068 +BINARY spl/u-boot-spl.bin 0000005b 00000068 diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig index 7aa216c47d..a7f13e2132 100644 --- a/configs/db-mv784mp-gp_defconfig +++ b/configs/db-mv784mp-gp_defconfig @@ -1,2 +1,3 @@ -CONFIG_ARM=y -CONFIG_TARGET_DB_MV784MP_GP=y +CONFIG_SPL=y ++S:CONFIG_ARM=y ++S:CONFIG_TARGET_DB_MV784MP_GP=y diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index cb03e33b6e..1683a1582f 100644 --- a/include/configs/db-mv784mp-gp.h +++ b/include/configs/db-mv784mp-gp.h @@ -11,6 +11,8 @@ * High Level Configuration Options (easy to change) */ #define CONFIG_ARMADA_XP /* SOC Family Name */ +#define CONFIG_DB_784MP_GP /* Board target name for DDR training */ + #define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ #define CONFIG_SYS_GENERIC_BOARD #define CONFIG_DISPLAY_BOARDINFO_LATE @@ -65,4 +67,51 @@ */ #include "mv-common.h" +/* + * Memory layout while starting into the bin_hdr via the + * BootROM: + * + * 0x4000.4000 - 0x4003.4000 headers space (192KiB) + * 0x4000.4030 bin_hdr start address + * 0x4003.4000 - 0x4004.7c00 BootROM memory allocations (15KiB) + * 0x4007.fffc BootROM stack top + * + * The address space between 0x4007.fffc and 0x400f.fff is not locked in + * L2 cache thus cannot be used. + */ + +/* SPL */ +/* Defines for SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x40004030 +#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030) + +#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10)) +#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10) + +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \ + CONFIG_SPL_BSS_MAX_SIZE) +#define CONFIG_SYS_SPL_MALLOC_SIZE (16 << 10) + +#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10)) +#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4) + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_LDSCRIPT "arch/arm/mvebu-common/u-boot-spl.lds" + +/* SPL related SPI defines */ +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 + +/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */ +#define CONFIG_SYS_MVEBU_DDR +#define CONFIG_SPD_EEPROM 0x4e + #endif /* _CONFIG_DB_MV7846MP_GP_H */ -- cgit From a90ffb5632ad7eaba514500c1a2593af96378c1e Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:45 +0100 Subject: Makefile: Add another kwb build target used on Marvell Armada-XP (AXP) This build target now includes the SPL binary as the bin_hdr into the kwb image. Its used on the AXP port with the mainlined DDR training code. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 92faed63fd..76bae8b6d5 100644 --- a/Makefile +++ b/Makefile @@ -856,12 +856,18 @@ MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \ MKIMAGEFLAGS_u-boot.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \ -T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) +MKIMAGEFLAGS_u-boot-spl.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \ + -T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) + MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \ -R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage u-boot.img u-boot.kwb u-boot.pbl: u-boot.bin FORCE $(call if_changed,mkimage) +u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + MKIMAGEFLAGS_u-boot-dtb.img = $(MKIMAGEFLAGS_u-boot.img) u-boot-dtb.img: u-boot-dtb.bin FORCE -- cgit From 5632e580c652eb600f3ff48dd79a71394c03dbe5 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:44 +0100 Subject: tools: kwbimage: Support u-boot.img padding to CONFIG_SYS_SPI_U_BOOT_OFFS This is used on the AXP boards, to pad u-boot.img to the desired offset in SPI flash (only this boot target supported right now). This offset is used by the SPL then to load u-boot.img into SDRAM and execute it there. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- tools/kwbimage.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 66f459ad6b..28ce1e4f08 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -16,6 +16,7 @@ #include #include #include "kwbimage.h" +#include #define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1)) @@ -868,6 +869,16 @@ static int kwbimage_generate(struct image_tool_params *params, sizeof(struct ext_hdr_v0); } else { alloc_len = image_headersz_v1(params, NULL); +#if defined(CONFIG_SYS_SPI_U_BOOT_OFFS) + if (alloc_len > CONFIG_SYS_SPI_U_BOOT_OFFS) { + fprintf(stderr, "Error: Image header (incl. SPL image) too big!\n"); + fprintf(stderr, "header=0x%x CONFIG_SYS_SPI_U_BOOT_OFFS=0x%x!\n", + alloc_len, CONFIG_SYS_SPI_U_BOOT_OFFS); + fprintf(stderr, "Increase CONFIG_SYS_SPI_U_BOOT_OFFS!\n"); + } else { + alloc_len = CONFIG_SYS_SPI_U_BOOT_OFFS; + } +#endif } hdr = malloc(alloc_len); -- cgit From 0cf47862bf647690762c841e247fb5b097ca7316 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:43 +0100 Subject: scripts/Makefile.spl: Add MVEBU DDR code to SPL Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- scripts/Makefile.spl | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index ecf3037cb8..e4b9881186 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -57,6 +57,7 @@ libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/ libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/ libs-$(CONFIG_SPL_MMC_SUPPORT) += drivers/mmc/ libs-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += drivers/ddr/fsl/ +libs-$(CONFIG_SYS_MVEBU_DDR) += drivers/ddr/mvebu/ libs-$(CONFIG_SPL_SERIAL_SUPPORT) += drivers/serial/ libs-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/ libs-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/ -- cgit From b0f80b913f5a8aec8ba75093328ac17d178c3b95 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:42 +0100 Subject: arm: armada-xp: Add SPL support used to include the DDR training code This patch adds SPL support to the Marvell Armada-XP. With this addition the bin_hdr integration is not needed any more. The SPL will first initialize the serdes/PHY and the call the DDR setup and training code now integrated into mainline U-Boot. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- arch/arm/cpu/armv7/armada-xp/Makefile | 2 + arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S | 62 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/armada-xp/spl.c | 38 ++++++++++++++++++ arch/arm/include/asm/arch-armada-xp/cpu.h | 13 ++++++ arch/arm/mvebu-common/u-boot-spl.lds | 57 ++++++++++++++++++++++++++ 5 files changed, 172 insertions(+) create mode 100644 arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S create mode 100644 arch/arm/cpu/armv7/armada-xp/spl.c create mode 100644 arch/arm/mvebu-common/u-boot-spl.lds diff --git a/arch/arm/cpu/armv7/armada-xp/Makefile b/arch/arm/cpu/armv7/armada-xp/Makefile index 885dcee2e1..737159ba12 100644 --- a/arch/arm/cpu/armv7/armada-xp/Makefile +++ b/arch/arm/cpu/armv7/armada-xp/Makefile @@ -5,3 +5,5 @@ # obj-y = cpu.o +obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_SPL_BUILD) += lowlevel_spl.o diff --git a/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S b/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S new file mode 100644 index 0000000000..1febd7bac5 --- /dev/null +++ b/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S @@ -0,0 +1,62 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +ENTRY(save_boot_params) + bx lr +ENDPROC(save_boot_params) + +/* + * cache_inv - invalidate Cache line + * r0 - dest + */ + .global cache_inv + .type cache_inv, %function + cache_inv: + + stmfd sp!, {r1-r12} + + mcr p15, 0, r0, c7, c6, 1 + + ldmfd sp!, {r1-r12} + bx lr + + +/* + * flush_l1_v6 - l1 cache clean invalidate + * r0 - dest + */ + .global flush_l1_v6 + .type flush_l1_v6, %function + flush_l1_v6: + + stmfd sp!, {r1-r12} + + mcr p15, 0, r0, c7, c10, 5 /* @ data memory barrier */ + mcr p15, 0, r0, c7, c14, 1 /* @ clean & invalidate D line */ + mcr p15, 0, r0, c7, c10, 4 /* @ data sync barrier */ + + ldmfd sp!, {r1-r12} + bx lr + + +/* + * flush_l1_v7 - l1 cache clean invalidate + * r0 - dest + */ + .global flush_l1_v7 + .type flush_l1_v7, %function + flush_l1_v7: + + stmfd sp!, {r1-r12} + + dmb /* @data memory barrier */ + mcr p15, 0, r0, c7, c14, 1 /* @ clean & invalidate D line */ + dsb /* @data sync barrier */ + + ldmfd sp!, {r1-r12} + bx lr diff --git a/arch/arm/cpu/armv7/armada-xp/spl.c b/arch/arm/cpu/armv7/armada-xp/spl.c new file mode 100644 index 0000000000..402e520ea9 --- /dev/null +++ b/arch/arm/cpu/armv7/armada-xp/spl.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +u32 spl_boot_device(void) +{ + /* Right now only booting via SPI NOR flash is supported */ + return BOOT_DEVICE_SPI; +} + +void board_init_f(ulong dummy) +{ + /* Set global data pointer */ + gd = &gdata; + + /* Linux expects the internal registers to be at 0xf1000000 */ + arch_cpu_init(); + + preloader_console_init(); + + /* First init the serdes PHY's */ + serdes_phy_config(); + + /* Setup DDR */ + ddr3_init(); + + board_init_r(NULL, 0); +} diff --git a/arch/arm/include/asm/arch-armada-xp/cpu.h b/arch/arm/include/asm/arch-armada-xp/cpu.h index 43417992b4..4f5ff96d84 100644 --- a/arch/arm/include/asm/arch-armada-xp/cpu.h +++ b/arch/arm/include/asm/arch-armada-xp/cpu.h @@ -106,5 +106,18 @@ unsigned int mvebu_sdram_bar(enum memory_bank bank); unsigned int mvebu_sdram_bs(enum memory_bank bank); void mvebu_sdram_size_adjust(enum memory_bank bank); int mvebu_mbus_probe(struct mbus_win windows[], int count); + +/* + * Highspeed SERDES PHY config init, ported from bin_hdr + * to mainline U-Boot + */ +int serdes_phy_config(void); + +/* + * DDR3 init / training code ported from Marvell bin_hdr. Now + * available in mainline U-Boot in: + * drivers/ddr/mvebu/ + */ +int ddr3_init(void); #endif /* __ASSEMBLY__ */ #endif /* _ARMADA_XP_CPU_H */ diff --git a/arch/arm/mvebu-common/u-boot-spl.lds b/arch/arm/mvebu-common/u-boot-spl.lds new file mode 100644 index 0000000000..eee1db49ee --- /dev/null +++ b/arch/arm/mvebu-common/u-boot-spl.lds @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2010 + * Texas Instruments, + * Aneesh V + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + *(.vectors) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*_i2c_*))); + } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +} -- cgit From 2e19cc316f38c56e3bbc127491bc8722c1b0386c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:41 +0100 Subject: arm: mvebu: Add Serdes PHY config code This code is ported from the Marvell bin_hdr code into mainline SPL U-Boot. It needs to be executed very early so that the devices connected to the serdes PHY are configured correctly. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- arch/arm/mvebu-common/Makefile | 2 + arch/arm/mvebu-common/serdes/Makefile | 6 + arch/arm/mvebu-common/serdes/board_env_spec.h | 262 ++++ arch/arm/mvebu-common/serdes/high_speed_env_lib.c | 1572 ++++++++++++++++++++ arch/arm/mvebu-common/serdes/high_speed_env_spec.c | 185 +++ arch/arm/mvebu-common/serdes/high_speed_env_spec.h | 87 ++ 6 files changed, 2114 insertions(+) create mode 100644 arch/arm/mvebu-common/serdes/Makefile create mode 100644 arch/arm/mvebu-common/serdes/board_env_spec.h create mode 100644 arch/arm/mvebu-common/serdes/high_speed_env_lib.c create mode 100644 arch/arm/mvebu-common/serdes/high_speed_env_spec.c create mode 100644 arch/arm/mvebu-common/serdes/high_speed_env_spec.h diff --git a/arch/arm/mvebu-common/Makefile b/arch/arm/mvebu-common/Makefile index 9dcab6958c..de243feaab 100644 --- a/arch/arm/mvebu-common/Makefile +++ b/arch/arm/mvebu-common/Makefile @@ -10,3 +10,5 @@ obj-y = dram.o obj-y += gpio.o obj-$(CONFIG_ARMADA_XP) += mbus.o obj-y += timer.o + +obj-y += serdes/ diff --git a/arch/arm/mvebu-common/serdes/Makefile b/arch/arm/mvebu-common/serdes/Makefile new file mode 100644 index 0000000000..a380fee144 --- /dev/null +++ b/arch/arm/mvebu-common/serdes/Makefile @@ -0,0 +1,6 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SPL_BUILD) = high_speed_env_lib.o +obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec.o diff --git a/arch/arm/mvebu-common/serdes/board_env_spec.h b/arch/arm/mvebu-common/serdes/board_env_spec.h new file mode 100644 index 0000000000..36e0ed80f0 --- /dev/null +++ b/arch/arm/mvebu-common/serdes/board_env_spec.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __BOARD_ENV_SPEC +#define __BOARD_ENV_SPEC + +/* Board specific configuration */ + +/* KW40 */ +#define MV_6710_DEV_ID 0x6710 + +#define MV_6710_Z1_REV 0x0 +#define MV_6710_Z1_ID ((MV_6710_DEV_ID << 16) | MV_6710_Z1_REV) +#define MV_6710_Z1_NAME "MV6710 Z1" + +/* Armada XP Family */ +#define MV_78130_DEV_ID 0x7813 +#define MV_78160_DEV_ID 0x7816 +#define MV_78230_DEV_ID 0x7823 +#define MV_78260_DEV_ID 0x7826 +#define MV_78460_DEV_ID 0x7846 +#define MV_78000_DEV_ID 0x7888 + +#define MV_FPGA_DEV_ID 0x2107 + +#define MV_78XX0_Z1_REV 0x0 + +/* boards ID numbers */ +#define BOARD_ID_BASE 0x0 + +/* New board ID numbers */ +#define DB_88F78XX0_BP_ID (BOARD_ID_BASE) +#define RD_78460_SERVER_ID (DB_88F78XX0_BP_ID + 1) +#define DB_78X60_PCAC_ID (RD_78460_SERVER_ID + 1) +#define FPGA_88F78XX0_ID (DB_78X60_PCAC_ID + 1) +#define DB_88F78XX0_BP_REV2_ID (FPGA_88F78XX0_ID + 1) +#define RD_78460_NAS_ID (DB_88F78XX0_BP_REV2_ID + 1) +#define DB_78X60_AMC_ID (RD_78460_NAS_ID + 1) +#define DB_78X60_PCAC_REV2_ID (DB_78X60_AMC_ID + 1) +#define RD_78460_SERVER_REV2_ID (DB_78X60_PCAC_REV2_ID + 1) +#define DB_784MP_GP_ID (RD_78460_SERVER_REV2_ID + 1) +#define RD_78460_CUSTOMER_ID (DB_784MP_GP_ID + 1) +#define MV_MAX_BOARD_ID (RD_78460_CUSTOMER_ID + 1) +#define INVALID_BAORD_ID 0xFFFFFFFF + +/* Sample at Reset */ +#define MPP_SAMPLE_AT_RESET(id) (0x18230 + (id * 4)) + +/* BIOS Modes related defines */ + +#define SAR0_BOOTWIDTH_OFFSET 3 +#define SAR0_BOOTWIDTH_MASK (0x3 << SAR0_BOOTWIDTH_OFFSET) +#define SAR0_BOOTSRC_OFFSET 5 +#define SAR0_BOOTSRC_MASK (0xF << SAR0_BOOTSRC_OFFSET) + +#define SAR0_L2_SIZE_OFFSET 19 +#define SAR0_L2_SIZE_MASK (0x3 << SAR0_L2_SIZE_OFFSET) +#define SAR0_CPU_FREQ_OFFSET 21 +#define SAR0_CPU_FREQ_MASK (0x7 << SAR0_CPU_FREQ_OFFSET) +#define SAR0_FABRIC_FREQ_OFFSET 24 +#define SAR0_FABRIC_FREQ_MASK (0xF << SAR0_FABRIC_FREQ_OFFSET) +#define SAR0_CPU0CORE_OFFSET 31 +#define SAR0_CPU0CORE_MASK (0x1 << SAR0_CPU0CORE_OFFSET) +#define SAR1_CPU0CORE_OFFSET 0 +#define SAR1_CPU0CORE_MASK (0x1 << SAR1_CPU0CORE_OFFSET) + +#define PEX_CLK_100MHZ_OFFSET 2 +#define PEX_CLK_100MHZ_MASK (0x1 << PEX_CLK_100MHZ_OFFSET) + +#define SAR1_FABRIC_MODE_OFFSET 19 +#define SAR1_FABRIC_MODE_MASK (0x1 << SAR1_FABRIC_MODE_OFFSET) +#define SAR1_CPU_MODE_OFFSET 20 +#define SAR1_CPU_MODE_MASK (0x1 << SAR1_CPU_MODE_OFFSET) + +#define SAR_CPU_FAB_GET(cpu, fab) (((cpu & 0x7) << 21) | ((fab & 0xF) << 24)) + + +#define CORE_AVS_CONTROL_0REG 0x18300 +#define CORE_AVS_CONTROL_2REG 0x18308 +#define CPU_AVS_CONTROL2_REG 0x20868 +#define CPU_AVS_CONTROL0_REG 0x20860 +#define GENERAL_PURPOSE_RESERVED0_REG 0x182E0 + +#define MSAR_TCLK_OFFS 28 +#define MSAR_TCLK_MASK (0x1 << MSAR_TCLK_OFFS) + + +/* Controler environment registers offsets */ +#define GEN_PURP_RES_1_REG 0x182F4 +#define GEN_PURP_RES_2_REG 0x182F8 + +/* registers offsets */ +#define MV_GPP_REGS_OFFSET(unit) (0x18100 + ((unit) * 0x40)) +#define MPP_CONTROL_REG(id) (0x18000 + (id * 4)) +#define MV_GPP_REGS_BASE(unit) (MV_GPP_REGS_OFFSET(unit)) +#define MV_GPP_REGS_BASE_0 (MV_GPP_REGS_OFFSET_0) + +#define GPP_DATA_OUT_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x00) +#define GPP_DATA_OUT_REG_0 (MV_GPP_REGS_BASE_0 + 0x00) /* Used in .S files */ +#define GPP_DATA_OUT_EN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x04) +#define GPP_BLINK_EN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x08) +#define GPP_DATA_IN_POL_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x0C) +#define GPP_DATA_IN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x10) +#define GPP_INT_CAUSE_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x14) +#define GPP_INT_MASK_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x18) +#define GPP_INT_LVL_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x1C) +#define GPP_OUT_SET_REG(grp) (0x18130 + ((grp) * 0x40)) +#define GPP_64_66_DATA_OUT_SET_REG 0x181A4 +#define GPP_OUT_CLEAR_REG(grp) (0x18134 + ((grp) * 0x40)) +#define GPP_64_66_DATA_OUT_CLEAR_REG 0x181B0 +#define GPP_FUNC_SELECT_REG (MV_GPP_REGS_BASE(0) + 0x40) + +#define MV_GPP66 (1 << 2) + +/* Relevant for MV78XX0 */ +#define GPP_DATA_OUT_SET_REG (MV_GPP_REGS_BASE(0) + 0x20) +#define GPP_DATA_OUT_CLEAR_REG (MV_GPP_REGS_BASE(0) + 0x24) + +/* This define describes the maximum number of supported PEX Interfaces */ +#define MV_PEX_MAX_IF 10 +#define MV_PEX_MAX_UNIT 4 + +#define MV_SERDES_NUM_TO_PEX_NUM(num) ((num < 8) ? (num) : (8 + (num / 12))) + +#define PEX_PHY_ACCESS_REG(unit) (0x40000 + ((unit) % 2 * 0x40000) + \ + ((unit)/2 * 0x2000) + 0x1B00) + +#define SATA_BASE_REG(port) (0xA2000 + (port)*0x2000) + +#define SATA_PWR_PLL_CTRL_REG(port) (SATA_BASE_REG(port) + 0x804) +#define SATA_DIG_LP_ENA_REG(port) (SATA_BASE_REG(port) + 0x88C) +#define SATA_REF_CLK_SEL_REG(port) (SATA_BASE_REG(port) + 0x918) +#define SATA_COMPHY_CTRL_REG(port) (SATA_BASE_REG(port) + 0x920) +#define SATA_LP_PHY_EXT_CTRL_REG(port) (SATA_BASE_REG(port) + 0x058) +#define SATA_LP_PHY_EXT_STAT_REG(port) (SATA_BASE_REG(port) + 0x05C) +#define SATA_IMP_TX_SSC_CTRL_REG(port) (SATA_BASE_REG(port) + 0x810) +#define SATA_GEN_1_SET_0_REG(port) (SATA_BASE_REG(port) + 0x834) +#define SATA_GEN_1_SET_1_REG(port) (SATA_BASE_REG(port) + 0x838) +#define SATA_GEN_2_SET_0_REG(port) (SATA_BASE_REG(port) + 0x83C) +#define SATA_GEN_2_SET_1_REG(port) (SATA_BASE_REG(port) + 0x840) + +#define MV_ETH_BASE_ADDR (0x72000) +#define MV_ETH_REGS_OFFSET(port) (MV_ETH_BASE_ADDR - ((port) / 2) * \ + 0x40000 + ((port) % 2) * 0x4000) +#define MV_ETH_REGS_BASE(port) MV_ETH_REGS_OFFSET(port) + + +#define SGMII_PWR_PLL_CTRL_REG(port) (MV_ETH_REGS_BASE(port) + 0xE04) +#define SGMII_DIG_LP_ENA_REG(port) (MV_ETH_REGS_BASE(port) + 0xE8C) +#define SGMII_REF_CLK_SEL_REG(port) (MV_ETH_REGS_BASE(port) + 0xF18) +#define SGMII_SERDES_CFG_REG(port) (MV_ETH_REGS_BASE(port) + 0x4A0) +#define SGMII_SERDES_STAT_REG(port) (MV_ETH_REGS_BASE(port) + 0x4A4) +#define SGMII_COMPHY_CTRL_REG(port) (MV_ETH_REGS_BASE(port) + 0xF20) +#define QSGMII_GEN_1_SETTING_REG(port) (MV_ETH_REGS_BASE(port) + 0xE38) +#define QSGMII_SERDES_CFG_REG(port) (MV_ETH_REGS_BASE(port) + 0x4a0) + +#define SERDES_LINE_MUX_REG_0_7 0x18270 +#define SERDES_LINE_MUX_REG_8_15 0x18274 +#define QSGMII_CONTROL_1_REG 0x18404 + +/* SOC_CTRL_REG fields */ +#define SCR_PEX_ENA_OFFS(pex) ((pex) & 0x3) +#define SCR_PEX_ENA_MASK(pex) (1 << pex) + +#define PCIE0_QUADX1_EN (1<<7) +#define PCIE1_QUADX1_EN (1<<8) + +#define SCR_PEX_4BY1_OFFS(pex) ((pex) + 7) +#define SCR_PEX_4BY1_MASK(pex) (1 << SCR_PEX_4BY1_OFFS(pex)) + +#define PCIE1_CLK_OUT_EN_OFF 5 +#define PCIE1_CLK_OUT_EN_MASK (1 << PCIE1_CLK_OUT_EN_OFF) + +#define PCIE0_CLK_OUT_EN_OFF 4 +#define PCIE0_CLK_OUT_EN_MASK (1 << PCIE0_CLK_OUT_EN_OFF) + +#define SCR_PEX0_4BY1_OFFS 7 +#define SCR_PEX0_4BY1_MASK (1 << SCR_PEX0_4BY1_OFFS) + +#define SCR_PEX1_4BY1_OFFS 8 +#define SCR_PEX1_4BY1_MASK (1 << SCR_PEX1_4BY1_OFFS) + + +#define MV_MISC_REGS_OFFSET (0x18200) +#define MV_MISC_REGS_BASE (MV_MISC_REGS_OFFSET) +#define SOC_CTRL_REG (MV_MISC_REGS_BASE + 0x4) + +/* + * PCI Express Control and Status Registers + */ +#define MAX_PEX_DEVICES 32 +#define MAX_PEX_FUNCS 8 +#define MAX_PEX_BUSSES 256 + +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */ +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS) + +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */ +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS) + +#define PXSR_DL_DOWN 0x1 /* DL_Down indication. */ +#define PXCAR_CONFIG_EN (1 << 31) +#define PEX_STATUS_AND_COMMAND 0x004 +#define PXSAC_MABORT (1 << 29) /* Recieved Master Abort */ + +/* PCI Express Configuration Address Register */ + +/* PEX_CFG_ADDR_REG (PXCAR) */ +#define PXCAR_REG_NUM_OFFS 2 +#define PXCAR_REG_NUM_MAX 0x3F +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS) +#define PXCAR_FUNC_NUM_OFFS 8 +#define PXCAR_FUNC_NUM_MAX 0x7 +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS) +#define PXCAR_DEVICE_NUM_OFFS 11 +#define PXCAR_DEVICE_NUM_MAX 0x1F +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS) +#define PXCAR_BUS_NUM_OFFS 16 +#define PXCAR_BUS_NUM_MAX 0xFF +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS) +#define PXCAR_EXT_REG_NUM_OFFS 24 +#define PXCAR_EXT_REG_NUM_MAX 0xF + +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8 +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS) + + +#define PEX_CAPABILITIES_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x60) +#define PEX_LINK_CAPABILITIES_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x6C) +#define PEX_LINK_CTRL_STATUS_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x70) +#define PEX_LINK_CTRL_STATUS2_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x90) +#define PEX_CTRL_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A00) +#define PEX_STATUS_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A04) +#define PEX_COMPLT_TMEOUT_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A10) +#define PEX_PWR_MNG_EXT_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A18) +#define PEX_FLOW_CTRL_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A20) +#define PEX_DYNMC_WIDTH_MNG_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A30) +#define PEX_ROOT_CMPLX_SSPL_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A0C) +#define PEX_RAM_PARITY_CTRL_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A50) +#define PEX_DBG_CTRL_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A60) +#define PEX_DBG_STATUS_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1A64) + +#define PXLCSR_NEG_LNK_GEN_OFFS 16 /* Negotiated Link GEN */ +#define PXLCSR_NEG_LNK_GEN_MASK (0xf << PXLCSR_NEG_LNK_GEN_OFFS) +#define PXLCSR_NEG_LNK_GEN_1_1 (0x1 << PXLCSR_NEG_LNK_GEN_OFFS) +#define PXLCSR_NEG_LNK_GEN_2_0 (0x2 << PXLCSR_NEG_LNK_GEN_OFFS) + +#define PEX_CFG_ADDR_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x18F8) +#define PEX_CFG_DATA_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x18FC) +#define PEX_CAUSE_REG(if) ((MV_PEX_IF_REGS_BASE(if)) + 0x1900) + +#define PEX_CAPABILITY_REG 0x60 +#define PEX_DEV_CAPABILITY_REG 0x64 +#define PEX_DEV_CTRL_STAT_REG 0x68 +#define PEX_LINK_CAPABILITY_REG 0x6C +#define PEX_LINK_CTRL_STAT_REG 0x70 +#define PEX_LINK_CTRL_STAT_2_REG 0x90 + +#endif /* __BOARD_ENV_SPEC */ diff --git a/arch/arm/mvebu-common/serdes/high_speed_env_lib.c b/arch/arm/mvebu-common/serdes/high_speed_env_lib.c new file mode 100644 index 0000000000..702273aee1 --- /dev/null +++ b/arch/arm/mvebu-common/serdes/high_speed_env_lib.c @@ -0,0 +1,1572 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "high_speed_env_spec.h" +#include "board_env_spec.h" + +#define SERDES_VERION "2.1.5" +#define ENDED_OK "High speed PHY - Ended Successfully\n" + +static const u8 serdes_cfg[][SERDES_LAST_UNIT] = BIN_SERDES_CFG; + +extern MV_BIN_SERDES_CFG *serdes_info_tbl[]; + +extern u8 rd78460gp_twsi_dev[]; +extern u8 db88f78xx0rev2_twsi_dev[]; + +u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs); +int pex_local_bus_num_set(u32 pex_if, u32 bus_num); +int pex_local_dev_num_set(u32 pex_if, u32 dev_num); + +#define MV_BOARD_PEX_MODULE_ADDR 0x23 +#define MV_BOARD_PEX_MODULE_ID 1 +#define MV_BOARD_ETM_MODULE_ID 2 + +#define PEX_MODULE_DETECT 1 +#define ETM_MODULE_DETECT 2 + +#define PEX_MODE_GET(satr) ((satr & 0x6) >> 1) +#define PEX_CAPABILITY_GET(satr) (satr & 1) +#define MV_PEX_UNIT_TO_IF(pex_unit) ((pex_unit < 3) ? (pex_unit * 4) : 9) + +/* Static parametes */ +static int config_module; +static int switch_module; + +/* Local function */ +static u32 board_id_get(void) +{ +#if defined(CONFIG_DB_88F78X60) + return DB_88F78XX0_BP_ID; +#elif defined(CONFIG_RD_88F78460_SERVER) + return RD_78460_SERVER_ID; +#elif defined(CONFIG_RD_78460_SERVER_REV2) + return RD_78460_SERVER_REV2_ID; +#elif defined(CONFIG_DB_78X60_PCAC) + return DB_78X60_PCAC_ID; +#elif defined(CONFIG_DB_88F78X60_REV2) + return DB_88F78XX0_BP_REV2_ID; +#elif defined(CONFIG_RD_78460_NAS) + return RD_78460_NAS_ID; +#elif defined(CONFIG_DB_78X60_AMC) + return DB_78X60_AMC_ID; +#elif defined(CONFIG_DB_78X60_PCAC_REV2) + return DB_78X60_PCAC_REV2_ID; +#elif defined(CONFIG_DB_784MP_GP) + return DB_784MP_GP_ID; +#elif defined(CONFIG_RD_78460_CUSTOMER) + return RD_78460_CUSTOMER_ID; +#else + /* + * Return 0 here for custom board as this should not be used + * for custom boards. + */ + return 0; +#endif +} + +static u8 board_sat_r_get(u8 dev_num, u8 reg) +{ + u8 data; + u8 *dev; + u32 board_id = board_id_get(); + int ret; + + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + switch (board_id) { + case DB_784MP_GP_ID: + dev = rd78460gp_twsi_dev; + + break; + case DB_88F78XX0_BP_ID: + case DB_88F78XX0_BP_REV2_ID: + dev = db88f78xx0rev2_twsi_dev; + break; + + case DB_78X60_PCAC_ID: + case FPGA_88F78XX0_ID: + case DB_78X60_PCAC_REV2_ID: + case RD_78460_SERVER_REV2_ID: + default: + return 0; + } + + /* Read MPP module ID */ + ret = i2c_read(dev[dev_num], 0, 1, (u8 *)&data, 1); + if (ret) + return MV_ERROR; + + return data; +} + +static int board_modules_scan(void) +{ + u8 val; + u32 board_id = board_id_get(); + int ret; + + /* Perform scan only for DB board */ + if ((board_id == DB_88F78XX0_BP_ID) || + (board_id == DB_88F78XX0_BP_REV2_ID)) { + /* reset modules flags */ + config_module = 0; + + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + /* SERDES module (only PEX model is supported now) */ + ret = i2c_read(MV_BOARD_PEX_MODULE_ADDR, 0, 1, (u8 *)&val, 1); + if (ret) + return MV_ERROR; + + if (val == MV_BOARD_PEX_MODULE_ID) + config_module = PEX_MODULE_DETECT; + if (val == MV_BOARD_ETM_MODULE_ID) + config_module = ETM_MODULE_DETECT; + } else if (board_id == RD_78460_NAS_ID) { + switch_module = 0; + if ((reg_read(GPP_DATA_IN_REG(2)) & MV_GPP66) == 0x0) + switch_module = 1; + } + + return MV_OK; +} + +u32 pex_max_unit_get(void) +{ + /* + * TODO: + * Right now only MV78460 is supported. Other SoC's might need + * a different value here. + */ + return MV_PEX_MAX_UNIT; +} + +u32 pex_max_if_get(void) +{ + /* + * TODO: + * Right now only MV78460 is supported. Other SoC's might need + * a different value here. + */ + return MV_PEX_MAX_IF; +} + +u8 board_cpu_freq_get(void) +{ + u32 sar; + u32 sar_msb; + + sar = reg_read(MPP_SAMPLE_AT_RESET(0)); + sar_msb = reg_read(MPP_SAMPLE_AT_RESET(1)); + return ((sar_msb & 0x100000) >> 17) | ((sar & 0xe00000) >> 21); +} + +__weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +{ + u32 board_id; + u32 serdes_cfg_val = 0; /* default */ + + board_id = board_id_get(); + + switch (board_id) { + case DB_784MP_GP_ID: + serdes_cfg_val = 0; + break; + } + + return &serdes_info_tbl[board_id - BOARD_ID_BASE][serdes_cfg_val]; +} + +u16 ctrl_model_get(void) +{ + /* Right now only MV78460 supported */ + return MV_78460_DEV_ID; +} + +u32 get_line_cfg(u32 line_num, MV_BIN_SERDES_CFG *info) +{ + if (line_num < 8) + return (info->line0_7 >> (line_num << 2)) & 0xF; + else + return (info->line8_15 >> ((line_num - 8) << 2)) & 0xF; +} + +int serdes_phy_config(void) +{ + int status = MV_OK; + u32 line_cfg; + u8 line_num; + /* addr/value for each line @ every setup step */ + u32 addr[16][11], val[16][11]; + u8 pex_unit, pex_line_num; + u8 sgmii_port = 0; + u32 tmp; + u32 in_direct; + u8 max_serdes_lines; + MV_BIN_SERDES_CFG *info; + u8 satr11; + u8 sata_port; + u8 freq; + u8 device_rev; + u32 rx_high_imp_mode; + u16 ctrl_mode; + u32 board_id = board_id_get(); + u32 pex_if; + u32 pex_if_num; + + /* + * TODO: + * Right now we only support the MV78460 with 16 serdes lines + */ + max_serdes_lines = 16; + if (max_serdes_lines == 0) + return MV_OK; + + switch (board_id) { + case DB_78X60_AMC_ID: + case DB_78X60_PCAC_REV2_ID: + case RD_78460_CUSTOMER_ID: + case RD_78460_SERVER_ID: + case RD_78460_SERVER_REV2_ID: + case DB_78X60_PCAC_ID: + satr11 = (0x1 << 1) | 1; + break; + case FPGA_88F78XX0_ID: + case RD_78460_NAS_ID: + satr11 = (0x0 << 1) | 1; + break; + case DB_88F78XX0_BP_REV2_ID: + case DB_784MP_GP_ID: + case DB_88F78XX0_BP_ID: + satr11 = board_sat_r_get(1, 1); + if ((u8) MV_ERROR == (u8) satr11) + return MV_ERROR; + break; + } + + board_modules_scan(); + memset(addr, 0, sizeof(addr)); + memset(val, 0, sizeof(val)); + + /* Check if DRAM is already initialized */ + if (reg_read(REG_BOOTROM_ROUTINE_ADDR) & + (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { + DEBUG_INIT_S("High speed PHY - Version: "); + DEBUG_INIT_S(SERDES_VERION); + DEBUG_INIT_S(" - 2nd boot - Skip\n"); + return MV_OK; + } + DEBUG_INIT_S("High speed PHY - Version: "); + DEBUG_INIT_S(SERDES_VERION); + DEBUG_INIT_S(" (COM-PHY-V20)\n"); + + /* + * AVS : disable AVS for frequency less than 1333 + */ + freq = board_cpu_freq_get(); + device_rev = mv_ctrl_rev_get(); + + if (device_rev == 2) { /* for B0 only */ + u32 cpu_avs; + u8 fabric_freq; + cpu_avs = reg_read(CPU_AVS_CONTROL2_REG); + DEBUG_RD_REG(CPU_AVS_CONTROL2_REG, cpu_avs); + cpu_avs &= ~(1 << 9); + + if ((0x4 == freq) || (0xB == freq)) { + u32 tmp2; + + tmp2 = reg_read(CPU_AVS_CONTROL0_REG); + DEBUG_RD_REG(CPU_AVS_CONTROL0_REG, tmp2); + /* cpu upper limit = 1.1V cpu lower limit = 0.9125V */ + tmp2 |= 0x0FF; + reg_write(CPU_AVS_CONTROL0_REG, tmp2); + DEBUG_WR_REG(CPU_AVS_CONTROL0_REG, tmp2); + cpu_avs |= (1 << 9); /* cpu avs enable */ + cpu_avs |= (1 << 18); /* AvsAvddDetEn enable */ + fabric_freq = (reg_read(MPP_SAMPLE_AT_RESET(0)) & + SAR0_FABRIC_FREQ_MASK) >> SAR0_FABRIC_FREQ_OFFSET; + if ((0xB == freq) && (5 == fabric_freq)) { + u32 core_avs; + + core_avs = reg_read(CORE_AVS_CONTROL_0REG); + DEBUG_RD_REG(CORE_AVS_CONTROL_0REG, core_avs); + + /* + * Set core lower limit = 0.9V & + * core upper limit = 0.9125V + */ + core_avs &= ~(0xff); + core_avs |= 0x0E; + reg_write(CORE_AVS_CONTROL_0REG, core_avs); + DEBUG_WR_REG(CORE_AVS_CONTROL_0REG, core_avs); + + core_avs = reg_read(CORE_AVS_CONTROL_2REG); + DEBUG_RD_REG(CORE_AVS_CONTROL_2REG, core_avs); + core_avs |= (1 << 9); /* core AVS enable */ + reg_write(CORE_AVS_CONTROL_2REG, core_avs); + DEBUG_WR_REG(CORE_AVS_CONTROL_2REG, core_avs); + + tmp2 = reg_read(GENERAL_PURPOSE_RESERVED0_REG); + DEBUG_RD_REG(GENERAL_PURPOSE_RESERVED0_REG, + tmp2); + tmp2 |= 0x1; /* AvsCoreAvddDetEn enable */ + reg_write(GENERAL_PURPOSE_RESERVED0_REG, tmp2); + DEBUG_WR_REG(GENERAL_PURPOSE_RESERVED0_REG, + tmp2); + } + } + reg_write(CPU_AVS_CONTROL2_REG, cpu_avs); + DEBUG_WR_REG(CPU_AVS_CONTROL2_REG, cpu_avs); + } + + info = board_serdes_cfg_get(PEX_MODE_GET(satr11)); + DEBUG_INIT_FULL_S("info->line0_7= 0x"); + DEBUG_INIT_FULL_D(info->line0_7, 8); + DEBUG_INIT_FULL_S(" info->line8_15= 0x"); + DEBUG_INIT_FULL_D(info->line8_15, 8); + DEBUG_INIT_FULL_S("\n"); + + if (info == NULL) { + DEBUG_INIT_S("Hight speed PHY Error #1\n"); + return MV_ERROR; + } + + if (config_module & ETM_MODULE_DETECT) { /* step 0.9 ETM */ + DEBUG_INIT_FULL_S("ETM module detect Step 0.9:\n"); + reg_write(SERDES_LINE_MUX_REG_0_7, 0x11111111); + DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x11111111); + info->pex_mode[1] = PEX_BUS_DISABLED; /* pex unit 1 is configure for ETM */ + mdelay(100); + reg_write(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */ + reg_write(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */ + } + + /* STEP -1 [PEX-Only] First phase of PEX-PIPE Configuration: */ + DEBUG_INIT_FULL_S("Step 1: First phase of PEX-PIPE Configuration\n"); + for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + + /* 1. GLOB_CLK_CTRL Reset and Clock Control */ + reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25); + + /* 2. GLOB_TEST_CTRL Test Mode Control */ + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) { + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0xC2 << 16) | 0x200); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0xC2 << 16) | 0x200); + } + + /* 3. GLOB_CLK_SRC_LO Clock Source Low */ + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) { + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0xC3 << 16) | 0x0F); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0xC3 << 16) | 0x0F); + } + + reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC5 << 16) | 0x11F); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0xC5 << 16) | 0x11F); + } + + /* + * 2 Configure the desire PIN_PHY_GEN and do power down to the PU_PLL, + * PU_RX,PU_TX. (bits[12:5]) + */ + DEBUG_INIT_FULL_S("Step 2: Configure the desire PIN_PHY_GEN\n"); + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + line_cfg = get_line_cfg(line_num, info); + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) + continue; + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) + continue; + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { + switch (line_num) { + case 4: + case 6: + sata_port = 0; + break; + case 5: + sata_port = 1; + break; + default: + DEBUG_INIT_C + ("SATA port error for serdes line: ", + line_num, 2); + return MV_ERROR; + } + tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port)); + DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + tmp &= ~((0x1ff << 5) | 0x7); + tmp |= ((info->bus_speed & (1 << line_num)) != 0) ? + (0x11 << 5) : 0x0; + + reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { + /* + * 4) Configure the desire PIN_PHY_GEN and do power + * down to the PU_PLL,PU_RX,PU_TX. (bits[12:5]) + */ + tmp = reg_read(SGMII_SERDES_CFG_REG(0)); + DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp); + tmp &= ~((0x1ff << 5) | 0x7); + tmp |= 0x660; + reg_write(SGMII_SERDES_CFG_REG(0), tmp); + DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp); + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) + sgmii_port = 0; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) + sgmii_port = 1; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) + sgmii_port = 2; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) + sgmii_port = 3; + else + continue; + + tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port)); + DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + tmp &= ~((0x1ff << 5) | 0x7); + tmp |= (((info->bus_speed & (1 << line_num)) != 0) ? + (0x88 << 5) : (0x66 << 5)); + reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + } + + /* Step 3 - QSGMII enable */ + DEBUG_INIT_FULL_S("Step 3 QSGMII enable\n"); + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + line_cfg = get_line_cfg(line_num, info); + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { + /* QSGMII Active bit set to true */ + tmp = reg_read(QSGMII_CONTROL_1_REG); + DEBUG_RD_REG(QSGMII_CONTROL_1_REG, tmp); + tmp |= (1 << 30); +#ifdef ERRATA_GL_6572255 + tmp |= (1 << 27); +#endif + reg_write(QSGMII_CONTROL_1_REG, tmp); + DEBUG_WR_REG(QSGMII_CONTROL_1_REG, tmp); + } + } + + /* Step 4 - configure SERDES MUXes */ + DEBUG_INIT_FULL_S("Step 4: Configure SERDES MUXes\n"); + if (config_module & ETM_MODULE_DETECT) { + reg_write(SERDES_LINE_MUX_REG_0_7, 0x40041111); + DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x40041111); + } else { + reg_write(SERDES_LINE_MUX_REG_0_7, info->line0_7); + DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, info->line0_7); + } + reg_write(SERDES_LINE_MUX_REG_8_15, info->line8_15); + DEBUG_WR_REG(SERDES_LINE_MUX_REG_8_15, info->line8_15); + + /* Step 5: Activate the RX High Impedance Mode */ + DEBUG_INIT_FULL_S("Step 5: Activate the RX High Impedance Mode\n"); + rx_high_imp_mode = 0x8080; + if (device_rev == 2) /* for B0 only */ + rx_high_imp_mode |= 4; + + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + /* for each serdes lane */ + DEBUG_INIT_FULL_S("SERDES "); + DEBUG_INIT_FULL_D_10(line_num, 2); + line_cfg = get_line_cfg(line_num, info); + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) { + DEBUG_INIT_FULL_S(" unconnected ***\n"); + continue; + } + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { + pex_unit = line_num >> 2; + pex_line_num = line_num % 4; + DEBUG_INIT_FULL_S(" - PEX unit "); + DEBUG_INIT_FULL_D_10(pex_unit, 1); + DEBUG_INIT_FULL_S(" line= "); + DEBUG_INIT_FULL_D_10(pex_line_num, 1); + DEBUG_INIT_FULL_S("\n"); + + /* Needed for PEX_PHY_ACCESS_REG macro */ + if ((line_num > 7) && + (info->pex_mode[3] == PEX_BUS_MODE_X8)) + /* lines 8 - 15 are belong to PEX3 in x8 mode */ + pex_unit = 3; + + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + + /* + * 8) Activate the RX High Impedance Mode field + * (bit [2]) in register /PCIe_USB Control (Each MAC + * contain different Access to reach its + * Serdes-Regfile). + * [PEX-Only] Set bit[12]: The analog part latches idle + * if PU_TX = 1 and PU_PLL =1. + */ + + /* Termination enable */ + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) { + in_direct = (0x48 << 16) | (pex_line_num << 24) | + 0x1000 | rx_high_imp_mode; /* x1 */ + } else if ((info->pex_mode[pex_unit] == + PEX_BUS_MODE_X4) && (pex_line_num == 0)) + in_direct = (0x48 << 16) | (pex_line_num << 24) | + 0x1000 | (rx_high_imp_mode & 0xff); /* x4 */ + else + in_direct = 0; + + if (in_direct) { + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + in_direct); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + in_direct); + } + + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { + /* + * port 0 for serdes lines 4,6, and port 1 for + * serdes lines 5 + */ + sata_port = line_num & 1; + DEBUG_INIT_FULL_S(" - SATA port "); + DEBUG_INIT_FULL_D_10(sata_port, 2); + DEBUG_INIT_FULL_S("\n"); + reg_write(SATA_COMPHY_CTRL_REG(sata_port), + rx_high_imp_mode); + DEBUG_WR_REG(SATA_COMPHY_CTRL_REG(sata_port), + rx_high_imp_mode); + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { + DEBUG_INIT_FULL_S(" - QSGMII\n"); + reg_write(SGMII_COMPHY_CTRL_REG(0), rx_high_imp_mode); + DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(0), + rx_high_imp_mode); + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) + sgmii_port = 0; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) + sgmii_port = 1; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) + sgmii_port = 2; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) + sgmii_port = 3; + else + continue; + DEBUG_INIT_FULL_S(" - SGMII port "); + DEBUG_INIT_FULL_D_10(sgmii_port, 2); + DEBUG_INIT_FULL_S("\n"); + reg_write(SGMII_COMPHY_CTRL_REG(sgmii_port), rx_high_imp_mode); + DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(sgmii_port), + rx_high_imp_mode); + } /* for each serdes lane */ + + /* Step 6 [PEX-Only] PEX-Main configuration (X4 or X1): */ + DEBUG_INIT_FULL_S("Step 6: [PEX-Only] PEX-Main configuration (X4 or X1)\n"); + tmp = reg_read(SOC_CTRL_REG); + DEBUG_RD_REG(SOC_CTRL_REG, tmp); + tmp &= 0x200; + if (info->pex_mode[0] == PEX_BUS_MODE_X1) + tmp |= PCIE0_QUADX1_EN; + if (info->pex_mode[1] == PEX_BUS_MODE_X1) + tmp |= PCIE1_QUADX1_EN; + if (((reg_read(MPP_SAMPLE_AT_RESET(0)) & PEX_CLK_100MHZ_MASK) >> + PEX_CLK_100MHZ_OFFSET) == 0x1) + tmp |= (PCIE0_CLK_OUT_EN_MASK | PCIE1_CLK_OUT_EN_MASK); + + reg_write(SOC_CTRL_REG, tmp); + DEBUG_WR_REG(SOC_CTRL_REG, tmp); + + /* 6.2 PCI Express Link Capabilities */ + DEBUG_INIT_FULL_S("Step 6.2: [PEX-Only] PCI Express Link Capabilities\n"); + + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + line_cfg = get_line_cfg(line_num, info); + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { + /* + * PCI Express Control + * 0xX1A00 [0]: + * 0x0 X4-Link. + * 0x1 X1-Link + */ + pex_unit = line_num >> 2; + pex_if = MV_SERDES_NUM_TO_PEX_NUM(line_num); + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + + /* set Common Clock Configuration */ + tmp = reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if)); + DEBUG_RD_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); + tmp |= (1 << 6); + reg_write(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); + DEBUG_WR_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp); + + tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if)); + DEBUG_RD_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); + tmp &= ~(0x3FF); + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) + tmp |= (0x1 << 4); + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) + tmp |= (0x4 << 4); + if (0 == PEX_CAPABILITY_GET(satr11)) + tmp |= 0x1; + else + tmp |= 0x2; + DEBUG_INIT_FULL_S("Step 6.2: PEX "); + DEBUG_INIT_FULL_D(pex_if, 1); + DEBUG_INIT_FULL_C(" set GEN", (tmp & 3), 1); + reg_write(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); + DEBUG_WR_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp); + + /* + * If pex is X4, no need to pass thru the other + * 3X1 serdes lines + */ + if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) + line_num += 3; + } + } + + /* + * Step 7 [PEX-X4 Only] To create PEX-Link that contain 4-lanes you + * need to config the register SOC_Misc/General Purpose2 + * (Address= 182F8) + */ + DEBUG_INIT_FULL_S("Step 7: [PEX-X4 Only] To create PEX-Link\n"); + tmp = reg_read(GEN_PURP_RES_2_REG); + DEBUG_RD_REG(GEN_PURP_RES_2_REG, tmp); + + tmp &= 0xFFFF0000; + if (info->pex_mode[0] == PEX_BUS_MODE_X4) + tmp |= 0x0000000F; + + if (info->pex_mode[1] == PEX_BUS_MODE_X4) + tmp |= 0x000000F0; + + if (info->pex_mode[2] == PEX_BUS_MODE_X4) + tmp |= 0x00000F00; + + if (info->pex_mode[3] == PEX_BUS_MODE_X4) + tmp |= 0x0000F000; + + reg_write(GEN_PURP_RES_2_REG, tmp); + DEBUG_WR_REG(GEN_PURP_RES_2_REG, tmp); + + /* Steps 8 , 9 ,10 - use prepared REG addresses and values */ + DEBUG_INIT_FULL_S("Steps 7,8,9,10 and 11\n"); + + /* Prepare PHY parameters for each step according to MUX selection */ + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + /* for each serdes lane */ + + line_cfg = get_line_cfg(line_num, info); + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) + continue; + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { + pex_unit = line_num >> 2; + pex_line_num = line_num % 4; + + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + /* + * 8) Configure the desire PHY_MODE (bits [7:5]) + * and REF_FREF_SEL (bits[4:0]) in the register Power + * and PLL Control (Each MAC contain different Access + * to reach its Serdes-Regfile). + */ + if (((info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) && + (0 == pex_line_num)) + || ((info->pex_mode[pex_unit] == PEX_BUS_MODE_X1))) { + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0x01 << 16) | (pex_line_num << 24) | + 0xFC60); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0x01 << 16) | (pex_line_num << 24) + | 0xFC60); + /* + * Step 8.1: [PEX-Only] Configure Max PLL Rate + * (bit 8 in KVCO Calibration Control and + * bits[10:9] in + */ + /* Use Maximum PLL Rate(Bit 8) */ + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0x02 << 16) | (1 << 31) | + (pex_line_num << 24)); /* read command */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0x02 << 16) | (1 << 31) | + (pex_line_num << 24)); + tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit)); + DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); + tmp &= ~(1 << 31); + tmp |= (1 << 8); + reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); + + /* Use Maximum PLL Rate(Bits [10:9]) */ + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0x81 << 16) | (1 << 31) | + (pex_line_num << 24)); /* read command */ + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0x81 << 16) | (1 << 31) | + (pex_line_num << 24)); + tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit)); + DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); + tmp &= ~(1 << 31); + tmp |= (3 << 9); + reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp); + } + + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { + /* + * Port 0 for serdes lines 4,6, and port 1 for serdes + * lines 5 + */ + sata_port = line_num & 1; + + /* + * 8) Configure the desire PHY_MODE (bits [7:5]) and + * REF_FREF_SEL (bits[4:0]) in the register Power + * and PLL Control (Each MAC contain different Access + * to reach its Serdes-Regfile). + */ + reg_write(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801); + DEBUG_WR_REG(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801); + + /* 9) Configure the desire SEL_BITS */ + reg_write(SATA_DIG_LP_ENA_REG(sata_port), 0x400); + DEBUG_WR_REG(SATA_DIG_LP_ENA_REG(sata_port), 0x400); + + /* 10) Configure the desire REFCLK_SEL */ + + reg_write(SATA_REF_CLK_SEL_REG(sata_port), 0x400); + DEBUG_WR_REG(SATA_REF_CLK_SEL_REG(sata_port), 0x400); + + /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ + tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port)); + DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + tmp |= 7; + reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp); + + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { + /* + * 8) Configure the desire PHY_MODE (bits [7:5]) + * and REF_FREF_SEL (bits[4:0]) in the register + */ + reg_write(SGMII_PWR_PLL_CTRL_REG(0), 0xF881); + DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(0), 0xF881); + + /* + * 9) Configure the desire SEL_BITS (bits [11:0] + * in register + */ + reg_write(SGMII_DIG_LP_ENA_REG(0), 0x400); + DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(0), 0x400); + + /* + * 10) Configure the desire REFCLK_SEL (bit [10]) + * in register + */ + reg_write(SGMII_REF_CLK_SEL_REG(0), 0x400); + DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(0), 0x400); + + /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ + tmp = reg_read(SGMII_SERDES_CFG_REG(0)); + DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp); + tmp |= 7; + reg_write(SGMII_SERDES_CFG_REG(0), tmp); + DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp); + continue; + } + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0]) + sgmii_port = 0; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1]) + sgmii_port = 1; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2]) + sgmii_port = 2; + else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3]) + sgmii_port = 3; + else + continue; + + /* + * 8) Configure the desire PHY_MODE (bits [7:5]) and + * REF_FREF_SEL (bits[4:0]) in the register + */ + reg_write(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881); + DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881); + + /* 9) Configure the desire SEL_BITS (bits [11:0] in register */ + reg_write(SGMII_DIG_LP_ENA_REG(sgmii_port), 0); + DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(sgmii_port), 0); + + /* 10) Configure the desire REFCLK_SEL (bit [10]) in register */ + reg_write(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400); + DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400); + + /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */ + tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port)); + DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + tmp |= 7; + reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp); + + } /* for each serdes lane */ + + /* Step 12 [PEX-Only] Last phase of PEX-PIPE Configuration */ + DEBUG_INIT_FULL_S("Steps 12: [PEX-Only] Last phase of PEX-PIPE Configuration\n"); + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + /* for each serdes lane */ + + line_cfg = get_line_cfg(line_num, info); + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) + continue; + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) { + pex_unit = line_num >> 2; + pex_line_num = line_num % 4; + if (0 == pex_line_num) { + reg_write(PEX_PHY_ACCESS_REG(pex_unit), + (0xC1 << 16) | 0x24); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), + (0xC1 << 16) | 0x24); + } + } + } + + /*--------------------------------------------------------------*/ + /* Step 13: Wait 15ms before checking results */ + DEBUG_INIT_FULL_S("Steps 13: Wait 15ms before checking results"); + mdelay(15); + tmp = 20; + while (tmp) { + status = MV_OK; + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + u32 tmp; + line_cfg = get_line_cfg(line_num, info); + if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) + continue; + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) + continue; + + if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) { + /* + * Port 0 for serdes lines 4,6, and port 1 + * for serdes lines 5 + */ + sata_port = line_num & 1; + + tmp = + reg_read(SATA_LP_PHY_EXT_STAT_REG + (sata_port)); + DEBUG_RD_REG(SATA_LP_PHY_EXT_STAT_REG + (sata_port), tmp); + if ((tmp & 0x7) != 0x7) + status = MV_ERROR; + continue; + } + + if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_QSGMII]) { + tmp = reg_read(SGMII_SERDES_STAT_REG(0)); + DEBUG_RD_REG(SGMII_SERDES_STAT_REG(0), tmp); + if ((tmp & 0x7) != 0x7) + status = MV_ERROR; + continue; + } + + if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_SGMII0]) + sgmii_port = 0; + else if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_SGMII1]) + sgmii_port = 1; + else if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_SGMII2]) + sgmii_port = 2; + else if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_SGMII3]) + sgmii_port = 3; + else + continue; + + tmp = reg_read(SGMII_SERDES_STAT_REG(sgmii_port)); + DEBUG_RD_REG(SGMII_SERDES_STAT_REG(sgmii_port), tmp); + if ((tmp & 0x7) != 0x7) + status = MV_ERROR; + } + + if (status == MV_OK) + break; + mdelay(5); + tmp--; + } + + /* + * Step14 [PEX-Only] In order to configure RC/EP mode please write + * to register 0x0060 bits + */ + DEBUG_INIT_FULL_S("Steps 14: [PEX-Only] In order to configure\n"); + for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + tmp = + reg_read(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit))); + DEBUG_RD_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), + tmp); + tmp &= ~(0xf << 20); + if (info->pex_type == MV_PEX_ROOT_COMPLEX) + tmp |= (0x4 << 20); + else + tmp |= (0x1 << 20); + reg_write(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), + tmp); + DEBUG_WR_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)), + tmp); + } + + /* + * Step 15 [PEX-Only] Only for EP mode set to Zero bits 19 and 16 of + * register 0x1a60 + */ + DEBUG_INIT_FULL_S("Steps 15: [PEX-Only] In order to configure\n"); + for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) + continue; + if (info->pex_type == MV_PEX_END_POINT) { + tmp = + reg_read(PEX_DBG_CTRL_REG + (MV_PEX_UNIT_TO_IF(pex_unit))); + DEBUG_RD_REG(PEX_DBG_CTRL_REG + (MV_PEX_UNIT_TO_IF(pex_unit)), tmp); + tmp &= 0xfff6ffff; + reg_write(PEX_DBG_CTRL_REG(MV_PEX_UNIT_TO_IF(pex_unit)), + tmp); + DEBUG_WR_REG(PEX_DBG_CTRL_REG + (MV_PEX_UNIT_TO_IF(pex_unit)), tmp); + } + } + + if (info->serdes_m_phy_change) { + MV_SERDES_CHANGE_M_PHY *serdes_m_phy_change; + u32 bus_speed; + for (line_num = 0; line_num < max_serdes_lines; line_num++) { + line_cfg = get_line_cfg(line_num, info); + if (line_cfg == + serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) + continue; + serdes_m_phy_change = info->serdes_m_phy_change; + bus_speed = info->bus_speed & (1 << line_num); + while (serdes_m_phy_change->type != + SERDES_UNIT_UNCONNECTED) { + switch (serdes_m_phy_change->type) { + case SERDES_UNIT_PEX: + if (line_cfg != SERDES_UNIT_PEX) + break; + pex_unit = line_num >> 2; + pex_line_num = line_num % 4; + if (info->pex_mode[pex_unit] == + PEX_BUS_DISABLED) + break; + if ((info->pex_mode[pex_unit] == + PEX_BUS_MODE_X4) && pex_line_num) + break; + + if (bus_speed) { + reg_write(PEX_PHY_ACCESS_REG + (pex_unit), + (pex_line_num << 24) | + serdes_m_phy_change->val_hi_speed); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG + (pex_unit), + (pex_line_num << + 24) | + serdes_m_phy_change->val_hi_speed); + } else { + reg_write(PEX_PHY_ACCESS_REG + (pex_unit), + (pex_line_num << 24) | + serdes_m_phy_change->val_low_speed); + DEBUG_WR_REG(PEX_PHY_ACCESS_REG + (pex_unit), + (pex_line_num << + 24) | + serdes_m_phy_change->val_low_speed); + } + break; + case SERDES_UNIT_SATA: + if (line_cfg != SERDES_UNIT_SATA) + break; + /* + * Port 0 for serdes lines 4,6, and + * port 1 for serdes lines 5 + */ + sata_port = line_num & 1; + if (bus_speed) { + reg_write(SATA_BASE_REG + (sata_port) | + serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + DEBUG_WR_REG(SATA_BASE_REG + (sata_port) | + serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + } else { + reg_write(SATA_BASE_REG + (sata_port) | + serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + DEBUG_WR_REG(SATA_BASE_REG + (sata_port) | + serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + } + break; + case SERDES_UNIT_SGMII0: + case SERDES_UNIT_SGMII1: + case SERDES_UNIT_SGMII2: + case SERDES_UNIT_SGMII3: + if (line_cfg == serdes_cfg[line_num] + [SERDES_UNIT_SGMII0]) + sgmii_port = 0; + else if (line_cfg == + serdes_cfg[line_num] + [SERDES_UNIT_SGMII1]) + sgmii_port = 1; + else if (line_cfg == + serdes_cfg[line_num] + [SERDES_UNIT_SGMII2]) + sgmii_port = 2; + else if (line_cfg == + serdes_cfg[line_num] + [SERDES_UNIT_SGMII3]) + sgmii_port = 3; + else + break; + if (bus_speed) { + reg_write(MV_ETH_REGS_BASE + (sgmii_port) | + serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + DEBUG_WR_REG(MV_ETH_REGS_BASE + (sgmii_port) | + serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + } else { + reg_write(MV_ETH_REGS_BASE + (sgmii_port) | + serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + DEBUG_WR_REG(MV_ETH_REGS_BASE + (sgmii_port) | + serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + } + break; + case SERDES_UNIT_QSGMII: + if (line_cfg != SERDES_UNIT_QSGMII) + break; + if (bus_speed) { + reg_write + (serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + DEBUG_WR_REG + (serdes_m_phy_change->reg_hi_speed, + serdes_m_phy_change->val_hi_speed); + } else { + reg_write + (serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + DEBUG_WR_REG + (serdes_m_phy_change->reg_low_speed, + serdes_m_phy_change->val_low_speed); + } + break; + default: + break; + } + serdes_m_phy_change++; + } + } + } + + /* Step 16 [PEX-Only] Training Enable */ + DEBUG_INIT_FULL_S("Steps 16: [PEX-Only] Training Enable"); + tmp = reg_read(SOC_CTRL_REG); + DEBUG_RD_REG(SOC_CTRL_REG, tmp); + tmp &= ~(0x0F); + for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) { + reg_write(PEX_CAUSE_REG(pex_unit), 0); + DEBUG_WR_REG(PEX_CAUSE_REG(pex_unit), 0); + if (info->pex_mode[pex_unit] != PEX_BUS_DISABLED) + tmp |= (0x1 << pex_unit); + } + reg_write(SOC_CTRL_REG, tmp); + DEBUG_WR_REG(SOC_CTRL_REG, tmp); + + /* Step 17: Speed change to target speed and width */ + { + u32 tmp_reg, tmp_pex_reg; + u32 addr; + u32 first_busno, next_busno; + u32 max_link_width = 0; + u32 neg_link_width = 0; + pex_if_num = pex_max_if_get(); + mdelay(150); + DEBUG_INIT_FULL_C("step 17: max_if= 0x", pex_if_num, 1); + next_busno = 0; + for (pex_if = 0; pex_if < pex_if_num; pex_if++) { + line_num = (pex_if <= 8) ? pex_if : 12; + line_cfg = get_line_cfg(line_num, info); + if (line_cfg != serdes_cfg[line_num][SERDES_UNIT_PEX]) + continue; + pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3; + DEBUG_INIT_FULL_S("step 17: PEX"); + DEBUG_INIT_FULL_D(pex_if, 1); + DEBUG_INIT_FULL_C(" pex_unit= ", pex_unit, 1); + + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) { + DEBUG_INIT_FULL_C("PEX disabled interface ", + pex_if, 1); + if (pex_if < 8) + pex_if += 3; + continue; + } + first_busno = next_busno; + if ((info->pex_type == MV_PEX_END_POINT) && + (0 == pex_if)) { + if ((pex_if < 8) && (info->pex_mode[pex_unit] == + PEX_BUS_MODE_X4)) + pex_if += 3; + continue; + } + + tmp = reg_read(PEX_DBG_STATUS_REG(pex_if)); + DEBUG_RD_REG(PEX_DBG_STATUS_REG(pex_if), tmp); + if ((tmp & 0x7f) == 0x7e) { + next_busno++; + tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if)); + max_link_width = tmp; + DEBUG_RD_REG((PEX_LINK_CAPABILITIES_REG + (pex_if)), tmp); + max_link_width = ((max_link_width >> 4) & 0x3F); + neg_link_width = + reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if)); + DEBUG_RD_REG((PEX_LINK_CTRL_STATUS_REG(pex_if)), + neg_link_width); + neg_link_width = ((neg_link_width >> 20) & 0x3F); + if (max_link_width > neg_link_width) { + tmp &= ~(0x3F << 4); + tmp |= (neg_link_width << 4); + reg_write(PEX_LINK_CAPABILITIES_REG + (pex_if), tmp); + DEBUG_WR_REG((PEX_LINK_CAPABILITIES_REG + (pex_if)), tmp); + mdelay(1); /* wait 1ms before reading capability for speed */ + DEBUG_INIT_S("PEX"); + DEBUG_INIT_D(pex_if, 1); + DEBUG_INIT_C(": change width to X", + neg_link_width, 1); + } + tmp_pex_reg = + reg_read((PEX_CFG_DIRECT_ACCESS + (pex_if, + PEX_LINK_CAPABILITY_REG))); + DEBUG_RD_REG((PEX_CFG_DIRECT_ACCESS + (pex_if, + PEX_LINK_CAPABILITY_REG)), + tmp_pex_reg); + tmp_pex_reg &= (0xF); + if (tmp_pex_reg == 0x2) { + tmp_reg = + (reg_read + (PEX_CFG_DIRECT_ACCESS + (pex_if, + PEX_LINK_CTRL_STAT_REG)) & + 0xF0000) >> 16; + DEBUG_RD_REG(PEX_CFG_DIRECT_ACCESS + (pex_if, + PEX_LINK_CTRL_STAT_REG), + tmp_pex_reg); + /* check if the link established is GEN1 */ + if (tmp_reg == 0x1) { + pex_local_bus_num_set(pex_if, + first_busno); + pex_local_dev_num_set(pex_if, + 1); + + DEBUG_INIT_FULL_S("** Link is Gen1, check the EP capability\n"); + /* link is Gen1, check the EP capability */ + addr = + pex_cfg_read(pex_if, + first_busno, 0, + 0, + 0x34) & 0xFF; + DEBUG_INIT_FULL_C("pex_cfg_read: return addr=0x%x", + addr, 4); + if (addr == 0xff) { + DEBUG_INIT_FULL_C("pex_cfg_read: return 0xff -->PEX (%d): Detected No Link.", + pex_if, 1); + continue; + } + while ((pex_cfg_read + (pex_if, first_busno, 0, + 0, + addr) & 0xFF) != + 0x10) { + addr = + (pex_cfg_read + (pex_if, + first_busno, 0, 0, + addr) & 0xFF00) >> + 8; + } + if ((pex_cfg_read + (pex_if, first_busno, 0, 0, + addr + 0xC) & 0xF) >= + 0x2) { + tmp = + reg_read + (PEX_LINK_CTRL_STATUS2_REG + (pex_if)); + DEBUG_RD_REG + (PEX_LINK_CTRL_STATUS2_REG + (pex_if), tmp); + tmp &= ~(0x1 | 1 << 1); + tmp |= (1 << 1); + reg_write + (PEX_LINK_CTRL_STATUS2_REG + (pex_if), tmp); + DEBUG_WR_REG + (PEX_LINK_CTRL_STATUS2_REG + (pex_if), tmp); + + tmp = + reg_read + (PEX_CTRL_REG + (pex_if)); + DEBUG_RD_REG + (PEX_CTRL_REG + (pex_if), tmp); + tmp |= (1 << 10); + reg_write(PEX_CTRL_REG + (pex_if), + tmp); + DEBUG_WR_REG + (PEX_CTRL_REG + (pex_if), tmp); + mdelay(10); /* We need to wait 10ms before reading the PEX_DBG_STATUS_REG in order not to read the status of the former state */ + DEBUG_INIT_FULL_S + ("Gen2 client!\n"); + } else { + DEBUG_INIT_FULL_S + ("GEN1 client!\n"); + } + } + } + } else { + DEBUG_INIT_FULL_S("PEX"); + DEBUG_INIT_FULL_D(pex_if, 1); + DEBUG_INIT_FULL_S(" : Detected No Link. Status Reg(0x"); + DEBUG_INIT_FULL_D(PEX_DBG_STATUS_REG(pex_if), + 8); + DEBUG_INIT_FULL_C(") = 0x", tmp, 8); + } + + if ((pex_if < 8) && + (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) + pex_if += 3; + } + } + + /* Step 18: update pex DEVICE ID */ + { + u32 devId; + pex_if_num = pex_max_if_get(); + ctrl_mode = ctrl_model_get(); + for (pex_if = 0; pex_if < pex_if_num; pex_if++) { + pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3; + if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) { + if ((pex_if < 8) && + (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) + pex_if += 3; + continue; + } + + devId = reg_read(PEX_CFG_DIRECT_ACCESS( + pex_if, PEX_DEVICE_AND_VENDOR_ID)); + devId &= 0xFFFF; + devId |= ((ctrl_mode << 16) & 0xffff0000); + DEBUG_INIT_S("Update Device ID PEX"); + DEBUG_INIT_D(pex_if, 1); + DEBUG_INIT_D(devId, 8); + DEBUG_INIT_S("\n"); + reg_write(PEX_CFG_DIRECT_ACCESS + (pex_if, PEX_DEVICE_AND_VENDOR_ID), devId); + if ((pex_if < 8) && + (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) + pex_if += 3; + } + DEBUG_INIT_S("Update PEX Device ID 0x"); + DEBUG_INIT_D(ctrl_mode, 4); + DEBUG_INIT_S("0\n"); + } + tmp = reg_read(PEX_DBG_STATUS_REG(0)); + DEBUG_RD_REG(PEX_DBG_STATUS_REG(0), tmp); + + DEBUG_INIT_S(ENDED_OK); + return MV_OK; +} + +/* PEX configuration space read write */ + +/* + * pex_cfg_read - Read from configuration space + * + * DESCRIPTION: + * This function performs a 32 bit read from PEX configuration space. + * It supports both type 0 and type 1 of Configuration Transactions + * (local and over bridge). In order to read from local bus segment, use + * bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers + * will result configuration transaction of type 1 (over bridge). + * + * INPUT: + * pex_if - PEX interface number. + * bus - PEX segment bus number. + * dev - PEX device number. + * func - Function number. + * offss - Register offset. + * + * OUTPUT: + * None. + * + * RETURN: + * 32bit register data, 0xffffffff on error + * + */ +u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs) +{ + u32 pex_data = 0; + u32 local_dev, local_bus; + u32 val; + + if (pex_if >= MV_PEX_MAX_IF) + return 0xFFFFFFFF; + + if (dev >= MAX_PEX_DEVICES) { + DEBUG_INIT_C("pex_cfg_read: ERR. device number illigal ", dev, + 1); + return 0xFFFFFFFF; + } + + if (func >= MAX_PEX_FUNCS) { + DEBUG_INIT_C("pex_cfg_read: ERR. function num illigal ", func, + 1); + return 0xFFFFFFFF; + } + + if (bus >= MAX_PEX_BUSSES) { + DEBUG_INIT_C("pex_cfg_read: ERR. bus number illigal ", bus, 1); + return MV_ERROR; + } + val = reg_read(PEX_STATUS_REG(pex_if)); + + local_dev = + ((val & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS); + local_bus = + ((val & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS); + + /* Speed up the process. In case on no link, return MV_ERROR */ + if ((dev != local_dev) || (bus != local_bus)) { + pex_data = reg_read(PEX_STATUS_REG(pex_if)); + + if ((pex_data & PXSR_DL_DOWN)) + return MV_ERROR; + } + + /* + * In PCI Express we have only one device number + * and this number is the first number we encounter else that the + * local_dev spec pex define return on config read/write on any device + */ + if (bus == local_bus) { + if (local_dev == 0) { + /* + * If local dev is 0 then the first number we encounter + * after 0 is 1 + */ + if ((dev != 1) && (dev != local_dev)) + return MV_ERROR; + } else { + /* + * If local dev is not 0 then the first number we + * encounter is 0 + */ + if ((dev != 0) && (dev != local_dev)) + return MV_ERROR; + } + } + + /* Creating PEX address to be passed */ + pex_data = (bus << PXCAR_BUS_NUM_OFFS); + pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS); + pex_data |= (func << PXCAR_FUNC_NUM_OFFS); + pex_data |= (offs & PXCAR_REG_NUM_MASK); /* lgacy register space */ + /* extended register space */ + pex_data |= (((offs & PXCAR_REAL_EXT_REG_NUM_MASK) >> + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS); + + pex_data |= PXCAR_CONFIG_EN; + + /* Write the address to the PEX configuration address register */ + reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data); + + /* + * In order to let the PEX controller absorbed the address of the read + * transaction we perform a validity check that the address was written + */ + if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if))) + return MV_ERROR; + + /* cleaning Master Abort */ + reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND), + PXSAC_MABORT); + /* Read the Data returned in the PEX Data register */ + pex_data = reg_read(PEX_CFG_DATA_REG(pex_if)); + + DEBUG_INIT_FULL_C(" --> ", pex_data, 4); + + return pex_data; +} + +/* + * pex_local_bus_num_set - Set PEX interface local bus number. + * + * DESCRIPTION: + * This function sets given PEX interface its local bus number. + * Note: In case the PEX interface is PEX-X, the information is read-only. + * + * INPUT: + * pex_if - PEX interface number. + * bus_num - Bus number. + * + * OUTPUT: + * None. + * + * RETURN: + * MV_NOT_ALLOWED in case PEX interface is PEX-X. + * MV_BAD_PARAM on bad parameters , + * otherwise MV_OK + * + */ +int pex_local_bus_num_set(u32 pex_if, u32 bus_num) +{ + u32 val; + + if (bus_num >= MAX_PEX_BUSSES) { + DEBUG_INIT_C("pex_local_bus_num_set: ERR. bus number illigal %d\n", + bus_num, 4); + return MV_ERROR; + } + + val = reg_read(PEX_STATUS_REG(pex_if)); + val &= ~PXSR_PEX_BUS_NUM_MASK; + val |= (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK; + reg_write(PEX_STATUS_REG(pex_if), val); + + return MV_OK; +} + +/* + * pex_local_dev_num_set - Set PEX interface local device number. + * + * DESCRIPTION: + * This function sets given PEX interface its local device number. + * Note: In case the PEX interface is PEX-X, the information is read-only. + * + * INPUT: + * pex_if - PEX interface number. + * dev_num - Device number. + * + * OUTPUT: + * None. + * + * RETURN: + * MV_NOT_ALLOWED in case PEX interface is PEX-X. + * MV_BAD_PARAM on bad parameters , + * otherwise MV_OK + * + */ +int pex_local_dev_num_set(u32 pex_if, u32 dev_num) +{ + u32 val; + + if (pex_if >= MV_PEX_MAX_IF) + return MV_BAD_PARAM; + + val = reg_read(PEX_STATUS_REG(pex_if)); + val &= ~PXSR_PEX_DEV_NUM_MASK; + val |= (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK; + reg_write(PEX_STATUS_REG(pex_if), val); + + return MV_OK; +} diff --git a/arch/arm/mvebu-common/serdes/high_speed_env_spec.c b/arch/arm/mvebu-common/serdes/high_speed_env_spec.c new file mode 100644 index 0000000000..115ec2cd60 --- /dev/null +++ b/arch/arm/mvebu-common/serdes/high_speed_env_spec.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "high_speed_env_spec.h" + +MV_SERDES_CHANGE_M_PHY serdes_change_m_phy[] = { + /* SERDES TYPE, Low REG OFFS, Low REG VALUE, Hi REG OFS, Hi REG VALUE */ + { + /* PEX: Change of Slew Rate port0 */ + SERDES_UNIT_PEX, 0x0, + (0x0F << 16) | 0x2a21, 0x0, (0x0F << 16) | 0x2a21 + }, { + /* PEX: Change PLL BW port0 */ + SERDES_UNIT_PEX, 0x0, + (0x4F << 16) | 0x6219, 0x0, (0x4F << 16) | 0x6219 + }, { + /* SATA: Slew rate change port 0 */ + SERDES_UNIT_SATA, 0x0083C, 0x8a31, 0x0083C, 0x8a31 + }, { + /* SATA: Slew rate change port 0 */ + SERDES_UNIT_SATA, 0x00834, 0xc928, 0x00834, 0xc928 + }, { + /* SATA: Slew rate change port 0 */ + SERDES_UNIT_SATA, 0x00838, 0x30f0, 0x00838, 0x30f0 + }, { + /* SATA: Slew rate change port 0 */ + SERDES_UNIT_SATA, 0x00840, 0x30f5, 0x00840, 0x30f5 + }, { + /* SGMII: FFE setting Port0 */ + SERDES_UNIT_SGMII0, 0x00E18, 0x989F, 0x00E18, 0x989F + }, { + /* SGMII: SELMUP and SELMUF Port0 */ + SERDES_UNIT_SGMII0, 0x00E38, 0x10FA, 0x00E38, 0x10FA + }, { + /* SGMII: Amplitude new setting gen2 Port3 */ + SERDES_UNIT_SGMII0, 0x00E34, 0xC968, 0x00E34, 0xC66C + }, { + /* QSGMII: Amplitude and slew rate change */ + SERDES_UNIT_QSGMII, 0x72E34, 0xaa58, 0x72E34, 0xaa58 + }, { + /* QSGMII: SELMUP and SELMUF */ + SERDES_UNIT_QSGMII, 0x72e38, 0x10aF, 0x72e38, 0x10aF + }, { + /* QSGMII: 0x72e18 */ + SERDES_UNIT_QSGMII, 0x72e18, 0x98AC, 0x72e18, 0x98AC + }, { + /* Null terminated */ + SERDES_UNIT_UNCONNECTED, 0, 0 + } +}; + +MV_BIN_SERDES_CFG db88f78xx0_serdes_cfg[] = { + /* Z1B */ + {MV_PEX_ROOT_COMPLEX, 0x32221111, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Default */ + {MV_PEX_ROOT_COMPLEX, 0x31211111, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_MODE_X1, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* PEX module */ + /* Z1A */ + {MV_PEX_ROOT_COMPLEX, 0x32220000, 0x00000000, + {PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED, + PEX_BUS_DISABLED}, 0x0030, serdes_change_m_phy}, /* Default - Z1A */ + {MV_PEX_ROOT_COMPLEX, 0x31210000, 0x00000000, + {PEX_BUS_DISABLED, PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0030, serdes_change_m_phy} /* PEX module - Z1A */ +}; + +MV_BIN_SERDES_CFG db88f78xx0rev2_serdes_cfg[] = { + /* A0 */ + {MV_PEX_ROOT_COMPLEX, 0x33221111, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Default: No Pex module, PEX0 x1, disabled */ + {MV_PEX_ROOT_COMPLEX, 0x33211111, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_MODE_X1, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Pex module, PEX0 x1, PEX1 x1 */ + {MV_PEX_ROOT_COMPLEX, 0x33221111, 0x11111111, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* no Pex module, PEX0 x4, PEX1 disabled */ + {MV_PEX_ROOT_COMPLEX, 0x33211111, 0x11111111, + {PEX_BUS_MODE_X4, PEX_BUS_MODE_X1, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Pex module, PEX0 x4, PEX1 x1 */ + {MV_PEX_ROOT_COMPLEX, 0x11111111, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Pex module, PEX0 x1, PEX1 x4 */ + {MV_PEX_ROOT_COMPLEX, 0x11111111, 0x11111111, + {PEX_BUS_MODE_X4, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Pex module, PEX0 x4, PEX1 x4 */ +}; + +MV_BIN_SERDES_CFG rd78460nas_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x00223001, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy}, /* Default */ + {MV_PEX_ROOT_COMPLEX, 0x33320201, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x00f4, serdes_change_m_phy}, /* Switch module */ +}; + +MV_BIN_SERDES_CFG rd78460_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x22321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy}, /* CPU0 */ + {MV_PEX_ROOT_COMPLEX, 0x00321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy} /* CPU1-3 */ +}; + +MV_BIN_SERDES_CFG rd78460server_rev2_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x00321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy}, /* CPU0 */ + {MV_PEX_ROOT_COMPLEX, 0x00321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy} /* CPU1-3 */ +}; + +MV_BIN_SERDES_CFG db78X60pcac_serdes_cfg[] = { + {MV_PEX_END_POINT, 0x22321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy} /* Default */ +}; + +MV_BIN_SERDES_CFG db78X60pcacrev2_serdes_cfg[] = { + {MV_PEX_END_POINT, 0x23321111, 0x00000000, + {PEX_BUS_MODE_X4, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0010, serdes_change_m_phy} /* Default */ +}; + +MV_BIN_SERDES_CFG fpga88f78xx0_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x00000000, 0x00000000, + {PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED, PEX_BUS_DISABLED}, + 0x0000, serdes_change_m_phy} /* No PEX in FPGA */ +}; + +MV_BIN_SERDES_CFG db78X60amc_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x33111111, 0x00010001, + {PEX_BUS_MODE_X4, PEX_BUS_MODE_X1, PEX_BUS_MODE_X1, PEX_BUS_MODE_X1}, + 0x0030, serdes_change_m_phy} /* Default */ +}; + +/* + * ARMADA-XP CUSTOMER BOARD + */ +MV_BIN_SERDES_CFG rd78460customer_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x00223001, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x00000030, serdes_change_m_phy}, /* Default */ + {MV_PEX_ROOT_COMPLEX, 0x33320201, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x00000030, serdes_change_m_phy}, /* Switch module */ +}; + +MV_BIN_SERDES_CFG rd78460AXP_GP_serdes_cfg[] = { + {MV_PEX_ROOT_COMPLEX, 0x00223001, 0x11111111, + {PEX_BUS_MODE_X1, PEX_BUS_DISABLED, PEX_BUS_MODE_X4, PEX_BUS_MODE_X4}, + 0x0030, serdes_change_m_phy} /* Default */ +}; + +MV_BIN_SERDES_CFG *serdes_info_tbl[] = { + db88f78xx0_serdes_cfg, + rd78460_serdes_cfg, + db78X60pcac_serdes_cfg, + fpga88f78xx0_serdes_cfg, + db88f78xx0rev2_serdes_cfg, + rd78460nas_serdes_cfg, + db78X60amc_serdes_cfg, + db78X60pcacrev2_serdes_cfg, + rd78460server_rev2_serdes_cfg, + rd78460AXP_GP_serdes_cfg, + rd78460customer_serdes_cfg +}; + +u8 rd78460gp_twsi_dev[] = { 0x4C, 0x4D, 0x4E }; +u8 db88f78xx0rev2_twsi_dev[] = { 0x4C, 0x4D, 0x4E, 0x4F }; diff --git a/arch/arm/mvebu-common/serdes/high_speed_env_spec.h b/arch/arm/mvebu-common/serdes/high_speed_env_spec.h new file mode 100644 index 0000000000..e5aa1b06ed --- /dev/null +++ b/arch/arm/mvebu-common/serdes/high_speed_env_spec.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __HIGHSPEED_ENV_SPEC_H +#define __HIGHSPEED_ENV_SPEC_H + +#include "../../../drivers/ddr/mvebu/ddr3_hw_training.h" + +typedef enum { + SERDES_UNIT_UNCONNECTED = 0x0, + SERDES_UNIT_PEX = 0x1, + SERDES_UNIT_SATA = 0x2, + SERDES_UNIT_SGMII0 = 0x3, + SERDES_UNIT_SGMII1 = 0x4, + SERDES_UNIT_SGMII2 = 0x5, + SERDES_UNIT_SGMII3 = 0x6, + SERDES_UNIT_QSGMII = 0x7, + SERDES_UNIT_SETM = 0x8, + SERDES_LAST_UNIT +} MV_BIN_SERDES_UNIT_INDX; + + +typedef enum { + PEX_BUS_DISABLED = 0, + PEX_BUS_MODE_X1 = 1, + PEX_BUS_MODE_X4 = 2, + PEX_BUS_MODE_X8 = 3 +} MV_PEX_UNIT_CFG; + +typedef enum pex_type { + MV_PEX_ROOT_COMPLEX, /* root complex device */ + MV_PEX_END_POINT /* end point device */ +} MV_PEX_TYPE; + +typedef struct serdes_change_m_phy { + MV_BIN_SERDES_UNIT_INDX type; + u32 reg_low_speed; + u32 val_low_speed; + u32 reg_hi_speed; + u32 val_hi_speed; +} MV_SERDES_CHANGE_M_PHY; + +/* + * Configuration per SERDES line. Each nibble is MV_SERDES_LINE_TYPE + */ +typedef struct board_serdes_conf { + MV_PEX_TYPE pex_type; /* MV_PEX_ROOT_COMPLEX MV_PEX_END_POINT */ + u32 line0_7; /* Lines 0 to 7 SERDES MUX one nibble per line */ + u32 line8_15; /* Lines 8 to 15 SERDES MUX one nibble per line */ + MV_PEX_UNIT_CFG pex_mode[4]; + + /* + * Bus speed - one bit per SERDES line: + * Low speed (0) High speed (1) + * PEX 2.5 G (10 bit) 5 G (20 bit) + * SATA 1.5 G 3 G + * SGMII 1.25 Gbps 3.125 Gbps + */ + u32 bus_speed; + + MV_SERDES_CHANGE_M_PHY *serdes_m_phy_change; +} MV_BIN_SERDES_CFG; + + +#define BIN_SERDES_CFG { \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 0 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, 2}, /* Lane 1 */ \ + {0, 1, -1 , 2, -1, -1, -1, -1, 3}, /* Lane 2 */ \ + {0, 1, -1 , -1, 2, -1, -1, 3, -1}, /* Lane 3 */ \ + {0, 1, 2 , -1, -1, 3, -1, -1, 4}, /* Lane 4 */ \ + {0, 1, 2 , -1, 3, -1, -1, 4, -1}, /* Lane 5 */ \ + {0, 1, 2 , 4, -1, 3, -1, -1, -1}, /* Lane 6 */ \ + {0, 1, -1 , 2, -1, -1, 3, -1, 4}, /* Lane 7*/ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 8 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 9 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 10 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 11 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 12 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 13 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 14 */ \ + {0, 1, -1 , -1, -1, -1, -1, -1, -1}, /* Lane 15 */ \ +} + +#endif /* __HIGHSPEED_ENV_SPEC_H */ -- cgit From f8d25d7466142c1d4ebf879e2a83a9cfc19559cb Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:40 +0100 Subject: arm: mvebu: drivers/ddr: Add DDR3 driver with training code from Marvell bin_hdr This patch adds the DDR3 setup and training code taken from the Marvell U-Boot repository. This code used to be included as a binary (bin_hdr) into the AXP boot image. Not linked with the main U-Boot. With this code addition and the following serdes/PHY setup code, the Armada-XP support in mainline U-Boot is finally self-contained. So the complete image for booting can be built from mainline U-Boot. Without any additional external inclusion. Hopefully other MVEBU SoC's will follow here. Support for some SoC's has been removed in this version. This is: MV_MSYS: The code referred to by the MV_MSYS define is currently unused. And its not really planned to support this in mainline. So lets remove it to make the code clearer and increase the readability. MV88F68XX (A38x): The code referred to by the MV88F68XX define (A38x) is currently unused. And its partial and not sufficient for this device in this stage. So lets remove it to make the code clearer and increase the readability. MV88F66XX (ALP): The code referred to by the MV88F66XX define is currently unused. And its not really planned to support this in mainline. So lets remove it to make the code clearer and increase the readability. MV88F78X60_Z1: The code referred to by the MV88F78X60_Z1 define is currently unused. As the Z1 revision of the AXP is not supported in mainline anymore. So lets remove it to make the code clearer and increase the readability. Remove support for Z1 & A0 AXP revisions (steppings). The current stepping is B0 and this is the only one that is actively supported in this code version. Tested on AXP using a SPD DIMM setup on the Marvell DB-MV784MP-GP board and on a custom fixed DDR configuration board (maxbcm). Note: This code has undergone many hours of coding-style cleanup and refactoring. It still is not checkpatch clean though, I'm afraid. As the factoring of the code has so many levels of indentation that many lines are longer than 80 chars. This might be some task to tackly later on. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- drivers/ddr/mvebu/Makefile | 14 + drivers/ddr/mvebu/ddr3_axp.h | 510 +++++++++ drivers/ddr/mvebu/ddr3_axp_config.h | 146 +++ drivers/ddr/mvebu/ddr3_axp_mc_static.h | 284 +++++ drivers/ddr/mvebu/ddr3_axp_training_static.h | 770 +++++++++++++ drivers/ddr/mvebu/ddr3_axp_vars.h | 226 ++++ drivers/ddr/mvebu/ddr3_dfs.c | 1552 +++++++++++++++++++++++++ drivers/ddr/mvebu/ddr3_dqs.c | 1374 ++++++++++++++++++++++ drivers/ddr/mvebu/ddr3_hw_training.c | 1115 ++++++++++++++++++ drivers/ddr/mvebu/ddr3_hw_training.h | 392 +++++++ drivers/ddr/mvebu/ddr3_init.c | 1219 ++++++++++++++++++++ drivers/ddr/mvebu/ddr3_init.h | 143 +++ drivers/ddr/mvebu/ddr3_patterns_64bit.h | 924 +++++++++++++++ drivers/ddr/mvebu/ddr3_pbs.c | 1592 ++++++++++++++++++++++++++ drivers/ddr/mvebu/ddr3_read_leveling.c | 1214 ++++++++++++++++++++ drivers/ddr/mvebu/ddr3_sdram.c | 669 +++++++++++ drivers/ddr/mvebu/ddr3_spd.c | 1300 +++++++++++++++++++++ drivers/ddr/mvebu/ddr3_write_leveling.c | 1366 ++++++++++++++++++++++ drivers/ddr/mvebu/xor.c | 436 +++++++ drivers/ddr/mvebu/xor.h | 70 ++ drivers/ddr/mvebu/xor_regs.h | 103 ++ 21 files changed, 15419 insertions(+) create mode 100644 drivers/ddr/mvebu/Makefile create mode 100644 drivers/ddr/mvebu/ddr3_axp.h create mode 100644 drivers/ddr/mvebu/ddr3_axp_config.h create mode 100644 drivers/ddr/mvebu/ddr3_axp_mc_static.h create mode 100644 drivers/ddr/mvebu/ddr3_axp_training_static.h create mode 100644 drivers/ddr/mvebu/ddr3_axp_vars.h create mode 100644 drivers/ddr/mvebu/ddr3_dfs.c create mode 100644 drivers/ddr/mvebu/ddr3_dqs.c create mode 100644 drivers/ddr/mvebu/ddr3_hw_training.c create mode 100644 drivers/ddr/mvebu/ddr3_hw_training.h create mode 100644 drivers/ddr/mvebu/ddr3_init.c create mode 100644 drivers/ddr/mvebu/ddr3_init.h create mode 100644 drivers/ddr/mvebu/ddr3_patterns_64bit.h create mode 100644 drivers/ddr/mvebu/ddr3_pbs.c create mode 100644 drivers/ddr/mvebu/ddr3_read_leveling.c create mode 100644 drivers/ddr/mvebu/ddr3_sdram.c create mode 100644 drivers/ddr/mvebu/ddr3_spd.c create mode 100644 drivers/ddr/mvebu/ddr3_write_leveling.c create mode 100644 drivers/ddr/mvebu/xor.c create mode 100644 drivers/ddr/mvebu/xor.h create mode 100644 drivers/ddr/mvebu/xor_regs.h diff --git a/drivers/ddr/mvebu/Makefile b/drivers/ddr/mvebu/Makefile new file mode 100644 index 0000000000..50a69eaffa --- /dev/null +++ b/drivers/ddr/mvebu/Makefile @@ -0,0 +1,14 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SPL_BUILD) += ddr3_dfs.o +obj-$(CONFIG_SPL_BUILD) += ddr3_dqs.o +obj-$(CONFIG_SPL_BUILD) += ddr3_hw_training.o +obj-$(CONFIG_SPL_BUILD) += ddr3_init.o +obj-$(CONFIG_SPL_BUILD) += ddr3_pbs.o +obj-$(CONFIG_SPL_BUILD) += ddr3_read_leveling.o +obj-$(CONFIG_SPL_BUILD) += ddr3_sdram.o +obj-$(CONFIG_SPL_BUILD) += ddr3_spd.o +obj-$(CONFIG_SPL_BUILD) += ddr3_write_leveling.o +obj-$(CONFIG_SPL_BUILD) += xor.o diff --git a/drivers/ddr/mvebu/ddr3_axp.h b/drivers/ddr/mvebu/ddr3_axp.h new file mode 100644 index 0000000000..bf65f6bab7 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_axp.h @@ -0,0 +1,510 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DDR3_AXP_H +#define __DDR3_AXP_H + +#define MV_78XX0_Z1_REV 0x0 +#define MV_78XX0_A0_REV 0x1 +#define MV_78XX0_B0_REV 0x2 + +#define SAR_DDR3_FREQ_MASK 0xFE00000 +#define SAR_CPU_FAB_GET(cpu, fab) (((cpu & 0x7) << 21) | ((fab & 0xF) << 24)) + +#define MAX_CS 4 + +#define MIN_DIMM_ADDR 0x50 +#define FAR_END_DIMM_ADDR 0x50 +#define MAX_DIMM_ADDR 0x60 + +#ifndef CONFIG_DDR_FIXED_SIZE +#define SDRAM_CS_SIZE 0xFFFFFFF +#else +#define SDRAM_CS_SIZE (CONFIG_DDR_FIXED_SIZE - 1) +#endif +#define SDRAM_CS_BASE 0x0 +#define SDRAM_DIMM_SIZE 0x80000000 + +#define CPU_CONFIGURATION_REG(id) (0x21800 + (id * 0x100)) +#define CPU_MRVL_ID_OFFSET 0x10 +#define SAR1_CPU_CORE_MASK 0x00000018 +#define SAR1_CPU_CORE_OFFSET 3 + +#define ECC_SUPPORT +#define NEW_FABRIC_TWSI_ADDR 0x4E +#ifdef DB_784MP_GP +#define BUS_WIDTH_ECC_TWSI_ADDR 0x4E +#else +#define BUS_WIDTH_ECC_TWSI_ADDR 0x4F +#endif +#define MV_MAX_DDR3_STATIC_SIZE 50 +#define MV_DDR3_MODES_NUMBER 30 + +#define RESUME_RL_PATTERNS_ADDR (0xFE0000) +#define RESUME_RL_PATTERNS_SIZE (0x100) +#define RESUME_TRAINING_VALUES_ADDR (RESUME_RL_PATTERNS_ADDR + RESUME_RL_PATTERNS_SIZE) +#define RESUME_TRAINING_VALUES_MAX (0xCD0) +#define BOOT_INFO_ADDR (RESUME_RL_PATTERNS_ADDR + 0x1000) +#define CHECKSUM_RESULT_ADDR (BOOT_INFO_ADDR + 0x1000) +#define NUM_OF_REGISTER_ADDR (CHECKSUM_RESULT_ADDR + 4) +#define SUSPEND_MAGIC_WORD (0xDEADB002) +#define REGISTER_LIST_END (0xFFFFFFFF) + +/* + * Registers offset + */ + +#define REG_SAMPLE_RESET_LOW_ADDR 0x18230 +#define REG_SAMPLE_RESET_HIGH_ADDR 0x18234 +#define REG_SAMPLE_RESET_CPU_FREQ_OFFS 21 +#define REG_SAMPLE_RESET_CPU_FREQ_MASK 0x00E00000 +#define REG_SAMPLE_RESET_FAB_OFFS 24 +#define REG_SAMPLE_RESET_FAB_MASK 0xF000000 +#define REG_SAMPLE_RESET_TCLK_OFFS 28 +#define REG_SAMPLE_RESET_CPU_ARCH_OFFS 31 +#define REG_SAMPLE_RESET_HIGH_CPU_FREQ_OFFS 20 + +/* MISC */ +/* + * In mainline U-Boot we're re-configuring the mvebu base address + * register to 0xf1000000. So need to use this value for the DDR + * training code as well. + */ +#define INTER_REGS_BASE SOC_REGS_PHY_BASE + +/* DDR */ +#define REG_SDRAM_CONFIG_ADDR 0x1400 +#define REG_SDRAM_CONFIG_MASK 0x9FFFFFFF +#define REG_SDRAM_CONFIG_RFRS_MASK 0x3FFF +#define REG_SDRAM_CONFIG_WIDTH_OFFS 15 +#define REG_SDRAM_CONFIG_REGDIMM_OFFS 17 +#define REG_SDRAM_CONFIG_ECC_OFFS 18 +#define REG_SDRAM_CONFIG_IERR_OFFS 19 +#define REG_SDRAM_CONFIG_PUPRSTDIV_OFFS 28 +#define REG_SDRAM_CONFIG_RSTRD_OFFS 30 + +#define REG_DUNIT_CTRL_LOW_ADDR 0x1404 +#define REG_DUNIT_CTRL_LOW_2T_OFFS 3 +#define REG_DUNIT_CTRL_LOW_2T_MASK 0x3 +#define REG_DUNIT_CTRL_LOW_DPDE_OFFS 14 + +#define REG_SDRAM_TIMING_LOW_ADDR 0x1408 + +#define REG_SDRAM_TIMING_HIGH_ADDR 0x140C +#define REG_SDRAM_TIMING_H_R2R_OFFS 7 +#define REG_SDRAM_TIMING_H_R2R_MASK 0x3 +#define REG_SDRAM_TIMING_H_R2W_W2R_OFFS 9 +#define REG_SDRAM_TIMING_H_R2W_W2R_MASK 0x3 +#define REG_SDRAM_TIMING_H_W2W_OFFS 11 +#define REG_SDRAM_TIMING_H_W2W_MASK 0x1F +#define REG_SDRAM_TIMING_H_R2R_H_OFFS 19 +#define REG_SDRAM_TIMING_H_R2R_H_MASK 0x7 +#define REG_SDRAM_TIMING_H_R2W_W2R_H_OFFS 22 +#define REG_SDRAM_TIMING_H_R2W_W2R_H_MASK 0x7 + +#define REG_SDRAM_ADDRESS_CTRL_ADDR 0x1410 +#define REG_SDRAM_ADDRESS_SIZE_OFFS 2 +#define REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS 18 +#define REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS 4 + +#define REG_SDRAM_OPEN_PAGES_ADDR 0x1414 +#define REG_SDRAM_OPERATION_CS_OFFS 8 + +#define REG_SDRAM_OPERATION_ADDR 0x1418 +#define REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS 24 +#define REG_SDRAM_OPERATION_CWA_DATA_OFFS 20 +#define REG_SDRAM_OPERATION_CWA_DATA_MASK 0xF +#define REG_SDRAM_OPERATION_CWA_RC_OFFS 16 +#define REG_SDRAM_OPERATION_CWA_RC_MASK 0xF +#define REG_SDRAM_OPERATION_CMD_MR0 0xF03 +#define REG_SDRAM_OPERATION_CMD_MR1 0xF04 +#define REG_SDRAM_OPERATION_CMD_MR2 0xF08 +#define REG_SDRAM_OPERATION_CMD_MR3 0xF09 +#define REG_SDRAM_OPERATION_CMD_RFRS 0xF02 +#define REG_SDRAM_OPERATION_CMD_CWA 0xF0E +#define REG_SDRAM_OPERATION_CMD_RFRS_DONE 0xF +#define REG_SDRAM_OPERATION_CMD_MASK 0xF +#define REG_SDRAM_OPERATION_CS_OFFS 8 + +#define REG_OUDDR3_TIMING_ADDR 0x142C + +#define REG_SDRAM_MODE_ADDR 0x141C + +#define REG_SDRAM_EXT_MODE_ADDR 0x1420 + +#define REG_DDR_CONT_HIGH_ADDR 0x1424 + +#define REG_ODT_TIME_LOW_ADDR 0x1428 +#define REG_ODT_ON_CTL_RD_OFFS 12 +#define REG_ODT_OFF_CTL_RD_OFFS 16 +#define REG_SDRAM_ERROR_ADDR 0x1454 +#define REG_SDRAM_AUTO_PWR_SAVE_ADDR 0x1474 +#define REG_ODT_TIME_HIGH_ADDR 0x147C + +#define REG_SDRAM_INIT_CTRL_ADDR 0x1480 +#define REG_SDRAM_INIT_CTRL_OFFS 0 +#define REG_SDRAM_INIT_CKE_ASSERT_OFFS 2 +#define REG_SDRAM_INIT_RESET_DEASSERT_OFFS 3 + +#define REG_SDRAM_ODT_CTRL_LOW_ADDR 0x1494 + +#define REG_SDRAM_ODT_CTRL_HIGH_ADDR 0x1498 +/*#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK 0xFFFFFF55 */ +#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK 0x0 +#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_ENA 0x3 + +#define REG_DUNIT_ODT_CTRL_ADDR 0x149C +#define REG_DUNIT_ODT_CTRL_OVRD_OFFS 8 +#define REG_DUNIT_ODT_CTRL_OVRD_VAL_OFFS 9 + +#define REG_DRAM_FIFO_CTRL_ADDR 0x14A0 + +#define REG_DRAM_AXI_CTRL_ADDR 0x14A8 +#define REG_DRAM_AXI_CTRL_AXIDATABUSWIDTH_OFFS 0 + +#define REG_METAL_MASK_ADDR 0x14B0 +#define REG_METAL_MASK_MASK 0xDFFFFFFF +#define REG_METAL_MASK_RETRY_OFFS 0 + +#define REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR 0x14C0 + +#define REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR 0x14C4 +#define REG_DRAM_VER_CAL_MACHINE_CTRL_ADDR 0x14c8 +#define REG_DRAM_MAIN_PADS_CAL_ADDR 0x14CC + +#define REG_DRAM_HOR_CAL_MACHINE_CTRL_ADDR 0x17c8 + +#define REG_CS_SIZE_SCRATCH_ADDR 0x1504 +#define REG_DYNAMIC_POWER_SAVE_ADDR 0x1520 +#define REG_DDR_IO_ADDR 0x1524 +#define REG_DDR_IO_CLK_RATIO_OFFS 15 + +#define REG_DFS_ADDR 0x1528 +#define REG_DFS_DLLNEXTSTATE_OFFS 0 +#define REG_DFS_BLOCK_OFFS 1 +#define REG_DFS_SR_OFFS 2 +#define REG_DFS_ATSR_OFFS 3 +#define REG_DFS_RECONF_OFFS 4 +#define REG_DFS_CL_NEXT_STATE_OFFS 8 +#define REG_DFS_CL_NEXT_STATE_MASK 0xF +#define REG_DFS_CWL_NEXT_STATE_OFFS 12 +#define REG_DFS_CWL_NEXT_STATE_MASK 0x7 + +#define REG_READ_DATA_SAMPLE_DELAYS_ADDR 0x1538 +#define REG_READ_DATA_SAMPLE_DELAYS_MASK 0x1F +#define REG_READ_DATA_SAMPLE_DELAYS_OFFS 8 + +#define REG_READ_DATA_READY_DELAYS_ADDR 0x153C +#define REG_READ_DATA_READY_DELAYS_MASK 0x1F +#define REG_READ_DATA_READY_DELAYS_OFFS 8 + +#define START_BURST_IN_ADDR 1 + +#define REG_DRAM_TRAINING_SHADOW_ADDR 0x18488 +#define REG_DRAM_TRAINING_ADDR 0x15B0 +#define REG_DRAM_TRAINING_LOW_FREQ_OFFS 0 +#define REG_DRAM_TRAINING_PATTERNS_OFFS 4 +#define REG_DRAM_TRAINING_MED_FREQ_OFFS 2 +#define REG_DRAM_TRAINING_WL_OFFS 3 +#define REG_DRAM_TRAINING_RL_OFFS 6 +#define REG_DRAM_TRAINING_DQS_RX_OFFS 15 +#define REG_DRAM_TRAINING_DQS_TX_OFFS 16 +#define REG_DRAM_TRAINING_CS_OFFS 20 +#define REG_DRAM_TRAINING_RETEST_OFFS 24 +#define REG_DRAM_TRAINING_DFS_FREQ_OFFS 27 +#define REG_DRAM_TRAINING_DFS_REQ_OFFS 29 +#define REG_DRAM_TRAINING_ERROR_OFFS 30 +#define REG_DRAM_TRAINING_AUTO_OFFS 31 +#define REG_DRAM_TRAINING_RETEST_PAR 0x3 +#define REG_DRAM_TRAINING_RETEST_MASK 0xF8FFFFFF +#define REG_DRAM_TRAINING_CS_MASK 0xFF0FFFFF +#define REG_DRAM_TRAINING_PATTERNS_MASK 0xFF0F0000 + +#define REG_DRAM_TRAINING_1_ADDR 0x15B4 +#define REG_DRAM_TRAINING_1_TRNBPOINT_OFFS 16 + +#define REG_DRAM_TRAINING_2_ADDR 0x15B8 +#define REG_DRAM_TRAINING_2_OVERRUN_OFFS 17 +#define REG_DRAM_TRAINING_2_FIFO_RST_OFFS 4 +#define REG_DRAM_TRAINING_2_RL_MODE_OFFS 3 +#define REG_DRAM_TRAINING_2_WL_MODE_OFFS 2 +#define REG_DRAM_TRAINING_2_ECC_MUX_OFFS 1 +#define REG_DRAM_TRAINING_2_SW_OVRD_OFFS 0 + +#define REG_DRAM_TRAINING_PATTERN_BASE_ADDR 0x15BC +#define REG_DRAM_TRAINING_PATTERN_BASE_OFFS 3 + +#define REG_TRAINING_DEBUG_2_ADDR 0x15C4 +#define REG_TRAINING_DEBUG_2_OFFS 16 +#define REG_TRAINING_DEBUG_2_MASK 0x3 + +#define REG_TRAINING_DEBUG_3_ADDR 0x15C8 +#define REG_TRAINING_DEBUG_3_OFFS 3 +#define REG_TRAINING_DEBUG_3_MASK 0x7 + +#define MR_CS_ADDR_OFFS 4 + +#define REG_DDR3_MR0_ADDR 0x15D0 +#define REG_DDR3_MR0_CS_ADDR 0x1870 +#define REG_DDR3_MR0_CL_MASK 0x74 +#define REG_DDR3_MR0_CL_OFFS 2 +#define REG_DDR3_MR0_CL_HIGH_OFFS 3 +#define CL_MASK 0xF + +#define REG_DDR3_MR1_ADDR 0x15D4 +#define REG_DDR3_MR1_CS_ADDR 0x1874 +#define REG_DDR3_MR1_RTT_MASK 0xFFFFFDBB +#define REG_DDR3_MR1_DLL_ENA_OFFS 0 +#define REG_DDR3_MR1_RTT_DISABLED 0x0 +#define REG_DDR3_MR1_RTT_RZQ2 0x40 +#define REG_DDR3_MR1_RTT_RZQ4 0x2 +#define REG_DDR3_MR1_RTT_RZQ6 0x42 +#define REG_DDR3_MR1_RTT_RZQ8 0x202 +#define REG_DDR3_MR1_RTT_RZQ12 0x4 +#define REG_DDR3_MR1_OUTBUF_WL_MASK 0xFFFFEF7F /* WL-disabled,OB-enabled */ +#define REG_DDR3_MR1_OUTBUF_DIS_OFFS 12 /* Output Buffer Disabled */ +#define REG_DDR3_MR1_WL_ENA_OFFS 7 +#define REG_DDR3_MR1_WL_ENA 0x80 /* WL Enabled */ +#define REG_DDR3_MR1_ODT_MASK 0xFFFFFDBB + +#define REG_DDR3_MR2_ADDR 0x15D8 +#define REG_DDR3_MR2_CS_ADDR 0x1878 +#define REG_DDR3_MR2_CWL_OFFS 3 +#define REG_DDR3_MR2_CWL_MASK 0x7 +#define REG_DDR3_MR2_ODT_MASK 0xFFFFF9FF +#define REG_DDR3_MR3_ADDR 0x15DC +#define REG_DDR3_MR3_CS_ADDR 0x187C + +#define REG_DDR3_RANK_CTRL_ADDR 0x15E0 +#define REG_DDR3_RANK_CTRL_CS_ENA_MASK 0xF +#define REG_DDR3_RANK_CTRL_MIRROR_OFFS 4 + +#define REG_ZQC_CONF_ADDR 0x15E4 + +#define REG_DRAM_PHY_CONFIG_ADDR 0x15EC +#define REG_DRAM_PHY_CONFIG_MASK 0x3FFFFFFF + +#define REG_ODPG_CNTRL_ADDR 0x1600 +#define REG_ODPG_CNTRL_OFFS 21 + +#define REG_PHY_LOCK_MASK_ADDR 0x1670 +#define REG_PHY_LOCK_MASK_MASK 0xFFFFF000 + +#define REG_PHY_LOCK_STATUS_ADDR 0x1674 +#define REG_PHY_LOCK_STATUS_LOCK_OFFS 9 +#define REG_PHY_LOCK_STATUS_LOCK_MASK 0xFFF +#define REG_PHY_LOCK_APLL_ADLL_STATUS_MASK 0x7FF + +#define REG_PHY_REGISTRY_FILE_ACCESS_ADDR 0x16A0 +#define REG_PHY_REGISTRY_FILE_ACCESS_OP_WR 0xC0000000 +#define REG_PHY_REGISTRY_FILE_ACCESS_OP_RD 0x80000000 +#define REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE 0x80000000 +#define REG_PHY_BC_OFFS 27 +#define REG_PHY_CNTRL_OFFS 26 +#define REG_PHY_CS_OFFS 16 +#define REG_PHY_DQS_REF_DLY_OFFS 10 +#define REG_PHY_PHASE_OFFS 8 +#define REG_PHY_PUP_OFFS 22 + +#define REG_TRAINING_WL_ADDR 0x16AC +#define REG_TRAINING_WL_CS_MASK 0xFFFFFFFC +#define REG_TRAINING_WL_UPD_OFFS 2 +#define REG_TRAINING_WL_CS_DONE_OFFS 3 +#define REG_TRAINING_WL_RATIO_MASK 0xFFFFFF0F +#define REG_TRAINING_WL_1TO1 0x50 +#define REG_TRAINING_WL_2TO1 0x10 +#define REG_TRAINING_WL_DELAYEXP_MASK 0x20000000 +#define REG_TRAINING_WL_RESULTS_MASK 0x000001FF +#define REG_TRAINING_WL_RESULTS_OFFS 20 + +#define REG_REGISTERED_DRAM_CTRL_ADDR 0x16D0 +#define REG_REGISTERED_DRAM_CTRL_SR_FLOAT_OFFS 15 +#define REG_REGISTERED_DRAM_CTRL_PARITY_MASK 0x3F +/* DLB*/ +#define REG_STATIC_DRAM_DLB_CONTROL 0x1700 +#define DLB_BUS_OPTIMIZATION_WEIGHTS_REG 0x1704 +#define DLB_AGING_REGISTER 0x1708 +#define DLB_EVICTION_CONTROL_REG 0x170c +#define DLB_EVICTION_TIMERS_REGISTER_REG 0x1710 + +#define DLB_ENABLE 0x1 +#define DLB_WRITE_COALESING (0x1 << 2) +#define DLB_AXI_PREFETCH_EN (0x1 << 3) +#define DLB_MBUS_PREFETCH_EN (0x1 << 4) +#define PREFETCH_NLNSZTR (0x1 << 6) + +/* CPU */ +#define REG_BOOTROM_ROUTINE_ADDR 0x182D0 +#define REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS 12 + +#define REG_DRAM_INIT_CTRL_STATUS_ADDR 0x18488 +#define REG_DRAM_INIT_CTRL_TRN_CLK_OFFS 16 +#define REG_CPU_DIV_CLK_CTRL_0_NEW_RATIO 0x000200FF +#define REG_DRAM_INIT_CTRL_STATUS_2_ADDR 0x1488 + +#define REG_CPU_DIV_CLK_CTRL_0_ADDR 0x18700 + +#define REG_CPU_DIV_CLK_CTRL_1_ADDR 0x18704 +#define REG_CPU_DIV_CLK_CTRL_2_ADDR 0x18708 + +#define REG_CPU_DIV_CLK_CTRL_3_ADDR 0x1870C +#define REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK 0xFFFFC0FF +#define REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS 8 + +#define REG_CPU_DIV_CLK_CTRL_4_ADDR 0x18710 + +#define REG_CPU_DIV_CLK_STATUS_0_ADDR 0x18718 +#define REG_CPU_DIV_CLK_ALL_STABLE_OFFS 8 + +#define REG_CPU_PLL_CTRL_0_ADDR 0x1871C +#define REG_CPU_PLL_STATUS_0_ADDR 0x18724 +#define REG_CORE_DIV_CLK_CTRL_ADDR 0x18740 +#define REG_CORE_DIV_CLK_STATUS_ADDR 0x18744 +#define REG_DDRPHY_APLL_CTRL_ADDR 0x18780 + +#define REG_DDRPHY_APLL_CTRL_2_ADDR 0x18784 + +#define REG_SFABRIC_CLK_CTRL_ADDR 0x20858 +#define REG_SFABRIC_CLK_CTRL_SMPL_OFFS 8 + +/* DRAM Windows */ +#define REG_XBAR_WIN_19_CTRL_ADDR 0x200e8 +#define REG_XBAR_WIN_4_CTRL_ADDR 0x20040 +#define REG_XBAR_WIN_4_BASE_ADDR 0x20044 +#define REG_XBAR_WIN_4_REMAP_ADDR 0x20048 +#define REG_FASTPATH_WIN_0_CTRL_ADDR 0x20184 +#define REG_XBAR_WIN_7_REMAP_ADDR 0x20078 + +/* SRAM */ +#define REG_CDI_CONFIG_ADDR 0x20220 +#define REG_SRAM_WINDOW_0_ADDR 0x20240 +#define REG_SRAM_WINDOW_0_ENA_OFFS 0 +#define REG_SRAM_WINDOW_1_ADDR 0x20244 +#define REG_SRAM_L2_ENA_ADDR 0x8500 +#define REG_SRAM_CLEAN_BY_WAY_ADDR 0x87BC + +/* PMU */ +#define REG_PMU_I_F_CTRL_ADDR 0x1C090 +#define REG_PMU_DUNIT_BLK_OFFS 16 +#define REG_PMU_DUNIT_RFRS_OFFS 20 +#define REG_PMU_DUNIT_ACK_OFFS 24 + +/* MBUS*/ +#define MBUS_UNITS_PRIORITY_CONTROL_REG (MV_MBUS_REGS_OFFSET + 0x420) +#define FABRIC_UNITS_PRIORITY_CONTROL_REG (MV_MBUS_REGS_OFFSET + 0x424) +#define MBUS_UNITS_PREFETCH_CONTROL_REG (MV_MBUS_REGS_OFFSET + 0x428) +#define FABRIC_UNITS_PREFETCH_CONTROL_REG (MV_MBUS_REGS_OFFSET + 0x42c) + +#define REG_PM_STAT_MASK_ADDR 0x2210C +#define REG_PM_STAT_MASK_CPU0_IDLE_MASK_OFFS 16 + +#define REG_PM_EVENT_STAT_MASK_ADDR 0x22120 +#define REG_PM_EVENT_STAT_MASK_DFS_DONE_OFFS 17 + +#define REG_PM_CTRL_CONFIG_ADDR 0x22104 +#define REG_PM_CTRL_CONFIG_DFS_REQ_OFFS 18 + +#define REG_FABRIC_LOCAL_IRQ_MASK_ADDR 0x218C4 +#define REG_FABRIC_LOCAL_IRQ_PMU_MASK_OFFS 18 + +/* Controller revision info */ +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define PCCRIR_REVID_OFFS 0 /* Revision ID */ +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS) + +/* Power Management Clock Gating Control Register */ +#define MV_PEX_IF_REGS_OFFSET(if) \ + (if < 8 ? (0x40000 + ((if) / 4) * 0x40000 + ((if) % 4) * 0x4000) \ + : (0x42000 + ((if) % 8) * 0x40000)) +#define MV_PEX_IF_REGS_BASE(unit) (MV_PEX_IF_REGS_OFFSET(unit)) +#define POWER_MNG_CTRL_REG 0x18220 +#define PEX_DEVICE_AND_VENDOR_ID 0x000 +#define PEX_CFG_DIRECT_ACCESS(if, reg) (MV_PEX_IF_REGS_BASE(if) + (reg)) +#define PMC_PEXSTOPCLOCK_OFFS(port) ((port) < 8 ? (5 + (port)) : (18 + (port))) +#define PMC_PEXSTOPCLOCK_MASK(port) (1 << PMC_PEXSTOPCLOCK_OFFS(port)) +#define PMC_PEXSTOPCLOCK_EN(port) (1 << PMC_PEXSTOPCLOCK_OFFS(port)) +#define PMC_PEXSTOPCLOCK_STOP(port) (0 << PMC_PEXSTOPCLOCK_OFFS(port)) + +/* TWSI */ +#define TWSI_DATA_ADDR_MASK 0x7 +#define TWSI_DATA_ADDR_OFFS 1 + +/* General */ +#define MAX_CS 4 + +/* Frequencies */ +#define FAB_OPT 21 +#define CLK_CPU 12 +#define CLK_VCO (2 * CLK_CPU) +#define CLK_DDR 12 + +/* Cpu Frequencies: */ +#define CLK_CPU_1000 0 +#define CLK_CPU_1066 1 +#define CLK_CPU_1200 2 +#define CLK_CPU_1333 3 +#define CLK_CPU_1500 4 +#define CLK_CPU_1666 5 +#define CLK_CPU_1800 6 +#define CLK_CPU_2000 7 +#define CLK_CPU_600 8 +#define CLK_CPU_667 9 +#define CLK_CPU_800 0xa + +/* Extra Cpu Frequencies: */ +#define CLK_CPU_1600 11 +#define CLK_CPU_2133 12 +#define CLK_CPU_2200 13 +#define CLK_CPU_2400 14 + +/* DDR3 Frequencies: */ +#define DDR_100 0 +#define DDR_300 1 +#define DDR_333 1 +#define DDR_360 2 +#define DDR_400 3 +#define DDR_444 4 +#define DDR_500 5 +#define DDR_533 6 +#define DDR_600 7 +#define DDR_640 8 +#define DDR_666 8 +#define DDR_720 9 +#define DDR_750 9 +#define DDR_800 10 +#define DDR_833 11 +#define DDR_HCLK 20 +#define DDR_S 12 +#define DDR_S_1TO1 13 +#define MARGIN_FREQ DDR_400 +#define DFS_MARGIN DDR_100 + +#define ODT_OPT 16 +#define ODT20 0x200 +#define ODT30 0x204 +#define ODT40 0x44 +#define ODT120 0x40 +#define ODT120D 0x400 + +#define MRS_DELAY 100 + +#define SDRAM_WL_SW_OFFS 0x100 +#define SDRAM_RL_OFFS 0x0 +#define SDRAM_PBS_I_OFFS 0x140 +#define SDRAM_PBS_II_OFFS 0x180 +#define SDRAM_PBS_NEXT_OFFS (SDRAM_PBS_II_OFFS - SDRAM_PBS_I_OFFS) +#define SDRAM_PBS_TX_OFFS 0x180 +#define SDRAM_PBS_TX_DM_OFFS 576 +#define SDRAM_DQS_RX_OFFS 1024 +#define SDRAM_DQS_TX_OFFS 2048 +#define SDRAM_DQS_RX_SPECIAL_OFFS 5120 + +#define LEN_STD_PATTERN 16 +#define LEN_KILLER_PATTERN 128 +#define LEN_SPECIAL_PATTERN 128 +#define LEN_PBS_PATTERN 16 + +#endif /* __DDR3_AXP_H */ diff --git a/drivers/ddr/mvebu/ddr3_axp_config.h b/drivers/ddr/mvebu/ddr3_axp_config.h new file mode 100644 index 0000000000..800d2d1476 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_axp_config.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DDR3_AXP_CONFIG_H +#define __DDR3_AXP_CONFIG_H + +/* + * DDR3_LOG_LEVEL Information + * + * Level 0: Provides an error code in a case of failure, RL, WL errors + * and other algorithm failure + * Level 1: Provides the D-Unit setup (SPD/Static configuration) + * Level 2: Provides the windows margin as a results of DQS centeralization + * Level 3: Provides the windows margin of each DQ as a results of DQS + * centeralization + */ +#ifdef CONFIG_DDR_LOG_LEVEL +#define DDR3_LOG_LEVEL CONFIG_DDR_LOG_LEVEL +#else +#define DDR3_LOG_LEVEL 0 +#endif + +#define DDR3_PBS 1 + +/* This flag allows the execution of SW WL/RL upon HW failure */ +#define DDR3_RUN_SW_WHEN_HW_FAIL 1 + +/* + * General Configurations + * + * The following parameters are required for proper setup: + * + * DDR_TARGET_FABRIC - Set desired fabric configuration + * (for sample@Reset fabfreq parameter) + * DRAM_ECC - Set ECC support 1/0 + * BUS_WIDTH - 64/32 bit + * CONFIG_SPD_EEPROM - Enables auto detection of DIMMs and their timing values + * DQS_CLK_ALIGNED - Set this if CLK and DQS signals are aligned on board + * MIXED_DIMM_STATIC - Mixed DIMM + On board devices support (ODT registers + * values are taken statically) + * DDR3_TRAINING_DEBUG - Debug prints of internal code + */ +#define DDR_TARGET_FABRIC 5 +#define DRAM_ECC 0 + +#ifdef MV_DDR_32BIT +#define BUS_WIDTH 32 +#else +#define BUS_WIDTH 64 +#endif + +#undef DQS_CLK_ALIGNED +#undef MIXED_DIMM_STATIC +#define DDR3_TRAINING_DEBUG 0 +#define REG_DIMM_SKIP_WL 0 + +/* Marvell boards specific configurations */ +#if defined(DB_78X60_PCAC) +#undef CONFIG_SPD_EEPROM +#define STATIC_TRAINING +#endif + +#if defined(DB_78X60_AMC) +#undef CONFIG_SPD_EEPROM +#undef DRAM_ECC +#define DRAM_ECC 1 +#endif + +#ifdef CONFIG_SPD_EEPROM +/* + * DIMM support parameters: + * DRAM_2T - Set Desired 2T Mode - 0 - 1T, 0x1 - 2T, 0x2 - 3T + * DIMM_CS_BITMAP - bitmap representing the optional CS in DIMMs + * (0xF=CS0+CS1+CS2+CS3, 0xC=CS2+CS3...) + */ +#define DRAM_2T 0x0 +#define DIMM_CS_BITMAP 0xF +#define DUNIT_SPD +#endif + +#ifdef DRAM_ECC +/* + * ECC support parameters: + * + * U_BOOT_START_ADDR, U_BOOT_SCRUB_SIZE - relevant when using ECC and need + * to configure the scrubbing area + */ +#define TRAINING_SIZE 0x20000 +#define U_BOOT_START_ADDR 0 +#define U_BOOT_SCRUB_SIZE 0x1000000 /* TRAINING_SIZE */ +#endif + +/* + * Registered DIMM Support - In case registered DIMM is attached, + * please supply the following values: + * (see JEDEC - JESD82-29A "Definition of the SSTE32882 Registering Clock + * Driver with Parity and Quad Chip + * Selects for DDR3/DDR3L/DDR3U RDIMM 1.5 V/1.35 V/1.25 V Applications") + * RC0: Global Features Control Word + * RC1: Clock Driver Enable Control Word + * RC2: Timing Control Word + * RC3-RC5 - taken from SPD + * RC8: Additional IBT Setting Control Word + * RC9: Power Saving Settings Control Word + * RC10: Encoding for RDIMM Operating Speed + * RC11: Operating Voltage VDD and VREFCA Control Word + */ +#define RDIMM_RC0 0 +#define RDIMM_RC1 0 +#define RDIMM_RC2 0 +#define RDIMM_RC8 0 +#define RDIMM_RC9 0 +#define RDIMM_RC10 0x2 +#define RDIMM_RC11 0x0 + +#if defined(MIXED_DIMM_STATIC) || !defined(CONFIG_SPD_EEPROM) +#define DUNIT_STATIC +#endif + +#if defined(MIXED_DIMM_STATIC) || defined(CONFIG_SPD_EEPROM) +/* + * This flag allows the user to change the dram refresh cycle in ps, + * only in case of SPD or MIX DIMM topology + */ +#define TREFI_USER_EN + +#ifdef TREFI_USER_EN +#define TREFI_USER 3900000 +#endif +#endif + +#ifdef CONFIG_SPD_EEPROM +/* + * AUTO_DETECTION_SUPPORT - relevant ONLY for Marvell DB boards. + * Enables I2C auto detection different options + */ +#if defined(CONFIG_DB_88F78X60) || defined(CONFIG_DB_88F78X60_REV2) || \ + defined(CONFIG_DB_784MP_GP) +#define AUTO_DETECTION_SUPPORT +#endif +#endif + +#endif /* __DDR3_AXP_CONFIG_H */ diff --git a/drivers/ddr/mvebu/ddr3_axp_mc_static.h b/drivers/ddr/mvebu/ddr3_axp_mc_static.h new file mode 100644 index 0000000000..2c0e9075e9 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_axp_mc_static.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __AXP_MC_STATIC_H +#define __AXP_MC_STATIC_H + +MV_DRAM_MC_INIT ddr3_A0_db_667[MV_MAX_DDR3_STATIC_SIZE] = { +#ifdef MV_DDR_32BIT + {0x00001400, 0x7301c924}, /*DDR SDRAM Configuration Register */ +#else /*MV_DDR_64BIT */ + {0x00001400, 0x7301CA28}, /*DDR SDRAM Configuration Register */ +#endif + {0x00001404, 0x3630b800}, /*Dunit Control Low Register */ + {0x00001408, 0x43149775}, /*DDR SDRAM Timing (Low) Register */ + /* {0x0000140C, 0x38000C6A}, *//*DDR SDRAM Timing (High) Register */ + {0x0000140C, 0x38d83fe0}, /*DDR SDRAM Timing (High) Register */ + +#ifdef DB_78X60_PCAC + {0x00001410, 0x040F0001}, /*DDR SDRAM Address Control Register */ +#else + {0x00001410, 0x040F0000}, /*DDR SDRAM Open Pages Control Register */ +#endif + + {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */ + {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */ + {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0000D3FF}, /*Dunit Control High Register */ + {0x00001428, 0x000F8830}, /*Dunit Control High Register */ + {0x0000142C, 0x214C2F38}, /*Dunit Control High Register */ + {0x0000147C, 0x0000c671}, + + {0x000014a0, 0x000002A9}, + {0x000014a8, 0x00000101}, /*2:1 */ + {0x00020220, 0x00000007}, + + {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */ + {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */ + {0x0000149C, 0x00000301}, /*DDR Dunit ODT Control Register */ + + {0x000014C0, 0x192434e9}, /* DRAM address and Control Driving Strenght */ + {0x000014C4, 0x092434e9}, /* DRAM Data and DQS Driving Strenght */ + + {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence */ + {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */ + + {0x0001504, 0x7FFFFFF1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + /* {0x00001524, 0x0000C800}, */ + {0x00001538, 0x0000000b}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000d}, /*Read Data Ready Delay Register */ + + {0x000015D0, 0x00000640}, /*MR0 */ + {0x000015D4, 0x00000046}, /*MR1 */ + {0x000015D8, 0x00000010}, /*MR2 */ + {0x000015DC, 0x00000000}, /*MR3 */ + + {0x000015E4, 0x00203c18}, /*ZQC Configuration Register */ + {0x000015EC, 0xd800aa25}, /*DDR PHY */ + {0x0, 0x0} +}; + +MV_DRAM_MC_INIT ddr3_A0_AMC_667[MV_MAX_DDR3_STATIC_SIZE] = { +#ifdef MV_DDR_32BIT + {0x00001400, 0x7301c924}, /*DDR SDRAM Configuration Register */ +#else /*MV_DDR_64BIT */ + {0x00001400, 0x7301CA28}, /*DDR SDRAM Configuration Register */ +#endif + {0x00001404, 0x3630b800}, /*Dunit Control Low Register */ + {0x00001408, 0x43149775}, /*DDR SDRAM Timing (Low) Register */ + /* {0x0000140C, 0x38000C6A}, *//*DDR SDRAM Timing (High) Register */ + {0x0000140C, 0x38d83fe0}, /*DDR SDRAM Timing (High) Register */ + +#ifdef DB_78X60_PCAC + {0x00001410, 0x040F0001}, /*DDR SDRAM Address Control Register */ +#else + {0x00001410, 0x040F000C}, /*DDR SDRAM Open Pages Control Register */ +#endif + + {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */ + {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */ + {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0000D3FF}, /*Dunit Control High Register */ + {0x00001428, 0x000F8830}, /*Dunit Control High Register */ + {0x0000142C, 0x214C2F38}, /*Dunit Control High Register */ + {0x0000147C, 0x0000c671}, + + {0x000014a0, 0x000002A9}, + {0x000014a8, 0x00000101}, /*2:1 */ + {0x00020220, 0x00000007}, + + {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */ + {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */ + {0x0000149C, 0x00000301}, /*DDR Dunit ODT Control Register */ + + {0x000014C0, 0x192434e9}, /* DRAM address and Control Driving Strenght */ + {0x000014C4, 0x092434e9}, /* DRAM Data and DQS Driving Strenght */ + + {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence */ + {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */ + + {0x0001504, 0x3FFFFFF1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + /* {0x00001524, 0x0000C800}, */ + {0x00001538, 0x0000000b}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000d}, /*Read Data Ready Delay Register */ + + {0x000015D0, 0x00000640}, /*MR0 */ + {0x000015D4, 0x00000046}, /*MR1 */ + {0x000015D8, 0x00000010}, /*MR2 */ + {0x000015DC, 0x00000000}, /*MR3 */ + + {0x000015E4, 0x00203c18}, /*ZQC Configuration Register */ + {0x000015EC, 0xd800aa25}, /*DDR PHY */ + {0x0, 0x0} +}; + +MV_DRAM_MC_INIT ddr3_A0_db_400[MV_MAX_DDR3_STATIC_SIZE] = { +#ifdef MV_DDR_32BIT + {0x00001400, 0x73004C30}, /*DDR SDRAM Configuration Register */ +#else /* MV_DDR_64BIT */ + {0x00001400, 0x7300CC30}, /*DDR SDRAM Configuration Register */ +#endif + {0x00001404, 0x3630B840}, /*Dunit Control Low Register */ + {0x00001408, 0x33137663}, /*DDR SDRAM Timing (Low) Register */ + {0x0000140C, 0x38000C55}, /*DDR SDRAM Timing (High) Register */ + {0x00001410, 0x040F0000}, /*DDR SDRAM Address Control Register */ + {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */ + {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */ + {0x0000141C, 0x00000672}, /*DDR SDRAM Mode Register */ + {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0100D3FF}, /*Dunit Control High Register */ + {0x00001428, 0x000D6720}, /*Dunit Control High Register */ + {0x0000142C, 0x014C2F38}, /*Dunit Control High Register */ + {0x0000147C, 0x00006571}, + + {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */ + {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */ + {0x0000149C, 0x00000301}, /*DDR Dunit ODT Control Register */ + + {0x000014a0, 0x000002A9}, + {0x000014a8, 0x00000101}, /*2:1 */ + {0x00020220, 0x00000007}, + + {0x000014C0, 0x192424C8}, /* DRAM address and Control Driving Strenght */ + {0x000014C4, 0xEFB24C8}, /* DRAM Data and DQS Driving Strenght */ + + {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence */ + {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */ + + {0x0001504, 0x7FFFFFF1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + {0x00001538, 0x00000008}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000A}, /*Read Data Ready Delay Register */ + + {0x000015D0, 0x00000630}, /*MR0 */ + {0x000015D4, 0x00000046}, /*MR1 */ + {0x000015D8, 0x00000008}, /*MR2 */ + {0x000015DC, 0x00000000}, /*MR3 */ + + {0x000015E4, 0x00203c18}, /*ZQDS Configuration Register */ + /* {0x000015EC, 0xDE000025}, *//*DDR PHY */ + {0x000015EC, 0xF800AA25}, /*DDR PHY */ + {0x0, 0x0} +}; + +MV_DRAM_MC_INIT ddr3_Z1_db_600[MV_MAX_DDR3_STATIC_SIZE] = { +#ifdef MV_DDR_32BIT + {0x00001400, 0x73014A28}, /*DDR SDRAM Configuration Register */ +#else /*MV_DDR_64BIT */ + {0x00001400, 0x7301CA28}, /*DDR SDRAM Configuration Register */ +#endif + {0x00001404, 0x3630B040}, /*Dunit Control Low Register */ + {0x00001408, 0x44149887}, /*DDR SDRAM Timing (Low) Register */ + /* {0x0000140C, 0x38000C6A}, *//*DDR SDRAM Timing (High) Register */ + {0x0000140C, 0x38D83FE0}, /*DDR SDRAM Timing (High) Register */ + +#ifdef DB_78X60_PCAC + {0x00001410, 0x040F0001}, /*DDR SDRAM Address Control Register */ +#else + {0x00001410, 0x040F0000}, /*DDR SDRAM Open Pages Control Register */ +#endif + + {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */ + {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */ + {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0100D1FF}, /*Dunit Control High Register */ + {0x00001428, 0x000F8830}, /*Dunit Control High Register */ + {0x0000142C, 0x214C2F38}, /*Dunit Control High Register */ + {0x0000147C, 0x0000c671}, + + {0x000014a8, 0x00000101}, /*2:1 */ + {0x00020220, 0x00000007}, + + {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */ + {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */ + {0x0000149C, 0x00000301}, /*DDR Dunit ODT Control Register */ + + {0x000014C0, 0x192424C8}, /* DRAM address and Control Driving Strenght */ + {0x000014C4, 0xEFB24C8}, /* DRAM Data and DQS Driving Strenght */ + + {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence */ + {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */ + + {0x0001504, 0x7FFFFFF1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + /* {0x00001524, 0x0000C800}, */ + {0x00001538, 0x0000000b}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000d}, /*Read Data Ready Delay Register */ + + {0x000015D0, 0x00000650}, /*MR0 */ + {0x000015D4, 0x00000046}, /*MR1 */ + {0x000015D8, 0x00000010}, /*MR2 */ + {0x000015DC, 0x00000000}, /*MR3 */ + + {0x000015E4, 0x00203c18}, /*ZQC Configuration Register */ + {0x000015EC, 0xDE000025}, /*DDR PHY */ + {0x0, 0x0} +}; + +MV_DRAM_MC_INIT ddr3_Z1_db_300[MV_MAX_DDR3_STATIC_SIZE] = { +#ifdef MV_DDR_32BIT + {0x00001400, 0x73004C30}, /*DDR SDRAM Configuration Register */ +#else /*MV_DDR_64BIT */ + {0x00001400, 0x7300CC30}, /*DDR SDRAM Configuration Register */ + /*{0x00001400, 0x7304CC30}, *//*DDR SDRAM Configuration Register */ +#endif + {0x00001404, 0x3630B840}, /*Dunit Control Low Register */ + {0x00001408, 0x33137663}, /*DDR SDRAM Timing (Low) Register */ + {0x0000140C, 0x38000C55}, /*DDR SDRAM Timing (High) Register */ + {0x00001410, 0x040F0000}, /*DDR SDRAM Address Control Register */ + {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */ + {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */ + {0x0000141C, 0x00000672}, /*DDR SDRAM Mode Register */ + {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */ + {0x00001424, 0x0100F1FF}, /*Dunit Control High Register */ + {0x00001428, 0x000D6720}, /*Dunit Control High Register */ + {0x0000142C, 0x014C2F38}, /*Dunit Control High Register */ + {0x0000147C, 0x00006571}, + + {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */ + {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */ + {0x0000149C, 0x00000301}, /*DDR Dunit ODT Control Register */ + + {0x000014C0, 0x192424C8}, /* DRAM address and Control Driving Strenght */ + {0x000014C4, 0xEFB24C8}, /* DRAM Data and DQS Driving Strenght */ + + {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence */ + {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */ + + {0x0001504, 0x7FFFFFF1}, /* CS0 Size */ + {0x000150C, 0x00000000}, /* CS1 Size */ + {0x0001514, 0x00000000}, /* CS2 Size */ + {0x000151C, 0x00000000}, /* CS3 Size */ + + {0x00001538, 0x00000008}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000A}, /*Read Data Ready Delay Register */ + + {0x000015D0, 0x00000630}, /*MR0 */ + {0x000015D4, 0x00000046}, /*MR1 */ + {0x000015D8, 0x00000008}, /*MR2 */ + {0x000015DC, 0x00000000}, /*MR3 */ + + {0x000015E4, 0x00203c18}, /*ZQDS Configuration Register */ + {0x000015EC, 0xDE000025}, /*DDR PHY */ + + {0x0, 0x0} +}; + +#endif /* __AXP_MC_STATIC_H */ diff --git a/drivers/ddr/mvebu/ddr3_axp_training_static.h b/drivers/ddr/mvebu/ddr3_axp_training_static.h new file mode 100644 index 0000000000..4e615479ad --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_axp_training_static.h @@ -0,0 +1,770 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __AXP_TRAINING_STATIC_H +#define __AXP_TRAINING_STATIC_H + +/* + * STATIC_TRAINING - Set only if static parameters for training are set and + * required + */ + +MV_DRAM_TRAINING_INIT ddr3_db_rev2_667[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC002011A}, + /*1 */ + {0x000016A0, 0xC0420100}, + /*2 */ + {0x000016A0, 0xC082020A}, + /*3 */ + {0x000016A0, 0xC0C20017}, + /*4 */ + {0x000016A0, 0xC1020113}, + /*5 */ + {0x000016A0, 0xC1420107}, + /*6 */ + {0x000016A0, 0xC182011F}, + /*7 */ + {0x000016A0, 0xC1C2001C}, + /*8 */ + {0x000016A0, 0xC202010D}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0004A06}, + /*1 */ + {0x000016A0, 0xC040690D}, + /*2 */ + {0x000016A0, 0xC0806A0D}, + /*3 */ + {0x000016A0, 0xC0C0A01B}, + /*4 */ + {0x000016A0, 0xC1003A01}, + /*5 */ + {0x000016A0, 0xC1408113}, + /*6 */ + {0x000016A0, 0xC1805609}, + /*7 */ + {0x000016A0, 0xC1C04504}, + /*8 */ + {0x000016A0, 0xC2009518}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_rev2_800[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC0020301}, + /*1 */ + {0x000016A0, 0xC0420202}, + /*2 */ + {0x000016A0, 0xC0820314}, + /*3 */ + {0x000016A0, 0xC0C20117}, + /*4 */ + {0x000016A0, 0xC1020219}, + /*5 */ + {0x000016A0, 0xC142020B}, + /*6 */ + {0x000016A0, 0xC182030A}, + /*7 */ + {0x000016A0, 0xC1C2011D}, + /*8 */ + {0x000016A0, 0xC2020212}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0007A12}, + /*1 */ + {0x000016A0, 0xC0408D16}, + /*2 */ + {0x000016A0, 0xC0809E1B}, + /*3 */ + {0x000016A0, 0xC0C0AC1F}, + /*4 */ + {0x000016A0, 0xC1005E0A}, + /*5 */ + {0x000016A0, 0xC140A91D}, + /*6 */ + {0x000016A0, 0xC1808E17}, + /*7 */ + {0x000016A0, 0xC1C05509}, + /*8 */ + {0x000016A0, 0xC2003A01}, + + /* PBS Leveling */ + /*0 */ + {0x000016A0, 0xC0007A12}, + /*1 */ + {0x000016A0, 0xC0408D16}, + /*2 */ + {0x000016A0, 0xC0809E1B}, + /*3 */ + {0x000016A0, 0xC0C0AC1F}, + /*4 */ + {0x000016A0, 0xC1005E0A}, + /*5 */ + {0x000016A0, 0xC140A91D}, + /*6 */ + {0x000016A0, 0xC1808E17}, + /*7 */ + {0x000016A0, 0xC1C05509}, + /*8 */ + {0x000016A0, 0xC2003A01}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000B}, + + {0x00001538, 0x0000000D}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x00000011}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_400[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 2 4 15 */ + {0x000016A0, 0xC002010C}, + /*1 2 4 2 */ + {0x000016A0, 0xC042001C}, + /*2 2 4 27 */ + {0x000016A0, 0xC0820115}, + /*3 2 4 0 */ + {0x000016A0, 0xC0C20019}, + /*4 2 4 13 */ + {0x000016A0, 0xC1020108}, + /*5 2 4 5 */ + {0x000016A0, 0xC1420100}, + /*6 2 4 19 */ + {0x000016A0, 0xC1820111}, + /*7 2 4 0 */ + {0x000016A0, 0xC1C2001B}, + /*8 2 4 10 */ + /*{0x000016A0, 0xC2020117}, */ + {0x000016A0, 0xC202010C}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0005508}, + /*1 */ + {0x000016A0, 0xC0409819}, + /*2 */ + {0x000016A0, 0xC080650C}, + /*3 */ + {0x000016A0, 0xC0C0700F}, + /*4 */ + {0x000016A0, 0xC1004103}, + /*5 */ + {0x000016A0, 0xC140A81D}, + /*6 */ + {0x000016A0, 0xC180650C}, + /*7 */ + {0x000016A0, 0xC1C08013}, + /*8 */ + {0x000016A0, 0xC2005508}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x00000008}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000A}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_533[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 2 4 15 */ + {0x000016A0, 0xC002040C}, + /*1 2 4 2 */ + {0x000016A0, 0xC0420117}, + /*2 2 4 27 */ + {0x000016A0, 0xC082041B}, + /*3 2 4 0 */ + {0x000016A0, 0xC0C20117}, + /*4 2 4 13 */ + {0x000016A0, 0xC102040A}, + /*5 2 4 5 */ + {0x000016A0, 0xC1420117}, + /*6 2 4 19 */ + {0x000016A0, 0xC1820419}, + /*7 2 4 0 */ + {0x000016A0, 0xC1C20117}, + /*8 2 4 10 */ + {0x000016A0, 0xC2020117}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0008113}, + /*1 */ + {0x000016A0, 0xC0404504}, + /*2 */ + {0x000016A0, 0xC0808514}, + /*3 */ + {0x000016A0, 0xC0C09418}, + /*4 */ + {0x000016A0, 0xC1006D0E}, + /*5 */ + {0x000016A0, 0xC1405508}, + /*6 */ + {0x000016A0, 0xC1807D12}, + /*7 */ + {0x000016A0, 0xC1C0b01F}, + /*8 */ + {0x000016A0, 0xC2005D0A}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x00000008}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000A}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_600[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 2 3 1 */ + {0x000016A0, 0xC0020104}, + /*1 2 2 6 */ + {0x000016A0, 0xC0420010}, + /*2 2 3 16 */ + {0x000016A0, 0xC0820112}, + /*3 2 1 26 */ + {0x000016A0, 0xC0C20009}, + /*4 2 2 29 */ + {0x000016A0, 0xC102001F}, + /*5 2 2 13 */ + {0x000016A0, 0xC1420014}, + /*6 2 3 6 */ + {0x000016A0, 0xC1820109}, + /*7 2 1 31 */ + {0x000016A0, 0xC1C2000C}, + /*8 2 2 22 */ + {0x000016A0, 0xC2020112}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0009919}, + /*1 */ + {0x000016A0, 0xC0405508}, + /*2 */ + {0x000016A0, 0xC0809919}, + /*3 */ + {0x000016A0, 0xC0C09C1A}, + /*4 */ + {0x000016A0, 0xC1008113}, + /*5 */ + {0x000016A0, 0xC140650C}, + /*6 */ + {0x000016A0, 0xC1809518}, + /*7 */ + {0x000016A0, 0xC1C04103}, + /*8 */ + {0x000016A0, 0xC2006D0E}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_667[MV_MAX_DDR3_STATIC_SIZE] = { + + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 2 3 1 */ + {0x000016A0, 0xC0020103}, + /*1 2 2 6 */ + {0x000016A0, 0xC0420012}, + /*2 2 3 16 */ + {0x000016A0, 0xC0820113}, + /*3 2 1 26 */ + {0x000016A0, 0xC0C20012}, + /*4 2 2 29 */ + {0x000016A0, 0xC1020100}, + /*5 2 2 13 */ + {0x000016A0, 0xC1420016}, + /*6 2 3 6 */ + {0x000016A0, 0xC1820109}, + /*7 2 1 31 */ + {0x000016A0, 0xC1C20010}, + /*8 2 2 22 */ + {0x000016A0, 0xC2020112}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC000b11F}, + /*1 */ + {0x000016A0, 0xC040690D}, + /*2 */ + {0x000016A0, 0xC0803600}, + /*3 */ + {0x000016A0, 0xC0C0a81D}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC180ad1e}, + /*7 */ + {0x000016A0, 0xC1C04d06}, + /*8 */ + {0x000016A0, 0xC2008514}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_800[MV_MAX_DDR3_STATIC_SIZE] = { + + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 2 3 1 */ + {0x000016A0, 0xC0020213}, + /*1 2 2 6 */ + {0x000016A0, 0xC0420108}, + /*2 2 3 16 */ + {0x000016A0, 0xC0820210}, + /*3 2 1 26 */ + {0x000016A0, 0xC0C20108}, + /*4 2 2 29 */ + {0x000016A0, 0xC102011A}, + /*5 2 2 13 */ + {0x000016A0, 0xC1420300}, + /*6 2 3 6 */ + {0x000016A0, 0xC1820204}, + /*7 2 1 31 */ + {0x000016A0, 0xC1C20106}, + /*8 2 2 22 */ + {0x000016A0, 0xC2020112}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC000620B}, + /*1 */ + {0x000016A0, 0xC0408D16}, + /*2 */ + {0x000016A0, 0xC0806A0D}, + /*3 */ + {0x000016A0, 0xC0C03D02}, + /*4 */ + {0x000016A0, 0xC1004a05}, + /*5 */ + {0x000016A0, 0xC140A11B}, + /*6 */ + {0x000016A0, 0xC1805E0A}, + /*7 */ + {0x000016A0, 0xC1C06D0E}, + /*8 */ + {0x000016A0, 0xC200AD1E}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000C}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000E}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_rd_667_0[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC002010E}, + /*1 */ + {0x000016A0, 0xC042001E}, + /*2 */ + {0x000016A0, 0xC0820118}, + /*3 */ + {0x000016A0, 0xC0C2001E}, + /*4 */ + {0x000016A0, 0xC102010C}, + /*5 */ + {0x000016A0, 0xC1420102}, + /*6 */ + {0x000016A0, 0xC1820111}, + /*7 */ + {0x000016A0, 0xC1C2001C}, + /*8 */ + {0x000016A0, 0xC2020109}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0003600}, + /*1 */ + {0x000016A0, 0xC040690D}, + /*2 */ + {0x000016A0, 0xC0805207}, + /*3 */ + {0x000016A0, 0xC0C0A81D}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC1803E02}, + /*7 */ + {0x000016A0, 0xC1C05107}, + /*8 */ + {0x000016A0, 0xC2008113}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_rd_667_1[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC0020106}, + /*1 */ + {0x000016A0, 0xC0420016}, + /*2 */ + {0x000016A0, 0xC0820117}, + /*3 */ + {0x000016A0, 0xC0C2000F}, + /*4 */ + {0x000016A0, 0xC1020105}, + /*5 */ + {0x000016A0, 0xC142001B}, + /*6 */ + {0x000016A0, 0xC182010C}, + /*7 */ + {0x000016A0, 0xC1C20011}, + /*8 */ + {0x000016A0, 0xC2020101}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0003600}, + /*1 */ + {0x000016A0, 0xC0406D0E}, + /*2 */ + {0x000016A0, 0xC0803600}, + /*3 */ + {0x000016A0, 0xC0C04504}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC1803600}, + /*7 */ + {0x000016A0, 0xC1C0610B}, + /*8 */ + {0x000016A0, 0xC2008113}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_rd_667_2[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC002010C}, + /*1 */ + {0x000016A0, 0xC042001B}, + /*2 */ + {0x000016A0, 0xC082011D}, + /*3 */ + {0x000016A0, 0xC0C20015}, + /*4 */ + {0x000016A0, 0xC102010B}, + /*5 */ + {0x000016A0, 0xC1420101}, + /*6 */ + {0x000016A0, 0xC1820113}, + /*7 */ + {0x000016A0, 0xC1C20017}, + /*8 */ + {0x000016A0, 0xC2020107}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0003600}, + /*1 */ + {0x000016A0, 0xC0406D0E}, + /*2 */ + {0x000016A0, 0xC0803600}, + /*3 */ + {0x000016A0, 0xC0C04504}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC180B11F}, + /*7 */ + {0x000016A0, 0xC1C0610B}, + /*8 */ + {0x000016A0, 0xC2008113}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_db_667_M[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /* CS 0 */ + /*0 2 3 1 */ + {0x000016A0, 0xC0020103}, + /*1 2 2 6 */ + {0x000016A0, 0xC0420012}, + /*2 2 3 16 */ + {0x000016A0, 0xC0820113}, + /*3 2 1 26 */ + {0x000016A0, 0xC0C20012}, + /*4 2 2 29 */ + {0x000016A0, 0xC1020100}, + /*5 2 2 13 */ + {0x000016A0, 0xC1420016}, + /*6 2 3 6 */ + {0x000016A0, 0xC1820109}, + /*7 2 1 31 */ + {0x000016A0, 0xC1C20010}, + /*8 2 2 22 */ + {0x000016A0, 0xC2020112}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC000b11F}, + /*1 */ + {0x000016A0, 0xC040690D}, + /*2 */ + {0x000016A0, 0xC0803600}, + /*3 */ + {0x000016A0, 0xC0C0a81D}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC180ad1e}, + /*7 */ + {0x000016A0, 0xC1C04d06}, + /*8 */ + {0x000016A0, 0xC2008514}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + /* CS 1 */ + + {0x000016A0, 0xC0060103}, + /*1 2 2 6 */ + {0x000016A0, 0xC0460012}, + /*2 2 3 16 */ + {0x000016A0, 0xC0860113}, + /*3 2 1 26 */ + {0x000016A0, 0xC0C60012}, + /*4 2 2 29 */ + {0x000016A0, 0xC1060100}, + /*5 2 2 13 */ + {0x000016A0, 0xC1460016}, + /*6 2 3 6 */ + {0x000016A0, 0xC1860109}, + /*7 2 1 31 */ + {0x000016A0, 0xC1C60010}, + /*8 2 2 22 */ + {0x000016A0, 0xC2060112}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC004b11F}, + /*1 */ + {0x000016A0, 0xC044690D}, + /*2 */ + {0x000016A0, 0xC0843600}, + /*3 */ + {0x000016A0, 0xC0C4a81D}, + /*4 */ + {0x000016A0, 0xC1049919}, + /*5 */ + {0x000016A0, 0xC1447911}, + /*6 */ + {0x000016A0, 0xC184ad1e}, + /*7 */ + {0x000016A0, 0xC1C44d06}, + /*8 */ + {0x000016A0, 0xC2048514}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC807000F}, + + /* Both CS */ + + {0x00001538, 0x00000B0B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x00000F0F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_rd_667_3[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC0020118}, + /*1 */ + {0x000016A0, 0xC0420108}, + /*2 */ + {0x000016A0, 0xC0820202}, + /*3 */ + {0x000016A0, 0xC0C20108}, + /*4 */ + {0x000016A0, 0xC1020117}, + /*5 */ + {0x000016A0, 0xC142010C}, + /*6 */ + {0x000016A0, 0xC182011B}, + /*7 */ + {0x000016A0, 0xC1C20107}, + /*8 */ + {0x000016A0, 0xC2020113}, + + /* Write Leveling */ + /*0 */ + {0x000016A0, 0xC0003600}, + /*1 */ + {0x000016A0, 0xC0406D0E}, + /*2 */ + {0x000016A0, 0xC0805207}, + /*3 */ + {0x000016A0, 0xC0C0A81D}, + /*4 */ + {0x000016A0, 0xC1009919}, + /*5 */ + {0x000016A0, 0xC1407911}, + /*6 */ + {0x000016A0, 0xC1803E02}, + /*7 */ + {0x000016A0, 0xC1C04D06}, + /*8 */ + {0x000016A0, 0xC2008113}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + + {0x00001538, 0x0000000B}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000F}, /*Read Data Ready Delay Register */ + + /*init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +MV_DRAM_TRAINING_INIT ddr3_pcac_600[MV_MAX_DDR3_STATIC_SIZE] = { + /* Read Leveling */ + /*PUP RdSampleDly (+CL) Phase RL ADLL value */ + /*0 */ + {0x000016A0, 0xC0020404}, + /* 1 2 2 6 */ + {0x000016A0, 0xC042031E}, + /* 2 2 3 16 */ + {0x000016A0, 0xC0820411}, + /* 3 2 1 26 */ + {0x000016A0, 0xC0C20400}, + /* 4 2 2 29 */ + {0x000016A0, 0xC1020404}, + /* 5 2 2 13 */ + {0x000016A0, 0xC142031D}, + /* 6 2 3 6 */ + {0x000016A0, 0xC182040C}, + /* 7 2 1 31 */ + {0x000016A0, 0xC1C2031B}, + /* 8 2 2 22 */ + {0x000016A0, 0xC2020112}, + + /* Write Leveling */ + /* 0 */ + {0x000016A0, 0xC0004905}, + /* 1 */ + {0x000016A0, 0xC040A81D}, + /* 2 */ + {0x000016A0, 0xC0804504}, + /* 3 */ + {0x000016A0, 0xC0C08013}, + /* 4 */ + {0x000016A0, 0xC1004504}, + /* 5 */ + {0x000016A0, 0xC140A81D}, + /* 6 */ + {0x000016A0, 0xC1805909}, + /* 7 */ + {0x000016A0, 0xC1C09418}, + /* 8 */ + {0x000016A0, 0xC2006D0E}, + + /*center DQS on read cycle */ + {0x000016A0, 0xC803000F}, + {0x00001538, 0x00000009}, /*Read Data Sample Delays Register */ + {0x0000153C, 0x0000000D}, /*Read Data Ready Delay Register */ + /* init DRAM */ + {0x00001480, 0x00000001}, + {0x0, 0x0} +}; + +#endif /* __AXP_TRAINING_STATIC_H */ diff --git a/drivers/ddr/mvebu/ddr3_axp_vars.h b/drivers/ddr/mvebu/ddr3_axp_vars.h new file mode 100644 index 0000000000..1b0ab5603e --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_axp_vars.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __AXP_VARS_H +#define __AXP_VARS_H + +#include "ddr3_axp_config.h" +#include "ddr3_axp_mc_static.h" +#include "ddr3_axp_training_static.h" + +MV_DRAM_MODES ddr_modes[MV_DDR3_MODES_NUMBER] = { + /* Conf name CPUFreq FabFreq Chip ID Chip/Board MC regs Training Values */ + /* db board values: */ + {"db_800-400", 0xA, 0x5, 0x0, A0, ddr3_A0_db_400, NULL}, + {"db_1200-300", 0x2, 0xC, 0x0, A0, ddr3_A0_db_400, NULL}, + {"db_1200-600", 0x2, 0x5, 0x0, A0, NULL, NULL}, + {"db_1333-667", 0x3, 0x5, 0x0, A0, ddr3_A0_db_667, ddr3_db_rev2_667}, + {"db_1600-800", 0xB, 0x5, 0x0, A0, ddr3_A0_db_667, ddr3_db_rev2_800}, + {"amc_1333-667", 0x3, 0x5, 0x0, A0_AMC, ddr3_A0_AMC_667, NULL}, + {"db_667-667", 0x9, 0x13, 0x0, Z1, ddr3_Z1_db_600, ddr3_db_667}, + {"db_800-400", 0xA, 0x1, 0x0, Z1, ddr3_Z1_db_300, ddr3_db_400}, + {"db_1066-533", 0x1, 0x1, 0x0, Z1, ddr3_Z1_db_300, ddr3_db_533}, + {"db_1200-300", 0x2, 0xC, 0x0, Z1, ddr3_Z1_db_300, ddr3_db_667}, + {"db_1200-600", 0x2, 0x5, 0x0, Z1, ddr3_Z1_db_600, NULL}, + {"db_1333-333", 0x3, 0xC, 0x0, Z1, ddr3_Z1_db_300, ddr3_db_400}, + {"db_1333-667", 0x3, 0x5, 0x0, Z1, ddr3_Z1_db_600, ddr3_db_667}, + /* pcac board values (Z1 device): */ + {"pcac_1200-600", 0x2, 0x5, 0x0, Z1_PCAC, ddr3_Z1_db_600, + ddr3_pcac_600}, + /* rd board values (Z1 device): */ + {"rd_667_0", 0x3, 0x5, 0x0, Z1_RD_SLED, ddr3_Z1_db_600, ddr3_rd_667_0}, + {"rd_667_1", 0x3, 0x5, 0x1, Z1_RD_SLED, ddr3_Z1_db_600, ddr3_rd_667_1}, + {"rd_667_2", 0x3, 0x5, 0x2, Z1_RD_SLED, ddr3_Z1_db_600, ddr3_rd_667_2}, + {"rd_667_3", 0x3, 0x5, 0x3, Z1_RD_SLED, ddr3_Z1_db_600, ddr3_rd_667_3} +}; + +/* ODT settings - if needed update the following tables: (ODT_OPT - represents the CS configuration bitmap) */ + +u16 odt_static[ODT_OPT][MAX_CS] = { /* NearEnd/FarEnd */ + {0, 0, 0, 0}, /* 0000 0/0 - Not supported */ + {ODT40, 0, 0, 0}, /* 0001 0/1 */ + {0, 0, 0, 0}, /* 0010 0/0 - Not supported */ + {ODT40, ODT40, 0, 0}, /* 0011 0/2 */ + {0, 0, ODT40, 0}, /* 0100 1/0 */ + {ODT30, 0, ODT30, 0}, /* 0101 1/1 */ + {0, 0, 0, 0}, /* 0110 0/0 - Not supported */ + {ODT120, ODT20, ODT20, 0}, /* 0111 1/2 */ + {0, 0, 0, 0}, /* 1000 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1001 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1010 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1011 0/0 - Not supported */ + {0, 0, ODT40, 0}, /* 1100 2/0 */ + {ODT20, 0, ODT120, ODT20}, /* 1101 2/1 */ + {0, 0, 0, 0}, /* 1110 0/0 - Not supported */ + {ODT120, ODT30, ODT120, ODT30} /* 1111 2/2 */ +}; + +u16 odt_dynamic[ODT_OPT][MAX_CS] = { /* NearEnd/FarEnd */ + {0, 0, 0, 0}, /* 0000 0/0 */ + {0, 0, 0, 0}, /* 0001 0/1 */ + {0, 0, 0, 0}, /* 0010 0/0 - Not supported */ + {0, 0, 0, 0}, /* 0011 0/2 */ + {0, 0, 0, 0}, /* 0100 1/0 */ + {ODT120D, 0, ODT120D, 0}, /* 0101 1/1 */ + {0, 0, 0, 0}, /* 0110 0/0 - Not supported */ + {0, 0, ODT120D, 0}, /* 0111 1/2 */ + {0, 0, 0, 0}, /* 1000 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1001 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1010 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1011 0/0 - Not supported */ + {0, 0, 0, 0}, /* 1100 2/0 */ + {ODT120D, 0, 0, 0}, /* 1101 2/1 */ + {0, 0, 0, 0}, /* 1110 0/0 - Not supported */ + {0, 0, 0, 0} /* 1111 2/2 */ +}; + +u32 odt_config[ODT_OPT] = { + 0, 0x00010000, 0, 0x00030000, 0x04000000, 0x05050104, 0, 0x07430340, 0, + 0, 0, 0, + 0x30000, 0x1C0D100C, 0, 0x3CC330C0 +}; + +/* + * User can manually set SPD values (in case SPD is not available on + * DIMM/System). + * SPD Values can simplify calculating the DUNIT registers values + */ +u8 spd_data[SPD_SIZE] = { + /* AXP DB Board DIMM SPD Values - manually set */ + 0x92, 0x10, 0x0B, 0x2, 0x3, 0x19, 0x0, 0x9, 0x09, 0x52, 0x1, 0x8, 0x0C, + 0x0, 0x7E, 0x0, 0x69, 0x78, + 0x69, 0x30, 0x69, 0x11, 0x20, 0x89, 0x0, 0x5, 0x3C, 0x3C, 0x0, 0xF0, + 0x82, 0x5, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0F, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x80, 0x2C, 0x1, 0x10, 0x23, 0x35, 0x28, 0xEB, 0xCA, 0x19, 0x8F +}; + +/* + * Controller Specific configurations Starts Here - DO NOT MODIFY + */ + +/* Frequency - values are 1/HCLK in ps */ +u32 cpu_fab_clk_to_hclk[FAB_OPT][CLK_CPU] = +/* CPU Frequency: + 1000 1066 1200 1333 1500 1666 1800 2000 600 667 800 1600 Fabric */ +{ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 2500, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 4500, 3750, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2500, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4000, 3750, 3333, 3000, 2666, 2400, 0, 0, 0, 0, 5000, 2500}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 5000, 0, 4000, 0, 0, 0, 0, 0, 0, 3750}, + {5000, 0, 0, 3750, 3333, 0, 0, 0, 0, 0, 0, 3125}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 3330, 3000, 0, 0, 0, 0, 0, 0, 0, 2500}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3750}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 3000, 2500, 0}, + {3000, 0, 2500, 0, 0, 0, 0, 0, 0, 0, 3750, 0} +}; + +u32 cpu_ddr_ratios[FAB_OPT][CLK_CPU] = +/* CPU Frequency: + 1000 1066 1200 1333 1500 1666 1800 2000 600 667 800 1600 Fabric */ +{ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, DDR_333, DDR_400, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, DDR_444, DDR_533, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, DDR_400, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {DDR_500, DDR_533, DDR_600, DDR_666, DDR_750, DDR_833, 0, 0, 0, 0, + DDR_400, DDR_800}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, DDR_333, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {DDR_400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, DDR_400, 0, DDR_500, 0, 0, 0, 0, 0, 0, DDR_533}, + {DDR_400, 0, 0, DDR_533, DDR_600, 0, 0, 0, 0, 0, 0, DDR_640}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, DDR_300, DDR_333, 0, 0, 0, 0, 0, 0, 0, DDR_400}, + {0, 0, 0, 0, 0, 0, DDR_600, DDR_666, 0, 0, 0, DDR_533}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, DDR_666, DDR_800, 0}, + {DDR_666, 0, DDR_800, 0, 0, 0, 0, 0, 0, 0, DDR_533, 0} +}; + +u8 div_ratio1to1[CLK_VCO][CLK_DDR] = +/* DDR Frequency: + 100 300 360 400 444 500 533 600 666 750 800 833 */ +{ {0xA, 3, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1000 */ +{0xB, 3, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1066 */ +{0xC, 4, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1200 */ +{0xD, 4, 0, 4, 0, 0, 0, 0, 2, 0, 0, 0}, /* 1:1 CLK_CPU_1333 */ +{0xF, 5, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1500 */ +{0x11, 5, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1666 */ +{0x12, 6, 5, 4, 0, 0, 0, 3, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1800 */ +{0x14, 7, 0, 5, 0, 4, 0, 0, 3, 0, 0, 0}, /* 1:1 CLK_CPU_2000 */ +{0x6, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_600 */ +{0x6, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_667 */ +{0x8, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_800 */ +{0x10, 5, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1600 */ +{0x14, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1000 VCO_2000 */ +{0x15, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1066 VCO_2133 */ +{0x18, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1200 VCO_2400 */ +{0x1A, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1333 VCO_2666 */ +{0x1E, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1500 VCO_3000 */ +{0x21, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1666 VCO_3333 */ +{0x24, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_1800 VCO_3600 */ +{0x28, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_2000 VCO_4000 */ +{0xC, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_600 VCO_1200 */ +{0xD, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_667 VCO_1333 */ +{0x10, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, /* 1:1 CLK_CPU_800 VCO_1600 */ +{0x20, 10, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0} /* 1:1 CLK_CPU_1600 VCO_3200 */ +}; + +u8 div_ratio2to1[CLK_VCO][CLK_DDR] = +/* DDR Frequency: + 100 300 360 400 444 500 533 600 666 750 800 833 */ +{ {0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0}, /* 2:1 CLK_CPU_1000 */ +{0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1066 */ +{0, 0, 0, 3, 5, 0, 0, 2, 0, 0, 3, 3}, /* 2:1 CLK_CPU_1200 */ +{0, 0, 0, 0, 0, 0, 5, 0, 2, 0, 3, 0}, /* 2:1 CLK_CPU_1333 */ +{0, 0, 0, 0, 0, 3, 0, 5, 0, 2, 0, 0}, /* 2:1 CLK_CPU_1500 */ +{0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 2}, /* 2:1 CLK_CPU_1666 */ +{0, 0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 0}, /* 2:1 CLK_CPU_1800 */ +{0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 5}, /* 2:1 CLK_CPU_2000 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_600 */ +{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, /* 2:1 CLK_CPU_667 */ +{0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0}, /* 2:1 CLK_CPU_800 */ +{0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0}, /* 2:1 CLK_CPU_1600 */ +{0, 0, 0, 5, 0, 0, 0, 0, 3, 0, 0, 0}, /* 2:1 CLK_CPU_1000 VCO_2000 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1066 VCO_2133 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0}, /* 2:1 CLK_CPU_1200 VCO_2400 */ +{0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1333 VCO_2666 */ +{0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1500 VCO_3000 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1666 VCO_3333 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_1800 VCO_3600 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_2000 VCO_4000 */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_600 VCO_1200 */ +{0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_667 VCO_1333 */ +{0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0}, /* 2:1 CLK_CPU_800 VCO_1600 */ +{0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0} /* 2:1 CLK_CPU_1600 VCO_3200 */ +}; + +#endif /* __AXP_VARS_H */ diff --git a/drivers/ddr/mvebu/ddr3_dfs.c b/drivers/ddr/mvebu/ddr3_dfs.c new file mode 100644 index 0000000000..934777368a --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_dfs.c @@ -0,0 +1,1552 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" + +/* + * Debug + */ +#define DEBUG_DFS_C(s, d, l) \ + DEBUG_DFS_S(s); DEBUG_DFS_D(d, l); DEBUG_DFS_S("\n") +#define DEBUG_DFS_FULL_C(s, d, l) \ + DEBUG_DFS_FULL_S(s); DEBUG_DFS_FULL_D(d, l); DEBUG_DFS_FULL_S("\n") + +#ifdef MV_DEBUG_DFS +#define DEBUG_DFS_S(s) puts(s) +#define DEBUG_DFS_D(d, l) printf("%x", d) +#else +#define DEBUG_DFS_S(s) +#define DEBUG_DFS_D(d, l) +#endif + +#ifdef MV_DEBUG_DFS_FULL +#define DEBUG_DFS_FULL_S(s) puts(s) +#define DEBUG_DFS_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_DFS_FULL_S(s) +#define DEBUG_DFS_FULL_D(d, l) +#endif + +#if defined(MV88F672X) +extern u8 div_ratio[CLK_VCO][CLK_DDR]; +extern void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps); +#else +extern u16 odt_dynamic[ODT_OPT][MAX_CS]; +extern u8 div_ratio1to1[CLK_CPU][CLK_DDR]; +extern u8 div_ratio2to1[CLK_CPU][CLK_DDR]; +#endif +extern u16 odt_static[ODT_OPT][MAX_CS]; + +extern u32 cpu_fab_clk_to_hclk[FAB_OPT][CLK_CPU]; + +extern u32 ddr3_get_vco_freq(void); + +u32 ddr3_get_freq_parameter(u32 target_freq, int ratio_2to1); + +#ifdef MV_DEBUG_DFS +static inline void dfs_reg_write(u32 addr, u32 val) +{ + printf("\n write reg 0x%08x = 0x%08x", addr, val); + writel(val, INTER_REGS_BASE + addr); +} +#else +static inline void dfs_reg_write(u32 addr, u32 val) +{ + writel(val, INTER_REGS_BASE + addr); +} +#endif + +static void wait_refresh_op_complete(void) +{ + u32 reg; + + /* Poll - Wait for Refresh operation completion */ + do { + reg = reg_read(REG_SDRAM_OPERATION_ADDR) & + REG_SDRAM_OPERATION_CMD_RFRS_DONE; + } while (reg); /* Wait for '0' */ +} + +/* + * Name: ddr3_get_freq_parameter + * Desc: Finds CPU/DDR frequency ratio according to Sample@reset and table. + * Args: target_freq - target frequency + * Notes: + * Returns: freq_par - the ratio parameter + */ +u32 ddr3_get_freq_parameter(u32 target_freq, int ratio_2to1) +{ + u32 ui_vco_freq, freq_par; + + ui_vco_freq = ddr3_get_vco_freq(); + +#if defined(MV88F672X) + freq_par = div_ratio[ui_vco_freq][target_freq]; +#else + /* Find the ratio between PLL frequency and ddr-clk */ + if (ratio_2to1) + freq_par = div_ratio2to1[ui_vco_freq][target_freq]; + else + freq_par = div_ratio1to1[ui_vco_freq][target_freq]; +#endif + + return freq_par; +} + +/* + * Name: ddr3_dfs_high_2_low + * Desc: + * Args: freq - target frequency + * Notes: + * Returns: MV_OK - success, MV_FAIL - fail + */ +int ddr3_dfs_high_2_low(u32 freq, MV_DRAM_INFO *dram_info) +{ +#if defined(MV88F78X60) || defined(MV88F672X) + /* This Flow is relevant for ArmadaXP A0 */ + u32 reg, freq_par, tmp; + u32 cs = 0; + + DEBUG_DFS_C("DDR3 - DFS - High To Low - Starting DFS procedure to Frequency - ", + freq, 1); + + /* target frequency - 100MHz */ + freq_par = ddr3_get_freq_parameter(freq, 0); + +#if defined(MV88F672X) + u32 hclk; + u32 cpu_freq = ddr3_get_cpu_freq(); + get_target_freq(cpu_freq, &tmp, &hclk); +#endif + + /* Configure - DRAM DLL final state after DFS is complete - Enable */ + reg = reg_read(REG_DFS_ADDR); + /* [0] - DfsDllNextState - Disable */ + reg |= (1 << REG_DFS_DLLNEXTSTATE_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Configure - XBAR Retry response during Block to enable internal + * access - Disable + */ + reg = reg_read(REG_METAL_MASK_ADDR); + /* [0] - RetryMask - Disable */ + reg &= ~(1 << REG_METAL_MASK_RETRY_OFFS); + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + /* Configure - Block new external transactions - Enable */ + reg = reg_read(REG_DFS_ADDR); + reg |= (1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Enable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Registered DIMM support */ + if (dram_info->reg_dimm) { + /* + * Configure - Disable Register DIMM CKE Power + * Down mode - CWA_RC + */ + reg = (0x9 & REG_SDRAM_OPERATION_CWA_RC_MASK) << + REG_SDRAM_OPERATION_CWA_RC_OFFS; + /* + * Configure - Disable Register DIMM CKE Power + * Down mode - CWA_DATA + */ + reg |= ((0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + + /* + * Configure - Disable Register DIMM CKE Power + * Down mode - Set Delay - tMRD + */ + reg |= (0 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS); + + /* Configure - Issue CWA command with the above parameters */ + reg |= (REG_SDRAM_OPERATION_CMD_CWA & + ~(0xF << REG_SDRAM_OPERATION_CS_OFFS)); + + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for CWA operation completion */ + do { + reg = reg_read(REG_SDRAM_OPERATION_ADDR) & + (REG_SDRAM_OPERATION_CMD_MASK); + } while (reg); + + /* Configure - Disable outputs floating during Self Refresh */ + reg = reg_read(REG_REGISTERED_DRAM_CTRL_ADDR); + /* [15] - SRFloatEn - Disable */ + reg &= ~(1 << REG_REGISTERED_DRAM_CTRL_SR_FLOAT_OFFS); + /* 0x16D0 - DDR3 Registered DRAM Control */ + dfs_reg_write(REG_REGISTERED_DRAM_CTRL_ADDR, reg); + } + + /* Optional - Configure - DDR3_Rtt_nom_CS# */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)); + reg &= REG_DDR3_MR1_RTT_MASK; + dfs_reg_write(REG_DDR3_MR1_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* Configure - Move DRAM into Self Refresh */ + reg = reg_read(REG_DFS_ADDR); + reg |= (1 << REG_DFS_SR_OFFS); /* [2] - DfsSR - Enable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Poll - Wait for Self Refresh indication */ + do { + reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS)); + } while (reg == 0x0); /* 0x1528 [3] - DfsAtSR - Wait for '1' */ + + /* Start of clock change procedure (PLL) */ +#if defined(MV88F672X) + /* avantaLP */ + /* Configure cpupll_clkdiv_reset_mask */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL0_MASK; + /* 0xE8264[7:0] 0xff CPU Clock Dividers Reset mask */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, (reg + 0xFF)); + + /* Configure cpu_clkdiv_reload_smooth */ + reg = reg_read(CPU_PLL_CNTRL0); + reg &= CPU_PLL_CNTRL0_RELOAD_SMOOTH_MASK; + /* 0xE8260 [15:8] 0x2 CPU Clock Dividers Reload Smooth enable */ + dfs_reg_write(CPU_PLL_CNTRL0, + (reg + (2 << CPU_PLL_CNTRL0_RELOAD_SMOOTH_OFFS))); + + /* Configure cpupll_clkdiv_relax_en */ + reg = reg_read(CPU_PLL_CNTRL0); + reg &= CPU_PLL_CNTRL0_RELAX_EN_MASK; + /* 0xE8260 [31:24] 0x2 Relax Enable */ + dfs_reg_write(CPU_PLL_CNTRL0, + (reg + (2 << CPU_PLL_CNTRL0_RELAX_EN_OFFS))); + + /* Configure cpupll_clkdiv_ddr_clk_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL1); + /* + * 0xE8268 [13:8] N Set Training clock: + * APLL Out Clock (VCO freq) / N = 100 MHz + */ + reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL1_MASK; + reg |= (freq_par << 8); /* full Integer ratio from PLL-out to ddr-clk */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL1, reg); + + /* Configure cpupll_clkdiv_reload_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK; + /* 0xE8264 [8]=0x1 CPU Clock Dividers Reload Ratio trigger set */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, + (reg + (1 << CPU_PLL_CLOCK_RELOAD_RATIO_OFFS))); + + udelay(1); + + /* Configure cpupll_clkdiv_reload_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK; + /* 0xE8264 [8]=0x0 CPU Clock Dividers Reload Ratio trigger clear */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, reg); + + udelay(5); + +#else + /* + * Initial Setup - assure that the "load new ratio" is clear (bit 24) + * and in the same chance, block reassertions of reset [15:8] and + * force reserved bits[7:0]. + */ + reg = 0x0000FDFF; + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + /* + * RelaX whenever reset is asserted to that channel + * (good for any case) + */ + reg = 0x0000FF00; + /* 0x18704 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + reg = reg_read(REG_CPU_DIV_CLK_CTRL_2_ADDR) & + REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK; + + /* full Integer ratio from PLL-out to ddr-clk */ + reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS); + /* 0x1870C - CPU Div CLK control 3 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_2_ADDR, reg); + + /* + * Shut off clock enable to the DDRPHY clock channel (this is the "D"). + * All the rest are kept as is (forced, but could be read-modify-write). + * This is done now by RMW above. + */ + + /* Clock is not shut off gracefully - keep it running */ + reg = 0x000FFF02; + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg); + + /* Wait before replacing the clock on the DDR Phy Channel. */ + udelay(1); + + /* + * This for triggering the frequency update. Bit[24] is the + * central control + * bits [23:16] == which channels to change ==2 ==> + * only DDR Phy (smooth transition) + * bits [15:8] == mask reset reassertion due to clock modification + * to these channels. + * bits [7:0] == not in use + */ + reg = 0x0102FDFF; + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(1); /* Wait 1usec */ + + /* + * Poll Div CLK status 0 register - indication that the clocks + * are active - 0x18718 [8] + */ + do { + reg = (reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR)) & + (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS); + } while (reg == 0); + + /* + * Clean the CTRL0, to be ready for next resets and next requests + * of ratio modifications. + */ + reg = 0x000000FF; + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(5); +#endif + /* End of clock change procedure (PLL) */ + + /* Configure - Select normal clock for the DDR PHY - Enable */ + reg = reg_read(REG_DRAM_INIT_CTRL_STATUS_ADDR); + /* [16] - ddr_phy_trn_clk_sel - Enable */ + reg |= (1 << REG_DRAM_INIT_CTRL_TRN_CLK_OFFS); + /* 0x18488 - DRAM Init control status register */ + dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg); + + /* Configure - Set Correct Ratio - 1:1 */ + /* [15] - Phy2UnitClkRatio = 0 - Set 1:1 Ratio between Dunit and Phy */ + + reg = reg_read(REG_DDR_IO_ADDR) & ~(1 << REG_DDR_IO_CLK_RATIO_OFFS); + dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */ + + /* Configure - 2T Mode - Restore original configuration */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + /* [3:4] 2T - 1T Mode - low freq */ + reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS); + /* 0x1404 - DDR Controller Control Low Register */ + dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + + /* Configure - Restore CL and CWL - MRS Commands */ + reg = reg_read(REG_DFS_ADDR); + reg &= ~(REG_DFS_CL_NEXT_STATE_MASK << REG_DFS_CL_NEXT_STATE_OFFS); + reg &= ~(REG_DFS_CWL_NEXT_STATE_MASK << REG_DFS_CWL_NEXT_STATE_OFFS); + /* [8] - DfsCLNextState - MRS CL=6 after DFS (due to DLL-off mode) */ + reg |= (0x4 << REG_DFS_CL_NEXT_STATE_OFFS); + /* [12] - DfsCWLNextState - MRS CWL=6 after DFS (due to DLL-off mode) */ + reg |= (0x1 << REG_DFS_CWL_NEXT_STATE_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Poll - Wait for APLL + ADLLs lock on new frequency */ + do { + reg = (reg_read(REG_PHY_LOCK_STATUS_ADDR)) & + REG_PHY_LOCK_APLL_ADLL_STATUS_MASK; + /* 0x1674 [10:0] - Phy lock status Register */ + } while (reg != REG_PHY_LOCK_APLL_ADLL_STATUS_MASK); + + /* Configure - Reset the PHY Read FIFO and Write channels - Set Reset */ + reg = (reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK); + /* [30:29] = 0 - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* + * Configure - DRAM Data PHY Read [30], Write [29] path + * reset - Release Reset + */ + reg = (reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK); + /* [30:29] = '11' - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* Registered DIMM support */ + if (dram_info->reg_dimm) { + /* + * Configure - Change register DRAM operating speed + * (below 400MHz) - CWA_RC + */ + reg = (0xA & REG_SDRAM_OPERATION_CWA_RC_MASK) << + REG_SDRAM_OPERATION_CWA_RC_OFFS; + + /* + * Configure - Change register DRAM operating speed + * (below 400MHz) - CWA_DATA + */ + reg |= ((0x0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + + /* Configure - Set Delay - tSTAB */ + reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS); + + /* Configure - Issue CWA command with the above parameters */ + reg |= (REG_SDRAM_OPERATION_CMD_CWA & + ~(0xF << REG_SDRAM_OPERATION_CS_OFFS)); + + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for CWA operation completion */ + do { + reg = reg_read(REG_SDRAM_OPERATION_ADDR) & + (REG_SDRAM_OPERATION_CMD_MASK); + } while (reg); + } + + /* Configure - Exit Self Refresh */ + /* [2] - DfsSR */ + reg = (reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS)); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll - DFS Register - 0x1528 [3] - DfsAtSR - All DRAM devices + * on all ranks are NOT in self refresh mode + */ + do { + reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS)); + } while (reg); /* Wait for '0' */ + + /* Configure - Issue Refresh command */ + /* [3-0] = 0x2 - Refresh Command, [11-8] - enabled Cs */ + reg = REG_SDRAM_OPERATION_CMD_RFRS; + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) + reg &= ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + } + + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* Configure - Block new external transactions - Disable */ + reg = reg_read(REG_DFS_ADDR); + reg &= ~(1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Disable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Configure - XBAR Retry response during Block to enable + * internal access - Disable + */ + reg = reg_read(REG_METAL_MASK_ADDR); + /* [0] - RetryMask - Enable */ + reg |= (1 << REG_METAL_MASK_RETRY_OFFS); + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + /* Configure - Set CL */ + reg = reg_read(REG_DDR3_MR0_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)) & + ~REG_DDR3_MR0_CL_MASK; + tmp = 0x4; /* CL=6 - 0x4 */ + reg |= ((tmp & 0x1) << REG_DDR3_MR0_CL_OFFS); + reg |= ((tmp & 0xE) << REG_DDR3_MR0_CL_HIGH_OFFS); + dfs_reg_write(REG_DDR3_MR0_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + + /* Configure - Set CWL */ + reg = reg_read(REG_DDR3_MR2_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)) + & ~(REG_DDR3_MR2_CWL_MASK << REG_DDR3_MR2_CWL_OFFS); + /* CWL=6 - 0x1 */ + reg |= ((0x1) << REG_DDR3_MR2_CWL_OFFS); + dfs_reg_write(REG_DDR3_MR2_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + DEBUG_DFS_C("DDR3 - DFS - High To Low - Ended successfuly - new Frequency - ", + freq, 1); + + return MV_OK; +#else + /* This Flow is relevant for Armada370 A0 and ArmadaXP Z1 */ + + u32 reg, freq_par; + u32 cs = 0; + + DEBUG_DFS_C("DDR3 - DFS - High To Low - Starting DFS procedure to Frequency - ", + freq, 1); + + /* target frequency - 100MHz */ + freq_par = ddr3_get_freq_parameter(freq, 0); + + reg = 0x0000FF00; + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + /* 0x1600 - ODPG_CNTRL_Control */ + reg = reg_read(REG_ODPG_CNTRL_ADDR); + /* [21] = 1 - auto refresh disable */ + reg |= (1 << REG_ODPG_CNTRL_OFFS); + dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg); + + /* 0x1670 - PHY lock mask register */ + reg = reg_read(REG_PHY_LOCK_MASK_ADDR); + reg &= REG_PHY_LOCK_MASK_MASK; /* [11:0] = 0 */ + dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg); + + reg = reg_read(REG_DFS_ADDR); /* 0x1528 - DFS register */ + + /* Disable reconfig */ + reg &= ~0x10; /* [4] - Enable reconfig MR registers after DFS_ERG */ + reg |= 0x1; /* [0] - DRAM DLL disabled after DFS */ + + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + reg = reg_read(REG_METAL_MASK_ADDR) & ~(1 << 0); /* [0] - disable */ + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + /* [1] - DFS Block enable */ + reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_BLOCK_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* [2] - DFS Self refresh enable */ + reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_SR_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll DFS Register - 0x1528 [3] - DfsAtSR - + * All DRAM devices on all ranks are in self refresh mode - + * DFS can be executed afterwards + */ + do { + reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS); + } while (reg == 0x0); /* Wait for '1' */ + + /* Disable ODT on DLL-off mode */ + dfs_reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, + REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK); + + /* [11:0] = 0 */ + reg = (reg_read(REG_PHY_LOCK_MASK_ADDR) & REG_PHY_LOCK_MASK_MASK); + /* 0x1670 - PHY lock mask register */ + dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg); + + /* Add delay between entering SR and start ratio modification */ + udelay(1); + + /* + * Initial Setup - assure that the "load new ratio" is clear (bit 24) + * and in the same chance, block reassertions of reset [15:8] and + * force reserved bits[7:0]. + */ + reg = 0x0000FDFF; + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + /* + * RelaX whenever reset is asserted to that channel (good for any case) + */ + reg = 0x0000FF00; + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + reg = reg_read(REG_CPU_DIV_CLK_CTRL_3_ADDR) & + REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK; + /* Full Integer ratio from PLL-out to ddr-clk */ + reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS); + /* 0x1870C - CPU Div CLK control 3 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_3_ADDR, reg); + + /* + * Shut off clock enable to the DDRPHY clock channel (this is the "D"). + * All the rest are kept as is (forced, but could be read-modify-write). + * This is done now by RMW above. + */ + + /* Clock is not shut off gracefully - keep it running */ + reg = 0x000FFF02; + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg); + + /* Wait before replacing the clock on the DDR Phy Channel. */ + udelay(1); + + /* + * This for triggering the frequency update. Bit[24] is the + * central control + * bits [23:16] == which channels to change ==2 ==> only DDR Phy + * (smooth transition) + * bits [15:8] == mask reset reassertion due to clock modification + * to these channels. + * bits [7:0] == not in use + */ + reg = 0x0102FDFF; + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(1); /* Wait 1usec */ + + /* + * Poll Div CLK status 0 register - indication that the clocks + * are active - 0x18718 [8] + */ + do { + reg = (reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR)) & + (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS); + } while (reg == 0); + + /* + * Clean the CTRL0, to be ready for next resets and next requests of + * ratio modifications. + */ + reg = 0x000000FF; + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(5); + + /* Switch HCLK Mux to training clk (100Mhz), keep DFS request bit */ + reg = 0x20050000; + /* 0x18488 - DRAM Init control status register */ + dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg); + + reg = reg_read(REG_DDR_IO_ADDR) & ~(1 << REG_DDR_IO_CLK_RATIO_OFFS); + /* [15] = 0 - Set 1:1 Ratio between Dunit and Phy */ + dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Regist */ + + reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK; + /* [31:30]] - reset pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + reg = (reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK); + /* [31:30] - normal pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + udelay(1); /* Wait 1usec */ + + /* 0x1404 */ + reg = (reg_read(REG_DUNIT_CTRL_LOW_ADDR) & 0xFFFFFFE7); + dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + + /* Poll Phy lock status register - APLL lock indication - 0x1674 */ + do { + reg = (reg_read(REG_PHY_LOCK_STATUS_ADDR)) & + REG_PHY_LOCK_STATUS_LOCK_MASK; + } while (reg != REG_PHY_LOCK_STATUS_LOCK_MASK); /* Wait for '0xFFF' */ + + reg = (reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK); + /* [30:29] = 0 - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK; + /* [30:29] = '11' - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + udelay(1000); /* Wait 1msec */ + + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* Config CL and CWL with MR0 and MR2 registers */ + reg = reg_read(REG_DDR3_MR0_ADDR); + reg &= ~0x74; /* CL [3:0]; [6:4],[2] */ + reg |= (1 << 5); /* CL = 4, CAS is 6 */ + dfs_reg_write(REG_DDR3_MR0_ADDR, reg); + reg = REG_SDRAM_OPERATION_CMD_MR0 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + reg = reg_read(REG_DDR3_MR2_ADDR); + reg &= ~0x38; /* CWL [5:3] */ + reg |= (1 << 3); /* CWL = 1, CWL is 6 */ + dfs_reg_write(REG_DDR3_MR2_ADDR, reg); + + reg = REG_SDRAM_OPERATION_CMD_MR2 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* Set current rd_sample_delay */ + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + reg |= (5 << (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + dfs_reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg); + + /* Set current rd_ready_delay */ + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= ((6) << (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + dfs_reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + } + } + + /* [2] - DFS Self refresh disable */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* [1] - DFS Block enable */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_BLOCK_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll DFS Register - 0x1528 [3] - DfsAtSR - + * All DRAM devices on all ranks are in self refresh mode - DFS can + * be executed afterwards + */ + do { + reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS); + } while (reg); /* Wait for '1' */ + + reg = (reg_read(REG_METAL_MASK_ADDR) | (1 << 0)); + /* [0] - Enable Dunit to crossbar retry */ + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + /* 0x1600 - PHY lock mask register */ + reg = reg_read(REG_ODPG_CNTRL_ADDR); + reg &= ~(1 << REG_ODPG_CNTRL_OFFS); /* [21] = 0 */ + dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg); + + /* 0x1670 - PHY lock mask register */ + reg = reg_read(REG_PHY_LOCK_MASK_ADDR); + reg |= ~REG_PHY_LOCK_MASK_MASK; /* [11:0] = FFF */ + dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg); + + DEBUG_DFS_C("DDR3 - DFS - High To Low - Ended successfuly - new Frequency - ", + freq, 1); + + return MV_OK; +#endif +} + +/* + * Name: ddr3_dfs_low_2_high + * Desc: + * Args: freq - target frequency + * Notes: + * Returns: MV_OK - success, MV_FAIL - fail + */ +int ddr3_dfs_low_2_high(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info) +{ +#if defined(MV88F78X60) || defined(MV88F672X) + /* This Flow is relevant for ArmadaXP A0 */ + u32 reg, freq_par, tmp; + u32 cs = 0; + + DEBUG_DFS_C("DDR3 - DFS - Low To High - Starting DFS procedure to Frequency - ", + freq, 1); + + /* target frequency - freq */ + freq_par = ddr3_get_freq_parameter(freq, ratio_2to1); + +#if defined(MV88F672X) + u32 hclk; + u32 cpu_freq = ddr3_get_cpu_freq(); + get_target_freq(cpu_freq, &tmp, &hclk); +#endif + + /* Configure - DRAM DLL final state after DFS is complete - Enable */ + reg = reg_read(REG_DFS_ADDR); + /* [0] - DfsDllNextState - Enable */ + reg &= ~(1 << REG_DFS_DLLNEXTSTATE_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Configure - XBAR Retry response during Block to enable + * internal access - Disable + */ + reg = reg_read(REG_METAL_MASK_ADDR); + /* [0] - RetryMask - Disable */ + reg &= ~(1 << REG_METAL_MASK_RETRY_OFFS); + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + /* Configure - Block new external transactions - Enable */ + reg = reg_read(REG_DFS_ADDR); + reg |= (1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Enable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Configure - Move DRAM into Self Refresh */ + reg = reg_read(REG_DFS_ADDR); + reg |= (1 << REG_DFS_SR_OFFS); /* [2] - DfsSR - Enable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Poll - Wait for Self Refresh indication */ + do { + reg = ((reg_read(REG_DFS_ADDR)) & (1 << REG_DFS_ATSR_OFFS)); + } while (reg == 0x0); /* 0x1528 [3] - DfsAtSR - Wait for '1' */ + + /* Start of clock change procedure (PLL) */ +#if defined(MV88F672X) + /* avantaLP */ + /* Configure cpupll_clkdiv_reset_mask */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL0_MASK; + /* 0xE8264[7:0] 0xff CPU Clock Dividers Reset mask */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, (reg + 0xFF)); + + /* Configure cpu_clkdiv_reload_smooth */ + reg = reg_read(CPU_PLL_CNTRL0); + reg &= CPU_PLL_CNTRL0_RELOAD_SMOOTH_MASK; + /* 0xE8260 [15:8] 0x2 CPU Clock Dividers Reload Smooth enable */ + dfs_reg_write(CPU_PLL_CNTRL0, + reg + (2 << CPU_PLL_CNTRL0_RELOAD_SMOOTH_OFFS)); + + /* Configure cpupll_clkdiv_relax_en */ + reg = reg_read(CPU_PLL_CNTRL0); + reg &= CPU_PLL_CNTRL0_RELAX_EN_MASK; + /* 0xE8260 [31:24] 0x2 Relax Enable */ + dfs_reg_write(CPU_PLL_CNTRL0, + reg + (2 << CPU_PLL_CNTRL0_RELAX_EN_OFFS)); + + /* Configure cpupll_clkdiv_ddr_clk_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL1); + /* + * 0xE8268 [13:8] N Set Training clock: + * APLL Out Clock (VCO freq) / N = 100 MHz + */ + reg &= CPU_PLL_CLOCK_DIVIDER_CNTRL1_MASK; + reg |= (freq_par << 8); /* full Integer ratio from PLL-out to ddr-clk */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL1, reg); + /* Configure cpupll_clkdiv_reload_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK; + /* 0xE8264 [8]=0x1 CPU Clock Dividers Reload Ratio trigger set */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, + reg + (1 << CPU_PLL_CLOCK_RELOAD_RATIO_OFFS)); + + udelay(1); + + /* Configure cpupll_clkdiv_reload_ratio */ + reg = reg_read(CPU_PLL_CLOCK_DIVIDER_CNTRL0); + reg &= CPU_PLL_CLOCK_RELOAD_RATIO_MASK; + /* 0xE8264 [8]=0x0 CPU Clock Dividers Reload Ratio trigger clear */ + dfs_reg_write(CPU_PLL_CLOCK_DIVIDER_CNTRL0, reg); + + udelay(5); + +#else + /* + * Initial Setup - assure that the "load new ratio" is clear (bit 24) + * and in the same chance, block reassertions of reset [15:8] + * and force reserved bits[7:0]. + */ + reg = 0x0000FFFF; + + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + /* + * RelaX whenever reset is asserted to that channel (good for any case) + */ + reg = 0x0000FF00; + /* 0x18704 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + reg = reg_read(REG_CPU_DIV_CLK_CTRL_2_ADDR) & + REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK; + reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS); + /* full Integer ratio from PLL-out to ddr-clk */ + /* 0x1870C - CPU Div CLK control 3 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_2_ADDR, reg); + + /* + * Shut off clock enable to the DDRPHY clock channel (this is the "D"). + * All the rest are kept as is (forced, but could be read-modify-write). + * This is done now by RMW above. + */ + reg = 0x000FFF02; + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg); + + /* Wait before replacing the clock on the DDR Phy Channel. */ + udelay(1); + + reg = 0x0102FDFF; + /* + * This for triggering the frequency update. Bit[24] is the + * central control + * bits [23:16] == which channels to change ==2 ==> only DDR Phy + * (smooth transition) + * bits [15:8] == mask reset reassertion due to clock modification + * to these channels. + * bits [7:0] == not in use + */ + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(1); + + /* + * Poll Div CLK status 0 register - indication that the clocks + * are active - 0x18718 [8] + */ + do { + reg = reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR) & + (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS); + } while (reg == 0); + + reg = 0x000000FF; + /* + * Clean the CTRL0, to be ready for next resets and next requests + * of ratio modifications. + */ + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); +#endif + /* End of clock change procedure (PLL) */ + + if (ratio_2to1) { + /* Configure - Select normal clock for the DDR PHY - Disable */ + reg = reg_read(REG_DRAM_INIT_CTRL_STATUS_ADDR); + /* [16] - ddr_phy_trn_clk_sel - Disable */ + reg &= ~(1 << REG_DRAM_INIT_CTRL_TRN_CLK_OFFS); + /* 0x18488 - DRAM Init control status register */ + dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg); + } + + /* + * Configure - Set Correct Ratio - according to target ratio + * parameter - 2:1/1:1 + */ + if (ratio_2to1) { + /* + * [15] - Phy2UnitClkRatio = 1 - Set 2:1 Ratio between + * Dunit and Phy + */ + reg = reg_read(REG_DDR_IO_ADDR) | + (1 << REG_DDR_IO_CLK_RATIO_OFFS); + } else { + /* + * [15] - Phy2UnitClkRatio = 0 - Set 1:1 Ratio between + * Dunit and Phy + */ + reg = reg_read(REG_DDR_IO_ADDR) & + ~(1 << REG_DDR_IO_CLK_RATIO_OFFS); + } + dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */ + + /* Configure - 2T Mode - Restore original configuration */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + /* [3:4] 2T - Restore value */ + reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS); + reg |= ((dram_info->mode_2t & REG_DUNIT_CTRL_LOW_2T_MASK) << + REG_DUNIT_CTRL_LOW_2T_OFFS); + /* 0x1404 - DDR Controller Control Low Register */ + dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + + /* Configure - Restore CL and CWL - MRS Commands */ + reg = reg_read(REG_DFS_ADDR); + reg &= ~(REG_DFS_CL_NEXT_STATE_MASK << REG_DFS_CL_NEXT_STATE_OFFS); + reg &= ~(REG_DFS_CWL_NEXT_STATE_MASK << REG_DFS_CWL_NEXT_STATE_OFFS); + + if (freq == DDR_400) { + if (dram_info->target_frequency == 0x8) + tmp = ddr3_cl_to_valid_cl(5); + else + tmp = ddr3_cl_to_valid_cl(6); + } else { + tmp = ddr3_cl_to_valid_cl(dram_info->cl); + } + + /* [8] - DfsCLNextState */ + reg |= ((tmp & REG_DFS_CL_NEXT_STATE_MASK) << REG_DFS_CL_NEXT_STATE_OFFS); + if (freq == DDR_400) { + /* [12] - DfsCWLNextState */ + reg |= (((0) & REG_DFS_CWL_NEXT_STATE_MASK) << + REG_DFS_CWL_NEXT_STATE_OFFS); + } else { + /* [12] - DfsCWLNextState */ + reg |= (((dram_info->cwl) & REG_DFS_CWL_NEXT_STATE_MASK) << + REG_DFS_CWL_NEXT_STATE_OFFS); + } + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Optional - Configure - DDR3_Rtt_nom_CS# */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)); + reg &= REG_DDR3_MR1_RTT_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + dfs_reg_write(REG_DDR3_MR1_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* Configure - Reset ADLLs - Set Reset */ + reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK; + /* [31:30]] - reset pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config Register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + /* Configure - Reset ADLLs - Release Reset */ + reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK; + /* [31:30] - normal pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + /* Poll - Wait for APLL + ADLLs lock on new frequency */ + do { + reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) & + REG_PHY_LOCK_APLL_ADLL_STATUS_MASK; + /* 0x1674 [10:0] - Phy lock status Register */ + } while (reg != REG_PHY_LOCK_APLL_ADLL_STATUS_MASK); + + /* Configure - Reset the PHY SDR clock divider */ + if (ratio_2to1) { + /* Pup Reset Divider B - Set Reset */ + /* [28] - DataPupRdRST = 0 */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) & + ~(1 << REG_SDRAM_CONFIG_PUPRSTDIV_OFFS); + /* [28] - DataPupRdRST = 1 */ + tmp = reg_read(REG_SDRAM_CONFIG_ADDR) | + (1 << REG_SDRAM_CONFIG_PUPRSTDIV_OFFS); + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* Pup Reset Divider B - Release Reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, tmp); + } + + /* Configure - Reset the PHY Read FIFO and Write channels - Set Reset */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK; + /* [30:29] = 0 - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* + * Configure - DRAM Data PHY Read [30], Write [29] path reset - + * Release Reset + */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK; + /* [30:29] = '11' - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* Registered DIMM support */ + if (dram_info->reg_dimm) { + /* + * Configure - Change register DRAM operating speed + * (DDR3-1333 / DDR3-1600) - CWA_RC + */ + reg = (0xA & REG_SDRAM_OPERATION_CWA_RC_MASK) << + REG_SDRAM_OPERATION_CWA_RC_OFFS; + if (freq <= DDR_400) { + /* + * Configure - Change register DRAM operating speed + * (DDR3-800) - CWA_DATA + */ + reg |= ((0x0 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + } else if ((freq > DDR_400) && (freq <= DDR_533)) { + /* + * Configure - Change register DRAM operating speed + * (DDR3-1066) - CWA_DATA + */ + reg |= ((0x1 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + } else if ((freq > DDR_533) && (freq <= DDR_666)) { + /* + * Configure - Change register DRAM operating speed + * (DDR3-1333) - CWA_DATA + */ + reg |= ((0x2 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + } else { + /* + * Configure - Change register DRAM operating speed + * (DDR3-1600) - CWA_DATA + */ + reg |= ((0x3 & REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + } + + /* Configure - Set Delay - tSTAB */ + reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS); + /* Configure - Issue CWA command with the above parameters */ + reg |= (REG_SDRAM_OPERATION_CMD_CWA & + ~(0xF << REG_SDRAM_OPERATION_CS_OFFS)); + + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for CWA operation completion */ + do { + reg = reg_read(REG_SDRAM_OPERATION_ADDR) & + REG_SDRAM_OPERATION_CMD_MASK; + } while (reg); + } + + /* Configure - Exit Self Refresh */ + /* [2] - DfsSR */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll - DFS Register - 0x1528 [3] - DfsAtSR - All DRAM + * devices on all ranks are NOT in self refresh mode + */ + do { + reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS); + } while (reg); /* Wait for '0' */ + + /* Configure - Issue Refresh command */ + /* [3-0] = 0x2 - Refresh Command, [11-8] - enabled Cs */ + reg = REG_SDRAM_OPERATION_CMD_RFRS; + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) + reg &= ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + } + + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* Configure - Block new external transactions - Disable */ + reg = reg_read(REG_DFS_ADDR); + reg &= ~(1 << REG_DFS_BLOCK_OFFS); /* [1] - DfsBlock - Disable */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Configure - XBAR Retry response during Block to enable + * internal access - Disable + */ + reg = reg_read(REG_METAL_MASK_ADDR); + /* [0] - RetryMask - Enable */ + reg |= (1 << REG_METAL_MASK_RETRY_OFFS); + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + /* Configure - Set CL */ + reg = reg_read(REG_DDR3_MR0_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)) & + ~REG_DDR3_MR0_CL_MASK; + if (freq == DDR_400) + tmp = ddr3_cl_to_valid_cl(6); + else + tmp = ddr3_cl_to_valid_cl(dram_info->cl); + reg |= ((tmp & 0x1) << REG_DDR3_MR0_CL_OFFS); + reg |= ((tmp & 0xE) << REG_DDR3_MR0_CL_HIGH_OFFS); + dfs_reg_write(REG_DDR3_MR0_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + + /* Configure - Set CWL */ + reg = reg_read(REG_DDR3_MR2_CS_ADDR + + (cs << MR_CS_ADDR_OFFS)) & + ~(REG_DDR3_MR2_CWL_MASK << REG_DDR3_MR2_CWL_OFFS); + if (freq == DDR_400) + reg |= ((0) << REG_DDR3_MR2_CWL_OFFS); + else + reg |= ((dram_info->cwl) << REG_DDR3_MR2_CWL_OFFS); + dfs_reg_write(REG_DDR3_MR2_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + DEBUG_DFS_C("DDR3 - DFS - Low To High - Ended successfuly - new Frequency - ", + freq, 1); + + return MV_OK; + +#else + + /* This Flow is relevant for Armada370 A0 and ArmadaXP Z1 */ + + u32 reg, freq_par, tmp; + u32 cs = 0; + + DEBUG_DFS_C("DDR3 - DFS - Low To High - Starting DFS procedure to Frequency - ", + freq, 1); + + /* target frequency - freq */ + freq_par = ddr3_get_freq_parameter(freq, ratio_2to1); + + reg = 0x0000FF00; + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + /* 0x1600 - PHY lock mask register */ + reg = reg_read(REG_ODPG_CNTRL_ADDR); + reg |= (1 << REG_ODPG_CNTRL_OFFS); /* [21] = 1 */ + dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg); + + /* 0x1670 - PHY lock mask register */ + reg = reg_read(REG_PHY_LOCK_MASK_ADDR); + reg &= REG_PHY_LOCK_MASK_MASK; /* [11:0] = 0 */ + dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg); + + /* Enable reconfig MR Registers after DFS */ + reg = reg_read(REG_DFS_ADDR); /* 0x1528 - DFS register */ + /* [4] - Disable - reconfig MR registers after DFS_ERG */ + reg &= ~0x11; + /* [0] - Enable - DRAM DLL after DFS */ + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Disable DRAM Controller to crossbar retry */ + /* [0] - disable */ + reg = reg_read(REG_METAL_MASK_ADDR) & ~(1 << 0); + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + /* Enable DRAM Blocking */ + /* [1] - DFS Block enable */ + reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_BLOCK_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Enable Self refresh */ + /* [2] - DFS Self refresh enable */ + reg = reg_read(REG_DFS_ADDR) | (1 << REG_DFS_SR_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll DFS Register - All DRAM devices on all ranks are in + * self refresh mode - DFS can be executed afterwards + */ + /* 0x1528 [3] - DfsAtSR */ + do { + reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS); + } while (reg == 0x0); /* Wait for '1' */ + + /* + * Set Correct Ratio - if freq>MARGIN_FREQ use 2:1 ratio + * else use 1:1 ratio + */ + if (ratio_2to1) { + /* [15] = 1 - Set 2:1 Ratio between Dunit and Phy */ + reg = reg_read(REG_DDR_IO_ADDR) | + (1 << REG_DDR_IO_CLK_RATIO_OFFS); + } else { + /* [15] = 0 - Set 1:1 Ratio between Dunit and Phy */ + reg = reg_read(REG_DDR_IO_ADDR) & + ~(1 << REG_DDR_IO_CLK_RATIO_OFFS); + } + dfs_reg_write(REG_DDR_IO_ADDR, reg); /* 0x1524 - DDR IO Register */ + + /* Switch HCLK Mux from (100Mhz) [16]=0, keep DFS request bit */ + reg = 0x20040000; + /* + * [29] - training logic request DFS, [28:27] - + * preload patterns frequency [18] + */ + + /* 0x18488 - DRAM Init control status register */ + dfs_reg_write(REG_DRAM_INIT_CTRL_STATUS_ADDR, reg); + + /* Add delay between entering SR and start ratio modification */ + udelay(1); + + /* + * Initial Setup - assure that the "load new ratio" is clear (bit 24) + * and in the same chance, block reassertions of reset [15:8] and + * force reserved bits[7:0]. + */ + reg = 0x0000FFFF; + /* 0x18700 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + /* + * RelaX whenever reset is asserted to that channel (good for any case) + */ + reg = 0x0000FF00; + /* 0x18704 - CPU Div CLK control 0 */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_1_ADDR, reg); + + reg = reg_read(REG_CPU_DIV_CLK_CTRL_3_ADDR) & + REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK; + reg |= (freq_par << REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS); + /* Full Integer ratio from PLL-out to ddr-clk */ + /* 0x1870C - CPU Div CLK control 3 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_3_ADDR, reg); + + /* + * Shut off clock enable to the DDRPHY clock channel (this is the "D"). + * All the rest are kept as is (forced, but could be read-modify-write). + * This is done now by RMW above. + */ + + reg = 0x000FFF02; + + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_4_ADDR, reg); + + /* Wait before replacing the clock on the DDR Phy Channel. */ + udelay(1); + + reg = 0x0102FDFF; + /* + * This for triggering the frequency update. Bit[24] is the + * central control + * bits [23:16] == which channels to change ==2 ==> only DDR Phy + * (smooth transition) + * bits [15:8] == mask reset reassertion due to clock modification + * to these channels. + * bits [7:0] == not in use + */ + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(1); + + /* + * Poll Div CLK status 0 register - indication that the clocks are + * active - 0x18718 [8] + */ + do { + reg = reg_read(REG_CPU_DIV_CLK_STATUS_0_ADDR) & + (1 << REG_CPU_DIV_CLK_ALL_STABLE_OFFS); + } while (reg == 0); + + reg = 0x000000FF; + /* + * Clean the CTRL0, to be ready for next resets and next requests of + * ratio modifications. + */ + /* 0x18700 - CPU Div CLK control 0 register */ + dfs_reg_write(REG_CPU_DIV_CLK_CTRL_0_ADDR, reg); + + udelay(5); + + if (ratio_2to1) { + /* Pup Reset Divider B - Set Reset */ + /* [28] = 0 - Pup Reset Divider B */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) & ~(1 << 28); + /* [28] = 1 - Pup Reset Divider B */ + tmp = reg_read(REG_SDRAM_CONFIG_ADDR) | (1 << 28); + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* Pup Reset Divider B - Release Reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, tmp); + } + + /* DRAM Data PHYs ADLL Reset - Set Reset */ + reg = (reg_read(REG_DRAM_PHY_CONFIG_ADDR) & REG_DRAM_PHY_CONFIG_MASK); + /* [31:30]] - reset pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config Register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + udelay(25); + + /* APLL lock indication - Poll Phy lock status Register - 0x1674 [9] */ + do { + reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) & + (1 << REG_PHY_LOCK_STATUS_LOCK_OFFS); + } while (reg == 0); + + /* DRAM Data PHYs ADLL Reset - Release Reset */ + reg = reg_read(REG_DRAM_PHY_CONFIG_ADDR) | ~REG_DRAM_PHY_CONFIG_MASK; + /* [31:30] - normal pup data ctrl ADLL */ + /* 0x15EC - DRAM PHY Config register */ + dfs_reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + + udelay(10000); /* Wait 10msec */ + + /* + * APLL lock indication - Poll Phy lock status Register - 0x1674 [11:0] + */ + do { + reg = reg_read(REG_PHY_LOCK_STATUS_ADDR) & + REG_PHY_LOCK_STATUS_LOCK_MASK; + } while (reg != REG_PHY_LOCK_STATUS_LOCK_MASK); + + /* DRAM Data PHY Read [30], Write [29] path reset - Set Reset */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) & REG_SDRAM_CONFIG_MASK; + /* [30:29] = 0 - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* DRAM Data PHY Read [30], Write [29] path reset - Release Reset */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) | ~REG_SDRAM_CONFIG_MASK; + /* [30:29] = '11' - Data Pup R/W path reset */ + /* 0x1400 - SDRAM Configuration register */ + dfs_reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /* Disable DFS Reconfig */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << 4); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* [2] - DFS Self refresh disable */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_SR_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* + * Poll DFS Register - 0x1528 [3] - DfsAtSR - All DRAM devices on + * all ranks are NOT in self refresh mode + */ + do { + reg = reg_read(REG_DFS_ADDR) & (1 << REG_DFS_ATSR_OFFS); + } while (reg); /* Wait for '0' */ + + /* 0x1404 */ + reg = (reg_read(REG_DUNIT_CTRL_LOW_ADDR) & 0xFFFFFFE7) | 0x2; + + /* Configure - 2T Mode - Restore original configuration */ + /* [3:4] 2T - Restore value */ + reg &= ~(REG_DUNIT_CTRL_LOW_2T_MASK << REG_DUNIT_CTRL_LOW_2T_OFFS); + reg |= ((dram_info->mode_2t & REG_DUNIT_CTRL_LOW_2T_MASK) << + REG_DUNIT_CTRL_LOW_2T_OFFS); + dfs_reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + + udelay(1); /* Wait 1us */ + + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = (reg_read(REG_DDR3_MR1_ADDR)); + /* DLL Enable */ + reg &= ~(1 << REG_DDR3_MR1_DLL_ENA_OFFS); + dfs_reg_write(REG_DDR3_MR1_ADDR, reg); + + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* DLL Reset - MR0 */ + reg = reg_read(REG_DDR3_MR0_ADDR); + dfs_reg_write(REG_DDR3_MR0_ADDR, reg); + + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR0 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + reg = reg_read(REG_DDR3_MR0_ADDR); + reg &= ~0x74; /* CL [3:0]; [6:4],[2] */ + + if (freq == DDR_400) + tmp = ddr3_cl_to_valid_cl(6) & 0xF; + else + tmp = ddr3_cl_to_valid_cl(dram_info->cl) & 0xF; + + reg |= ((tmp & 0x1) << 2); + reg |= ((tmp >> 1) << 4); /* to bit 4 */ + dfs_reg_write(REG_DDR3_MR0_ADDR, reg); + + reg = REG_SDRAM_OPERATION_CMD_MR0 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + reg = reg_read(REG_DDR3_MR2_ADDR); + reg &= ~0x38; /* CWL [5:3] */ + /* CWL = 0 ,for 400 MHg is 5 */ + if (freq != DDR_400) + reg |= dram_info->cwl << REG_DDR3_MR2_CWL_OFFS; + dfs_reg_write(REG_DDR3_MR2_ADDR, reg); + reg = REG_SDRAM_OPERATION_CMD_MR2 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* 0x1418 - SDRAM Operation Register */ + dfs_reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* Poll - Wait for Refresh operation completion */ + wait_refresh_op_complete(); + + /* Set current rd_sample_delay */ + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + reg |= (dram_info->cl << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + dfs_reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg); + + /* Set current rd_ready_delay */ + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= ((dram_info->cl + 1) << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + dfs_reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + } + } + + /* Enable ODT on DLL-on mode */ + dfs_reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, 0); + + /* [1] - DFS Block disable */ + reg = reg_read(REG_DFS_ADDR) & ~(1 << REG_DFS_BLOCK_OFFS); + dfs_reg_write(REG_DFS_ADDR, reg); /* 0x1528 - DFS register */ + + /* Change DDR frequency to 100MHz procedure: */ + /* 0x1600 - PHY lock mask register */ + reg = reg_read(REG_ODPG_CNTRL_ADDR); + reg &= ~(1 << REG_ODPG_CNTRL_OFFS); /* [21] = 0 */ + dfs_reg_write(REG_ODPG_CNTRL_ADDR, reg); + + /* Change DDR frequency to 100MHz procedure: */ + /* 0x1670 - PHY lock mask register */ + reg = reg_read(REG_PHY_LOCK_MASK_ADDR); + reg |= ~REG_PHY_LOCK_MASK_MASK; /* [11:0] = FFF */ + dfs_reg_write(REG_PHY_LOCK_MASK_ADDR, reg); + + reg = reg_read(REG_METAL_MASK_ADDR) | (1 << 0); /* [0] - disable */ + /* 0x14B0 - Dunit MMask Register */ + dfs_reg_write(REG_METAL_MASK_ADDR, reg); + + DEBUG_DFS_C("DDR3 - DFS - Low To High - Ended successfuly - new Frequency - ", + freq, 1); + return MV_OK; +#endif +} diff --git a/drivers/ddr/mvebu/ddr3_dqs.c b/drivers/ddr/mvebu/ddr3_dqs.c new file mode 100644 index 0000000000..71a986d54f --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_dqs.c @@ -0,0 +1,1374 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" + +/* + * Debug + */ +#define DEBUG_DQS_C(s, d, l) \ + DEBUG_DQS_S(s); DEBUG_DQS_D(d, l); DEBUG_DQS_S("\n") +#define DEBUG_DQS_FULL_C(s, d, l) \ + DEBUG_DQS_FULL_S(s); DEBUG_DQS_FULL_D(d, l); DEBUG_DQS_FULL_S("\n") +#define DEBUG_DQS_RESULTS_C(s, d, l) \ + DEBUG_DQS_RESULTS_S(s); DEBUG_DQS_RESULTS_D(d, l); DEBUG_DQS_RESULTS_S("\n") +#define DEBUG_PER_DQ_C(s, d, l) \ + puts(s); printf("%x", d); puts("\n") + +#define DEBUG_DQS_RESULTS_S(s) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s) +#define DEBUG_DQS_RESULTS_D(d, l) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d) + +#define DEBUG_PER_DQ_S(s) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%s", s) +#define DEBUG_PER_DQ_D(d, l) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%x", d) +#define DEBUG_PER_DQ_DD(d, l) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%d", d) + +#ifdef MV_DEBUG_DQS +#define DEBUG_DQS_S(s) puts(s) +#define DEBUG_DQS_D(d, l) printf("%x", d) +#else +#define DEBUG_DQS_S(s) +#define DEBUG_DQS_D(d, l) +#endif + +#ifdef MV_DEBUG_DQS_FULL +#define DEBUG_DQS_FULL_S(s) puts(s) +#define DEBUG_DQS_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_DQS_FULL_S(s) +#define DEBUG_DQS_FULL_D(d, l) +#endif + +/* State machine for centralization - find low & high limit */ +enum { + PUP_ADLL_LIMITS_STATE_FAIL, + PUP_ADLL_LIMITS_STATE_PASS, + PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS, +}; + +/* Hold centralization low results */ +static int centralization_low_limit[MAX_PUP_NUM] = { 0 }; +/* Hold centralization high results */ +static int centralization_high_limit[MAX_PUP_NUM] = { 0 }; + +int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx); +int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx, + int *size_valid); +static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx); +int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx, u32 special_pattern_pup); +int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx, u32 special_pattern_pup); +int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx); + +#ifdef MV88F78X60 +extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN]; +extern u32 killer_pattern_64b[DQ_NUM][LEN_SPECIAL_PATTERN]; +extern int per_bit_data[MAX_PUP_NUM][DQ_NUM]; +#else +extern u32 killer_pattern[DQ_NUM][LEN_16BIT_KILLER_PATTERN]; +extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN]; +#if defined(MV88F672X) +extern int per_bit_data[MAX_PUP_NUM][DQ_NUM]; +#endif +#endif +extern u32 special_pattern[DQ_NUM][LEN_SPECIAL_PATTERN]; + +static u32 *ddr3_dqs_choose_pattern(MV_DRAM_INFO *dram_info, u32 victim_dq) +{ + u32 *pattern_ptr; + + /* Choose pattern */ + switch (dram_info->ddr_width) { +#if defined(MV88F672X) + case 16: + pattern_ptr = (u32 *)&killer_pattern[victim_dq]; + break; +#endif + case 32: + pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq]; + break; +#if defined(MV88F78X60) + case 64: + pattern_ptr = (u32 *)&killer_pattern_64b[victim_dq]; + break; +#endif + default: +#if defined(MV88F78X60) + pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq]; +#else + pattern_ptr = (u32 *)&killer_pattern[victim_dq]; +#endif + break; + } + + return pattern_ptr; +} + +/* + * Name: ddr3_dqs_centralization_rx + * Desc: Execute the DQS centralization RX phase. + * Args: dram_info + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_dqs_centralization_rx(MV_DRAM_INFO *dram_info) +{ + u32 cs, ecc, reg; + int status; + + DEBUG_DQS_S("DDR3 - DQS Centralization RX - Starting procedure\n"); + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_DQS_S("DDR3 - DQS Centralization RX - SW Override Enabled\n"); + + reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + /* Loop for each CS */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + DEBUG_DQS_FULL_C("DDR3 - DQS Centralization RX - CS - ", + (u32) cs, 1); + + for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { + + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg |= (dram_info->ecc_ena * + ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + if (ecc) + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Enabled\n"); + else + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Disabled\n"); + + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Find all limits\n"); + + status = ddr3_find_adll_limits(dram_info, cs, + ecc, 0); + if (MV_OK != status) + return status; + + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Start calculating center\n"); + + status = ddr3_center_calc(dram_info, cs, ecc, + 0); + if (MV_OK != status) + return status; + } + } + } + + /* ECC Support - Disable ECC MUX */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + return MV_OK; +} + +/* + * Name: ddr3_dqs_centralization_tx + * Desc: Execute the DQS centralization TX phase. + * Args: dram_info + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_dqs_centralization_tx(MV_DRAM_INFO *dram_info) +{ + u32 cs, ecc, reg; + int status; + + DEBUG_DQS_S("DDR3 - DQS Centralization TX - Starting procedure\n"); + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_DQS_S("DDR3 - DQS Centralization TX - SW Override Enabled\n"); + + reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + /* Loop for each CS */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + DEBUG_DQS_FULL_C("DDR3 - DQS Centralization TX - CS - ", + (u32) cs, 1); + for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg |= (dram_info->ecc_ena * + ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + if (ecc) + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Enabled\n"); + else + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Disabled\n"); + + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Find all limits\n"); + + status = ddr3_find_adll_limits(dram_info, cs, + ecc, 1); + if (MV_OK != status) + return status; + + DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Start calculating center\n"); + + status = ddr3_center_calc(dram_info, cs, ecc, + 1); + if (MV_OK != status) + return status; + } + } + } + + /* ECC Support - Disable ECC MUX */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + return MV_OK; +} + +/* + * Name: ddr3_find_adll_limits + * Desc: Execute the Find ADLL limits phase. + * Args: dram_info + * cs + * ecc_ena + * is_tx Indicate whether Rx or Tx + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx) +{ + u32 victim_dq, pup, tmp; + u32 adll_addr; + u32 max_pup; /* maximal pup index */ + u32 pup_mask = 0; + u32 unlock_pup; /* bit array of un locked pups */ + u32 new_unlock_pup; /* bit array of compare failed pups */ + u32 curr_adll; + u32 adll_start_val; /* adll start loop value - for rx or tx limit */ + u32 high_limit; /* holds found High Limit */ + u32 low_limit; /* holds found Low Limit */ + int win_valid; + int update_win; + u32 sdram_offset; + u32 uj, cs_count, cs_tmp, ii; + u32 *pattern_ptr; + u32 dq; + u32 adll_end_val; /* adll end of loop val - for rx or tx limit */ + u8 analog_pbs[DQ_NUM][MAX_PUP_NUM][DQ_NUM][2]; + u8 analog_pbs_sum[MAX_PUP_NUM][DQ_NUM][2]; + int pup_adll_limit_state[MAX_PUP_NUM]; /* hold state of each pup */ + + adll_addr = ((is_tx == 1) ? PUP_DQS_WR : PUP_DQS_RD); + adll_end_val = ((is_tx == 1) ? ADLL_MIN : ADLL_MAX); + adll_start_val = ((is_tx == 1) ? ADLL_MAX : ADLL_MIN); + max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); + + DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - Starting Find ADLL Limits\n"); + + /* init the array */ + for (pup = 0; pup < max_pup; pup++) { + centralization_low_limit[pup] = ADLL_MIN; + centralization_high_limit[pup] = ADLL_MAX; + } + + /* Killer Pattern */ + cs_count = 0; + for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) { + if (dram_info->cs_ena & (1 << cs_tmp)) + cs_count++; + } + sdram_offset = cs_count * (SDRAM_CS_SIZE + 1); + sdram_offset += ((is_tx == 1) ? + SDRAM_DQS_TX_OFFS : SDRAM_DQS_RX_OFFS); + + /* Prepare pup masks */ + for (pup = 0; pup < max_pup; pup++) + pup_mask |= (1 << pup); + + for (pup = 0; pup < max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + analog_pbs_sum[pup][dq][0] = adll_start_val; + analog_pbs_sum[pup][dq][1] = adll_end_val; + } + } + + /* Loop - use different pattern for each victim_dq */ + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Victim DQ - ", + (u32)victim_dq, 1); + /* + * The pups 3 bit arrays represent state machine. with + * 3 stages for each pup. + * 1. fail and didn't get pass in earlier compares. + * 2. pass compare + * 3. fail after pass - end state. + * The window limits are the adll values where the adll + * was in the pass stage. + */ + + /* Set all states to Fail (1st state) */ + for (pup = 0; pup < max_pup; pup++) + pup_adll_limit_state[pup] = PUP_ADLL_LIMITS_STATE_FAIL; + + /* Set current valid pups */ + unlock_pup = pup_mask; + + /* Set ADLL to start value */ + curr_adll = adll_start_val; + +#if defined(MV88F78X60) + for (pup = 0; pup < max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + analog_pbs[victim_dq][pup][dq][0] = + adll_start_val; + analog_pbs[victim_dq][pup][dq][1] = + adll_end_val; + per_bit_data[pup][dq] = 0; + } + } +#endif + + for (uj = 0; uj < ADLL_MAX; uj++) { + DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Setting ADLL to ", + curr_adll, 2); + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + tmp = ((is_tx == 1) ? curr_adll + + dram_info->wl_val[cs] + [pup * (1 - ecc) + ecc * ECC_PUP] + [D] : curr_adll); + ddr3_write_pup_reg(adll_addr, cs, pup + + (ecc * ECC_PUP), 0, tmp); + } + } + + /* Choose pattern */ + pattern_ptr = ddr3_dqs_choose_pattern(dram_info, + victim_dq); + + /* '1' - means pup failed, '0' - means pup pass */ + new_unlock_pup = 0; + + /* Read and compare results for Victim_DQ# */ + for (ii = 0; ii < 3; ii++) { + u32 tmp = 0; + if (MV_OK != ddr3_sdram_dqs_compare(dram_info, + unlock_pup, &tmp, + pattern_ptr, + LEN_KILLER_PATTERN, + sdram_offset + + LEN_KILLER_PATTERN * + 4 * victim_dq, + is_tx, 0, NULL, + 0)) + return MV_DDR3_TRAINING_ERR_DRAM_COMPARE; + + new_unlock_pup |= tmp; + } + + pup = 0; + DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - UnlockPup: ", + unlock_pup, 2); + DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - NewUnlockPup: ", + new_unlock_pup, 2); + + /* Update pup state */ + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 0) { + DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Skipping pup ", + pup, 1); + continue; + } + + /* + * Still didn't find the window limit of the pup + */ + if (IS_PUP_ACTIVE(new_unlock_pup, pup) == 1) { + /* Current compare result == fail */ + if (pup_adll_limit_state[pup] == + PUP_ADLL_LIMITS_STATE_PASS) { + /* + * If now it failed but passed + * earlier + */ + DEBUG_DQS_S("DDR3 - DQS Find Limits - PASS to FAIL: CS - "); + DEBUG_DQS_D(cs, 1); + DEBUG_DQS_S(", DQ - "); + DEBUG_DQS_D(victim_dq, 1); + DEBUG_DQS_S(", Pup - "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_S(", ADLL - "); + DEBUG_DQS_D(curr_adll, 2); + DEBUG_DQS_S("\n"); + +#if defined(MV88F78X60) + for (dq = 0; dq < DQ_NUM; dq++) { + if ((analog_pbs[victim_dq][pup][dq][0] != adll_start_val) + && (analog_pbs[victim_dq][pup] + [dq][1] == adll_end_val)) + analog_pbs + [victim_dq] + [pup][dq] + [1] = + curr_adll; + } +#endif + win_valid = 1; + update_win = 0; + + /* Keep min / max limit value */ + if (is_tx == 0) { + /* RX - found upper limit */ + if (centralization_high_limit[pup] > + (curr_adll - 1)) { + high_limit = + curr_adll - 1; + low_limit = + centralization_low_limit[pup]; + update_win = 1; + } + } else { + /* TX - found lower limit */ + if (centralization_low_limit[pup] < (curr_adll + 1)) { + high_limit = + centralization_high_limit + [pup]; + low_limit = + curr_adll + 1; + update_win = + 1; + } + } + + if (update_win == 1) { + /* + * Before updating + * window limits we need + * to check that the + * limits are valid + */ + if (MV_OK != + ddr3_check_window_limits + (pup, high_limit, + low_limit, is_tx, + &win_valid)) + return MV_DDR3_TRAINING_ERR_WIN_LIMITS; + + if (win_valid == 1) { + /* + * Window limits + * should be + * updated + */ + centralization_low_limit + [pup] = + low_limit; + centralization_high_limit + [pup] = + high_limit; + } + } + + if (win_valid == 1) { + /* Found end of window - lock the pup */ + pup_adll_limit_state[pup] = + PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS; + unlock_pup &= ~(1 << pup); + } else { + /* Probably false pass - reset status */ + pup_adll_limit_state[pup] = + PUP_ADLL_LIMITS_STATE_FAIL; + +#if defined(MV88F78X60) + /* Clear logging array of win size (per Dq) */ + for (dq = 0; + dq < DQ_NUM; + dq++) { + analog_pbs + [victim_dq] + [pup][dq] + [0] = + adll_start_val; + analog_pbs + [victim_dq] + [pup][dq] + [1] = + adll_end_val; + per_bit_data + [pup][dq] + = 0; + } +#endif + } + } + } else { + /* Current compare result == pass */ + if (pup_adll_limit_state[pup] == + PUP_ADLL_LIMITS_STATE_FAIL) { + /* If now it passed but failed earlier */ + DEBUG_DQS_S("DDR3 - DQS Find Limits - FAIL to PASS: CS - "); + DEBUG_DQS_D(cs, 1); + DEBUG_DQS_S(", DQ - "); + DEBUG_DQS_D(victim_dq, 1); + DEBUG_DQS_S(", Pup - "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_S(", ADLL - "); + DEBUG_DQS_D(curr_adll, 2); + DEBUG_DQS_S("\n"); + +#if defined(MV88F78X60) + for (dq = 0; dq < DQ_NUM; + dq++) { + if (analog_pbs[victim_dq][pup][dq][0] == adll_start_val) + analog_pbs + [victim_dq] + [pup][dq] + [0] = + curr_adll; + } +#endif + /* Found start of window */ + pup_adll_limit_state[pup] = + PUP_ADLL_LIMITS_STATE_PASS; + + /* Keep min / max limit value */ + if (is_tx == 0) { + /* RX - found low limit */ + if (centralization_low_limit[pup] <= curr_adll) + centralization_low_limit + [pup] = + curr_adll; + } else { + /* TX - found high limit */ + if (centralization_high_limit[pup] >= curr_adll) + centralization_high_limit + [pup] = + curr_adll; + } + } + } + } + + if (unlock_pup == 0) { + /* Found limit to all pups */ + DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - found PUP limit\n"); + break; + } + + /* + * Increment / decrement (Move to right / left + * one phase - ADLL) dqs RX / TX delay (for all un + * lock pups + */ + if (is_tx == 0) + curr_adll++; + else + curr_adll--; + } + + if (unlock_pup != 0) { + /* + * Found pups that didn't reach to the end of the + * state machine + */ + DEBUG_DQS_C("DDR3 - DQS Find Limits - Pups that didn't reached end of the state machine: ", + unlock_pup, 1); + + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + if (pup_adll_limit_state[pup] == + PUP_ADLL_LIMITS_STATE_FAIL) { + /* ERROR - found fail for all window size */ + DEBUG_DQS_S("DDR3 - DQS Find Limits - Got FAIL for the complete range on pup - "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_C(" victim DQ ", + victim_dq, 1); + + /* For debug - set min limit to illegal limit */ + centralization_low_limit[pup] + = ADLL_ERROR; + /* + * In case the pup is in mode + * PASS - the limit is the min + * / max adll, no need to + * update because of the results + * array default value + */ + return MV_DDR3_TRAINING_ERR_PUP_RANGE; + } + } + } + } + } + + DEBUG_DQS_S("DDR3 - DQS Find Limits - DQ values per victim results:\n"); + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + for (pup = 0; pup < max_pup; pup++) { + DEBUG_DQS_S("Victim DQ-"); + DEBUG_DQS_D(victim_dq, 1); + DEBUG_DQS_S(", PUP-"); + DEBUG_DQS_D(pup, 1); + for (dq = 0; dq < DQ_NUM; dq++) { + DEBUG_DQS_S(", DQ-"); + DEBUG_DQS_D(dq, 1); + DEBUG_DQS_S(",S-"); + DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq] + [0], 2); + DEBUG_DQS_S(",E-"); + DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq] + [1], 2); + + if (is_tx == 0) { + if (analog_pbs[victim_dq][pup][dq][0] + > analog_pbs_sum[pup][dq][0]) + analog_pbs_sum[pup][dq][0] = + analog_pbs[victim_dq][pup] + [dq][0]; + if (analog_pbs[victim_dq][pup][dq][1] + < analog_pbs_sum[pup][dq][1]) + analog_pbs_sum[pup][dq][1] = + analog_pbs[victim_dq][pup] + [dq][1]; + } else { + if (analog_pbs[victim_dq][pup][dq][0] + < analog_pbs_sum[pup][dq][0]) + analog_pbs_sum[pup][dq][0] = + analog_pbs[victim_dq][pup] + [dq][0]; + if (analog_pbs[victim_dq][pup][dq][1] + > analog_pbs_sum[pup][dq][1]) + analog_pbs_sum[pup][dq][1] = + analog_pbs[victim_dq][pup] + [dq][1]; + } + } + DEBUG_DQS_S("\n"); + } + } + + if (ddr3_get_log_level() >= MV_LOG_LEVEL_3) { + u32 dq; + + DEBUG_PER_DQ_S("\n########## LOG LEVEL 3(Windows margins per-DQ) ##########\n"); + if (is_tx) { + DEBUG_PER_DQ_C("DDR3 - TX CS: ", cs, 1); + } else { + DEBUG_PER_DQ_C("DDR3 - RX CS: ", cs, 1); + } + + if (ecc == 0) { + DEBUG_PER_DQ_S("\n DATA RESULTS:\n"); + } else { + DEBUG_PER_DQ_S("\n ECC RESULTS:\n"); + } + + /* Since all dq has the same value we take 0 as representive */ + dq = 0; + for (pup = 0; pup < max_pup; pup++) { + if (ecc == 0) { + DEBUG_PER_DQ_S("\nBYTE:"); + DEBUG_PER_DQ_D(pup, 1); + DEBUG_PER_DQ_S("\n"); + } else { + DEBUG_PER_DQ_S("\nECC BYTE:\n"); + } + DEBUG_PER_DQ_S(" DQ's LOW HIGH WIN-SIZE\n"); + DEBUG_PER_DQ_S("============================================\n"); + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + if (ecc == 0) { + DEBUG_PER_DQ_S("DQ["); + DEBUG_PER_DQ_DD((victim_dq + + DQ_NUM * pup), 2); + DEBUG_PER_DQ_S("]"); + } else { + DEBUG_PER_DQ_S("CB["); + DEBUG_PER_DQ_DD(victim_dq, 2); + DEBUG_PER_DQ_S("]"); + } + if (is_tx) { + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1], 2); /* low value */ + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* high value */ + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0] - analog_pbs[victim_dq][pup][dq][1], 2); /* win-size */ + } else { + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* low value */ + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D((analog_pbs[victim_dq][pup][dq][1] - 1), 2); /* high value */ + DEBUG_PER_DQ_S(" 0x"); + DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1] - analog_pbs[victim_dq][pup][dq][0], 2); /* win-size */ + } + DEBUG_PER_DQ_S("\n"); + } + } + DEBUG_PER_DQ_S("\n"); + } + + if (is_tx) { + DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n"); + } else { + DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n"); + } + + for (pup = 0; pup < max_pup; pup++) { + DEBUG_DQS_S("PUP-"); + DEBUG_DQS_D(pup, 1); + for (dq = 0; dq < DQ_NUM; dq++) { + DEBUG_DQS_S(", DQ-"); + DEBUG_DQS_D(dq, 1); + DEBUG_DQS_S(",S-"); + DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2); + DEBUG_DQS_S(",E-"); + DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2); + } + DEBUG_DQS_S("\n"); + } + + if (is_tx) { + DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n"); + } else { + DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n"); + } + + for (pup = 0; pup < max_pup; pup++) { + if (max_pup == 1) { + /* For ECC PUP */ + DEBUG_DQS_S("DDR3 - DQS8"); + } else { + DEBUG_DQS_S("DDR3 - DQS"); + DEBUG_DQS_D(pup, 1); + } + + for (dq = 0; dq < DQ_NUM; dq++) { + DEBUG_DQS_S(", DQ-"); + DEBUG_DQS_D(dq, 1); + DEBUG_DQS_S("::S-"); + DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2); + DEBUG_DQS_S(",E-"); + DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2); + } + DEBUG_DQS_S("\n"); + } + + DEBUG_DQS_S("DDR3 - DQS Find Limits - Ended\n"); + + return MV_OK; +} + +/* + * Name: ddr3_check_window_limits + * Desc: Check window High & Low limits. + * Args: pup pup index + * high_limit window high limit + * low_limit window low limit + * is_tx Indicate whether Rx or Tx + * size_valid Indicate whether window size is valid + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx, + int *size_valid) +{ + DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Starting\n"); + + if (low_limit > high_limit) { + DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_S(" Low Limit grater than High Limit\n"); + *size_valid = 0; + return MV_OK; + } + + /* + * Check that window size is valid, if not it was probably false pass + * before + */ + if ((high_limit - low_limit) < MIN_WIN_SIZE) { + /* + * Since window size is too small probably there was false + * pass + */ + *size_valid = 0; + + DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_S(" Window size is smaller than MIN_WIN_SIZE\n"); + + } else if ((high_limit - low_limit) > ADLL_MAX) { + *size_valid = 0; + + DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); + DEBUG_DQS_D(pup, 1); + DEBUG_DQS_S + (" Window size is bigger than max ADLL taps (31) Exiting.\n"); + + return MV_FAIL; + + } else { + *size_valid = 1; + + DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Pup "); + DEBUG_DQS_FULL_D(pup, 1); + DEBUG_DQS_FULL_C(" window size is ", (high_limit - low_limit), + 2); + } + + return MV_OK; +} + +/* + * Name: ddr3_center_calc + * Desc: Execute the calculate the center of windows phase. + * Args: pDram Info + * is_tx Indicate whether Rx or Tx + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx) +{ + /* bit array of pups that need specail search */ + u32 special_pattern_i_pup = 0; + u32 special_pattern_ii_pup = 0; + u32 pup; + u32 max_pup; + + max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); + + for (pup = 0; pup < max_pup; pup++) { + if (is_tx == 0) { + /* Check special pattern I */ + /* + * Special pattern Low limit search - relevant only + * for Rx, win size < threshold and low limit = 0 + */ + if (((centralization_high_limit[pup] - + centralization_low_limit[pup]) < VALID_WIN_THRS) + && (centralization_low_limit[pup] == MIN_DELAY)) + special_pattern_i_pup |= (1 << pup); + + /* Check special pattern II */ + /* + * Special pattern High limit search - relevant only + * for Rx, win size < threshold and high limit = 31 + */ + if (((centralization_high_limit[pup] - + centralization_low_limit[pup]) < VALID_WIN_THRS) + && (centralization_high_limit[pup] == MAX_DELAY)) + special_pattern_ii_pup |= (1 << pup); + } + } + + /* Run special pattern Low limit search - for relevant pup */ + if (special_pattern_i_pup != 0) { + DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern I for Low limit search\n"); + if (MV_OK != + ddr3_special_pattern_i_search(dram_info, cs, ecc, is_tx, + special_pattern_i_pup)) + return MV_DDR3_TRAINING_ERR_DQS_LOW_LIMIT_SEARCH; + } + + /* Run special pattern High limit search - for relevant pup */ + if (special_pattern_ii_pup != 0) { + DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern II for High limit search\n"); + if (MV_OK != + ddr3_special_pattern_ii_search(dram_info, cs, ecc, is_tx, + special_pattern_ii_pup)) + return MV_DDR3_TRAINING_ERR_DQS_HIGH_LIMIT_SEARCH; + } + + /* Set adll to center = (General_High_limit + General_Low_limit)/2 */ + return ddr3_set_dqs_centralization_results(dram_info, cs, ecc, is_tx); +} + +/* + * Name: ddr3_special_pattern_i_search + * Desc: Execute special pattern low limit search. + * Args: + * special_pattern_pup The pups that need the special search + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx, u32 special_pattern_pup) +{ + u32 victim_dq; /* loop index - victim DQ */ + u32 adll_idx; + u32 pup; + u32 unlock_pup; /* bit array of the unlock pups */ + u32 first_fail; /* bit array - of pups that get first fail */ + u32 new_lockup_pup; /* bit array of compare failed pups */ + u32 pass_pup; /* bit array of compare pass pup */ + u32 sdram_offset; + u32 max_pup; + u32 comp_val; + u32 special_res[MAX_PUP_NUM]; /* hold tmp results */ + + DEBUG_DQS_S("DDR3 - DQS - Special Pattern I Search - Starting\n"); + + max_pup = ecc + (1 - ecc) * dram_info->num_of_std_pups; + + /* Init the temporary results to max ADLL value */ + for (pup = 0; pup < max_pup; pup++) + special_res[pup] = ADLL_MAX; + + /* Run special pattern for all DQ - use the same pattern */ + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + unlock_pup = special_pattern_pup; + first_fail = 0; + + sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS + + LEN_KILLER_PATTERN * 4 * victim_dq; + + for (pup = 0; pup < max_pup; pup++) { + /* Set adll value per PUP. adll = high limit per pup */ + if (IS_PUP_ACTIVE(unlock_pup, pup)) { + /* only for pups that need special search */ + ddr3_write_pup_reg(PUP_DQS_RD, cs, + pup + (ecc * ECC_PUP), 0, + centralization_high_limit + [pup]); + } + } + + adll_idx = 0; + do { + /* + * Perform read and compare simultaneously for all + * un-locked MC use the special pattern mask + */ + new_lockup_pup = 0; + + if (MV_OK != + ddr3_sdram_dqs_compare(dram_info, unlock_pup, + &new_lockup_pup, + special_pattern + [victim_dq], + LEN_SPECIAL_PATTERN, + sdram_offset, 0, + 0, NULL, 1)) + return MV_FAIL; + + DEBUG_DQS_S("DDR3 - DQS - Special I - ADLL value is: "); + DEBUG_DQS_D(adll_idx, 2); + DEBUG_DQS_S(", UnlockPup: "); + DEBUG_DQS_D(unlock_pup, 2); + DEBUG_DQS_S(", NewLockPup: "); + DEBUG_DQS_D(new_lockup_pup, 2); + DEBUG_DQS_S("\n"); + + if (unlock_pup != new_lockup_pup) + DEBUG_DQS_S("DDR3 - DQS - Special I - Some Pup passed!\n"); + + /* Search for pups with passed compare & already fail */ + pass_pup = first_fail & ~new_lockup_pup & unlock_pup; + first_fail |= new_lockup_pup; + unlock_pup &= ~pass_pup; + + /* Get pass pups */ + if (pass_pup != 0) { + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(pass_pup, pup) == + 1) { + /* If pup passed and has first fail = 1 */ + /* keep min value of ADLL max value - current adll */ + /* (centralization_high_limit[pup] + adll_idx) = current adll !!! */ + comp_val = + (ADLL_MAX - + (centralization_high_limit + [pup] + adll_idx)); + + DEBUG_DQS_C + ("DDR3 - DQS - Special I - Pup - ", + pup, 1); + DEBUG_DQS_C + (" comp_val = ", + comp_val, 2); + + if (comp_val < + special_res[pup]) { + special_res[pup] = + comp_val; + centralization_low_limit + [pup] = + (-1) * + comp_val; + + DEBUG_DQS_C + ("DDR3 - DQS - Special I - Pup - ", + pup, 1); + DEBUG_DQS_C + (" Changed Low limit to ", + centralization_low_limit + [pup], 2); + } + } + } + } + + /* + * Did all PUP found missing window? + * Check for each pup if adll (different for each pup) + * reach maximum if reach max value - lock the pup + * if not - increment (Move to right one phase - ADLL) + * dqs RX delay + */ + adll_idx++; + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + /* Check only unlocked pups */ + if ((centralization_high_limit[pup] + + adll_idx) >= ADLL_MAX) { + /* reach maximum - lock the pup */ + DEBUG_DQS_C("DDR3 - DQS - Special I - reach maximum - lock pup ", + pup, 1); + unlock_pup &= ~(1 << pup); + } else { + /* Didn't reach maximum - increment ADLL */ + ddr3_write_pup_reg(PUP_DQS_RD, + cs, + pup + + (ecc * + ECC_PUP), 0, + (centralization_high_limit + [pup] + + adll_idx)); + } + } + } + } while (unlock_pup != 0); + } + + return MV_OK; +} + +/* + * Name: ddr3_special_pattern_ii_search + * Desc: Execute special pattern high limit search. + * Args: + * special_pattern_pup The pups that need the special search + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, + int is_tx, u32 special_pattern_pup) +{ + u32 victim_dq; /* loop index - victim DQ */ + u32 adll_idx; + u32 pup; + u32 unlock_pup; /* bit array of the unlock pups */ + u32 first_fail; /* bit array - of pups that get first fail */ + u32 new_lockup_pup; /* bit array of compare failed pups */ + u32 pass_pup; /* bit array of compare pass pup */ + u32 sdram_offset; + u32 max_pup; + u32 comp_val; + u32 special_res[MAX_PUP_NUM]; /* hold tmp results */ + + DEBUG_DQS_S("DDR3 - DQS - Special Pattern II Search - Starting\n"); + + max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); + + /* init the tmporary results to max ADLL value */ + for (pup = 0; pup < max_pup; pup++) + special_res[pup] = ADLL_MAX; + + sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS; + + /* run special pattern for all DQ - use the same pattern */ + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + unlock_pup = special_pattern_pup; + first_fail = 0; + + for (pup = 0; pup < max_pup; pup++) { + /* Set adll value per PUP. adll = 0 */ + if (IS_PUP_ACTIVE(unlock_pup, pup)) { + /* Only for pups that need special search */ + ddr3_write_pup_reg(PUP_DQS_RD, cs, + pup + (ecc * ECC_PUP), 0, + ADLL_MIN); + } + } + + adll_idx = 0; + do { + /* + * Perform read and compare simultaneously for all + * un-locked MC use the special pattern mask + */ + new_lockup_pup = 0; + + if (MV_OK != ddr3_sdram_dqs_compare( + dram_info, unlock_pup, &new_lockup_pup, + special_pattern[victim_dq], + LEN_SPECIAL_PATTERN, + sdram_offset, 0, 0, NULL, 0)) + return MV_FAIL; + + DEBUG_DQS_S("DDR3 - DQS - Special II - ADLL value is "); + DEBUG_DQS_D(adll_idx, 2); + DEBUG_DQS_S("unlock_pup "); + DEBUG_DQS_D(unlock_pup, 1); + DEBUG_DQS_S("new_lockup_pup "); + DEBUG_DQS_D(new_lockup_pup, 1); + DEBUG_DQS_S("\n"); + + if (unlock_pup != new_lockup_pup) { + DEBUG_DQS_S("DDR3 - DQS - Special II - Some Pup passed!\n"); + } + + /* Search for pups with passed compare & already fail */ + pass_pup = first_fail & ~new_lockup_pup & unlock_pup; + first_fail |= new_lockup_pup; + unlock_pup &= ~pass_pup; + + /* Get pass pups */ + if (pass_pup != 0) { + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(pass_pup, pup) == + 1) { + /* If pup passed and has first fail = 1 */ + /* keep min value of ADLL max value - current adll */ + /* (adll_idx) = current adll !!! */ + comp_val = adll_idx; + + DEBUG_DQS_C("DDR3 - DQS - Special II - Pup - ", + pup, 1); + DEBUG_DQS_C(" comp_val = ", + comp_val, 1); + + if (comp_val < + special_res[pup]) { + special_res[pup] = + comp_val; + centralization_high_limit + [pup] = + ADLL_MAX + + comp_val; + + DEBUG_DQS_C + ("DDR3 - DQS - Special II - Pup - ", + pup, 1); + DEBUG_DQS_C + (" Changed High limit to ", + centralization_high_limit + [pup], 2); + } + } + } + } + + /* + * Did all PUP found missing window? + * Check for each pup if adll (different for each pup) + * reach maximum if reach max value - lock the pup + * if not - increment (Move to right one phase - ADLL) + * dqs RX delay + */ + adll_idx++; + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + /* Check only unlocked pups */ + if ((adll_idx) >= ADLL_MAX) { + /* Reach maximum - lock the pup */ + DEBUG_DQS_C("DDR3 - DQS - Special II - reach maximum - lock pup ", + pup, 1); + unlock_pup &= ~(1 << pup); + } else { + /* Didn't reach maximum - increment ADLL */ + ddr3_write_pup_reg(PUP_DQS_RD, + cs, + pup + + (ecc * + ECC_PUP), 0, + (adll_idx)); + } + } + } + } while (unlock_pup != 0); + } + + return MV_OK; +} + +/* + * Name: ddr3_set_dqs_centralization_results + * Desc: Set to HW the DQS centralization phase results. + * Args: + * is_tx Indicates whether to set Tx or RX results + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs, + u32 ecc, int is_tx) +{ + u32 pup, pup_num; + int addl_val; + u32 max_pup; + + max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); + + DEBUG_DQS_RESULTS_S("\n############ LOG LEVEL 2(Windows margins) ############\n");; + + if (is_tx) { + DEBUG_DQS_RESULTS_C("DDR3 - DQS TX - Set Dqs Centralization Results - CS: ", + cs, 1); + } else { + DEBUG_DQS_RESULTS_C("DDR3 - DQS RX - Set Dqs Centralization Results - CS: ", + cs, 1); + } + + /* Set adll to center = (General_High_limit + General_Low_limit)/2 */ + DEBUG_DQS_RESULTS_S("\nDQS LOW HIGH WIN-SIZE Set\n"); + DEBUG_DQS_RESULTS_S("==============================================\n"); + for (pup = 0; pup < max_pup; pup++) { + addl_val = (centralization_high_limit[pup] + + centralization_low_limit[pup]) / 2; + + pup_num = pup * (1 - ecc) + ecc * ECC_PUP; + + DEBUG_DQS_RESULTS_D(pup_num, 1); + DEBUG_DQS_RESULTS_S(" 0x"); + DEBUG_DQS_RESULTS_D(centralization_low_limit[pup], 2); + DEBUG_DQS_RESULTS_S(" 0x"); + DEBUG_DQS_RESULTS_D(centralization_high_limit[pup], 2); + DEBUG_DQS_RESULTS_S(" 0x"); + DEBUG_DQS_RESULTS_D(centralization_high_limit[pup] - + centralization_low_limit[pup], 2); + DEBUG_DQS_RESULTS_S(" 0x"); + DEBUG_DQS_RESULTS_D(addl_val, 2); + DEBUG_DQS_RESULTS_S("\n"); + + if (addl_val < ADLL_MIN) { + addl_val = ADLL_MIN; + DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MIN (since it was lower than 0)\n"); + } + + if (addl_val > ADLL_MAX) { + addl_val = ADLL_MAX; + DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MAX (since it was higher than 31)\n"); + } + + if (is_tx) { + ddr3_write_pup_reg(PUP_DQS_WR, cs, pup_num, 0, + addl_val + + dram_info->wl_val[cs][pup_num][D]); + } else { + ddr3_write_pup_reg(PUP_DQS_RD, cs, pup_num, 0, + addl_val); + } + } + + return MV_OK; +} + +/* + * Set training patterns + */ +int ddr3_load_dqs_patterns(MV_DRAM_INFO *dram_info) +{ + u32 cs, cs_count, cs_tmp, victim_dq; + u32 sdram_addr; + u32 *pattern_ptr; + + /* Loop for each CS */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + cs_count = 0; + for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) { + if (dram_info->cs_ena & (1 << cs_tmp)) + cs_count++; + } + + /* Init killer pattern */ + sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + + SDRAM_DQS_RX_OFFS); + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + pattern_ptr = ddr3_dqs_choose_pattern(dram_info, + victim_dq); + if (MV_OK != ddr3_sdram_dqs_compare( + dram_info, (u32)NULL, NULL, + pattern_ptr, LEN_KILLER_PATTERN, + sdram_addr + LEN_KILLER_PATTERN * + 4 * victim_dq, 1, 0, NULL, + 0)) + return MV_DDR3_TRAINING_ERR_DQS_PATTERN; + } + + /* Init special-killer pattern */ + sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + + SDRAM_DQS_RX_SPECIAL_OFFS); + for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { + if (MV_OK != ddr3_sdram_dqs_compare( + dram_info, (u32)NULL, NULL, + special_pattern[victim_dq], + LEN_KILLER_PATTERN, sdram_addr + + LEN_KILLER_PATTERN * 4 * victim_dq, + 1, 0, NULL, 0)) + return MV_DDR3_TRAINING_ERR_DQS_PATTERN; + } + } + } + + return MV_OK; +} diff --git a/drivers/ddr/mvebu/ddr3_hw_training.c b/drivers/ddr/mvebu/ddr3_hw_training.c new file mode 100644 index 0000000000..a8c5e6a534 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_hw_training.c @@ -0,0 +1,1115 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_init.h" +#include "ddr3_hw_training.h" +#include "xor.h" + +#ifdef MV88F78X60 +#include "ddr3_patterns_64bit.h" +#else +#include "ddr3_patterns_16bit.h" +#if defined(MV88F672X) +#include "ddr3_patterns_16bit.h" +#endif +#endif + +/* + * Debug + */ + +#define DEBUG_MAIN_C(s, d, l) \ + DEBUG_MAIN_S(s); DEBUG_MAIN_D(d, l); DEBUG_MAIN_S("\n") +#define DEBUG_MAIN_FULL_C(s, d, l) \ + DEBUG_MAIN_FULL_S(s); DEBUG_MAIN_FULL_D(d, l); DEBUG_MAIN_FULL_S("\n") + +#ifdef MV_DEBUG_MAIN +#define DEBUG_MAIN_S(s) puts(s) +#define DEBUG_MAIN_D(d, l) printf("%x", d) +#else +#define DEBUG_MAIN_S(s) +#define DEBUG_MAIN_D(d, l) +#endif + +#ifdef MV_DEBUG_MAIN_FULL +#define DEBUG_MAIN_FULL_S(s) puts(s) +#define DEBUG_MAIN_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_MAIN_FULL_S(s) +#define DEBUG_MAIN_FULL_D(d, l) +#endif + +#ifdef MV_DEBUG_SUSPEND_RESUME +#define DEBUG_SUSPEND_RESUME_S(s) puts(s) +#define DEBUG_SUSPEND_RESUME_D(d, l) printf("%x", d) +#else +#define DEBUG_SUSPEND_RESUME_S(s) +#define DEBUG_SUSPEND_RESUME_D(d, l) +#endif + +static u32 ddr3_sw_wl_rl_debug; +static u32 ddr3_run_pbs = 1; + +void ddr3_print_version(void) +{ + puts("DDR3 Training Sequence - Ver 5.7."); +} + +void ddr3_set_sw_wl_rl_debug(u32 val) +{ + ddr3_sw_wl_rl_debug = val; +} + +void ddr3_set_pbs(u32 val) +{ + ddr3_run_pbs = val; +} + +int ddr3_hw_training(u32 target_freq, u32 ddr_width, int xor_bypass, + u32 scrub_offs, u32 scrub_size, int dqs_clk_aligned, + int debug_mode, int reg_dimm_skip_wl) +{ + /* A370 has no PBS mechanism */ + __maybe_unused u32 first_loop_flag = 0; + u32 freq, reg; + MV_DRAM_INFO dram_info; + int ratio_2to1 = 0; + int tmp_ratio = 1; + int status; + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 1\n"); + + memset(&dram_info, 0, sizeof(dram_info)); + dram_info.num_cs = ddr3_get_cs_num_from_reg(); + dram_info.cs_ena = ddr3_get_cs_ena_from_reg(); + dram_info.target_frequency = target_freq; + dram_info.ddr_width = ddr_width; + dram_info.num_of_std_pups = ddr_width / PUP_SIZE; + dram_info.rl400_bug = 0; + dram_info.multi_cs_mr_support = 0; +#ifdef MV88F67XX + dram_info.rl400_bug = 1; +#endif + + /* Ignore ECC errors - if ECC is enabled */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR); + if (reg & (1 << REG_SDRAM_CONFIG_ECC_OFFS)) { + dram_info.ecc_ena = 1; + reg |= (1 << REG_SDRAM_CONFIG_IERR_OFFS); + reg_write(REG_SDRAM_CONFIG_ADDR, reg); + } else { + dram_info.ecc_ena = 0; + } + + reg = reg_read(REG_SDRAM_CONFIG_ADDR); + if (reg & (1 << REG_SDRAM_CONFIG_REGDIMM_OFFS)) + dram_info.reg_dimm = 1; + else + dram_info.reg_dimm = 0; + + dram_info.num_of_total_pups = ddr_width / PUP_SIZE + dram_info.ecc_ena; + + /* Get target 2T value */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + dram_info.mode_2t = (reg >> REG_DUNIT_CTRL_LOW_2T_OFFS) & + REG_DUNIT_CTRL_LOW_2T_MASK; + + /* Get target CL value */ +#ifdef MV88F67XX + reg = reg_read(REG_DDR3_MR0_ADDR) >> 2; +#else + reg = reg_read(REG_DDR3_MR0_CS_ADDR) >> 2; +#endif + + reg = (((reg >> 1) & 0xE) | (reg & 0x1)) & 0xF; + dram_info.cl = ddr3_valid_cl_to_cl(reg); + + /* Get target CWL value */ +#ifdef MV88F67XX + reg = reg_read(REG_DDR3_MR2_ADDR) >> REG_DDR3_MR2_CWL_OFFS; +#else + reg = reg_read(REG_DDR3_MR2_CS_ADDR) >> REG_DDR3_MR2_CWL_OFFS; +#endif + + reg &= REG_DDR3_MR2_CWL_MASK; + dram_info.cwl = reg; +#if !defined(MV88F67XX) + /* A370 has no PBS mechanism */ +#if defined(MV88F78X60) + if ((dram_info.target_frequency > DDR_400) && (ddr3_run_pbs)) + first_loop_flag = 1; +#else + /* first_loop_flag = 1; skip mid freq at ALP/A375 */ + if ((dram_info.target_frequency > DDR_400) && (ddr3_run_pbs) && + (mv_ctrl_revision_get() >= UMC_A0)) + first_loop_flag = 1; + else + first_loop_flag = 0; +#endif +#endif + + freq = dram_info.target_frequency; + + /* Set ODT to always on */ + ddr3_odt_activate(1); + + /* Init XOR */ + mv_sys_xor_init(&dram_info); + + /* Get DRAM/HCLK ratio */ + if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS)) + ratio_2to1 = 1; + + /* + * Xor Bypass - ECC support in AXP is currently available for 1:1 + * modes frequency modes. + * Not all frequency modes support the ddr3 training sequence + * (Only 1200/300). + * Xor Bypass allows using the Xor initializations and scrubbing + * inside the ddr3 training sequence without running the training + * itself. + */ + if (xor_bypass == 0) { + if (ddr3_run_pbs) { + DEBUG_MAIN_S("DDR3 Training Sequence - Run with PBS.\n"); + } else { + DEBUG_MAIN_S("DDR3 Training Sequence - Run without PBS.\n"); + } + + if (dram_info.target_frequency > DFS_MARGIN) { + tmp_ratio = 0; + freq = DDR_100; + + if (dram_info.reg_dimm == 1) + freq = DDR_300; + + if (MV_OK != ddr3_dfs_high_2_low(freq, &dram_info)) { + /* Set low - 100Mhz DDR Frequency by HW */ + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Dfs High2Low)\n"); + return MV_DDR3_TRAINING_ERR_DFS_H2L; + } + + if ((dram_info.reg_dimm == 1) && + (reg_dimm_skip_wl == 0)) { + if (MV_OK != + ddr3_write_leveling_hw_reg_dimm(freq, + &dram_info)) + DEBUG_MAIN_S("DDR3 Training Sequence - Registered DIMM Low WL - SKIP\n"); + } + + if (ddr3_get_log_level() >= MV_LOG_LEVEL_1) + ddr3_print_freq(freq); + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 2\n"); + } else { + if (!dqs_clk_aligned) { +#ifdef MV88F67XX + /* + * If running training sequence without DFS, + * we must run Write leveling before writing + * the patterns + */ + + /* + * ODT - Multi CS system use SW WL, + * Single CS System use HW WL + */ + if (dram_info.cs_ena > 1) { + if (MV_OK != + ddr3_write_leveling_sw( + freq, tmp_ratio, + &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Sw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_SW; + } + } else { + if (MV_OK != + ddr3_write_leveling_hw(freq, + &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } +#else + if (MV_OK != ddr3_write_leveling_hw( + freq, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hw)\n"); + if (ddr3_sw_wl_rl_debug) { + if (MV_OK != + ddr3_write_leveling_sw( + freq, tmp_ratio, + &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Sw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_SW; + } + } else { + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } +#endif + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 3\n"); + } + + if (MV_OK != ddr3_load_patterns(&dram_info, 0)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Loading Patterns)\n"); + return MV_DDR3_TRAINING_ERR_LOAD_PATTERNS; + } + + /* + * TODO: + * The mainline U-Boot port of the bin_hdr DDR training code + * needs a delay of minimum 20ms here (10ms is a bit too short + * and the CPU hangs). The bin_hdr code doesn't have this delay. + * To be save here, lets add a delay of 50ms here. + * + * Tested on the Marvell DB-MV784MP-GP board + */ + mdelay(50); + + do { + freq = dram_info.target_frequency; + tmp_ratio = ratio_2to1; + DEBUG_MAIN_FULL_S("DDR3 Training Sequence - DEBUG - 4\n"); + +#if defined(MV88F78X60) + /* + * There is a difference on the DFS frequency at the + * first iteration of this loop + */ + if (first_loop_flag) { + freq = DDR_400; + tmp_ratio = 0; + } +#endif + + if (MV_OK != ddr3_dfs_low_2_high(freq, tmp_ratio, + &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Dfs Low2High)\n"); + return MV_DDR3_TRAINING_ERR_DFS_H2L; + } + + if (ddr3_get_log_level() >= MV_LOG_LEVEL_1) { + ddr3_print_freq(freq); + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 5\n"); + + /* Write leveling */ + if (!dqs_clk_aligned) { +#ifdef MV88F67XX + /* + * ODT - Multi CS system that not support Multi + * CS MRS commands must use SW WL + */ + if (dram_info.cs_ena > 1) { + if (MV_OK != ddr3_write_leveling_sw( + freq, tmp_ratio, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Sw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_SW; + } + } else { + if (MV_OK != ddr3_write_leveling_hw( + freq, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } +#else + if ((dram_info.reg_dimm == 1) && + (freq == DDR_400)) { + if (reg_dimm_skip_wl == 0) { + if (MV_OK != ddr3_write_leveling_hw_reg_dimm( + freq, &dram_info)) + DEBUG_MAIN_S("DDR3 Training Sequence - Registered DIMM WL - SKIP\n"); + } + } else { + if (MV_OK != ddr3_write_leveling_hw( + freq, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hw)\n"); + if (ddr3_sw_wl_rl_debug) { + if (MV_OK != ddr3_write_leveling_sw( + freq, tmp_ratio, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Sw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_SW; + } + } else { + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } + } +#endif + if (debug_mode) + DEBUG_MAIN_S + ("DDR3 Training Sequence - DEBUG - 6\n"); + } + + /* Read Leveling */ + /* + * Armada 370 - Support for HCLK @ 400MHZ - must use + * SW read leveling + */ + if (freq == DDR_400 && dram_info.rl400_bug) { + status = ddr3_read_leveling_sw(freq, tmp_ratio, + &dram_info); + if (MV_OK != status) { + DEBUG_MAIN_S + ("DDR3 Training Sequence - FAILED (Read Leveling Sw)\n"); + return status; + } + } else { + if (MV_OK != ddr3_read_leveling_hw( + freq, &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Read Leveling Hw)\n"); + if (ddr3_sw_wl_rl_debug) { + if (MV_OK != ddr3_read_leveling_sw( + freq, tmp_ratio, + &dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Read Leveling Sw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_SW; + } + } else { + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 7\n"); + + if (MV_OK != ddr3_wl_supplement(&dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hi-Freq Sup)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_HI_FREQ; + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 8\n"); +#if !defined(MV88F67XX) + /* A370 has no PBS mechanism */ +#if defined(MV88F78X60) || defined(MV88F672X) + if (first_loop_flag == 1) { + first_loop_flag = 0; + + status = MV_OK; + status = ddr3_pbs_rx(&dram_info); + if (MV_OK != status) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (PBS RX)\n"); + return status; + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 9\n"); + + status = ddr3_pbs_tx(&dram_info); + if (MV_OK != status) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (PBS TX)\n"); + return status; + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 10\n"); + } +#endif +#endif + } while (freq != dram_info.target_frequency); + + status = ddr3_dqs_centralization_rx(&dram_info); + if (MV_OK != status) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (DQS Centralization RX)\n"); + return status; + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 11\n"); + + status = ddr3_dqs_centralization_tx(&dram_info); + if (MV_OK != status) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (DQS Centralization TX)\n"); + return status; + } + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 12\n"); + } + + ddr3_set_performance_params(&dram_info); + + if (dram_info.ecc_ena) { + /* Need to SCRUB the DRAM memory area to load U-boot */ + mv_sys_xor_finish(); + dram_info.num_cs = 1; + dram_info.cs_ena = 1; + mv_sys_xor_init(&dram_info); + mv_xor_mem_init(0, scrub_offs, scrub_size, 0xdeadbeef, + 0xdeadbeef); + + /* Wait for previous transfer completion */ + while (mv_xor_state_get(0) != MV_IDLE) + ; + + if (debug_mode) + DEBUG_MAIN_S("DDR3 Training Sequence - DEBUG - 13\n"); + } + + /* Return XOR State */ + mv_sys_xor_finish(); + +#if defined(MV88F78X60) + /* Save training results in memeory for resume state */ + ddr3_save_training(&dram_info); +#endif + /* Clear ODT always on */ + ddr3_odt_activate(0); + + /* Configure Dynamic read ODT */ + ddr3_odt_read_dynamic_config(&dram_info); + + return MV_OK; +} + +void ddr3_set_performance_params(MV_DRAM_INFO *dram_info) +{ + u32 twr2wr, trd2rd, trd2wr_wr2rd; + u32 tmp1, tmp2, reg; + + DEBUG_MAIN_FULL_C("Max WL Phase: ", dram_info->wl_max_phase, 2); + DEBUG_MAIN_FULL_C("Min WL Phase: ", dram_info->wl_min_phase, 2); + DEBUG_MAIN_FULL_C("Max RL Phase: ", dram_info->rl_max_phase, 2); + DEBUG_MAIN_FULL_C("Min RL Phase: ", dram_info->rl_min_phase, 2); + + if (dram_info->wl_max_phase < 2) + twr2wr = 0x2; + else + twr2wr = 0x3; + + trd2rd = 0x1 + (dram_info->rl_max_phase + 1) / 2 + + (dram_info->rl_max_phase + 1) % 2; + + tmp1 = (dram_info->rl_max_phase - dram_info->wl_min_phase) / 2 + + (((dram_info->rl_max_phase - dram_info->wl_min_phase) % 2) > + 0 ? 1 : 0); + tmp2 = (dram_info->wl_max_phase - dram_info->rl_min_phase) / 2 + + ((dram_info->wl_max_phase - dram_info->rl_min_phase) % 2 > + 0 ? 1 : 0); + trd2wr_wr2rd = (tmp1 >= tmp2) ? tmp1 : tmp2; + + trd2wr_wr2rd += 2; + trd2rd += 2; + twr2wr += 2; + + DEBUG_MAIN_FULL_C("WR 2 WR: ", twr2wr, 2); + DEBUG_MAIN_FULL_C("RD 2 RD: ", trd2rd, 2); + DEBUG_MAIN_FULL_C("RD 2 WR / WR 2 RD: ", trd2wr_wr2rd, 2); + + reg = reg_read(REG_SDRAM_TIMING_HIGH_ADDR); + + reg &= ~(REG_SDRAM_TIMING_H_W2W_MASK << REG_SDRAM_TIMING_H_W2W_OFFS); + reg |= ((twr2wr & REG_SDRAM_TIMING_H_W2W_MASK) << + REG_SDRAM_TIMING_H_W2W_OFFS); + + reg &= ~(REG_SDRAM_TIMING_H_R2R_MASK << REG_SDRAM_TIMING_H_R2R_OFFS); + reg &= ~(REG_SDRAM_TIMING_H_R2R_H_MASK << + REG_SDRAM_TIMING_H_R2R_H_OFFS); + reg |= ((trd2rd & REG_SDRAM_TIMING_H_R2R_MASK) << + REG_SDRAM_TIMING_H_R2R_OFFS); + reg |= (((trd2rd >> 2) & REG_SDRAM_TIMING_H_R2R_H_MASK) << + REG_SDRAM_TIMING_H_R2R_H_OFFS); + + reg &= ~(REG_SDRAM_TIMING_H_R2W_W2R_MASK << + REG_SDRAM_TIMING_H_R2W_W2R_OFFS); + reg &= ~(REG_SDRAM_TIMING_H_R2W_W2R_H_MASK << + REG_SDRAM_TIMING_H_R2W_W2R_H_OFFS); + reg |= ((trd2wr_wr2rd & REG_SDRAM_TIMING_H_R2W_W2R_MASK) << + REG_SDRAM_TIMING_H_R2W_W2R_OFFS); + reg |= (((trd2wr_wr2rd >> 2) & REG_SDRAM_TIMING_H_R2W_W2R_H_MASK) << + REG_SDRAM_TIMING_H_R2W_W2R_H_OFFS); + + reg_write(REG_SDRAM_TIMING_HIGH_ADDR, reg); +} + +/* + * Perform DDR3 PUP Indirect Write + */ +void ddr3_write_pup_reg(u32 mode, u32 cs, u32 pup, u32 phase, u32 delay) +{ + u32 reg = 0; + + if (pup == PUP_BC) + reg |= (1 << REG_PHY_BC_OFFS); + else + reg |= (pup << REG_PHY_PUP_OFFS); + + reg |= ((0x4 * cs + mode) << REG_PHY_CS_OFFS); + reg |= (phase << REG_PHY_PHASE_OFFS) | delay; + + if (mode == PUP_WL_MODE) + reg |= ((INIT_WL_DELAY + delay) << REG_PHY_DQS_REF_DLY_OFFS); + + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); /* Wait for '0' to mark the end of the transaction */ + + /* If read Leveling mode - need to write to register 3 separetly */ + if (mode == PUP_RL_MODE) { + reg = 0; + + if (pup == PUP_BC) + reg |= (1 << REG_PHY_BC_OFFS); + else + reg |= (pup << REG_PHY_PUP_OFFS); + + reg |= ((0x4 * cs + mode + 1) << REG_PHY_CS_OFFS); + reg |= (INIT_RL_DELAY); + + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); + } +} + +/* + * Perform DDR3 PUP Indirect Read + */ +u32 ddr3_read_pup_reg(u32 mode, u32 cs, u32 pup) +{ + u32 reg; + + reg = (pup << REG_PHY_PUP_OFFS) | + ((0x4 * cs + mode) << REG_PHY_CS_OFFS); + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + + reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_RD; + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); /* Wait for '0' to mark the end of the transaction */ + + return reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR); /* 0x16A0 */ +} + +/* + * Set training patterns + */ +int ddr3_load_patterns(MV_DRAM_INFO *dram_info, int resume) +{ + u32 reg; + + /* Enable SW override - Required for the ECC Pup */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + if (resume == 0) { +#if defined(MV88F78X60) || defined(MV88F672X) + ddr3_load_pbs_patterns(dram_info); +#endif + ddr3_load_dqs_patterns(dram_info); + } + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + /* Set Base Addr */ +#if defined(MV88F67XX) + reg_write(REG_DRAM_TRAINING_PATTERN_BASE_ADDR, 0); +#else + if (resume == 0) + reg_write(REG_DRAM_TRAINING_PATTERN_BASE_ADDR, 0); + else + reg_write(REG_DRAM_TRAINING_PATTERN_BASE_ADDR, + RESUME_RL_PATTERNS_ADDR); +#endif + + /* Set Patterns */ + if (resume == 0) { + reg = (dram_info->cs_ena << REG_DRAM_TRAINING_CS_OFFS) | + (1 << REG_DRAM_TRAINING_PATTERNS_OFFS); + } else { + reg = (0x1 << REG_DRAM_TRAINING_CS_OFFS) | + (1 << REG_DRAM_TRAINING_PATTERNS_OFFS); + } + + reg |= (1 << REG_DRAM_TRAINING_AUTO_OFFS); + + reg_write(REG_DRAM_TRAINING_ADDR, reg); + + udelay(100); + + /* Check if Successful */ + if (reg_read(REG_DRAM_TRAINING_ADDR) & + (1 << REG_DRAM_TRAINING_ERROR_OFFS)) + return MV_OK; + else + return MV_FAIL; +} + +#if !defined(MV88F67XX) +/* + * Name: ddr3_save_training(MV_DRAM_INFO *dram_info) + * Desc: saves the training results to memeory (RL,WL,PBS,Rx/Tx + * Centeralization) + * Args: MV_DRAM_INFO *dram_info + * Notes: + * Returns: None. + */ +void ddr3_save_training(MV_DRAM_INFO *dram_info) +{ + u32 val, pup, tmp_cs, cs, i, dq; + u32 crc = 0; + u32 regs = 0; + u32 *sdram_offset = (u32 *)RESUME_TRAINING_VALUES_ADDR; + u32 mode_config[MAX_TRAINING_MODE]; + + mode_config[DQS_WR_MODE] = PUP_DQS_WR; + mode_config[WL_MODE_] = PUP_WL_MODE; + mode_config[RL_MODE_] = PUP_RL_MODE; + mode_config[DQS_RD_MODE] = PUP_DQS_RD; + mode_config[PBS_TX_DM_MODE] = PUP_PBS_TX_DM; + mode_config[PBS_TX_MODE] = PUP_PBS_TX; + mode_config[PBS_RX_MODE] = PUP_PBS_RX; + + /* num of training modes */ + for (i = 0; i < MAX_TRAINING_MODE; i++) { + tmp_cs = dram_info->cs_ena; + /* num of CS */ + for (cs = 0; cs < MAX_CS; cs++) { + if (tmp_cs & (1 << cs)) { + /* num of PUPs */ + for (pup = 0; pup < dram_info->num_of_total_pups; + pup++) { + if (pup == dram_info->num_of_std_pups && + dram_info->ecc_ena) + pup = ECC_PUP; + if (i == PBS_TX_DM_MODE) { + /* + * Change CS bitmask because + * PBS works only with CS0 + */ + tmp_cs = 0x1; + val = ddr3_read_pup_reg( + mode_config[i], CS0, pup); + } else if (i == PBS_TX_MODE || + i == PBS_RX_MODE) { + /* + * Change CS bitmask because + * PBS works only with CS0 + */ + tmp_cs = 0x1; + for (dq = 0; dq <= DQ_NUM; + dq++) { + val = ddr3_read_pup_reg( + mode_config[i] + dq, + CS0, + pup); + (*sdram_offset) = val; + crc += *sdram_offset; + sdram_offset++; + regs++; + } + continue; + } else { + val = ddr3_read_pup_reg( + mode_config[i], cs, pup); + } + + *sdram_offset = val; + crc += *sdram_offset; + sdram_offset++; + regs++; + } + } + } + } + + *sdram_offset = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + crc += *sdram_offset; + sdram_offset++; + regs++; + *sdram_offset = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + crc += *sdram_offset; + sdram_offset++; + regs++; + sdram_offset = (u32 *)NUM_OF_REGISTER_ADDR; + *sdram_offset = regs; + DEBUG_SUSPEND_RESUME_S("Training Results CheckSum write= "); + DEBUG_SUSPEND_RESUME_D(crc, 8); + DEBUG_SUSPEND_RESUME_S("\n"); + sdram_offset = (u32 *)CHECKSUM_RESULT_ADDR; + *sdram_offset = crc; +} + +/* + * Name: ddr3_read_training_results() + * Desc: Reads the training results from memeory (RL,WL,PBS,Rx/Tx + * Centeralization) + * and writes them to the relevant registers + * Args: MV_DRAM_INFO *dram_info + * Notes: + * Returns: None. + */ +int ddr3_read_training_results(void) +{ + u32 val, reg, idx, dqs_wr_idx = 0, crc = 0; + u32 *sdram_offset = (u32 *)RESUME_TRAINING_VALUES_ADDR; + u32 training_val[RESUME_TRAINING_VALUES_MAX] = { 0 }; + u32 regs = *((u32 *)NUM_OF_REGISTER_ADDR); + + /* + * Read Training results & Dunit registers from memory and write + * it to an array + */ + for (idx = 0; idx < regs; idx++) { + training_val[idx] = *sdram_offset; + crc += *sdram_offset; + sdram_offset++; + } + + sdram_offset = (u32 *)CHECKSUM_RESULT_ADDR; + + if ((*sdram_offset) == crc) { + DEBUG_SUSPEND_RESUME_S("Training Results CheckSum read PASS= "); + DEBUG_SUSPEND_RESUME_D(crc, 8); + DEBUG_SUSPEND_RESUME_S("\n"); + } else { + DEBUG_MAIN_S("Wrong Training Results CheckSum\n"); + return MV_FAIL; + } + + /* + * We iterate through all the registers except for the last 2 since + * they are Dunit registers (and not PHY registers) + */ + for (idx = 0; idx < (regs - 2); idx++) { + val = training_val[idx]; + reg = (val >> REG_PHY_CS_OFFS) & 0x3F; /*read the phy address */ + + /* Check if the values belongs to the DQS WR */ + if (reg == PUP_WL_MODE) { + /* bit[5:0] in DQS_WR are delay */ + val = (training_val[dqs_wr_idx++] & 0x3F); + /* + * bit[15:10] are DQS_WR delay & bit[9:0] are + * WL phase & delay + */ + val = (val << REG_PHY_DQS_REF_DLY_OFFS) | + (training_val[idx] & 0x3C003FF); + /* Add Request pending and write operation bits */ + val |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + } else if (reg == PUP_DQS_WR) { + /* + * Do nothing since DQS_WR will be done in PUP_WL_MODE + */ + continue; + } + + val |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, val); + do { + val = (reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (val); /* Wait for '0' to mark the end of the transaction */ + } + + /* write last 2 Dunit configurations */ + val = training_val[idx]; + reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, val); /* reg 0x1538 */ + val = training_val[idx + 1]; + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, val); /* reg 0x153c */ + + return MV_OK; +} + +/* + * Name: ddr3_check_if_resume_mode() + * Desc: Reads the address (0x3000) of the Resume Magic word (0xDEADB002) + * Args: MV_DRAM_INFO *dram_info + * Notes: + * Returns: return (magic_word == SUSPEND_MAGIC_WORD) + */ +int ddr3_check_if_resume_mode(MV_DRAM_INFO *dram_info, u32 freq) +{ + u32 magic_word; + u32 *sdram_offset = (u32 *)BOOT_INFO_ADDR; + + if (dram_info->reg_dimm != 1) { + /* + * Perform write levleling in order initiate the phy with + * low frequency + */ + if (MV_OK != ddr3_write_leveling_hw(freq, dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Write Leveling Hw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + } + + if (MV_OK != ddr3_load_patterns(dram_info, 1)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Loading Patterns)\n"); + return MV_DDR3_TRAINING_ERR_LOAD_PATTERNS; + } + + /* Enable CS0 only for RL */ + dram_info->cs_ena = 0x1; + + /* Perform Read levleling in order to get stable memory */ + if (MV_OK != ddr3_read_leveling_hw(freq, dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Read Leveling Hw)\n"); + return MV_DDR3_TRAINING_ERR_WR_LVL_HW; + } + + /* Back to relevant CS */ + dram_info->cs_ena = ddr3_get_cs_ena_from_reg(); + + magic_word = *sdram_offset; + return magic_word == SUSPEND_MAGIC_WORD; +} + +/* + * Name: ddr3_training_suspend_resume() + * Desc: Execute the Resume state + * Args: MV_DRAM_INFO *dram_info + * Notes: + * Returns: return (magic_word == SUSPEND_MAGIC_WORD) + */ +int ddr3_training_suspend_resume(MV_DRAM_INFO *dram_info) +{ + u32 freq, reg; + int tmp_ratio; + + /* Configure DDR */ + if (MV_OK != ddr3_read_training_results()) + return MV_FAIL; + + /* Reset read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_ADDR); + + /* Start Auto Read Leveling procedure */ + reg |= (1 << REG_DRAM_TRAINING_RL_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS) + + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS)); + + /* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + udelay(2); + + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Clear Auto Read Leveling procedure */ + reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + /* Return to target frequency */ + freq = dram_info->target_frequency; + tmp_ratio = 1; + if (MV_OK != ddr3_dfs_low_2_high(freq, tmp_ratio, dram_info)) { + DEBUG_MAIN_S("DDR3 Training Sequence - FAILED (Dfs Low2High)\n"); + return MV_DDR3_TRAINING_ERR_DFS_H2L; + } + + if (dram_info->ecc_ena) { + /* Scabbling the RL area pattern and the training area */ + mv_sys_xor_finish(); + dram_info->num_cs = 1; + dram_info->cs_ena = 1; + mv_sys_xor_init(dram_info); + mv_xor_mem_init(0, RESUME_RL_PATTERNS_ADDR, + RESUME_RL_PATTERNS_SIZE, 0xFFFFFFFF, 0xFFFFFFFF); + + /* Wait for previous transfer completion */ + + while (mv_xor_state_get(0) != MV_IDLE) + ; + + /* Return XOR State */ + mv_sys_xor_finish(); + } + + return MV_OK; +} +#endif + +void ddr3_print_freq(u32 freq) +{ + u32 tmp_freq; + + switch (freq) { + case 0: + tmp_freq = 100; + break; + case 1: + tmp_freq = 300; + break; + case 2: + tmp_freq = 360; + break; + case 3: + tmp_freq = 400; + break; + case 4: + tmp_freq = 444; + break; + case 5: + tmp_freq = 500; + break; + case 6: + tmp_freq = 533; + break; + case 7: + tmp_freq = 600; + break; + case 8: + tmp_freq = 666; + break; + case 9: + tmp_freq = 720; + break; + case 10: + tmp_freq = 800; + break; + default: + tmp_freq = 100; + } + + printf("Current frequency is: %dMHz\n", tmp_freq); +} + +int ddr3_get_min_max_read_sample_delay(u32 cs_enable, u32 reg, u32 *min, + u32 *max, u32 *cs_max) +{ + u32 cs, delay; + + *min = 0xFFFFFFFF; + *max = 0x0; + + for (cs = 0; cs < MAX_CS; cs++) { + if ((cs_enable & (1 << cs)) == 0) + continue; + + delay = ((reg >> (cs * 8)) & 0x1F); + + if (delay < *min) + *min = delay; + + if (delay > *max) { + *max = delay; + *cs_max = cs; + } + } + + return MV_OK; +} + +int ddr3_get_min_max_rl_phase(MV_DRAM_INFO *dram_info, u32 *min, u32 *max, + u32 cs) +{ + u32 pup, reg, phase; + + *min = 0xFFFFFFFF; + *max = 0x0; + + for (pup = 0; pup < dram_info->num_of_total_pups; pup++) { + reg = ddr3_read_pup_reg(PUP_RL_MODE, cs, pup); + phase = ((reg >> 8) & 0x7); + + if (phase < *min) + *min = phase; + + if (phase > *max) + *max = phase; + } + + return MV_OK; +} + +int ddr3_odt_activate(int activate) +{ + u32 reg, mask; + + mask = (1 << REG_DUNIT_ODT_CTRL_OVRD_OFFS) | + (1 << REG_DUNIT_ODT_CTRL_OVRD_VAL_OFFS); + /* {0x0000149C} - DDR Dunit ODT Control Register */ + reg = reg_read(REG_DUNIT_ODT_CTRL_ADDR); + if (activate) + reg |= mask; + else + reg &= ~mask; + + reg_write(REG_DUNIT_ODT_CTRL_ADDR, reg); + + return MV_OK; +} + +int ddr3_odt_read_dynamic_config(MV_DRAM_INFO *dram_info) +{ + u32 min_read_sample_delay, max_read_sample_delay, max_rl_phase; + u32 min, max, cs_max; + u32 cs_ena, reg; + + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + cs_ena = ddr3_get_cs_ena_from_reg(); + + /* Get minimum and maximum of read sample delay of all CS */ + ddr3_get_min_max_read_sample_delay(cs_ena, reg, &min_read_sample_delay, + &max_read_sample_delay, &cs_max); + + /* + * Get minimum and maximum read leveling phase which belongs to the + * maximal read sample delay + */ + ddr3_get_min_max_rl_phase(dram_info, &min, &max, cs_max); + max_rl_phase = max; + + /* DDR ODT Timing (Low) Register calculation */ + reg = reg_read(REG_ODT_TIME_LOW_ADDR); + reg &= ~(0x1FF << REG_ODT_ON_CTL_RD_OFFS); + reg |= (((min_read_sample_delay - 1) & 0xF) << REG_ODT_ON_CTL_RD_OFFS); + reg |= (((max_read_sample_delay + 4 + (((max_rl_phase + 1) / 2) + 1)) & + 0x1F) << REG_ODT_OFF_CTL_RD_OFFS); + reg_write(REG_ODT_TIME_LOW_ADDR, reg); + + return MV_OK; +} diff --git a/drivers/ddr/mvebu/ddr3_hw_training.h b/drivers/ddr/mvebu/ddr3_hw_training.h new file mode 100644 index 0000000000..cffa7c4ff9 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_hw_training.h @@ -0,0 +1,392 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DDR3_TRAINING_H +#define __DDR3_TRAINING_H + +#include "ddr3_init.h" + +#ifdef MV88F78X60 +#include "ddr3_axp.h" +#elif defined(MV88F67XX) +#include "ddr3_a370.h" +#elif defined(MV88F672X) +#include "ddr3_a375.h" +#endif + +/* The following is a list of Marvell status */ +#define MV_ERROR (-1) +#define MV_OK (0x00) /* Operation succeeded */ +#define MV_FAIL (0x01) /* Operation failed */ +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */ +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */ +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */ +#define MV_BAD_PTR (0x05) /* Illegal pointer value */ +#define MV_BAD_SIZE (0x06) /* Illegal size */ +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */ +#define MV_SET_ERROR (0x08) /* Set operation failed */ +#define MV_GET_ERROR (0x09) /* Get operation failed */ +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */ +#define MV_NOT_FOUND (0x0B) /* Item not found */ +#define MV_NO_MORE (0x0C) /* No more items found */ +#define MV_NO_SUCH (0x0D) /* No such item */ +#define MV_TIMEOUT (0x0E) /* Time Out */ +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */ +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */ +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented*/ +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */ +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */ +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */ +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */ +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */ +#define MV_HW_ERROR (0x17) /* Hardware error */ +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */ +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */ +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */ +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */ +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */ +#define MV_NOT_STARTED (0x1D) /* Not started yet */ +#define MV_BUSY (0x1E) /* Item is busy. */ +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */ +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */ +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */ +#define MV_WRITE_PROTECT (0x22) /* Write protected */ + +#define MV_INVALID (int)(-1) + +/* + * Debug (Enable/Disable modules) and Error report + */ + +#ifdef BASIC_DEBUG +#define MV_DEBUG_WL +#define MV_DEBUG_RL +#define MV_DEBUG_DQS_RESULTS +#endif + +#ifdef FULL_DEBUG +#define MV_DEBUG_WL +#define MV_DEBUG_RL +#define MV_DEBUG_DQS + +#define MV_DEBUG_PBS +#define MV_DEBUG_DFS +#define MV_DEBUG_MAIN_FULL +#define MV_DEBUG_DFS_FULL +#define MV_DEBUG_DQS_FULL +#define MV_DEBUG_RL_FULL +#define MV_DEBUG_WL_FULL +#endif + +/* + * General Consts + */ + +#define SDRAM_READ_WRITE_LEN_IN_WORDS 16 +#define SDRAM_READ_WRITE_LEN_IN_DOUBLE_WORDS 8 +#define CACHE_LINE_SIZE 0x20 + +#define SDRAM_CS_BASE 0x0 + +#define SRAM_BASE 0x40000000 +#define SRAM_SIZE 0xFFF + +#define LEN_64BIT_STD_PATTERN 16 +#define LEN_64BIT_KILLER_PATTERN 128 +#define LEN_64BIT_SPECIAL_PATTERN 128 +#define LEN_64BIT_PBS_PATTERN 16 +#define LEN_WL_SUP_PATTERN 32 + +#define LEN_16BIT_STD_PATTERN 4 +#define LEN_16BIT_KILLER_PATTERN 128 +#define LEN_16BIT_SPECIAL_PATTERN 128 +#define LEN_16BIT_PBS_PATTERN 4 + +#define CMP_BYTE_SHIFT 8 +#define CMP_BYTE_MASK 0xFF +#define PUP_SIZE 8 + +#define S 0 +#define C 1 +#define P 2 +#define D 3 +#define DQS 6 +#define PS 2 +#define DS 3 +#define PE 4 +#define DE 5 + +#define CS0 0 +#define MAX_DIMM_NUM 2 +#define MAX_DELAY 0x1F + +/* + * Invertion limit and phase1 limit are WA for the RL @ 1:1 design bug - + * Armada 370 & AXP Z1 + */ +#define MAX_DELAY_INV_LIMIT 0x5 +#define MIN_DELAY_PHASE_1_LIMIT 0x10 + +#define MAX_DELAY_INV (0x3F - MAX_DELAY_INV_LIMIT) +#define MIN_DELAY 0 +#define MAX_PUP_NUM 9 +#define ECC_PUP 8 +#define DQ_NUM 8 +#define DQS_DQ_NUM 8 +#define INIT_WL_DELAY 13 +#define INIT_RL_DELAY 15 +#define TWLMRD_DELAY 20 +#define TCLK_3_DELAY 3 +#define ECC_BIT 8 +#define DMA_SIZE 64 +#define MV_DMA_0 0 +#define MAX_TRAINING_RETRY 10 + +#define PUP_RL_MODE 0x2 +#define PUP_WL_MODE 0 +#define PUP_PBS_TX 0x10 +#define PUP_PBS_TX_DM 0x1A +#define PUP_PBS_RX 0x30 +#define PUP_DQS_WR 0x1 +#define PUP_DQS_RD 0x3 +#define PUP_BC 10 +#define PUP_DELAY_MASK 0x1F +#define PUP_PHASE_MASK 0x7 +#define PUP_NUM_64BIT 8 +#define PUP_NUM_32BIT 4 +#define PUP_NUM_16BIT 2 + +/* control PHY registers */ +#define CNTRL_PUP_DESKEW 0x10 + +/* WL */ +#define COUNT_WL_HI_FREQ 2 +#define COUNT_WL 2 +#define COUNT_WL_RFRS 9 +#define WL_HI_FREQ_SHIFT 2 +#define WL_HI_FREQ_STATE 1 +#define COUNT_HW_WL 2 + +/* RL */ +/* + * RL_MODE - this define uses the RL mode SW RL instead of the functional + * window SW RL + */ +#define RL_MODE +#define RL_WINDOW_WA +#define MAX_PHASE_1TO1 2 +#define MAX_PHASE_2TO1 4 + +#define MAX_PHASE_RL_UL_1TO1 0 +#define MAX_PHASE_RL_L_1TO1 4 +#define MAX_PHASE_RL_UL_2TO1 3 +#define MAX_PHASE_RL_L_2TO1 7 + +#define RL_UNLOCK_STATE 0 +#define RL_WINDOW_STATE 1 +#define RL_FINAL_STATE 2 +#define RL_RETRY_COUNT 2 +#define COUNT_HW_RL 2 + +/* PBS */ +#define MAX_PBS 31 +#define MIN_PBS 0 +#define COUNT_PBS_PATTERN 2 +#define COUNT_PBS_STARTOVER 2 +#define COUNT_PBS_REPEAT 3 +#define COUNT_PBS_COMP_RETRY_NUM 2 +#define PBS_DIFF_LIMIT 31 +#define PATTERN_PBS_TX_A 0x55555555 +#define PATTERN_PBS_TX_B 0xAAAAAAAA + +/* DQS */ +#define ADLL_ERROR 0x55 +#define ADLL_MAX 31 +#define ADLL_MIN 0 +#define MIN_WIN_SIZE 4 +#define VALID_WIN_THRS MIN_WIN_SIZE + +#define MODE_2TO1 1 +#define MODE_1TO1 0 + +/* + * Macros + */ +#define IS_PUP_ACTIVE(_data_, _pup_) (((_data_) >> (_pup_)) & 0x1) + +/* + * Internal ERROR codes + */ +#define MV_DDR3_TRAINING_ERR_WR_LVL_HW 0xDD302001 +#define MV_DDR3_TRAINING_ERR_LOAD_PATTERNS 0xDD302002 +#define MV_DDR3_TRAINING_ERR_WR_LVL_HI_FREQ 0xDD302003 +#define MV_DDR3_TRAINING_ERR_DFS_H2L 0xDD302004 +#define MV_DDR3_TRAINING_ERR_DRAM_COMPARE 0xDD302005 +#define MV_DDR3_TRAINING_ERR_WIN_LIMITS 0xDD302006 +#define MV_DDR3_TRAINING_ERR_PUP_RANGE 0xDD302025 +#define MV_DDR3_TRAINING_ERR_DQS_LOW_LIMIT_SEARCH 0xDD302007 +#define MV_DDR3_TRAINING_ERR_DQS_HIGH_LIMIT_SEARCH 0xDD302008 +#define MV_DDR3_TRAINING_ERR_DQS_PATTERN 0xDD302009 +#define MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE 0xDD302010 +#define MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL 0xDD302011 +#define MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT 0xDD302012 +#define MV_DDR3_TRAINING_ERR_PBS_TX_PER_BIT 0xDD302013 +#define MV_DDR3_TRAINING_ERR_PBS_RX_MAX_VAL 0xDD302014 +#define MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP 0xDD302015 +#define MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_MAX_VAL 0xDD302016 +#define MV_DDR3_TRAINING_ERR_RD_LVL_RL_PATTERN 0xDD302017 +#define MV_DDR3_TRAINING_ERR_RD_LVL_RL_PUP_UNLOCK 0xDD302018 +#define MV_DDR3_TRAINING_ERR_RD_LVL_PUP_UNLOCK 0xDD302019 +#define MV_DDR3_TRAINING_ERR_WR_LVL_SW 0xDD302020 +#define MV_DDR3_TRAINING_ERR_PRBS_RX 0xDD302021 +#define MV_DDR3_TRAINING_ERR_DQS_RX 0xDD302022 +#define MV_DDR3_TRAINING_ERR_PRBS_TX 0xDD302023 +#define MV_DDR3_TRAINING_ERR_DQS_TX 0xDD302024 + +/* + * DRAM information structure + */ +typedef struct dram_info { + u32 num_cs; + u32 cs_ena; + u32 num_of_std_pups; /* Q value = ddrWidth/8 - Without ECC!! */ + u32 num_of_total_pups; /* numOfStdPups + eccEna */ + u32 target_frequency; /* DDR Frequency */ + u32 ddr_width; /* 32/64 Bit or 16/32 Bit */ + u32 ecc_ena; /* 0/1 */ + u32 wl_val[MAX_CS][MAX_PUP_NUM][7]; + u32 rl_val[MAX_CS][MAX_PUP_NUM][7]; + u32 rl_max_phase; + u32 rl_min_phase; + u32 wl_max_phase; + u32 wl_min_phase; + u32 rd_smpl_dly; + u32 rd_rdy_dly; + u32 cl; + u32 cwl; + u32 mode_2t; + int rl400_bug; + int multi_cs_mr_support; + int reg_dimm; +} MV_DRAM_INFO; + +enum training_modes { + DQS_WR_MODE, + WL_MODE_, + RL_MODE_, + DQS_RD_MODE, + PBS_TX_DM_MODE, + PBS_TX_MODE, + PBS_RX_MODE, + MAX_TRAINING_MODE, +}; + +typedef struct dram_training_init { + u32 reg_addr; + u32 reg_value; +} MV_DRAM_TRAINING_INIT; + +typedef struct dram_mv_init { + u32 reg_addr; + u32 reg_value; +} MV_DRAM_MC_INIT; + +/* Board/Soc revisions define */ +enum board_rev { + Z1, + Z1_PCAC, + Z1_RD_SLED, + A0, + A0_AMC +}; + +typedef struct dram_modes { + char *mode_name; + u8 cpu_freq; + u8 fab_freq; + u8 chip_id; + int chip_board_rev; + MV_DRAM_MC_INIT *regs; + MV_DRAM_TRAINING_INIT *vals; +} MV_DRAM_MODES; + +/* + * Function Declarations + */ + +u32 cache_inv(u32 addr); +void flush_l1_v7(u32 line); +void flush_l1_v6(u32 line); + +u32 ddr3_cl_to_valid_cl(u32 cl); +u32 ddr3_valid_cl_to_cl(u32 ui_valid_cl); + +void ddr3_write_pup_reg(u32 mode, u32 cs, u32 pup, u32 phase, u32 delay); +u32 ddr3_read_pup_reg(u32 mode, u32 cs, u32 pup); + +int ddr3_sdram_pbs_compare(MV_DRAM_INFO *dram_info, u32 pup_locked, int is_tx, + u32 pbs_pattern_idx, u32 pbs_curr_val, + u32 pbs_lock_val, u32 *skew_array, + u8 *unlock_pup_dq_array, u32 ecc); + +int ddr3_sdram_dqs_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 pattern_len, u32 sdram_offset, int write, + int mask, u32 *mask_pattern, int b_special_compare); + +int ddr3_sdram_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, u32 pattern_len, + u32 sdram_offset, int write, int mask, + u32 *mask_pattern, int b_special_compare); + +int ddr3_sdram_direct_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 pattern_len, u32 sdram_offset, int write, + int mask, u32 *mask_pattern); + +int ddr3_sdram_dm_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 sdram_offset); +int ddr3_dram_sram_read(u32 src, u32 dst, u32 len); +int ddr3_load_patterns(MV_DRAM_INFO *dram_info, int resume); + +int ddr3_read_leveling_hw(u32 freq, MV_DRAM_INFO *dram_info); +int ddr3_read_leveling_sw(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info); + +int ddr3_write_leveling_hw(u32 freq, MV_DRAM_INFO *dram_info); +int ddr3_write_leveling_sw(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info); +int ddr3_write_leveling_hw_reg_dimm(u32 freq, MV_DRAM_INFO *dram_info); +int ddr3_wl_supplement(MV_DRAM_INFO *dram_info); + +int ddr3_dfs_high_2_low(u32 freq, MV_DRAM_INFO *dram_info); +int ddr3_dfs_low_2_high(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info); + +int ddr3_pbs_tx(MV_DRAM_INFO *dram_info); +int ddr3_pbs_rx(MV_DRAM_INFO *dram_info); +int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info); + +int ddr3_dqs_centralization_rx(MV_DRAM_INFO *dram_info); +int ddr3_dqs_centralization_tx(MV_DRAM_INFO *dram_info); +int ddr3_load_dqs_patterns(MV_DRAM_INFO *dram_info); + +void ddr3_static_training_init(void); + +u8 ddr3_get_eprom_fabric(void); +void ddr3_set_performance_params(MV_DRAM_INFO *dram_info); +int ddr3_dram_sram_burst(u32 src, u32 dst, u32 len); +void ddr3_save_training(MV_DRAM_INFO *dram_info); +int ddr3_read_training_results(void); +int ddr3_training_suspend_resume(MV_DRAM_INFO *dram_info); +int ddr3_get_min_max_read_sample_delay(u32 cs_enable, u32 reg, u32 *min, + u32 *max, u32 *cs_max); +int ddr3_get_min_max_rl_phase(MV_DRAM_INFO *dram_info, u32 *min, u32 *max, + u32 cs); +int ddr3_odt_activate(int activate); +int ddr3_odt_read_dynamic_config(MV_DRAM_INFO *dram_info); +void ddr3_print_freq(u32 freq); +void ddr3_reset_phy_read_fifo(void); + +#endif /* __DDR3_TRAINING_H */ diff --git a/drivers/ddr/mvebu/ddr3_init.c b/drivers/ddr/mvebu/ddr3_init.c new file mode 100644 index 0000000000..11b85916b7 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_init.c @@ -0,0 +1,1219 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_init.h" + +#if defined(MV88F78X60) +#include "ddr3_axp_vars.h" +#elif defined(MV88F67XX) +#include "ddr3_a370_vars.h" +#elif defined(MV88F672X) +#include "ddr3_a375_vars.h" +#endif + +#ifdef STATIC_TRAINING +static void ddr3_static_training_init(void); +#endif +#ifdef DUNIT_STATIC +static void ddr3_static_mc_init(void); +#endif +#if defined(DUNIT_STATIC) || defined(STATIC_TRAINING) +MV_DRAM_MODES *ddr3_get_static_ddr_mode(void); +#endif +#if defined(MV88F672X) +void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps); +#endif +u32 mv_board_id_get(void); +extern void ddr3_set_sw_wl_rl_debug(u32); +extern void ddr3_set_pbs(u32); +extern void ddr3_set_log_level(u32 val); + +static u32 log_level = DDR3_LOG_LEVEL; + +static u32 ddr3_init_main(void); + +/* + * Name: ddr3_set_log_level + * Desc: This routine initialize the log_level acording to nLogLevel + * which getting from user + * Args: nLogLevel + * Notes: + * Returns: None. + */ +void ddr3_set_log_level(u32 val) +{ + log_level = val; +} + +/* + * Name: ddr3_get_log_level + * Desc: This routine returns the log level + * Args: none + * Notes: + * Returns: log level. + */ +u32 ddr3_get_log_level(void) +{ + return log_level; +} + +static void debug_print_reg(u32 reg) +{ + printf("0x%08x = 0x%08x\n", reg, reg_read(reg)); +} + +static void print_dunit_setup(void) +{ + puts("\n########### LOG LEVEL 1 (D-UNIT SETUP)###########\n"); + +#ifdef DUNIT_STATIC + puts("\nStatic D-UNIT Setup:\n"); +#endif +#ifdef DUNIT_SPD + puts("\nDynamic(using SPD) D-UNIT Setup:\n"); +#endif + debug_print_reg(REG_SDRAM_CONFIG_ADDR); + debug_print_reg(REG_DUNIT_CTRL_LOW_ADDR); + debug_print_reg(REG_SDRAM_TIMING_LOW_ADDR); + debug_print_reg(REG_SDRAM_TIMING_HIGH_ADDR); + debug_print_reg(REG_SDRAM_ADDRESS_CTRL_ADDR); + debug_print_reg(REG_SDRAM_OPEN_PAGES_ADDR); + debug_print_reg(REG_SDRAM_OPERATION_ADDR); + debug_print_reg(REG_SDRAM_MODE_ADDR); + debug_print_reg(REG_SDRAM_EXT_MODE_ADDR); + debug_print_reg(REG_DDR_CONT_HIGH_ADDR); + debug_print_reg(REG_ODT_TIME_LOW_ADDR); + debug_print_reg(REG_SDRAM_ERROR_ADDR); + debug_print_reg(REG_SDRAM_AUTO_PWR_SAVE_ADDR); + debug_print_reg(REG_OUDDR3_TIMING_ADDR); + debug_print_reg(REG_ODT_TIME_HIGH_ADDR); + debug_print_reg(REG_SDRAM_ODT_CTRL_LOW_ADDR); + debug_print_reg(REG_SDRAM_ODT_CTRL_HIGH_ADDR); + debug_print_reg(REG_DUNIT_ODT_CTRL_ADDR); +#ifndef MV88F67XX + debug_print_reg(REG_DRAM_FIFO_CTRL_ADDR); + debug_print_reg(REG_DRAM_AXI_CTRL_ADDR); + debug_print_reg(REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR); + debug_print_reg(REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR); + debug_print_reg(REG_DRAM_VER_CAL_MACHINE_CTRL_ADDR); + debug_print_reg(REG_DRAM_MAIN_PADS_CAL_ADDR); + debug_print_reg(REG_DRAM_HOR_CAL_MACHINE_CTRL_ADDR); + debug_print_reg(REG_CS_SIZE_SCRATCH_ADDR); + debug_print_reg(REG_DYNAMIC_POWER_SAVE_ADDR); + debug_print_reg(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + debug_print_reg(REG_READ_DATA_READY_DELAYS_ADDR); + debug_print_reg(REG_DDR3_MR0_ADDR); + debug_print_reg(REG_DDR3_MR1_ADDR); + debug_print_reg(REG_DDR3_MR2_ADDR); + debug_print_reg(REG_DDR3_MR3_ADDR); + debug_print_reg(REG_DDR3_RANK_CTRL_ADDR); + debug_print_reg(REG_DRAM_PHY_CONFIG_ADDR); + debug_print_reg(REG_STATIC_DRAM_DLB_CONTROL); + debug_print_reg(DLB_BUS_OPTIMIZATION_WEIGHTS_REG); + debug_print_reg(DLB_AGING_REGISTER); + debug_print_reg(DLB_EVICTION_CONTROL_REG); + debug_print_reg(DLB_EVICTION_TIMERS_REGISTER_REG); +#if defined(MV88F672X) + debug_print_reg(REG_FASTPATH_WIN_CTRL_ADDR(0)); + debug_print_reg(REG_FASTPATH_WIN_BASE_ADDR(0)); + debug_print_reg(REG_FASTPATH_WIN_CTRL_ADDR(1)); + debug_print_reg(REG_FASTPATH_WIN_BASE_ADDR(1)); +#else + debug_print_reg(REG_FASTPATH_WIN_0_CTRL_ADDR); +#endif + debug_print_reg(REG_CDI_CONFIG_ADDR); +#endif +} + +#if !defined(STATIC_TRAINING) +static void ddr3_restore_and_set_final_windows(u32 *win_backup) +{ + u32 ui, reg, cs; + u32 win_ctrl_reg, num_of_win_regs; + u32 cs_ena = ddr3_get_cs_ena_from_reg(); + +#if defined(MV88F672X) + if (DDR3_FAST_PATH_EN == 0) + return; +#endif + +#if defined(MV88F672X) + win_ctrl_reg = REG_XBAR_WIN_16_CTRL_ADDR; + num_of_win_regs = 8; +#else + win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR; + num_of_win_regs = 16; +#endif + + /* Return XBAR windows 4-7 or 16-19 init configuration */ + for (ui = 0; ui < num_of_win_regs; ui++) + reg_write((win_ctrl_reg + 0x4 * ui), win_backup[ui]); + + DEBUG_INIT_FULL_S("DDR3 Training Sequence - Switching XBAR Window to FastPath Window\n"); + +#if defined(MV88F672X) + /* Set L2 filtering to 1G */ + reg_write(0x8c04, 0x40000000); + + /* Open fast path windows */ + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + /* set fast path window control for the cs */ + reg = 0x1FFFFFE1; + reg |= (cs << 2); + reg |= (SDRAM_CS_SIZE & 0xFFFF0000); + /* Open fast path Window */ + reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg); + /* set fast path window base address for the cs */ + reg = (((SDRAM_CS_SIZE + 1) * cs) & 0xFFFF0000); + /* Set base address */ + reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg); + } + } +#else + reg = 0x1FFFFFE1; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg |= (cs << 2); + break; + } + } + + /* Open fast path Window to - 0.5G */ + reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, reg); +#endif +} + +static void ddr3_save_and_set_training_windows(u32 *win_backup) +{ + u32 cs_ena = ddr3_get_cs_ena_from_reg(); + u32 reg, tmp_count, cs, ui; + u32 win_ctrl_reg, win_base_reg, win_remap_reg; + u32 num_of_win_regs, win_jump_index; + +#if defined(MV88F672X) + /* Disable L2 filtering */ + reg_write(0x8c04, 0); + + win_ctrl_reg = REG_XBAR_WIN_16_CTRL_ADDR; + win_base_reg = REG_XBAR_WIN_16_BASE_ADDR; + win_remap_reg = REG_XBAR_WIN_16_REMAP_ADDR; + win_jump_index = 0x8; + num_of_win_regs = 8; +#else + win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR; + win_base_reg = REG_XBAR_WIN_4_BASE_ADDR; + win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR; + win_jump_index = 0x10; + num_of_win_regs = 16; +#endif + + /* Close XBAR Window 19 - Not needed */ + /* {0x000200e8} - Open Mbus Window - 2G */ + reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0); + + /* Save XBAR Windows 4-19 init configurations */ + for (ui = 0; ui < num_of_win_regs; ui++) + win_backup[ui] = reg_read(win_ctrl_reg + 0x4 * ui); + + /* Open XBAR Windows 4-7 or 16-19 for other CS */ + reg = 0; + tmp_count = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + switch (cs) { + case 0: + reg = 0x0E00; + break; + case 1: + reg = 0x0D00; + break; + case 2: + reg = 0x0B00; + break; + case 3: + reg = 0x0700; + break; + } + reg |= (1 << 0); + reg |= (SDRAM_CS_SIZE & 0xFFFF0000); + + reg_write(win_ctrl_reg + win_jump_index * tmp_count, + reg); + reg = ((SDRAM_CS_SIZE + 1) * (tmp_count)) & 0xFFFF0000; + reg_write(win_base_reg + win_jump_index * tmp_count, + reg); + + if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR) { + reg_write(win_remap_reg + + win_jump_index * tmp_count, 0); + } + + tmp_count++; + } + } +} +#endif /* !defined(STATIC_TRAINING) */ + +/* + * Name: ddr3_init - Main DDR3 Init function + * Desc: This routine initialize the DDR3 MC and runs HW training. + * Args: None. + * Notes: + * Returns: None. + */ +int ddr3_init(void) +{ + unsigned int status; + + ddr3_set_pbs(DDR3_PBS); + ddr3_set_sw_wl_rl_debug(DDR3_RUN_SW_WHEN_HW_FAIL); + + status = ddr3_init_main(); + if (status == MV_DDR3_TRAINING_ERR_BAD_SAR) + DEBUG_INIT_S("DDR3 Training Error: Bad sample at reset"); + if (status == MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP) + DEBUG_INIT_S("DDR3 Training Error: Bad DIMM setup"); + if (status == MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT) + DEBUG_INIT_S("DDR3 Training Error: Max CS limit"); + if (status == MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT) + DEBUG_INIT_S("DDR3 Training Error: Max enable CS limit"); + if (status == MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP) + DEBUG_INIT_S("DDR3 Training Error: Bad R-DIMM setup"); + if (status == MV_DDR3_TRAINING_ERR_TWSI_FAIL) + DEBUG_INIT_S("DDR3 Training Error: TWSI failure"); + if (status == MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH) + DEBUG_INIT_S("DDR3 Training Error: DIMM type no match"); + if (status == MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE) + DEBUG_INIT_S("DDR3 Training Error: TWSI bad type"); + if (status == MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH) + DEBUG_INIT_S("DDR3 Training Error: bus width no match"); + if (status > MV_DDR3_TRAINING_ERR_HW_FAIL_BASE) + DEBUG_INIT_C("DDR3 Training Error: HW Failure 0x", status, 8); + + return status; +} + +static void print_ddr_target_freq(u32 cpu_freq, u32 fab_opt) +{ + puts("\nDDR3 Training Sequence - Run DDR3 at "); + + switch (cpu_freq) { +#if defined(MV88F672X) + case 21: + puts("533 Mhz\n"); + break; +#else + case 1: + puts("533 Mhz\n"); + break; + case 2: + if (fab_opt == 5) + puts("600 Mhz\n"); + if (fab_opt == 9) + puts("400 Mhz\n"); + break; + case 3: + puts("667 Mhz\n"); + break; + case 4: + if (fab_opt == 5) + puts("750 Mhz\n"); + if (fab_opt == 9) + puts("500 Mhz\n"); + break; + case 0xa: + puts("400 Mhz\n"); + break; + case 0xb: + if (fab_opt == 5) + puts("800 Mhz\n"); + if (fab_opt == 9) + puts("553 Mhz\n"); + if (fab_opt == 0xA) + puts("640 Mhz\n"); + break; +#endif + default: + puts("NOT DEFINED FREQ\n"); + } +} + +static u32 ddr3_init_main(void) +{ + u32 target_freq; + u32 reg = 0; + u32 cpu_freq, fab_opt, hclk_time_ps, soc_num; + __maybe_unused u32 ecc = DRAM_ECC; + __maybe_unused int dqs_clk_aligned = 0; + __maybe_unused u32 scrub_offs, scrub_size; + __maybe_unused u32 ddr_width = BUS_WIDTH; + __maybe_unused int status; + __maybe_unused u32 win_backup[16]; + + /* SoC/Board special Initializtions */ + fab_opt = ddr3_get_fab_opt(); + +#ifdef CONFIG_SPD_EEPROM + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif + + ddr3_print_version(); + DEBUG_INIT_S("4\n"); + /* Lib version 5.5.4 */ + + fab_opt = ddr3_get_fab_opt(); + + /* Switching CPU to MRVL ID */ + soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >> + SAR1_CPU_CORE_OFFSET; + switch (soc_num) { + case 0x3: + reg_bit_set(CPU_CONFIGURATION_REG(3), CPU_MRVL_ID_OFFSET); + reg_bit_set(CPU_CONFIGURATION_REG(2), CPU_MRVL_ID_OFFSET); + case 0x1: + reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET); + case 0x0: + reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET); + default: + break; + } + + /* Power down deskew PLL */ +#if !defined(MV88F672X) + /* 0x18780 [25] */ + reg = (reg_read(REG_DDRPHY_APLL_CTRL_ADDR) & ~(1 << 25)); + reg_write(REG_DDRPHY_APLL_CTRL_ADDR, reg); +#endif + + /* + * Stage 0 - Set board configuration + */ + cpu_freq = ddr3_get_cpu_freq(); + if (fab_opt > FAB_OPT) + fab_opt = FAB_OPT - 1; + + if (ddr3_get_log_level() > 0) + print_ddr_target_freq(cpu_freq, fab_opt); + +#if defined(MV88F672X) + get_target_freq(cpu_freq, &target_freq, &hclk_time_ps); +#else + target_freq = cpu_ddr_ratios[fab_opt][cpu_freq]; + hclk_time_ps = cpu_fab_clk_to_hclk[fab_opt][cpu_freq]; +#endif + if ((target_freq == 0) || (hclk_time_ps == 0)) { + DEBUG_INIT_S("DDR3 Training Sequence - FAILED - Wrong Sample at Reset Configurations\n"); + if (target_freq == 0) { + DEBUG_INIT_C("target_freq", target_freq, 2); + DEBUG_INIT_C("fab_opt", fab_opt, 2); + DEBUG_INIT_C("cpu_freq", cpu_freq, 2); + } else if (hclk_time_ps == 0) { + DEBUG_INIT_C("hclk_time_ps", hclk_time_ps, 2); + DEBUG_INIT_C("fab_opt", fab_opt, 2); + DEBUG_INIT_C("cpu_freq", cpu_freq, 2); + } + + return MV_DDR3_TRAINING_ERR_BAD_SAR; + } + +#if defined(ECC_SUPPORT) + scrub_offs = U_BOOT_START_ADDR; + scrub_size = U_BOOT_SCRUB_SIZE; +#else + scrub_offs = 0; + scrub_size = 0; +#endif + +#if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) + ecc = DRAM_ECC; +#endif + +#if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) + ecc = 0; + if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_ECC)) + ecc = 1; +#endif + +#ifdef DQS_CLK_ALIGNED + dqs_clk_aligned = 1; +#endif + + /* Check if DRAM is already initialized */ + if (reg_read(REG_BOOTROM_ROUTINE_ADDR) & + (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { + DEBUG_INIT_S("DDR3 Training Sequence - 2nd boot - Skip\n"); + return MV_OK; + } + + /* + * Stage 1 - Dunit Setup + */ + +#ifdef DUNIT_STATIC + /* + * For Static D-Unit Setup use must set the correct static values + * at the ddr3_*soc*_vars.h file + */ + DEBUG_INIT_FULL_S("DDR3 Training Sequence - Static MC Init\n"); + ddr3_static_mc_init(); + +#ifdef ECC_SUPPORT + ecc = DRAM_ECC; + if (ecc) { + reg = reg_read(REG_SDRAM_CONFIG_ADDR); + reg |= (1 << REG_SDRAM_CONFIG_ECC_OFFS); + reg_write(REG_SDRAM_CONFIG_ADDR, reg); + } +#endif +#endif + +#if defined(MV88F78X60) || defined(MV88F672X) +#if defined(AUTO_DETECTION_SUPPORT) + /* + * Configurations for both static and dynamic MC setups + * + * Dynamically Set 32Bit and ECC for AXP (Relevant only for + * Marvell DB boards) + */ + if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_BUS_WIDTH)) { + ddr_width = 32; + DEBUG_INIT_S("DDR3 Training Sequence - DRAM bus width 32Bit\n"); + } +#endif + +#if defined(MV88F672X) + reg = reg_read(REG_SDRAM_CONFIG_ADDR); + if ((reg >> 15) & 1) + ddr_width = 32; + else + ddr_width = 16; +#endif +#endif + +#ifdef DUNIT_SPD + status = ddr3_dunit_setup(ecc, hclk_time_ps, &ddr_width); + if (MV_OK != status) { + DEBUG_INIT_S("DDR3 Training Sequence - FAILED (ddr3 Dunit Setup)\n"); + return status; + } +#endif + + /* Fix read ready phases for all SOC in reg 0x15C8 */ + reg = reg_read(REG_TRAINING_DEBUG_3_ADDR); + reg &= ~(REG_TRAINING_DEBUG_3_MASK); + reg |= 0x4; /* Phase 0 */ + reg &= ~(REG_TRAINING_DEBUG_3_MASK << REG_TRAINING_DEBUG_3_OFFS); + reg |= (0x4 << (1 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 1 */ + reg &= ~(REG_TRAINING_DEBUG_3_MASK << (3 * REG_TRAINING_DEBUG_3_OFFS)); + reg |= (0x6 << (3 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 3 */ + reg &= ~(REG_TRAINING_DEBUG_3_MASK << (4 * REG_TRAINING_DEBUG_3_OFFS)); + reg |= (0x6 << (4 * REG_TRAINING_DEBUG_3_OFFS)); + reg &= ~(REG_TRAINING_DEBUG_3_MASK << (5 * REG_TRAINING_DEBUG_3_OFFS)); + reg |= (0x6 << (5 * REG_TRAINING_DEBUG_3_OFFS)); + reg_write(REG_TRAINING_DEBUG_3_ADDR, reg); + +#if defined(MV88F672X) + /* + * AxiBrespMode[8] = Compliant, + * AxiAddrDecodeCntrl[11] = Internal, + * AxiDataBusWidth[0] = 128bit + */ + /* 0x14A8 - AXI Control Register */ + reg_write(REG_DRAM_AXI_CTRL_ADDR, 0); +#else + /* 0x14A8 - AXI Control Register */ + reg_write(REG_DRAM_AXI_CTRL_ADDR, 0x00000100); + reg_write(REG_CDI_CONFIG_ADDR, 0x00000006); + + if ((ddr_width == 64) && (reg_read(REG_DDR_IO_ADDR) & + (1 << REG_DDR_IO_CLK_RATIO_OFFS))) { + /* 0x14A8 - AXI Control Register */ + reg_write(REG_DRAM_AXI_CTRL_ADDR, 0x00000101); + reg_write(REG_CDI_CONFIG_ADDR, 0x00000007); + } +#endif + +#if !defined(MV88F67XX) + /* + * ARMADA-370 activate DLB later at the u-boot, + * Armada38x - No DLB activation at this time + */ + reg_write(DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x18C01E); + +#if defined(MV88F78X60) + /* WA according to eratta GL-8672902*/ + if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) + reg_write(DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0xc19e); +#endif + + reg_write(DLB_AGING_REGISTER, 0x0f7f007f); + reg_write(DLB_EVICTION_CONTROL_REG, 0x0); + reg_write(DLB_EVICTION_TIMERS_REGISTER_REG, 0x00FF3C1F); + + reg_write(MBUS_UNITS_PRIORITY_CONTROL_REG, 0x55555555); + reg_write(FABRIC_UNITS_PRIORITY_CONTROL_REG, 0xAA); + reg_write(MBUS_UNITS_PREFETCH_CONTROL_REG, 0xffff); + reg_write(FABRIC_UNITS_PREFETCH_CONTROL_REG, 0xf0f); + +#if defined(MV88F78X60) + /* WA according to eratta GL-8672902 */ + if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) { + reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL); + reg |= DLB_ENABLE; + reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg); + } +#endif /* end defined(MV88F78X60) */ +#endif /* end !defined(MV88F67XX) */ + + if (ddr3_get_log_level() >= MV_LOG_LEVEL_1) + print_dunit_setup(); + + /* + * Stage 2 - Training Values Setup + */ +#ifdef STATIC_TRAINING + /* + * DRAM Init - After all the D-unit values are set, its time to init + * the D-unit + */ + /* Wait for '0' */ + reg_write(REG_SDRAM_INIT_CTRL_ADDR, 0x1); + do { + reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) & + (1 << REG_SDRAM_INIT_CTRL_OFFS); + } while (reg); + + /* ddr3 init using static parameters - HW training is disabled */ + DEBUG_INIT_FULL_S("DDR3 Training Sequence - Static Training Parameters\n"); + ddr3_static_training_init(); + +#if defined(MV88F78X60) + /* + * If ECC is enabled, need to scrub the U-Boot area memory region - + * Run training function with Xor bypass just to scrub the memory + */ + status = ddr3_hw_training(target_freq, ddr_width, + 1, scrub_offs, scrub_size, + dqs_clk_aligned, DDR3_TRAINING_DEBUG, + REG_DIMM_SKIP_WL); + if (MV_OK != status) { + DEBUG_INIT_FULL_S("DDR3 Training Sequence - FAILED\n"); + return status; + } +#endif +#else + /* Set X-BAR windows for the training sequence */ + ddr3_save_and_set_training_windows(win_backup); + + /* Run DDR3 Training Sequence */ + /* DRAM Init */ + reg_write(REG_SDRAM_INIT_CTRL_ADDR, 0x1); + do { + reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) & + (1 << REG_SDRAM_INIT_CTRL_OFFS); + } while (reg); /* Wait for '0' */ + + /* ddr3 init using DDR3 HW training procedure */ + DEBUG_INIT_FULL_S("DDR3 Training Sequence - HW Training Procedure\n"); + status = ddr3_hw_training(target_freq, ddr_width, + 0, scrub_offs, scrub_size, + dqs_clk_aligned, DDR3_TRAINING_DEBUG, + REG_DIMM_SKIP_WL); + if (MV_OK != status) { + DEBUG_INIT_FULL_S("DDR3 Training Sequence - FAILED\n"); + return status; + } +#endif + + /* + * Stage 3 - Finish + */ +#if defined(MV88F78X60) || defined(MV88F672X) + /* Disable ECC Ignore bit */ + reg = reg_read(REG_SDRAM_CONFIG_ADDR) & + ~(1 << REG_SDRAM_CONFIG_IERR_OFFS); + reg_write(REG_SDRAM_CONFIG_ADDR, reg); +#endif + +#if !defined(STATIC_TRAINING) + /* Restore and set windows */ + ddr3_restore_and_set_final_windows(win_backup); +#endif + + /* Update DRAM init indication in bootROM register */ + reg = reg_read(REG_BOOTROM_ROUTINE_ADDR); + reg_write(REG_BOOTROM_ROUTINE_ADDR, + reg | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)); + +#if !defined(MV88F67XX) +#if defined(MV88F78X60) + if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) { + reg = reg_read(REG_SDRAM_CONFIG_ADDR); + if (ecc == 0) + reg_write(REG_SDRAM_CONFIG_ADDR, reg | (1 << 19)); + } +#endif /* end defined(MV88F78X60) */ + + reg_write(DLB_EVICTION_CONTROL_REG, 0x9); + + reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL); + reg |= (DLB_ENABLE | DLB_WRITE_COALESING | DLB_AXI_PREFETCH_EN | + DLB_MBUS_PREFETCH_EN | PREFETCH_NLNSZTR); + reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg); +#endif /* end !defined(MV88F67XX) */ + +#ifdef STATIC_TRAINING + DEBUG_INIT_S("DDR3 Training Sequence - Ended Successfully (S)\n"); +#else + DEBUG_INIT_S("DDR3 Training Sequence - Ended Successfully\n"); +#endif + + return MV_OK; +} + +/* + * Name: ddr3_get_cpu_freq + * Desc: read S@R and return CPU frequency + * Args: + * Notes: + * Returns: required value + */ + +u32 ddr3_get_cpu_freq(void) +{ + u32 reg, cpu_freq; + +#if defined(MV88F672X) + /* Read sample at reset setting */ + reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR); /* 0xE8200 */ + cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >> + REG_SAMPLE_RESET_CPU_FREQ_OFFS; +#else + /* Read sample at reset setting */ + reg = reg_read(REG_SAMPLE_RESET_LOW_ADDR); /* 0x18230 [23:21] */ +#if defined(MV88F78X60) + cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >> + REG_SAMPLE_RESET_CPU_FREQ_OFFS; + reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR); /* 0x18234 [20] */ + cpu_freq |= (((reg >> REG_SAMPLE_RESET_HIGH_CPU_FREQ_OFFS) & 0x1) << 3); +#elif defined(MV88F67XX) + cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >> + REG_SAMPLE_RESET_CPU_FREQ_OFFS; +#endif +#endif + + return cpu_freq; +} + +/* + * Name: ddr3_get_fab_opt + * Desc: read S@R and return CPU frequency + * Args: + * Notes: + * Returns: required value + */ +u32 ddr3_get_fab_opt(void) +{ + __maybe_unused u32 reg, fab_opt; + +#if defined(MV88F672X) + return 0; /* No fabric */ +#else + /* Read sample at reset setting */ + reg = reg_read(REG_SAMPLE_RESET_LOW_ADDR); + fab_opt = (reg & REG_SAMPLE_RESET_FAB_MASK) >> + REG_SAMPLE_RESET_FAB_OFFS; + +#if defined(MV88F78X60) + reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR); + fab_opt |= (((reg >> 19) & 0x1) << 4); +#endif + + return fab_opt; +#endif +} + +/* + * Name: ddr3_get_vco_freq + * Desc: read S@R and return VCO frequency + * Args: + * Notes: + * Returns: required value + */ +u32 ddr3_get_vco_freq(void) +{ + u32 fab, cpu_freq, ui_vco_freq; + + fab = ddr3_get_fab_opt(); + cpu_freq = ddr3_get_cpu_freq(); + + if (fab == 2 || fab == 3 || fab == 7 || fab == 8 || fab == 10 || + fab == 15 || fab == 17 || fab == 20) + ui_vco_freq = cpu_freq + CLK_CPU; + else + ui_vco_freq = cpu_freq; + + return ui_vco_freq; +} + +#ifdef STATIC_TRAINING +/* + * Name: ddr3_static_training_init - Init DDR3 Training with + * static parameters + * Desc: Use this routine to init the controller without the HW training + * procedure + * User must provide compatible header file with registers data. + * Args: None. + * Notes: + * Returns: None. + */ +void ddr3_static_training_init(void) +{ + MV_DRAM_MODES *ddr_mode; + u32 reg; + int j; + + ddr_mode = ddr3_get_static_ddr_mode(); + + j = 0; + while (ddr_mode->vals[j].reg_addr != 0) { + udelay(10); /* haim want to delay each write */ + reg_write(ddr_mode->vals[j].reg_addr, + ddr_mode->vals[j].reg_value); + + if (ddr_mode->vals[j].reg_addr == + REG_PHY_REGISTRY_FILE_ACCESS_ADDR) + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); + j++; + } +} +#endif + +/* + * Name: ddr3_get_static_mc_value - Init Memory controller with static + * parameters + * Desc: Use this routine to init the controller without the HW training + * procedure + * User must provide compatible header file with registers data. + * Args: None. + * Notes: + * Returns: None. + */ +u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1, u32 offset2, + u32 mask2) +{ + u32 reg, tmp; + + reg = reg_read(reg_addr); + + tmp = (reg >> offset1) & mask1; + if (mask2) + tmp |= (reg >> offset2) & mask2; + + return tmp; +} + +/* + * Name: ddr3_get_static_ddr_mode - Init Memory controller with static + * parameters + * Desc: Use this routine to init the controller without the HW training + * procedure + * User must provide compatible header file with registers data. + * Args: None. + * Notes: + * Returns: None. + */ +__weak MV_DRAM_MODES *ddr3_get_static_ddr_mode(void) +{ + u32 chip_board_rev, i; + u32 size; + + /* Do not modify this code. relevant only for marvell Boards */ +#if defined(DB_78X60_PCAC) + chip_board_rev = Z1_PCAC; +#elif defined(DB_78X60_AMC) + chip_board_rev = A0_AMC; +#elif defined(DB_88F6710_PCAC) + chip_board_rev = A0_PCAC; +#elif defined(RD_88F6710) + chip_board_rev = A0_RD; +#elif defined(MV88F672X) + chip_board_rev = mv_board_id_get(); +#else + chip_board_rev = A0; +#endif + + size = sizeof(ddr_modes) / sizeof(MV_DRAM_MODES); + for (i = 0; i < size; i++) { + if ((ddr3_get_cpu_freq() == ddr_modes[i].cpu_freq) && + (ddr3_get_fab_opt() == ddr_modes[i].fab_freq) && + (chip_board_rev == ddr_modes[i].chip_board_rev)) + return &ddr_modes[i]; + } + + return &ddr_modes[0]; +} + +#ifdef DUNIT_STATIC +/* + * Name: ddr3_static_mc_init - Init Memory controller with static parameters + * Desc: Use this routine to init the controller without the HW training + * procedure + * User must provide compatible header file with registers data. + * Args: None. + * Notes: + * Returns: None. + */ +void ddr3_static_mc_init(void) +{ + MV_DRAM_MODES *ddr_mode; + u32 reg; + int j; + + ddr_mode = ddr3_get_static_ddr_mode(); + j = 0; + while (ddr_mode->regs[j].reg_addr != 0) { + reg_write(ddr_mode->regs[j].reg_addr, + ddr_mode->regs[j].reg_value); + if (ddr_mode->regs[j].reg_addr == + REG_PHY_REGISTRY_FILE_ACCESS_ADDR) + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); + j++; + } +} +#endif + +/* + * Name: ddr3_check_config - Check user configurations: ECC/MultiCS + * Desc: + * Args: twsi Address + * Notes: Only Available for ArmadaXP/Armada 370 DB boards + * Returns: None. + */ +int ddr3_check_config(u32 twsi_addr, MV_CONFIG_TYPE config_type) +{ +#ifdef AUTO_DETECTION_SUPPORT + u8 data = 0; + int ret; + int offset; + + if ((config_type == CONFIG_ECC) || (config_type == CONFIG_BUS_WIDTH)) + offset = 1; + else + offset = 0; + + ret = i2c_read(twsi_addr, offset, 1, (u8 *)&data, 1); + if (!ret) { + switch (config_type) { + case CONFIG_ECC: + if (data & 0x2) + return 1; + break; + case CONFIG_BUS_WIDTH: + if (data & 0x1) + return 1; + break; +#ifdef DB_88F6710 + case CONFIG_MULTI_CS: + if (CFG_MULTI_CS_MODE(data)) + return 1; + break; +#else + case CONFIG_MULTI_CS: + break; +#endif + } + } +#endif + + return 0; +} + +#if defined(DB_88F78X60_REV2) +/* + * Name: ddr3_get_eprom_fabric - Get Fabric configuration from EPROM + * Desc: + * Args: twsi Address + * Notes: Only Available for ArmadaXP DB Rev2 boards + * Returns: None. + */ +u8 ddr3_get_eprom_fabric(void) +{ +#ifdef AUTO_DETECTION_SUPPORT + u8 data = 0; + int ret; + + ret = i2c_read(NEW_FABRIC_TWSI_ADDR, 1, 1, (u8 *)&data, 1); + if (!ret) + return data & 0x1F; +#endif + + return 0; +} + +#endif + +/* + * Name: ddr3_cl_to_valid_cl - this return register matching CL value + * Desc: + * Args: clValue - the value + + * Notes: + * Returns: required CL value + */ +u32 ddr3_cl_to_valid_cl(u32 cl) +{ + switch (cl) { + case 5: + return 2; + break; + case 6: + return 4; + break; + case 7: + return 6; + break; + case 8: + return 8; + break; + case 9: + return 10; + break; + case 10: + return 12; + break; + case 11: + return 14; + break; + case 12: + return 1; + break; + case 13: + return 3; + break; + case 14: + return 5; + break; + default: + return 2; + } +} + +/* + * Name: ddr3_cl_to_valid_cl - this return register matching CL value + * Desc: + * Args: clValue - the value + * Notes: + * Returns: required CL value + */ +u32 ddr3_valid_cl_to_cl(u32 ui_valid_cl) +{ + switch (ui_valid_cl) { + case 1: + return 12; + break; + case 2: + return 5; + break; + case 3: + return 13; + break; + case 4: + return 6; + break; + case 5: + return 14; + break; + case 6: + return 7; + break; + case 8: + return 8; + break; + case 10: + return 9; + break; + case 12: + return 10; + break; + case 14: + return 11; + break; + default: + return 0; + } +} + +/* + * Name: ddr3_get_cs_num_from_reg + * Desc: + * Args: + * Notes: + * Returns: + */ +u32 ddr3_get_cs_num_from_reg(void) +{ + u32 cs_ena = ddr3_get_cs_ena_from_reg(); + u32 cs_count = 0; + u32 cs; + + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) + cs_count++; + } + + return cs_count; +} + +/* + * Name: ddr3_get_cs_ena_from_reg + * Desc: + * Args: + * Notes: + * Returns: + */ +u32 ddr3_get_cs_ena_from_reg(void) +{ + return reg_read(REG_DDR3_RANK_CTRL_ADDR) & + REG_DDR3_RANK_CTRL_CS_ENA_MASK; +} + +/* + * mv_ctrl_rev_get - Get Marvell controller device revision number + * + * DESCRIPTION: + * This function returns 8bit describing the device revision as defined + * in PCI Express Class Code and Revision ID Register. + * + * INPUT: + * None. + * + * OUTPUT: + * None. + * + * RETURN: + * 8bit desscribing Marvell controller revision number + * + */ +#if !defined(MV88F672X) +u8 mv_ctrl_rev_get(void) +{ + u8 rev_num; + +#if defined(MV_INCLUDE_CLK_PWR_CNTRL) + /* Check pex power state */ + u32 pex_power; + pex_power = mv_ctrl_pwr_clck_get(PEX_UNIT_ID, 0); + if (pex_power == 0) + mv_ctrl_pwr_clck_set(PEX_UNIT_ID, 0, 1); +#endif + rev_num = (u8)reg_read(PEX_CFG_DIRECT_ACCESS(0, + PCI_CLASS_CODE_AND_REVISION_ID)); + +#if defined(MV_INCLUDE_CLK_PWR_CNTRL) + /* Return to power off state */ + if (pex_power == 0) + mv_ctrl_pwr_clck_set(PEX_UNIT_ID, 0, 0); +#endif + + return (rev_num & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS; +} + +#endif + +#if defined(MV88F672X) +void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps) +{ + u32 tmp, hclk; + + switch (freq_mode) { + case CPU_333MHz_DDR_167MHz_L2_167MHz: + hclk = 84; + tmp = DDR_100; + break; + case CPU_266MHz_DDR_266MHz_L2_133MHz: + case CPU_333MHz_DDR_222MHz_L2_167MHz: + case CPU_400MHz_DDR_200MHz_L2_200MHz: + case CPU_400MHz_DDR_267MHz_L2_200MHz: + case CPU_533MHz_DDR_267MHz_L2_267MHz: + case CPU_500MHz_DDR_250MHz_L2_250MHz: + case CPU_600MHz_DDR_300MHz_L2_300MHz: + case CPU_800MHz_DDR_267MHz_L2_400MHz: + case CPU_900MHz_DDR_300MHz_L2_450MHz: + tmp = DDR_300; + hclk = 150; + break; + case CPU_333MHz_DDR_333MHz_L2_167MHz: + case CPU_500MHz_DDR_334MHz_L2_250MHz: + case CPU_666MHz_DDR_333MHz_L2_333MHz: + tmp = DDR_333; + hclk = 165; + break; + case CPU_533MHz_DDR_356MHz_L2_267MHz: + tmp = DDR_360; + hclk = 180; + break; + case CPU_400MHz_DDR_400MHz_L2_200MHz: + case CPU_600MHz_DDR_400MHz_L2_300MHz: + case CPU_800MHz_DDR_400MHz_L2_400MHz: + case CPU_400MHz_DDR_400MHz_L2_400MHz: + tmp = DDR_400; + hclk = 200; + break; + case CPU_666MHz_DDR_444MHz_L2_333MHz: + case CPU_900MHz_DDR_450MHz_L2_450MHz: + tmp = DDR_444; + hclk = 222; + break; + case CPU_500MHz_DDR_500MHz_L2_250MHz: + case CPU_1000MHz_DDR_500MHz_L2_500MHz: + case CPU_1000MHz_DDR_500MHz_L2_333MHz: + tmp = DDR_500; + hclk = 250; + break; + case CPU_533MHz_DDR_533MHz_L2_267MHz: + case CPU_800MHz_DDR_534MHz_L2_400MHz: + case CPU_1100MHz_DDR_550MHz_L2_550MHz: + tmp = DDR_533; + hclk = 267; + break; + case CPU_600MHz_DDR_600MHz_L2_300MHz: + case CPU_900MHz_DDR_600MHz_L2_450MHz: + case CPU_1200MHz_DDR_600MHz_L2_600MHz: + tmp = DDR_600; + hclk = 300; + break; + case CPU_666MHz_DDR_666MHz_L2_333MHz: + case CPU_1000MHz_DDR_667MHz_L2_500MHz: + tmp = DDR_666; + hclk = 333; + break; + default: + *ddr_freq = 0; + *hclk_ps = 0; + break; + } + + *ddr_freq = tmp; /* DDR freq define */ + *hclk_ps = 1000000 / hclk; /* values are 1/HCLK in ps */ + + return; +} +#endif diff --git a/drivers/ddr/mvebu/ddr3_init.h b/drivers/ddr/mvebu/ddr3_init.h new file mode 100644 index 0000000000..b259e098e5 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_init.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DDR3_INIT_H +#define __DDR3_INIT_H + +/* + * Debug + */ + +/* + * MV_DEBUG_INIT need to be defines, otherwise the output of the + * DDR2 training code is not complete and misleading + */ +#define MV_DEBUG_INIT + +#ifdef MV_DEBUG_INIT +#define DEBUG_INIT_S(s) puts(s) +#define DEBUG_INIT_D(d, l) printf("%x", d) +#define DEBUG_INIT_D_10(d, l) printf("%d", d) +#else +#define DEBUG_INIT_S(s) +#define DEBUG_INIT_D(d, l) +#define DEBUG_INIT_D_10(d, l) +#endif + +#ifdef MV_DEBUG_INIT_FULL +#define DEBUG_INIT_FULL_S(s) puts(s) +#define DEBUG_INIT_FULL_D(d, l) printf("%x", d) +#define DEBUG_INIT_FULL_D_10(d, l) printf("%d", d) +#define DEBUG_WR_REG(reg, val) \ + { DEBUG_INIT_S("Write Reg: 0x"); DEBUG_INIT_D((reg), 8); \ + DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); } +#define DEBUG_RD_REG(reg, val) \ + { DEBUG_INIT_S("Read Reg: 0x"); DEBUG_INIT_D((reg), 8); \ + DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); } +#else +#define DEBUG_INIT_FULL_S(s) +#define DEBUG_INIT_FULL_D(d, l) +#define DEBUG_INIT_FULL_D_10(d, l) +#define DEBUG_WR_REG(reg, val) +#define DEBUG_RD_REG(reg, val) +#endif + +#define DEBUG_INIT_FULL_C(s, d, l) \ + { DEBUG_INIT_FULL_S(s); DEBUG_INIT_FULL_D(d, l); DEBUG_INIT_FULL_S("\n"); } +#define DEBUG_INIT_C(s, d, l) \ + { DEBUG_INIT_S(s); DEBUG_INIT_D(d, l); DEBUG_INIT_S("\n"); } + +#define MV_MBUS_REGS_OFFSET (0x20000) + +#include "ddr3_hw_training.h" + +#define MAX_DIMM_NUM 2 +#define SPD_SIZE 128 + +#ifdef MV88F78X60 +#include "ddr3_axp.h" +#elif defined(MV88F67XX) +#include "ddr3_a370.h" +#elif defined(MV88F672X) +#include "ddr3_a375.h" +#endif + +/* DRR training Error codes */ +/* Stage 0 errors */ +#define MV_DDR3_TRAINING_ERR_BAD_SAR 0xDD300001 +/* Stage 1 errors */ +#define MV_DDR3_TRAINING_ERR_TWSI_FAIL 0xDD301001 +#define MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH 0xDD301001 +#define MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE 0xDD301003 +#define MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH 0xDD301004 +#define MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP 0xDD301005 +#define MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT 0xDD301006 +#define MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT 0xDD301007 +#define MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP 0xDD301008 +/* Stage 2 errors */ +#define MV_DDR3_TRAINING_ERR_HW_FAIL_BASE 0xDD302000 + +typedef enum config_type { + CONFIG_ECC, + CONFIG_MULTI_CS, + CONFIG_BUS_WIDTH +} MV_CONFIG_TYPE; + +enum log_level { + MV_LOG_LEVEL_0, + MV_LOG_LEVEL_1, + MV_LOG_LEVEL_2, + MV_LOG_LEVEL_3 +}; + +int ddr3_hw_training(u32 target_freq, u32 ddr_width, + int xor_bypass, u32 scrub_offs, u32 scrub_size, + int dqs_clk_aligned, int debug_mode, int reg_dimm_skip_wl); + +void ddr3_print_version(void); +void fix_pll_val(u8 target_fab); +u8 ddr3_get_eprom_fabric(void); +u32 ddr3_get_fab_opt(void); +u32 ddr3_get_cpu_freq(void); +u32 ddr3_get_vco_freq(void); +int ddr3_check_config(u32 addr, MV_CONFIG_TYPE config_type); +u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1, u32 offset2, + u32 mask2); +u32 ddr3_cl_to_valid_cl(u32 cl); +u32 ddr3_valid_cl_to_cl(u32 ui_valid_cl); +u32 ddr3_get_cs_num_from_reg(void); +u32 ddr3_get_cs_ena_from_reg(void); +u8 mv_ctrl_rev_get(void); + +u32 ddr3_get_log_level(void); + +/* SPD */ +int ddr3_dunit_setup(u32 ecc_ena, u32 hclk_time, u32 *ddr_width); + +/* + * Accessor functions for the registers + */ +static inline void reg_write(u32 addr, u32 val) +{ + writel(val, INTER_REGS_BASE + addr); +} + +static inline u32 reg_read(u32 addr) +{ + return readl(INTER_REGS_BASE + addr); +} + +static inline void reg_bit_set(u32 addr, u32 mask) +{ + setbits_le32(INTER_REGS_BASE + addr, mask); +} + +static inline void reg_bit_clr(u32 addr, u32 mask) +{ + clrbits_le32(INTER_REGS_BASE + addr, mask); +} + +#endif /* __DDR3_INIT_H */ diff --git a/drivers/ddr/mvebu/ddr3_patterns_64bit.h b/drivers/ddr/mvebu/ddr3_patterns_64bit.h new file mode 100644 index 0000000000..1b57328f7f --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_patterns_64bit.h @@ -0,0 +1,924 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DDR3_PATTERNS_64_H +#define __DDR3_PATTERNS_64_H + +/* + * Patterns Declerations + */ + +u32 wl_sup_pattern[LEN_WL_SUP_PATTERN] __aligned(32) = { + 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, + 0x14131211, 0x18171615, 0x1c1b1a19, 0x201f1e1d, + 0x24232221, 0x28272625, 0x2c2b2a29, 0x302f2e2d, + 0x34333231, 0x38373635, 0x3c3b3a39, 0x403f3e3d, + 0x44434241, 0x48474645, 0x4c4b4a49, 0x504f4e4d, + 0x54535251, 0x58575655, 0x5c5b5a59, 0x605f5e5d, + 0x64636261, 0x68676665, 0x6c6b6a69, 0x706f6e6d, + 0x74737271, 0x78777675, 0x7c7b7a79, 0x807f7e7d +}; + +u32 pbs_pattern_32b[2][LEN_PBS_PATTERN] __aligned(32) = { + { + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555, + 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, 0x55555555 + }, + { + 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, + 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, + 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA, + 0x55555555, 0xAAAAAAAA, 0x55555555, 0xAAAAAAAA + } +}; + +u32 pbs_pattern_64b[2][LEN_PBS_PATTERN] __aligned(32) = { + { + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555 + }, + { + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA + } +}; + +u32 rl_pattern[LEN_STD_PATTERN] __aligned(32) = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x01010101, 0x01010101, 0x01010101, 0x01010101 +}; + +u32 killer_pattern_32b[DQ_NUM][LEN_KILLER_PATTERN] __aligned(32) = { + { + 0x01010101, 0x00000000, 0x01010101, 0xFFFFFFFF, + 0x01010101, 0x00000000, 0x01010101, 0xFFFFFFFF, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0xFEFEFEFE, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0xFEFEFEFE, + 0x01010101, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0x01010101, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0xFEFEFEFE, 0x01010101, 0xFEFEFEFE, 0x00000000, + 0xFEFEFEFE, 0x01010101, 0xFEFEFEFE, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x01010101, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x01010101, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xFEFEFEFE, + 0x00000000, 0x00000000, 0x00000000, 0xFEFEFEFE, + 0xFEFEFEFE, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFEFEFEFE, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFEFEFEFE, 0x00000000, 0xFEFEFEFE, 0x00000000, + 0xFEFEFEFE, 0x00000000, 0xFEFEFEFE, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, + 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, 0x00000000, + 0x01010101, 0xFFFFFFFF, 0xFEFEFEFE, 0xFEFEFEFE, + 0x01010101, 0xFFFFFFFF, 0xFEFEFEFE, 0xFEFEFEFE + }, + { + 0x02020202, 0x00000000, 0x02020202, 0xFFFFFFFF, + 0x02020202, 0x00000000, 0x02020202, 0xFFFFFFFF, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0xFDFDFDFD, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0xFDFDFDFD, + 0x02020202, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0x02020202, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0xFDFDFDFD, 0x02020202, 0xFDFDFDFD, 0x00000000, + 0xFDFDFDFD, 0x02020202, 0xFDFDFDFD, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x02020202, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x02020202, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xFDFDFDFD, + 0x00000000, 0x00000000, 0x00000000, 0xFDFDFDFD, + 0xFDFDFDFD, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFDFDFDFD, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFDFDFDFD, 0x00000000, 0xFDFDFDFD, 0x00000000, + 0xFDFDFDFD, 0x00000000, 0xFDFDFDFD, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, + 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, 0x00000000, + 0x02020202, 0xFFFFFFFF, 0xFDFDFDFD, 0xFDFDFDFD, + 0x02020202, 0xFFFFFFFF, 0xFDFDFDFD, 0xFDFDFDFD + }, + { + 0x04040404, 0x00000000, 0x04040404, 0xFFFFFFFF, + 0x04040404, 0x00000000, 0x04040404, 0xFFFFFFFF, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0xFBFBFBFB, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0xFBFBFBFB, + 0x04040404, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0x04040404, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0xFBFBFBFB, 0x04040404, 0xFBFBFBFB, 0x00000000, + 0xFBFBFBFB, 0x04040404, 0xFBFBFBFB, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x04040404, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x04040404, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xFBFBFBFB, + 0x00000000, 0x00000000, 0x00000000, 0xFBFBFBFB, + 0xFBFBFBFB, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFBFBFBFB, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFBFBFBFB, 0x00000000, 0xFBFBFBFB, 0x00000000, + 0xFBFBFBFB, 0x00000000, 0xFBFBFBFB, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, + 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, 0x00000000, + 0x04040404, 0xFFFFFFFF, 0xFBFBFBFB, 0xFBFBFBFB, + 0x04040404, 0xFFFFFFFF, 0xFBFBFBFB, 0xFBFBFBFB + }, + { + 0x08080808, 0x00000000, 0x08080808, 0xFFFFFFFF, + 0x08080808, 0x00000000, 0x08080808, 0xFFFFFFFF, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0xF7F7F7F7, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0xF7F7F7F7, + 0x08080808, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0x08080808, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0xF7F7F7F7, 0x08080808, 0xF7F7F7F7, 0x00000000, + 0xF7F7F7F7, 0x08080808, 0xF7F7F7F7, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x08080808, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x08080808, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xF7F7F7F7, + 0x00000000, 0x00000000, 0x00000000, 0xF7F7F7F7, + 0xF7F7F7F7, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xF7F7F7F7, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xF7F7F7F7, 0x00000000, 0xF7F7F7F7, 0x00000000, + 0xF7F7F7F7, 0x00000000, 0xF7F7F7F7, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, + 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, 0x00000000, + 0x08080808, 0xFFFFFFFF, 0xF7F7F7F7, 0xF7F7F7F7, + 0x08080808, 0xFFFFFFFF, 0xF7F7F7F7, 0xF7F7F7F7 + }, + { + 0x10101010, 0x00000000, 0x10101010, 0xFFFFFFFF, + 0x10101010, 0x00000000, 0x10101010, 0xFFFFFFFF, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0xEFEFEFEF, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0xEFEFEFEF, + 0x10101010, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0x10101010, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0xEFEFEFEF, 0x10101010, 0xEFEFEFEF, 0x00000000, + 0xEFEFEFEF, 0x10101010, 0xEFEFEFEF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x10101010, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x10101010, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xEFEFEFEF, + 0x00000000, 0x00000000, 0x00000000, 0xEFEFEFEF, + 0xEFEFEFEF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xEFEFEFEF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xEFEFEFEF, 0x00000000, 0xEFEFEFEF, 0x00000000, + 0xEFEFEFEF, 0x00000000, 0xEFEFEFEF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, + 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, 0x00000000, + 0x10101010, 0xFFFFFFFF, 0xEFEFEFEF, 0xEFEFEFEF, + 0x10101010, 0xFFFFFFFF, 0xEFEFEFEF, 0xEFEFEFEF + }, + { + 0x20202020, 0x00000000, 0x20202020, 0xFFFFFFFF, + 0x20202020, 0x00000000, 0x20202020, 0xFFFFFFFF, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0xDFDFDFDF, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0xDFDFDFDF, + 0x20202020, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0x20202020, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0xDFDFDFDF, 0x20202020, 0xDFDFDFDF, 0x00000000, + 0xDFDFDFDF, 0x20202020, 0xDFDFDFDF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x20202020, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x20202020, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xDFDFDFDF, + 0x00000000, 0x00000000, 0x00000000, 0xDFDFDFDF, + 0xDFDFDFDF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xDFDFDFDF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xDFDFDFDF, 0x00000000, 0xDFDFDFDF, 0x00000000, + 0xDFDFDFDF, 0x00000000, 0xDFDFDFDF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, + 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, 0x00000000, + 0x20202020, 0xFFFFFFFF, 0xDFDFDFDF, 0xDFDFDFDF, + 0x20202020, 0xFFFFFFFF, 0xDFDFDFDF, 0xDFDFDFDF + }, + { + 0x40404040, 0x00000000, 0x40404040, 0xFFFFFFFF, + 0x40404040, 0x00000000, 0x40404040, 0xFFFFFFFF, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0xBFBFBFBF, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0xBFBFBFBF, + 0x40404040, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0x40404040, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0xBFBFBFBF, 0x40404040, 0xBFBFBFBF, 0x00000000, + 0xBFBFBFBF, 0x40404040, 0xBFBFBFBF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x40404040, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x40404040, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0xBFBFBFBF, + 0x00000000, 0x00000000, 0x00000000, 0xBFBFBFBF, + 0xBFBFBFBF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xBFBFBFBF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xBFBFBFBF, 0x00000000, 0xBFBFBFBF, 0x00000000, + 0xBFBFBFBF, 0x00000000, 0xBFBFBFBF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, + 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, 0x00000000, + 0x40404040, 0xFFFFFFFF, 0xBFBFBFBF, 0xBFBFBFBF, + 0x40404040, 0xFFFFFFFF, 0xBFBFBFBF, 0xBFBFBFBF + }, + { + 0x80808080, 0x00000000, 0x80808080, 0xFFFFFFFF, + 0x80808080, 0x00000000, 0x80808080, 0xFFFFFFFF, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x7F7F7F7F, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x7F7F7F7F, + 0x80808080, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x80808080, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x7F7F7F7F, 0x80808080, 0x7F7F7F7F, 0x00000000, + 0x7F7F7F7F, 0x80808080, 0x7F7F7F7F, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x80808080, + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x80808080, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x7F7F7F7F, + 0x00000000, 0x00000000, 0x00000000, 0x7F7F7F7F, + 0x7F7F7F7F, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x7F7F7F7F, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, + 0x7F7F7F7F, 0x00000000, 0x7F7F7F7F, 0x00000000, + 0x7F7F7F7F, 0x00000000, 0x7F7F7F7F, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, + 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, 0x00000000, + 0x80808080, 0xFFFFFFFF, 0x7F7F7F7F, 0x7F7F7F7F, + 0x80808080, 0xFFFFFFFF, 0x7F7F7F7F, 0x7F7F7F7F + } +}; + +u32 killer_pattern_64b[DQ_NUM][LEN_KILLER_PATTERN] __aligned(32) = { + { + 0x01010101, 0x01010101, 0x00000000, 0x00000000, + 0x01010101, 0x01010101, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE, + 0x01010101, 0x01010101, 0xFEFEFEFE, 0xFEFEFEFE, + 0x01010101, 0x01010101, 0xFEFEFEFE, 0xFEFEFEFE, + 0x01010101, 0x01010101, 0x01010101, 0x01010101, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0xFEFEFEFE, 0xFEFEFEFE, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, 0x01010101, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFEFEFEFE, 0xFEFEFEFE, + 0xFEFEFEFE, 0xFEFEFEFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFEFEFEFE, 0xFEFEFEFE, 0x00000000, 0x00000000, + 0xFEFEFEFE, 0xFEFEFEFE, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, 0x01010101, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x01010101, 0x01010101, 0x00000000, 0x00000000, + 0x01010101, 0x01010101, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE + }, + { + 0x02020202, 0x02020202, 0x00000000, 0x00000000, + 0x02020202, 0x02020202, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD, + 0x02020202, 0x02020202, 0xFDFDFDFD, 0xFDFDFDFD, + 0x02020202, 0x02020202, 0xFDFDFDFD, 0xFDFDFDFD, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0xFDFDFDFD, 0xFDFDFDFD, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, 0x02020202, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFDFDFDFD, 0xFDFDFDFD, + 0xFDFDFDFD, 0xFDFDFDFD, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFDFDFDFD, 0xFDFDFDFD, 0x00000000, 0x00000000, + 0xFDFDFDFD, 0xFDFDFDFD, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, 0x02020202, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x02020202, 0x02020202, 0x00000000, 0x00000000, + 0x02020202, 0x02020202, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD + }, + { + 0x04040404, 0x04040404, 0x00000000, 0x00000000, + 0x04040404, 0x04040404, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, + 0x04040404, 0x04040404, 0xFBFBFBFB, 0xFBFBFBFB, + 0x04040404, 0x04040404, 0xFBFBFBFB, 0xFBFBFBFB, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0xFBFBFBFB, 0xFBFBFBFB, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, 0x04040404, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFBFBFBFB, 0xFBFBFBFB, + 0xFBFBFBFB, 0xFBFBFBFB, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFBFBFBFB, 0xFBFBFBFB, 0x00000000, 0x00000000, + 0xFBFBFBFB, 0xFBFBFBFB, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, 0x04040404, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x04040404, 0x04040404, 0x00000000, 0x00000000, + 0x04040404, 0x04040404, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB + }, + { + 0x08080808, 0x08080808, 0x00000000, 0x00000000, + 0x08080808, 0x08080808, 0xFFFFFFFF, 0xFFFFFFFF, + 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7, + 0x08080808, 0x08080808, 0xF7F7F7F7, 0xF7F7F7F7, + 0x08080808, 0x08080808, 0xF7F7F7F7, 0xF7F7F7F7, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0xF7F7F7F7, 0xF7F7F7F7, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, 0x08080808, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xF7F7F7F7, 0xF7F7F7F7, + 0xF7F7F7F7, 0xF7F7F7F7, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xF7F7F7F7, 0xF7F7F7F7, 0x00000000, 0x00000000, + 0xF7F7F7F7, 0xF7F7F7F7, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, 0x08080808, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x08080808, 0x08080808, 0x00000000, 0x00000000, + 0x08080808, 0x08080808, 0xFFFFFFFF, 0xFFFFFFFF, + 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7 + }, + { + 0x10101010, 0x10101010, 0x00000000, 0x00000000, + 0x10101010, 0x10101010, 0xFFFFFFFF, 0xFFFFFFFF, + 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF, + 0x10101010, 0x10101010, 0xEFEFEFEF, 0xEFEFEFEF, + 0x10101010, 0x10101010, 0xEFEFEFEF, 0xEFEFEFEF, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0xEFEFEFEF, 0xEFEFEFEF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, 0x10101010, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xEFEFEFEF, 0xEFEFEFEF, + 0xEFEFEFEF, 0xEFEFEFEF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xEFEFEFEF, 0xEFEFEFEF, 0x00000000, 0x00000000, + 0xEFEFEFEF, 0xEFEFEFEF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, 0x10101010, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x10101010, 0x10101010, 0x00000000, 0x00000000, + 0x10101010, 0x10101010, 0xFFFFFFFF, 0xFFFFFFFF, + 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF + }, + { + 0x20202020, 0x20202020, 0x00000000, 0x00000000, + 0x20202020, 0x20202020, 0xFFFFFFFF, 0xFFFFFFFF, + 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF, + 0x20202020, 0x20202020, 0xDFDFDFDF, 0xDFDFDFDF, + 0x20202020, 0x20202020, 0xDFDFDFDF, 0xDFDFDFDF, + 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0xDFDFDFDF, 0xDFDFDFDF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, 0x20202020, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xDFDFDFDF, 0xDFDFDFDF, + 0xDFDFDFDF, 0xDFDFDFDF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xDFDFDFDF, 0xDFDFDFDF, 0x00000000, 0x00000000, + 0xDFDFDFDF, 0xDFDFDFDF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, 0x20202020, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x20202020, 0x20202020, 0x00000000, 0x00000000, + 0x20202020, 0x20202020, 0xFFFFFFFF, 0xFFFFFFFF, + 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF + }, + { + 0x40404040, 0x40404040, 0x00000000, 0x00000000, + 0x40404040, 0x40404040, 0xFFFFFFFF, 0xFFFFFFFF, + 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF, + 0x40404040, 0x40404040, 0xBFBFBFBF, 0xBFBFBFBF, + 0x40404040, 0x40404040, 0xBFBFBFBF, 0xBFBFBFBF, + 0x40404040, 0x40404040, 0x40404040, 0x40404040, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0xBFBFBFBF, 0xBFBFBFBF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, 0x40404040, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xBFBFBFBF, 0xBFBFBFBF, + 0xBFBFBFBF, 0xBFBFBFBF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xBFBFBFBF, 0xBFBFBFBF, 0x00000000, 0x00000000, + 0xBFBFBFBF, 0xBFBFBFBF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, 0x40404040, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x40404040, 0x40404040, 0x00000000, 0x00000000, + 0x40404040, 0x40404040, 0xFFFFFFFF, 0xFFFFFFFF, + 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF + }, + { + 0x80808080, 0x80808080, 0x00000000, 0x00000000, + 0x80808080, 0x80808080, 0xFFFFFFFF, 0xFFFFFFFF, + 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F, + 0x80808080, 0x80808080, 0x7F7F7F7F, 0x7F7F7F7F, + 0x80808080, 0x80808080, 0x7F7F7F7F, 0x7F7F7F7F, + 0x80808080, 0x80808080, 0x80808080, 0x80808080, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x7F7F7F7F, 0x7F7F7F7F, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, 0x80808080, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x7F7F7F7F, 0x7F7F7F7F, + 0x7F7F7F7F, 0x7F7F7F7F, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x7F7F7F7F, 0x7F7F7F7F, 0x00000000, 0x00000000, + 0x7F7F7F7F, 0x7F7F7F7F, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, 0x80808080, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x80808080, 0x80808080, 0x00000000, 0x00000000, + 0x80808080, 0x80808080, 0xFFFFFFFF, 0xFFFFFFFF, + 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F + } +}; + +u32 special_pattern[DQ_NUM][LEN_SPECIAL_PATTERN] __aligned(32) = { + { + 0x00000000, 0x00000000, 0x01010101, 0x01010101, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFEFEFEFE, 0xFEFEFEFE, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0xFEFEFEFE, 0xFEFEFEFE, 0x01010101, 0x01010101, + 0x01010101, 0x01010101, 0xFEFEFEFE, 0xFEFEFEFE, + 0x01010101, 0x01010101, 0xFEFEFEFE, 0xFEFEFEFE, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x01010101, 0x01010101, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE, 0xFEFEFEFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFEFEFEFE, 0xFEFEFEFE, + 0x00000000, 0x00000000, 0xFEFEFEFE, 0xFEFEFEFE, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x01010101, 0x01010101, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x01010101, 0x01010101, + 0x00000000, 0x00000000, 0x01010101, 0x01010101, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFEFEFEFE, 0xFEFEFEFE, + 0xFEFEFEFE, 0xFEFEFEFE, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x02020202, 0x02020202, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFDFDFDFD, 0xFDFDFDFD, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0xFDFDFDFD, 0xFDFDFDFD, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0xFDFDFDFD, 0xFDFDFDFD, + 0x02020202, 0x02020202, 0xFDFDFDFD, 0xFDFDFDFD, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x02020202, 0x02020202, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD, 0xFDFDFDFD, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFDFDFDFD, 0xFDFDFDFD, + 0x00000000, 0x00000000, 0xFDFDFDFD, 0xFDFDFDFD, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x02020202, 0x02020202, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x02020202, 0x02020202, + 0x00000000, 0x00000000, 0x02020202, 0x02020202, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFDFDFDFD, 0xFDFDFDFD, + 0xFDFDFDFD, 0xFDFDFDFD, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x04040404, 0x04040404, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFBFBFBFB, 0xFBFBFBFB, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0xFBFBFBFB, 0xFBFBFBFB, 0x04040404, 0x04040404, + 0x04040404, 0x04040404, 0xFBFBFBFB, 0xFBFBFBFB, + 0x04040404, 0x04040404, 0xFBFBFBFB, 0xFBFBFBFB, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x04040404, 0x04040404, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFBFBFBFB, 0xFBFBFBFB, + 0x00000000, 0x00000000, 0xFBFBFBFB, 0xFBFBFBFB, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x04040404, 0x04040404, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x04040404, 0x04040404, + 0x00000000, 0x00000000, 0x04040404, 0x04040404, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFBFBFBFB, 0xFBFBFBFB, + 0xFBFBFBFB, 0xFBFBFBFB, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x08080808, 0x08080808, + 0xFFFFFFFF, 0xFFFFFFFF, 0xF7F7F7F7, 0xF7F7F7F7, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0xF7F7F7F7, 0xF7F7F7F7, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0xF7F7F7F7, 0xF7F7F7F7, + 0x08080808, 0x08080808, 0xF7F7F7F7, 0xF7F7F7F7, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x08080808, 0x08080808, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7, 0xF7F7F7F7, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xF7F7F7F7, 0xF7F7F7F7, + 0x00000000, 0x00000000, 0xF7F7F7F7, 0xF7F7F7F7, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x08080808, 0x08080808, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x08080808, 0x08080808, + 0x00000000, 0x00000000, 0x08080808, 0x08080808, + 0xFFFFFFFF, 0xFFFFFFFF, 0xF7F7F7F7, 0xF7F7F7F7, + 0xF7F7F7F7, 0xF7F7F7F7, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x10101010, 0x10101010, + 0xFFFFFFFF, 0xFFFFFFFF, 0xEFEFEFEF, 0xEFEFEFEF, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0xEFEFEFEF, 0xEFEFEFEF, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0xEFEFEFEF, 0xEFEFEFEF, + 0x10101010, 0x10101010, 0xEFEFEFEF, 0xEFEFEFEF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x10101010, 0x10101010, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF, 0xEFEFEFEF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xEFEFEFEF, 0xEFEFEFEF, + 0x00000000, 0x00000000, 0xEFEFEFEF, 0xEFEFEFEF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x10101010, 0x10101010, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x10101010, 0x10101010, + 0x00000000, 0x00000000, 0x10101010, 0x10101010, + 0xFFFFFFFF, 0xFFFFFFFF, 0xEFEFEFEF, 0xEFEFEFEF, + 0xEFEFEFEF, 0xEFEFEFEF, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x20202020, 0x20202020, + 0xFFFFFFFF, 0xFFFFFFFF, 0xDFDFDFDF, 0xDFDFDFDF, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0xDFDFDFDF, 0xDFDFDFDF, 0x20202020, 0x20202020, + 0x20202020, 0x20202020, 0xDFDFDFDF, 0xDFDFDFDF, + 0x20202020, 0x20202020, 0xDFDFDFDF, 0xDFDFDFDF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x20202020, 0x20202020, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF, 0xDFDFDFDF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xDFDFDFDF, 0xDFDFDFDF, + 0x00000000, 0x00000000, 0xDFDFDFDF, 0xDFDFDFDF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x20202020, 0x20202020, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x20202020, 0x20202020, + 0x00000000, 0x00000000, 0x20202020, 0x20202020, + 0xFFFFFFFF, 0xFFFFFFFF, 0xDFDFDFDF, 0xDFDFDFDF, + 0xDFDFDFDF, 0xDFDFDFDF, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x40404040, 0x40404040, + 0xFFFFFFFF, 0xFFFFFFFF, 0xBFBFBFBF, 0xBFBFBFBF, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0xBFBFBFBF, 0xBFBFBFBF, 0x40404040, 0x40404040, + 0x40404040, 0x40404040, 0xBFBFBFBF, 0xBFBFBFBF, + 0x40404040, 0x40404040, 0xBFBFBFBF, 0xBFBFBFBF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x40404040, 0x40404040, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF, 0xBFBFBFBF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xBFBFBFBF, 0xBFBFBFBF, + 0x00000000, 0x00000000, 0xBFBFBFBF, 0xBFBFBFBF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x40404040, 0x40404040, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x40404040, 0x40404040, + 0x00000000, 0x00000000, 0x40404040, 0x40404040, + 0xFFFFFFFF, 0xFFFFFFFF, 0xBFBFBFBF, 0xBFBFBFBF, + 0xBFBFBFBF, 0xBFBFBFBF, 0x00000000, 0x00000000 + }, + { + 0x00000000, 0x00000000, 0x80808080, 0x80808080, + 0xFFFFFFFF, 0xFFFFFFFF, 0x7F7F7F7F, 0x7F7F7F7F, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x7F7F7F7F, 0x7F7F7F7F, 0x80808080, 0x80808080, + 0x80808080, 0x80808080, 0x7F7F7F7F, 0x7F7F7F7F, + 0x80808080, 0x80808080, 0x7F7F7F7F, 0x7F7F7F7F, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x80808080, 0x80808080, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F, 0x7F7F7F7F, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x7F7F7F7F, 0x7F7F7F7F, + 0x00000000, 0x00000000, 0x7F7F7F7F, 0x7F7F7F7F, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0x80808080, 0x80808080, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x80808080, 0x80808080, + 0x00000000, 0x00000000, 0x80808080, 0x80808080, + 0xFFFFFFFF, 0xFFFFFFFF, 0x7F7F7F7F, 0x7F7F7F7F, + 0x7F7F7F7F, 0x7F7F7F7F, 0x00000000, 0x00000000 + } +}; + +/* Fabric ratios table */ +u32 fabric_ratio[FAB_OPT] = { + 0x04010204, + 0x04020202, + 0x08020306, + 0x08020303, + 0x04020303, + 0x04020204, + 0x04010202, + 0x08030606, + 0x08030505, + 0x04020306, + 0x0804050A, + 0x04030606, + 0x04020404, + 0x04030306, + 0x04020505, + 0x08020505, + 0x04010303, + 0x08050A0A, + 0x04030408, + 0x04010102, + 0x08030306 +}; + +u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM] = { + {3, 2, 5, 7, 1, 0, 6, 4}, + {2, 3, 6, 7, 1, 0, 4, 5}, + {1, 3, 5, 6, 0, 2, 4, 7}, + {0, 2, 4, 7, 1, 3, 5, 6}, + {3, 0, 4, 6, 1, 2, 5, 7}, + {0, 3, 5, 7, 1, 2, 4, 6}, + {2, 3, 5, 7, 1, 0, 4, 6}, + {0, 2, 5, 4, 1, 3, 6, 7}, + {2, 3, 4, 7, 0, 1, 5, 6} +}; + +#endif /* __DDR3_PATTERNS_64_H */ diff --git a/drivers/ddr/mvebu/ddr3_pbs.c b/drivers/ddr/mvebu/ddr3_pbs.c new file mode 100644 index 0000000000..00ea3fdb91 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_pbs.c @@ -0,0 +1,1592 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" + +/* + * Debug + */ +#define DEBUG_PBS_FULL_C(s, d, l) \ + DEBUG_PBS_FULL_S(s); DEBUG_PBS_FULL_D(d, l); DEBUG_PBS_FULL_S("\n") +#define DEBUG_PBS_C(s, d, l) \ + DEBUG_PBS_S(s); DEBUG_PBS_D(d, l); DEBUG_PBS_S("\n") + +#ifdef MV_DEBUG_PBS +#define DEBUG_PBS_S(s) puts(s) +#define DEBUG_PBS_D(d, l) printf("%x", d) +#else +#define DEBUG_PBS_S(s) +#define DEBUG_PBS_D(d, l) +#endif + +#ifdef MV_DEBUG_FULL_PBS +#define DEBUG_PBS_FULL_S(s) puts(s) +#define DEBUG_PBS_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_PBS_FULL_S(s) +#define DEBUG_PBS_FULL_D(d, l) +#endif + +#if defined(MV88F78X60) || defined(MV88F672X) + +/* Temp array for skew data storage */ +static u32 skew_array[(MAX_PUP_NUM) * DQ_NUM] = { 0 }; + +/* PBS locked dq (per pup) */ +extern u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM]; +extern u32 pbs_locked_dm[MAX_PUP_NUM]; +extern u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM]; + +#if defined(MV88F672X) +extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN]; +extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN]; +#else +extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN]; +extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN]; +#endif + +extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM]; + +static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info, + u32 cur_pup, u32 pbs_pattern_idx, u32 ecc); +static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup, + u32 pbs_pattern_idx, u32 ecc); +static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx, + u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc); +static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx); +static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay); + +/* + * Name: ddr3_pbs_tx + * Desc: Execute the PBS TX phase. + * Args: dram_info ddr3 training information struct + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_pbs_tx(MV_DRAM_INFO *dram_info) +{ + /* Array of Deskew results */ + + /* + * Array to hold the total sum of skew from all iterations + * (for average purpose) + */ + u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} }; + + /* + * Array to hold the total average skew from both patterns + * (for average purpose) + */ + u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} }; + + u32 pbs_rep_time = 0; /* counts number of loop in case of fail */ + /* bit array for unlock pups - used to repeat on the RX operation */ + u32 cur_pup; + u32 max_pup; + u32 pbs_retry; + u32 pup, dq, pups, cur_max_pup, valid_pup, reg; + u32 pattern_idx; + u32 ecc; + /* indicates whether we need to start the loop again */ + int start_over; + + DEBUG_PBS_S("DDR3 - PBS TX - Starting PBS TX procedure\n"); + + pups = dram_info->num_of_total_pups; + max_pup = dram_info->num_of_total_pups; + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_PBS_S("DDR3 - PBS RX - SW Override Enabled\n"); + + reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS; + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + /* Running twice for 2 different patterns. each patterns - 3 times */ + for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) { + DEBUG_PBS_C("DDR3 - PBS TX - Working with pattern - ", + pattern_idx, 1); + + /* Reset sum array */ + for (pup = 0; pup < pups; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) + skew_sum_array[pup][dq] = 0; + } + + /* + * Perform PBS several of times (3 for each pattern). + * At the end, we'll use the average + */ + /* If there is ECC, do each PBS again with mux change */ + for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) { + for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { + + /* + * This parameter stores the current PUP + * num - ecc mode dependent - 4-8 / 1 pups + */ + cur_max_pup = (1 - ecc) * + dram_info->num_of_std_pups + ecc; + + if (ecc) { + /* Only 1 pup in this case */ + valid_pup = 0x1; + } else if (cur_max_pup > 4) { + /* 64 bit - 8 pups */ + valid_pup = 0xFF; + } else if (cur_max_pup == 4) { + /* 32 bit - 4 pups */ + valid_pup = 0xF; + } else { + /* 16 bit - 2 pups */ + valid_pup = 0x3; + } + + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg |= (dram_info->ecc_ena * ecc << + REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + if (ecc) + DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Enabled\n"); + else + DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Disabled\n"); + + /* Init iteration values */ + /* Clear the locked DQs */ + for (pup = 0; pup < cur_max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + pbs_locked_dq[ + pup + ecc * + (max_pup - 1)][dq] = + 0; + } + } + + pbs_rep_time = 0; + cur_pup = valid_pup; + start_over = 0; + + /* + * Run loop On current Pattern and current + * pattern iteration (just to cover the false + * fail problem) + */ + do { + DEBUG_PBS_S("DDR3 - PBS Tx - Pbs Rep Loop is "); + DEBUG_PBS_D(pbs_rep_time, 1); + DEBUG_PBS_S(", for Retry No."); + DEBUG_PBS_D(pbs_retry, 1); + DEBUG_PBS_S("\n"); + + /* Set all PBS values to MIN (0) */ + DEBUG_PBS_S("DDR3 - PBS Tx - Set all PBS values to MIN\n"); + + for (dq = 0; dq < DQ_NUM; dq++) { + ddr3_write_pup_reg( + PUP_PBS_TX + + pbs_dq_mapping[pup * + (1 - ecc) + + ecc * ECC_PUP] + [dq], CS0, (1 - ecc) * + PUP_BC + ecc * ECC_PUP, 0, + 0); + } + + /* + * Shift DQ ADLL right, One step before + * fail + */ + DEBUG_PBS_S("DDR3 - PBS Tx - ADLL shift right one phase before fail\n"); + + if (MV_OK != ddr3_tx_shift_dqs_adll_step_before_fail + (dram_info, cur_pup, pattern_idx, + ecc)) + return MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE; + + /* PBS For each bit */ + DEBUG_PBS_S("DDR3 - PBS Tx - perform PBS for each bit\n"); + + /* + * In this stage - start_over = 0 + */ + if (MV_OK != ddr3_pbs_per_bit( + dram_info, &start_over, 1, + &cur_pup, pattern_idx, ecc)) + return MV_DDR3_TRAINING_ERR_PBS_TX_PER_BIT; + + } while ((start_over == 1) && + (++pbs_rep_time < COUNT_PBS_STARTOVER)); + + if (pbs_rep_time == COUNT_PBS_STARTOVER && + start_over == 1) { + DEBUG_PBS_S("DDR3 - PBS Tx - FAIL - Adll reach max value\n"); + return MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL; + } + + DEBUG_PBS_FULL_C("DDR3 - PBS TX - values for iteration - ", + pbs_retry, 1); + for (pup = 0; pup < cur_max_pup; pup++) { + /* + * To minimize delay elements, inc + * from pbs value the min pbs val + */ + DEBUG_PBS_S("DDR3 - PBS - PUP"); + DEBUG_PBS_D((pup + (ecc * ECC_PUP)), 1); + DEBUG_PBS_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - + * last / first failing bit + * Deskew For all bits (per PUP) + * (minimize delay elements) + */ + DEBUG_PBS_S("DQ"); + DEBUG_PBS_D(dq, 1); + DEBUG_PBS_S("-"); + DEBUG_PBS_D(skew_array + [((pup) * DQ_NUM) + + dq], 2); + DEBUG_PBS_S(", "); + } + DEBUG_PBS_S("\n"); + } + + /* + * Collect the results we got on this trial + * of PBS + */ + for (pup = 0; pup < cur_max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + skew_sum_array[pup + (ecc * (max_pup - 1))] + [dq] += skew_array + [((pup) * DQ_NUM) + dq]; + } + } + + /* ECC Support - Disable ECC MUX */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + } + } + + DEBUG_PBS_C("DDR3 - PBS TX - values for current pattern - ", + pattern_idx, 1); + for (pup = 0; pup < max_pup; pup++) { + /* + * To minimize delay elements, inc from pbs value the + * min pbs val + */ + DEBUG_PBS_S("DDR3 - PBS - PUP"); + DEBUG_PBS_D(pup, 1); + DEBUG_PBS_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* set skew value for all dq */ + /* Bit# Deskew <- Bit# Deskew - last / first failing bit Deskew For all bits (per PUP) (minimize delay elements) */ + DEBUG_PBS_S("DQ"); + DEBUG_PBS_D(dq, 1); + DEBUG_PBS_S("-"); + DEBUG_PBS_D(skew_sum_array[pup][dq] / + COUNT_PBS_REPEAT, 2); + DEBUG_PBS_S(", "); + } + DEBUG_PBS_S("\n"); + } + + /* + * Calculate the average skew for current pattern for each + * pup and each bit + */ + DEBUG_PBS_C("DDR3 - PBS TX - Average for pattern - ", + pattern_idx, 1); + + for (pup = 0; pup < max_pup; pup++) { + /* + * FOR ECC only :: found min and max value for current + * pattern skew array + */ + /* Loop for all dqs */ + for (dq = 0; dq < DQ_NUM; dq++) { + pattern_skew_array[pup][dq] += + (skew_sum_array[pup][dq] / + COUNT_PBS_REPEAT); + } + } + } + + /* Calculate the average skew */ + for (pup = 0; pup < max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) + skew_array[((pup) * DQ_NUM) + dq] = + pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN; + } + + DEBUG_PBS_S("DDR3 - PBS TX - Average for all patterns:\n"); + for (pup = 0; pup < max_pup; pup++) { + /* + * To minimize delay elements, inc from pbs value the min + * pbs val + */ + DEBUG_PBS_S("DDR3 - PBS - PUP"); + DEBUG_PBS_D(pup, 1); + DEBUG_PBS_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - last / first + * failing bit Deskew For all bits (per PUP) + * (minimize delay elements) + */ + DEBUG_PBS_S("DQ"); + DEBUG_PBS_D(dq, 1); + DEBUG_PBS_S("-"); + DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2); + DEBUG_PBS_S(", "); + } + DEBUG_PBS_S("\n"); + } + + /* Return ADLL to default value */ + for (pup = 0; pup < max_pup; pup++) { + if (pup == (max_pup - 1) && dram_info->ecc_ena) + pup = ECC_PUP; + ddr3_pbs_write_pup_dqs_reg(CS0, pup, INIT_WL_DELAY); + } + + /* Set averaged PBS results */ + ddr3_set_pbs_results(dram_info, 1); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + DEBUG_PBS_S("DDR3 - PBS Tx - PBS TX ended successfuly\n"); + + return MV_OK; +} + +/* + * Name: ddr3_tx_shift_dqs_adll_step_before_fail + * Desc: Execute the Tx shift DQ phase. + * Args: dram_info ddr3 training information struct + * cur_pup bit array of the function active pups. + * pbs_pattern_idx Index of PBS pattern + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info, + u32 cur_pup, + u32 pbs_pattern_idx, u32 ecc) +{ + u32 unlock_pup; /* bit array of unlock pups */ + u32 new_lockup_pup; /* bit array of compare failed pups */ + u32 adll_val = 4; /* INIT_WL_DELAY */ + u32 cur_max_pup, pup; + u32 dqs_dly_set[MAX_PUP_NUM] = { 0 }; + u32 *pattern_ptr; + + /* Choose pattern */ + switch (dram_info->ddr_width) { +#if defined(MV88F672X) + case 16: + pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx]; + break; +#endif + case 32: + pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx]; + break; +#if defined(MV88F78X60) + case 64: + pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx]; + break; +#endif + default: + return MV_FAIL; + } + + /* Set current pup number */ + if (cur_pup == 0x1) /* Ecc mode */ + cur_max_pup = 1; + else + cur_max_pup = dram_info->num_of_std_pups; + + unlock_pup = cur_pup; /* '1' for each unlocked pup */ + + /* Loop on all ADLL Vaules */ + do { + /* Loop until found first fail */ + adll_val++; + + /* + * Increment (Move to right - ADLL) DQ TX delay + * (broadcast to all Data PUPs) + */ + for (pup = 0; pup < cur_max_pup; pup++) + ddr3_pbs_write_pup_dqs_reg(CS0, + pup * (1 - ecc) + + ECC_PUP * ecc, adll_val); + + /* + * Write and Read, compare results (read was already verified) + */ + /* 0 - all locked */ + new_lockup_pup = 0; + + if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, + &new_lockup_pup, + pattern_ptr, LEN_PBS_PATTERN, + SDRAM_PBS_TX_OFFS, 1, 0, + NULL, + 0)) + return MV_FAIL; + + unlock_pup &= ~new_lockup_pup; + + DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: "); + DEBUG_PBS_FULL_D(unlock_pup, 2); + DEBUG_PBS_FULL_C(", Set ADLL value = ", adll_val, 2); + + /* If any PUP failed there is '1' to mark the PUP */ + if (new_lockup_pup != 0) { + /* + * Decrement (Move Back to Left two steps - ADLL) + * DQ TX delay for current failed pups and save + */ + for (pup = 0; pup < cur_max_pup; pup++) { + if (((new_lockup_pup >> pup) & 0x1) && + dqs_dly_set[pup] == 0) + dqs_dly_set[pup] = adll_val - 1; + } + } + } while ((unlock_pup != 0) && (adll_val != ADLL_MAX)); + + if (unlock_pup != 0) { + DEBUG_PBS_FULL_S("DDR3 - PBS Tx - Shift DQ - Adll value reached maximum\n"); + + for (pup = 0; pup < cur_max_pup; pup++) { + if (((unlock_pup >> pup) & 0x1) && + dqs_dly_set[pup] == 0) + dqs_dly_set[pup] = adll_val - 1; + } + } + + DEBUG_PBS_FULL_C("PBS TX one step before fail last pups locked Adll ", + adll_val - 2, 2); + + /* Set the PUP DQS DLY Values */ + for (pup = 0; pup < cur_max_pup; pup++) + ddr3_pbs_write_pup_dqs_reg(CS0, pup * (1 - ecc) + ECC_PUP * ecc, + dqs_dly_set[pup]); + + /* Found one phase before fail */ + return MV_OK; +} + +/* + * Name: ddr3_pbs_rx + * Desc: Execute the PBS RX phase. + * Args: dram_info ddr3 training information struct + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_pbs_rx(MV_DRAM_INFO *dram_info) +{ + /* + * Array to hold the total sum of skew from all iterations + * (for average purpose) + */ + u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} }; + + /* + * Array to hold the total average skew from both patterns + * (for average purpose) + */ + u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} }; + + u32 pbs_rep_time = 0; /* counts number of loop in case of fail */ + /* bit array for unlock pups - used to repeat on the RX operation */ + u32 cur_pup; + u32 max_pup; + u32 pbs_retry; + u32 pup, dq, pups, cur_max_pup, valid_pup, reg; + u32 pattern_idx; + u32 ecc; + /* indicates whether we need to start the loop again */ + int start_over; + int status; + + DEBUG_PBS_S("DDR3 - PBS RX - Starting PBS RX procedure\n"); + + pups = dram_info->num_of_total_pups; + max_pup = dram_info->num_of_total_pups; + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_PBS_FULL_S("DDR3 - PBS RX - SW Override Enabled\n"); + + reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS; + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + /* Running twice for 2 different patterns. each patterns - 3 times */ + for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) { + DEBUG_PBS_FULL_C("DDR3 - PBS RX - Working with pattern - ", + pattern_idx, 1); + + /* Reset sum array */ + for (pup = 0; pup < pups; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) + skew_sum_array[pup][dq] = 0; + } + + /* + * Perform PBS several of times (3 for each pattern). + * At the end, we'll use the average + */ + /* If there is ECC, do each PBS again with mux change */ + for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) { + for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { + /* + * This parameter stores the current PUP + * num - ecc mode dependent - 4-8 / 1 pups + */ + cur_max_pup = (1 - ecc) * + dram_info->num_of_std_pups + ecc; + + if (ecc) { + /* Only 1 pup in this case */ + valid_pup = 0x1; + } else if (cur_max_pup > 4) { + /* 64 bit - 8 pups */ + valid_pup = 0xFF; + } else if (cur_max_pup == 4) { + /* 32 bit - 4 pups */ + valid_pup = 0xF; + } else { + /* 16 bit - 2 pups */ + valid_pup = 0x3; + } + + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg |= (dram_info->ecc_ena * ecc << + REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + if (ecc) + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Enabled\n"); + else + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Disabled\n"); + + /* Init iteration values */ + /* Clear the locked DQs */ + for (pup = 0; pup < cur_max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + pbs_locked_dq[ + pup + ecc * (max_pup - 1)][dq] = + 0; + } + } + + pbs_rep_time = 0; + cur_pup = valid_pup; + start_over = 0; + + /* + * Run loop On current Pattern and current + * pattern iteration (just to cover the false + * fail problem + */ + do { + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Pbs Rep Loop is "); + DEBUG_PBS_FULL_D(pbs_rep_time, 1); + DEBUG_PBS_FULL_S(", for Retry No."); + DEBUG_PBS_FULL_D(pbs_retry, 1); + DEBUG_PBS_FULL_S("\n"); + + /* Set all PBS values to MAX (31) */ + for (pup = 0; pup < cur_max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) + ddr3_write_pup_reg( + PUP_PBS_RX + + pbs_dq_mapping[ + pup * (1 - ecc) + + ecc * ECC_PUP] + [dq], CS0, + pup + ecc * ECC_PUP, + 0, MAX_PBS); + } + + /* Set all DQS PBS values to MIN (0) */ + for (pup = 0; pup < cur_max_pup; pup++) { + ddr3_write_pup_reg(PUP_PBS_RX + + DQ_NUM, CS0, + pup + + ecc * + ECC_PUP, 0, + 0); + } + + /* Shift DQS, To first Fail */ + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift RX DQS to first fail\n"); + + status = ddr3_rx_shift_dqs_to_first_fail + (dram_info, cur_pup, + pattern_idx, ecc); + if (MV_OK != status) { + DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_rx_shift_dqs_to_first_fail failed.\n"); + DEBUG_PBS_D(status, 8); + DEBUG_PBS_S("\nDDR3 - PBS Rx - SKIP.\n"); + + /* Reset read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Start Auto Read Leveling procedure */ + reg |= (1 << REG_DRAM_TRAINING_RL_OFFS); + /* 0x15B0 - Training Register */ + reg_write(REG_DRAM_TRAINING_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS) + + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS)); + /* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + do { + reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) + & (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + } while (reg); /* Wait for '0' */ + + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Clear Auto Read Leveling procedure */ + reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS); + /* 0x15B0 - Training Register */ + reg_write(REG_DRAM_TRAINING_ADDR, reg); + + /* Set ADLL to 15 */ + for (pup = 0; pup < max_pup; + pup++) { + ddr3_write_pup_reg + (PUP_DQS_RD, CS0, + pup + + (ecc * ECC_PUP), 0, + 15); + } + + /* Set all PBS values to MIN (0) */ + for (pup = 0; pup < cur_max_pup; + pup++) { + for (dq = 0; + dq < DQ_NUM; dq++) + ddr3_write_pup_reg + (PUP_PBS_RX + + pbs_dq_mapping + [pup * (1 - ecc) + + ecc * ECC_PUP] + [dq], CS0, + pup + ecc * ECC_PUP, + 0, MIN_PBS); + } + + return MV_OK; + } + + /* PBS For each bit */ + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - perform PBS for each bit\n"); + /* in this stage - start_over = 0; */ + if (MV_OK != ddr3_pbs_per_bit( + dram_info, &start_over, + 0, &cur_pup, + pattern_idx, ecc)) { + DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_pbs_per_bit failed."); + return MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT; + } + + } while ((start_over == 1) && + (++pbs_rep_time < COUNT_PBS_STARTOVER)); + + if (pbs_rep_time == COUNT_PBS_STARTOVER && + start_over == 1) { + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - FAIL - Algorithm failed doing RX PBS\n"); + return MV_DDR3_TRAINING_ERR_PBS_RX_MAX_VAL; + } + + /* Return DQS ADLL to default value - 15 */ + /* Set all DQS PBS values to MIN (0) */ + for (pup = 0; pup < cur_max_pup; pup++) + ddr3_write_pup_reg(PUP_DQS_RD, CS0, + pup + ecc * ECC_PUP, + 0, INIT_RL_DELAY); + + DEBUG_PBS_FULL_C("DDR3 - PBS RX - values for iteration - ", + pbs_retry, 1); + for (pup = 0; pup < cur_max_pup; pup++) { + /* + * To minimize delay elements, inc from + * pbs value the min pbs val + */ + DEBUG_PBS_FULL_S("DDR3 - PBS - PUP"); + DEBUG_PBS_FULL_D((pup + + (ecc * ECC_PUP)), 1); + DEBUG_PBS_FULL_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - + * last / first failing bit + * Deskew For all bits (per PUP) + * (minimize delay elements) + */ + DEBUG_PBS_FULL_S("DQ"); + DEBUG_PBS_FULL_D(dq, 1); + DEBUG_PBS_FULL_S("-"); + DEBUG_PBS_FULL_D(skew_array + [((pup) * + DQ_NUM) + + dq], 2); + DEBUG_PBS_FULL_S(", "); + } + DEBUG_PBS_FULL_S("\n"); + } + + /* + * Collect the results we got on this trial + * of PBS + */ + for (pup = 0; pup < cur_max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + skew_sum_array + [pup + (ecc * (max_pup - 1))] + [dq] += + skew_array[((pup) * DQ_NUM) + dq]; + } + } + + /* ECC Support - Disable ECC MUX */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + } + } + + /* + * Calculate the average skew for current pattern for each + * pup and each bit + */ + DEBUG_PBS_FULL_C("DDR3 - PBS RX - Average for pattern - ", + pattern_idx, 1); + for (pup = 0; pup < max_pup; pup++) { + /* + * FOR ECC only :: found min and max value for + * current pattern skew array + */ + /* Loop for all dqs */ + for (dq = 0; dq < DQ_NUM; dq++) { + pattern_skew_array[pup][dq] += + (skew_sum_array[pup][dq] / + COUNT_PBS_REPEAT); + } + } + + DEBUG_PBS_C("DDR3 - PBS RX - values for current pattern - ", + pattern_idx, 1); + for (pup = 0; pup < max_pup; pup++) { + /* + * To minimize delay elements, inc from pbs value the + * min pbs val + */ + DEBUG_PBS_S("DDR3 - PBS RX - PUP"); + DEBUG_PBS_D(pup, 1); + DEBUG_PBS_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - last / first + * failing bit Deskew For all bits (per PUP) + * (minimize delay elements) + */ + DEBUG_PBS_S("DQ"); + DEBUG_PBS_D(dq, 1); + DEBUG_PBS_S("-"); + DEBUG_PBS_D(skew_sum_array[pup][dq] / + COUNT_PBS_REPEAT, 2); + DEBUG_PBS_S(", "); + } + DEBUG_PBS_S("\n"); + } + } + + /* Calculate the average skew */ + for (pup = 0; pup < max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) + skew_array[((pup) * DQ_NUM) + dq] = + pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN; + } + + DEBUG_PBS_S("DDR3 - PBS RX - Average for all patterns:\n"); + for (pup = 0; pup < max_pup; pup++) { + /* + * To minimize delay elements, inc from pbs value the + * min pbs val + */ + DEBUG_PBS_S("DDR3 - PBS - PUP"); + DEBUG_PBS_D(pup, 1); + DEBUG_PBS_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - last / first + * failing bit Deskew For all bits (per PUP) + * (minimize delay elements) + */ + DEBUG_PBS_S("DQ"); + DEBUG_PBS_D(dq, 1); + DEBUG_PBS_S("-"); + DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2); + DEBUG_PBS_S(", "); + } + DEBUG_PBS_S("\n"); + } + + /* Return ADLL to default value */ + ddr3_write_pup_reg(PUP_DQS_RD, CS0, PUP_BC, 0, INIT_RL_DELAY); + + /* Set averaged PBS results */ + ddr3_set_pbs_results(dram_info, 0); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + DEBUG_PBS_FULL_S("DDR3 - PBS RX - ended successfuly\n"); + + return MV_OK; +} + +/* + * Name: ddr3_rx_shift_dqs_to_first_fail + * Desc: Execute the Rx shift DQ phase. + * Args: dram_info ddr3 training information struct + * cur_pup bit array of the function active pups. + * pbs_pattern_idx Index of PBS pattern + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup, + u32 pbs_pattern_idx, u32 ecc) +{ + u32 unlock_pup; /* bit array of unlock pups */ + u32 new_lockup_pup; /* bit array of compare failed pups */ + u32 adll_val = MAX_DELAY; + u32 dqs_deskew_val = 0; /* current value of DQS PBS deskew */ + u32 cur_max_pup, pup, pass_pup; + u32 *pattern_ptr; + + /* Choose pattern */ + switch (dram_info->ddr_width) { +#if defined(MV88F672X) + case 16: + pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx]; + break; +#endif + case 32: + pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx]; + break; +#if defined(MV88F78X60) + case 64: + pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx]; + break; +#endif + default: + return MV_FAIL; + } + + /* Set current pup number */ + if (cur_pup == 0x1) /* Ecc mode */ + cur_max_pup = 1; + else + cur_max_pup = dram_info->num_of_std_pups; + + unlock_pup = cur_pup; /* '1' for each unlocked pup */ + + DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Starting...\n"); + + /* Set DQS ADLL to MAX */ + DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Set DQS ADLL to Max for all PUPs\n"); + for (pup = 0; pup < cur_max_pup; pup++) + ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP, 0, + MAX_DELAY); + + /* Loop on all ADLL Vaules */ + do { + /* Loop until found fail for all pups */ + new_lockup_pup = 0; + if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, + &new_lockup_pup, + pattern_ptr, LEN_PBS_PATTERN, + SDRAM_PBS_I_OFFS + + pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS, + 0, 0, NULL, 0)) { + DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n"); + return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP; + } + + if ((new_lockup_pup != 0) && (dqs_deskew_val <= 1)) { + /* Fail on start with first deskew value */ + /* Decrement DQS ADLL */ + --adll_val; + if (adll_val == ADLL_MIN) { + DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - fail on start with first deskew value\n"); + return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP; + } + ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP, + 0, adll_val); + continue; + } + + /* Update all new locked pups */ + unlock_pup &= ~new_lockup_pup; + + if ((unlock_pup == 0) || (dqs_deskew_val == MAX_PBS)) { + if (dqs_deskew_val == MAX_PBS) { + /* + * Reach max value of dqs deskew or get fail + * for all pups + */ + DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - DQS deskew reached maximum value\n"); + } + break; + } + + DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Inc DQS deskew for PUPs: "); + DEBUG_PBS_FULL_D(unlock_pup, 2); + DEBUG_PBS_FULL_C(", deskew = ", dqs_deskew_val, 2); + + /* Increment DQS deskew elements - Only for unlocked pups */ + dqs_deskew_val++; + for (pup = 0; pup < cur_max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + ddr3_write_pup_reg(PUP_PBS_RX + DQS_DQ_NUM, CS0, + pup + ecc * ECC_PUP, 0, + dqs_deskew_val); + } + } + } while (1); + + DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - ADLL shift one step before fail\n"); + /* Continue to ADLL shift one step before fail */ + unlock_pup = cur_pup; + do { + /* Loop until pass compare for all pups */ + new_lockup_pup = 0; + /* Read and compare results */ + if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, &new_lockup_pup, + pattern_ptr, LEN_PBS_PATTERN, + SDRAM_PBS_I_OFFS + + pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS, + 1, 0, NULL, 0)) { + DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n"); + return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP; + } + + /* + * Get mask for pup which passed so their adll will be + * changed to 2 steps before fails + */ + pass_pup = unlock_pup & ~new_lockup_pup; + + DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: "); + DEBUG_PBS_FULL_D(pass_pup, 2); + DEBUG_PBS_FULL_C(", Set ADLL value = ", (adll_val - 2), 2); + + /* Only for pass pups */ + for (pup = 0; pup < cur_max_pup; pup++) { + if (IS_PUP_ACTIVE(pass_pup, pup) == 1) { + ddr3_write_pup_reg(PUP_DQS_RD, CS0, + pup + ecc * ECC_PUP, 0, + (adll_val - 2)); + } + } + + /* Locked pups that compare success */ + unlock_pup &= new_lockup_pup; + + if (unlock_pup == 0) { + /* All pups locked */ + break; + } + + /* Found error */ + if (adll_val == 0) { + DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift DQS - Adll reach min value\n"); + return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_MAX_VAL; + } + + /* + * Decrement (Move Back to Left one phase - ADLL) dqs RX delay + */ + adll_val--; + for (pup = 0; pup < cur_max_pup; pup++) { + if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { + ddr3_write_pup_reg(PUP_DQS_RD, CS0, + pup + ecc * ECC_PUP, 0, + adll_val); + } + } + } while (1); + + return MV_OK; +} + +/* + * lock_pups() extracted from ddr3_pbs_per_bit(). This just got too + * much indented making it hard to read / edit. + */ +static void lock_pups(u32 pup, u32 *pup_locked, u8 *unlock_pup_dq_array, + u32 pbs_curr_val, u32 start_pbs, u32 ecc, int is_tx) +{ + u32 dq; + int idx; + + /* Lock PBS value for all remaining PUPs bits */ + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Lock PBS value for all remaining PUPs bits, pup "); + DEBUG_PBS_FULL_D(pup, 1); + DEBUG_PBS_FULL_C(" pbs value ", pbs_curr_val, 2); + + idx = pup * (1 - ecc) + ecc * ECC_PUP; + *pup_locked &= ~(1 << pup); + + for (dq = 0; dq < DQ_NUM; dq++) { + if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) == 1) { + int offs; + + /* Lock current dq */ + unlock_pup_dq_array[dq] &= ~(1 << pup); + skew_array[(pup * DQ_NUM) + dq] = pbs_curr_val; + + if (is_tx == 1) + offs = PUP_PBS_TX; + else + offs = PUP_PBS_RX; + + ddr3_write_pup_reg(offs + + pbs_dq_mapping[idx][dq], CS0, + idx, 0, start_pbs); + } + } +} + +/* + * Name: ddr3_pbs_per_bit + * Desc: Execute the Per Bit Skew phase. + * Args: start_over Return whether need to start over the algorithm + * is_tx Indicate whether Rx or Tx + * pcur_pup bit array of the function active pups. return the + * pups that need to repeat on the PBS + * pbs_pattern_idx Index of PBS pattern + * + * Notes: Current implementation supports double activation of this function. + * i.e. in order to activate this function (using start_over) more than + * twice, the implementation should change. + * imlementation limitation are marked using + * ' CHIP-ONLY! - Implementation Limitation ' + * Returns: MV_OK if success, other error code if fail. + */ +static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx, + u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc) +{ + /* + * Bit array to indicate if we already get fail on bit per pup & dq bit + */ + u8 unlock_pup_dq_array[DQ_NUM] = { + *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup, + *pcur_pup, *pcur_pup, *pcur_pup + }; + + u8 cmp_unlock_pup_dq_array[COUNT_PBS_COMP_RETRY_NUM][DQ_NUM]; + u32 pup, dq; + /* value of pbs is according to RX or TX */ + u32 start_pbs, last_pbs; + u32 pbs_curr_val; + /* bit array that indicates all dq of the pup locked */ + u32 pup_locked; + u32 first_fail[MAX_PUP_NUM] = { 0 }; /* count first fail per pup */ + /* indicates whether we get first fail per pup */ + int first_failed[MAX_PUP_NUM] = { 0 }; + /* bit array that indicates pup already get fail */ + u32 sum_pup_fail; + /* use to calculate diff between curr pbs to first fail pbs */ + u32 calc_pbs_diff; + u32 pbs_cmp_retry; + u32 max_pup; + + /* Set init values for retry array - 8 retry */ + for (pbs_cmp_retry = 0; pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM; + pbs_cmp_retry++) { + for (dq = 0; dq < DQ_NUM; dq++) + cmp_unlock_pup_dq_array[pbs_cmp_retry][dq] = *pcur_pup; + } + + memset(&skew_array, 0, MAX_PUP_NUM * DQ_NUM * sizeof(u32)); + + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Started\n"); + + /* The pbs value depends if rx or tx */ + if (is_tx == 1) { + start_pbs = MIN_PBS; + last_pbs = MAX_PBS; + } else { + start_pbs = MAX_PBS; + last_pbs = MIN_PBS; + } + + pbs_curr_val = start_pbs; + pup_locked = *pcur_pup; + + /* Set current pup number */ + if (pup_locked == 0x1) /* Ecc mode */ + max_pup = 1; + else + max_pup = dram_info->num_of_std_pups; + + do { + /* Increment/ decrement PBS for un-lock bits only */ + if (is_tx == 1) + pbs_curr_val++; + else + pbs_curr_val--; + + /* Set Current PBS delay */ + for (dq = 0; dq < DQ_NUM; dq++) { + /* Check DQ bits to see if locked in all pups */ + if (unlock_pup_dq_array[dq] == 0) { + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All pups are locked for DQ "); + DEBUG_PBS_FULL_D(dq, 1); + DEBUG_PBS_FULL_S("\n"); + continue; + } + + for (pup = 0; pup < max_pup; pup++) { + int idx; + + idx = pup * (1 - ecc) + ecc * ECC_PUP; + + if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) + == 0) + continue; + + if (is_tx == 1) + ddr3_write_pup_reg( + PUP_PBS_TX + pbs_dq_mapping[idx][dq], + CS0, idx, 0, pbs_curr_val); + else + ddr3_write_pup_reg( + PUP_PBS_RX + pbs_dq_mapping[idx][dq], + CS0, idx, 0, pbs_curr_val); + } + } + + /* + * Write Read and compare results - run the test + * DDR_PBS_COMP_RETRY_NUM times + */ + /* Run number of read and write to verify */ + for (pbs_cmp_retry = 0; + pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM; + pbs_cmp_retry++) { + + if (MV_OK != + ddr3_sdram_pbs_compare(dram_info, pup_locked, is_tx, + pbs_pattern_idx, + pbs_curr_val, start_pbs, + skew_array, + cmp_unlock_pup_dq_array + [pbs_cmp_retry], ecc)) + return MV_FAIL; + + for (pup = 0; pup < max_pup; pup++) { + for (dq = 0; dq < DQ_NUM; dq++) { + if ((IS_PUP_ACTIVE(unlock_pup_dq_array[dq], + pup) == 1) + && (IS_PUP_ACTIVE(cmp_unlock_pup_dq_array + [pbs_cmp_retry][dq], + pup) == 0)) { + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PbsCurrVal: "); + DEBUG_PBS_FULL_D(pbs_curr_val, 2); + DEBUG_PBS_FULL_S(" PUP: "); + DEBUG_PBS_FULL_D(pup, 1); + DEBUG_PBS_FULL_S(" DQ: "); + DEBUG_PBS_FULL_D(dq, 1); + DEBUG_PBS_FULL_S(" - failed\n"); + } + } + } + + for (dq = 0; dq < DQ_NUM; dq++) { + unlock_pup_dq_array[dq] &= + cmp_unlock_pup_dq_array[pbs_cmp_retry][dq]; + } + } + + pup_locked = 0; + sum_pup_fail = *pcur_pup; + + /* Check which DQ is failed */ + for (dq = 0; dq < DQ_NUM; dq++) { + /* Summarize the locked pup */ + pup_locked |= unlock_pup_dq_array[dq]; + + /* Check if get fail */ + sum_pup_fail &= unlock_pup_dq_array[dq]; + } + + /* If all PUPS are locked in all DQ - Break */ + if (pup_locked == 0) { + /* All pups are locked */ + *start_over = 0; + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All bit in all pups are successfully locked\n"); + break; + } + + /* PBS deskew elements reach max ? */ + if (pbs_curr_val == last_pbs) { + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PBS deskew elements reach max\n"); + /* CHIP-ONLY! - Implementation Limitation */ + *start_over = (sum_pup_fail != 0) && (!(*start_over)); + *pcur_pup = pup_locked; + + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - StartOver: "); + DEBUG_PBS_FULL_D(*start_over, 1); + DEBUG_PBS_FULL_S(" pup_locked: "); + DEBUG_PBS_FULL_D(pup_locked, 2); + DEBUG_PBS_FULL_S(" sum_pup_fail: "); + DEBUG_PBS_FULL_D(sum_pup_fail, 2); + DEBUG_PBS_FULL_S("\n"); + + /* Lock PBS value for all remaining bits */ + for (pup = 0; pup < max_pup; pup++) { + /* Check if current pup already received error */ + if (IS_PUP_ACTIVE(pup_locked, pup) == 1) { + /* Valid pup for current function */ + if (IS_PUP_ACTIVE(sum_pup_fail, pup) == + 1 && (*start_over == 1)) { + DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - skipping lock of pup (first loop of pbs)", + pup, 1); + continue; + } else + if (IS_PUP_ACTIVE(sum_pup_fail, pup) + == 1) { + DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - Locking pup %d (even though it wasn't supposed to be locked)", + pup, 1); + } + + /* Already got fail on the PUP */ + /* Lock PBS value for all remaining bits */ + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Locking remaning DQs for pup - "); + DEBUG_PBS_FULL_D(pup, 1); + DEBUG_PBS_FULL_S(": "); + + for (dq = 0; dq < DQ_NUM; dq++) { + if (IS_PUP_ACTIVE + (unlock_pup_dq_array[dq], + pup) == 1) { + DEBUG_PBS_FULL_D(dq, 1); + DEBUG_PBS_FULL_S(","); + /* set current PBS */ + skew_array[((pup) * + DQ_NUM) + + dq] = + pbs_curr_val; + } + } + + if (*start_over == 1) { + /* + * Reset this pup bit - when + * restart the PBS, ignore this + * pup + */ + *pcur_pup &= ~(1 << pup); + } + DEBUG_PBS_FULL_S("\n"); + } else { + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Pup "); + DEBUG_PBS_FULL_D(pup, 1); + DEBUG_PBS_FULL_C(" is not set in puplocked - ", + pup_locked, 1); + } + } + + /* Need to start the PBS again */ + if (*start_over == 1) { + DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - false fail - returning to start\n"); + return MV_OK; + } + break; + } + + /* Diff Check */ + for (pup = 0; pup < max_pup; pup++) { + if (IS_PUP_ACTIVE(pup_locked, pup) == 1) { + /* pup is not locked */ + if (first_failed[pup] == 0) { + /* No first fail until now */ + if (IS_PUP_ACTIVE(sum_pup_fail, pup) == + 0) { + /* Get first fail */ + DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - First fail in pup ", + pup, 1); + first_failed[pup] = 1; + first_fail[pup] = pbs_curr_val; + } + } else { + /* Already got first fail */ + if (is_tx == 1) { + /* TX - inc pbs */ + calc_pbs_diff = pbs_curr_val - + first_fail[pup]; + } else { + /* RX - dec pbs */ + calc_pbs_diff = first_fail[pup] - + pbs_curr_val; + } + + if (calc_pbs_diff >= PBS_DIFF_LIMIT) { + lock_pups(pup, &pup_locked, + unlock_pup_dq_array, + pbs_curr_val, + start_pbs, ecc, is_tx); + } + } + } + } + } while (1); + + return MV_OK; +} + +/* + * Name: ddr3_set_pbs_results + * Desc: Set to HW the PBS phase results. + * Args: is_tx Indicates whether to set Tx or RX results + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx) +{ + u32 pup, phys_pup, dq; + u32 max_pup; /* number of valid pups */ + u32 pbs_min; /* minimal pbs val per pup */ + u32 pbs_max; /* maximum pbs val per pup */ + u32 val[9]; + + max_pup = dram_info->num_of_total_pups; + DEBUG_PBS_FULL_S("DDR3 - PBS - ddr3_set_pbs_results:\n"); + + /* Loop for all dqs & pups */ + for (pup = 0; pup < max_pup; pup++) { + if (pup == (max_pup - 1) && dram_info->ecc_ena) + phys_pup = ECC_PUP; + else + phys_pup = pup; + + /* + * To minimize delay elements, inc from pbs value the min + * pbs val + */ + pbs_min = MAX_PBS; + pbs_max = 0; + for (dq = 0; dq < DQ_NUM; dq++) { + if (pbs_min > skew_array[(pup * DQ_NUM) + dq]) + pbs_min = skew_array[(pup * DQ_NUM) + dq]; + + if (pbs_max < skew_array[(pup * DQ_NUM) + dq]) + pbs_max = skew_array[(pup * DQ_NUM) + dq]; + } + + pbs_max -= pbs_min; + + DEBUG_PBS_FULL_S("DDR3 - PBS - PUP"); + DEBUG_PBS_FULL_D(phys_pup, 1); + DEBUG_PBS_FULL_S(": Min Val = "); + DEBUG_PBS_FULL_D(pbs_min, 2); + DEBUG_PBS_FULL_C(", Max Val = ", pbs_max, 2); + + val[pup] = 0; + + for (dq = 0; dq < DQ_NUM; dq++) { + int idx; + int offs; + + /* Set skew value for all dq */ + /* + * Bit# Deskew <- Bit# Deskew - last / first + * failing bit Deskew For all bits (per PUP) + * (minimize delay elements) + */ + + DEBUG_PBS_FULL_S("DQ"); + DEBUG_PBS_FULL_D(dq, 1); + DEBUG_PBS_FULL_S("-"); + DEBUG_PBS_FULL_D((skew_array[(pup * DQ_NUM) + dq] - + pbs_min), 2); + DEBUG_PBS_FULL_S(", "); + + idx = (pup * DQ_NUM) + dq; + + if (is_tx == 1) + offs = PUP_PBS_TX; + else + offs = PUP_PBS_RX; + + ddr3_write_pup_reg(offs + pbs_dq_mapping[phys_pup][dq], + CS0, phys_pup, 0, + skew_array[idx] - pbs_min); + + if (is_tx == 1) + val[pup] += skew_array[idx] - pbs_min; + } + + DEBUG_PBS_FULL_S("\n"); + + /* Set the DQS the half of the Max PBS of the DQs */ + if (is_tx == 1) { + ddr3_write_pup_reg(PUP_PBS_TX + 8, CS0, phys_pup, 0, + pbs_max / 2); + ddr3_write_pup_reg(PUP_PBS_TX + 0xa, CS0, phys_pup, 0, + val[pup] / 8); + } else + ddr3_write_pup_reg(PUP_PBS_RX + 8, CS0, phys_pup, 0, + pbs_max / 2); + } + + return MV_OK; +} + +static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay) +{ + u32 reg, delay; + + reg = (ddr3_read_pup_reg(PUP_WL_MODE, cs, pup) & 0x3FF); + delay = reg & PUP_DELAY_MASK; + reg |= ((dqs_delay + delay) << REG_PHY_DQS_REF_DLY_OFFS); + reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + reg |= (pup << REG_PHY_PUP_OFFS); + reg |= ((0x4 * cs + PUP_WL_MODE) << REG_PHY_CS_OFFS); + + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + do { + reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); /* Wait for '0' to mark the end of the transaction */ + + udelay(10); +} + +/* + * Set training patterns + */ +int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info) +{ + u32 cs, cs_count, cs_tmp; + u32 sdram_addr; + u32 *pattern_ptr0, *pattern_ptr1; + + /* Choose pattern */ + switch (dram_info->ddr_width) { +#if defined(MV88F672X) + case 16: + pattern_ptr0 = (u32 *)&pbs_pattern[0]; + pattern_ptr1 = (u32 *)&pbs_pattern[1]; + break; +#endif + case 32: + pattern_ptr0 = (u32 *)&pbs_pattern_32b[0]; + pattern_ptr1 = (u32 *)&pbs_pattern_32b[1]; + break; +#if defined(MV88F78X60) + case 64: + pattern_ptr0 = (u32 *)&pbs_pattern_64b[0]; + pattern_ptr1 = (u32 *)&pbs_pattern_64b[1]; + break; +#endif + default: + return MV_FAIL; + } + + /* Loop for each CS */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + cs_count = 0; + for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) { + if (dram_info->cs_ena & (1 << cs_tmp)) + cs_count++; + } + + /* Init PBS I pattern */ + sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + + SDRAM_PBS_I_OFFS); + if (MV_OK != + ddr3_sdram_compare(dram_info, (u32) NULL, NULL, + pattern_ptr0, LEN_STD_PATTERN, + sdram_addr, 1, 0, NULL, + 0)) + return MV_FAIL; + + /* Init PBS II pattern */ + sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + + SDRAM_PBS_II_OFFS); + if (MV_OK != + ddr3_sdram_compare(dram_info, (u32) NULL, NULL, + pattern_ptr1, LEN_STD_PATTERN, + sdram_addr, 1, 0, NULL, + 0)) + return MV_FAIL; + } + } + + return MV_OK; +} +#endif diff --git a/drivers/ddr/mvebu/ddr3_read_leveling.c b/drivers/ddr/mvebu/ddr3_read_leveling.c new file mode 100644 index 0000000000..4662bde994 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_read_leveling.c @@ -0,0 +1,1214 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" + +/* + * Debug + */ +#define DEBUG_RL_C(s, d, l) \ + DEBUG_RL_S(s); DEBUG_RL_D(d, l); DEBUG_RL_S("\n") +#define DEBUG_RL_FULL_C(s, d, l) \ + DEBUG_RL_FULL_S(s); DEBUG_RL_FULL_D(d, l); DEBUG_RL_FULL_S("\n") + +#ifdef MV_DEBUG_RL +#define DEBUG_RL_S(s) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s) +#define DEBUG_RL_D(d, l) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d) +#else +#define DEBUG_RL_S(s) +#define DEBUG_RL_D(d, l) +#endif + +#ifdef MV_DEBUG_RL_FULL +#define DEBUG_RL_FULL_S(s) puts(s) +#define DEBUG_RL_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_RL_FULL_S(s) +#define DEBUG_RL_FULL_D(d, l) +#endif + +extern u32 rl_pattern[LEN_STD_PATTERN]; + +#ifdef RL_MODE +static int ddr3_read_leveling_single_cs_rl_mode(u32 cs, u32 freq, + int ratio_2to1, u32 ecc, + MV_DRAM_INFO *dram_info); +#else +static int ddr3_read_leveling_single_cs_window_mode(u32 cs, u32 freq, + int ratio_2to1, u32 ecc, + MV_DRAM_INFO *dram_info); +#endif + +/* + * Name: ddr3_read_leveling_hw + * Desc: Execute the Read leveling phase by HW + * Args: dram_info - main struct + * freq - current sequence frequency + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_read_leveling_hw(u32 freq, MV_DRAM_INFO *dram_info) +{ + u32 reg; + + /* Debug message - Start Read leveling procedure */ + DEBUG_RL_S("DDR3 - Read Leveling - Starting HW RL procedure\n"); + + /* Start Auto Read Leveling procedure */ + reg = 1 << REG_DRAM_TRAINING_RL_OFFS; + /* Config the retest number */ + reg |= (COUNT_HW_RL << REG_DRAM_TRAINING_RETEST_OFFS); + + /* Enable CS in the automatic process */ + reg |= (dram_info->cs_ena << REG_DRAM_TRAINING_CS_OFFS); + + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) | + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_SHADOW_ADDR, reg); + + /* Wait */ + do { + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) & + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + } while (reg); /* Wait for '0' */ + + /* Check if Successful */ + if (reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) & + (1 << REG_DRAM_TRAINING_ERROR_OFFS)) { + u32 delay, phase, pup, cs; + + dram_info->rl_max_phase = 0; + dram_info->rl_min_phase = 10; + + /* Read results to arrays */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_PUP; + reg = + ddr3_read_pup_reg(PUP_RL_MODE, cs, + pup); + phase = (reg >> REG_PHY_PHASE_OFFS) & + PUP_PHASE_MASK; + delay = reg & PUP_DELAY_MASK; + dram_info->rl_val[cs][pup][P] = phase; + if (phase > dram_info->rl_max_phase) + dram_info->rl_max_phase = phase; + if (phase < dram_info->rl_min_phase) + dram_info->rl_min_phase = phase; + dram_info->rl_val[cs][pup][D] = delay; + dram_info->rl_val[cs][pup][S] = + RL_FINAL_STATE; + reg = + ddr3_read_pup_reg(PUP_RL_MODE + 0x1, + cs, pup); + dram_info->rl_val[cs][pup][DQS] = + (reg & 0x3F); + } +#ifdef MV_DEBUG_RL + /* Print results */ + DEBUG_RL_C("DDR3 - Read Leveling - Results for CS - ", + (u32) cs, 1); + + for (pup = 0; + pup < (dram_info->num_of_total_pups); + pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_PUP; + DEBUG_RL_S("DDR3 - Read Leveling - PUP: "); + DEBUG_RL_D((u32) pup, 1); + DEBUG_RL_S(", Phase: "); + DEBUG_RL_D((u32) dram_info-> + rl_val[cs][pup][P], 1); + DEBUG_RL_S(", Delay: "); + DEBUG_RL_D((u32) dram_info-> + rl_val[cs][pup][D], 2); + DEBUG_RL_S("\n"); + } +#endif + } + } + + dram_info->rd_rdy_dly = + reg_read(REG_READ_DATA_READY_DELAYS_ADDR) & + REG_READ_DATA_SAMPLE_DELAYS_MASK; + dram_info->rd_smpl_dly = + reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR) & + REG_READ_DATA_READY_DELAYS_MASK; +#ifdef MV_DEBUG_RL + DEBUG_RL_C("DDR3 - Read Leveling - Read Sample Delay: ", + dram_info->rd_smpl_dly, 2); + DEBUG_RL_C("DDR3 - Read Leveling - Read Ready Delay: ", + dram_info->rd_rdy_dly, 2); + DEBUG_RL_S("DDR3 - Read Leveling - HW RL Ended Successfully\n"); +#endif + return MV_OK; + + } else { + DEBUG_RL_S("DDR3 - Read Leveling - HW RL Error\n"); + return MV_FAIL; + } +} + +/* + * Name: ddr3_read_leveling_sw + * Desc: Execute the Read leveling phase by SW + * Args: dram_info - main struct + * freq - current sequence frequency + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_read_leveling_sw(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info) +{ + u32 reg, cs, ecc, pup_num, phase, delay, pup; + int status; + + /* Debug message - Start Read leveling procedure */ + DEBUG_RL_S("DDR3 - Read Leveling - Starting SW RL procedure\n"); + + /* Enable SW Read Leveling */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + reg &= ~(1 << REG_DRAM_TRAINING_2_RL_MODE_OFFS); + /* [0]=1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + +#ifdef RL_MODE + reg = (dram_info->cs_ena << REG_DRAM_TRAINING_CS_OFFS) | + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ +#endif + + /* Loop for each CS */ + for (cs = 0; cs < dram_info->num_cs; cs++) { + DEBUG_RL_C("DDR3 - Read Leveling - CS - ", (u32) cs, 1); + + for (ecc = 0; ecc <= (dram_info->ecc_ena); ecc++) { + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg |= (dram_info->ecc_ena * + ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + if (ecc) + DEBUG_RL_S("DDR3 - Read Leveling - ECC Mux Enabled\n"); + else + DEBUG_RL_S("DDR3 - Read Leveling - ECC Mux Disabled\n"); + + /* Set current sample delays */ + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + reg |= (dram_info->cl << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg); + + /* Set current Ready delay */ + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + if (!ratio_2to1) { + /* 1:1 mode */ + reg |= ((dram_info->cl + 1) << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + } else { + /* 2:1 mode */ + reg |= ((dram_info->cl + 2) << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + } + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + + /* Read leveling Single CS[cs] */ +#ifdef RL_MODE + status = + ddr3_read_leveling_single_cs_rl_mode(cs, freq, + ratio_2to1, + ecc, + dram_info); + if (MV_OK != status) + return status; +#else + status = + ddr3_read_leveling_single_cs_window_mode(cs, freq, + ratio_2to1, + ecc, + dram_info) + if (MV_OK != status) + return status; +#endif + } + + /* Print results */ + DEBUG_RL_C("DDR3 - Read Leveling - Results for CS - ", (u32) cs, + 1); + + for (pup = 0; + pup < (dram_info->num_of_std_pups + dram_info->ecc_ena); + pup++) { + DEBUG_RL_S("DDR3 - Read Leveling - PUP: "); + DEBUG_RL_D((u32) pup, 1); + DEBUG_RL_S(", Phase: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][P], 1); + DEBUG_RL_S(", Delay: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][D], 2); + DEBUG_RL_S("\n"); + } + + DEBUG_RL_C("DDR3 - Read Leveling - Read Sample Delay: ", + dram_info->rd_smpl_dly, 2); + DEBUG_RL_C("DDR3 - Read Leveling - Read Ready Delay: ", + dram_info->rd_rdy_dly, 2); + + /* Configure PHY with average of 3 locked leveling settings */ + for (pup = 0; + pup < (dram_info->num_of_std_pups + dram_info->ecc_ena); + pup++) { + /* ECC support - bit 8 */ + pup_num = (pup == dram_info->num_of_std_pups) ? ECC_BIT : pup; + + /* For now, set last cnt result */ + phase = dram_info->rl_val[cs][pup][P]; + delay = dram_info->rl_val[cs][pup][D]; + ddr3_write_pup_reg(PUP_RL_MODE, cs, pup_num, phase, + delay); + } + } + + /* Reset PHY read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + do { + reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) & + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + } while (reg); /* Wait for '0' */ + + /* ECC Support - Switch ECC Mux off ecc=0 */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + +#ifdef RL_MODE + reg_write(REG_DRAM_TRAINING_ADDR, 0); /* 0x15B0 - Training Register */ +#endif + + /* Disable SW Read Leveling */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* [0] = 0 - Disable SW override */ + reg = (reg | (0x1 << REG_DRAM_TRAINING_2_RL_MODE_OFFS)); + /* [3] = 1 - Disable RL MODE */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + DEBUG_RL_S("DDR3 - Read Leveling - Finished RL procedure for all CS\n"); + return MV_OK; +} + +#ifdef RL_MODE +/* + * overrun() extracted from ddr3_read_leveling_single_cs_rl_mode(). + * This just got too much indented making it hard to read / edit. + */ +static void overrun(u32 cs, MV_DRAM_INFO *info, u32 pup, u32 locked_pups, + u32 *locked_sum, u32 ecc, int *first_octet_locked, + int *counter_in_progress, int final_delay, u32 delay, + u32 phase) +{ + /* If no OverRun */ + if (((~locked_pups >> pup) & 0x1) && (final_delay == 0)) { + int idx; + + idx = pup + ecc * ECC_BIT; + + /* PUP passed, start examining */ + if (info->rl_val[cs][idx][S] == RL_UNLOCK_STATE) { + /* Must be RL_UNLOCK_STATE */ + /* Match expected value ? - Update State Machine */ + if (info->rl_val[cs][idx][C] < RL_RETRY_COUNT) { + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have no overrun and a match on pup: ", + (u32)pup, 1); + info->rl_val[cs][idx][C]++; + + /* If pup got to last state - lock the delays */ + if (info->rl_val[cs][idx][C] == RL_RETRY_COUNT) { + info->rl_val[cs][idx][C] = 0; + info->rl_val[cs][idx][DS] = delay; + info->rl_val[cs][idx][PS] = phase; + + /* Go to Final State */ + info->rl_val[cs][idx][S] = RL_FINAL_STATE; + *locked_sum = *locked_sum + 1; + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have locked pup: ", + (u32)pup, 1); + + /* + * If first lock - need to lock delays + */ + if (*first_octet_locked == 0) { + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got first lock on pup: ", + (u32)pup, 1); + *first_octet_locked = 1; + } + + /* + * If pup is in not in final state but + * there was match - dont increment + * counter + */ + } else { + *counter_in_progress = 1; + } + } + } + } +} + +/* + * Name: ddr3_read_leveling_single_cs_rl_mode + * Desc: Execute Read leveling for single Chip select + * Args: cs - current chip select + * freq - current sequence frequency + * ecc - ecc iteration indication + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +static int ddr3_read_leveling_single_cs_rl_mode(u32 cs, u32 freq, + int ratio_2to1, u32 ecc, + MV_DRAM_INFO *dram_info) +{ + u32 reg, delay, phase, pup, rd_sample_delay, add, locked_pups, + repeat_max_cnt, sdram_offset, locked_sum; + u32 phase_min, ui_max_delay; + int all_locked, first_octet_locked, counter_in_progress; + int final_delay = 0; + + DEBUG_RL_FULL_C("DDR3 - Read Leveling - Single CS - ", (u32) cs, 1); + + /* Init values */ + phase = 0; + delay = 0; + rd_sample_delay = dram_info->cl; + all_locked = 0; + first_octet_locked = 0; + repeat_max_cnt = 0; + locked_sum = 0; + + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); + pup++) + dram_info->rl_val[cs][pup + ecc * ECC_BIT][S] = 0; + + /* Main loop */ + while (!all_locked) { + counter_in_progress = 0; + + DEBUG_RL_FULL_S("DDR3 - Read Leveling - RdSmplDly = "); + DEBUG_RL_FULL_D(rd_sample_delay, 2); + DEBUG_RL_FULL_S(", RdRdyDly = "); + DEBUG_RL_FULL_D(dram_info->rd_rdy_dly, 2); + DEBUG_RL_FULL_S(", Phase = "); + DEBUG_RL_FULL_D(phase, 1); + DEBUG_RL_FULL_S(", Delay = "); + DEBUG_RL_FULL_D(delay, 2); + DEBUG_RL_FULL_S("\n"); + + /* + * Broadcast to all PUPs current RL delays: DQS phase, + * leveling delay + */ + ddr3_write_pup_reg(PUP_RL_MODE, cs, PUP_BC, phase, delay); + + /* Reset PHY read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + do { + reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) & + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + } while (reg); /* Wait for '0' */ + + /* Read pattern from SDRAM */ + sdram_offset = cs * (SDRAM_CS_SIZE + 1) + SDRAM_RL_OFFS; + locked_pups = 0; + if (MV_OK != + ddr3_sdram_compare(dram_info, 0xFF, &locked_pups, + rl_pattern, LEN_STD_PATTERN, + sdram_offset, 0, 0, NULL, 0)) + return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PATTERN; + + /* Octet evaluation */ + /* pup_num = Q or 1 for ECC */ + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) { + /* Check Overrun */ + if (!((reg_read(REG_DRAM_TRAINING_2_ADDR) >> + (REG_DRAM_TRAINING_2_OVERRUN_OFFS + pup)) & 0x1)) { + overrun(cs, dram_info, pup, locked_pups, + &locked_sum, ecc, &first_octet_locked, + &counter_in_progress, final_delay, + delay, phase); + } else { + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got overrun on pup: ", + (u32)pup, 1); + } + } + + if (locked_sum == (dram_info->num_of_std_pups * + (1 - ecc) + ecc)) { + all_locked = 1; + DEBUG_RL_FULL_S("DDR3 - Read Leveling - Single Cs - All pups locked\n"); + } + + /* + * This is a fix for unstable condition where pups are + * toggling between match and no match + */ + /* + * If some of the pups is >1 <3, check if we did it too + * many times + */ + if (counter_in_progress == 1) { + /* Notify at least one Counter is >=1 and < 3 */ + if (repeat_max_cnt < RL_RETRY_COUNT) { + repeat_max_cnt++; + counter_in_progress = 1; + DEBUG_RL_FULL_S("DDR3 - Read Leveling - Counter is >=1 and <3\n"); + DEBUG_RL_FULL_S("DDR3 - Read Leveling - So we will not increment the delay to see if locked again\n"); + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - repeat_max_cnt reached max so now we will increment the delay\n"); + counter_in_progress = 0; + } + } + + /* + * Check some of the pups are in the middle of state machine + * and don't increment the delays + */ + if (!counter_in_progress && !all_locked) { + int idx; + + idx = pup + ecc * ECC_BIT; + + repeat_max_cnt = 0; + /* if 1:1 mode */ + if ((!ratio_2to1) && ((phase == 0) || (phase == 4))) + ui_max_delay = MAX_DELAY_INV; + else + ui_max_delay = MAX_DELAY; + + /* Increment Delay */ + if (delay < ui_max_delay) { + delay++; + /* + * Mark the last delay/pahse place for + * window final place + */ + if (delay == ui_max_delay) { + if ((!ratio_2to1 && phase == + MAX_PHASE_RL_L_1TO1) + || (ratio_2to1 && phase == + MAX_PHASE_RL_L_2TO1)) + final_delay = 1; + } + } else { + /* Phase+CL Incrementation */ + delay = 0; + + if (!ratio_2to1) { + /* 1:1 mode */ + if (first_octet_locked) { + /* some Pup was Locked */ + if (phase < MAX_PHASE_RL_L_1TO1) { + if (phase == 1) { + phase = 4; + } else { + phase++; + delay = MIN_DELAY_PHASE_1_LIMIT; + } + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + DEBUG_RL_S("1)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked n"); + return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PUP_UNLOCK; + } + } else { + /* NO Pup was Locked */ + if (phase < MAX_PHASE_RL_UL_1TO1) { + phase++; + delay = + MIN_DELAY_PHASE_1_LIMIT; + } else { + phase = 0; + } + } + } else { + /* 2:1 mode */ + if (first_octet_locked) { + /* some Pup was Locked */ + if (phase < MAX_PHASE_RL_L_2TO1) { + phase++; + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + DEBUG_RL_S("2)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) { + /* pup_num = Q or 1 for ECC */ + if (dram_info->rl_val[cs][idx][S] + == 0) { + DEBUG_RL_C("Failed byte is = ", + pup, 1); + } + } + return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PUP_UNLOCK; + } + } else { + /* No Pup was Locked */ + if (phase < MAX_PHASE_RL_UL_2TO1) + phase++; + else + phase = 0; + } + } + + /* + * If we finished a full Phases cycle (so now + * phase = 0, need to increment rd_sample_dly + */ + if (phase == 0 && first_octet_locked == 0) { + rd_sample_delay++; + if (rd_sample_delay == 0x10) { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + DEBUG_RL_S("3)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) { + /* pup_num = Q or 1 for ECC */ + if (dram_info-> + rl_val[cs][idx][S] == 0) { + DEBUG_RL_C("Failed byte is = ", + pup, 1); + } + } + return MV_DDR3_TRAINING_ERR_RD_LVL_PUP_UNLOCK; + } + + /* Set current rd_sample_delay */ + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK + << (REG_READ_DATA_SAMPLE_DELAYS_OFFS + * cs)); + reg |= (rd_sample_delay << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * + cs)); + reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, + reg); + } + + /* + * Set current rdReadyDelay according to the + * hash table (Need to do this in every phase + * change) + */ + if (!ratio_2to1) { + /* 1:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_2_ADDR); + switch (phase) { + case 0: + add = (add >> + REG_TRAINING_DEBUG_2_OFFS); + break; + case 1: + add = (add >> + (REG_TRAINING_DEBUG_2_OFFS + + 3)); + break; + case 4: + add = (add >> + (REG_TRAINING_DEBUG_2_OFFS + + 6)); + break; + case 5: + add = (add >> + (REG_TRAINING_DEBUG_2_OFFS + + 9)); + break; + } + add &= REG_TRAINING_DEBUG_2_MASK; + } else { + /* 2:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_3_ADDR); + add = (add >> + (phase * + REG_TRAINING_DEBUG_3_OFFS)); + add &= REG_TRAINING_DEBUG_3_MASK; + } + + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= ((rd_sample_delay + add) << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + dram_info->rd_smpl_dly = rd_sample_delay; + dram_info->rd_rdy_dly = rd_sample_delay + add; + } + + /* Reset counters for pups with statesnum_of_std_pups * (1 - ecc) + ecc); + pup++) { + if (dram_info->rl_val[cs][idx][C] < RL_RETRY_COUNT) + dram_info->rl_val[cs][idx][C] = 0; + } + } + } + + phase_min = 10; + + for (pup = 0; pup < (dram_info->num_of_std_pups); pup++) { + if (dram_info->rl_val[cs][pup][PS] < phase_min) + phase_min = dram_info->rl_val[cs][pup][PS]; + } + + /* + * Set current rdReadyDelay according to the hash table (Need to + * do this in every phase change) + */ + if (!ratio_2to1) { + /* 1:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_2_ADDR); + switch (phase_min) { + case 0: + add = (add >> REG_TRAINING_DEBUG_2_OFFS); + break; + case 1: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 3)); + break; + case 4: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 6)); + break; + case 5: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 9)); + break; + } + add &= REG_TRAINING_DEBUG_2_MASK; + } else { + /* 2:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_3_ADDR); + add = (add >> (phase_min * REG_TRAINING_DEBUG_3_OFFS)); + add &= REG_TRAINING_DEBUG_3_MASK; + } + + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= ((rd_sample_delay + add) << (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + dram_info->rd_rdy_dly = rd_sample_delay + add; + + for (cs = 0; cs < dram_info->num_cs; cs++) { + for (pup = 0; pup < dram_info->num_of_total_pups; pup++) { + reg = ddr3_read_pup_reg(PUP_RL_MODE + 0x1, cs, pup); + dram_info->rl_val[cs][pup][DQS] = (reg & 0x3F); + } + } + + return MV_OK; +} + +#else + +/* + * Name: ddr3_read_leveling_single_cs_window_mode + * Desc: Execute Read leveling for single Chip select + * Args: cs - current chip select + * freq - current sequence frequency + * ecc - ecc iteration indication + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +static int ddr3_read_leveling_single_cs_window_mode(u32 cs, u32 freq, + int ratio_2to1, u32 ecc, + MV_DRAM_INFO *dram_info) +{ + u32 reg, delay, phase, sum, pup, rd_sample_delay, add, locked_pups, + repeat_max_cnt, sdram_offset, final_sum, locked_sum; + u32 delay_s, delay_e, tmp, phase_min, ui_max_delay; + int all_locked, first_octet_locked, counter_in_progress; + int final_delay = 0; + + DEBUG_RL_FULL_C("DDR3 - Read Leveling - Single CS - ", (u32) cs, 1); + + /* Init values */ + phase = 0; + delay = 0; + rd_sample_delay = dram_info->cl; + all_locked = 0; + first_octet_locked = 0; + repeat_max_cnt = 0; + sum = 0; + final_sum = 0; + locked_sum = 0; + + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); + pup++) + dram_info->rl_val[cs][pup + ecc * ECC_BIT][S] = 0; + + /* Main loop */ + while (!all_locked) { + counter_in_progress = 0; + + DEBUG_RL_FULL_S("DDR3 - Read Leveling - RdSmplDly = "); + DEBUG_RL_FULL_D(rd_sample_delay, 2); + DEBUG_RL_FULL_S(", RdRdyDly = "); + DEBUG_RL_FULL_D(dram_info->rd_rdy_dly, 2); + DEBUG_RL_FULL_S(", Phase = "); + DEBUG_RL_FULL_D(phase, 1); + DEBUG_RL_FULL_S(", Delay = "); + DEBUG_RL_FULL_D(delay, 2); + DEBUG_RL_FULL_S("\n"); + + /* + * Broadcast to all PUPs current RL delays: DQS phase,leveling + * delay + */ + ddr3_write_pup_reg(PUP_RL_MODE, cs, PUP_BC, phase, delay); + + /* Reset PHY read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + do { + reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) & + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + } while (reg); /* Wait for '0' */ + + /* Read pattern from SDRAM */ + sdram_offset = cs * (SDRAM_CS_SIZE + 1) + SDRAM_RL_OFFS; + locked_pups = 0; + if (MV_OK != + ddr3_sdram_compare(dram_info, 0xFF, &locked_pups, + rl_pattern, LEN_STD_PATTERN, + sdram_offset, 0, 0, NULL, 0)) + return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PATTERN; + + /* Octet evaluation */ + for (pup = 0; pup < (dram_info->num_of_std_pups * + (1 - ecc) + ecc); pup++) { + /* pup_num = Q or 1 for ECC */ + int idx; + + idx = pup + ecc * ECC_BIT; + + /* Check Overrun */ + if (!((reg_read(REG_DRAM_TRAINING_2_ADDR) >> + (REG_DRAM_TRAINING_2_OVERRUN_OFFS + + pup)) & 0x1)) { + /* If no OverRun */ + + /* Inside the window */ + if (dram_info->rl_val[cs][idx][S] == RL_WINDOW_STATE) { + /* + * Match expected value ? - Update + * State Machine + */ + if (((~locked_pups >> pup) & 0x1) + && (final_delay == 0)) { + /* Match - Still inside the Window */ + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got another match inside the window for pup: ", + (u32)pup, 1); + + } else { + /* We got fail -> this is the end of the window */ + dram_info->rl_val[cs][idx][DE] = delay; + dram_info->rl_val[cs][idx][PE] = phase; + /* Go to Final State */ + dram_info->rl_val[cs][idx][S]++; + final_sum++; + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We finished the window for pup: ", + (u32)pup, 1); + } + + /* Before the start of the window */ + } else if (dram_info->rl_val[cs][idx][S] == + RL_UNLOCK_STATE) { + /* Must be RL_UNLOCK_STATE */ + /* + * Match expected value ? - Update + * State Machine + */ + if (dram_info->rl_val[cs][idx][C] < + RL_RETRY_COUNT) { + if (((~locked_pups >> pup) & 0x1)) { + /* Match */ + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have no overrun and a match on pup: ", + (u32)pup, 1); + dram_info->rl_val[cs][idx][C]++; + + /* If pup got to last state - lock the delays */ + if (dram_info->rl_val[cs][idx][C] == + RL_RETRY_COUNT) { + dram_info->rl_val[cs][idx][C] = 0; + dram_info->rl_val[cs][idx][DS] = + delay; + dram_info->rl_val[cs][idx][PS] = + phase; + dram_info->rl_val[cs][idx][S]++; /* Go to Window State */ + locked_sum++; + /* Will count the pups that got locked */ + + /* IF First lock - need to lock delays */ + if (first_octet_locked == 0) { + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got first lock on pup: ", + (u32)pup, 1); + first_octet_locked + = + 1; + } + } + + /* if pup is in not in final state but there was match - dont increment counter */ + else { + counter_in_progress + = 1; + } + } + } + } + } else { + DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got overrun on pup: ", + (u32)pup, 1); + counter_in_progress = 1; + } + } + + if (final_sum == (dram_info->num_of_std_pups * (1 - ecc) + ecc)) { + all_locked = 1; + DEBUG_RL_FULL_S("DDR3 - Read Leveling - Single Cs - All pups locked\n"); + } + + /* + * This is a fix for unstable condition where pups are + * toggling between match and no match + */ + /* + * If some of the pups is >1 <3, check if we did it too many + * times + */ + if (counter_in_progress == 1) { + if (repeat_max_cnt < RL_RETRY_COUNT) { + /* Notify at least one Counter is >=1 and < 3 */ + repeat_max_cnt++; + counter_in_progress = 1; + DEBUG_RL_FULL_S("DDR3 - Read Leveling - Counter is >=1 and <3\n"); + DEBUG_RL_FULL_S("DDR3 - Read Leveling - So we will not increment the delay to see if locked again\n"); + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - repeat_max_cnt reached max so now we will increment the delay\n"); + counter_in_progress = 0; + } + } + + /* + * Check some of the pups are in the middle of state machine + * and don't increment the delays + */ + if (!counter_in_progress && !all_locked) { + repeat_max_cnt = 0; + if (!ratio_2to1) + ui_max_delay = MAX_DELAY_INV; + else + ui_max_delay = MAX_DELAY; + + /* Increment Delay */ + if (delay < ui_max_delay) { + /* Delay Incrementation */ + delay++; + if (delay == ui_max_delay) { + /* + * Mark the last delay/pahse place + * for window final place + */ + if ((!ratio_2to1 + && phase == MAX_PHASE_RL_L_1TO1) + || (ratio_2to1 + && phase == + MAX_PHASE_RL_L_2TO1)) + final_delay = 1; + } + } else { + /* Phase+CL Incrementation */ + delay = 0; + if (!ratio_2to1) { + /* 1:1 mode */ + if (first_octet_locked) { + /* some pupet was Locked */ + if (phase < MAX_PHASE_RL_L_1TO1) { +#ifdef RL_WINDOW_WA + if (phase == 0) +#else + if (phase == 1) +#endif + phase = 4; + else + phase++; + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PUP_UNLOCK; + } + } else { + /* No Pup was Locked */ + if (phase < MAX_PHASE_RL_UL_1TO1) { +#ifdef RL_WINDOW_WA + if (phase == 0) + phase = 4; +#else + phase++; +#endif + } else + phase = 0; + } + } else { + /* 2:1 mode */ + if (first_octet_locked) { + /* Some Pup was Locked */ + if (phase < MAX_PHASE_RL_L_2TO1) { + phase++; + } else { + DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n"); + return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PUP_UNLOCK; + } + } else { + /* No Pup was Locked */ + if (phase < MAX_PHASE_RL_UL_2TO1) + phase++; + else + phase = 0; + } + } + + /* + * If we finished a full Phases cycle (so + * now phase = 0, need to increment + * rd_sample_dly + */ + if (phase == 0 && first_octet_locked == 0) { + rd_sample_delay++; + + /* Set current rd_sample_delay */ + reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS + * cs)); + reg |= (rd_sample_delay << + (REG_READ_DATA_SAMPLE_DELAYS_OFFS * + cs)); + reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, + reg); + } + + /* + * Set current rdReadyDelay according to the + * hash table (Need to do this in every phase + * change) + */ + if (!ratio_2to1) { + /* 1:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_2_ADDR); + switch (phase) { + case 0: + add = add >> + REG_TRAINING_DEBUG_2_OFFS; + break; + case 1: + add = add >> + (REG_TRAINING_DEBUG_2_OFFS + + 3); + break; + case 4: + add = add >> + (REG_TRAINING_DEBUG_2_OFFS + + 6); + break; + case 5: + add = add >> + (REG_TRAINING_DEBUG_2_OFFS + + 9); + break; + } + } else { + /* 2:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_3_ADDR); + add = (add >> phase * + REG_TRAINING_DEBUG_3_OFFS); + } + add &= REG_TRAINING_DEBUG_2_MASK; + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= ((rd_sample_delay + add) << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + dram_info->rd_smpl_dly = rd_sample_delay; + dram_info->rd_rdy_dly = rd_sample_delay + add; + } + + /* Reset counters for pups with statesnum_of_std_pups * (1 - ecc) + ecc); + pup++) { + if (dram_info->rl_val[cs][idx][C] < RL_RETRY_COUNT) + dram_info->rl_val[cs][idx][C] = 0; + } + } + } + + phase_min = 10; + + for (pup = 0; pup < (dram_info->num_of_std_pups); pup++) { + DEBUG_RL_S("DDR3 - Read Leveling - Window info - PUP: "); + DEBUG_RL_D((u32) pup, 1); + DEBUG_RL_S(", PS: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][PS], 1); + DEBUG_RL_S(", DS: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][DS], 2); + DEBUG_RL_S(", PE: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][PE], 1); + DEBUG_RL_S(", DE: "); + DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][DE], 2); + DEBUG_RL_S("\n"); + } + + /* Find center of the window procedure */ + for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); + pup++) { +#ifdef RL_WINDOW_WA + if (!ratio_2to1) { /* 1:1 mode */ + if (dram_info->rl_val[cs][idx][PS] == 4) + dram_info->rl_val[cs][idx][PS] = 1; + if (dram_info->rl_val[cs][idx][PE] == 4) + dram_info->rl_val[cs][idx][PE] = 1; + + delay_s = dram_info->rl_val[cs][idx][PS] * + MAX_DELAY_INV + dram_info->rl_val[cs][idx][DS]; + delay_e = dram_info->rl_val[cs][idx][PE] * + MAX_DELAY_INV + dram_info->rl_val[cs][idx][DE]; + + tmp = (delay_e - delay_s) / 2 + delay_s; + phase = tmp / MAX_DELAY_INV; + if (phase == 1) /* 1:1 mode */ + phase = 4; + + if (phase < phase_min) /* for the read ready delay */ + phase_min = phase; + + dram_info->rl_val[cs][idx][P] = phase; + dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY_INV; + + } else { + delay_s = dram_info->rl_val[cs][idx][PS] * + MAX_DELAY + dram_info->rl_val[cs][idx][DS]; + delay_e = dram_info->rl_val[cs][idx][PE] * + MAX_DELAY + dram_info->rl_val[cs][idx][DE]; + + tmp = (delay_e - delay_s) / 2 + delay_s; + phase = tmp / MAX_DELAY; + + if (phase < phase_min) /* for the read ready delay */ + phase_min = phase; + + dram_info->rl_val[cs][idx][P] = phase; + dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY; + } +#else + if (!ratio_2to1) { /* 1:1 mode */ + if (dram_info->rl_val[cs][idx][PS] > 1) + dram_info->rl_val[cs][idx][PS] -= 2; + if (dram_info->rl_val[cs][idx][PE] > 1) + dram_info->rl_val[cs][idx][PE] -= 2; + } + + delay_s = dram_info->rl_val[cs][idx][PS] * MAX_DELAY + + dram_info->rl_val[cs][idx][DS]; + delay_e = dram_info->rl_val[cs][idx][PE] * MAX_DELAY + + dram_info->rl_val[cs][idx][DE]; + + tmp = (delay_e - delay_s) / 2 + delay_s; + phase = tmp / MAX_DELAY; + if (!ratio_2to1 && phase > 1) /* 1:1 mode */ + phase += 2; + + if (phase < phase_min) /* for the read ready delay */ + phase_min = phase; + + dram_info->rl_val[cs][idx][P] = phase; + dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY; +#endif + } + + /* Set current rdReadyDelay according to the hash table (Need to do this in every phase change) */ + if (!ratio_2to1) { /* 1:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_2_ADDR); + switch (phase_min) { + case 0: + add = (add >> REG_TRAINING_DEBUG_2_OFFS); + break; + case 1: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 3)); + break; + case 4: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 6)); + break; + case 5: + add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 9)); + break; + } + } else { /* 2:1 mode */ + add = reg_read(REG_TRAINING_DEBUG_3_ADDR); + add = (add >> phase_min * REG_TRAINING_DEBUG_3_OFFS); + } + + add &= REG_TRAINING_DEBUG_2_MASK; + reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR); + reg &= + ~(REG_READ_DATA_READY_DELAYS_MASK << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg |= + ((rd_sample_delay + add) << (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + dram_info->rd_rdy_dly = rd_sample_delay + add; + + for (cs = 0; cs < dram_info->num_cs; cs++) { + for (pup = 0; pup < dram_info->num_of_total_pups; pup++) { + reg = ddr3_read_pup_reg(PUP_RL_MODE + 0x1, cs, pup); + dram_info->rl_val[cs][pup][DQS] = (reg & 0x3F); + } + } + + return MV_OK; +} +#endif diff --git a/drivers/ddr/mvebu/ddr3_sdram.c b/drivers/ddr/mvebu/ddr3_sdram.c new file mode 100644 index 0000000000..50c1bf8361 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_sdram.c @@ -0,0 +1,669 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" +#include "xor.h" +#include "xor_regs.h" + +static void ddr3_flush_l1_line(u32 line); + +extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN]; +extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN]; +#if defined(MV88F78X60) +extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN]; +#endif +extern u32 pbs_dq_mapping[PUP_NUM_64BIT][DQ_NUM]; + +#if defined(MV88F78X60) || defined(MV88F672X) +/* PBS locked dq (per pup) */ +u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM] = { { 0 } }; +u32 pbs_locked_dm[MAX_PUP_NUM] = { 0 }; +u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM] = { { 0 } }; + +int per_bit_data[MAX_PUP_NUM][DQ_NUM]; +#endif + +static u32 sdram_data[LEN_KILLER_PATTERN] __aligned(32) = { 0 }; + +static struct crc_dma_desc dma_desc __aligned(32) = { 0 }; + +#define XOR_TIMEOUT 0x8000000 + +struct xor_channel_t { + struct crc_dma_desc *desc; + unsigned long desc_phys_addr; +}; + +#define XOR_CAUSE_DONE_MASK(chan) ((0x1 | 0x2) << (chan * 16)) + +void xor_waiton_eng(int chan) +{ + int timeout; + + timeout = 0; + while (!(reg_read(XOR_CAUSE_REG(XOR_UNIT(chan))) & + XOR_CAUSE_DONE_MASK(XOR_CHAN(chan)))) { + if (timeout > XOR_TIMEOUT) + goto timeout; + + timeout++; + } + + timeout = 0; + while (mv_xor_state_get(chan) != MV_IDLE) { + if (timeout > XOR_TIMEOUT) + goto timeout; + + timeout++; + } + + /* Clear int */ + reg_write(XOR_CAUSE_REG(XOR_UNIT(chan)), + ~(XOR_CAUSE_DONE_MASK(XOR_CHAN(chan)))); + +timeout: + return; +} + +static int special_compare_pattern(u32 uj) +{ + if ((uj == 30) || (uj == 31) || (uj == 61) || (uj == 62) || + (uj == 93) || (uj == 94) || (uj == 126) || (uj == 127)) + return 1; + + return 0; +} + +/* + * Compare code extracted as its used by multiple functions. This + * reduces code-size and makes it easier to maintain it. Additionally + * the code is not indented that much and therefore easier to read. + */ +static void compare_pattern_v1(u32 uj, u32 *pup, u32 *pattern, + u32 pup_groups, int debug_dqs) +{ + u32 val; + u32 uk; + u32 var1; + u32 var2; + __maybe_unused u32 dq; + + if (((sdram_data[uj]) != (pattern[uj])) && (*pup != 0xFF)) { + for (uk = 0; uk < PUP_NUM_32BIT; uk++) { + val = CMP_BYTE_SHIFT * uk; + var1 = ((sdram_data[uj] >> val) & CMP_BYTE_MASK); + var2 = ((pattern[uj] >> val) & CMP_BYTE_MASK); + + if (var1 != var2) { + *pup |= (1 << (uk + (PUP_NUM_32BIT * + (uj % pup_groups)))); + +#ifdef MV_DEBUG_DQS + if (!debug_dqs) + continue; + + for (dq = 0; dq < DQ_NUM; dq++) { + val = uk + (PUP_NUM_32BIT * + (uj % pup_groups)); + if (((var1 >> dq) & 0x1) != + ((var2 >> dq) & 0x1)) + per_bit_data[val][dq] = 1; + else + per_bit_data[val][dq] = 0; + } +#endif + } + } + } +} + +static void compare_pattern_v2(u32 uj, u32 *pup, u32 *pattern) +{ + u32 val; + u32 uk; + u32 var1; + u32 var2; + + if (((sdram_data[uj]) != (pattern[uj])) && (*pup != 0x3)) { + /* Found error */ + for (uk = 0; uk < PUP_NUM_32BIT; uk++) { + val = CMP_BYTE_SHIFT * uk; + var1 = (sdram_data[uj] >> val) & CMP_BYTE_MASK; + var2 = (pattern[uj] >> val) & CMP_BYTE_MASK; + if (var1 != var2) + *pup |= (1 << (uk % PUP_NUM_16BIT)); + } + } +} + +/* + * Name: ddr3_sdram_compare + * Desc: Execute compare per PUP + * Args: unlock_pup Bit array of the unlock pups + * new_locked_pup Output bit array of the pups with failed compare + * pattern Pattern to compare + * pattern_len Length of pattern (in bytes) + * sdram_offset offset address to the SDRAM + * write write to the SDRAM before read + * mask compare pattern with mask; + * mask_pattern Mask to compare pattern + * + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_sdram_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 pattern_len, u32 sdram_offset, int write, + int mask, u32 *mask_pattern, + int special_compare) +{ + u32 uj; + __maybe_unused u32 pup_groups; + __maybe_unused u32 dq; + +#if !defined(MV88F67XX) + if (dram_info->num_of_std_pups == PUP_NUM_64BIT) + pup_groups = 2; + else + pup_groups = 1; +#endif + + ddr3_reset_phy_read_fifo(); + + /* Check if need to write to sdram before read */ + if (write == 1) + ddr3_dram_sram_burst((u32)pattern, sdram_offset, pattern_len); + + ddr3_dram_sram_burst(sdram_offset, (u32)sdram_data, pattern_len); + + /* Compare read result to write */ + for (uj = 0; uj < pattern_len; uj++) { + if (special_compare && special_compare_pattern(uj)) + continue; + +#if defined(MV88F78X60) || defined(MV88F672X) + compare_pattern_v1(uj, new_locked_pup, pattern, pup_groups, 1); +#elif defined(MV88F67XX) + compare_pattern_v2(uj, new_locked_pup, pattern); +#endif + } + + return MV_OK; +} + +#if defined(MV88F78X60) || defined(MV88F672X) +/* + * Name: ddr3_sdram_dm_compare + * Desc: Execute compare per PUP + * Args: unlock_pup Bit array of the unlock pups + * new_locked_pup Output bit array of the pups with failed compare + * pattern Pattern to compare + * pattern_len Length of pattern (in bytes) + * sdram_offset offset address to the SDRAM + * write write to the SDRAM before read + * mask compare pattern with mask; + * mask_pattern Mask to compare pattern + * + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_sdram_dm_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 sdram_offset) +{ + u32 uj, uk, var1, var2, pup_groups; + u32 val; + u32 pup = 0; + + if (dram_info->num_of_std_pups == PUP_NUM_64BIT) + pup_groups = 2; + else + pup_groups = 1; + + ddr3_dram_sram_burst((u32)pattern, SDRAM_PBS_TX_OFFS, + LEN_PBS_PATTERN); + ddr3_dram_sram_burst(SDRAM_PBS_TX_OFFS, (u32)sdram_data, + LEN_PBS_PATTERN); + + /* Validate the correctness of the results */ + for (uj = 0; uj < LEN_PBS_PATTERN; uj++) + compare_pattern_v1(uj, &pup, pattern, pup_groups, 0); + + /* Test the DM Signals */ + *(u32 *)(SDRAM_PBS_TX_OFFS + 0x10) = 0x12345678; + *(u32 *)(SDRAM_PBS_TX_OFFS + 0x14) = 0x12345678; + + sdram_data[0] = *(u32 *)(SDRAM_PBS_TX_OFFS + 0x10); + sdram_data[1] = *(u32 *)(SDRAM_PBS_TX_OFFS + 0x14); + + for (uj = 0; uj < 2; uj++) { + if (((sdram_data[uj]) != (pattern[uj])) && + (*new_locked_pup != 0xFF)) { + for (uk = 0; uk < PUP_NUM_32BIT; uk++) { + val = CMP_BYTE_SHIFT * uk; + var1 = ((sdram_data[uj] >> val) & CMP_BYTE_MASK); + var2 = ((pattern[uj] >> val) & CMP_BYTE_MASK); + if (var1 != var2) { + *new_locked_pup |= (1 << (uk + + (PUP_NUM_32BIT * (uj % pup_groups)))); + *new_locked_pup |= pup; + } + } + } + } + + return MV_OK; +} + +/* + * Name: ddr3_sdram_pbs_compare + * Desc: Execute SRAM compare per PUP and DQ. + * Args: pup_locked bit array of locked pups + * is_tx Indicate whether Rx or Tx + * pbs_pattern_idx Index of PBS pattern + * pbs_curr_val The PBS value + * pbs_lock_val The value to set to locked PBS + * skew_array Global array to update with the compare results + * ai_unlock_pup_dq_array bit array of the locked / unlocked pups per dq. + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_sdram_pbs_compare(MV_DRAM_INFO *dram_info, u32 pup_locked, + int is_tx, u32 pbs_pattern_idx, + u32 pbs_curr_val, u32 pbs_lock_val, + u32 *skew_array, u8 *unlock_pup_dq_array, + u32 ecc) +{ + /* bit array failed dq per pup for current compare */ + u32 pbs_write_pup[DQ_NUM] = { 0 }; + u32 update_pup; /* pup as HW convention */ + u32 max_pup; /* maximal pup index */ + u32 pup_addr; + u32 ui, dq, pup; + int var1, var2; + u32 sdram_offset, pup_groups, tmp_pup; + u32 *pattern_ptr; + u32 val; + + /* Choose pattern */ + switch (dram_info->ddr_width) { +#if defined(MV88F672X) + case 16: + pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx]; + break; +#endif + case 32: + pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx]; + break; +#if defined(MV88F78X60) + case 64: + pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx]; + break; +#endif + default: + return MV_FAIL; + } + + max_pup = dram_info->num_of_std_pups; + + sdram_offset = SDRAM_PBS_I_OFFS + pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS; + + if (dram_info->num_of_std_pups == PUP_NUM_64BIT) + pup_groups = 2; + else + pup_groups = 1; + + ddr3_reset_phy_read_fifo(); + + /* Check if need to write to sdram before read */ + if (is_tx == 1) { + ddr3_dram_sram_burst((u32)pattern_ptr, sdram_offset, + LEN_PBS_PATTERN); + } + + ddr3_dram_sram_read(sdram_offset, (u32)sdram_data, LEN_PBS_PATTERN); + + /* Compare read result to write */ + for (ui = 0; ui < LEN_PBS_PATTERN; ui++) { + if ((sdram_data[ui]) != (pattern_ptr[ui])) { + /* found error */ + /* error in low pup group */ + for (pup = 0; pup < PUP_NUM_32BIT; pup++) { + val = CMP_BYTE_SHIFT * pup; + var1 = ((sdram_data[ui] >> val) & + CMP_BYTE_MASK); + var2 = ((pattern_ptr[ui] >> val) & + CMP_BYTE_MASK); + + if (var1 != var2) { + if (dram_info->ddr_width > 16) { + tmp_pup = (pup + PUP_NUM_32BIT * + (ui % pup_groups)); + } else { + tmp_pup = (pup % PUP_NUM_16BIT); + } + + update_pup = (1 << tmp_pup); + if (ecc && (update_pup != 0x1)) + continue; + + /* + * Pup is failed - Go over all DQs and + * look for failures + */ + for (dq = 0; dq < DQ_NUM; dq++) { + val = tmp_pup * (1 - ecc) + + ecc * ECC_PUP; + if (((var1 >> dq) & 0x1) != + ((var2 >> dq) & 0x1)) { + if (pbs_locked_dq[val][dq] == 1 && + pbs_locked_value[val][dq] != pbs_curr_val) + continue; + + /* + * Activate write to + * update PBS to + * pbs_lock_val + */ + pbs_write_pup[dq] |= + update_pup; + + /* + * Update the + * unlock_pup_dq_array + */ + unlock_pup_dq_array[dq] &= + ~update_pup; + + /* + * Lock PBS value for + * failed bits in + * compare operation + */ + skew_array[tmp_pup * DQ_NUM + dq] = + pbs_curr_val; + } + } + } + } + } + } + + pup_addr = (is_tx == 1) ? PUP_PBS_TX : PUP_PBS_RX; + + /* Set last failed bits PBS to min / max pbs value */ + for (dq = 0; dq < DQ_NUM; dq++) { + for (pup = 0; pup < max_pup; pup++) { + if (pbs_write_pup[dq] & (1 << pup)) { + val = pup * (1 - ecc) + ecc * ECC_PUP; + if (pbs_locked_dq[val][dq] == 1 && + pbs_locked_value[val][dq] != pbs_curr_val) + continue; + + /* Mark the dq as locked */ + pbs_locked_dq[val][dq] = 1; + pbs_locked_value[val][dq] = pbs_curr_val; + ddr3_write_pup_reg(pup_addr + + pbs_dq_mapping[val][dq], + CS0, val, 0, pbs_lock_val); + } + } + } + + return MV_OK; +} +#endif + +/* + * Name: ddr3_sdram_direct_compare + * Desc: Execute compare per PUP without DMA (no burst mode) + * Args: unlock_pup Bit array of the unlock pups + * new_locked_pup Output bit array of the pups with failed compare + * pattern Pattern to compare + * pattern_len Length of pattern (in bytes) + * sdram_offset offset address to the SDRAM + * write write to the SDRAM before read + * mask compare pattern with mask; + * auiMaskPatter Mask to compare pattern + * + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_sdram_direct_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 pattern_len, u32 sdram_offset, + int write, int mask, u32 *mask_pattern) +{ + u32 uj, uk, pup_groups; + u32 *sdram_addr; /* used to read from SDRAM */ + + sdram_addr = (u32 *)sdram_offset; + + if (dram_info->num_of_std_pups == PUP_NUM_64BIT) + pup_groups = 2; + else + pup_groups = 1; + + /* Check if need to write before read */ + if (write == 1) { + for (uk = 0; uk < pattern_len; uk++) { + *sdram_addr = pattern[uk]; + sdram_addr++; + } + } + + sdram_addr = (u32 *)sdram_offset; + + for (uk = 0; uk < pattern_len; uk++) { + sdram_data[uk] = *sdram_addr; + sdram_addr++; + } + + /* Compare read result to write */ + for (uj = 0; uj < pattern_len; uj++) { + if (dram_info->ddr_width > 16) { + compare_pattern_v1(uj, new_locked_pup, pattern, + pup_groups, 0); + } else { + compare_pattern_v2(uj, new_locked_pup, pattern); + } + } + + return MV_OK; +} + +/* + * Name: ddr3_dram_sram_burst + * Desc: Read from the SDRAM in burst of 64 bytes + * Args: src + * dst + * Notes: Using the XOR mechanism + * Returns: MV_OK if success, other error code if fail. + */ +int ddr3_dram_sram_burst(u32 src, u32 dst, u32 len) +{ + u32 chan, byte_count, cs_num, byte; + struct xor_channel_t channel; + + chan = 0; + byte_count = len * 4; + + /* Wait for previous transfer completion */ + while (mv_xor_state_get(chan) != MV_IDLE) + ; + + /* Build the channel descriptor */ + channel.desc = &dma_desc; + + /* Enable Address Override and set correct src and dst */ + if (src < SRAM_BASE) { + /* src is DRAM CS, dst is SRAM */ + cs_num = (src / (1 + SDRAM_CS_SIZE)); + reg_write(XOR_ADDR_OVRD_REG(0, 0), + ((cs_num << 1) | (1 << 0))); + channel.desc->src_addr0 = (src % (1 + SDRAM_CS_SIZE)); + channel.desc->dst_addr = dst; + } else { + /* src is SRAM, dst is DRAM CS */ + cs_num = (dst / (1 + SDRAM_CS_SIZE)); + reg_write(XOR_ADDR_OVRD_REG(0, 0), + ((cs_num << 25) | (1 << 24))); + channel.desc->src_addr0 = (src); + channel.desc->dst_addr = (dst % (1 + SDRAM_CS_SIZE)); + channel.desc->src_addr0 = src; + channel.desc->dst_addr = (dst % (1 + SDRAM_CS_SIZE)); + } + + channel.desc->src_addr1 = 0; + channel.desc->byte_cnt = byte_count; + channel.desc->next_desc_ptr = 0; + channel.desc->status = 1 << 31; + channel.desc->desc_cmd = 0x0; + channel.desc_phys_addr = (unsigned long)&dma_desc; + + ddr3_flush_l1_line((u32)&dma_desc); + + /* Issue the transfer */ + if (mv_xor_transfer(chan, MV_DMA, channel.desc_phys_addr) != MV_OK) + return MV_FAIL; + + /* Wait for completion */ + xor_waiton_eng(chan); + + if (dst > SRAM_BASE) { + for (byte = 0; byte < byte_count; byte += 0x20) + cache_inv(dst + byte); + } + + return MV_OK; +} + +/* + * Name: ddr3_flush_l1_line + * Desc: + * Args: + * Notes: + * Returns: MV_OK if success, other error code if fail. + */ +static void ddr3_flush_l1_line(u32 line) +{ + u32 reg; + +#if defined(MV88F672X) + reg = 1; +#else + reg = reg_read(REG_SAMPLE_RESET_LOW_ADDR) & + (1 << REG_SAMPLE_RESET_CPU_ARCH_OFFS); +#ifdef MV88F67XX + reg = ~reg & (1 << REG_SAMPLE_RESET_CPU_ARCH_OFFS); +#endif +#endif + + if (reg) { + /* V7 Arch mode */ + flush_l1_v7(line); + flush_l1_v7(line + CACHE_LINE_SIZE); + } else { + /* V6 Arch mode */ + flush_l1_v6(line); + flush_l1_v6(line + CACHE_LINE_SIZE); + } +} + +int ddr3_dram_sram_read(u32 src, u32 dst, u32 len) +{ + u32 ui; + u32 *dst_ptr, *src_ptr; + + dst_ptr = (u32 *)dst; + src_ptr = (u32 *)src; + + for (ui = 0; ui < len; ui++) { + *dst_ptr = *src_ptr; + dst_ptr++; + src_ptr++; + } + + return MV_OK; +} + +int ddr3_sdram_dqs_compare(MV_DRAM_INFO *dram_info, u32 unlock_pup, + u32 *new_locked_pup, u32 *pattern, + u32 pattern_len, u32 sdram_offset, int write, + int mask, u32 *mask_pattern, + int special_compare) +{ + u32 uj, pup_groups; + + if (dram_info->num_of_std_pups == PUP_NUM_64BIT) + pup_groups = 2; + else + pup_groups = 1; + + ddr3_reset_phy_read_fifo(); + + /* Check if need to write to sdram before read */ + if (write == 1) + ddr3_dram_sram_burst((u32)pattern, sdram_offset, pattern_len); + + ddr3_dram_sram_burst(sdram_offset, (u32)sdram_data, pattern_len); + + /* Compare read result to write */ + for (uj = 0; uj < pattern_len; uj++) { + if (special_compare && special_compare_pattern(uj)) + continue; + + if (dram_info->ddr_width > 16) { + compare_pattern_v1(uj, new_locked_pup, pattern, + pup_groups, 1); + } else { + compare_pattern_v2(uj, new_locked_pup, pattern); + } + } + + return MV_OK; +} + +void ddr3_reset_phy_read_fifo(void) +{ + u32 reg; + + /* reset read FIFO */ + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Start Auto Read Leveling procedure */ + reg |= (1 << REG_DRAM_TRAINING_RL_OFFS); + + /* 0x15B0 - Training Register */ + reg_write(REG_DRAM_TRAINING_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS) + + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS)); + + /* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + do { + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS); + } while (reg); /* Wait for '0' */ + + reg = reg_read(REG_DRAM_TRAINING_ADDR); + + /* Clear Auto Read Leveling procedure */ + reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS); + + /* 0x15B0 - Training Register */ + reg_write(REG_DRAM_TRAINING_ADDR, reg); +} diff --git a/drivers/ddr/mvebu/ddr3_spd.c b/drivers/ddr/mvebu/ddr3_spd.c new file mode 100644 index 0000000000..f4f94c5c7e --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_spd.c @@ -0,0 +1,1300 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_init.h" + +#if defined(MV88F78X60) +#include "ddr3_axp_config.h" +#elif defined(MV88F67XX) +#include "ddr3_a370_config.h" +#endif + +#if defined(MV88F672X) +#include "ddr3_a375_config.h" +#endif + +#ifdef DUNIT_SPD + +/* DIMM SPD offsets */ +#define SPD_DEV_TYPE_BYTE 2 + +#define SPD_MODULE_TYPE_BYTE 3 +#define SPD_MODULE_MASK 0xf +#define SPD_MODULE_TYPE_RDIMM 1 +#define SPD_MODULE_TYPE_UDIMM 2 + +#define SPD_DEV_DENSITY_BYTE 4 +#define SPD_DEV_DENSITY_MASK 0xf + +#define SPD_ROW_NUM_BYTE 5 +#define SPD_ROW_NUM_MIN 12 +#define SPD_ROW_NUM_OFF 3 +#define SPD_ROW_NUM_MASK (7 << SPD_ROW_NUM_OFF) + +#define SPD_COL_NUM_BYTE 5 +#define SPD_COL_NUM_MIN 9 +#define SPD_COL_NUM_OFF 0 +#define SPD_COL_NUM_MASK (7 << SPD_COL_NUM_OFF) + +#define SPD_MODULE_ORG_BYTE 7 +#define SPD_MODULE_SDRAM_DEV_WIDTH_OFF 0 +#define SPD_MODULE_SDRAM_DEV_WIDTH_MASK (7 << SPD_MODULE_SDRAM_DEV_WIDTH_OFF) +#define SPD_MODULE_BANK_NUM_MIN 1 +#define SPD_MODULE_BANK_NUM_OFF 3 +#define SPD_MODULE_BANK_NUM_MASK (7 << SPD_MODULE_BANK_NUM_OFF) + +#define SPD_BUS_WIDTH_BYTE 8 +#define SPD_BUS_WIDTH_OFF 0 +#define SPD_BUS_WIDTH_MASK (7 << SPD_BUS_WIDTH_OFF) +#define SPD_BUS_ECC_OFF 3 +#define SPD_BUS_ECC_MASK (3 << SPD_BUS_ECC_OFF) + +#define SPD_MTB_DIVIDEND_BYTE 10 +#define SPD_MTB_DIVISOR_BYTE 11 +#define SPD_TCK_BYTE 12 +#define SPD_SUP_CAS_LAT_LSB_BYTE 14 +#define SPD_SUP_CAS_LAT_MSB_BYTE 15 +#define SPD_TAA_BYTE 16 +#define SPD_TWR_BYTE 17 +#define SPD_TRCD_BYTE 18 +#define SPD_TRRD_BYTE 19 +#define SPD_TRP_BYTE 20 + +#define SPD_TRAS_MSB_BYTE 21 +#define SPD_TRAS_MSB_MASK 0xf + +#define SPD_TRC_MSB_BYTE 21 +#define SPD_TRC_MSB_MASK 0xf0 + +#define SPD_TRAS_LSB_BYTE 22 +#define SPD_TRC_LSB_BYTE 23 +#define SPD_TRFC_LSB_BYTE 24 +#define SPD_TRFC_MSB_BYTE 25 +#define SPD_TWTR_BYTE 26 +#define SPD_TRTP_BYTE 27 + +#define SPD_TFAW_MSB_BYTE 28 +#define SPD_TFAW_MSB_MASK 0xf + +#define SPD_TFAW_LSB_BYTE 29 +#define SPD_OPT_FEATURES_BYTE 30 +#define SPD_THERMAL_REFRESH_OPT_BYTE 31 + +#define SPD_ADDR_MAP_BYTE 63 +#define SPD_ADDR_MAP_MIRROR_OFFS 0 + +#define SPD_RDIMM_RC_BYTE 69 +#define SPD_RDIMM_RC_NIBBLE_MASK 0xF +#define SPD_RDIMM_RC_NUM 16 + +/* Dimm Memory Type values */ +#define SPD_MEM_TYPE_SDRAM 0x4 +#define SPD_MEM_TYPE_DDR1 0x7 +#define SPD_MEM_TYPE_DDR2 0x8 +#define SPD_MEM_TYPE_DDR3 0xB + +#define DIMM_MODULE_MANU_OFFS 64 +#define DIMM_MODULE_MANU_SIZE 8 +#define DIMM_MODULE_VEN_OFFS 73 +#define DIMM_MODULE_VEN_SIZE 25 +#define DIMM_MODULE_ID_OFFS 99 +#define DIMM_MODULE_ID_SIZE 18 + +/* enumeration for voltage levels. */ +enum dimm_volt_if { + TTL_5V_TOLERANT, + LVTTL, + HSTL_1_5V, + SSTL_3_3V, + SSTL_2_5V, + VOLTAGE_UNKNOWN, +}; + +/* enumaration for SDRAM CAS Latencies. */ +enum dimm_sdram_cas { + SD_CL_1 = 1, + SD_CL_2, + SD_CL_3, + SD_CL_4, + SD_CL_5, + SD_CL_6, + SD_CL_7, + SD_FAULT +}; + +/* enumeration for memory types */ +enum memory_type { + MEM_TYPE_SDRAM, + MEM_TYPE_DDR1, + MEM_TYPE_DDR2, + MEM_TYPE_DDR3 +}; + +/* DIMM information structure */ +typedef struct dimm_info { + /* DIMM dimensions */ + u32 num_of_module_ranks; + u32 data_width; + u32 rank_capacity; + u32 num_of_devices; + + u32 sdram_width; + u32 num_of_banks_on_each_device; + u32 sdram_capacity; + + u32 num_of_row_addr; + u32 num_of_col_addr; + + u32 addr_mirroring; + + u32 err_check_type; /* ECC , PARITY.. */ + u32 type_info; /* DDR2 only */ + + /* DIMM timing parameters */ + u32 supported_cas_latencies; + u32 refresh_interval; + u32 min_cycle_time; + u32 min_row_precharge_time; + u32 min_row_active_to_row_active; + u32 min_ras_to_cas_delay; + u32 min_write_recovery_time; /* DDR3/2 only */ + u32 min_write_to_read_cmd_delay; /* DDR3/2 only */ + u32 min_read_to_prech_cmd_delay; /* DDR3/2 only */ + u32 min_active_to_precharge; + u32 min_refresh_recovery; /* DDR3/2 only */ + u32 min_cas_lat_time; + u32 min_four_active_win_delay; + u8 dimm_rc[SPD_RDIMM_RC_NUM]; + + /* DIMM vendor ID */ + u32 vendor; +} MV_DIMM_INFO; + +static int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info, + u32 dimm); +static u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val); +static u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val); +static int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width); +static u32 ddr3_div(u32 val, u32 divider, u32 sub); + +extern u8 spd_data[SPD_SIZE]; +extern u32 odt_config[ODT_OPT]; +extern u16 odt_static[ODT_OPT][MAX_CS]; +extern u16 odt_dynamic[ODT_OPT][MAX_CS]; + +#if !(defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710)) +/* + * Name: ddr3_get_dimm_num - Find number of dimms and their addresses + * Desc: + * Args: dimm_addr - array of dimm addresses + * Notes: + * Returns: None. + */ +static u32 ddr3_get_dimm_num(u32 *dimm_addr) +{ + u32 dimm_cur_addr; + u8 data[3]; + u32 dimm_num = 0; + int ret; + + /* Read the dimm eeprom */ + for (dimm_cur_addr = MAX_DIMM_ADDR; dimm_cur_addr > MIN_DIMM_ADDR; + dimm_cur_addr--) { + data[SPD_DEV_TYPE_BYTE] = 0; + + /* Far-End DIMM must be connected */ + if ((dimm_num == 0) && (dimm_cur_addr < FAR_END_DIMM_ADDR)) + return 0; + + ret = i2c_read(dimm_cur_addr, 0, 1, (uchar *)data, 3); + if (!ret) { + if (data[SPD_DEV_TYPE_BYTE] == SPD_MEM_TYPE_DDR3) { + dimm_addr[dimm_num] = dimm_cur_addr; + dimm_num++; + } + } + } + + return dimm_num; +} +#endif + +/* + * Name: dimmSpdInit - Get the SPD parameters. + * Desc: Read the DIMM SPD parameters into given struct parameter. + * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator. + * info - DIMM information structure. + * Notes: + * Returns: MV_OK if function could read DIMM parameters, 0 otherwise. + */ +int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width) +{ + u32 tmp; + u32 time_base; + int ret; + __maybe_unused u32 rc; + __maybe_unused u8 vendor_high, vendor_low; + + if (dimm_addr != 0) { + memset(spd_data, 0, SPD_SIZE * sizeof(u8)); + + ret = i2c_read(dimm_addr, 0, 1, (uchar *)spd_data, SPD_SIZE); + if (ret) + return MV_DDR3_TRAINING_ERR_TWSI_FAIL; + } + + /* Check if DDR3 */ + if (spd_data[SPD_DEV_TYPE_BYTE] != SPD_MEM_TYPE_DDR3) + return MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE; + + /* Error Check Type */ + /* No byte for error check in DDR3 SPD, use DDR2 convention */ + info->err_check_type = 0; + + /* Check if ECC */ + if ((spd_data[SPD_BUS_WIDTH_BYTE] & 0x18) >> 3) + info->err_check_type = 1; + + DEBUG_INIT_FULL_C("DRAM err_check_type ", info->err_check_type, 1); + switch (spd_data[SPD_MODULE_TYPE_BYTE]) { + case 1: + /* support RDIMM */ + info->type_info = SPD_MODULE_TYPE_RDIMM; + break; + case 2: + /* support UDIMM */ + info->type_info = SPD_MODULE_TYPE_UDIMM; + break; + case 11: /* LRDIMM current not supported */ + default: + info->type_info = (spd_data[SPD_MODULE_TYPE_BYTE]); + break; + } + + /* Size Calculations: */ + + /* Number Of Row Addresses - 12/13/14/15/16 */ + info->num_of_row_addr = + (spd_data[SPD_ROW_NUM_BYTE] & SPD_ROW_NUM_MASK) >> + SPD_ROW_NUM_OFF; + info->num_of_row_addr += SPD_ROW_NUM_MIN; + DEBUG_INIT_FULL_C("DRAM num_of_row_addr ", info->num_of_row_addr, 2); + + /* Number Of Column Addresses - 9/10/11/12 */ + info->num_of_col_addr = + (spd_data[SPD_COL_NUM_BYTE] & SPD_COL_NUM_MASK) >> + SPD_COL_NUM_OFF; + info->num_of_col_addr += SPD_COL_NUM_MIN; + DEBUG_INIT_FULL_C("DRAM num_of_col_addr ", info->num_of_col_addr, 1); + + /* Number Of Ranks = number of CS on Dimm - 1/2/3/4 Ranks */ + info->num_of_module_ranks = + (spd_data[SPD_MODULE_ORG_BYTE] & SPD_MODULE_BANK_NUM_MASK) >> + SPD_MODULE_BANK_NUM_OFF; + info->num_of_module_ranks += SPD_MODULE_BANK_NUM_MIN; + DEBUG_INIT_FULL_C("DRAM numOfModuleBanks ", info->num_of_module_ranks, + 1); + + /* Data Width - 8/16/32/64 bits */ + info->data_width = + 1 << (3 + (spd_data[SPD_BUS_WIDTH_BYTE] & SPD_BUS_WIDTH_MASK)); + DEBUG_INIT_FULL_C("DRAM data_width ", info->data_width, 1); + + /* Number Of Banks On Each Device - 8/16/32/64 banks */ + info->num_of_banks_on_each_device = + 1 << (3 + ((spd_data[SPD_DEV_DENSITY_BYTE] >> 4) & 0x7)); + DEBUG_INIT_FULL_C("DRAM num_of_banks_on_each_device ", + info->num_of_banks_on_each_device, 1); + + /* Total SDRAM capacity - 256Mb/512Mb/1Gb/2Gb/4Gb/8Gb/16Gb - MegaBits */ + info->sdram_capacity = + spd_data[SPD_DEV_DENSITY_BYTE] & SPD_DEV_DENSITY_MASK; + + /* Sdram Width - 4/8/16/32 bits */ + info->sdram_width = 1 << (2 + (spd_data[SPD_MODULE_ORG_BYTE] & + SPD_MODULE_SDRAM_DEV_WIDTH_MASK)); + DEBUG_INIT_FULL_C("DRAM sdram_width ", info->sdram_width, 1); + + /* CS (Rank) Capacity - MB */ + /* + * DDR3 device uiDensity val are: (device capacity/8) * + * (Module_width/Device_width) + */ + /* Jedec SPD DDR3 - page 7, Save spd_data in Mb - 2048=2GB */ + if (dimm_width == 32) { + info->rank_capacity = + ((1 << info->sdram_capacity) * 256 * + (info->data_width / info->sdram_width)) << 16; + /* CS size = CS size / 2 */ + } else { + info->rank_capacity = + ((1 << info->sdram_capacity) * 256 * + (info->data_width / info->sdram_width) * 0x2) << 16; + /* 0x2 => 0x100000-1Mbit / 8-bit->byte / 0x10000 */ + } + DEBUG_INIT_FULL_C("DRAM rank_capacity[31] ", info->rank_capacity, 1); + + /* Number of devices includeing Error correction */ + info->num_of_devices = + ((info->data_width / info->sdram_width) * + info->num_of_module_ranks) + info->err_check_type; + DEBUG_INIT_FULL_C("DRAM num_of_devices ", info->num_of_devices, 1); + + /* Address Mapping from Edge connector to DRAM - mirroring option */ + info->addr_mirroring = + spd_data[SPD_ADDR_MAP_BYTE] & (1 << SPD_ADDR_MAP_MIRROR_OFFS); + + /* Timings - All in ps */ + + time_base = (1000 * spd_data[SPD_MTB_DIVIDEND_BYTE]) / + spd_data[SPD_MTB_DIVISOR_BYTE]; + + /* Minimum Cycle Time At Max CasLatancy */ + info->min_cycle_time = spd_data[SPD_TCK_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM tCKmin ", info->min_cycle_time, 1); + + /* Refresh Interval */ + /* No byte for refresh interval in DDR3 SPD, use DDR2 convention */ + /* + * JEDEC param are 0 <= Tcase <= 85: 7.8uSec, 85 <= Tcase + * <= 95: 3.9uSec + */ + info->refresh_interval = 7800000; /* Set to 7.8uSec */ + DEBUG_INIT_FULL_C("DRAM refresh_interval ", info->refresh_interval, 1); + + /* Suported Cas Latencies - DDR 3: */ + + /* + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * + *******-******-******-******-******-******-******-*******-******* + CAS = 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 * + *********************************************************-******* + *******-******-******-******-******-******-******-*******-******* + * bit15 |bit14 |bit13 |bit12 |bit11 |bit10 | bit9 | bit8 * + *******-******-******-******-******-******-******-*******-******* + CAS = TBD | 18 | 17 | 16 | 15 | 14 | 13 | 12 * + */ + + /* DDR3 include 2 byte of CAS support */ + info->supported_cas_latencies = + (spd_data[SPD_SUP_CAS_LAT_MSB_BYTE] << 8) | + spd_data[SPD_SUP_CAS_LAT_LSB_BYTE]; + DEBUG_INIT_FULL_C("DRAM supported_cas_latencies ", + info->supported_cas_latencies, 1); + + /* Minimum Cycle Time At Max CasLatancy */ + info->min_cas_lat_time = (spd_data[SPD_TAA_BYTE] * time_base); + /* + * This field divided by the cycleTime will give us the CAS latency + * to config + */ + + /* + * For DDR3 and DDR2 includes Write Recovery Time field. + * Other SDRAM ignore + */ + info->min_write_recovery_time = spd_data[SPD_TWR_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_write_recovery_time ", + info->min_write_recovery_time, 1); + + /* Mininmum Ras to Cas Delay */ + info->min_ras_to_cas_delay = spd_data[SPD_TRCD_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_ras_to_cas_delay ", + info->min_ras_to_cas_delay, 1); + + /* Minimum Row Active to Row Active Time */ + info->min_row_active_to_row_active = + spd_data[SPD_TRRD_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_row_active_to_row_active ", + info->min_row_active_to_row_active, 1); + + /* Minimum Row Precharge Delay Time */ + info->min_row_precharge_time = spd_data[SPD_TRP_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_row_precharge_time ", + info->min_row_precharge_time, 1); + + /* Minimum Active to Precharge Delay Time - tRAS ps */ + info->min_active_to_precharge = + (spd_data[SPD_TRAS_MSB_BYTE] & SPD_TRAS_MSB_MASK) << 8; + info->min_active_to_precharge |= spd_data[SPD_TRAS_LSB_BYTE]; + info->min_active_to_precharge *= time_base; + DEBUG_INIT_FULL_C("DRAM min_active_to_precharge ", + info->min_active_to_precharge, 1); + + /* Minimum Refresh Recovery Delay Time - tRFC ps */ + info->min_refresh_recovery = spd_data[SPD_TRFC_MSB_BYTE] << 8; + info->min_refresh_recovery |= spd_data[SPD_TRFC_LSB_BYTE]; + info->min_refresh_recovery *= time_base; + DEBUG_INIT_FULL_C("DRAM min_refresh_recovery ", + info->min_refresh_recovery, 1); + + /* + * For DDR3 and DDR2 includes Internal Write To Read Command Delay + * field. + */ + info->min_write_to_read_cmd_delay = spd_data[SPD_TWTR_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_write_to_read_cmd_delay ", + info->min_write_to_read_cmd_delay, 1); + + /* + * For DDR3 and DDR2 includes Internal Read To Precharge Command Delay + * field. + */ + info->min_read_to_prech_cmd_delay = spd_data[SPD_TRTP_BYTE] * time_base; + DEBUG_INIT_FULL_C("DRAM min_read_to_prech_cmd_delay ", + info->min_read_to_prech_cmd_delay, 1); + + /* + * For DDR3 includes Minimum Activate to Activate/Refresh Command + * field + */ + tmp = ((spd_data[SPD_TFAW_MSB_BYTE] & SPD_TFAW_MSB_MASK) << 8) | + spd_data[SPD_TFAW_LSB_BYTE]; + info->min_four_active_win_delay = tmp * time_base; + DEBUG_INIT_FULL_C("DRAM min_four_active_win_delay ", + info->min_four_active_win_delay, 1); + +#if defined(MV88F78X60) || defined(MV88F672X) + /* Registered DIMM support */ + if (info->type_info == SPD_MODULE_TYPE_RDIMM) { + for (rc = 2; rc < 6; rc += 2) { + tmp = spd_data[SPD_RDIMM_RC_BYTE + rc / 2]; + info->dimm_rc[rc] = + spd_data[SPD_RDIMM_RC_BYTE + rc / 2] & + SPD_RDIMM_RC_NIBBLE_MASK; + info->dimm_rc[rc + 1] = + (spd_data[SPD_RDIMM_RC_BYTE + rc / 2] >> 4) & + SPD_RDIMM_RC_NIBBLE_MASK; + } + + vendor_low = spd_data[66]; + vendor_high = spd_data[65]; + info->vendor = (vendor_high << 8) + vendor_low; + DEBUG_INIT_C("DDR3 Training Sequence - Registered DIMM vendor ID 0x", + info->vendor, 4); + + info->dimm_rc[0] = RDIMM_RC0; + info->dimm_rc[1] = RDIMM_RC1; + info->dimm_rc[2] = RDIMM_RC2; + info->dimm_rc[8] = RDIMM_RC8; + info->dimm_rc[9] = RDIMM_RC9; + info->dimm_rc[10] = RDIMM_RC10; + info->dimm_rc[11] = RDIMM_RC11; + } +#endif + + return MV_OK; +} + +/* + * Name: ddr3_spd_sum_init - Get the SPD parameters. + * Desc: Read the DIMM SPD parameters into given struct parameter. + * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator. + * info - DIMM information structure. + * Notes: + * Returns: MV_OK if function could read DIMM parameters, 0 otherwise. + */ +int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info, u32 dimm) +{ + if (dimm == 0) { + memcpy(sum_info, info, sizeof(MV_DIMM_INFO)); + return MV_OK; + } + if (sum_info->type_info != info->type_info) { + DEBUG_INIT_S("DDR3 Dimm Compare - DIMM type does not match - FAIL\n"); + return MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH; + } + if (sum_info->err_check_type > info->err_check_type) { + sum_info->err_check_type = info->err_check_type; + DEBUG_INIT_S("DDR3 Dimm Compare - ECC does not match. ECC is disabled\n"); + } + if (sum_info->data_width != info->data_width) { + DEBUG_INIT_S("DDR3 Dimm Compare - DRAM bus width does not match - FAIL\n"); + return MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH; + } + if (sum_info->min_cycle_time < info->min_cycle_time) + sum_info->min_cycle_time = info->min_cycle_time; + if (sum_info->refresh_interval < info->refresh_interval) + sum_info->refresh_interval = info->refresh_interval; + sum_info->supported_cas_latencies &= info->supported_cas_latencies; + if (sum_info->min_cas_lat_time < info->min_cas_lat_time) + sum_info->min_cas_lat_time = info->min_cas_lat_time; + if (sum_info->min_write_recovery_time < info->min_write_recovery_time) + sum_info->min_write_recovery_time = + info->min_write_recovery_time; + if (sum_info->min_ras_to_cas_delay < info->min_ras_to_cas_delay) + sum_info->min_ras_to_cas_delay = info->min_ras_to_cas_delay; + if (sum_info->min_row_active_to_row_active < + info->min_row_active_to_row_active) + sum_info->min_row_active_to_row_active = + info->min_row_active_to_row_active; + if (sum_info->min_row_precharge_time < info->min_row_precharge_time) + sum_info->min_row_precharge_time = info->min_row_precharge_time; + if (sum_info->min_active_to_precharge < info->min_active_to_precharge) + sum_info->min_active_to_precharge = + info->min_active_to_precharge; + if (sum_info->min_refresh_recovery < info->min_refresh_recovery) + sum_info->min_refresh_recovery = info->min_refresh_recovery; + if (sum_info->min_write_to_read_cmd_delay < + info->min_write_to_read_cmd_delay) + sum_info->min_write_to_read_cmd_delay = + info->min_write_to_read_cmd_delay; + if (sum_info->min_read_to_prech_cmd_delay < + info->min_read_to_prech_cmd_delay) + sum_info->min_read_to_prech_cmd_delay = + info->min_read_to_prech_cmd_delay; + if (sum_info->min_four_active_win_delay < + info->min_four_active_win_delay) + sum_info->min_four_active_win_delay = + info->min_four_active_win_delay; + if (sum_info->min_write_to_read_cmd_delay < + info->min_write_to_read_cmd_delay) + sum_info->min_write_to_read_cmd_delay = + info->min_write_to_read_cmd_delay; + + return MV_OK; +} + +/* + * Name: ddr3_dunit_setup + * Desc: Set the controller with the timing values. + * Args: ecc_ena - User ECC setup + * Notes: + * Returns: + */ +int ddr3_dunit_setup(u32 ecc_ena, u32 hclk_time, u32 *ddr_width) +{ + u32 reg, tmp, cwl; + u32 ddr_clk_time; + MV_DIMM_INFO dimm_info[2]; + MV_DIMM_INFO sum_info; + u32 stat_val, spd_val; + u32 cs, cl, cs_num, cs_ena; + u32 dimm_num = 0; + int status; + u32 rc; + __maybe_unused u32 dimm_cnt, cs_count, dimm; + __maybe_unused u32 dimm_addr[2] = { 0, 0 }; + +#if defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710) + /* Armada 370 - SPD is not available on DIMM */ + /* + * Set MC registers according to Static SPD values Values - + * must be set manually + */ + /* + * We only have one optional DIMM for the DB and we already got the + * SPD matching values + */ + status = ddr3_spd_init(&dimm_info[0], 0, *ddr_width); + if (MV_OK != status) + return status; + + dimm_num = 1; + /* Use JP8 to enable multiCS support for Armada 370 DB */ + if (!ddr3_check_config(EEPROM_MODULE_ADDR, CONFIG_MULTI_CS)) + dimm_info[0].num_of_module_ranks = 1; + status = ddr3_spd_sum_init(&dimm_info[0], &sum_info, 0); + if (MV_OK != status) + return status; +#else + /* Dynamic D-Unit Setup - Read SPD values */ +#ifdef DUNIT_SPD + dimm_num = ddr3_get_dimm_num(dimm_addr); + if (dimm_num == 0) { +#ifdef MIXED_DIMM_STATIC + DEBUG_INIT_S("DDR3 Training Sequence - No DIMMs detected\n"); +#else + DEBUG_INIT_S("DDR3 Training Sequence - FAILED (Wrong DIMMs Setup)\n"); + return MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP; +#endif + } else { + DEBUG_INIT_C("DDR3 Training Sequence - Number of DIMMs detected: ", + dimm_num, 1); + } + + for (dimm = 0; dimm < dimm_num; dimm++) { + status = ddr3_spd_init(&dimm_info[dimm], dimm_addr[dimm], + *ddr_width); + if (MV_OK != status) + return status; + status = ddr3_spd_sum_init(&dimm_info[dimm], &sum_info, dimm); + if (MV_OK != status) + return status; + } +#endif +#endif + + /* Set number of enabled CS */ + cs_num = 0; +#ifdef DUNIT_STATIC + cs_num = ddr3_get_cs_num_from_reg(); +#endif +#ifdef DUNIT_SPD + for (dimm = 0; dimm < dimm_num; dimm++) + cs_num += dimm_info[dimm].num_of_module_ranks; +#endif + if (cs_num > MAX_CS) { + DEBUG_INIT_C("DDR3 Training Sequence - Number of CS exceed limit - ", + MAX_CS, 1); + return MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT; + } + + /* Set bitmap of enabled CS */ + cs_ena = 0; +#ifdef DUNIT_STATIC + cs_ena = ddr3_get_cs_ena_from_reg(); +#endif +#ifdef DUNIT_SPD + dimm = 0; + + if (dimm_num) { + for (cs = 0; cs < MAX_CS; cs += 2) { + if (((1 << cs) & DIMM_CS_BITMAP) && + !(cs_ena & (1 << cs))) { + if (dimm_info[dimm].num_of_module_ranks == 1) + cs_ena |= (0x1 << cs); + else if (dimm_info[dimm].num_of_module_ranks == 2) + cs_ena |= (0x3 << cs); + else if (dimm_info[dimm].num_of_module_ranks == 3) + cs_ena |= (0x7 << cs); + else if (dimm_info[dimm].num_of_module_ranks == 4) + cs_ena |= (0xF << cs); + + dimm++; + if (dimm == dimm_num) + break; + } + } + } +#endif + + if (cs_ena > 0xF) { + DEBUG_INIT_C("DDR3 Training Sequence - Number of enabled CS exceed limit - ", + MAX_CS, 1); + return MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT; + } + + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Number of CS = ", cs_num, 1); + + /* Check Ratio - '1' - 2:1, '0' - 1:1 */ + if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS)) + ddr_clk_time = hclk_time / 2; + else + ddr_clk_time = hclk_time; + +#ifdef DUNIT_STATIC + /* Get target CL value from set register */ + reg = (reg_read(REG_DDR3_MR0_ADDR) >> 2); + reg = ((((reg >> 1) & 0xE)) | (reg & 0x1)) & 0xF; + + cl = ddr3_get_max_val(ddr3_div(sum_info.min_cas_lat_time, + ddr_clk_time, 0), + dimm_num, ddr3_valid_cl_to_cl(reg)); +#else + cl = ddr3_div(sum_info.min_cas_lat_time, ddr_clk_time, 0); +#endif + if (cl < 5) + cl = 5; + + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Cas Latency = ", cl, 1); + + /* {0x00001400} - DDR SDRAM Configuration Register */ + reg = 0x73004000; + stat_val = ddr3_get_static_mc_value( + REG_SDRAM_CONFIG_ADDR, REG_SDRAM_CONFIG_ECC_OFFS, 0x1, 0, 0); + if (ecc_ena && ddr3_get_min_val(sum_info.err_check_type, dimm_num, + stat_val)) { + reg |= (1 << REG_SDRAM_CONFIG_ECC_OFFS); + reg |= (1 << REG_SDRAM_CONFIG_IERR_OFFS); + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Enabled\n"); + } else { + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Disabled\n"); + } + + if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) { +#ifdef DUNIT_STATIC + DEBUG_INIT_S("DDR3 Training Sequence - FAIL - Illegal R-DIMM setup\n"); + return MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP; +#endif + reg |= (1 << REG_SDRAM_CONFIG_REGDIMM_OFFS); + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - R-DIMM\n"); + } else { + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - U-DIMM\n"); + } + +#ifndef MV88F67XX +#ifdef DUNIT_STATIC + if (ddr3_get_min_val(sum_info.data_width, dimm_num, BUS_WIDTH) == 64) { +#else + if (*ddr_width == 64) { +#endif + reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS); + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 64Bits\n"); + } else { + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n"); + } +#else + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n"); +#endif + +#if defined(MV88F672X) + if (*ddr_width == 32) { + reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS); + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n"); + } else { + DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n"); + } +#endif + stat_val = ddr3_get_static_mc_value(REG_SDRAM_CONFIG_ADDR, 0, + REG_SDRAM_CONFIG_RFRS_MASK, 0, 0); + tmp = ddr3_get_min_val(sum_info.refresh_interval / hclk_time, + dimm_num, stat_val); + +#ifdef TREFI_USER_EN + tmp = min(TREFI_USER / hclk_time, tmp); +#endif + + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - RefreshInterval/Hclk = ", tmp, 4); + reg |= tmp; + + if (cl != 3) + reg |= (1 << 16); /* If 2:1 need to set P2DWr */ + +#if defined(MV88F672X) + reg |= (1 << 27); /* PhyRfRST = Disable */ +#endif + reg_write(REG_SDRAM_CONFIG_ADDR, reg); + + /*{0x00001404} - DDR SDRAM Configuration Register */ + reg = 0x3630B800; +#ifdef DUNIT_SPD + reg |= (DRAM_2T << REG_DUNIT_CTRL_LOW_2T_OFFS); +#endif + reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + + /* {0x00001408} - DDR SDRAM Timing (Low) Register */ + reg = 0x0; + + /* tRAS - (0:3,20) */ + spd_val = ddr3_div(sum_info.min_active_to_precharge, + ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 0, 0xF, 16, 0x10); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRAS-1 = ", tmp, 1); + reg |= (tmp & 0xF); + reg |= ((tmp & 0x10) << 16); /* to bit 20 */ + + /* tRCD - (4:7) */ + spd_val = ddr3_div(sum_info.min_ras_to_cas_delay, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 4, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRCD-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 4); + + /* tRP - (8:11) */ + spd_val = ddr3_div(sum_info.min_row_precharge_time, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 8, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRP-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 8); + + /* tWR - (12:15) */ + spd_val = ddr3_div(sum_info.min_write_recovery_time, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 12, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWR-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 12); + + /* tWTR - (16:19) */ + spd_val = ddr3_div(sum_info.min_write_to_read_cmd_delay, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 16, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWTR-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 16); + + /* tRRD - (24:27) */ + spd_val = ddr3_div(sum_info.min_row_active_to_row_active, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 24, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRRD-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 24); + + /* tRTP - (28:31) */ + spd_val = ddr3_div(sum_info.min_read_to_prech_cmd_delay, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR, + 28, 0xF, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRTP-1 = ", tmp, 1); + reg |= ((tmp & 0xF) << 28); + + if (cl < 7) + reg = 0x33137663; + + reg_write(REG_SDRAM_TIMING_LOW_ADDR, reg); + + /*{0x0000140C} - DDR SDRAM Timing (High) Register */ + /* Add cycles to R2R W2W */ + reg = 0x39F8FF80; + + /* tRFC - (0:6,16:18) */ + spd_val = ddr3_div(sum_info.min_refresh_recovery, ddr_clk_time, 1); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_HIGH_ADDR, + 0, 0x7F, 9, 0x380); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRFC-1 = ", tmp, 1); + reg |= (tmp & 0x7F); + reg |= ((tmp & 0x380) << 9); /* to bit 16 */ + reg_write(REG_SDRAM_TIMING_HIGH_ADDR, reg); + + /*{0x00001410} - DDR SDRAM Address Control Register */ + reg = 0x000F0000; + + /* tFAW - (24:28) */ +#if (defined(MV88F78X60) || defined(MV88F672X)) + tmp = sum_info.min_four_active_win_delay; + spd_val = ddr3_div(tmp, ddr_clk_time, 0); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR, + 24, 0x3F, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW = ", tmp, 1); + reg |= ((tmp & 0x3F) << 24); +#else + tmp = sum_info.min_four_active_win_delay - + 4 * (sum_info.min_row_active_to_row_active); + spd_val = ddr3_div(tmp, ddr_clk_time, 0); + stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR, + 24, 0x1F, 0, 0); + tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val); + DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW-4*tRRD = ", tmp, 1); + reg |= ((tmp & 0x1F) << 24); +#endif + + /* SDRAM device capacity */ +#ifdef DUNIT_STATIC + reg |= (reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR) & 0xF0FFFF); +#endif + +#ifdef DUNIT_SPD + cs_count = 0; + dimm_cnt = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) { + if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) { + dimm_cnt++; + cs_count = 0; + } + cs_count++; + if (dimm_info[dimm_cnt].sdram_capacity < 0x3) { + reg |= ((dimm_info[dimm_cnt].sdram_capacity + 1) << + (REG_SDRAM_ADDRESS_SIZE_OFFS + + (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs))); + } else if (dimm_info[dimm_cnt].sdram_capacity > 0x3) { + reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x3) << + (REG_SDRAM_ADDRESS_SIZE_OFFS + + (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs))); + reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x4) << + (REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS + cs)); + } + } + } + + /* SDRAM device structure */ + cs_count = 0; + dimm_cnt = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) { + if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) { + dimm_cnt++; + cs_count = 0; + } + cs_count++; + if (dimm_info[dimm_cnt].sdram_width == 16) + reg |= (1 << (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs)); + } + } +#endif + reg_write(REG_SDRAM_ADDRESS_CTRL_ADDR, reg); + + /*{0x00001418} - DDR SDRAM Operation Register */ + reg = 0xF00; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) + reg &= ~(1 << (cs + REG_SDRAM_OPERATION_CS_OFFS)); + } + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /*{0x00001420} - DDR SDRAM Extended Mode Register */ + reg = 0x00000004; + reg_write(REG_SDRAM_EXT_MODE_ADDR, reg); + + /*{0x00001424} - DDR Controller Control (High) Register */ +#if (defined(MV88F78X60) || defined(MV88F672X)) + reg = 0x0000D3FF; +#else + reg = 0x0100D1FF; +#endif + reg_write(REG_DDR_CONT_HIGH_ADDR, reg); + + /*{0x0000142C} - DDR3 Timing Register */ + reg = 0x014C2F38; +#if defined(MV88F78X60) || defined(MV88F672X) + reg = 0x1FEC2F38; +#endif + reg_write(0x142C, reg); + + /*{0x00001484} - MBus CPU Block Register */ +#ifdef MV88F67XX + if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS)) + reg_write(REG_MBUS_CPU_BLOCK_ADDR, 0x0000E907); +#endif + + /* + * In case of mixed dimm and on-board devices setup paramters will + * be taken statically + */ + /*{0x00001494} - DDR SDRAM ODT Control (Low) Register */ + reg = odt_config[cs_ena]; + reg_write(REG_SDRAM_ODT_CTRL_LOW_ADDR, reg); + + /*{0x00001498} - DDR SDRAM ODT Control (High) Register */ + reg = 0x00000000; + reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, reg); + + /*{0x0000149C} - DDR Dunit ODT Control Register */ + reg = cs_ena; + reg_write(REG_DUNIT_ODT_CTRL_ADDR, reg); + + /*{0x000014A0} - DDR Dunit ODT Control Register */ +#if defined(MV88F672X) + reg = 0x000006A9; + reg_write(REG_DRAM_FIFO_CTRL_ADDR, reg); +#endif + + /*{0x000014C0} - DRAM address and Control Driving Strenght */ + reg_write(REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR, 0x192435e9); + + /*{0x000014C4} - DRAM Data and DQS Driving Strenght */ + reg_write(REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR, 0xB2C35E9); + +#if (defined(MV88F78X60) || defined(MV88F672X)) + /*{0x000014CC} - DRAM Main Pads Calibration Machine Control Register */ + reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR); + reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg | (1 << 0)); +#endif + +#if defined(MV88F672X) + /* DRAM Main Pads Calibration Machine Control Register */ + /* 0x14CC[4:3] - CalUpdateControl = IntOnly */ + reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR); + reg &= 0xFFFFFFE7; + reg |= (1 << 3); + reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg); +#endif + +#ifdef DUNIT_SPD + cs_count = 0; + dimm_cnt = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if ((1 << cs) & DIMM_CS_BITMAP) { + if ((1 << cs) & cs_ena) { + if (dimm_info[dimm_cnt].num_of_module_ranks == + cs_count) { + dimm_cnt++; + cs_count = 0; + } + cs_count++; + reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8), + dimm_info[dimm_cnt].rank_capacity - 1); + } else { + reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8), 0); + } + } + } +#endif + + /*{0x00020184} - Close FastPath - 2G */ + reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, 0); + + /*{0x00001538} - Read Data Sample Delays Register */ + reg = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) + reg |= (cl << (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs)); + } + + reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg); + DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Sample Delays = ", reg, + 1); + + /*{0x0000153C} - Read Data Ready Delay Register */ + reg = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg |= ((cl + 2) << + (REG_READ_DATA_READY_DELAYS_OFFS * cs)); + } + } + reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg); + DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Ready Delays = ", reg, 1); + + /* Set MR registers */ + /* MR0 */ + reg = 0x00000600; + tmp = ddr3_cl_to_valid_cl(cl); + reg |= ((tmp & 0x1) << 2); + reg |= ((tmp & 0xE) << 3); /* to bit 4 */ + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg_write(REG_DDR3_MR0_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* MR1 */ + reg = 0x00000044 & REG_DDR3_MR1_ODT_MASK; + if (cs_num > 1) + reg = 0x00000046 & REG_DDR3_MR1_ODT_MASK; + + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg |= odt_static[cs_ena][cs]; + reg_write(REG_DDR3_MR1_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* MR2 */ + if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS)) + tmp = hclk_time / 2; + else + tmp = hclk_time; + + if (tmp >= 2500) + cwl = 5; /* CWL = 5 */ + else if (tmp >= 1875 && tmp < 2500) + cwl = 6; /* CWL = 6 */ + else if (tmp >= 1500 && tmp < 1875) + cwl = 7; /* CWL = 7 */ + else if (tmp >= 1250 && tmp < 1500) + cwl = 8; /* CWL = 8 */ + else if (tmp >= 1070 && tmp < 1250) + cwl = 9; /* CWL = 9 */ + else if (tmp >= 935 && tmp < 1070) + cwl = 10; /* CWL = 10 */ + else if (tmp >= 833 && tmp < 935) + cwl = 11; /* CWL = 11 */ + else if (tmp >= 750 && tmp < 833) + cwl = 12; /* CWL = 12 */ + else { + cwl = 12; /* CWL = 12 */ + printf("Unsupported hclk %d MHz\n", tmp); + } + + reg = ((cwl - 5) << REG_DDR3_MR2_CWL_OFFS); + + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg &= REG_DDR3_MR2_ODT_MASK; + reg |= odt_dynamic[cs_ena][cs]; + reg_write(REG_DDR3_MR2_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* MR3 */ + reg = 0x00000000; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs)) { + reg_write(REG_DDR3_MR3_CS_ADDR + + (cs << MR_CS_ADDR_OFFS), reg); + } + } + + /* {0x00001428} - DDR ODT Timing (Low) Register */ + reg = 0; + reg |= (((cl - cwl + 1) & 0xF) << 4); + reg |= (((cl - cwl + 6) & 0xF) << 8); + reg |= ((((cl - cwl + 6) >> 4) & 0x1) << 21); + reg |= (((cl - 1) & 0xF) << 12); + reg |= (((cl + 6) & 0x1F) << 16); + reg_write(REG_ODT_TIME_LOW_ADDR, reg); + + /* {0x0000147C} - DDR ODT Timing (High) Register */ + reg = 0x00000071; + reg |= ((cwl - 1) << 8); + reg |= ((cwl + 5) << 12); + reg_write(REG_ODT_TIME_HIGH_ADDR, reg); + +#ifdef DUNIT_SPD + /*{0x000015E0} - DDR3 Rank Control Register */ + reg = cs_ena; + cs_count = 0; + dimm_cnt = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) { + if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) { + dimm_cnt++; + cs_count = 0; + } + cs_count++; + + if (dimm_info[dimm_cnt].addr_mirroring && + (cs == 1 || cs == 3) && + (sum_info.type_info != SPD_MODULE_TYPE_RDIMM)) { + reg |= (1 << (REG_DDR3_RANK_CTRL_MIRROR_OFFS + cs)); + DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Setting Address Mirroring for CS = ", + cs, 1); + } + } + } + reg_write(REG_DDR3_RANK_CTRL_ADDR, reg); +#endif + + /*{0xD00015E4} - ZQDS Configuration Register */ + reg = 0x00203c18; + reg_write(REG_ZQC_CONF_ADDR, reg); + + /* {0x00015EC} - DDR PHY */ +#if defined(MV88F78X60) + reg = 0xF800AAA5; + if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) + reg = 0xF800A225; +#else + reg = 0xDE000025; +#if defined(MV88F672X) + reg = 0xF800A225; +#endif +#endif + reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg); + +#if (defined(MV88F78X60) || defined(MV88F672X)) + /* Registered DIMM support - supported only in AXP A0 devices */ + /* Currently supported for SPD detection only */ + /* + * Flow is according to the Registered DIMM chapter in the + * Functional Spec + */ + if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) { + DEBUG_INIT_S("DDR3 Training Sequence - Registered DIMM detected\n"); + + /* Set commands parity completion */ + reg = reg_read(REG_REGISTERED_DRAM_CTRL_ADDR); + reg &= ~REG_REGISTERED_DRAM_CTRL_PARITY_MASK; + reg |= 0x8; + reg_write(REG_REGISTERED_DRAM_CTRL_ADDR, reg); + + /* De-assert M_RESETn and assert M_CKE */ + reg_write(REG_SDRAM_INIT_CTRL_ADDR, + 1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS); + do { + reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) & + (1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS); + } while (reg); + + for (rc = 0; rc < SPD_RDIMM_RC_NUM; rc++) { + if (rc != 6 && rc != 7) { + /* Set CWA Command */ + reg = (REG_SDRAM_OPERATION_CMD_CWA & + ~(0xF << REG_SDRAM_OPERATION_CS_OFFS)); + reg |= ((dimm_info[0].dimm_rc[rc] & + REG_SDRAM_OPERATION_CWA_DATA_MASK) << + REG_SDRAM_OPERATION_CWA_DATA_OFFS); + reg |= rc << REG_SDRAM_OPERATION_CWA_RC_OFFS; + /* Configure - Set Delay - tSTAB/tMRD */ + if (rc == 2 || rc == 10) + reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS); + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + /* + * Poll the "cmd" field in the SDRAM OP + * register for 0x0 + */ + do { + reg = reg_read(REG_SDRAM_OPERATION_ADDR) & + (REG_SDRAM_OPERATION_CMD_MASK); + } while (reg); + } + } + } +#endif + + return MV_OK; +} + +/* + * Name: ddr3_div - this function divides integers + * Desc: + * Args: val - the value + * divider - the divider + * sub - substruction value + * Notes: + * Returns: required value + */ +u32 ddr3_div(u32 val, u32 divider, u32 sub) +{ + return val / divider + (val % divider > 0 ? 1 : 0) - sub; +} + +/* + * Name: ddr3_get_max_val + * Desc: + * Args: + * Notes: + * Returns: + */ +u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val) +{ +#ifdef DUNIT_STATIC + if (dimm_num > 0) { + if (spd_val >= static_val) + return spd_val; + else + return static_val; + } else { + return static_val; + } +#else + return spd_val; +#endif +} + +/* + * Name: ddr3_get_min_val + * Desc: + * Args: + * Notes: + * Returns: + */ +u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val) +{ +#ifdef DUNIT_STATIC + if (dimm_num > 0) { + if (spd_val <= static_val) + return spd_val; + else + return static_val; + } else + return static_val; +#else + return spd_val; +#endif +} +#endif diff --git a/drivers/ddr/mvebu/ddr3_write_leveling.c b/drivers/ddr/mvebu/ddr3_write_leveling.c new file mode 100644 index 0000000000..df3a3df4a6 --- /dev/null +++ b/drivers/ddr/mvebu/ddr3_write_leveling.c @@ -0,0 +1,1366 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "ddr3_hw_training.h" + +/* + * Debug + */ +#define DEBUG_WL_C(s, d, l) \ + DEBUG_WL_S(s); DEBUG_WL_D(d, l); DEBUG_WL_S("\n") +#define DEBUG_WL_FULL_C(s, d, l) \ + DEBUG_WL_FULL_S(s); DEBUG_WL_FULL_D(d, l); DEBUG_WL_FULL_S("\n") + +#ifdef MV_DEBUG_WL +#define DEBUG_RL_S(s) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s) +#define DEBUG_RL_D(d, l) \ + debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d) +#else +#define DEBUG_WL_S(s) +#define DEBUG_WL_D(d, l) +#endif + +#ifdef MV_DEBUG_WL_FULL +#define DEBUG_WL_FULL_S(s) puts(s) +#define DEBUG_WL_FULL_D(d, l) printf("%x", d) +#else +#define DEBUG_WL_FULL_S(s) +#define DEBUG_WL_FULL_D(d, l) +#endif + +#define WL_SUP_EXPECTED_DATA 0x21 +#define WL_SUP_READ_DRAM_ENTRY 0x8 + +static int ddr3_write_leveling_single_cs(u32 cs, u32 freq, int ratio_2to1, + u32 *result, + MV_DRAM_INFO *dram_info); +static void ddr3_write_ctrl_pup_reg(int bc_acc, u32 pup, u32 reg_addr, + u32 data); + +extern u16 odt_static[ODT_OPT][MAX_CS]; +extern u16 odt_dynamic[ODT_OPT][MAX_CS]; +extern u32 wl_sup_pattern[LEN_WL_SUP_PATTERN]; + +/* + * Name: ddr3_write_leveling_hw + * Desc: Execute Write leveling phase by HW + * Args: freq - current sequence frequency + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_write_leveling_hw(u32 freq, MV_DRAM_INFO *dram_info) +{ + u32 reg, phase, delay, cs, pup; +#ifdef MV88F67XX + int dpde_flag = 0; +#endif + /* Debug message - Start Read leveling procedure */ + DEBUG_WL_S("DDR3 - Write Leveling - Starting HW WL procedure\n"); + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + if (reg & (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)) { + dpde_flag = 1; + reg_write(REG_DUNIT_CTRL_LOW_ADDR, + reg & ~(1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)); + } +#endif + + reg = 1 << REG_DRAM_TRAINING_WL_OFFS; + /* Config the retest number */ + reg |= (COUNT_HW_WL << REG_DRAM_TRAINING_RETEST_OFFS); + reg |= (dram_info->cs_ena << (REG_DRAM_TRAINING_CS_OFFS)); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) | + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_SHADOW_ADDR, reg); + + /* Wait */ + do { + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) & + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + } while (reg); /* Wait for '0' */ + + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Check if Successful */ + if (reg & (1 << REG_DRAM_TRAINING_ERROR_OFFS)) { + /* + * Read results to arrays - Results are required for WL + * High freq Supplement and DQS Centralization + */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_PUP; + reg = + ddr3_read_pup_reg(PUP_WL_MODE, cs, + pup); + phase = + (reg >> REG_PHY_PHASE_OFFS) & + PUP_PHASE_MASK; + delay = reg & PUP_DELAY_MASK; + dram_info->wl_val[cs][pup][P] = phase; + dram_info->wl_val[cs][pup][D] = delay; + dram_info->wl_val[cs][pup][S] = + WL_HI_FREQ_STATE - 1; + reg = + ddr3_read_pup_reg(PUP_WL_MODE + 0x1, + cs, pup); + dram_info->wl_val[cs][pup][DQS] = + (reg & 0x3F); + } + +#ifdef MV_DEBUG_WL + /* Debug message - Print res for cs[i]: cs,PUP,Phase,Delay */ + DEBUG_WL_S("DDR3 - Write Leveling - Write Leveling Cs - "); + DEBUG_WL_D((u32) cs, 1); + DEBUG_WL_S(" Results:\n"); + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_PUP; + DEBUG_WL_S("DDR3 - Write Leveling - PUP: "); + DEBUG_WL_D((u32) pup, 1); + DEBUG_WL_S(", Phase: "); + DEBUG_WL_D((u32) + dram_info->wl_val[cs][pup] + [P], 1); + DEBUG_WL_S(", Delay: "); + DEBUG_WL_D((u32) + dram_info->wl_val[cs][pup] + [D], 2); + DEBUG_WL_S("\n"); + } +#endif + } + } + + /* Dynamic pad issue (BTS669) during WL */ +#ifdef MV88F67XX + if (dpde_flag) { + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR) | + (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS); + reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + } +#endif + + DEBUG_WL_S("DDR3 - Write Leveling - HW WL Ended Successfully\n"); + + return MV_OK; + } else { + DEBUG_WL_S("DDR3 - Write Leveling - HW WL Error\n"); + return MV_FAIL; + } +} + +/* + * Name: ddr3_wl_supplement + * Desc: Write Leveling Supplement + * Args: dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_wl_supplement(MV_DRAM_INFO *dram_info) +{ + u32 cs, cnt, pup_num, sum, phase, delay, max_pup_num, pup, sdram_offset; + u32 tmp_count, ecc, reg; + u32 ddr_width, tmp_pup, idx; + u32 sdram_pup_val, uj; + u32 one_clk_err = 0, align_err = 0, no_err = 0, err = 0, err_n = 0; + u32 sdram_data[LEN_WL_SUP_PATTERN] __aligned(32) = { 0 }; + + ddr_width = dram_info->ddr_width; + no_err = 0; + + DEBUG_WL_S("DDR3 - Write Leveling Hi-Freq Supplement - Starting\n"); + + switch (ddr_width) { + /* Data error from pos-adge to pos-adge */ + case 16: + one_clk_err = 4; + align_err = 4; + break; + case 32: + one_clk_err = 8; + align_err = 8; + break; + case 64: + one_clk_err = 0x10; + align_err = 0x10; + break; + default: + DEBUG_WL_S("Error - bus width!!!\n"); + return MV_FAIL; + } + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_WL_S("DDR3 - Write Leveling Hi-Freq Supplement - SW Override Enabled\n"); + reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + tmp_count = 0; + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + sum = 0; + /* + * 2 iterations loop: 1)actual WL results 2) fix WL + * if needed + */ + for (cnt = 0; cnt < COUNT_WL_HI_FREQ; cnt++) { + DEBUG_WL_C("COUNT = ", cnt, 1); + for (ecc = 0; ecc < (dram_info->ecc_ena + 1); + ecc++) { + if (ecc) { + DEBUG_WL_S("ECC PUP:\n"); + } else { + DEBUG_WL_S("DATA PUP:\n"); + } + + max_pup_num = + dram_info->num_of_std_pups * (1 - + ecc) + + ecc; + /* ECC Support - Switch ECC Mux on ecc=1 */ + reg = + (reg_read(REG_DRAM_TRAINING_2_ADDR) + & ~(1 << + REG_DRAM_TRAINING_2_ECC_MUX_OFFS)); + reg |= + (dram_info->ecc_ena * + ecc << + REG_DRAM_TRAINING_2_ECC_MUX_OFFS); + reg_write(REG_DRAM_TRAINING_2_ADDR, + reg); + ddr3_reset_phy_read_fifo(); + + /* Write to memory */ + sdram_offset = + tmp_count * (SDRAM_CS_SIZE + 1) + + 0x200; + if (MV_OK != ddr3_dram_sram_burst((u32) + wl_sup_pattern, + sdram_offset, + LEN_WL_SUP_PATTERN)) + return MV_FAIL; + + /* Read from memory */ + if (MV_OK != + ddr3_dram_sram_burst(sdram_offset, + (u32) + sdram_data, + LEN_WL_SUP_PATTERN)) + return MV_FAIL; + + /* Print the buffer */ + for (uj = 0; uj < LEN_WL_SUP_PATTERN; + uj++) { + if ((uj % 4 == 0) && (uj != 0)) { + DEBUG_WL_S("\n"); + } + DEBUG_WL_D(sdram_data[uj], + 8); + DEBUG_WL_S(" "); + } + + /* Check pup which DQS/DATA is error */ + for (pup = 0; pup < max_pup_num; pup++) { + /* ECC support - bit 8 */ + pup_num = (ecc) ? ECC_PUP : pup; + if (pup < 4) { /* lower 32 bit */ + tmp_pup = pup; + idx = + WL_SUP_READ_DRAM_ENTRY; + } else { /* higher 32 bit */ + tmp_pup = pup - 4; + idx = + WL_SUP_READ_DRAM_ENTRY + + 1; + } + DEBUG_WL_S("\nCS: "); + DEBUG_WL_D((u32) cs, 1); + DEBUG_WL_S(" PUP: "); + DEBUG_WL_D((u32) pup_num, 1); + DEBUG_WL_S("\n"); + sdram_pup_val = + ((sdram_data[idx] >> + ((tmp_pup) * 8)) & 0xFF); + DEBUG_WL_C("Actual Data = ", + sdram_pup_val, 2); + DEBUG_WL_C("Expected Data = ", + (WL_SUP_EXPECTED_DATA + + pup), 2); + /* + * ALINGHMENT: calculate + * expected data vs actual data + */ + err = + (WL_SUP_EXPECTED_DATA + + pup) - sdram_pup_val; + /* + * CLOCK LONG: calculate + * expected data vs actual data + */ + err_n = + sdram_pup_val - + (WL_SUP_EXPECTED_DATA + + pup); + DEBUG_WL_C("err = ", err, 2); + DEBUG_WL_C("err_n = ", err_n, + 2); + if (err == no_err) { + /* PUP is correct - increment State */ + dram_info->wl_val[cs] + [pup_num] + [S] = 1; + } else if (err_n == one_clk_err) { + /* clock is longer than DQS */ + phase = + ((dram_info->wl_val + [cs] + [pup_num][P] + + WL_HI_FREQ_SHIFT) + % MAX_PHASE_2TO1); + dram_info->wl_val[cs] + [pup_num] + [P] = phase; + delay = + dram_info->wl_val + [cs][pup_num] + [D]; + DEBUG_WL_S("#### Clock is longer than DQS more than one clk cycle ####\n"); + ddr3_write_pup_reg + (PUP_WL_MODE, cs, + pup * (1 - ecc) + + ECC_PUP * ecc, + phase, delay); + } else if (err == align_err) { + /* clock is align to DQS */ + phase = + dram_info->wl_val + [cs][pup_num] + [P]; + delay = + dram_info->wl_val + [cs][pup_num] + [D]; + DEBUG_WL_S("#### Alignment PUPS problem ####\n"); + if ((phase == 0) + || ((phase == 1) + && (delay <= + 0x10))) { + DEBUG_WL_S("#### Warning - Possible Layout Violation (DQS is longer than CLK)####\n"); + } + + phase = 0x0; + delay = 0x0; + dram_info->wl_val[cs] + [pup_num] + [P] = phase; + dram_info->wl_val[cs] + [pup_num] + [D] = delay; + ddr3_write_pup_reg + (PUP_WL_MODE, cs, + pup * (1 - ecc) + + ECC_PUP * ecc, + phase, delay); + } + /* Stop condition for ECC phase */ + pup = (ecc) ? max_pup_num : pup; + } + + /* ECC Support - Disable ECC MUX */ + reg = + (reg_read(REG_DRAM_TRAINING_2_ADDR) + & ~(1 << + REG_DRAM_TRAINING_2_ECC_MUX_OFFS)); + reg_write(REG_DRAM_TRAINING_2_ADDR, + reg); + } + } + + for (pup = 0; pup < dram_info->num_of_std_pups; pup++) + sum += dram_info->wl_val[cs][pup][S]; + + if (dram_info->ecc_ena) + sum += dram_info->wl_val[cs][ECC_PUP][S]; + + /* Checks if any pup is not locked after the change */ + if (sum < (WL_HI_FREQ_STATE * (dram_info->num_of_total_pups))) { + DEBUG_WL_C("DDR3 - Write Leveling Hi-Freq Supplement - didn't work for Cs - ", + (u32) cs, 1); + return MV_FAIL; + } + tmp_count++; + } + } + + dram_info->wl_max_phase = 0; + dram_info->wl_min_phase = 10; + + /* + * Read results to arrays - Results are required for DQS Centralization + */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + for (pup = 0; pup < dram_info->num_of_total_pups; pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_PUP; + reg = ddr3_read_pup_reg(PUP_WL_MODE, cs, pup); + phase = + (reg >> REG_PHY_PHASE_OFFS) & + PUP_PHASE_MASK; + if (phase > dram_info->wl_max_phase) + dram_info->wl_max_phase = phase; + if (phase < dram_info->wl_min_phase) + dram_info->wl_min_phase = phase; + } + } + } + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | + (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); + reg_write(REG_DRAM_TRAINING_1_ADDR, reg); + + DEBUG_WL_S("DDR3 - Write Leveling Hi-Freq Supplement - Ended Successfully\n"); + + return MV_OK; +} + +/* + * Name: ddr3_write_leveling_hw_reg_dimm + * Desc: Execute Write leveling phase by HW + * Args: freq - current sequence frequency + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_write_leveling_hw_reg_dimm(u32 freq, MV_DRAM_INFO *dram_info) +{ + u32 reg, phase, delay, cs, pup, pup_num; + __maybe_unused int dpde_flag = 0; + + /* Debug message - Start Read leveling procedure */ + DEBUG_WL_S("DDR3 - Write Leveling - Starting HW WL procedure\n"); + + if (dram_info->num_cs > 2) { + DEBUG_WL_S("DDR3 - Write Leveling - HW WL Ended Successfully\n"); + return MV_NO_CHANGE; + } + + /* If target freq = 400 move clock start point */ + /* Write to control PUP to Control Deskew Regs */ + if (freq <= DDR_400) { + for (pup = 0; pup <= dram_info->num_of_total_pups; pup++) { + /* PUP_DELAY_MASK 0x1F */ + /* reg = 0x0C10001F + (uj << 16); */ + ddr3_write_ctrl_pup_reg(1, pup, CNTRL_PUP_DESKEW + pup, + 0x1F); + } + } + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + if (reg & (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)) { + dpde_flag = 1; + reg_write(REG_DUNIT_CTRL_LOW_ADDR, + reg & ~(1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)); + } +#endif + + reg = (1 << REG_DRAM_TRAINING_WL_OFFS); + /* Config the retest number */ + reg |= (COUNT_HW_WL << REG_DRAM_TRAINING_RETEST_OFFS); + reg |= (dram_info->cs_ena << (REG_DRAM_TRAINING_CS_OFFS)); + reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ + + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) | + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + reg_write(REG_DRAM_TRAINING_SHADOW_ADDR, reg); + + /* Wait */ + do { + reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) & + (1 << REG_DRAM_TRAINING_AUTO_OFFS); + } while (reg); /* Wait for '0' */ + + reg = reg_read(REG_DRAM_TRAINING_ADDR); + /* Check if Successful */ + if (reg & (1 << REG_DRAM_TRAINING_ERROR_OFFS)) { + /* + * Read results to arrays - Results are required for WL High + * freq Supplement and DQS Centralization + */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + if (pup == dram_info->num_of_std_pups + && dram_info->ecc_ena) + pup = ECC_BIT; + reg = + ddr3_read_pup_reg(PUP_WL_MODE, cs, + pup); + phase = + (reg >> REG_PHY_PHASE_OFFS) & + PUP_PHASE_MASK; + delay = reg & PUP_DELAY_MASK; + dram_info->wl_val[cs][pup][P] = phase; + dram_info->wl_val[cs][pup][D] = delay; + if ((phase == 1) && (delay >= 0x1D)) { + /* + * Need to do it here for + * uncorrect WL values + */ + ddr3_write_pup_reg(PUP_WL_MODE, + cs, pup, 0, + 0); + dram_info->wl_val[cs][pup][P] = + 0; + dram_info->wl_val[cs][pup][D] = + 0; + } + dram_info->wl_val[cs][pup][S] = + WL_HI_FREQ_STATE - 1; + reg = + ddr3_read_pup_reg(PUP_WL_MODE + 0x1, + cs, pup); + dram_info->wl_val[cs][pup][DQS] = + (reg & 0x3F); + } +#ifdef MV_DEBUG_WL + /* + * Debug message - Print res for cs[i]: + * cs,PUP,Phase,Delay + */ + DEBUG_WL_S("DDR3 - Write Leveling - Write Leveling Cs - "); + DEBUG_WL_D((u32) cs, 1); + DEBUG_WL_S(" Results:\n"); + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + DEBUG_WL_S + ("DDR3 - Write Leveling - PUP: "); + DEBUG_WL_D((u32) pup, 1); + DEBUG_WL_S(", Phase: "); + DEBUG_WL_D((u32) + dram_info->wl_val[cs][pup] + [P], 1); + DEBUG_WL_S(", Delay: "); + DEBUG_WL_D((u32) + dram_info->wl_val[cs][pup] + [D], 2); + DEBUG_WL_S("\n"); + } +#endif + } + } + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + if (dpde_flag) { + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR) | + (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS); + reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + } +#endif + DEBUG_WL_S("DDR3 - Write Leveling - HW WL Ended Successfully\n"); + + /* If target freq = 400 move clock back */ + /* Write to control PUP to Control Deskew Regs */ + if (freq <= DDR_400) { + for (pup = 0; pup <= dram_info->num_of_total_pups; + pup++) { + ddr3_write_ctrl_pup_reg(1, pup, + CNTRL_PUP_DESKEW + pup, 0); + } + } + + return MV_OK; + } else { + /* Configure Each PUP with locked leveling settings */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + for (pup = 0; + pup < dram_info->num_of_total_pups; + pup++) { + /* ECC support - bit 8 */ + pup_num = (pup == dram_info->num_of_std_pups) ? + ECC_BIT : pup; + ddr3_write_pup_reg(PUP_WL_MODE, cs, + pup_num, 0, 0); + } + } + } + + reg_write(REG_DRAM_TRAINING_ADDR, 0); + + /* If target freq = 400 move clock back */ + /* Write to control PUP to Control Deskew Regs */ + if (freq <= DDR_400) { + for (pup = 0; pup <= dram_info->num_of_total_pups; + pup++) { + ddr3_write_ctrl_pup_reg(1, pup, + CNTRL_PUP_DESKEW + pup, 0); + } + } + + DEBUG_WL_S("DDR3 - Write Leveling - HW WL Ended Successfully\n"); + return MV_NO_CHANGE; + } +} + +/* + * Name: ddr3_write_leveling_sw + * Desc: Execute Write leveling phase by SW + * Args: freq - current sequence frequency + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_write_leveling_sw(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info) +{ + u32 reg, cs, cnt, pup, max_pup_num; + u32 res[MAX_CS]; + max_pup_num = dram_info->num_of_total_pups; + __maybe_unused int dpde_flag = 0; + + /* Debug message - Start Write leveling procedure */ + DEBUG_WL_S("DDR3 - Write Leveling - Starting SW WL procedure\n"); + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + if (reg & (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)) { + dpde_flag = 1; + reg_write(REG_DUNIT_CTRL_LOW_ADDR, + reg & ~(1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)); + } +#endif + + /* Set Output buffer-off to all CS and correct ODT values */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_ODT_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + reg |= (1 << REG_DDR3_MR1_OUTBUF_DIS_OFFS); + + /* 0x15D0 - DDR3 MR0 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Qoff and RTT Values are set for all Cs\n"); + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_WL_FULL_S("DDR3 - Write Leveling - SW Override Enabled\n"); + + /* Enable PHY write leveling mode */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_WL_MODE_OFFS); + /* [2] = 0 - TrnWLMode - Enable */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + /* Reset WL results arry */ + memset(dram_info->wl_val, 0, sizeof(u32) * MAX_CS * MAX_PUP_NUM * 7); + + /* Loop for each cs */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + DEBUG_WL_FULL_C("DDR3 - Write Leveling - Starting working with Cs - ", + (u32) cs, 1); + /* Refresh X9 current cs */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Refresh X9\n"); + for (cnt = 0; cnt < COUNT_WL_RFRS; cnt++) { + reg = + REG_SDRAM_OPERATION_CMD_RFRS & ~(1 << + (REG_SDRAM_OPERATION_CS_OFFS + + cs)); + /* [3-0] = 0x2 - refresh, [11-8] - enable current cs */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); /* 0x1418 - SDRAM Operation Register */ + + do { + reg = + ((reg_read + (REG_SDRAM_OPERATION_ADDR)) & + REG_SDRAM_OPERATION_CMD_RFRS_DONE); + } while (reg); /* Wait for '0' */ + } + + /* Configure MR1 in Cs[CsNum] - write leveling on, output buffer on */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Configure MR1 for current Cs: WL-on,OB-on\n"); + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_OUTBUF_WL_MASK; + /* Set ODT Values */ + reg &= REG_DDR3_MR1_ODT_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + /* Enable WL MODE */ + reg |= (1 << REG_DDR3_MR1_WL_ENA_OFFS); + /* [7]=1, [12]=0 - Output Buffer and write leveling enabled */ + reg_write(REG_DDR3_MR1_ADDR, reg); /* 0x15D4 - DDR3 MR1 Register */ + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + + /* Write leveling cs[cs] */ + if (MV_OK != + ddr3_write_leveling_single_cs(cs, freq, ratio_2to1, + (u32 *)(res + cs), + dram_info)) { + DEBUG_WL_FULL_C("DDR3 - Write Leveling single Cs - FAILED - Cs - ", + (u32) cs, 1); + for (pup = 0; pup < max_pup_num; pup++) { + if (((res[cs] >> pup) & 0x1) == 0) { + DEBUG_WL_C("Failed Byte : ", + pup, 1); + } + } + return MV_FAIL; + } + + /* Set TrnWLDeUpd - After each CS is done */ + reg = reg_read(REG_TRAINING_WL_ADDR) | + (1 << REG_TRAINING_WL_CS_DONE_OFFS); + /* 0x16AC - Training Write leveling register */ + reg_write(REG_TRAINING_WL_ADDR, reg); + + /* + * Debug message - Finished Write leveling cs[cs] - + * each PUP Fail/Success + */ + DEBUG_WL_FULL_C("DDR3 - Write Leveling - Finished Cs - ", (u32) cs, + 1); + DEBUG_WL_FULL_C("DDR3 - Write Leveling - The Results: 1-PUP locked, 0-PUP failed -", + (u32) res[cs], 3); + + /* + * Configure MR1 in cs[cs] - write leveling off (0), + * output buffer off (1) + */ + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_OUTBUF_WL_MASK; + reg |= (1 << REG_DDR3_MR1_OUTBUF_DIS_OFFS); + /* No need to sort ODT since it is same CS */ + /* 0x15D4 - DDR3 MR1 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + + /* Disable WL Mode */ + /* [2]=1 - TrnWLMode - Disable */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg |= (1 << REG_DRAM_TRAINING_2_WL_MODE_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Set Output buffer-on to all CS and correct ODT values */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_ODT_MASK; + reg &= REG_DDR3_MR1_OUTBUF_WL_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + + /* 0x15D0 - DDR3 MR1 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + if (dpde_flag) { + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR) | + (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS); + reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + } +#endif + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Finished WL procedure for all Cs\n"); + + return MV_OK; +} + +#if !defined(MV88F672X) +/* + * Name: ddr3_write_leveling_sw + * Desc: Execute Write leveling phase by SW + * Args: freq - current sequence frequency + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +int ddr3_write_leveling_sw_reg_dimm(u32 freq, int ratio_2to1, + MV_DRAM_INFO *dram_info) +{ + u32 reg, cs, cnt, pup; + u32 res[MAX_CS]; + __maybe_unused int dpde_flag = 0; + + /* Debug message - Start Write leveling procedure */ + DEBUG_WL_S("DDR3 - Write Leveling - Starting SW WL procedure\n"); + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR); + if (reg & (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)) { + dpde_flag = 1; + reg_write(REG_DUNIT_CTRL_LOW_ADDR, + reg & ~(1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS)); + } +#endif + + /* If target freq = 400 move clock start point */ + /* Write to control PUP to Control Deskew Regs */ + if (freq <= DDR_400) { + for (pup = 0; pup <= dram_info->num_of_total_pups; pup++) { + /* PUP_DELAY_MASK 0x1F */ + /* reg = 0x0C10001F + (uj << 16); */ + ddr3_write_ctrl_pup_reg(1, pup, CNTRL_PUP_DESKEW + pup, + 0x1F); + } + } + + /* Set Output buffer-off to all CS and correct ODT values */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_ODT_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + reg |= (1 << REG_DDR3_MR1_OUTBUF_DIS_OFFS); + + /* 0x15D0 - DDR3 MR0 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Qoff and RTT Values are set for all Cs\n"); + + /* Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* [0] = 1 - Enable SW override */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + DEBUG_WL_FULL_S("DDR3 - Write Leveling - SW Override Enabled\n"); + + /* Enable PHY write leveling mode */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & + ~(1 << REG_DRAM_TRAINING_2_WL_MODE_OFFS); + /* [2] = 0 - TrnWLMode - Enable */ + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Loop for each cs */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + DEBUG_WL_FULL_C("DDR3 - Write Leveling - Starting working with Cs - ", + (u32) cs, 1); + + /* Refresh X9 current cs */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Refresh X9\n"); + for (cnt = 0; cnt < COUNT_WL_RFRS; cnt++) { + reg = + REG_SDRAM_OPERATION_CMD_RFRS & ~(1 << + (REG_SDRAM_OPERATION_CS_OFFS + + cs)); + /* [3-0] = 0x2 - refresh, [11-8] - enable current cs */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); /* 0x1418 - SDRAM Operation Register */ + + do { + reg = + ((reg_read + (REG_SDRAM_OPERATION_ADDR)) & + REG_SDRAM_OPERATION_CMD_RFRS_DONE); + } while (reg); /* Wait for '0' */ + } + + /* + * Configure MR1 in Cs[CsNum] - write leveling on, + * output buffer on + */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Configure MR1 for current Cs: WL-on,OB-on\n"); + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_OUTBUF_WL_MASK; + /* Set ODT Values */ + reg &= REG_DDR3_MR1_ODT_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + /* Enable WL MODE */ + reg |= (1 << REG_DDR3_MR1_WL_ENA_OFFS); + /* + * [7]=1, [12]=0 - Output Buffer and write leveling + * enabled + */ + /* 0x15D4 - DDR3 MR1 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + + /* Write leveling cs[cs] */ + if (MV_OK != + ddr3_write_leveling_single_cs(cs, freq, ratio_2to1, + (u32 *)(res + cs), + dram_info)) { + DEBUG_WL_FULL_C("DDR3 - Write Leveling single Cs - FAILED - Cs - ", + (u32) cs, 1); + return MV_FAIL; + } + + /* Set TrnWLDeUpd - After each CS is done */ + reg = reg_read(REG_TRAINING_WL_ADDR) | + (1 << REG_TRAINING_WL_CS_DONE_OFFS); + /* 0x16AC - Training Write leveling register */ + reg_write(REG_TRAINING_WL_ADDR, reg); + + /* + * Debug message - Finished Write leveling cs[cs] - + * each PUP Fail/Success + */ + DEBUG_WL_FULL_C("DDR3 - Write Leveling - Finished Cs - ", (u32) cs, + 1); + DEBUG_WL_FULL_C("DDR3 - Write Leveling - The Results: 1-PUP locked, 0-PUP failed -", + (u32) res[cs], 3); + + /* Configure MR1 in cs[cs] - write leveling off (0), output buffer off (1) */ + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_OUTBUF_WL_MASK; + reg |= (1 << REG_DDR3_MR1_OUTBUF_DIS_OFFS); + /* No need to sort ODT since it is same CS */ + /* 0x15D4 - DDR3 MR1 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + + /* Disable WL Mode */ + /* [2]=1 - TrnWLMode - Disable */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg |= (1 << REG_DRAM_TRAINING_2_WL_MODE_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Disable SW override - Must be in a different stage */ + /* [0]=0 - Enable SW override */ + reg = reg_read(REG_DRAM_TRAINING_2_ADDR); + reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); + /* 0x15B8 - Training SW 2 Register */ + reg_write(REG_DRAM_TRAINING_2_ADDR, reg); + + /* Set Output buffer-on to all CS and correct ODT values */ + for (cs = 0; cs < MAX_CS; cs++) { + if (dram_info->cs_ena & (1 << cs)) { + reg = reg_read(REG_DDR3_MR1_ADDR) & + REG_DDR3_MR1_ODT_MASK; + reg &= REG_DDR3_MR1_OUTBUF_WL_MASK; + reg |= odt_static[dram_info->cs_ena][cs]; + + /* 0x15D0 - DDR3 MR1 Register */ + reg_write(REG_DDR3_MR1_ADDR, reg); + /* Issue MRS Command to current cs */ + reg = REG_SDRAM_OPERATION_CMD_MR1 & + ~(1 << (REG_SDRAM_OPERATION_CS_OFFS + cs)); + /* + * [3-0] = 0x4 - MR1 Command, [11-8] - + * enable current cs + */ + /* 0x1418 - SDRAM Operation Register */ + reg_write(REG_SDRAM_OPERATION_ADDR, reg); + + udelay(MRS_DELAY); + } + } + +#ifdef MV88F67XX + /* Dynamic pad issue (BTS669) during WL */ + if (dpde_flag) { + reg = reg_read(REG_DUNIT_CTRL_LOW_ADDR) | + (1 << REG_DUNIT_CTRL_LOW_DPDE_OFFS); + reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg); + } +#endif + + /* If target freq = 400 move clock back */ + /* Write to control PUP to Control Deskew Regs */ + if (freq <= DDR_400) { + for (pup = 0; pup <= dram_info->num_of_total_pups; pup++) { + ddr3_write_ctrl_pup_reg(1, pup, CNTRL_PUP_DESKEW + pup, + 0); + } + } + + DEBUG_WL_FULL_S("DDR3 - Write Leveling - Finished WL procedure for all Cs\n"); + return MV_OK; +} +#endif + +/* + * Name: ddr3_write_leveling_single_cs + * Desc: Execute Write leveling for single Chip select + * Args: cs - current chip select + * freq - current sequence frequency + * result - res array + * dram_info - main struct + * Notes: + * Returns: MV_OK if success, MV_FAIL if fail. + */ +static int ddr3_write_leveling_single_cs(u32 cs, u32 freq, int ratio_2to1, + u32 *result, MV_DRAM_INFO *dram_info) +{ + u32 reg, pup_num, delay, phase, phaseMax, max_pup_num, pup, + max_pup_mask; + + max_pup_num = dram_info->num_of_total_pups; + *result = 0; + u32 flag[MAX_PUP_NUM] = { 0 }; + + DEBUG_WL_FULL_C("DDR3 - Write Leveling Single Cs - WL for Cs - ", + (u32) cs, 1); + + switch (max_pup_num) { + case 2: + max_pup_mask = 0x3; + break; + case 4: + max_pup_mask = 0xf; + DEBUG_WL_C("max_pup_mask = ", max_pup_mask, 3); + break; + case 5: + max_pup_mask = 0x1f; + DEBUG_WL_C("max_pup_mask = ", max_pup_mask, 3); + break; + case 8: + max_pup_mask = 0xff; + DEBUG_WL_C("max_pup_mask = ", max_pup_mask, 3); + break; + case 9: + max_pup_mask = 0x1ff; + DEBUG_WL_C("max_pup_mask = ", max_pup_mask, 3); + break; + default: + DEBUG_WL_C("ddr3_write_leveling_single_cs wrong max_pup_num = ", + max_pup_num, 3); + return MV_FAIL; + } + + /* CS ODT Override */ + reg = reg_read(REG_SDRAM_ODT_CTRL_HIGH_ADDR) & + REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK; + reg |= (REG_SDRAM_ODT_CTRL_HIGH_OVRD_ENA << (2 * cs)); + /* Set 0x3 - Enable ODT on the curent cs and disable on other cs */ + /* 0x1498 - SDRAM ODT Control high */ + reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, reg); + + DEBUG_WL_FULL_S("DDR3 - Write Leveling Single Cs - ODT Asserted for current Cs\n"); + + /* tWLMRD Delay */ + /* Delay of minimum 40 Dram clock cycles - 20 Tclk cycles */ + udelay(1); + + /* [1:0] - current cs number */ + reg = (reg_read(REG_TRAINING_WL_ADDR) & REG_TRAINING_WL_CS_MASK) | cs; + reg |= (1 << REG_TRAINING_WL_UPD_OFFS); /* [2] - trnWLCsUpd */ + /* 0x16AC - Training Write leveling register */ + reg_write(REG_TRAINING_WL_ADDR, reg); + + /* Broadcast to all PUPs: Reset DQS phase, reset leveling delay */ + ddr3_write_pup_reg(PUP_WL_MODE, cs, PUP_BC, 0, 0); + + /* Seek Edge */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling Single Cs - Seek Edge - Current Cs\n"); + + /* Drive DQS high for one cycle - All data PUPs */ + DEBUG_WL_FULL_S("DDR3 - Write Leveling Single Cs - Seek Edge - Driving DQS high for one cycle\n"); + if (!ratio_2to1) { + reg = (reg_read(REG_TRAINING_WL_ADDR) & + REG_TRAINING_WL_RATIO_MASK) | REG_TRAINING_WL_1TO1; + } else { + reg = (reg_read(REG_TRAINING_WL_ADDR) & + REG_TRAINING_WL_RATIO_MASK) | REG_TRAINING_WL_2TO1; + } + /* 0x16AC - Training Write leveling register */ + reg_write(REG_TRAINING_WL_ADDR, reg); + + /* Wait tWLdelay */ + do { + /* [29] - trnWLDelayExp */ + reg = (reg_read(REG_TRAINING_WL_ADDR)) & + REG_TRAINING_WL_DELAYEXP_MASK; + } while (reg == 0x0); /* Wait for '1' */ + + /* Read WL res */ + reg = (reg_read(REG_TRAINING_WL_ADDR) >> REG_TRAINING_WL_RESULTS_OFFS) & + REG_TRAINING_WL_RESULTS_MASK; + /* [28:20] - TrnWLResult */ + + if (!ratio_2to1) /* Different phase options for 2:1 or 1:1 modes */ + phaseMax = MAX_PHASE_1TO1; + else + phaseMax = MAX_PHASE_2TO1; + + DEBUG_WL_FULL_S("DDR3 - Write Leveling Single Cs - Seek Edge - Shift DQS + Octet Leveling\n"); + + /* Shift DQS + Octet leveling */ + for (phase = 0; phase < phaseMax; phase++) { + for (delay = 0; delay < MAX_DELAY; delay++) { + /* Broadcast to all PUPs: DQS phase,leveling delay */ + ddr3_write_pup_reg(PUP_WL_MODE, cs, PUP_BC, phase, + delay); + + udelay(1); /* Delay of 3 Tclk cycles */ + + DEBUG_WL_FULL_S("DDR3 - Write Leveling Single Cs - Seek Edge: Phase = "); + DEBUG_WL_FULL_D((u32) phase, 1); + DEBUG_WL_FULL_S(", Delay = "); + DEBUG_WL_FULL_D((u32) delay, 1); + DEBUG_WL_FULL_S(", Counter = "); + DEBUG_WL_FULL_D((u32) i, 1); + DEBUG_WL_FULL_S("\n"); + + /* Drive DQS high for one cycle - All data PUPs */ + if (!ratio_2to1) { + reg = (reg_read(REG_TRAINING_WL_ADDR) & + REG_TRAINING_WL_RATIO_MASK) | + REG_TRAINING_WL_1TO1; + } else { + reg = (reg_read(REG_TRAINING_WL_ADDR) & + REG_TRAINING_WL_RATIO_MASK) | + REG_TRAINING_WL_2TO1; + } + reg_write(REG_TRAINING_WL_ADDR, reg); /* 0x16AC */ + + /* Wait tWLdelay */ + do { + reg = (reg_read(REG_TRAINING_WL_ADDR)) & + REG_TRAINING_WL_DELAYEXP_MASK; + } while (reg == 0x0); /* [29] Wait for '1' */ + + /* Read WL res */ + reg = reg_read(REG_TRAINING_WL_ADDR); + reg = (reg >> REG_TRAINING_WL_RESULTS_OFFS) & + REG_TRAINING_WL_RESULTS_MASK; /* [28:20] */ + + DEBUG_WL_FULL_C("DDR3 - Write Leveling Single Cs - Seek Edge: Results = ", + (u32) reg, 3); + + /* Update State machine */ + for (pup = 0; pup < (max_pup_num); pup++) { + /* ECC support - bit 8 */ + pup_num = (pup == dram_info->num_of_std_pups) ? + ECC_BIT : pup; + if (dram_info->wl_val[cs][pup][S] == 0) { + /* Update phase to PUP */ + dram_info->wl_val[cs][pup][P] = phase; + /* Update delay to PUP */ + dram_info->wl_val[cs][pup][D] = delay; + } + + if (((reg >> pup_num) & 0x1) == 0) + flag[pup_num] = 1; + + if (((reg >> pup_num) & 0x1) + && (flag[pup_num] == 1) + && (dram_info->wl_val[cs][pup][S] == 0)) { + /* + * If the PUP is locked now and in last + * counter states + */ + /* Go to next state */ + dram_info->wl_val[cs][pup][S] = 1; + /* Set res */ + *result = *result | (1 << pup_num); + } + } + + /* If all locked - Break the loops - Finished */ + if (*result == max_pup_mask) { + phase = phaseMax; + delay = MAX_DELAY; + DEBUG_WL_S("DDR3 - Write Leveling Single Cs - Seek Edge: All Locked\n"); + } + } + } + + /* Debug message - Print res for cs[i]: cs,PUP,Phase,Delay */ + DEBUG_WL_C("DDR3 - Write Leveling - Results for CS - ", (u32) cs, 1); + for (pup = 0; pup < (max_pup_num); pup++) { + DEBUG_WL_S("DDR3 - Write Leveling - PUP: "); + DEBUG_WL_D((u32) pup, 1); + DEBUG_WL_S(", Phase: "); + DEBUG_WL_D((u32) dram_info->wl_val[cs][pup][P], 1); + DEBUG_WL_S(", Delay: "); + DEBUG_WL_D((u32) dram_info->wl_val[cs][pup][D], 2); + DEBUG_WL_S("\n"); + } + + /* Check if some not locked and return error */ + if (*result != max_pup_mask) { + DEBUG_WL_S("DDR3 - Write Leveling - ERROR - not all PUPS were locked\n"); + return MV_FAIL; + } + + /* Configure Each PUP with locked leveling settings */ + for (pup = 0; pup < (max_pup_num); pup++) { + /* ECC support - bit 8 */ + pup_num = (pup == dram_info->num_of_std_pups) ? ECC_BIT : pup; + phase = dram_info->wl_val[cs][pup][P]; + delay = dram_info->wl_val[cs][pup][D]; + ddr3_write_pup_reg(PUP_WL_MODE, cs, pup_num, phase, delay); + } + + /* CS ODT Override */ + reg = reg_read(REG_SDRAM_ODT_CTRL_HIGH_ADDR) & + REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK; + /* 0x1498 - SDRAM ODT Control high */ + reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, reg); + + return MV_OK; +} + +/* + * Perform DDR3 Control PUP Indirect Write + */ +static void ddr3_write_ctrl_pup_reg(int bc_acc, u32 pup, u32 reg_addr, u32 data) +{ + u32 reg = 0; + + /* Store value for write */ + reg = (data & 0xFFFF); + + /* Set bit 26 for control PHY access */ + reg |= (1 << REG_PHY_CNTRL_OFFS); + + /* Configure BC or UC access to PHYs */ + if (bc_acc == 1) + reg |= (1 << REG_PHY_BC_OFFS); + else + reg |= (pup << REG_PHY_PUP_OFFS); + + /* Set PHY register address to write to */ + reg |= (reg_addr << REG_PHY_CS_OFFS); + + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR; + reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */ + + do { + reg = (reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR)) & + REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE; + } while (reg); /* Wait for '0' to mark the end of the transaction */ +} diff --git a/drivers/ddr/mvebu/xor.c b/drivers/ddr/mvebu/xor.c new file mode 100644 index 0000000000..66c96aef4e --- /dev/null +++ b/drivers/ddr/mvebu/xor.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "xor.h" +#include "xor_regs.h" + +static u32 xor_regs_ctrl_backup; +static u32 xor_regs_base_backup[MAX_CS]; +static u32 xor_regs_mask_backup[MAX_CS]; + +static void mv_xor_hal_init(u32 chan_num); +static int mv_xor_cmd_set(u32 chan, int command); +static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl); + +void mv_sys_xor_init(MV_DRAM_INFO *dram_info) +{ + u32 reg, ui, base, cs_count; + + xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); + for (ui = 0; ui < MAX_CS; ui++) + xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui)); + for (ui = 0; ui < MAX_CS; ui++) + xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui)); + + reg = 0; + for (ui = 0; ui < (dram_info->num_cs + 1); ui++) { + /* Enable Window x for each CS */ + reg |= (0x1 << (ui)); + /* Enable Window x for each CS */ + reg |= (0x3 << ((ui * 2) + 16)); + } + + reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg); + + /* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */ + base = (SRAM_BASE & 0xFFFF0000) | 0x1E00; + reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base); + /* Last window - Size - 64 MB */ + reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000); + + cs_count = 0; + for (ui = 0; ui < MAX_CS; ui++) { + if (dram_info->cs_ena & (1 << ui)) { + /* + * Window x - Base - 0x00000000, Attribute 0x0E - DRAM + */ + base = 0; + switch (ui) { + case 0: + base |= 0xE00; + break; + case 1: + base |= 0xD00; + break; + case 2: + base |= 0xB00; + break; + case 3: + base |= 0x700; + break; + } + + reg_write(XOR_BASE_ADDR_REG(0, cs_count), base); + + /* Window x - Size - 256 MB */ + reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000); + cs_count++; + } + } + + mv_xor_hal_init(1); + + return; +} + +void mv_sys_xor_finish(void) +{ + u32 ui; + + reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup); + for (ui = 0; ui < MAX_CS; ui++) + reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]); + for (ui = 0; ui < MAX_CS; ui++) + reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]); + + reg_write(XOR_ADDR_OVRD_REG(0, 0), 0); +} + +/* + * mv_xor_hal_init - Initialize XOR engine + * + * DESCRIPTION: + * This function initialize XOR unit. + * INPUT: + * None. + * + * OUTPUT: + * None. + * + * RETURN: + * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. + */ +static void mv_xor_hal_init(u32 chan_num) +{ + u32 i; + + /* Abort any XOR activity & set default configuration */ + for (i = 0; i < chan_num; i++) { + mv_xor_cmd_set(i, MV_STOP); + mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) | + (4 << XEXCR_DST_BURST_LIMIT_OFFS) | + (4 << XEXCR_SRC_BURST_LIMIT_OFFS)); + } +} + +/* + * mv_xor_ctrl_set - Set XOR channel control registers + * + * DESCRIPTION: + * + * INPUT: + * + * OUTPUT: + * None. + * + * RETURN: + * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. + * NOTE: + * This function does not modify the OperationMode field of control register. + * + */ +static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) +{ + u32 val; + + /* Update the XOR Engine [0..1] Configuration Registers (XExCR) */ + val = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) + & XEXCR_OPERATION_MODE_MASK; + xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK; + xor_ctrl |= val; + reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl); + + return MV_OK; +} + +int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high, + u32 init_val_low) +{ + u32 tmp; + + /* Parameter checking */ + if (chan >= MV_XOR_MAX_CHAN) + return MV_BAD_PARAM; + + if (MV_ACTIVE == mv_xor_state_get(chan)) + return MV_BUSY; + + if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) || + (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE)) + return MV_BAD_PARAM; + + /* Set the operation mode to Memory Init */ + tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); + tmp &= ~XEXCR_OPERATION_MODE_MASK; + tmp |= XEXCR_OPERATION_MODE_MEM_INIT; + reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp); + + /* + * Update the start_ptr field in XOR Engine [0..1] Destination Pointer + * Register (XExDPR0) + */ + reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr); + + /* + * Update the BlockSize field in the XOR Engine[0..1] Block Size + * Registers (XExBSR) + */ + reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + block_size); + + /* + * Update the field InitValL in the XOR Engine Initial Value Register + * Low (XEIVRL) + */ + reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low); + + /* + * Update the field InitValH in the XOR Engine Initial Value Register + * High (XEIVRH) + */ + reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high); + + /* Start transfer */ + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XESTART_MASK); + + return MV_OK; +} + +/* + * mv_xor_transfer - Transfer data from source to destination on one of + * three modes (XOR,CRC32,DMA) + * + * DESCRIPTION: + * This function initiates XOR channel, according to function parameters, + * in order to perform XOR or CRC32 or DMA transaction. + * To gain maximum performance the user is asked to keep the following + * restrictions: + * 1) Selected engine is available (not busy). + * 1) This module does not take into consideration CPU MMU issues. + * In order for the XOR engine to access the appropreate source + * and destination, address parameters must be given in system + * physical mode. + * 2) This API does not take care of cache coherency issues. The source, + * destination and in case of chain the descriptor list are assumed + * to be cache coherent. + * 4) Parameters validity. For example, does size parameter exceeds + * maximum byte count of descriptor mode (16M or 64K). + * + * INPUT: + * chan - XOR channel number. See MV_XOR_CHANNEL enumerator. + * xor_type - One of three: XOR, CRC32 and DMA operations. + * xor_chain_ptr - address of chain pointer + * + * OUTPUT: + * None. + * + * RETURS: + * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. + * + */ +int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr) +{ + u32 tmp; + + /* Parameter checking */ + if (chan >= MV_XOR_MAX_CHAN) { + debug("%s: ERR. Invalid chan num %d\n", __func__, chan); + return MV_BAD_PARAM; + } + + if (MV_ACTIVE == mv_xor_state_get(chan)) { + debug("%s: ERR. Channel is already active\n", __func__); + return MV_BUSY; + } + + if (0x0 == xor_chain_ptr) { + debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__); + return MV_BAD_PARAM; + } + + /* Read configuration register and mask the operation mode field */ + tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); + tmp &= ~XEXCR_OPERATION_MODE_MASK; + + switch (xor_type) { + case MV_XOR: + if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) { + debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n", + __func__); + return MV_BAD_PARAM; + } + + /* Set the operation mode to XOR */ + tmp |= XEXCR_OPERATION_MODE_XOR; + break; + + case MV_DMA: + if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) { + debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", + __func__); + return MV_BAD_PARAM; + } + + /* Set the operation mode to DMA */ + tmp |= XEXCR_OPERATION_MODE_DMA; + break; + + case MV_CRC32: + if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) { + debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", + __func__); + return MV_BAD_PARAM; + } + + /* Set the operation mode to CRC32 */ + tmp |= XEXCR_OPERATION_MODE_CRC; + break; + + default: + return MV_BAD_PARAM; + } + + /* Write the operation mode to the register */ + reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp); + + /* + * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor + * Pointer Register (XExNDPR) + */ + reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + xor_chain_ptr); + + /* Start transfer */ + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XESTART_MASK); + + return MV_OK; +} + +/* + * mv_xor_state_get - Get XOR channel state. + * + * DESCRIPTION: + * XOR channel activity state can be active, idle, paused. + * This function retrunes the channel activity state. + * + * INPUT: + * chan - the channel number + * + * OUTPUT: + * None. + * + * RETURN: + * XOR_CHANNEL_IDLE - If the engine is idle. + * XOR_CHANNEL_ACTIVE - If the engine is busy. + * XOR_CHANNEL_PAUSED - If the engine is paused. + * MV_UNDEFINED_STATE - If the engine state is undefind or there is no + * such engine + * + */ +int mv_xor_state_get(u32 chan) +{ + u32 state; + + /* Parameter checking */ + if (chan >= MV_XOR_MAX_CHAN) { + debug("%s: ERR. Invalid chan num %d\n", __func__, chan); + return MV_UNDEFINED_STATE; + } + + /* Read the current state */ + state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); + state &= XEXACTR_XESTATUS_MASK; + + /* Return the state */ + switch (state) { + case XEXACTR_XESTATUS_IDLE: + return MV_IDLE; + case XEXACTR_XESTATUS_ACTIVE: + return MV_ACTIVE; + case XEXACTR_XESTATUS_PAUSED: + return MV_PAUSED; + } + + return MV_UNDEFINED_STATE; +} + +/* + * mv_xor_cmd_set - Set command of XOR channel + * + * DESCRIPTION: + * XOR channel can be started, idle, paused and restarted. + * Paused can be set only if channel is active. + * Start can be set only if channel is idle or paused. + * Restart can be set only if channel is paused. + * Stop can be set only if channel is active. + * + * INPUT: + * chan - The channel number + * command - The command type (start, stop, restart, pause) + * + * OUTPUT: + * None. + * + * RETURN: + * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on + * undefind XOR engine mode + * + */ +static int mv_xor_cmd_set(u32 chan, int command) +{ + int state; + + /* Parameter checking */ + if (chan >= MV_XOR_MAX_CHAN) { + debug("%s: ERR. Invalid chan num %d\n", __func__, chan); + return MV_BAD_PARAM; + } + + /* Get the current state */ + state = mv_xor_state_get(chan); + + /* Command is start and current state is idle */ + if ((command == MV_START) && (state == MV_IDLE)) { + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XESTART_MASK); + return MV_OK; + } + /* Command is stop and current state is active */ + else if ((command == MV_STOP) && (state == MV_ACTIVE)) { + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XESTOP_MASK); + return MV_OK; + } + /* Command is paused and current state is active */ + else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) { + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XEPAUSE_MASK); + return MV_OK; + } + /* Command is restart and current state is paused */ + else if ((command == MV_RESTART) && (state == MV_PAUSED)) { + reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), + XEXACTR_XERESTART_MASK); + return MV_OK; + } + /* Command is stop and current state is active */ + else if ((command == MV_STOP) && (state == MV_IDLE)) + return MV_OK; + + /* Illegal command */ + debug("%s: ERR. Illegal command\n", __func__); + + return MV_BAD_PARAM; +} diff --git a/drivers/ddr/mvebu/xor.h b/drivers/ddr/mvebu/xor.h new file mode 100644 index 0000000000..353648758a --- /dev/null +++ b/drivers/ddr/mvebu/xor.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __XOR_H +#define __XOR_H + +#include "ddr3_hw_training.h" + +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together */ + +/* + * This enumerator describes the type of functionality the XOR channel + * can have while using the same data structures. + */ +enum xor_type { + MV_XOR, /* XOR channel functions as XOR accelerator */ + MV_DMA, /* XOR channel functions as IDMA channel */ + MV_CRC32 /* XOR channel functions as CRC 32 calculator */ +}; + +/* + * This enumerator describes the set of commands that can be applied on + * an engine (e.g. IDMA, XOR). Appling a comman depends on the current + * status (see MV_STATE enumerator) + * Start can be applied only when status is IDLE + * Stop can be applied only when status is IDLE, ACTIVE or PAUSED + * Pause can be applied only when status is ACTIVE + * Restart can be applied only when status is PAUSED + */ +enum mv_command { + MV_START, /* Start */ + MV_STOP, /* Stop */ + MV_PAUSE, /* Pause */ + MV_RESTART /* Restart */ +}; + +/* + * This enumerator describes the set of state conditions. + * Moving from one state to other is stricted. + */ +enum mv_state { + MV_IDLE, + MV_ACTIVE, + MV_PAUSED, + MV_UNDEFINED_STATE +}; + +/* XOR descriptor structure for CRC and DMA descriptor */ +struct crc_dma_desc { + u32 status; /* Successful descriptor execution indication */ + u32 crc32_result; /* Result of CRC-32 calculation */ + u32 desc_cmd; /* type of operation to be carried out on the data */ + u32 next_desc_ptr; /* Next descriptor address pointer */ + u32 byte_cnt; /* Size of source block part represented by the descriptor */ + u32 dst_addr; /* Destination Block address pointer (not used in CRC32 */ + u32 src_addr0; /* Mode: Source Block address pointer */ + u32 src_addr1; /* Mode: Source Block address pointer */ +} __packed; + +int mv_xor_state_get(u32 chan); +void mv_sys_xor_init(MV_DRAM_INFO *dram_info); +void mv_sys_xor_finish(void); +int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr); +int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high, + u32 init_val_low); + +#endif /* __XOR_H */ diff --git a/drivers/ddr/mvebu/xor_regs.h b/drivers/ddr/mvebu/xor_regs.h new file mode 100644 index 0000000000..884aa155b4 --- /dev/null +++ b/drivers/ddr/mvebu/xor_regs.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) Marvell International Ltd. and its affiliates + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __XOR_REGS_H +#define __XOR_REGS_H + +/* + * For controllers that have two XOR units, then chans 2 & 3 will be mapped + * to channels 0 & 1 of unit 1 + */ +#define XOR_UNIT(chan) ((chan) >> 1) +#define XOR_CHAN(chan) ((chan) & 1) + +#define MV_XOR_REGS_OFFSET(unit) (0x60900) +#define MV_XOR_REGS_BASE(unit) (MV_XOR_REGS_OFFSET(unit)) + +/* XOR Engine Control Register Map */ +#define XOR_CHANNEL_ARBITER_REG(unit) (MV_XOR_REGS_BASE(unit)) +#define XOR_CONFIG_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x10 + ((chan) * 4))) +#define XOR_ACTIVATION_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x20 + ((chan) * 4))) + +/* XOR Engine Interrupt Register Map */ +#define XOR_CAUSE_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x30) +#define XOR_MASK_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x40) +#define XOR_ERROR_CAUSE_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x50) +#define XOR_ERROR_ADDR_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x60) + +/* XOR Engine Descriptor Register Map */ +#define XOR_NEXT_DESC_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x200 + ((chan) * 4))) +#define XOR_CURR_DESC_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x210 + ((chan) * 4))) +#define XOR_BYTE_COUNT_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x220 + ((chan) * 4))) + +#define XOR_DST_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x2B0 + ((chan) * 4))) +#define XOR_BLOCK_SIZE_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x2C0 + ((chan) * 4))) +#define XOR_TIMER_MODE_CTRL_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x2D0) +#define XOR_TIMER_MODE_INIT_VAL_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x2D4) +#define XOR_TIMER_MODE_CURR_VAL_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x2D8) +#define XOR_INIT_VAL_LOW_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x2E0) +#define XOR_INIT_VAL_HIGH_REG(unit) (MV_XOR_REGS_BASE(unit) + 0x2E4) + +/* XOR register fileds */ + +/* XOR Engine [0..1] Configuration Registers (XExCR) */ +#define XEXCR_OPERATION_MODE_OFFS (0) +#define XEXCR_OPERATION_MODE_MASK (7 << XEXCR_OPERATION_MODE_OFFS) +#define XEXCR_OPERATION_MODE_XOR (0 << XEXCR_OPERATION_MODE_OFFS) +#define XEXCR_OPERATION_MODE_CRC (1 << XEXCR_OPERATION_MODE_OFFS) +#define XEXCR_OPERATION_MODE_DMA (2 << XEXCR_OPERATION_MODE_OFFS) +#define XEXCR_OPERATION_MODE_ECC (3 << XEXCR_OPERATION_MODE_OFFS) +#define XEXCR_OPERATION_MODE_MEM_INIT (4 << XEXCR_OPERATION_MODE_OFFS) + +#define XEXCR_SRC_BURST_LIMIT_OFFS (4) +#define XEXCR_SRC_BURST_LIMIT_MASK (7 << XEXCR_SRC_BURST_LIMIT_OFFS) +#define XEXCR_DST_BURST_LIMIT_OFFS (8) +#define XEXCR_DST_BURST_LIMIT_MASK (7 << XEXCR_DST_BURST_LIMIT_OFFS) +#define XEXCR_DRD_RES_SWP_OFFS (12) +#define XEXCR_DRD_RES_SWP_MASK (1 << XEXCR_DRD_RES_SWP_OFFS) +#define XEXCR_DWR_REQ_SWP_OFFS (13) +#define XEXCR_DWR_REQ_SWP_MASK (1 << XEXCR_DWR_REQ_SWP_OFFS) +#define XEXCR_DES_SWP_OFFS (14) +#define XEXCR_DES_SWP_MASK (1 << XEXCR_DES_SWP_OFFS) +#define XEXCR_REG_ACC_PROTECT_OFFS (15) +#define XEXCR_REG_ACC_PROTECT_MASK (1 << XEXCR_REG_ACC_PROTECT_OFFS) + +/* XOR Engine [0..1] Activation Registers (XExACTR) */ +#define XEXACTR_XESTART_OFFS (0) +#define XEXACTR_XESTART_MASK (1 << XEXACTR_XESTART_OFFS) +#define XEXACTR_XESTOP_OFFS (1) +#define XEXACTR_XESTOP_MASK (1 << XEXACTR_XESTOP_OFFS) +#define XEXACTR_XEPAUSE_OFFS (2) +#define XEXACTR_XEPAUSE_MASK (1 << XEXACTR_XEPAUSE_OFFS) +#define XEXACTR_XERESTART_OFFS (3) +#define XEXACTR_XERESTART_MASK (1 << XEXACTR_XERESTART_OFFS) +#define XEXACTR_XESTATUS_OFFS (4) +#define XEXACTR_XESTATUS_MASK (3 << XEXACTR_XESTATUS_OFFS) +#define XEXACTR_XESTATUS_IDLE (0 << XEXACTR_XESTATUS_OFFS) +#define XEXACTR_XESTATUS_ACTIVE (1 << XEXACTR_XESTATUS_OFFS) +#define XEXACTR_XESTATUS_PAUSED (2 << XEXACTR_XESTATUS_OFFS) + +/* XOR Engine [0..1] Destination Pointer Register (XExDPR0) */ +#define XEXDPR_DST_PTR_OFFS (0) +#define XEXDPR_DST_PTR_MASK (0xFFFFFFFF << XEXDPR_DST_PTR_OFFS) +#define XEXDPR_DST_PTR_XOR_MASK (0x3F) +#define XEXDPR_DST_PTR_DMA_MASK (0x1F) +#define XEXDPR_DST_PTR_CRC_MASK (0x1F) + +/* XOR Engine[0..1] Block Size Registers (XExBSR) */ +#define XEXBSR_BLOCK_SIZE_OFFS (0) +#define XEXBSR_BLOCK_SIZE_MASK (0xFFFFFFFF << XEXBSR_BLOCK_SIZE_OFFS) +#define XEXBSR_BLOCK_SIZE_MIN_VALUE (128) +#define XEXBSR_BLOCK_SIZE_MAX_VALUE (0xFFFFFFFF) + +/* XOR Engine Address Decoding Register Map */ +#define XOR_WINDOW_CTRL_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + (0x240 + ((chan) * 4))) +#define XOR_BASE_ADDR_REG(unit, win) (MV_XOR_REGS_BASE(unit) + (0x250 + ((win) * 4))) +#define XOR_SIZE_MASK_REG(unit, win) (MV_XOR_REGS_BASE(unit) + (0x270 + ((win) * 4))) +#define XOR_HIGH_ADDR_REMAP_REG(unit, win) (MV_XOR_REGS_BASE(unit) + (0x290 + ((win) * 4))) +#define XOR_ADDR_OVRD_REG(unit, win) (MV_XOR_REGS_BASE(unit) + (0x2A0 + ((win) * 4))) + +#endif /* __XOR_REGS_H */ -- cgit From 68102b81e8fb699087ec5757a75676c6c65af3fd Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 19 Jan 2015 11:33:39 +0100 Subject: arm: mvebu: maxbcm: Fix compilation warning and add Spansion SPI NOR support This patch fixes the following compilation warning for maxbcm: Building maxbcm board... text data bss dec hex filename 160075 6596 38240 204911 3206f ./u-boot board/maxbcm/maxbcm.c: In function 'reset_phy': board/maxbcm/maxbcm.c:68:6: warning: unused variable 'reg' [-Wunused-variable] u16 reg; ^ board/maxbcm/maxbcm.c:66:6: warning: unused variable 'devadr' [-Wunused-variable] u16 devadr = CONFIG_PHY_BASE_ADDR; ^ Additionally support Spansion SPI NOR flash is added. With larger SPI device support via the CONFIG_SPI_FLASH_BAR define. Signed-off-by: Stefan Roese Reviewed-by: Luka Perkov --- board/maxbcm/maxbcm.c | 2 -- include/configs/maxbcm.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/maxbcm/maxbcm.c b/board/maxbcm/maxbcm.c index a833cc3501..46b16ac29c 100644 --- a/board/maxbcm/maxbcm.c +++ b/board/maxbcm/maxbcm.c @@ -142,9 +142,7 @@ int checkboard(void) /* Configure and enable MV88E6185 switch */ void reset_phy(void) { - u16 devadr = CONFIG_PHY_BASE_ADDR; char *name = "neta0"; - u16 reg; if (miiphy_set_current_dev(name)) return; diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 4e962a3604..5999d60146 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -43,6 +43,8 @@ #define CONFIG_SF_DEFAULT_SPEED 1000000 #define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 #define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_SPI_FLASH_BAR /* Environment in SPI NOR flash */ #define CONFIG_ENV_IS_IN_SPI_FLASH -- cgit From 91785f70b9b7ebfd1a2da4772a8268b36f58fa3d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:39 -0700 Subject: x86: mmc: Move common FSP functions into a common file Since these board functions seem to be the same for all boards which use FSP, move them into a common file. We can adjust this later if future FSPs need more flexibility. This creates a generic PCI MMC device. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/x86/cpu/queensbay/tnc.c | 27 ------------------- arch/x86/cpu/queensbay/tnc_pci.c | 15 ----------- arch/x86/cpu/queensbay/topcliff.c | 33 +++-------------------- arch/x86/lib/fsp/Makefile | 1 + arch/x86/lib/fsp/fsp_common.c | 55 +++++++++++++++++++++++++++++++++++++++ drivers/mmc/Makefile | 1 + drivers/mmc/pci_mmc.c | 42 ++++++++++++++++++++++++++++++ include/mmc.h | 14 ++++++++++ 8 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 arch/x86/lib/fsp/fsp_common.c create mode 100644 drivers/mmc/pci_mmc.c diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index f9b3bfaada..30ab725bb9 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -43,30 +43,3 @@ int arch_cpu_init(void) return 0; } - -int print_cpuinfo(void) -{ - post_code(POST_CPU_INFO); - return default_print_cpuinfo(); -} - -void reset_cpu(ulong addr) -{ - /* cold reset */ - outb(0x06, PORT_RESET); -} - -void board_final_cleanup(void) -{ - u32 status; - - /* call into FspNotify */ - debug("Calling into FSP (notify phase INIT_PHASE_BOOT): "); - status = fsp_notify(NULL, INIT_PHASE_BOOT); - if (status != FSP_SUCCESS) - debug("fail, error code %x\n", status); - else - debug("OK\n"); - - return; -} diff --git a/arch/x86/cpu/queensbay/tnc_pci.c b/arch/x86/cpu/queensbay/tnc_pci.c index 9b0b725313..6c291f9ee9 100644 --- a/arch/x86/cpu/queensbay/tnc_pci.c +++ b/arch/x86/cpu/queensbay/tnc_pci.c @@ -44,18 +44,3 @@ void board_pci_setup_hose(struct pci_controller *hose) hose->region_count = 4; } - -int board_pci_post_scan(struct pci_controller *hose) -{ - u32 status; - - /* call into FspNotify */ - debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); - status = fsp_notify(NULL, INIT_PHASE_PCI); - if (status != FSP_SUCCESS) - debug("fail, error code %x\n", status); - else - debug("OK\n"); - - return 0; -} diff --git a/arch/x86/cpu/queensbay/topcliff.c b/arch/x86/cpu/queensbay/topcliff.c index b01422a965..9faf1b92bb 100644 --- a/arch/x86/cpu/queensbay/topcliff.c +++ b/arch/x86/cpu/queensbay/topcliff.c @@ -5,43 +5,16 @@ */ #include -#include -#include -#include +#include #include -#include static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 }, - { } }; int cpu_mmc_init(bd_t *bis) { - struct sdhci_host *mmc_host; - pci_dev_t devbusfn; - u32 iobase; - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) { - devbusfn = pci_find_devices(mmc_supported, i); - if (devbusfn == -1) - return -ENODEV; - - mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); - if (!mmc_host) - return -ENOMEM; - - mmc_host->name = "Topcliff SDHCI"; - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); - mmc_host->ioaddr = (void *)iobase; - mmc_host->quirks = 0; - ret = add_sdhci(mmc_host, 0, 0); - if (ret) - return ret; - } - - return 0; + return pci_mmc_init("Topcliff SDHCI", mmc_supported, + ARRAY_SIZE(mmc_supported)); } diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile index 3a2bac0636..5b12c12d7a 100644 --- a/arch/x86/lib/fsp/Makefile +++ b/arch/x86/lib/fsp/Makefile @@ -5,5 +5,6 @@ # obj-y += fsp_car.o +obj-y += fsp_common.o obj-y += fsp_dram.o obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c new file mode 100644 index 0000000000..f668259c0e --- /dev/null +++ b/arch/x86/lib/fsp/fsp_common.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +int print_cpuinfo(void) +{ + post_code(POST_CPU_INFO); + return default_print_cpuinfo(); +} + +void reset_cpu(ulong addr) +{ + /* cold reset */ + outb(0x06, PORT_RESET); +} + + +int board_pci_post_scan(struct pci_controller *hose) +{ + u32 status; + + /* call into FspNotify */ + debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); + status = fsp_notify(NULL, INIT_PHASE_PCI); + if (status != FSP_SUCCESS) + debug("fail, error code %x\n", status); + else + debug("OK\n"); + + return 0; +} + +void board_final_cleanup(void) +{ + u32 status; + + /* call into FspNotify */ + debug("Calling into FSP (notify phase INIT_PHASE_BOOT): "); + status = fsp_notify(NULL, INIT_PHASE_BOOT); + if (status != FSP_SUCCESS) + debug("fail, error code %x\n", status); + else + debug("OK\n"); + + return; +} diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 4ba5878936..ed73687735 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o obj-$(CONFIG_MXC_MMC) += mxcmmc.o obj-$(CONFIG_MXS_MMC) += mxsmmc.o obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o +obj-$(CONFIG_X86) += pci_mmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c new file mode 100644 index 0000000000..37171bfa71 --- /dev/null +++ b/drivers/mmc/pci_mmc.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015, Google, Inc + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported, + int num_ids) +{ + struct sdhci_host *mmc_host; + pci_dev_t devbusfn; + u32 iobase; + int ret; + int i; + + for (i = 0; i < num_ids; i++) { + devbusfn = pci_find_devices(mmc_supported, i); + if (devbusfn == -1) + return -ENODEV; + + mmc_host = malloc(sizeof(struct sdhci_host)); + if (!mmc_host) + return -ENOMEM; + + mmc_host->name = (char *)name; + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); + mmc_host->ioaddr = (void *)iobase; + mmc_host->quirks = 0; + ret = add_sdhci(mmc_host, 0, 0); + if (ret) + return ret; + } + + return 0; +} diff --git a/include/mmc.h b/include/mmc.h index 09101e2c87..56d97bbdcf 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -438,6 +438,20 @@ int board_mmc_init(bd_t *bis); int cpu_mmc_init(bd_t *bis); int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); +struct pci_device_id; + +/** + * pci_mmc_init() - set up PCI MMC devices + * + * This finds all the matching PCI IDs and sets them up as MMC devices. + * + * @name: Name to use for devices + * @mmc_supported: PCI IDs to search for + * @num_ids: Number of elements in @mmc_supported + */ +int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported, + int num_ids); + /* Set block count limit because of 16 bit register limit on some hardware*/ #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 -- cgit From f0809f9a38f81562638eb5576142b40e0e56a734 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:40 -0700 Subject: x86: Remove unnecessary casts and fix comment typos Tidy up the FSP support code a little. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/lib/fsp/fsp_support.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index bf3780711f..8b639f7819 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -124,25 +124,25 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) struct fsp_init_params *params_ptr; struct upd_region *fsp_upd; - fsp_hdr = (struct fsp_header *)find_fsp_header(); + fsp_hdr = find_fsp_header(); if (fsp_hdr == NULL) { /* No valid FSP info header was found */ panic("Invalid FSP header"); } - fsp_upd = (struct upd_region *)&shared_data.fsp_upd; + fsp_upd = &shared_data.fsp_upd; memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf)); /* Reserve a gap in stack top */ rt_buf.common.stack_top = (u32 *)stack_top - 32; rt_buf.common.boot_mode = boot_mode; - rt_buf.common.upd_data = (struct upd_region *)fsp_upd; + rt_buf.common.upd_data = fsp_upd; /* Get VPD region start */ fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base + fsp_hdr->cfg_region_off); - /* Verifify the VPD data region is valid */ + /* Verify the VPD data region is valid */ assert((fsp_vpd->img_rev == VPD_IMAGE_REV) && (fsp_vpd->sign == VPD_IMAGE_ID)); @@ -150,7 +150,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), sizeof(struct upd_region)); - /* Verifify the UPD data region is valid */ + /* Verify the UPD data region is valid */ assert(fsp_upd->terminator == UPD_TERMINATOR); /* Override any UPD setting if required */ -- cgit From 8ce24cd9919b9d7157a800e0fd1ec653730c937e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:41 -0700 Subject: x86: Allow FSP Kconfig settings for all x86 While queensbay is the first chip with these settings, others will want to use them too. Make them common. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/Kconfig | 38 ++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/queensbay/Kconfig | 38 -------------------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 928fc60863..c2af607ca6 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -344,6 +344,44 @@ config TSC_FREQ_IN_MHZ help The running frequency in MHz of Time-Stamp Counter (TSC). +config HAVE_FSP + bool "Add an Firmware Support Package binary" + help + Select this option to add an Firmware Support Package binary to + the resulting U-Boot image. It is a binary blob which U-Boot uses + to set up SDRAM and other chipset specific initialization. + + Note: Without this binary U-Boot will not be able to set up its + SDRAM so will not boot. + +config FSP_FILE + string "Firmware Support Package binary filename" + depends on HAVE_FSP + default "fsp.bin" + help + The filename of the file to use as Firmware Support Package binary + in the board directory. + +config FSP_ADDR + hex "Firmware Support Package binary location" + depends on HAVE_FSP + default 0xfffc0000 + help + FSP is not Position Independent Code (PIC) and the whole FSP has to + be rebased if it is placed at a location which is different from the + perferred base address specified during the FSP build. Use Intel's + Binary Configuration Tool (BCT) to do the rebase. + + The default base address of 0xfffc0000 indicates that the binary must + be located at offset 0xc0000 from the beginning of a 1MB flash device. + +config FSP_TEMP_RAM_ADDR + hex + default 0x2000000 + help + Stack top address which is used in FspInit after DRAM is ready and + CAR is disabled. + source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" diff --git a/arch/x86/cpu/queensbay/Kconfig b/arch/x86/cpu/queensbay/Kconfig index f6b52010c3..397e599f93 100644 --- a/arch/x86/cpu/queensbay/Kconfig +++ b/arch/x86/cpu/queensbay/Kconfig @@ -11,44 +11,6 @@ config INTEL_QUEENSBAY if INTEL_QUEENSBAY -config HAVE_FSP - bool "Add an Firmware Support Package binary" - help - Select this option to add an Firmware Support Package binary to - the resulting U-Boot image. It is a binary blob which U-Boot uses - to set up SDRAM and other chipset specific initialization. - - Note: Without this binary U-Boot will not be able to set up its - SDRAM so will not boot. - -config FSP_FILE - string "Firmware Support Package binary filename" - depends on HAVE_FSP - default "fsp.bin" - help - The filename of the file to use as Firmware Support Package binary - in the board directory. - -config FSP_ADDR - hex "Firmware Support Package binary location" - depends on HAVE_FSP - default 0xfffc0000 - help - FSP is not Position Independent Code (PIC) and the whole FSP has to - be rebased if it is placed at a location which is different from the - perferred base address specified during the FSP build. Use Intel's - Binary Configuration Tool (BCT) to do the rebase. - - The default base address of 0xfffc0000 indicates that the binary must - be located at offset 0xc0000 from the beginning of a 1MB flash device. - -config FSP_TEMP_RAM_ADDR - hex - default 0x2000000 - help - Stack top address which is used in FspInit after DRAM is ready and - CAR is disabled. - config HAVE_CMC bool "Add a Chipset Micro Code state machine binary" help -- cgit From 447f8b018e5e5bc5b6958ce6ed8f79e8c35c30af Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:42 -0700 Subject: x86: Allow a UART to be set up before the FSP is ready Since the FSP is a black box it helps to have some sort of debugging available to check its inputs. If the debug UART is in use, set it up after CAR is available. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/include/asm/u-boot-x86.h | 3 +++ arch/x86/lib/fsp/fsp_support.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index b98afa801d..5d7dff534d 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -45,6 +45,9 @@ ulong board_get_usable_ram_top(ulong total_size); void dram_init_banksize(void); int default_print_cpuinfo(void); +/* Set up a UART which can be used with printch(), printhex8(), etc. */ +int setup_early_uart(void); + void setup_pcat_compatibility(void); void isa_unmap_rom(u32 addr); diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 8b639f7819..5f96da120e 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -124,6 +124,10 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) struct fsp_init_params *params_ptr; struct upd_region *fsp_upd; +#ifdef CONFIG_DEBUG_UART + setup_early_uart(); +#endif + fsp_hdr = find_fsp_header(); if (fsp_hdr == NULL) { /* No valid FSP info header was found */ -- cgit From 5093badbb59e83b42b8f9e5579e07e3916271207 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:43 -0700 Subject: x86: spi: Support ValleyView in ICH SPI driver The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++--------------- drivers/spi/ich.h | 11 ++++++----- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index fdff158637..da857791e0 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -21,6 +22,7 @@ struct ich_ctlr { pci_dev_t dev; /* PCI device number */ int ich_version; /* Controller version, 7 or 9 */ + bool use_sbase; /* Use SBASE instead of RCB */ int ichspi_lock; int locked; uint8_t *opmenu; @@ -145,7 +147,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, * ICH 7 SPI controller only supports array read command * and byte program command for SST flash */ - if (ctlr.ich_version == 7) { + if (ctlr.ich_version == 7 || ctlr.use_sbase) { ich->slave.op_mode_rx = SPI_OPM_RX_AS; ich->slave.op_mode_tx = SPI_OPM_TX_BP; } @@ -181,7 +183,8 @@ static int get_ich_version(uint16_t device_id) if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) + device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) || + device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC) return 9; return 0; @@ -204,14 +207,14 @@ static int ich9_can_do_33mhz(pci_dev_t dev) return speed == 1; } -static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp) +static int ich_find_spi_controller(struct ich_ctlr *ich) { int last_bus = pci_last_busno(); int bus; if (last_bus == -1) { debug("No PCI busses?\n"); - return -1; + return -ENODEV; } for (bus = 0; bus <= last_bus; bus++) { @@ -225,24 +228,33 @@ static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp) device_id = ids >> 16; if (vendor_id == PCI_VENDOR_ID_INTEL) { - *devp = dev; - *ich_versionp = get_ich_version(device_id); - return 0; + ich->dev = dev; + ich->ich_version = get_ich_version(device_id); + if (device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC) + ich->use_sbase = true; + return ich->ich_version == 0 ? -ENODEV : 0; } } debug("ICH SPI: No ICH found.\n"); - return -1; + return -ENODEV; } static int ich_init_controller(struct ich_ctlr *ctlr) { uint8_t *rcrb; /* Root Complex Register Block */ uint32_t rcba; /* Root Complex Base Address */ + uint32_t sbase_addr; + uint8_t *sbase; pci_read_config_dword(ctlr->dev, 0xf0, &rcba); /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ rcrb = (uint8_t *)(rcba & 0xffffc000); + + /* SBASE is similar */ + pci_read_config_dword(ctlr->dev, 0x54, &sbase_addr); + sbase = (uint8_t *)(sbase_addr & 0xfffffe00); + if (ctlr->ich_version == 7) { struct ich7_spi_regs *ich7_spi; @@ -262,7 +274,10 @@ static int ich_init_controller(struct ich_ctlr *ctlr) } else if (ctlr->ich_version == 9) { struct ich9_spi_regs *ich9_spi; - ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800); + if (ctlr->use_sbase) + ich9_spi = (struct ich9_spi_regs *)sbase; + else + ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800); ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; ctlr->opmenu = ich9_spi->opmenu; ctlr->menubytes = sizeof(ich9_spi->opmenu); @@ -282,12 +297,13 @@ static int ich_init_controller(struct ich_ctlr *ctlr) ctlr->ich_version); return -1; } - debug("ICH SPI: Version %d detected\n", ctlr->ich_version); /* Work out the maximum speed we can support */ ctlr->max_speed = 20000000; if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev)) ctlr->max_speed = 33000000; + debug("ICH SPI: Version %d detected at %p, speed %ld\n", + ctlr->ich_version, ctlr->base, ctlr->max_speed); ich_set_bbar(ctlr, 0); @@ -298,7 +314,7 @@ void spi_init(void) { uint8_t bios_cntl; - if (ich_find_spi_controller(&ctlr.dev, &ctlr.ich_version)) { + if (ich_find_spi_controller(&ctlr)) { printf("ICH SPI: Cannot find device\n"); return; } @@ -312,10 +328,20 @@ void spi_init(void) * Disable the BIOS write protect so write commands are allowed. On * v9, deassert SMM BIOS Write Protect Disable. */ - pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl); - if (ctlr.ich_version == 9) - bios_cntl &= ~(1 << 5); - pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1); + if (ctlr.use_sbase) { + struct ich9_spi_regs *ich9_spi; + + ich9_spi = (struct ich9_spi_regs *)ctlr.base; + bios_cntl = ich_readb(&ich9_spi->bcr); + bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */ + bios_cntl |= 1; /* Write Protect Disable (WPD) */ + ich_writeb(bios_cntl, &ich9_spi->bcr); + } else { + pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl); + if (ctlr.ich_version == 9) + bios_cntl &= ~(1 << 5); + pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1); + } } int spi_claim_bus(struct spi_slave *slave) diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h index d2e4b8523b..1419b23e11 100644 --- a/drivers/spi/ich.h +++ b/drivers/spi/ich.h @@ -37,18 +37,19 @@ struct ich9_spi_regs { uint8_t opmenu[8]; /* 0x98 */ uint32_t bbar; uint8_t _reserved3[12]; - uint32_t fdoc; + uint32_t fdoc; /* 0xb0 */ uint32_t fdod; uint8_t _reserved4[8]; - uint32_t afc; + uint32_t afc; /* 0xc0 */ uint32_t lvscc; uint32_t uvscc; uint8_t _reserved5[4]; - uint32_t fpb; + uint32_t fpb; /* 0xd0 */ uint8_t _reserved6[28]; - uint32_t srdl; + uint32_t srdl; /* 0xf0 */ uint32_t srdc; - uint32_t srd; + uint32_t scs; + uint32_t bcr; } __packed; enum { -- cgit From abbdb262570f415b5eaea036486076669eff1e76 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:44 -0700 Subject: scsi: bootstage: Measure time taken to scan the bus On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- common/cmd_scsi.c | 2 ++ include/bootstage.h | 1 + 2 files changed, 3 insertions(+) diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index cbc107ea50..a0a62ebdca 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -217,8 +217,10 @@ void scsi_init(void) (busdevfunc >> 8) & 0x7); } #endif + bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci"); scsi_low_level_init(busdevfunc); scsi_scan(1); + bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI); } #endif diff --git a/include/bootstage.h b/include/bootstage.h index df13ab2f63..6b7588d38f 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -194,6 +194,7 @@ enum bootstage_id { BOOTSTAGE_ID_MAIN_CPU_READY, BOOTSTAGE_ID_ACCUM_LCD, + BOOTSTAGE_ID_ACCUM_SCSI, /* a few spare for the user, from here */ BOOTSTAGE_ID_USER, -- cgit From 8b4d659f4b3ce0e27253fa14066d380ea02b6695 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:45 -0700 Subject: x86: Enable bootstage features Allow measuring of boot time using bootstage. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng --- include/configs/x86-common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index ecedfc3ab1..66d4894256 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -245,6 +245,9 @@ #define CONFIG_BOOTP_GATEWAY #define CONFIG_BOOTP_HOSTNAME +#define CONFIG_BOOTSTAGE +#define CONFIG_CMD_BOOTSTAGE + #define CONFIG_CMD_USB #define CONFIG_EXTRA_ENV_SETTINGS \ -- cgit From 00bdd95278e189131f9b5858045c540bf0cce530 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:46 -0700 Subject: x86: Add some documentation on how to port U-Boot on x86 Some information has been gleaned on tools and procedures for porting U-Boot to different x86 platforms. Add a few notes to start things off. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- doc/README.x86 | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/doc/README.x86 b/doc/README.x86 index ddfd75e1cd..a9105f87c0 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -164,6 +164,70 @@ mtrr - List and set the Memory Type Range Registers (MTRR). These are used to mode to use. U-Boot sets up some reasonable values but you can adjust then with this command. +Development Flow +---------------- + +These notes are for those who want to port U-Boot to a new x86 platform. + +Since x86 CPUs boot from SPI flash, a SPI flash emulator is a good investment. +The Dediprog em100 can be used on Linux. The em100 tool is available here: + + http://review.coreboot.org/p/em100.git + +On Minnowboard Max the following command line can be used: + + sudo em100 -s -p LOW -d u-boot.rom -c W25Q64DW -r + +A suitable clip for connecting over the SPI flash chip is here: + + http://www.dediprog.com/pd/programmer-accessories/EM-TC-8 + +This allows you to override the SPI flash contents for development purposes. +Typically you can write to the em100 in around 1200ms, considerably faster +than programming the real flash device each time. The only important +limitation of the em100 is that it only supports SPI bus speeds up to 20MHz. +This means that images must be set to boot with that speed. This is an +Intel-specific feature - e.g. tools/ifttool has an option to set the SPI +speed in the SPI descriptor region. + +If your chip/board uses an Intel Firmware Support Package (FSP) it is fairly +easy to fit it in. You can follow the Minnowboard Max implementation, for +example. Hopefully you will just need to create new files similar to those +in arch/x86/cpu/baytrail which provide Bay Trail support. + +If you are not using an FSP you have more freedom and more responsibility. +The ivybridge support works this way, although it still uses a ROM for +graphics and still has binary blobs containing Intel code. You should aim to +support all important peripherals on your platform including video and storage. +Use the device tree for configuration where possible. + +For the microcode you can create a suitable device tree file using the +microcode tool: + + ./tools/microcode-tool -d microcode.dat create + +or if you only have header files and not the full Intel microcode.dat database: + + ./tools/microcode-tool -H BAY_TRAIL_FSP_KIT/Microcode/M0130673322.h \ + -H BAY_TRAIL_FSP_KIT/Microcode/M0130679901.h \ + create all + +These are written to arch/x86/dts/microcode/ by default. + +Note that it is possible to just add the micrcode for your CPU if you know its +model. U-Boot prints this information when it starts + + CPU: x86_64, vendor Intel, device 30673h + +so here we can use the M0130673322 file. + +If you platform can display POST codes on two little 7-segment displays on +the board, then you can use post_code() calls from C or assembler to monitor +boot progress. This can be good for debugging. + +If not, you can try to get serial working as early as possible. The early +debug serial port may be useful here. See setup_early_uart() for an example. + TODO List --------- - Audio -- cgit From 3a1a18ff1867d6f94921a24992354d3a547666d6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:47 -0700 Subject: x86: Add support for Intel Minnowboard Max This is a relatively low-cost x86 board in a small form factor. The main peripherals are uSD, USB, HDMI, Ethernet and SATA. It uses an Atom 3800 series CPU. So far only the dual core 2GB variant is supported. This uses the existing FSP support. Binary blobs are required to make this board work. The microcode update is included as a patch (all 3000 lines of it). Change-Id: I0088c47fe87cf08ae635b343d32c332269062156 Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/Kconfig | 15 + arch/x86/cpu/Makefile | 1 + arch/x86/cpu/baytrail/Kconfig | 9 + arch/x86/cpu/baytrail/Makefile | 10 + arch/x86/cpu/baytrail/early_uart.c | 77 + arch/x86/cpu/baytrail/fsp_configs.c | 156 + arch/x86/cpu/baytrail/pci.c | 46 + arch/x86/cpu/baytrail/valleyview.c | 38 + arch/x86/dts/Makefile | 3 +- arch/x86/dts/microcode/m0130673322.dtsi | 3284 ++++++++++++++++++++++ arch/x86/dts/minnowmax.dts | 45 + arch/x86/dts/serial.dtsi | 2 +- arch/x86/include/asm/arch-baytrail/fsp/azalia.h | 39 + arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h | 95 + arch/x86/include/asm/arch-baytrail/gpio.h | 13 + board/intel/minnowmax/Kconfig | 24 + board/intel/minnowmax/MAINTAINERS | 6 + board/intel/minnowmax/Makefile | 7 + board/intel/minnowmax/minnowmax.c | 32 + board/intel/minnowmax/start.S | 9 + configs/minnowmax_defconfig | 13 + doc/README.x86 | 47 +- include/configs/minnowmax.h | 72 + 23 files changed, 4036 insertions(+), 7 deletions(-) create mode 100644 arch/x86/cpu/baytrail/Kconfig create mode 100644 arch/x86/cpu/baytrail/Makefile create mode 100644 arch/x86/cpu/baytrail/early_uart.c create mode 100644 arch/x86/cpu/baytrail/fsp_configs.c create mode 100644 arch/x86/cpu/baytrail/pci.c create mode 100644 arch/x86/cpu/baytrail/valleyview.c create mode 100644 arch/x86/dts/microcode/m0130673322.dtsi create mode 100644 arch/x86/dts/minnowmax.dts create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/azalia.h create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h create mode 100644 arch/x86/include/asm/arch-baytrail/gpio.h create mode 100644 board/intel/minnowmax/Kconfig create mode 100644 board/intel/minnowmax/MAINTAINERS create mode 100644 board/intel/minnowmax/Makefile create mode 100644 board/intel/minnowmax/minnowmax.c create mode 100644 board/intel/minnowmax/start.S create mode 100644 configs/minnowmax_defconfig create mode 100644 include/configs/minnowmax.h diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c2af607ca6..defdce76b1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -41,6 +41,17 @@ config TARGET_CROWNBAY Intel Platform Controller Hub EG20T, other system components and peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS. +config TARGET_MINNOWMAX + bool "Support Intel Minnowboard MAX" + help + This is the Intel Minnowboard MAX. It contains an Atom E3800 + processor in a small form factor with Ethernet, micro-SD, USB 2, + USB 3, SATA, serial console, some GPIOs and HDMI 1.3 video out. + It requires some binary blobs - see README.x86 for details. + + Note that PCIE_ECAM_BASE is set up by the FSP so the value used + by U-Boot matches that value. + endchoice config RAMBASE @@ -382,6 +393,8 @@ config FSP_TEMP_RAM_ADDR Stack top address which is used in FspInit after DRAM is ready and CAR is disabled. +source "arch/x86/cpu/baytrail/Kconfig" + source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" @@ -394,6 +407,8 @@ source "board/google/chromebook_link/Kconfig" source "board/intel/crownbay/Kconfig" +source "board/intel/minnowmax/Kconfig" + config PCIE_ECAM_BASE hex default 0xe0000000 diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 62e43c04e5..5acf8bb427 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -12,6 +12,7 @@ extra-y = start.o obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o obj-y += interrupts.o cpu.o call64.o +obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig new file mode 100644 index 0000000000..e86cc01115 --- /dev/null +++ b/arch/x86/cpu/baytrail/Kconfig @@ -0,0 +1,9 @@ +# +# Copyright (C) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +config INTEL_BAYTRAIL + bool + select HAVE_FSP diff --git a/arch/x86/cpu/baytrail/Makefile b/arch/x86/cpu/baytrail/Makefile new file mode 100644 index 0000000000..8914e8b6d5 --- /dev/null +++ b/arch/x86/cpu/baytrail/Makefile @@ -0,0 +1,10 @@ +# +# Copyright (C) 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += early_uart.o +obj-y += fsp_configs.o +obj-y += pci.o +obj-y += valleyview.o diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c new file mode 100644 index 0000000000..41992105fe --- /dev/null +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define PCI_DEV_CONFIG(segbus, dev, fn) ( \ + (((segbus) & 0xfff) << 20) | \ + (((dev) & 0x1f) << 15) | \ + (((fn) & 0x07) << 12)) + +/* Platform Controller Unit */ +#define LPC_DEV 0x1f +#define LPC_FUNC 0 + +/* Enable UART */ +#define UART_CONT 0x80 + +/* SCORE Pad definitions */ +#define UART_RXD_PAD 82 +#define UART_TXD_PAD 83 + +/* Pad base: PAD_CONF0[n]= PAD_BASE + 16 * n */ +#define GPSCORE_PAD_BASE (IO_BASE_ADDRESS + IO_BASE_OFFSET_GPSCORE) + +/* IO Memory */ +#define IO_BASE_ADDRESS 0xfed0c000 +#define IO_BASE_OFFSET_GPSCORE 0x0000 +#define IO_BASE_OFFSET_GPNCORE 0x1000 +#define IO_BASE_OFFSET_GPSSUS 0x2000 +#define IO_BASE_SIZE 0x4000 + +static inline unsigned int score_pconf0(int pad_num) +{ + return GPSCORE_PAD_BASE + pad_num * 16; +} + +static void score_select_func(int pad, int func) +{ + uint32_t reg; + uint32_t pconf0_addr = score_pconf0(pad); + + reg = readl(pconf0_addr); + reg &= ~0x7; + reg |= func & 0x7; + writel(reg, pconf0_addr); +} + +static void pci_write_config32(int dev, unsigned int where, u32 value) +{ + unsigned long addr; + + addr = CONFIG_PCIE_ECAM_BASE | dev | (where & ~3); + writel(value, addr); +} + +/* This can be called after memory-mapped PCI is working */ +int setup_early_uart(void) +{ + /* Enable the legacy UART hardware. */ + pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, 1); + + /* + * Set up the pads to the UART function. This allows the signals to + * leave the chip + */ + score_select_func(UART_RXD_PAD, 1); + score_select_func(UART_TXD_PAD, 1); + + /* TODO(sjg@chromium.org): Call debug_uart_init() */ + + return 0; +} diff --git a/arch/x86/cpu/baytrail/fsp_configs.c b/arch/x86/cpu/baytrail/fsp_configs.c new file mode 100644 index 0000000000..86b6926272 --- /dev/null +++ b/arch/x86/cpu/baytrail/fsp_configs.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: Intel + */ + +#include +#include +#include + +/* ALC262 Verb Table - 10EC0262 */ +static const uint32_t verb_table_data13[] = { + /* Pin Complex (NID 0x11) */ + 0x01171cf0, + 0x01171d11, + 0x01171e11, + 0x01171f41, + /* Pin Complex (NID 0x12) */ + 0x01271cf0, + 0x01271d11, + 0x01271e11, + 0x01271f41, + /* Pin Complex (NID 0x14) */ + 0x01471c10, + 0x01471d40, + 0x01471e01, + 0x01471f01, + /* Pin Complex (NID 0x15) */ + 0x01571cf0, + 0x01571d11, + 0x01571e11, + 0x01571f41, + /* Pin Complex (NID 0x16) */ + 0x01671cf0, + 0x01671d11, + 0x01671e11, + 0x01671f41, + /* Pin Complex (NID 0x18) */ + 0x01871c20, + 0x01871d98, + 0x01871ea1, + 0x01871f01, + /* Pin Complex (NID 0x19) */ + 0x01971c21, + 0x01971d98, + 0x01971ea1, + 0x01971f02, + /* Pin Complex (NID 0x1A) */ + 0x01a71c2f, + 0x01a71d30, + 0x01a71e81, + 0x01a71f01, + /* Pin Complex */ + 0x01b71c1f, + 0x01b71d40, + 0x01b71e21, + 0x01b71f02, + /* Pin Complex */ + 0x01c71cf0, + 0x01c71d11, + 0x01c71e11, + 0x01c71f41, + /* Pin Complex */ + 0x01d71c01, + 0x01d71dc6, + 0x01d71e14, + 0x01d71f40, + /* Pin Complex */ + 0x01e71cf0, + 0x01e71d11, + 0x01e71e11, + 0x01e71f41, + /* Pin Complex */ + 0x01f71cf0, + 0x01f71d11, + 0x01f71e11, + 0x01f71f41, +}; + +/* + * This needs to be in ROM since if we put it in CAR, FSP init loses it when + * it drops CAR. + * + * TODO(sjg@chromium.org): Move to device tree when FSP allows it + * + * VerbTable: (RealTek ALC262) + * Revision ID = 0xFF, support all steps + * Codec Verb Table For AZALIA + * Codec Address: CAd value (0/1/2) + * Codec Vendor: 0x10EC0262 + */ +static const struct pch_azalia_verb_table azalia_verb_table[] = { + { + { + 0x10ec0262, + 0x0000, + 0xff, + 0x01, + 0x000b, + 0x0002, + }, + verb_table_data13 + } +}; + +const struct pch_azalia_config azalia_config = { + .pme_enable = 1, + .docking_supported = 1, + .docking_attached = 0, + .hdmi_codec_enable = 1, + .azalia_v_ci_enable = 1, + .rsvdbits = 0, + .azalia_verb_table_num = 1, + .azalia_verb_table = azalia_verb_table, + .reset_wait_timer_us = 300 +}; + +void update_fsp_upd(struct upd_region *fsp_upd) +{ + struct memory_down_data *mem; + + /* + * Configure everything here to avoid the poor hard-pressed user + * needing to run Intel's binary configuration tool. It may also allow + * us to support the 1GB single core variant easily. + * + * TODO(sjg@chromium.org): Move to device tree + */ + fsp_upd->mrc_init_tseg_size = 8; + fsp_upd->mrc_init_mmio_size = 0x800; + fsp_upd->emmc_boot_mode = 0xff; + fsp_upd->enable_sdio = 1; + fsp_upd->enable_sdcard = 1; + fsp_upd->enable_hsuart0 = 1; + fsp_upd->azalia_config_ptr = (uint32_t)&azalia_config; + fsp_upd->enable_i2_c0 = 0; + fsp_upd->enable_i2_c2 = 0; + fsp_upd->enable_i2_c3 = 0; + fsp_upd->enable_i2_c4 = 0; + fsp_upd->enable_xhci = 0; + fsp_upd->igd_render_standby = 1; + + mem = &fsp_upd->memory_params; + mem->enable_memory_down = 1; + mem->dram_speed = 1; + mem->dimm_width = 1; + mem->dimm_density = 2; + mem->dimm_tcl = 0xb; + mem->dimm_trpt_rcd = 0xb; + mem->dimm_twr = 0xc; + mem->dimm_twtr = 6; + mem->dimm_trrd = 6; + mem->dimm_trtp = 6; + mem->dimm_tfaw = 0x14; +} diff --git a/arch/x86/cpu/baytrail/pci.c b/arch/x86/cpu/baytrail/pci.c new file mode 100644 index 0000000000..6c291f9ee9 --- /dev/null +++ b/arch/x86/cpu/baytrail/pci.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void board_pci_setup_hose(struct pci_controller *hose) +{ + hose->first_busno = 0; + hose->last_busno = 0; + + /* PCI memory space */ + pci_set_region(hose->regions + 0, + CONFIG_PCI_MEM_BUS, + CONFIG_PCI_MEM_PHYS, + CONFIG_PCI_MEM_SIZE, + PCI_REGION_MEM); + + /* PCI IO space */ + pci_set_region(hose->regions + 1, + CONFIG_PCI_IO_BUS, + CONFIG_PCI_IO_PHYS, + CONFIG_PCI_IO_SIZE, + PCI_REGION_IO); + + pci_set_region(hose->regions + 2, + CONFIG_PCI_PREF_BUS, + CONFIG_PCI_PREF_PHYS, + CONFIG_PCI_PREF_SIZE, + PCI_REGION_PREFETCH); + + pci_set_region(hose->regions + 3, + 0, + 0, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 4; +} diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c new file mode 100644 index 0000000000..a3e837d43e --- /dev/null +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static struct pci_device_id mmc_supported[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD }, +}; + +int cpu_mmc_init(bd_t *bis) +{ + printf("mmc init\n"); + return pci_mmc_init("ValleyView SDHCI", mmc_supported, + ARRAY_SIZE(mmc_supported)); +} + +int arch_cpu_init(void) +{ + int ret; + + post_code(POST_CPU_INIT); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(rdtsc()); +#endif + + ret = x86_cpu_init_f(); + if (ret) + return ret; + + return 0; +} diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 97ed884288..4e0171a058 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,5 +1,6 @@ dtb-y += chromebook_link.dtb \ - crownbay.dtb + crownbay.dtb \ + minnowmax.dtb targets += $(dtb-y) diff --git a/arch/x86/dts/microcode/m0130673322.dtsi b/arch/x86/dts/microcode/m0130673322.dtsi new file mode 100644 index 0000000000..90bf2fb712 --- /dev/null +++ b/arch/x86/dts/microcode/m0130673322.dtsi @@ -0,0 +1,3284 @@ +/* + * --- + * This is a device tree fragment. Use #include to add these properties to a + * node. + * + * Date: + */ + +compatible = "intel,microcode"; +intel,header-version = <1>; +intel,update-revision = <0x322>; +intel,date-code = <0x4012014>; +intel,processor-signature = <0x30673>; +intel,checksum = <0x17b0d914>; +intel,loader-revision = <1>; +intel,processor-flags = <0x1>; + +/* The first 48-bytes are the public header which repeats the above data */ +data = < + 0x01000000 0x22030000 0x14200104 0x73060300 + 0x14d9b017 0x01000000 0x01000000 0xd0cb0000 + 0x00cc0000 0x00000000 0x00000000 0x00000000 + 0x00000000 0xa1000000 0x01000200 0x22030000 + 0x00000000 0x00000000 0x31031420 0x11320000 + 0x01000000 0x73060300 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0xf4320000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x0ae10178 0x7c98f9d1 0x41962d85 0x19391270 + 0xcf3c0336 0xc1f13d6f 0xe46abaf6 0x3b65ca6b + 0xdb666815 0x5a17bfc4 0x4fca009d 0x099ae8b3 + 0x198e2c7d 0x7c665bbf 0xc07a1a7a 0x7dbcee26 + 0x867296b2 0xc885b6ce 0xe602baff 0x68544b14 + 0xc928c400 0x3add156d 0x531946f9 0x92a03216 + 0xda352322 0xd967ee1f 0x3c5170a7 0xf6de834e + 0x5a2ed8b3 0x9fb8f050 0x450de17f 0xfd5ef070 + 0x4954575f 0xa3a071ab 0xb56e2afb 0xe2b48302 + 0x6655a958 0x57c9a438 0x1b2f688a 0x09309bc4 + 0x0be95612 0x529c1633 0xc48515d9 0x29eb78df + 0x9933409f 0xda58dea9 0x58c805fd 0xbc110f5a + 0x40780ec0 0x6ad59bb3 0xc7387fb8 0x591c1490 + 0xf9335932 0x32130e0b 0xef4b3c96 0xacd903f2 + 0x5b362539 0xe7f85529 0xcb17c41f 0xe7e440d8 + 0xfaf7e925 0x969b76fb 0x5edab8c7 0xf00012e8 + 0x121c2971 0xe5b18959 0xadfd07c0 0x1f09c9d7 + 0x9781006a 0x39550073 0x6c438b6d 0x436f60bc + 0x11000000 0x8514b971 0x40df7b4a 0x6a6b7285 + 0x7978ef59 0x319bddf5 0x04c68e5a 0xe1c28b10 + 0x172f63dc 0x306fb95d 0x31d881e8 0x69f8e08d + 0x617a99e1 0x1ab6b574 0x2951fa5b 0xcc7e3e94 + 0xff379d19 0x5c035dec 0xe28ed726 0x22b8a5ac + 0xd08b3ac5 0x45c03b9e 0xcea4083c 0xc26758aa + 0xbe7cf81e 0x43d898f3 0x5c45a635 0xc9cac095 + 0xb89aea20 0x2c02b40e 0xe3a8b48d 0xeabfb60e + 0x776ed2a9 0x080ae6d5 0x7f64b1df 0x00e40ee6 + 0x0f1c10f4 0x792e5423 0x787f5459 0x63a8b02c + 0x3fd6a255 0x049cae26 0x0949f5ff 0x9aebb236 + 0xecc01775 0x91b57b84 0xe0e45ea3 0x5a8bf79e + 0x356a843a 0x2406795f 0x8aaae5d8 0x6a8c877c + 0xa8b2b8f4 0x04cf8f49 0x422d9e2c 0xf09f9896 + 0xe9b92215 0x9c98fb44 0x88556b7f 0x519d6f4c + 0x9e8a016b 0xcb18d16c 0x419b4ee7 0x080b49c8 + 0xc51b875e 0x46aabc9c 0x262d27eb 0x93ea189d + 0xdd0da69d 0x3e5b17e8 0xcc78509a 0x00b07e6e + 0x363d5a70 0x64572070 0x8a84abc4 0x1cb03838 + 0x965fd76a 0x540aafc9 0x83a91654 0x1a722e67 + 0x4bf98ce1 0x2b3c2ff9 0x972cebd4 0xf3a68395 + 0x2613e422 0xf8d031d7 0xb1c79a0f 0xfd44f65b + 0xa7012a9b 0xd9a15a60 0xc311fc0c 0x6f52f878 + 0x3d68381d 0xd2a035d7 0xb790c50e 0x9f1e5010 + 0x41877064 0xa9d1e4ae 0xfe9abbd5 0x60c2c748 + 0x8167e5ad 0x022dbfb3 0x75abe483 0x51c37170 + 0x09b8590d 0xc1bb323d 0x2c7336b1 0xd4d0d49b + 0xc7f6152b 0x7919d596 0x1e1ff62e 0xc49604a0 + 0x33857369 0xeaa3f382 0x98b8cd86 0x176e1bf3 + 0x1a68867b 0x6af0a11c 0x69a82b25 0x48c72525 + 0xa00aae2d 0xb09f67f4 0x1a99f83d 0x7266cca3 + 0x8d03a7da 0x2e1d7c49 0x01ac68ae 0x93188770 + 0x0609e769 0x982ed28d 0xe40999e0 0x8932ebab + 0x5637ad5a 0x2725e8ad 0x56d7caaf 0xc351faa2 + 0x09dbd737 0x0d2f3bf0 0x0623330d 0xdd547489 + 0xcca7e722 0xa9096d13 0x95b17818 0xc092cb81 + 0x72c6eefc 0x1811c37e 0x78161497 0x8be0c4c6 + 0xd63aeb19 0x91ab68df 0x8f2e5e4d 0xf4c74566 + 0x7677a553 0x19698ac3 0xedca0620 0x77f32470 + 0x031e011b 0x751f6696 0xb277d06e 0x3eae2742 + 0x133e621a 0x38fa3172 0x9398cc1c 0xf42a507b + 0x4547d933 0x63a91eb0 0xf5bcf6a4 0x926ba056 + 0x0adf5bce 0x140f53e4 0x7ff6bb5c 0x87dd79ba + 0xbba240ac 0x694f743d 0x709cdb20 0x5b4d4401 + 0xc9693610 0x55f9f268 0x1142bc3f 0xf8fe3689 + 0x04a93c4c 0x33dedc46 0xdc73c725 0x2f5ba264 + 0x5b7a6a69 0x024b64f5 0x6e8bfa12 0x62bf2aa7 + 0x520f5a07 0x3c7c4292 0xb7ad2613 0x1f78fc87 + 0xd5284e4e 0x2c730f33 0x8861e947 0x8bacef7d + 0xbafa2608 0x14ed0b5b 0x3b9bfb02 0x24ced271 + 0x002b2941 0x22d4431c 0x855f4248 0x5ec46e29 + 0x6f1f42fb 0x5dd24fe0 0x290961f6 0xf392dbaf + 0xa1a8d9c2 0x61e18f4e 0xfda59a70 0x5498daa5 + 0x5ae7ea6f 0xf058c635 0x6817ebee 0x8e30dc8b + 0x7c8d79be 0x5fb15b9b 0xeed64741 0xe2642a94 + 0x680d7e6e 0x3cbad7aa 0x808c415f 0xe9323aa2 + 0xaadf5b25 0xf60abf13 0xd5c47967 0xc248d0b3 + 0x0f232cbd 0x84092449 0x5744384b 0x5e153ded + 0x8bb19817 0x34430271 0x917d2315 0x1fc790c7 + 0xc21b5db6 0xec578b1f 0x903a286e 0xca0c59bc + 0x03e95c7a 0x8c659e99 0x7b09da0a 0xd61e7517 + 0x90b1c519 0x8deac92c 0xf99c7bec 0xb6257d92 + 0x3d61c16e 0xebd58be0 0xb470e655 0xa44bbf4f + 0xfebe5313 0x4662110a 0x5d42ccd9 0x140845ec + 0xc80329a9 0x915ca966 0x71e33828 0xe46c870a + 0x7da9a490 0x255544da 0xa20fb8df 0xf94062b3 + 0xb2df5870 0xebf31e88 0x6e723e2f 0xe6ba9cf1 + 0x7e7084c2 0x1782ac71 0x0a0b0127 0xe9234e38 + 0x881356d6 0xb27a54b6 0x5594730e 0x9a14bd8f + 0x6dba7da9 0x1069e285 0x02a52798 0x61ea7d86 + 0x665b2572 0x29d41eb5 0x1d211169 0x1218b345 + 0xbfbd264c 0x5b8b0625 0xbbfdcf39 0x6768dfce + 0x0b5f10cb 0xe159414c 0x74356ed6 0x70077f49 + 0x672107e8 0x11616856 0x824e6f2f 0x99614958 + 0x5857305d 0x416a193f 0x010d266c 0xe5194f03 + 0x152d6516 0xeb83872e 0x4923cc1f 0x1191d1ca + 0x23feb738 0x6817c1d7 0xe49129ed 0x4a53132a + 0xdb46b95b 0x3f970366 0x93f1a518 0xae8d72ae + 0xb689d915 0x0bdfda17 0x2ac7238d 0x1c4291e7 + 0xc5b11085 0x3c51c1ba 0x9fd63edd 0xe464d740 + 0xc17f2789 0x0adef6b9 0xf9aaf83e 0xfb2a9798 + 0x7f16268b 0x4c8ca6c5 0x2b17be52 0x00c91157 + 0xb69eb5db 0xe55ed94a 0xdf13b5a5 0xbb52d1e3 + 0x651bb017 0xc7795724 0x0dfd4711 0x02d2d6e0 + 0xc835e771 0x8ab5dd50 0x7caca109 0xd5c18d6e + 0xbef0e727 0xaff2dd07 0xf1062a32 0x26d14796 + 0x97f6e36c 0xf845278e 0x185eb5b3 0xcde4e201 + 0x13166ab7 0xcdcebcdc 0x143ef0c7 0x2349893f + 0x9dfcb70e 0x7ef72725 0x141c5b71 0x7da0f5d3 + 0x76bebb67 0x28bc0a83 0xb67ecf0f 0xd60a1303 + 0x9391b279 0x6ad41154 0x317896b0 0x1237efa6 + 0x7b2a2e6c 0x3ad9a110 0xb44357d4 0xb32e39fe + 0x2358d28e 0x76e847d9 0x3e85db01 0x6c74e466 + 0x9e4e6b32 0x13072a53 0x5972132e 0xd97cb04d + 0x55ee6a0b 0xc1434b92 0x772f6a1d 0x0f81f7a6 + 0x072aa8f7 0x179da0e0 0x976bd78c 0x2e43c16b + 0x4f4a6b51 0x92d9c61b 0xa9c15fe4 0x3f8a527a + 0x3a232408 0x543d7957 0x21cbd682 0x896de3b0 + 0xba6b3df6 0x2ec86e51 0x2be889e3 0xae764ff0 + 0x3a2f0003 0x7a5f7949 0x577fb5ce 0xb5cbd1a6 + 0xc910ffe2 0x7fd76712 0xfc1e93ff 0xbee7b15c + 0x5db2356d 0x9721a3fd 0x0d408aed 0x4df4c922 + 0x45d5be91 0x6c79b1fc 0xf0bf73bd 0x3f6a73b6 + 0xdcc1b51e 0x2049fe2d 0xf2b2ad4b 0xd0484d3a + 0x1f097d3f 0xced1bf3d 0x10f4416b 0x73cb307c + 0x4b4d94b4 0x2918ece0 0x0cfe69f3 0xb7e86cfb + 0xa6c373b4 0x0d862b62 0x1735cd72 0xef23c127 + 0x09809c16 0x86cfb70b 0xe67c6903 0x743223a7 + 0x13c7d27f 0xb70a58cc 0x82c57566 0x2ead3c65 + 0xf9409863 0xf2b578ef 0x1622a34d 0x5ae8e861 + 0xf4384016 0x443ff5f4 0x088b8510 0xd738d1c5 + 0x577d624b 0x5adf3973 0x5f79add3 0xed7e7145 + 0x29008fc0 0xd5b278cf 0x5b4c08c2 0xb063af5c + 0x67d41bd9 0x2d11424a 0x727924de 0x8903a86f + 0xb122d314 0xd9675c8b 0xc2eb1382 0x4c4185da + 0x257a0fe1 0xc3fd536b 0xadbfc223 0xc940dab4 + 0x2e83d4b0 0xf1135ad4 0xfeb1cc1a 0x9178ae04 + 0x996d72ba 0x07f6bf0f 0x6588f833 0x44f95205 + 0xee4e6897 0xa9006735 0xa5f5502c 0xeb61aca6 + 0xf2ceddb5 0x40ef9001 0xf862c3d7 0x73deaad3 + 0x7b1d8b1d 0x467bcbcf 0x7f76f969 0x6c8e7f8c + 0xfb8e27c3 0x5075ce65 0x1c8628a8 0x7b6e3e32 + 0x4885fc9f 0xa9fa768c 0x15426120 0x1df9d006 + 0x31c52df4 0x1457f5c6 0xde5f2daa 0xfa250108 + 0xbcf7e460 0x565d4679 0x82c94142 0xae76342a + 0x85aca7c7 0x8bc49e03 0x73f03da3 0x1e500b4c + 0x250288a2 0x25a39951 0x66087700 0x6317754b + 0x6ff62bdc 0xa519ad4f 0xa537b8ac 0xea6292ab + 0xb5d66b68 0x15997d1f 0x0fdbf04a 0xaa2b1a25 + 0x74b72321 0xf8b1753a 0x33658d1e 0xb1cc5d96 + 0x5b0da6af 0x48f24997 0xb031146e 0xfe98e8d1 + 0x9bd75bf0 0x0ae088fe 0xb8fce721 0x964bc398 + 0xe82daef6 0x393884b5 0xa814f792 0xb3667bde + 0x1d1cf32d 0xce862720 0x7b69e921 0xabd26f33 + 0x61fad35f 0xd7144eeb 0x74016bce 0x1d56277b + 0x7f934eed 0xb1a3396a 0xd5090c7a 0x4ea94d12 + 0x1455ac10 0x7c37294c 0x06c60a9a 0xa735ab29 + 0xbffb880f 0x59e2cb48 0x54cca9d7 0xb569da05 + 0x595e72ec 0x7c82f204 0x7690420d 0xe02fbb37 + 0x4dbf4e68 0x221eda99 0x31868046 0xda435487 + 0xb4c0dcc4 0x37610096 0x35569b02 0xefcd4ecf + 0x7b6917bf 0x45946a25 0x5d42a84a 0x8c3801b7 + 0x5ac838fa 0x7a7f252d 0xbccf3cb5 0x99a54c4c + 0x39145831 0xfd5c1af3 0xcabb180c 0x8f0fe9dd + 0xabd42357 0x3b6d9aa9 0x0e87ede1 0x65ea46ae + 0xd89b618e 0x1e5cc772 0xfb43c9b4 0xdad3fdb2 + 0x96be6600 0x4887696e 0x82a4e73a 0xb2ca2cf0 + 0xc6840738 0x397d27a9 0xce971271 0x067e4de6 + 0xb593f079 0x6a77de2f 0xf9a92497 0xdc3e94aa + 0x03239a80 0x7f38430a 0xf7f87908 0x682a8425 + 0x2d491962 0xb5737b4b 0xa26434e5 0x238ced20 + 0x1ed9fcbe 0x283a8f7b 0x18f33cf6 0x29f27cd5 + 0xd95018aa 0x883dbd25 0xfb216723 0xe939d42c + 0xf4b1207d 0x54f5e102 0xbe2e46eb 0xb2ca8219 + 0xab181ad4 0x3a7dc3e6 0xf3713256 0x53f081ab + 0xd630a7a3 0x07c40bc3 0x7a1fde0c 0xb368bab8 + 0xc0baaad3 0xf070baac 0xe4ab7a4f 0x82a8cf5e + 0x9c3d7bb5 0xfe5f74a3 0x02548e86 0x2710ff5d + 0x1b42a8c4 0x34d4f5d8 0x8dfde8f2 0xf2949298 + 0xe9d711bf 0x44d91e17 0x51ba8b32 0xbc3f60cc + 0xa0d6c440 0xf71959b4 0x3b5f0603 0x02465794 + 0xff5d9b8a 0xd4a4abcf 0x8123626c 0x883ed4e4 + 0x9eaeaa09 0x91c38865 0xa0aaeebf 0xc48983ab + 0x1df7a001 0x7519a65e 0x5ef3cd1d 0x8348225d + 0x0f318b0b 0xbab1d51b 0x15ba9b84 0xef8c57bf + 0x15d0a8c1 0x0b542fb4 0x1d51ccc8 0x6c297041 + 0xf3bee946 0x6a8c3d64 0x6e16361d 0xed50ca69 + 0x8c1f66ba 0xff7220e0 0x84a87cba 0x15d75922 + 0x77546d82 0x7bd456e3 0x10166195 0x55604f1f + 0x894280d2 0x0ed406c4 0xc1b4058e 0x645252e5 + 0x670ea74e 0xd5b07337 0x9944e2cf 0xf2ac2579 + 0xd00c3ae8 0x2df3146d 0x4ee1c72a 0x3a3621cf + 0x8c099145 0xf5f530e6 0x210da136 0x7908cec6 + 0xc6e47e22 0xe9bcbe4e 0x94cbcb12 0xb81f0792 + 0x1111f81e 0x4df4ac93 0x335c69be 0x9e3546b9 + 0x06c046b4 0x6f29a99c 0xbcd48ee7 0xeb011efe + 0x41e80474 0xcee30bf4 0xad4e2ae0 0x6929a359 + 0xbdaa88e3 0x9e68a38e 0x16bbdac7 0x020d8d61 + 0x7bab6738 0x559cddbd 0xa6ae3d0c 0xe032c355 + 0xcb45a045 0x9f7680b2 0xc1cb73da 0x466052f7 + 0x488cb929 0xd93f0307 0xb2c9d81c 0xe25fdcd9 + 0xfe8b08c4 0xae6230bd 0x5238b335 0x3474b2a5 + 0x480ce0b7 0xd9a2942f 0xe830fa5b 0x3efa774f + 0x84e53e93 0xf49e7d79 0x59897b26 0x75b1080f + 0xc2212b0f 0xe5fe56bd 0x4556e908 0x1bd0bb17 + 0x2f159d20 0x866477e5 0x4e95a374 0xbdc9fd65 + 0x2ff87073 0x5d7dceea 0x69ada0c7 0x89f16ad0 + 0x97da55d8 0xe4457728 0x5ab7613e 0xf6bbe6ec + 0x56b83617 0x9119b521 0x4fabf948 0x2e1ab994 + 0xd16363f0 0xaee14b3f 0x5461ea55 0x55d95d02 + 0xf72c902c 0x1ede6c56 0x697006d9 0x4d15007f + 0x0c1cb5e5 0x55d3d5d5 0x1f18d76f 0x55c9f017 + 0x3e1d3b5b 0x8f775636 0x97e6bf8f 0x360a9fb5 + 0x1e080721 0xf9825356 0x30e900f3 0x55453bfe + 0xbd8f1df0 0x35b43ba8 0x45db013f 0x20484d34 + 0x944ca654 0x79c2c151 0xd4e9b39b 0x1b2e79b6 + 0x554314d6 0xce4ee44d 0xd0394232 0x9da4db20 + 0xa70beed6 0x4ae4ed10 0x4c244770 0x4b91208c + 0x39a01e0b 0x5eea0a55 0x4b36ffbe 0x6fd18df2 + 0x43fd13e3 0xa99302bc 0x63762b5d 0xd014d6b4 + 0xbf0e53d2 0x0f5b5aa5 0x3c23f5b7 0x16335036 + 0xe011bd10 0x66e596a3 0xf463e3ad 0x9670c0a3 + 0x4004e177 0xbd2b3260 0x01967017 0x1159a682 + 0x62931eb8 0xc581df9e 0x6710932f 0xfb2bb0b2 + 0xb8a0339c 0xc66f0fff 0x333f5ee3 0xc06f8586 + 0x7b9f47f1 0x9aaedaa3 0x6044562a 0x26c73565 + 0x82c6e5b2 0x39d4eed0 0x83b7432e 0x0c4f0e4a + 0x4d9df788 0x989e7f41 0x61cacc3b 0xdc34efeb + 0x240b22a8 0x70a508b0 0x7554f517 0x7269f02b + 0xd27ffcf6 0x96a5879f 0x0650f7e4 0xdc1fc1ac + 0x80781334 0x04ab3381 0x8bad17c1 0x18311833 + 0x65f06ee9 0xfaac30e1 0xe39b8b54 0x20b988ce + 0xa6a818f3 0x75ac753b 0x66f815a4 0x224d7121 + 0x63dc6031 0xcfeed2c7 0x3ccd07d7 0x9df44157 + 0xb9dcca97 0xcf5178f1 0x10e8fb28 0xa1faa527 + 0x8851846e 0x01f56075 0x2dd4fff2 0x40786960 + 0x41aa9e6c 0xf7c85573 0x64a36432 0x4449e726 + 0x7aa7bb0d 0x08f596cc 0x248e1eb3 0x5c5567cb + 0x62ffd012 0x2d79ce59 0xf9ed4239 0xe98e107a + 0x4da25561 0xc6f83333 0x1ca0482d 0xcc3f3b69 + 0xa9f48711 0x99139510 0xc5777d2b 0x9c80814d + 0xab47fbe4 0xf302d145 0x20aecccc 0x3be9e431 + 0x7dc34793 0x4d38171c 0xaa34e505 0xc32e492b + 0x4f31bd0b 0xb7549889 0xdb3da9cf 0x084d0791 + 0xa4c63c9f 0x62e770e9 0x862fdb93 0x52c45b9e + 0xf21019a5 0xdde6aa07 0xcb46386e 0x830693a8 + 0x651510c8 0xf3af66a4 0x78775e07 0xc9f22414 + 0x5769f089 0xac2ae873 0x044357d8 0x9fdc76f8 + 0xea16ade5 0x144e9211 0x181ade72 0xba50ce80 + 0x4573571a 0x5437c668 0x39c3b81d 0x013d766d + 0xc1754b48 0xa611fa3b 0x725eae72 0x04b02ca9 + 0x186a2541 0xa2784e47 0x8b7601bb 0x7f9132e3 + 0x3295d5b5 0x4b470dee 0xaf5ec559 0xc4c442d6 + 0x5b07293d 0x9a68b079 0xc1408c0c 0xc2371025 + 0x4af99e8c 0x332c416a 0xec04321b 0xb8493ffb + 0x51eab7de 0x26d7e9db 0x7880126e 0x439be5e3 + 0x7e8910f0 0xa8ba727b 0x88cb04df 0x70750495 + 0xc13413f6 0x684312db 0x0579d5b1 0x05fe44f7 + 0x627e04f3 0xe85b47da 0xbf646f0b 0x2ddf4932 + 0x1bcb6fc0 0x611de27d 0xb3ee1bed 0x247dad06 + 0xa7107d34 0xba434b88 0x6eb90466 0x45a65871 + 0xa9a67088 0x6af3b796 0xf5b73689 0xcab03ca4 + 0xca1f25e6 0xd4b7c32b 0x5908c88d 0xac6c1fa3 + 0x653184a5 0x062bc0bf 0x383de594 0x17064fc6 + 0x0650dbad 0xaec15153 0xab0572ff 0xab8c6f3c + 0x37a93f91 0xbe51b8c5 0xabcd8573 0x05b3ad78 + 0xad6c9ecc 0xf302c7ab 0x4b3b88f7 0x805a0107 + 0xa5821ddd 0xc36f10ad 0x374b1056 0x79e69f8c + 0x8368b6cf 0xf69458a7 0x9fad691d 0xb937724e + 0xc542bfb1 0x37c0178d 0xc4707414 0xd6c7fa86 + 0xb3933710 0x227800f4 0x6dca3e39 0xd88bdb91 + 0x03755bda 0xa7f2d11d 0x4ab40803 0xf353e7ed + 0xf2464ee4 0x8e58cea4 0xd05807fd 0xd8d8da5f + 0x1a461333 0x5e84830d 0xb94ea4bc 0x5bf3506f + 0x76461ba7 0xabe88c54 0x124c2e39 0xc3b01867 + 0xc6b0d4d1 0x9cc3c7be 0x8039ce38 0xfceb0e88 + 0xa965c5ce 0x9ff3811a 0x1af1c60e 0xae9c5f9b + 0xee28bd50 0x202cbd2e 0x340a1312 0xa8f7115e + 0xb000cf3a 0x21ff4052 0xa555f08f 0x1bead4d7 + 0xac14e135 0x449e208c 0x05ef8d94 0xb555a613 + 0x9d65a902 0x3ad8cc2a 0x55170533 0x75782927 + 0xefd4b5e5 0x6127ef1e 0x23fb5114 0x7ca3e1bc + 0xc08957ba 0x44c4e2cd 0xc0b97ef9 0xea99db5a + 0x53fdeb31 0x61721ee2 0xe41ef3c1 0x5f4788f5 + 0xa8543eca 0x3f36d642 0xda6eccef 0x0341c756 + 0xbfe7d2b9 0x66bb5cef 0xbfb43507 0xbd9c878e + 0x94f307bc 0x7cd56198 0xf98596ba 0x21e9c50b + 0xb9c9d725 0xf16211c2 0xe594b398 0x7e01aefc + 0x745e5ddb 0x00bae556 0xc317ed35 0x4269b4c6 + 0x02f6b67d 0xccb4aa57 0x8a3fa0fa 0xcc660149 + 0x57cf5e87 0x4ed03819 0x77286134 0x631cc0a5 + 0x877fe8e0 0xa48856dc 0xe1c57e93 0xef04482a + 0x40cd9ac8 0xc7f43528 0x473306c8 0x01eb339e + 0x52612a88 0x65c3212f 0x7cc5f5e6 0xd3efbc2a + 0xf2537dbc 0xa9428ffd 0x76ff40f9 0x0ad4a8e6 + 0x2020fbab 0xf8c5bbe4 0xb409e5a0 0x358d7b37 + 0x08220bd3 0xd3707d96 0x5e2f5edc 0x638feed5 + 0x045afa36 0x4f1604b4 0xd4dc85c7 0x37f97cef + 0xe1c8f5a6 0xd16fdbbc 0x986137fd 0x25b3e84c + 0x7f73be76 0xe25dbdcb 0x1f13d28a 0x7a31215b + 0x241967d2 0x2c5b4063 0xe8339988 0x13689262 + 0x0b6d2b79 0x58773464 0xe822e560 0x77d6ba8e + 0x6ae6c07f 0x105e1e88 0x0045bc6d 0x88ad198e + 0xa350b9de 0xd5d0b3e6 0xc4e1cd14 0x47ca431a + 0x2ee94476 0xa2aae1f9 0xfa2042a7 0x37b0cf82 + 0xb1aca28e 0x9a019883 0xbfb11afb 0x754ffff9 + 0xf065a9b5 0x916e14f2 0x93fba80f 0x1dd82da0 + 0xe41c950a 0x12b374bb 0x0f4d533f 0xbef539e2 + 0x1eb5c86a 0x577dd484 0x98900e2f 0xcaec8695 + 0x6a6ab336 0x135e9e68 0xc9b62a35 0xb8982b6c + 0x5bcdb533 0x389b1517 0xbb106e40 0xd402a301 + 0x7446687b 0x35eda3ec 0xd44ceb2a 0xcfa4e441 + 0x29664690 0x598a273e 0xf2a144b1 0x68f81403 + 0xca53e666 0x064e69a4 0x87bb8ca8 0x58193c68 + 0x9b34b17a 0xde2bffc7 0xf72594dc 0x388d3f3f + 0x638a1273 0x5ccf3567 0xcf1017a9 0xe616a6fd + 0x64cab73c 0xd209b022 0x6f08cd26 0xc30f57b1 + 0xac2295b2 0x0c05b1c8 0xf7915ad8 0x9bcf836f + 0x56d8b57a 0xc8b65a2c 0x11868dd3 0xea4764f8 + 0xa7bd30e8 0x8c895321 0xd276a894 0x86042daa + 0xaf6cd261 0x18cc4ea4 0x2c2185f6 0x2bf3ae70 + 0xf3023c31 0x49f4b0e2 0x1e00afc3 0x2053b3c6 + 0xb188c9cc 0x7437a27a 0x1b29925e 0xbc488906 + 0x81cd9003 0x332fcf9b 0xeb20987a 0x831f912a + 0x857387da 0xaf1edccb 0xfe01d809 0x05351b4a + 0x31ec96ac 0x4f064e52 0x10ec8119 0x96c2d29f + 0xc6e1f3fe 0x15b0d45f 0xdca23bc6 0x7b672563 + 0xa94fdc1b 0x7dd22f4f 0xd4d2260f 0xc9e055ff + 0x89e066cc 0x98200d25 0xcba82cf7 0xffb8475b + 0x26550a20 0xf5b4f84a 0x506cb84b 0x00d92997 + 0x7a5c5535 0xe11194eb 0x1ff21f4b 0x725d2be5 + 0xbe89242f 0x0b18afa7 0x6f5b1433 0x829bdaf9 + 0x42db07b9 0x479493cb 0xabd2ead3 0xea6afa58 + 0xf994c740 0x4cb77f7e 0xb946cbdc 0xfe558e82 + 0xa2ed5c20 0x7012b99c 0x72a41e08 0x2058815b + 0x0528d06d 0xe6dbd7e1 0x3d1f6f9e 0xca78b63c + 0x91fa57a2 0xb6d524a7 0x1a61863d 0x89c25c5f + 0x16960596 0x6ebed63e 0xfcd617d1 0x0a927121 + 0x887fdc75 0xec27c8de 0x8c91a821 0xd6bb116d + 0x51fe2c18 0x4af774d9 0x7aa13fdb 0xfc6ff59d + 0x27dd287b 0xe7e3151c 0x835552ea 0xe628aa1c + 0xe0edda2a 0x1957ade4 0x52336fae 0x9cecef28 + 0x2be84cbf 0xa5959450 0x65299682 0x8151d4f8 + 0x716a5209 0x0a8ca663 0x2187bc46 0x000767f5 + 0xe7295b8d 0xa8bc7a6c 0x2b4d2f10 0xf251372f + 0x92ff27ff 0x9bfd83e8 0x8e2b593e 0x8915fd15 + 0x1e44eed0 0x4a3a4679 0xce135f45 0xf996ec1b + 0xfd86c8ac 0x25b008fa 0x8973cf58 0x481512ae + 0xf2bc46f1 0x8b3a92bf 0xbf2a7b24 0xb19e88be + 0x1823f658 0xa8486c11 0x237771c0 0x6f5f0da2 + 0xb05a42e3 0xb562583c 0xa13d37f7 0xe8eede16 + 0xc5154af2 0xfdf7f9b9 0x0b907685 0x1f567e56 + 0x19987b40 0xc82974ab 0xf02ae429 0x9c356634 + 0xb85ba9e9 0xda2141b7 0xd44e331f 0x1dd722d3 + 0x68fd2f4e 0x4e7f88a2 0xab7314b3 0x3dd05c4e + 0x1bb4093f 0xff73db9b 0xf917c6e0 0xae822501 + 0x05cab9fe 0x67c91c76 0x1ebd2575 0x1ae193fd + 0x6f154ae6 0x13780ac7 0x6ff5bf0c 0x6b664594 + 0x494a71d1 0x9bc35a0f 0xb34f175b 0x0069468c + 0x9b125042 0x7df22e49 0xf39cf8ed 0xbe020df1 + 0xe206848b 0x8c428e75 0xc76c05d4 0x0089e2c4 + 0x5bf9a75a 0x30677869 0x544797ed 0x68456dbd + 0x45b8f0aa 0xac5c82d1 0x05aefb75 0x6d5c28bf + 0x009ddb3b 0x551ff144 0xd19127ea 0xfc860071 + 0x30c93457 0xa4c4b56a 0x6928a07c 0x9f63e6a7 + 0x9fa2b174 0x7c1b2fa4 0x4a5a1f25 0x24acb022 + 0x0c3c11f4 0xc7d4cec8 0x4484a031 0x6d3cc1c7 + 0x2eb86733 0x8cd4f77d 0x7b551519 0x124b6805 + 0x57385eef 0x3efd3da9 0xea300d5d 0xe64fc82d + 0x7d33386b 0x3933c4d3 0xe3cb61f8 0xc6fe8846 + 0xbe0df669 0x8646e4cf 0x194a444a 0x404c81af + 0x9448791e 0x586f2132 0x3def508a 0xa3edebe5 + 0x2f3b0b5c 0xc974f91f 0x400ec25b 0xf1513ffb + 0xc13b8859 0x32ac4d39 0xf8f334b2 0xab53ba5d + 0x9e196996 0xf14d8046 0x22fcb441 0xf27ac4c8 + 0xbbdf5623 0x255df428 0xd95a2352 0x8d26f0dd + 0x60a301d1 0x4a2e3e49 0x4654b081 0xf775e35f + 0x592b5eba 0x6a3f9583 0x6ec3d395 0xc8ab02e8 + 0xf343f806 0x62745498 0xb499dbf3 0xd427334a + 0xdf0b61e7 0xda67999e 0x14f9be12 0xf164898a + 0xd6347aa7 0x079a537e 0x294542e1 0x687b7b6b + 0x8478cffc 0xf335963f 0x6c1b9ac2 0x68ff2779 + 0xe3d3f8a8 0x5453c548 0xd968189b 0x13ad95b4 + 0xd71bee24 0x3939f36e 0xb19b3595 0x001961aa + 0x5f2f001a 0x77137eea 0x477698a0 0x1c07c440 + 0x9606b6d3 0x6ce95229 0x25445629 0x5a935f13 + 0x3e2154aa 0x6876442c 0xd9175c78 0xc94d2535 + 0xf2070dd4 0xd4d1f50b 0xa04d18e5 0x3456cfa4 + 0xc7610f62 0xb705a1a8 0xb8766e3e 0x225642de + 0x4be5b1b5 0x44d32453 0x80b8a9d4 0x7297d633 + 0x09e8aa04 0x540929ec 0xbcc58c41 0x6dcf7b61 + 0x6992928c 0xcd40ff22 0x13e4a724 0xd331d5f3 + 0xa512aeb5 0x1c1c4ae8 0x5f0fe5d2 0x3d539538 + 0x383c214c 0xd0a983e9 0x977e8682 0xf38a571d + 0xdb92de78 0x04ba543f 0xb531e880 0xfea55473 + 0xd6d17b05 0xbdd676ed 0xfc7d4f68 0x8b5170ed + 0xa738734f 0x8a25fff2 0xb1b0239f 0x60545acb + 0xcfb00725 0x35f58585 0xcce4ed42 0x05da1c3f + 0x29428b1b 0x099680c9 0xb4608916 0xa9f177b7 + 0x3b393c9d 0x92d19426 0x472dfe73 0x7b12de81 + 0x557ec0f2 0x166fa28f 0xfb6855da 0x592d3e69 + 0x373a1dba 0x9c76abae 0x13c7f717 0xbc53e796 + 0xb2d39602 0xf1efa3b2 0x00046c93 0x1faf82fa + 0x55dec395 0x22a034c8 0x576bd5f2 0x97c36a45 + 0x08a1a923 0x9ac2f22c 0xb029e4bf 0x6c4ca958 + 0xed7276cb 0xa0924918 0x1894c9d8 0xdb993c42 + 0xc31c6e18 0xbadc738b 0x57f95d64 0x4d766a25 + 0xea41493b 0x60c19727 0xe7c63d8a 0xcbc52763 + 0x7882b244 0xe2da61e5 0xd19111df 0x526d01d2 + 0x4e7021db 0xa13fb9fb 0x23e082cd 0xb426b603 + 0x9cac0cdc 0x44a94870 0xd0adbbe2 0x9b77a80b + 0xe1845f75 0xa1704da3 0x2d1c6207 0xba3ee883 + 0x0c3089d8 0x0cba7fdb 0xcb069fb0 0x38738df4 + 0x89971c2a 0xfbaeb7e6 0x459e1365 0x45fba877 + 0x02046ea3 0xd9d0bdb7 0x83c74383 0xc248e9d5 + 0xaae85a56 0x33092ec7 0x6bece02b 0x3b7af1d3 + 0xc92b6e83 0xba032588 0x70e61198 0xa5eb1239 + 0x4d9a6456 0x7d3fe964 0xdb3eb780 0x7e188648 + 0x511a6402 0x48c4ade9 0xba7e9153 0x09490df7 + 0x11b5ea7c 0x4e63145f 0x07ca7947 0xc337360a + 0x2b399632 0x5d1fef78 0x9b1e439e 0x8daa70b7 + 0xf55a59bb 0xc3a8c84c 0x4d18eb22 0x74568737 + 0xf0419b6a 0xbab459a5 0x0cb07a0a 0xeeb8e086 + 0x0a9241a7 0x419c5ce5 0xec841275 0x3ec13615 + 0x49e42b6f 0x2dae6c7d 0x3fc35088 0x1b92ff9e + 0x573b1cda 0x54381503 0x29a5b7b6 0x82994130 + 0xffb93c4c 0xc0a66aa1 0x68889181 0x0826e555 + 0xe81cdf31 0x740109a6 0xb8835558 0xaa5d9aac + 0x0d97ea3b 0x89f744c6 0x2b702162 0x992fe0ea + 0xab3a585a 0x3e7554db 0x9d97ebdc 0x9939bce8 + 0x486a5f50 0x804ccd06 0xff2e15cc 0x67bf77cb + 0xf9beadd4 0x2da33477 0x18adbaf0 0xdb00dae4 + 0xe727033c 0xd10ce1ac 0x4f8c4a29 0x281bf150 + 0x764e1387 0x8c65a901 0x841521e3 0x31d9dfd7 + 0x1e7ba122 0xe8fd6d3b 0x4bfe880b 0xd2c1c20f + 0x9a07169f 0xedbb94b8 0xe9cbcd9e 0x33cac378 + 0xa42fef1e 0xf0e5ff32 0xa86b9038 0x7dbec0cd + 0x7ad1abe8 0x5e3e4e8f 0xc4dfe8cd 0x86630ba1 + 0x02003c6f 0xbcb50d9c 0x65d874b1 0x01a09ddd + 0xc97d3d65 0x2d02bedf 0x6fc63309 0x214b421b + 0x72e0a28d 0xd9c8a577 0x1c8665a1 0xd33b4583 + 0xfa004d9b 0x5c2470b7 0xc671fed3 0xe033617a + 0x5a86c333 0x13388e4e 0x3bccdcda 0xc62fd60b + 0xcae17379 0xf6d84d27 0xaaa52422 0x5771e380 + 0xeb1feaf3 0x3c28e7fe 0xa0fded4c 0x5f63a3c7 + 0x3b42ed09 0x1748d617 0xbc2d4fd6 0x3416fabc + 0xc1e60e41 0x48ffe41d 0x4ea5532b 0xba7dba76 + 0x21378ac1 0x7425d0f3 0x426b3153 0xdc57d14a + 0x54997f9a 0xeda2a56a 0xfcec5ef5 0x6fd7acb3 + 0xf2691009 0xc1a219e3 0x09a82589 0xc6e1792c + 0xb4674578 0x0aaf55d2 0x23c7e9dc 0x7607d612 + 0x580fc695 0xd24b2629 0x0a8726a1 0x3544e0a2 + 0xc1de7011 0x30982b80 0x9cf4f328 0x02b22d26 + 0x78e33c10 0x2ce6bb5a 0x92280ed7 0x2ce5b007 + 0x64552836 0xda4a7b51 0xa6122870 0x00b28bb1 + 0xb98cda46 0x84cbe910 0xeccb62a8 0xe13c3645 + 0x2f4494e4 0xed0da7b1 0xb8aa8a1a 0x1adcbc0a + 0xdab03e90 0x904d9041 0xaa8fe377 0x087cf59e + 0xa123b5aa 0x633c29c0 0x36d915d6 0x8f5cacbb + 0x8834d1b5 0xa2c12731 0xfab5176b 0xe1888d76 + 0x4875b9d7 0x5747b32c 0x73fc6d36 0x202ffb90 + 0x62900e06 0xa5f2a41f 0x497589c6 0x7ec701fd + 0x45801f09 0x1833e8fd 0x734acfc5 0x2f65bdb8 + 0xe6add84d 0x4ad6dfaa 0xf59dd63b 0xb2150e00 + 0xed32ddd6 0x370ce8d7 0x5fec9315 0xb8e6ba73 + 0xccb15a6b 0x302a0084 0x9e49e2ce 0x7af3bc8b + 0x488e6ee3 0xcdbf0b31 0x762ce0d4 0xc50a111c + 0xd07d6e3e 0x18c391a2 0x1a7a559d 0x10b4b3bd + 0xd0703a3d 0x4e431eb9 0xf78edbe3 0x896604ba + 0xc0e8d4c9 0xd42f2292 0x5414ea6f 0x0ce7d429 + 0xbb659e0d 0x46fa830f 0xdad39c12 0x0f65fa5b + 0xa002e598 0x5408cfcf 0xc1c3a5e0 0x28ca35fc + 0x52b2b588 0xb76e1f54 0xb6c355c7 0x08e3ba79 + 0xfd89c1f8 0x6ebf03a9 0x51ebb756 0x729e1c5c + 0x1ed0cce2 0x29733f1c 0x42b76fcc 0xd94022b4 + 0x3efc8ac9 0x3f23eae1 0xa0ccf230 0x9da59cf1 + 0x5f6db360 0x922686e1 0xc9138d5d 0xda43fd20 + 0xe0757988 0xa315c62f 0xe3642291 0xc45d9701 + 0x2c394ee3 0xab92e7bf 0xf6037b8e 0x1f523243 + 0xe91791d1 0x19961c4d 0x35d3b069 0x1596143c + 0x203bca40 0xd26d72c1 0x94c059c2 0xae0df468 + 0x3b0909a4 0x34aa916f 0xe0c254e6 0xd0969c55 + 0xa9b0b923 0x80a9dd5c 0xe79b8d8a 0x3599f269 + 0x623c20dd 0x41e11b9c 0x40fcee5d 0x65dfa8f5 + 0xbffa7357 0xa5b8f59e 0x2bb8191f 0x226a1b43 + 0x910b6d4f 0x73837092 0xd666f5da 0x14fd4426 + 0xd41a8547 0x6f4e928d 0x8096c2f2 0x525ba180 + 0xc6a28d43 0x960b7cb0 0xb76dacbc 0x024de046 + 0xc8e3c937 0x0217493b 0x1516dc22 0xe19e70d0 + 0x655321c8 0xa46a9105 0x61ec2a61 0x1400405b + 0xcd0a758d 0xdc792982 0xbd994932 0x6565c8b2 + 0x187be349 0x0afa44ad 0x714870fc 0xede1b8dc + 0x2c4ac6b5 0x7d9793ea 0xe0bc3c0d 0xaa56f23a + 0x7fd4e2ec 0x2131ad26 0x2cd34428 0x45e9dec0 + 0xc15b692a 0xae73e713 0x37c5c3d4 0x70ff213c + 0x4d6322fe 0xa29a9b4a 0xca7d3c65 0x1024df74 + 0x308f4a3f 0x4f48c7d9 0x0c71a17b 0x540441ed + 0xbc2f36a8 0x2592d7d4 0xbb643dd3 0xb8fb607b + 0x6b2b339b 0x9a40ecc7 0x59226bdc 0x42a5c04c + 0x6a1dc320 0x14e3c7c4 0x39cb912c 0xcf5eb477 + 0xa3a43975 0x79f92cc3 0xe9d4cdfd 0x02dc8fb3 + 0x240b6842 0xe9ff7bed 0x8f5269b3 0xc4f44baa + 0x1f1c74b8 0xb5c39051 0x291cce82 0xfc129a8b + 0x0fae02cf 0x31b4d4cc 0x1dfe9722 0x093cd430 + 0x96c2a838 0x19b3a068 0xa7ead8c3 0xa2b3b92c + 0x2e1dc49f 0xe2f84217 0x670e73d3 0xd7c3710e + 0x94e4a7c9 0x33e063ab 0x35176206 0x910504bf + 0xb04b61d3 0xbed9c702 0x5d6c4cc3 0x63276a86 + 0x0bfe5143 0x7ed925a1 0xc455934b 0x402a8b04 + 0x01c03292 0x5de0933c 0xd932d260 0xb5b3b5ce + 0xde53664e 0xeaec4fc0 0x506030ac 0x6fbd8304 + 0x0b0e4881 0x99c16b3a 0x6fc976ad 0xeae57df9 + 0xc53a953c 0xca681bc7 0x905e49e1 0x405d42c5 + 0xef39b878 0x57ded0df 0x56b98e32 0x392ce7d0 + 0xaa7fbfb5 0x6ff550e8 0xf346ae82 0x2b25a8dc + 0x3ff980eb 0x302aff14 0x1a43c7ae 0x23f8ec16 + 0xf774024b 0x1c4e163d 0x6b6f9408 0x0646b4e5 + 0x2e55bfcb 0x14e3f7bf 0x86fec07a 0xda898470 + 0xd99a274a 0x8630e98f 0x8c843f0e 0xa840c028 + 0x950d7fb1 0xeca930fd 0xd281c9e3 0x29b3aed6 + 0xc419314d 0xa6147b28 0xb504311a 0x91c07531 + 0xe19ac720 0xfa8cfb5c 0xf8158bcd 0x42202a1d + 0xfff43b87 0xdc6fa0d9 0x8a599eeb 0xac3a8df2 + 0x83ffa50f 0x346a8ff1 0x0947d1ca 0x318a8949 + 0xe409dd30 0xf73ac9cd 0x9504c972 0xa2392b4c + 0x5594ac9f 0x7a45c3e8 0x181d42db 0x085e24a9 + 0x6cb3e60b 0x3568d771 0xfa96b628 0x945817e8 + 0xca9d28da 0xcd3a174b 0x7f84ca3d 0x90381d0e + 0x09a6f9d7 0x11396376 0x4d158586 0xcc451745 + 0x9844225c 0xa45b8a9c 0x0c64efde 0x7429ee29 + 0x308c39b5 0xa3454fb6 0xf949f709 0x09391206 + 0x0168257e 0x94e10cb6 0x48e49996 0x92928443 + 0x4a826036 0x9a777b3f 0xf77adfdf 0xc111b354 + 0xa7ece533 0x050706ac 0x91ed3fd2 0xca15baf6 + 0xd1714105 0xb564c842 0x886800cc 0xd57309e1 + 0x38e4fa43 0xb74fe550 0x26f300bc 0x6349cbe6 + 0x4bc132ae 0x310c1d40 0x3353100c 0x0a308892 + 0xea6ab62d 0x0a438e7c 0xb000cf51 0xa21aadb3 + 0xd3628343 0xee7f1a6f 0x3ee28d91 0xa846f25a + 0xc898e7c0 0x1198f67e 0x2401caf3 0x78d7acfc + 0xbc592220 0x1efd847f 0x1e3e935d 0xdb9025f6 + 0x41ab6bb6 0x08a10f85 0x160dc5b4 0x4f0ed74e + 0x8c3db59d 0x34034397 0xe26017c3 0x03fe3b41 + 0xc4480582 0x7c0c85de 0x4957c26d 0x9eb32143 + 0x28676ce2 0xe3627f34 0x71e3afb1 0x7e978fbe + 0x3b3ee0f9 0xb5ae1bcf 0x474dc4cc 0x470e2114 + 0x2490e60c 0xbb534e7c 0x7a8ad252 0x7cc08810 + 0x9ea23718 0x04ecf4e1 0x732a9f10 0x62c69e22 + 0x5a94fb4e 0xc1da497b 0x3ab3f2b9 0x09ff7310 + 0xd7749df9 0x170471dd 0xaa551e91 0x2d605856 + 0x66a13f75 0x0be4b8a2 0xe64a0c3f 0x288e5671 + 0x5ee690c8 0x9e1c4b10 0x9f055568 0x8c6ff177 + 0xa7229231 0x19e678db 0xd90be83f 0x0cf70d67 + 0x47462463 0x327fdd91 0x51986170 0x3ad883b2 + 0xa32fa5f2 0x82167691 0x74b6c59e 0x3eae0a3a + 0x569386dc 0x6d67fc33 0xa0943958 0x40b2939f + 0x334acedf 0x91b6a866 0x5debd880 0xa6f3712d + 0xbe8ca5c8 0x4b43fa68 0x72b677d7 0xa42b4d60 + 0xc719163c 0xa469fbb9 0xb484def6 0x508ddfd1 + 0x23bf14bd 0x857a13ad 0xf7a47090 0xe6816794 + 0xbf6d3db3 0xd19fe091 0xb9421e39 0x35b184c2 + 0xa5c94a6c 0x13b2b25c 0x5c7b45cf 0x648fdd47 + 0x8832d949 0x0e2380c2 0x2f8e4f88 0xc01022aa + 0x4dec89bb 0x0a2c5bff 0xa97e58f8 0x304dddd1 + 0x468828ac 0x603da881 0x646ddc90 0x1afa151b + 0x985bf8ad 0x6e3635d5 0x181268c6 0x420e1647 + 0x913af569 0x14075a17 0x803aba15 0x2a2562b7 + 0x2f0627db 0x52785b48 0x36ce7fc3 0x6057349e + 0x4affb11c 0x84e82be9 0xa0f60f66 0x1d176256 + 0x9f1dba85 0x2852129f 0x4592540a 0xae083e7e + 0x744edf82 0x75a1e1b7 0x518fbebc 0xf1828d15 + 0xfa1e31b7 0x88ebf51e 0x0a648385 0x956c002d + 0xc8b660cd 0xa82eeb58 0x0754bcf9 0xc4873df1 + 0xf06c843b 0x7e5ac181 0x59661ea5 0xef2ae542 + 0x0fea9691 0x9493a352 0xb401f705 0x85573914 + 0x4e1eefc9 0x45e51c5f 0xd713688c 0x97efca3f + 0x292d0e73 0x8db44fd8 0x9f4479e0 0xc049ff9a + 0xfac5ddbb 0x4d610fdf 0xa9e01cdf 0x93b4dafd + 0x925004b9 0xb0796ea4 0x7e166ac1 0xd030c4ea + 0xa9f34c73 0x276cbadb 0xf3b9c282 0xa5bd6a69 + 0x53df3f11 0xded46173 0x70bff329 0x0ddd0e77 + 0x52e4a782 0xf01b024c 0xda90618a 0x34a2dd05 + 0xc144d1fe 0xbaca12a5 0xbbd28cf1 0xc54d84f5 + 0x0e7cb67b 0xe009e900 0x23657441 0x2214b4fe + 0x37693ee7 0x62e093d0 0xf79ca670 0xf1bc6cec + 0x1b91f787 0xc9d234c4 0x2a193a4c 0x8c2bfaf4 + 0x75f4514b 0x03501d9a 0x5554de35 0x5ff35a26 + 0x670ad976 0xbc8151eb 0x725fb971 0x5768e86f + 0x7fdcf5ad 0xe814f3ce 0xe8b9510a 0x55bf074a + 0x415fc288 0xa1a360c5 0xf5fef671 0x2d6253fd + 0x7fa09b81 0x2bb2e018 0x7159e648 0x10d5d59d + 0x462047cd 0x77583e64 0x47f1074c 0xc3c0e0d3 + 0x023a55b5 0x4ad55057 0xe6d4b9d2 0x9cdd844f + 0x87eff8f4 0xd95c1e55 0x7499004e 0x2a43a598 + 0x0c1472b4 0x33c90a5c 0xc4703c62 0xf293e2d9 + 0xc3153c7e 0x6eeffef9 0x115e14ec 0x4ad27157 + 0x888d87c3 0x33edc70f 0x7c38ce66 0x61c10a52 + 0x5db41c48 0x8e309060 0x7b847b63 0x6b619cd1 + 0x12855e03 0x52c3281e 0x704f969e 0xf9ab7862 + 0xb143fc54 0x1ac23fd5 0x89dcd807 0x40a7ffc7 + 0xc84245b8 0x0248d94d 0x29aca158 0x92d7b241 + 0x751588ff 0xe8203587 0xc5bd7cdc 0x9de82608 + 0xb075493c 0x5d43c228 0xff6a5345 0xa64cae5c + 0x4a1a9a26 0x08c60b16 0x9399ba46 0x3f535d1c + 0x3b9a6ab1 0xa446115c 0xa77bd99c 0x2431dc72 + 0x729a637f 0x13f960d4 0x230d4e9f 0x0c608153 + 0x9b9670fc 0x72494838 0x14832ade 0x65aba892 + 0xd6434455 0x17697982 0x68b9bb34 0x1d700b3f + 0x6d0dda39 0x30e0d15e 0x87de41fa 0x9fc55b16 + 0x0f5730d3 0xc3ea8127 0xeee64f5f 0xa02c5baf + 0x64e18d74 0x31de5660 0x5cf8d724 0x6c07ceca + 0x409e862a 0xd4ee7999 0x90c22c99 0x59cd395f + 0x09c36563 0x1993b09f 0xb0c4e064 0x8d6870a5 + 0xe2e8e337 0xe8bef0cd 0x708d869e 0xdf808519 + 0x6fa61e32 0x27161ea8 0x063c783c 0x2aa55c1a + 0xa6fcc8a3 0x918b284d 0xbb7870b9 0x788102c3 + 0x3e49edfa 0x6c5eae4e 0x1c9fc361 0x554ca60b + 0xa08364d3 0xa7bd4442 0x204822a5 0x000b71a2 + 0xd4dff005 0x43265901 0xbdb99200 0xc438e254 + 0xa4982e58 0x02812101 0xfacbff1d 0xeec56aaa + 0xa5525774 0x21ada574 0xffe2f703 0x15d30ea7 + 0x600696f9 0xc7ff3f59 0xdb57c175 0xa16f78df + 0x54a15622 0xe3742dcf 0x06d32994 0xd48463a2 + 0x44c7c25a 0x41d6ded1 0x3b314de0 0x09992482 + 0xbeb183c5 0xa0a65c27 0x842075b7 0x9b97e3c6 + 0xd9545fc7 0x16d00629 0xd85640df 0xe79e694a + 0xe818d277 0x1c3d4623 0x23a9a926 0x83ac1b3d + 0x39e890c8 0xb3738b84 0x54b772ef 0x74518f0c + 0x7190098e 0xe26aff75 0xf6237011 0xbd3400fe + 0xda1b8fa6 0xdbf5566b 0x5155cef3 0xddbf1973 + 0x34e2cb2e 0x535fd6b8 0xbfd337aa 0x6dd1fb0e + 0x52b04fbb 0xab5eca05 0xdb740dc1 0x104e6131 + 0xbf4dcb75 0xaeff3524 0x4257c6b9 0xbf1c8cbb + 0x0a69ed82 0x90d991c7 0xea075cba 0x5e3c8330 + 0x823116f8 0xba8f8a2d 0xcb98a1e9 0x8b2655c6 + 0xd2f11133 0x3422f3ba 0x3e3a5742 0xdb9714fd + 0x91701f60 0xeba19983 0x8bf9f157 0xec87cd03 + 0xb63260fa 0x207c345c 0x0c838d5a 0x736415ba + 0x9638ab07 0xb32c72bc 0x304d191b 0x7775adc8 + 0x57ece662 0x0467bb66 0xb7cf80e8 0x4c635024 + 0x176946c3 0x29cba0ae 0xf214b3f2 0x6e727126 + 0x87b3747c 0x4c19b86b 0xfcc66fce 0x86681713 + 0x636387f1 0x589e78f3 0x2e8abf1c 0x22c828f7 + 0x99653c62 0x8e3bd31c 0x79187a73 0xc6d0e5e2 + 0x8005a045 0x78a38c60 0xe1e8ff4b 0x1102d320 + 0xaaf4ba7a 0x7223d041 0x45f73e81 0xaf7168af + 0x218ab3ae 0x8b1956a7 0x4db00173 0x482c3bc2 + 0xd982b945 0x4bd7757d 0x0c5ef18e 0x74e66de3 + 0xcf421ae1 0xf2ddc098 0xcec27e0c 0xe79e711c + 0x6f76e136 0xa8d72245 0x196390a6 0xbf56633d + 0xd1156298 0x5712cd8b 0xaed801ae 0xa345fab5 + 0xfde1ba97 0x437a0b29 0xfc5628a4 0x93acf698 + 0x83ce0bff 0x212f15c3 0x723ef016 0xe793bd50 + 0x8bc51b39 0x42f17ad2 0x1df73878 0x19af3c24 + 0xf55b6f93 0x506138d0 0x164c542a 0x8d4e1a26 + 0x6c606f83 0x6fbebdf5 0x0e4ad76e 0xabd88e6b + 0x0e0d74e6 0xd139e08d 0x8b6cf03b 0x04a527b1 + 0xe619c7a8 0xbf0d57f6 0xb38a5f5f 0x3f328013 + 0x374c0a9d 0xff36910c 0xe950a494 0xfc477720 + 0x37bd9390 0x4667497e 0x724eb66b 0x86bda8f7 + 0x52efc959 0x32d5c2bd 0xddbb49ca 0x9c1eef2c + 0x508d8b81 0xc33d7001 0x360ae3c7 0x1197f6c2 + 0x25efc933 0x4ad234a5 0x9e9c8658 0xc16d4aff + 0xbc428573 0x30e8b4c0 0x728c2c48 0xf34e1e70 + 0xd62187c5 0xca869f89 0x34685a33 0x85d9b877 + 0x9f77605f 0x93724d34 0x5fc8e8d1 0x70dd81a6 + 0x643e543b 0xe4ad6c73 0xd6b4e5cd 0x387519c3 + 0x719d8c6a 0xb2e0565f 0x02235c90 0x230c9b5e + 0xe76841a3 0xc2833be0 0x4dab4a72 0x0ae6c0a9 + 0x0b5e12e2 0x4cda3610 0x954b6ff8 0x6d89a683 + 0x3583e633 0xdc540da7 0xe2955deb 0x0f290d9d + 0xb01e57c4 0x977f4588 0x24b95f0c 0x45529128 + 0x4528b5ee 0x27511439 0xd088d9bc 0x7c471853 + 0xf03b8455 0xbda4a828 0xf49736df 0x50eb17c3 + 0x2affe0e6 0x6727858c 0x6500b8f0 0x0483aa89 + 0x0e1f6a41 0x72666733 0x85617ce8 0xa0c86838 + 0xbccd2eed 0x06e8462d 0xc947bf5c 0x4d2d0a53 + 0x02e70008 0x5039a596 0xb0118cc1 0x690ba325 + 0x057ca95e 0x032cc1ba 0x3dae2c88 0x4eaa740e + 0xf07b09b5 0x6b2c2135 0xeca746b7 0x76019533 + 0x4cf477b7 0x31848299 0x6b5c7df9 0xc0db5ff1 + 0x7cd3e08d 0xe25fa562 0x260d66a4 0xda30cf2c + 0x14ab6c70 0x029a8dd5 0x7cd5fe2d 0x98ea5852 + 0x555cf635 0x6c72ccbd 0x64120bef 0xd9e19613 + 0xf26ac6e8 0xafea03a4 0xc14a11d7 0xb2f8420e + 0xe319634a 0x8a8fedd9 0x6ce0da89 0x74269f31 + 0xd7e0d776 0x86ae9513 0x48bdea80 0xb2e4c581 + 0xab25566e 0x9ccb71a5 0x7cedb09f 0xd2bdade6 + 0x39c96ad5 0xe8ebbeec 0xac8a2e2a 0x915be930 + 0x95e7c98b 0xd00e1d3b 0xdacd08ac 0xd9f515fd + 0x45cd3946 0x828a2cc3 0xfbe1bd9a 0xc5e1ebcd + 0xac69128c 0xcd6423ba 0xd8653b60 0x48f0614f + 0x0c1ebbbe 0x7ab89792 0x9a4b0097 0x2bda854d + 0xf17ab2c9 0xcde54eb9 0x4b53a030 0xe2399c4c + 0x19454a2f 0x473fe390 0x3a42c16c 0xc4c106a9 + 0xf5d96e73 0x2ab4078c 0x5d20e7ba 0x47880aab + 0xff5e0d78 0xa374bdc2 0xc17109ea 0x39fce648 + 0x00821cbe 0xc54a60ee 0xd753386e 0x7b28fc16 + 0xb6309bbe 0xaefd0548 0x41168500 0xee5989a3 + 0xe0177f09 0xc9fc9eb6 0x09a6e188 0x45776a0d + 0xf19a4830 0xc6774893 0x814b2e43 0xf8be5e3c + 0x22fa8237 0x75c98f46 0xb1c52edc 0x443d54f8 + 0x6a1a886e 0xc7f33598 0xaa794644 0x685e5ca2 + 0x97a735ba 0x3c1a391c 0x13f6f89a 0x660d7041 + 0x333c3eef 0x40541bb9 0x5c3724d5 0xc348023e + 0x89791dd9 0xe72fba89 0x5af98b2c 0xb534fd29 + 0x64d0e6b1 0xa578e77f 0xf311215e 0x634cc8cb + 0xbc534e51 0xdfce3ac7 0x90f88f51 0xb3f7dd48 + 0x20b3e0ae 0xf4456e85 0xacb3925b 0x2eb3ce78 + 0x37e61d82 0x724b9cbc 0x1462d9c1 0xd3f49dc4 + 0xc1ffcc00 0x7c3e3f86 0x6f283bf8 0xf43671ab + 0x90cbfb35 0x55390829 0xc8fd0d31 0xc687c45d + 0x724ee656 0xfc1eab3c 0x3c8c2f04 0x3caa3af4 + 0xbe220358 0x4d5b49a2 0x12cf4893 0x867173fb + 0xccd4b513 0x7c94a1bb 0x86c42c18 0x2b2070f3 + 0xd2a70638 0x9d7c07e3 0xd02ed59e 0xd349488f + 0x1e85754d 0x333db889 0x0d0defdf 0xef282e45 + 0xac3f6c29 0xd65a68d1 0x5d0914e4 0x395ec78a + 0xb056aa6b 0x4d98d059 0x7ae08f88 0x25c923d2 + 0x79670f38 0xa881d62f 0x89cd5015 0xfb01da43 + 0x5861244c 0x05e201eb 0x41d71eda 0xb2babb53 + 0xc3845fb3 0x1f3b5c56 0xde6c10ac 0x73adb998 + 0x714aac3f 0x4ad9fc65 0x3acdd014 0xeb319d58 + 0x48842806 0x47ec1040 0xbfdf0052 0x3c478ec6 + 0x83b43a0f 0x9e727e69 0x9f4d5925 0x9f45c13e + 0x30b8572b 0x26edf8cb 0x577e8b9d 0x9b98d7b3 + 0xa44a9bbb 0x903e39eb 0x51226dbc 0x933a52b7 + 0x14c6dc86 0xbc24db59 0x21054454 0x98fc5fa6 + 0x2c9d8606 0x19178173 0xeda24205 0x90dfaca4 + 0x21d562ad 0x7e3ad05e 0x2b3a40a4 0x46513f35 + 0x0d13a598 0x8bf71ca2 0x6a36c430 0xe66f5587 + 0xc9f13bd6 0xb6534a8b 0x8a3fbfd6 0x38cdfe6c + 0x1a1c89f8 0x6d782709 0x7919c451 0x6ccc96fa + 0x334029b2 0xa638356e 0x001e709f 0xb2132b06 + 0x483f1933 0x189ab8f9 0x4ba0ec13 0x490aee0a + 0xda63f1fc 0x5679d38a 0xcf1e92f3 0xe7257fbe + 0xfeb733d7 0x0704860a 0x34ce2032 0x663b948f + 0x544cc928 0x8c23d5aa 0x67986469 0x93f9ac08 + 0x4fa9a13f 0x9eb311d4 0x41a64161 0x29d1050a + 0xa5285c24 0xb53d03a6 0xc5de26f3 0x7876d1c5 + 0xbdcdcb4b 0x79d1196c 0xe9890732 0x3e58a8c0 + 0x874f03c7 0xfdfc9cac 0x5d57fa57 0xa3ef01df + 0x47bcff48 0x8beb1aae 0xf4bb4f9b 0xa5c83b64 + 0xd69ab0ce 0x40f6691d 0x2eb8fb7d 0x22640f8d + 0xac1ba157 0x3687d705 0x7fac8727 0x4ad75cd8 + 0x7016d2e9 0x25c36c08 0x7e4248ea 0x292bda19 + 0x2acf589d 0x0ef7726d 0x835f9e62 0x3f9a1973 + 0xbb6d2588 0x078ff6b4 0xaec22b5d 0xc740501e + 0xa2ab115a 0xea993e64 0xa0cc3ed1 0x934e4e0e + 0xd732b66d 0x5fd28c47 0xe4ccb898 0xc6a101c0 + 0x78274bae 0x625df6a1 0xaf774052 0x3b7c08d2 + 0x6180ac39 0x3e5aa769 0x6ec74578 0x6b5d27b9 + 0x98e58a17 0x119dd7d4 0x39429c5a 0xe3d5b391 + 0xbb8fddb8 0x5929801c 0x68cef71c 0xc36fa301 + 0xeace4850 0x29f4f97d 0xa58bad79 0x2823998f + 0x0fe1352b 0x5960ded0 0x69308816 0x0d7e33c8 + 0x2fb13bfa 0xff6a326f 0x69cb631a 0x839ea2a1 + 0x528a8065 0x34cbebfa 0xd4432cc4 0xe13b550b + 0xe046569f 0x87b41fb1 0x7751107c 0x0ef6e60b + 0x856ffc50 0x11995683 0x77c2ebf1 0x4dec97f9 + 0x3a28ebc0 0xb7bfa04a 0x40cdceb0 0xd559dd06 + 0x61c2cd6a 0x8a906fa2 0xd55f43d6 0x7fb3ac35 + 0x8cea4e81 0x1d359c2e 0xec447c57 0x3414f7f1 + 0x18243b84 0xdf76849f 0xd753044a 0x7af2d51e + 0xaee26ecc 0xae6946b2 0x7478c675 0x88b22f49 + 0x4de13fc9 0xd35c5956 0xeebb60b6 0xa15b1736 + 0xa6e78d78 0xfd5e30b3 0xb4fade2d 0x964eb418 + 0xe9035f51 0x22ab8242 0xfaa64053 0xdfe03834 + 0x47beb588 0xb82a0887 0x11182e85 0x2f2f9a67 + 0x4b612f11 0xae04077e 0x7f783c25 0x883a34e1 + 0x32d43beb 0x6f0536f7 0x85c1537e 0xfb26199a + 0x45417e88 0x4af2c8cf 0x0a334486 0x2a3e6838 + 0x31b8725b 0x63d64541 0x7e516a0e 0x7e42e766 + 0x4cf30198 0x68abecff 0x7fb49c43 0x8f5b558b + 0x32b99abe 0x67337248 0x224c3411 0x4e7c41b7 + 0xd3aee3a2 0xca19e704 0x2a430b7d 0xe9aee453 + 0xf4ce492d 0x48fab2a9 0x42ec2076 0x0182cea5 + 0x8a6373c7 0x18f41b5d 0xdd062fd5 0xb1db44a7 + 0x285ad917 0xeaaabbd1 0x359b1b23 0xcc123c8e + 0x38b70cb9 0xb01ae722 0xa6e72010 0xb647530e + 0xf9651d41 0x366d6d0f 0x4b656a6d 0xd36637f0 + 0x4b5ab8bf 0xc22fdb1e 0xc57c8250 0x799f4e60 + 0xb55bd50b 0xe8a3432b 0xe752e4e0 0xd0c86482 + 0x122991f1 0x5bec598e 0xbcb89abd 0x739f61d0 + 0xd230ae2a 0xd0b99c05 0x2a998a6d 0xab715831 + 0xb7dd1939 0x57db0ea7 0xed1f4952 0x49274caa + 0x35e319b0 0xed2c9cb3 0x601caa20 0xfe782688 + 0x64b6d30b 0xcd5c325c 0x2c836157 0xa3552f79 + 0x188094db 0xa42dd7e8 0xc09c2dda 0x02d98d8d + 0xed270d28 0xb0f38ada 0x5d7b4261 0xb41df8d8 + 0x7341b6ae 0x024ce90a 0x0727ae4c 0xa8dd3a0d + 0x390f84d5 0x43f5bd12 0xd11fb61f 0x6fc330e1 + 0x7f2d7fa6 0xf758a4e0 0xceb1f3c3 0x2f341836 + 0x98fb470f 0x5bf68e58 0x1917a5b2 0x75f33be6 + 0x16e22316 0x8aa810a0 0x1fc6c9b2 0x22179249 + 0x3de701e9 0xec48d8b6 0xe85248c1 0x314ce9c1 + 0xddeb2f47 0x0187909e 0xaa755f62 0xb2019460 + 0xb2016a9c 0x91f789be 0xe5925997 0xe4864300 + 0x1fd13759 0x0ad97c1d 0x7cf08c01 0x7eac2dd6 + 0xcf61a7f3 0xaf9e108f 0x939a2fd9 0x0cb48e78 + 0xe6ea1a8b 0x0b968273 0xef1c9310 0xf60e82b7 + 0xe76e9bed 0xb8fa9668 0xf889765b 0x0e51eed6 + 0x6b6566ea 0xa8f7e2c5 0x9d8c283a 0x879afdcf + 0x944873c5 0x58afcfa2 0x2e60600e 0x59666667 + 0xc812b833 0x5842d0be 0xdbdc0829 0x786bcff9 + 0x5857ba06 0x6968c729 0xf5447949 0xdb1ceeb0 + 0xaf04d1f5 0x30614f7f 0x3e80fdc9 0x8a6e1ce0 + 0xa267d7d5 0x8896143e 0x24e59072 0x68122e1d + 0x3ce24add 0xda677bdc 0x8c3f74ef 0xfa60e825 + 0xf5c136cc 0x2cc5f249 0xa1c6b642 0x47a2305f + 0x52cadbc8 0x4d0c32f6 0x07f4d344 0x1f496d59 + 0x5699b970 0xb8cbe564 0x707f7a2e 0x818bfd45 + 0x800a8be0 0xd3de4f1f 0x62de0a3a 0x6b342869 + 0x054daa7c 0xc72b945f 0x1612f126 0xdb4ad492 + 0xa28c467b 0x78542799 0x61607353 0x39f1c142 + 0xebf30ad6 0xabe076d0 0x5125cce4 0x5584149c + 0x65fa33f4 0x878a918f 0x8c7e5c37 0x334c4284 + 0xbfd816e1 0x0f0f3460 0xd54519fd 0x03701ca9 + 0x64885229 0x00e841d0 0x756a9472 0x0c16c5f6 + 0x65560e81 0x129b6995 0x91c9dd1e 0xe9730dae + 0xce47f2a2 0xead8a0ee 0xcd58078f 0x7ca2df31 + 0x0ebbf13d 0x3c74e061 0xb7f3980a 0x0d354b88 + 0xfd8db90c 0xec6726d0 0x6bfce0f5 0xea98b7a0 + 0xac5ddde2 0xb372a14c 0x47b09ed5 0x531bd5c3 + 0xcfaf5a0a 0x51d6394f 0xe9efdfa8 0x37c79445 + 0xb13ebf62 0x46715efb 0x31e6a0d7 0xfa48ab48 + 0xc6552f2c 0x3067b978 0x0afa4ab7 0xc2c17055 + 0x68dd427d 0xeac01e43 0xe90f12d8 0x6d97c3b1 + 0xe0d339b0 0x2f3c84cd 0xca3eb3b1 0xbc0d86e1 + 0x3566f657 0x083374b0 0x199c677f 0xa4a8a4d3 + 0x224dd5a8 0x8f304abf 0xe1019878 0x9b290d4c + 0x5cef7341 0x59ff7e48 0xc91663ac 0xb0b1bede + 0xe9d8a9a5 0x8f34cb70 0x588d00d6 0xb7fe69b6 + 0x29036caa 0xd21d7998 0x4edc3ee9 0xdbd94f37 + 0x99c63455 0xac94efda 0x545635dc 0xb787b5e1 + 0x8228666b 0xc7cd8170 0x4f1924a5 0x437884c1 + 0xfa9236fb 0x1f0f949c 0xd1dc0597 0x56082a24 + 0x04e51919 0x05dd926f 0x06d264ac 0xaa672d38 + 0x5a3e396b 0xab48a57c 0x53489bd1 0xb36b3ba2 + 0x55164db6 0x5b52c5f9 0x68aa8b7f 0x922ce829 + 0x09e6e5bd 0xbc488a86 0xc0fb6dab 0x98e7754b + 0x4c9ad717 0xe3ae7045 0x0b498742 0x80a4384b + 0x0dfe0b99 0x70eab3b9 0xbee30b9f 0x4237ca85 + 0xe67662b1 0xdae3dce5 0x47c84a45 0xf72febf2 + 0xa58dfdc8 0x77ae88d4 0x038c76b7 0xae699990 + 0xf5f10de7 0x65d4c59a 0x004a8b4b 0x67c788ec + 0x71c918d7 0x0ec70171 0x7041de53 0x43591e1c + 0x807242f8 0xa27fe146 0x0055fc7e 0x2f08467e + 0x5e04a068 0x54dab094 0x4f6e8c7a 0x20ac2825 + 0x47949a42 0x9181486c 0x038e3132 0x7c1c51be + 0x97544f38 0xe2d27588 0x64889c21 0xdad9a1a9 + 0xf1d328a4 0x7d47991f 0x2faa1b85 0x2430cab0 + 0x0e849f91 0x213686c1 0xa2635f37 0xee7983ae + 0x87871273 0x6867d60f 0x04cb29ae 0x4e0ee4ee + 0xfbd2666a 0xfd7fe017 0x870b26ee 0xc42e104b + 0x78919117 0x19590e66 0x9e1a5039 0x9609471b + 0x4057fde6 0xc1f27544 0x30af8a8b 0x2ea267a6 + 0xcfd886b6 0xe632b1f3 0x3f10bc50 0xf38a1bd8 + 0x7ae1e284 0xe3876d7a 0xb4ce64f8 0xf74b4100 + 0xa97686da 0x17ebacde 0x2ab068e8 0xcebd1076 + 0xee8f81d8 0x0d394301 0x6f32c277 0xa926dc1c + 0xd5d2ea55 0xdc016b6b 0x6a96022f 0x0143e314 + 0x23836eed 0xa3e18369 0xd2a155bd 0x8022cef6 + 0x080b32a8 0x74ba38f0 0xd1ca2089 0x7c80219e + 0xf536af16 0xd7a337e3 0xa33600a6 0x39c7754d + 0x7d215312 0x1dd65026 0x8cb496c7 0x89dfd508 + 0x9f945a1c 0x45caec32 0x020a1edc 0x5917baa3 + 0x296b4b1a 0xcfaa2023 0x63e7a0e5 0xc48b19ae + 0x78d98b1e 0xc5d6be01 0xfe4ef13d 0xea6c9915 + 0xb8190f09 0xf1793822 0x9acf1593 0xc7710fa0 + 0x6b9a9f3d 0x0220ee2a 0x5d63043d 0x7292a0d5 + 0xba9a1682 0x6f1e7c19 0xed7cc52e 0x6bb89645 + 0x4370269c 0x9cb2c1a1 0xa7135973 0xfd1f3bbb + 0x50e6eb67 0xf2b9bd22 0xd891f6a7 0x4e0a7449 + 0xc3dc0005 0x878e3333 0x3b4b8686 0xb215c65c + 0x5d8d24c0 0x8d203496 0xff20d243 0x0a6c1253 + 0x2385c79f 0x52e8d6dc 0xda4bb8b7 0xfab66d97 + 0x05a4a795 0x6876e856 0x9dabedc2 0x53550c20 + 0xb3bba16e 0x853bf1cf 0xb85b906d 0x3f374468 + 0x62e07c2c 0x6903a495 0xdb119586 0x07e91546 + 0xa8388945 0x5a4e1dda 0xf054cdad 0x4b052880 + 0xe9bbc9ec 0xe3555e11 0xd4d6479a 0xcad6a986 + 0x31d9c4ae 0x510ff951 0xcb2f3164 0xbe283401 + 0x0c390b9e 0x0c9cb487 0xe64e8ffe 0x611a63c0 + 0xa1d700a5 0x3f864335 0xd1fdf32d 0x7a3aeb09 + 0xabbc8c4d 0x4d703604 0x6532c8e7 0xccebc529 + 0xf3c0f514 0x1567f19d 0x591abf6c 0x6c7fc459 + 0x0858b061 0x092b2489 0x33c1a9cd 0xd6cc8e2e + 0x7c1ffeb3 0x3f45cf40 0x1fbcbd39 0xc6f0e628 + 0xb88bab4d 0xc699de42 0xb62d850c 0xf71a6768 + 0x2866b891 0x13093fcc 0xc730c502 0x2deaeff4 + 0xb1bc8535 0x4303997b 0xb31ebd2f 0x82debe94 + 0x843fa02d 0xba29f80d 0x03cb58c1 0xef1d2017 + 0x0b5aadf0 0x6c5c3286 0xf084faeb 0x8b96a39b + 0x67cb38f8 0xf686ee62 0xbfdc22a1 0xee3f779c + 0x8ec73c8c 0xb448536d 0x67bb5d68 0x4369ea8d + 0x4b5367cd 0x2dbbc0be 0x8f5986e7 0x798c8392 + 0xd3aac078 0x0081c0bd 0x94d9d70b 0x40bdeae8 + 0x6b528e89 0xb0713745 0x063e535f 0x7d696463 + 0x64f0666b 0x68a82e8c 0xc749dd19 0x875883cc + 0x3d35728d 0x4c0e5d8d 0x135f11b3 0xb649b37f + 0x8aead5cb 0xdfbd573e 0x563bf917 0xcdb75f08 + 0x024b93fb 0xc6477eea 0xd88ce51d 0x95f7d77f + 0x0b561446 0x2fb6992c 0x4b48c8b1 0x940da60f + 0xf1be60b9 0x66d8641b 0x17a0ce15 0x49d22f40 + 0xb8c494da 0x91930bb1 0xcd317991 0x4c5b4c23 + 0xafda60eb 0x212c9f04 0xe4732f4e 0xf731ae57 + 0x19165943 0x2d9288c3 0xc9c45dd3 0x2e05b148 + 0x225a256a 0xc0249ea2 0xe96733d1 0x56a6803f + 0x20458549 0x28210fd6 0x13da740e 0xf0f0be41 + 0x029c1fa9 0xb1daf3f7 0x1bf0c9aa 0x6f0d5221 + 0x998b3616 0xa02212a3 0xe76b39b1 0xba0823e6 + 0x146da6a4 0x858a3e0e 0x58e75b32 0x732f75ed + 0x8d88385e 0xe0e7ed55 0xc08ca86d 0x97e2ef67 + 0xbb048208 0xd384c40b 0x8595bc69 0x65581977 + 0x7b091c4c 0x60bfbbb5 0x23bcf38f 0x32e4621a + 0x7f790d95 0x72c3267c 0x34dd0c12 0x27438915 + 0x5619893a 0x09d55159 0xdba7eef9 0x7413634f + 0xf4883417 0x59a2f28e 0x491f5779 0x0c138f9c + 0xc52a03de 0xcb1f92d0 0xb6cfcd21 0xbba95c83 + 0x5302f12d 0xfc4c030f 0x18722dde 0x131cd3b1 + 0xa19a1cdb 0x103d9216 0x403e45db 0x5cab72f3 + 0x17e18f5c 0xbad9d0d9 0xd0d2e010 0x798106fc + 0x3abace6c 0x2c3131c6 0xf9529b61 0x27cfa158 + 0x8890951f 0x87ccf0f3 0xa112b1e8 0x3e0eb033 + 0xd7469e14 0xb6ccd2ca 0x3d238069 0xb32f057e + 0x8d2c939b 0x18d8aa3d 0xdb3cdb2b 0x861ba258 + 0x46e7b170 0x4830d004 0xeea1b8b2 0x44e29b51 + 0x0cdd8591 0xf93ad973 0x9383c44d 0x24e323be + 0xaaac87a1 0x84eb09d7 0x1f66b641 0x303f92b4 + 0x81a63a86 0x516321e4 0xe33dfe2e 0x371a4624 + 0x8f936425 0x596976ca 0x7b1947ef 0x83a9db29 + 0xc5f337b0 0xe4d51b73 0xb35b56ce 0xb9cac5ba + 0x51705ecf 0x93e7d63f 0x5ee7d916 0x479f25b9 + 0xe90bb406 0xfcd6e78d 0xbd8ed9b7 0xbca7c8b7 + 0xdf95f4cb 0xc28baeba 0xb4534bbb 0x98b4f840 + 0xf2218357 0x726e4f81 0x7591ebc4 0xc0523d15 + 0x6bc82550 0xedfbcfa0 0x57280f50 0xbe7e420c + 0xd1152012 0xbf3ee0a2 0x11825710 0x18e728d1 + 0xb8af00b5 0x2d1e940d 0x1c9ade8f 0x923ed269 + 0xfd8c2580 0xf6477ff7 0x476a486e 0xd09c18dd + 0xaede7959 0x55fb68fc 0xe5692f7f 0x0bf4bd18 + 0xf5fede2b 0x07bb05e7 0x1bb8ec54 0xa46bba84 + 0x15051826 0x762ce6ae 0xa0246225 0x35c38cab + 0xbbd00a24 0x8205d3f4 0x4cb33ba4 0x293013fd + 0xd4f67965 0xe9c1951b 0xff108efa 0xb8e68197 + 0x36d51e4c 0x2959f7f9 0xf2e4206f 0xc9973e09 + 0xb61ce3fa 0x9543be90 0x63642668 0xcaaf02be + 0x7346a8eb 0x4111f5b5 0xa453cc2b 0xdb524b49 + 0x4d528cfa 0x71e5fc4d 0x62cbbab2 0x8423f40b + 0x1a4db908 0x560c41c2 0x03982d88 0xa49c553a + 0x529f6acc 0x82dae294 0x6c5dbaa4 0xfb4ae1f2 + 0x36e31345 0xb5cba88e 0x3704c623 0xe35245ea + 0xa412107c 0x35faf59c 0x08ceb649 0xbd67a6b9 + 0xe37ddfdf 0x21303abc 0xb7de5e8e 0x88d9366f + 0x49bdd73c 0xeca0cd02 0xfe1e01eb 0x30a56c2d + 0x0cae1f5b 0xe77521c7 0x5ca59eaf 0x1288aa13 + 0xc60bc96f 0xf7292504 0x2b037e4d 0xf34757b4 + 0xedcdc492 0x39044092 0x5d710fbb 0xb8658511 + 0xe23e4d57 0x595d4d3f 0xc0f80105 0xfe952879 + 0xe81e2cb6 0x4f5a8fed 0x3bd0d700 0x211887d3 + 0x6ea6e78a 0xe066640c 0x0d29c725 0xdabbeedd + 0xd2aca4d4 0x65c4a06a 0x6645b62f 0xb1de0cd7 + 0x022e07ea 0xe9f9248b 0x0a2251da 0xdf34159c + 0x7894bab3 0x72e465eb 0x37448fca 0xbfbc1911 + 0xa79e4938 0x48b83ec3 0xb9c6833f 0x19d24abb + 0xa434e777 0x77947277 0x2309612e 0x546a6ebb + 0x4c96447e 0xab918dce 0x5075ba1d 0x0aa55a7c + 0xadcce25b 0x837819d4 0x90d62a9d 0xf116ede5 + 0xb056cc7f 0xb036353e 0xb7c1af8d 0x014c2cd1 + 0x356f1593 0x008c2634 0xf7cd0cb0 0x02b0576c + 0x5364c954 0x5b40800b 0x60054bd7 0xef31bb60 + 0x1a85370a 0x458c4348 0x435b8da2 0xd8df0e06 + 0xde0cf1b8 0xd3c6171c 0x0bc14938 0xdc874128 + 0x694f96cc 0x7b6687e0 0x9ca59f25 0x617aea60 + 0x63ebcc8d 0x4bb44d00 0xce46d01c 0x4ab07a75 + 0x64757638 0xe5903811 0x3562895b 0x760627ce + 0x8939cc7f 0x225db9b1 0x730062d9 0x7a5a7a15 + 0x49678fc3 0x8620cb95 0x9439dee1 0x501f2cae + 0x3d08a33c 0x352de5c1 0xe7b24442 0x6ec76b79 + 0xc575a1e8 0xb7024b20 0xc9dbb9f0 0xfe2303c0 + 0xba3716ae 0x0cf37bdc 0x1c68a4a7 0x7ba0d609 + 0x43003a93 0x17dd96c3 0xb884aa37 0x15b2d65f + 0xf6016133 0xd1fd7e04 0xc0a22822 0xf8c26247 + 0x818c35fa 0x4e2b3605 0x83923c44 0x4ddd4397 + 0x6faf6a11 0x50438703 0x67796dac 0x3443b780 + 0x484f5bb9 0x8ead98ea 0x472ae543 0x94b0b17b + 0x1307833e 0xcb0e8286 0xb02e1ab1 0x36a89f9a + 0x372e82f0 0x84741303 0x111ad8ae 0xb1eeacb7 + 0xd7d8ccd6 0x5f779f32 0x0d65184c 0x0a398467 + 0xc07c099f 0x0704ffdc 0xa10b2f17 0x4c926dc9 + 0xd80829ee 0x0821015a 0x512e6d0e 0x57b514dd + 0x509cdfd6 0x7e08ef24 0xf536c381 0x65483797 + 0x439311fd 0xabed0f15 0x51a372c2 0xdd24c506 + 0x839cdd63 0x0c21c8dd 0x513d9eb4 0x43c6a95e + 0x5d543848 0x64843a49 0x687bbf41 0x93d3bce3 + 0xcf85eea3 0x5f3a6fc4 0xe7b45979 0x4c5848ce + 0x924188e3 0xbcbded12 0x0cc18c86 0xf3fd5723 + 0x148dddb6 0x77cb388f 0x30afd47c 0xa306c453 + 0x1da0b234 0x0f206f46 0xf25975bb 0x9c75d28f + 0xc60ad2fe 0x0067c5b0 0x497a1617 0x81d330e6 + 0x2c5362ef 0x86a54b1e 0x80ad976e 0x0a86ed37 + 0x1183b84e 0x2e2ce6e5 0x10b02598 0xd56fb0b7 + 0xe3e0bca5 0x755d2333 0xe0be1b85 0x6c976f4a + 0x555a1465 0x8ab38399 0x51d4a5c8 0xec3d86e1 + 0x2a85d0dd 0x0d31c16f 0x603f2d48 0x274d5d68 + 0x292e7df9 0xe444f292 0x329946f1 0x132c3230 + 0xb2c3ec05 0x88362f92 0x763dc2fa 0x7ee6f3ab + 0x7ca649e8 0xafee8a8b 0xeef65517 0x4789c1e3 + 0x85bd4cb3 0xc87762d3 0xfa528ba7 0xa8e20dde + 0xd369c227 0x97e7f300 0x8256f4ce 0xdd5d2901 + 0x1e37c55e 0xbb6e22fa 0xd9424392 0x8798d9a5 + 0xc118ddb2 0xc3c91c40 0xe68ead77 0x8cf3655b + 0x4381e8fc 0xc94f312a 0x0b372483 0x70b620df + 0x53820813 0xb50d6f0c 0x64a53e9e 0x6f7f19f3 + 0x6315f718 0x9aafff2e 0xf3b5a338 0xf1f3293c + 0x750ac26c 0xefe3ddf9 0xdc7369eb 0x024dafe0 + 0xf56354fe 0xf0afaf86 0x7da1df00 0x7447ffa2 + 0x4afd091f 0x24f39c82 0x3b3c8aa3 0xd90fc65d + 0x10d90b8a 0xf05d49fd 0x281320fe 0x75f62523 + 0x0537b558 0xf52ae61c 0x77961852 0xbd0db386 + 0xcb650cb6 0x7387ec69 0x320764c4 0xf5013b3f + 0x4f4239c8 0x4983a307 0xf510f405 0x7e355790 + 0x4f8480d2 0x50dd84ca 0x66947bed 0x56efdfe0 + 0xa593407d 0xdac216de 0x642a5f74 0x92bb9c2f + 0xf37abdd9 0xa24b1b64 0xca1f722c 0xaa5de969 + 0xb6cb128a 0x697f787b 0x5bd74fb3 0x6de74e39 + 0x2bc9a4aa 0x634455ab 0xa82aecc4 0x69647f0d + 0x4be06592 0x0c220c92 0xb08adf1f 0xd4571d2a + 0x0fadece6 0x297c124f 0x2830a499 0x3cc8363f + 0x44e34d3a 0x27b4d820 0x98be7f08 0x43417964 + 0x8a3af8ac 0x89c42336 0xe55d19dd 0x00ee1f6e + 0x47d48658 0x55986f58 0x11ccb046 0xf3b97a07 + 0x7ed364a3 0x106cfcd0 0xc1533857 0x3add2c15 + 0x143852c7 0x55b38512 0x49a85ce8 0xd61a285d + 0x513bd0b9 0x21bde48e 0x4f231482 0x93aa6dde + 0x88035659 0xa83e3d2b 0x542513f8 0xe6e74a1c + 0x06092343 0xd37c8770 0x41553ead 0x09980a79 + 0xb0e45895 0x80db4662 0xa6ce0960 0x965cfa7e + 0xfea96644 0x2a79157e 0xf020e115 0x61823e96 + 0xf14f63d7 0xd753d1bd 0xd24a060d 0xfd2691b9 + 0x18da9d0e 0x9f3c93c4 0x2730e0f2 0xb47e2afa + 0x920fda38 0xb5d89646 0xfb4728e5 0x7e78c2cb + 0xe46f812c 0xe51cc5c0 0x9d2957fc 0x548798a1 + 0x240c2103 0xd650ff70 0x15c49ff6 0x99587c0a + 0x1bb4a5ca 0xd6db66e7 0xec2d3ac5 0x54164690 + 0xe61bd6f8 0xc7a45cf8 0xee25f4f4 0xd1eb3ae7 + 0x90085a1b 0x46a7a74b 0x829717f2 0x7f0769cd + 0x3ef72792 0x0c8617a7 0xa86becad 0x9dfe5329 + 0x1a33c5a6 0x47d4c75b 0x2e10b45f 0xbd11762e + 0x15b72a9b 0x015c7f84 0x379c6bd2 0x27525345 + 0xff3ac5a6 0xac916082 0xf5c24317 0xcc43fc64 + 0x7f092c8d 0x931d9a0c 0x5a07f13e 0x3e1aa46b + 0x717a343f 0xd51221c4 0xc9422fcd 0x63f7af00 + 0xde81a497 0x0322d271 0x972a4065 0xd75df029 + 0x343a94a0 0x8c225f7d 0xb4abe87e 0x3cb8ba1b + 0x0babab14 0xf29704e7 0xd7134233 0x391f1a35 + 0x33aca565 0xe6ae586b 0x0470a42c 0x570efddf + 0xfea26a3b 0xcee8d934 0x99ece522 0xb8af1375 + 0xfe4dea4b 0xb96a32c2 0x3469ef9c 0x029fade7 + 0xc4e77d55 0xc0449b95 0x63336e95 0x8d46c2e0 + 0xd86d6e23 0xd365b781 0xe73ba0fe 0x10a354c5 + 0x2d4511a0 0x077206cf 0x1c0dbd55 0x03396771 + 0x8bce27af 0x70355b4b 0xc2275e58 0x3cfa4df5 + 0xc8b3b9b8 0xf3fd510f 0x6b055de5 0xb3fef295 + 0x42b95a20 0x5b5e75e7 0x0aaaa734 0x636d50ae + 0x8329283e 0x446e76f3 0x6adc320d 0x69a3e9df + 0x1da68939 0x6f071783 0x498dfee5 0xaece51ed + 0x4f8a72a8 0x4f2f2f65 0xdac3ba47 0xcbab0287 + 0xf966cb4d 0xba27861f 0x54c79a21 0x44e2359a + 0x6e6b0e7f 0xceae84fb 0xb1530a59 0xecb8cd96 + 0xff60633e 0xed748fe3 0xf1ab0d95 0x59997216 + 0x6894cf41 0x948fc7bc 0xfb162ae5 0xeb9951a1 + 0x99d0a7a3 0x9234587f 0xcd42615b 0x6f9ad0e8 + 0xeb936dbe 0xbe72b62c 0x44ab5e9f 0xed736b08 + 0xffaedca9 0x103b89bb 0x7896b40e 0x13a5a924 + 0x56786357 0x02ab80ec 0x72ef47fd 0x81bf0fd7 + 0x6661b300 0xaefadc79 0x9968433a 0x16f3718b + 0xe997a663 0xbbb55a49 0xf9b9a710 0x5727271f + 0x20e9bf55 0x358e3986 0xd1214e1f 0x4d42c46f + 0xa6bf8194 0x0c14a853 0x7b51aeb0 0x2f3d4de4 + 0x3d6ffef6 0x4e94ba19 0x71a9c861 0xcade2398 + 0xe0b3eb18 0xc9f028b0 0x7d29d2d0 0x372ec60a + 0x288a5bfd 0x4fc2bab3 0xc01dd045 0x8222e147 + 0xe06676de 0x750bbfea 0x586ffb3d 0x2addb655 + 0x767a6528 0x78abceec 0x1646cb38 0x21e26890 + 0xd2a7937b 0x2463457c 0x764103fb 0xd540867f + 0x3566875f 0x007449ba 0xf9c0c523 0x2c51c86c + 0x437e1196 0x69fc0059 0xe0103408 0x19f23997 + 0x23fdf335 0x7262eef4 0xcbe09390 0x583d0099 + 0xe862084d 0x19fffbab 0xd2958a5a 0xcb165416 + 0x32f3a97c 0xe502303a 0x16c4eda5 0xa1bcfd1d + 0xc4f35053 0xfd037f66 0xdeac9fee 0xbfb167b1 + 0x39804db6 0x0bc2011d 0xf56bcd68 0x368cb345 + 0x52fcb352 0xc306c535 0xf6bff09c 0xa429cbf7 + 0x7e504be4 0xd2240214 0xf09ee41f 0xcbcf1fe4 + 0x70f96a85 0x8394bf28 0x3cc19a50 0x49581f96 + 0x58da5ae0 0x94708c48 0x63febeaa 0x4f656940 + 0xa7fd6879 0x65524f66 0x5f7ee0df 0x11d487f9 + 0xb494641e 0x7eb57255 0x5aa208c0 0x5666243a + 0x7d5970b5 0x71ea69a1 0x67059c9d 0xd3bde5bc + 0xe952b3fe 0x27bbf258 0x197504f4 0x5da6649d + 0xecddf4de 0x2d040d3d 0xbc9d3ab6 0xd8cdfb81 + 0xb36ab627 0x7a548111 0xaaeefa4c 0x0e55b263 + 0x4f9da6e6 0x26a137dd 0xdea03395 0x23b87267 + 0x5b3cc98a 0x206de858 0x8d2e5cd2 0xb60f14e6 + 0xfc10356f 0xeecae1d5 0x39783cbe 0x1a1c9a70 + 0xb52c6f05 0x64adf10b 0xe12d9f3b 0xb3fb7cf1 + 0x9051fdea 0xc16ed3bc 0x697199b0 0x08f34342 + 0x2fb2bab6 0x729ed2b8 0x7691088b 0x82bc9cc1 + 0xafce7ac3 0xe167bbb9 0x362e5d43 0x945510ec + 0xf32dce5e 0x4aec9a82 0xb80520d3 0xd8fcbe40 + 0xf4877350 0xcfdd487e 0x8c9ff8b5 0x84ce70df + 0xffa6abd3 0xf9d2f273 0x342dbff8 0xa72580e3 + 0x6ffccdc3 0x0c7ccc0f 0x6b24afd4 0x82b71a25 + 0x1ba361f2 0x6ed8a67d 0x243ce000 0xd16b2e19 + 0x86d3c3e6 0xca209063 0xaff0b983 0xf411f71f + 0x0f2ca724 0xa6fb0fb6 0xfa663640 0xe40fe20e + 0xf8e2a5cc 0x1a0e8862 0x11de13a4 0xc811e4a7 + 0xfe6fa8e6 0xfefce644 0x8f7fcde9 0x94477c62 + 0xec9b942f 0xfda6b166 0x91330c4d 0xd059d679 + 0x96b0f7a1 0x22df13ce 0x3f36c3e9 0xc814e342 + 0x7b7dce7c 0x1000640a 0x8cbe7a56 0x622fa655 + 0x209d82d7 0x55668514 0x1534f8af 0xc2b7dc1f + 0xd89da0dc 0x3ddfe751 0x0532dfe4 0xd39c360c + 0x090f91d6 0x48587117 0x8ee383fe 0xf5ffdee4 + 0xd8bca448 0xd26d6d82 0xe8adcc12 0x8b14b8c1 + 0x7f872f36 0xb8cb0e16 0x76d60c06 0xf62ddbec + 0x3ec7c151 0xe418a789 0x920a3bf8 0xc5b62e09 + 0x4974ea7e 0x0d8d7962 0x5bbb246a 0x37183d1c + 0xf25c63dd 0xb15730a5 0x903e3400 0xdab426eb + 0x0323289f 0x9bc16f49 0x2dfd02a1 0x3ab916a1 + 0xcb6f770a 0x342021b2 0xf9f5c9c0 0x9c8d53a5 + 0x3d53f39b 0x8e693c58 0xebecc732 0xbf30c538 + 0x96648d11 0x60f62751 0x29745559 0x8e365fb3 + 0x7d0b1179 0xea5abbb2 0xe45c4af0 0x53056b1d + 0xac7b03dd 0x7015c355 0xf17f8dfd 0xe1ace271 + 0x9abacdc0 0x5ccedc75 0x478c717d 0xc01dfdad + 0x26fb551f 0x73e61f00 0x8bc0b111 0xb6855743 + 0x28690dc2 0xf13b6766 0xc098861c 0x5c0ffa55 + 0x271e7d0c 0x66b47b80 0x9921a158 0xd9c560d0 + 0xb29b6ee7 0x50a9bc97 0xbec4d91e 0xdb2c1fcc + 0xdf215786 0x1541e380 0x59cae516 0x2342b2ee + 0x8088cd9b 0x7312579d 0xb17be14a 0xa1638c41 + 0x805c6b18 0xb8a56151 0x56f0a6da 0x96b114d2 + 0x0845ea7c 0x23e8f7eb 0x4e88e7ce 0x84640f2c + 0xacf8eebe 0x4039725a 0x49bf9982 0xfbcfcbd9 + 0xfbbfb1c1 0x8041659b 0x5b8ee4f3 0x1b6d7a38 + 0xeb634fc4 0xbf818ab6 0x8076c921 0xc50be762 + 0x24c43f4b 0x3252acca 0xa7528630 0x9885b151 + 0x9154b37f 0xfd9d3ab1 0x4f93c117 0x578fba44 + 0xa56851fc 0x9d8083de 0x769f6fb4 0xd89fec27 + 0x747c8071 0xe6b2b747 0x8196e2a8 0x3ed6c699 + 0x8716f1df 0x65325e96 0xfbc715d5 0xb06f9171 + 0x7aa9cbdd 0x84bda56b 0xdeab06ee 0x80432d8b + 0xd76f0a57 0xe0ed5f9a 0x70f991a2 0xf1a9e557 + 0xcbecbcdd 0xcf0d91fc 0x6751fd67 0x590f206a + 0xa26d8130 0x1df02179 0x826303ce 0x6cd58190 + 0x1219d005 0x4bb2f3b2 0x0dbd8193 0xd8d8f582 + 0xa5867eed 0x2d6b8ec9 0x5f85ec18 0x7983775a + 0x214ca0c1 0x9af3febb 0x213d6568 0x2f8e8c43 + 0x92add018 0x6e33e00f 0x6fa6834f 0xc3c2cbbc + 0x1c65c8c5 0x1827f812 0x868d3a09 0xdac83ade + 0x57623da5 0x5ff83257 0x0992e621 0x25cc9ca9 + 0x10580130 0xff2ae8fe 0x40a58253 0xffdc24d5 + 0x3e4dbe68 0x291b11f7 0xb3594b9a 0x570c7b6d + 0x38d31bd4 0x7155ba24 0x84d56490 0xd98842d5 + 0xe037d2f6 0xdd2ba821 0xbeb861d5 0x0fda5758 + 0x5921c665 0x98c7676d 0x8eee487b 0xac0f2411 + 0xb332d321 0xa0816c65 0x76edde5c 0xab868b36 + 0x3f8da4fd 0x516af4e7 0xabf748a8 0xbe7820fc + 0xbf763827 0xa03a3566 0x8a63e804 0xb4f8f901 + 0x5d262ee9 0xaf905cf5 0x896d0c94 0x5f992cab + 0x81c2faf9 0xda3c686a 0xb01a06dc 0x45ef0c90 + 0xf2ca525f 0x0e74fe18 0x36ecdb11 0x494125d2 + 0x226b4aab 0x3e92ae29 0x5bb48774 0xc2c2ef90 + 0xa9e77d5a 0x409db546 0x7728f003 0x72229503 + 0x2e8febab 0x8322cfbc 0x5eaf74e9 0x621837f8 + 0xc70668d1 0xb25c1325 0xd741c010 0xf52e3166 + 0x71ef7a87 0x74cc93a4 0x7c25ecf4 0xb8b8e20f + 0x3658c239 0xbc58fba7 0xf13ec858 0x9271b2a1 + 0x37084dd5 0x6fc92e82 0x44a6abe6 0x92b9238a + 0x9ad3a57e 0xd75daf92 0x8ea573d6 0x69ce1fb6 + 0xe80df5f2 0xcc1c6ae7 0x6d565a77 0x6981ae63 + 0x18af1922 0x6e8a7af8 0x10716aa0 0xa7da9970 + 0x1abbc7cd 0x114f814a 0x4ebb0c07 0xc8fe6a69 + 0x93d7bc2e 0x0a16181c 0x0379c950 0x4b2e8c18 + 0x670b83f8 0x82a75eda 0x6eb772dd 0x42cfe197 + 0xd91ec29c 0x29fb4812 0xab693ead 0xb2f25a1c + 0x0b9df6cf 0xb7a1aba2 0x1d7d90bf 0x7de14655 + 0x649965f6 0x11fbe065 0xa54ac5a3 0x418bd3df + 0x4223c00f 0x7bfcf9ae 0xbd979739 0x6a2ee697 + 0x54e7d9c8 0x73803bdb 0x06654716 0x72225136 + 0xfaef3873 0x0b4b40dd 0xd3b98b57 0xc56cbab5 + 0x32174c47 0x4d4d8c32 0xd6f1bf93 0xeefb6950 + 0xb84ed0da 0x590723d4 0x2d006f09 0xc4bc139c + 0x55434982 0x8734189f 0x0e314a50 0x94340d09 + 0x021c24a4 0x0b0f022d 0xa61f9025 0x71eb72b6 + 0x744ccea1 0x2030b859 0x78203d74 0x0b8a8389 + 0xd5211777 0x2609edfc 0x6134eede 0xec74584f + 0x0bdb2d06 0xb1768f76 0x56221895 0xfc49bdae + 0xbcc6e6ed 0xfeb19c0c 0x18652996 0xaa1a0164 + 0x3ffdcb94 0x2dc1b090 0xb68bf220 0xc33b967d + 0xc907a1aa 0xa3968cb1 0xb3cc65e5 0x33e2b077 + 0x2bb22904 0xe0fe8fc2 0x4affcc46 0x6b0f0bbc + 0x5d1bef41 0x2de11c7f 0xb0d864ee 0x6e96d8dd + 0x59c1c108 0xb2544572 0xab3400af 0x604aefcd + 0x81be22c3 0x6741e6ca 0x3a93dc1c 0x7b10e639 + 0x0add7a92 0x39fc1df3 0x884f150b 0xd666a96d + 0x87da0c1a 0xf0f73c15 0xc0c00957 0x011ba61d + 0xa77e9463 0x96020e4e 0x92416e99 0x881e89c4 + 0x46981327 0x3bc624f4 0x57f226f5 0xac340cd8 + 0x3ce239b2 0xec6b33bc 0xa9123e11 0x70640b6b + 0xc30f59f0 0x411576fe 0x5ab12c3b 0x3cc20b85 + 0x924b3be2 0xd1fc7a28 0xa4b0cf7a 0x88098404 + 0xbbd331e3 0xff2b6047 0x2a1ab042 0xdf220849 + 0xaf774ae3 0x5a8da79d 0xf18450c8 0x8e6e235f + 0x1dd3c039 0x1a867ae2 0xe4ccd1f4 0x50dd3f39 + 0x8be186ba 0xc7e30fe2 0x17552d4d 0xffac16e4 + 0x4094bbc4 0xc18a2513 0x650e707f 0x8ecdbba2 + 0xf53e8e7d 0x047dbce2 0x7fc2a89f 0x07628f94 + 0x2a8bfc67 0x0d738727 0x7b5c2fd4 0x2c89d27f + 0x47f37a64 0xc63debc9 0x15d6c414 0x242c300a + 0x645d95ab 0x29e1a49d 0xaf77fab1 0x643b4cd5 + 0x3e0f63db 0x4f7cc43a 0x33d6797b 0x497d4332 + 0x7160786f 0xe0c5b75d 0xfb08ecb2 0x26063065 + 0x9835bf7c 0xf5465591 0x63155d2d 0x14babba1 + 0x384a0879 0x460db3b1 0xcd37760b 0xad675a77 + 0xf1dceded 0x69df690a 0x44c6f456 0x87d6a7a4 + 0x4e0d6504 0xf967f55f 0xca9bb20d 0xd5eb41f6 + 0xa9aa9b2a 0xa907387b 0x965b6f23 0xdcd47eb5 + 0x43b5b1a0 0xec876728 0xee7339e8 0x10c5ee16 + 0x1bd8c0bb 0x7235ae07 0x063e3564 0x388d0bb5 + 0x80f9a9f6 0xaf96f714 0x6895c899 0x00ad21bd + 0xee67961b 0x873781a9 0x22cf435a 0xee90cf3e + 0xc9a4fadd 0x9bc1af4c 0x35c0e803 0x211ce71a + 0xb9af86bb 0x97828ab5 0x9dbd002a 0x1cc981c7 + 0xefb36876 0xea739a75 0x5d5abcc1 0xd42260f2 + 0x95083e0a 0x31fb0b51 0xf243ab8f 0x628b1913 + 0xe74eb210 0x620b7d9f 0xc81666d2 0xc8fd1ce1 + 0xf054bd9e 0x78ba7618 0xe1df4e38 0x5e381b3a + 0xcc68da1b 0xb3ce70ac 0x7ecda229 0xf8778140 + 0xae823fa1 0x12af1708 0xc9373879 0x1e687d29 + 0x96062069 0xf1bfde2b 0x999ff6c0 0x8cbeddf0 + 0xc825a2bb 0x78106bbb 0x87a964fc 0xb358ec2f + 0x4d959300 0x0fe9706a 0xabb1d003 0x72b65294 + 0x43816b1f 0x6c83b958 0x5549567c 0xb474aa55 + 0x98851640 0x751a670f 0x25900026 0x2ab174e3 + 0x1952c3dd 0x38b47c29 0x32c0af52 0x460c8fad + 0x85a1004e 0x8cbddcd7 0x66578310 0x4904dcfb + 0x04b7a746 0x00c91fb7 0xb1ab2edb 0xd0178ae2 + 0xc4b8b57e 0x981d4753 0xfdd8939a 0xa8a05055 + 0x47c8c30e 0x0fab4f6b 0x6ea54079 0x23dc4151 + 0xc23e83aa 0x2ed2ce8a 0xff95b763 0x08df1d51 + 0xd16d104e 0x0fa3ee3b 0xdcfe8541 0xa0622490 + 0x085e5c0f 0xd9bc007b 0x24794e89 0xce341d16 + 0xf090a98c 0x317150a2 0xcc036257 0x3296722d + 0x9c8d4f58 0x7ca5f53b 0xb0e4f9d4 0x1f178bbe + 0xc0dcde7c 0x18551596 0x0507b8e2 0x3c40a8ca + 0xc632f82b 0x5d1965f9 0x92a00465 0x13a8ca32 + 0xc0b6756f 0x669d706c 0x58056b22 0xaa25fd37 + 0x128b731c 0xb141ed31 0x0a8d3ddf 0x48b63bd1 + 0xd24c5c4e 0x0ccd96b8 0x4b1ff726 0x309be62b + 0x26002e68 0x436f2bd0 0xacb62068 0xce098f50 + 0x330e6160 0x434da66d 0xce14054a 0x0a877e41 + 0x705eb2fb 0x8433fc7e 0xc1bd475b 0xb550de6d + 0xf4faf808 0x9f9b6ebe 0x0ff98ef7 0xace2766f + 0x01cc9606 0xd9654327 0x3544cf5b 0xbffbcd80 + 0xb4a5948f 0xcded4d04 0x69ef5a24 0xf5ae46de + 0xe2139499 0x549f82bf 0x2cdfc6b7 0x5fdd2462 + 0x63c68a37 0x8bce0d04 0x9c66ae30 0x9fd94951 + 0x5774366d 0xd671675a 0x5582f253 0x436c5b6b + 0xfc151e77 0x1974df45 0x5ea9eac2 0x30689b8a + 0x9806681a 0xb74d3ec8 0x4f207181 0x668b4951 + 0xb06514b2 0xeccffed1 0x16188ff2 0x5914d385 + 0xed4b7023 0xfb0640e8 0x179adcda 0x6e806687 + 0xb4f0ac07 0x35813615 0x143e66b4 0x1b012a50 + 0x384f31c5 0x1500dbca 0x06e47afe 0xa8a17374 + 0x9d0f5c57 0x4574db82 0x91b3680e 0x794683a7 + 0x30c25d5d 0xf8748c08 0x2e601dfc 0x553152f7 + 0xec5d489a 0x4bd37616 0xdc04dc7b 0xf0a35ba2 + 0xb36975db 0xbfe6f98a 0x6d744996 0x5507380b + 0x4191e01a 0x0092c384 0xcf3a4388 0x6b0e89c7 + 0xded7b820 0x1fbd6bba 0x3af210b1 0xfc4a608e + 0xa920eb22 0x22db2d65 0x7d6f0447 0x090f3679 + 0xc4c759cd 0x9758aac6 0xa63251a9 0x47b7a974 + 0x65421071 0xdca8495e 0x96f879d7 0x1d22ea6f + 0x46dd72ba 0xe0c59ccc 0x15737309 0x6d945f11 + 0xbcb15c8a 0xb11ef0b9 0xe2072633 0xccbd61dc + 0xfcb51c44 0xd2315c65 0x3087a6f8 0x5609ee34 + 0x94c7f951 0x0a057b31 0x6e6f2733 0x179facec + 0x36c005b9 0x60184919 0x50b3db1f 0x7a827d7f + 0x88755ecc 0x3fb0d6c3 0x63b150d4 0xe2ec3004 + 0xe0ee30f1 0x118d7040 0x2f4689e7 0xa78be0be + 0x3c9bb853 0x75c326cc 0x84097407 0xb0107b5e + 0x83a56a91 0x14e60445 0x0fa72553 0x1385e6ce + 0x9b8bbdcd 0xe6aa6a9b 0xc2072ccc 0xee916592 + 0xe44082e1 0x43dbf6d8 0x09f821fc 0xdc84b023 + 0x0e6a518b 0x945fb180 0x185d0841 0x9ece88f8 + 0x844558c2 0xed85f422 0xeceb983c 0x6db16826 + 0x7612b243 0xee3bf226 0xb8eebb7b 0x22e16615 + 0xc892bb7a 0xdc475a47 0xae390e93 0xe00baa1b + 0x725fca23 0xbb868b3a 0x17c62a69 0xeccd3731 + 0xbe1a4223 0x05c8fd7e 0xa8354afa 0xbbb09f8c + 0x31a77e83 0x01f17a68 0x5f37c847 0xa0fdd7db + 0x9f8da870 0x98f02167 0x1e966884 0x00e19b81 + 0x50c91add 0x6aba2a55 0x60be9575 0x3da40b37 + 0xde13ff4d 0x5b7a79ec 0x4700ffd9 0xfee5ea61 + 0xaf4d1d1e 0xfccb6f04 0xcf5076d2 0x48c4c98a + 0xd6a8915e 0xe4a58522 0x6bf3a6a9 0x4e7c2f15 + 0xcd7e8d2f 0x843b56b1 0xa35f1a5d 0x1ca226dc + 0x917fb163 0x44751f0a 0xd96fa8aa 0x5028dccc + 0x7792dd96 0x2a9d749d 0xe48385fb 0xde111e91 + 0x805e6581 0x3d9b9fad 0x5b750544 0x03785b71 + 0x9b583214 0x80022658 0xcf1f3730 0xa1be7be7 + 0x6c1e26f2 0x26de584b 0xb4fc8e35 0x072b520b + 0x55db3ac9 0x81e9d490 0x4b5ea53e 0xd5628e00 + 0x71bfcac3 0x79956bbf 0x275fab80 0x2ad497ed + 0x423854b2 0x686451ad 0xfd59d64e 0x9f2049d7 + 0xcb0f8f32 0x74d7545d 0x4f9c1df8 0x6fbf0afa + 0x7ef06915 0xc5117549 0xf20088b4 0x731a5ccf + 0xe78bbe74 0xdcb4996e 0x7062a6f1 0xa624b59a + 0x7b2d5e41 0xc1065234 0xa7c32078 0x367e7134 + 0x86f55f58 0x3084ee83 0x0c599d1f 0x69380e2e + 0xe59482b3 0x7096432e 0x81124388 0x5be8d01e + 0xeb25ec24 0x8b47e9ad 0x432216fd 0xdc496dea + 0xcb05fefe 0xe76eb9ab 0x8ed568d2 0xfa963d68 + 0x70ed6f4e 0xb2b88d58 0x15fc42bb 0xe992ec48 + 0x359856b3 0x4a0f7741 0x3f0b6eca 0x07c16950 + 0xcb9dae59 0x209570c2 0xf196555d 0xbf7c0a0f + 0x4a814210 0xf8f206c7 0x8bbb0763 0x360fa596 + 0x13d46195 0x901170e8 0x6dc2e376 0xbfa00989 + 0xd12cab90 0xf4f4699d 0xbc88b362 0x4827dbd5 + 0x7cde5cf5 0xe45dff5e 0x2d661b05 0x8902d99e + 0x6c9f3584 0x0db3f864 0x1132773f 0x3e944120 + 0x27058ae1 0xef978864 0xe58eff42 0x020ae503 + 0x77fe075b 0x9c577e08 0x210b42b9 0xcb8160c0 + 0x09f99f36 0x6a0b6bee 0x6f18b0ef 0x5452ee3f + 0x6c8c4a4d 0x480cb803 0x892f3973 0x066dbb63 + 0xf7f845c8 0x7ceeee7e 0x7c26c5ce 0xec89119a + 0xc64bdc20 0xf46e4324 0xff34c833 0x555b4b3c + 0x23ff2701 0x52360759 0xf60acad8 0x241ccb7b + 0x29e14901 0xcc068e2b 0xedd0ee02 0xc33a425d + 0x7d889b28 0x88577f8d 0xaaf614b1 0x8e8c8eb5 + 0x81a363f8 0x29f5bcc6 0x08aeb8e9 0x6f9ee222 + 0x1c50045b 0x792c9434 0x62bc2601 0xc9289175 + 0x374fc38c 0xbae91a86 0x3268e89b 0x5b008f10 + 0x0ea6b759 0x9d43ce10 0x09b30dd2 0x643e2b94 + 0x5c19bafb 0x29515176 0x56a81f95 0x60a80534 + 0x22fa0a73 0x1259cf8d 0x323fa5b3 0x6322f1d0 + 0x30581c47 0x50458048 0xd711c1b6 0x4a34236e + 0xb60a2e40 0x58df96c9 0x947b90d7 0xd327d664 + 0x5fe528db 0xf6d9c575 0xb0a251b9 0xed961301 + 0x2fee3cf9 0xb687e226 0x78fc46c2 0x29e9fef4 + 0x84bff086 0xd0482ed1 0x018996f1 0xb8b9cdf8 + 0x20885e68 0xa6f848e2 0xfddabc3e 0x5c9a7f67 + 0x7cbc3e40 0x5197ebe2 0x41a15775 0x8024fd2a + 0x7864106f 0x7cfaf482 0x27798720 0x4956355f + 0x30f7195e 0x6ea09dd6 0x6f2b5f3c 0xf38df38e + 0xcae7e8cb 0xf8a80b0b 0xbeb227ba 0xbbfa2428 + 0xbbba3ab6 0xbf83edbc 0x2cdcaa9b 0x2b0841a7 + 0x79d52e5e 0x40260460 0xb27709be 0x07e3bf6a + 0xbdccc2b9 0x369d0069 0x9d745e50 0xff251486 + 0x1e14957f 0xf7253467 0x9a31eeb9 0x4d77108a + 0x44fefc47 0xd02d4082 0x232e3fc1 0xce39396b + 0xd7a13714 0x2bd57e7e 0x00876803 0xee73377e + 0x78bb6240 0x2ae63c46 0x11e009d2 0x922539cd + 0xf3bef05a 0xf0c664c3 0x6e132a0b 0xb0c5bddd + 0x40c66494 0xd7d0d02a 0xa73110d0 0x4b409d78 + 0x6f49bf88 0xcfc9d22e 0x4836da89 0xde5a80be + 0xb9c8bdb3 0xe99b2e9d 0xf1b05e68 0x8ab599fc + 0x22675035 0x3c8480c0 0xfa3cd457 0xba617098 + 0x422eca1c 0x0cdc0d01 0x4779b95e 0xccfa0bfa + 0xd22674a4 0x76462be6 0x3015ab3b 0x7891688e + 0x1c83bf8b 0xaa55839a 0x7a71a83f 0xad451c1b + 0xf8b8bf06 0xc75a91be 0xcac50366 0x87e365ae + 0x9013ac11 0xe9cec5a5 0xef4d88f5 0x15c27162 + 0x3dcaf8ae 0xe023891b 0x7b6f1706 0x2f1198e4 + 0x048e34ba 0xb647b5e8 0xa1826caa 0xed3bc134 + 0x43b14d28 0xf0c49b54 0x1a6362d4 0xc77fa378 + 0x3bb12e79 0xcba4cd2b 0x620f2476 0x7729add6 + 0x9876c439 0x5f7d8795 0x858f7ac8 0x68b94589 + 0x1321d70b 0x5353a2fc 0x912a5ea4 0x390cf0f5 + 0x37320473 0x51b3cacf 0xe45046d2 0x9188dcc5 + 0xb3713b54 0xc9b936e3 0xe9f24574 0x5977a68c + 0xc23c56bd 0xcfc39ca9 0xc891b8d0 0x3683ef22 + 0xc1ce304a 0x3ebf1ce1 0x52cd1cc0 0x3777d973 + 0xde614072 0xf2efe226 0xbe1f9f9b 0x92a1896b + 0x9ca62763 0xcf5703be 0xa6d9c56a 0x185260d6 + 0xd9e3b86f 0x5c47180b 0x71a7a219 0xe9974375 + 0xf22af4d3 0xfbc92962 0x968c3fe4 0xc584b60e + 0xb9abee26 0x7e9737d8 0x5947da83 0x2f8ccad0 + 0x7b4ee942 0x51ad62dc 0xf517400c 0xe2bf9e37 + 0x63057e05 0xe1bfabf8 0xbf118805 0xc038de9c + 0x7aa57b7b 0x05584eff 0xb15ea286 0x26c6a6c0 + 0x8e1392e8 0x7dbf22e1 0x3546f5bd 0x0f84ed9b + 0x0b01da4d 0x6dc47417 0xadc6f687 0x4160c045 + 0xdc26765f 0x63b70c6e 0x8f177107 0x6a5f13cd + 0xb56fce56 0x5d1f5ed1 0x62f6a18e 0xf7235691 + 0x222fa999 0xd48b1435 0xe597d406 0x8dacf828 + 0x694ecd8c 0xe5283c02 0x60bcdcd3 0xfb9eb384 + 0x9895492c 0xd38172dd 0xe7b6dff6 0x0ead5894 + 0x910e2675 0x97d9ee09 0x270b2d8a 0xd03e25e0 + 0x9e7bbb69 0x57ab1d31 0xf2e7a13d 0x9c8e5baf + 0x65fa03f4 0xc66bcbfc 0xf2d8bfe1 0x23059412 + 0xa3ae7654 0x3a4734a3 0x32c0a8d3 0x4e007b8a + 0x5ce30660 0xbd10c57c 0x5365f540 0xeaed3002 + 0xc377d84d 0x87097a59 0x929edec9 0x5878368b + 0xbd450478 0xc3fab275 0x128fdced 0xb706fbb5 + 0x146f1d41 0x86782651 0xa530ca29 0xa3e1b6be + 0x25390048 0x572b4a05 0x8c9b4c90 0xb05428cd + 0x33fabab5 0xd16e513e 0x1d6cc812 0x4d80a6ed + 0xd6a5a07e 0xc0ee4c19 0x544b75d1 0x3f887360 + 0xb2f46d1d 0x21609cbd 0xe340211d 0xe9202fb6 + 0x3023b005 0x3341ead9 0x76c99537 0xc9d76547 + 0xfb736c3f 0xf6385346 0x93fe2a05 0x92de6df5 + 0x7793acd1 0x68249b3e 0xc22cae3b 0x668988e0 + 0xdc1ea28c 0x7ef72b95 0x974098f9 0xb214701c + 0xc2de7d98 0xeb1d443e 0x5975f0ec 0x21d67037 + 0x721e8e99 0x42105562 0x74b1e821 0x20193b2c + 0x743a7bb3 0x24643c9c 0x240b331c 0xdf125e2e + 0xcb4b0205 0x19edb174 0x505eb85c 0x1830bf22 + 0x6bf7a528 0x86a7281d 0xfee3488d 0x6c26f4ab + 0xbff4ce7a 0xff7cfaf1 0x5df6fd66 0x523f0802 + 0xf8a87595 0x463b5c19 0x72c564fd 0x2e4797d6 + 0x1f04a1af 0x0be96baf 0x44552094 0x2a158f50 + 0x83dac587 0xad4c881d 0x3178e710 0xe938d1be + 0xab715a65 0xc34b451e 0x1942832e 0x91557ecb + 0xdaf0606d 0xa64623d9 0x84e11fbb 0xa9c9d11b + 0x577a15b1 0xd49a2f23 0x6f204e0b 0x0a6e6a2f + 0xdaf13637 0x6b4ef557 0xdcaac9a3 0xad97c404 + 0x8471691a 0x50ca3cf5 0xde57c446 0x70aa02f1 + 0x84baa6de 0x0232bc79 0xa06427af 0xd2ce56be + 0x5da13949 0x254f5f4c 0x3fc3fd02 0x00b5f8eb + 0x54a0d4b8 0x5e3ec3b1 0xc6718376 0x5acce6d8 + 0x614c56e0 0x89a6b00e 0x6cb4e087 0xa9822fe9 + 0xdea290c6 0xb294582f 0x36f9640e 0x30d0afc4 + 0xef7d75b9 0xfd9aae2d 0xd6729573 0xac442321 + 0x158224fc 0xfd6632df 0x10cebf98 0xc3864dd8 + 0x31577c58 0x49e71f9c 0xb96d876c 0xd867604e + 0xba74c3f0 0xad69752f 0x716eb51a 0x469d9d03 + 0xda4b2e16 0x9e80a908 0x9bcb18e8 0x2f1c595a + 0xe823ecfa 0xdfd5badc 0xe460e9e0 0xae418438 + 0x457811b4 0x29df713a 0xd90b0d29 0x415ba2de + 0xa0af6489 0x4922a50e 0x2efa0b0b 0x9394e4cc + 0x0ef8f59b 0x0f851711 0xa4670f3b 0xcc6bbfc6 + 0xae194dfe 0x78e51752 0x4c65a2d2 0x1b0741cd + 0xc9f401c0 0x4a678062 0x290d2bc5 0x1a4279c4 + 0xb5f9160f 0x40ef7c77 0xa9bcfba9 0xaec75f21 + 0x53d6258e 0x8587eb74 0x0721d492 0x2c6a6e2d + 0x8e6cb70e 0xa6bee309 0x6faf5706 0xf8eee239 + 0x52c85943 0x8c198893 0x3db37858 0x557fbf2e + 0x92f1a0e5 0xbd279594 0x46d65132 0x90a2c32a + 0xd11db660 0xc73b3922 0x9d1075ff 0xdb80a1cb + 0x54158743 0x39694d0a 0x4a0ddc7c 0x721f9dc9 + 0x04b1b044 0x3bb40aed 0x6be7a88a 0x429a3b09 + 0xa6e9dfa8 0xba412f0c 0x354f08d2 0xa4569516 + 0x928cca34 0x398b1a99 0xb7e80291 0xe67d7b71 + 0xa6582bf0 0x556ebb23 0xdc6d9f6a 0x11b3b753 + 0xbdf31ae5 0xd3399560 0x6148cec8 0x5188689e + 0xde18f46b 0x3da414ad 0x4c44ad29 0x68582541 + 0x75c8b1e6 0x7ba572de 0xd753ed20 0x4a9c4578 + 0xf1c9159d 0xcfd9da31 0x46799fbe 0x1aee4426 + 0xdcdf7b57 0x327db61b 0xa160ea1c 0x84a01fc2 + 0xbe0aa020 0x5963688b 0x24f32751 0x885b4177 + 0x26cde88c 0x39e6df90 0x1c7fee90 0x882a5c0c + 0x56f1f2e0 0x10bb9f52 0x4f0502aa 0xeae6e5b9 + 0x65e7ee25 0x8ed230ac 0x38b5e02c 0x5f5311f7 + 0x929491c0 0xdd923e62 0x5bc6166e 0xa3c89f4e + 0x5844fb12 0x0c40f02f 0xdda07582 0x8ca1b803 + 0x9398b0d0 0x4dba17f9 0xb9879c85 0x26956147 + 0x3c26a130 0x58cdc52b 0x21fa4801 0x9d965ce6 + 0xb9942dac 0xd83d1518 0x36e630dc 0x50bb2822 + 0xcd472a65 0x6feee2f4 0x4853b680 0x7f54945f + 0xa522c561 0x28134f6a 0x89b46cb2 0x4fe0047e + 0xad602b28 0x4942494f 0x1536ea37 0x40ea6278 + 0x5020bdb1 0xad3c9f7e 0x1356d0ce 0x411700c8 + 0x1ba61954 0x65dece8c 0xb788efb9 0x26efcd5e + 0x9833fa21 0xea0052b8 0x119a994f 0xa71b168b + 0x164a96e0 0x0bd1b4e9 0xaae1e562 0xb550f48c + 0x3a3b55e1 0x4d921246 0xcb28af65 0xdd2388ff + 0xa63988c3 0x7dfa5a8b 0xc7c44102 0xc75e9f3a + 0x5e4305db 0xacb34d1c 0x9b50976b 0xad3f6379 + 0x6cd20ee3 0xba806f21 0xcd0fcf4a 0x18a55973 + 0xbafe5266 0x03ee9b8c 0xa35fbfde 0x7f2eb71b + 0x23d9aa11 0x0e183c35 0xefb0ae3e 0xc6093786 + 0x5b380af5 0x64838229 0x3bd69926 0xe9758e1d + 0xde439e4a 0x0cbc4bdd 0xda5858e8 0xbe8afc07 + 0x676379e1 0xccc4c628 0x763e3b38 0xb4823c67 + 0x9f4aa538 0xd8d33f50 0x41291e48 0xaed28ade + 0x6c72eea8 0xa751f4e8 0x3a75dba2 0x5073e3bd + 0xf10b4756 0xdf46ab98 0x9ad689f1 0xc2ba74a4 + 0xf2ce9419 0x4cf9732e 0x75cf58ca 0x249e3c52 + 0x95d10a93 0x51120008 0x7438d467 0x0a5e7f2d + 0xb7a44e46 0xe31e5dee 0x26e2ed14 0x8f16a7d2 + 0xfcda431c 0xab32ada3 0x3a863c94 0x5fe91346 + 0x2a92c590 0xb8c17e6b 0xcaf753fe 0x50283647 + 0x533c8f3c 0x1233e1c1 0x7a5b2eb0 0x79b4ba22 + 0x3164670c 0x201c500d 0xafeac6bf 0x2fbb0884 + 0x915de3b0 0xbf733b7f 0xc45d1a42 0xa3b86d4a + 0x333ef605 0x6348522a 0xd28d1d19 0xa2cad790 + 0xf8ad449c 0x05aacdcf 0x64500018 0xb1d8cb18 + 0x9e4a2ecc 0x091282c7 0xfd64bcf8 0xe1e7c24d + 0xfcd0f386 0x0c9faa0e 0xa82f265c 0x83cafc3e + 0xcad43563 0xc110837c 0x2a2da74f 0xbd98e00b + 0x5c24553d 0x41c75caa 0xe75cb110 0xa004b946 + 0xd4daa77c 0x88d07273 0x0c75c7eb 0xaf05657a + 0xbe1f8336 0x122a7acc 0xe0e5c29d 0xd5896217 + 0xfb2f909a 0xa74b6458 0xb33a1a38 0x815f7832 + 0x9584b271 0x9a3bb26e 0x39aa6d36 0x2fba41db + 0x133797be 0x9993699e 0xdb50268d 0xccd54ff0 + 0xb7a33011 0x71db612b 0xef9a4429 0x7217f1d0 + 0x0ee420ba 0x1f7eb025 0x26572853 0x72712e17 + 0x5bd7be37 0x74b2288e 0x3ffd1f1f 0xed566562 + 0x744f4159 0xdbedb36b 0x69e25131 0x604ccb70 + 0x50d83542 0xe4704ddb 0xdc5144aa 0x33467434 + 0x1c7c4f2b 0xac774e8e 0xce9c4d1b 0xa0e3c7f7 + 0xffbecc1c 0xa1c25fb2 0x0e9f6039 0xbe9ed6d0 + 0xf958fb6a 0xaec3fba8 0x2944e767 0x77dc717e + 0x06e9fe1d 0xaf3a4928 0x7d4f3f29 0xead3972b + 0x65670bc4 0xd058cc70 0x9fb58c45 0xf5f08926 + 0x9aed1955 0xb1a5d161 0x14b5aa11 0x66e14cee + 0x28d7aae3 0xae45fcec 0x92dc7dc3 0xe9eda97f + 0xbee84f22 0xea6f71ac 0x6347c2b8 0xe919afff + 0x2c409d7c 0xa9800c52 0xd8033a17 0xc3794565 + 0xb5311fe8 0x80d8a030 0xf9cf179a 0x508ea242 + 0x4464cd33 0x91da91a8 0x6c0806cd 0xb5473d09 + 0x0a0b99b3 0xdaf528eb 0xca1e99e7 0x064055ef + 0xc2dce623 0x0b4c15ac 0x23c13327 0x3f9fc266 + 0x335d9c40 0xaca940c2 0xc18c0797 0xd5027a07 + 0xb0a4d322 0x2e601275 0x6cc88888 0x658eaf8d + 0x509e2247 0xbae254d6 0xf097f138 0xa163751e + 0x19558f7c 0xb66f0cd4 0x87b1d966 0x81dd2cad + 0xf0c25e6d 0xb8e72dd1 0x00f15f42 0x6d2c1c68 + 0x43c7e436 0x68eedad4 0xc2686b38 0x6ff30211 + 0x197c7734 0x905b8602 0x6ab9d204 0x0d16385c + 0xb1cb5e16 0x8249a5c4 0x29d1ce0e 0x779f7b63 + 0x63042725 0x12ce98e3 0x11282058 0xca3a9eb2 + 0xdb8294e7 0x423e41ac 0xc3ab2774 0xca658d6d + 0x519f8896 0xaf6010f0 0xd57a94aa 0xcc17df91 + 0x7d25cf8b 0x041e6835 0xa056d9e0 0xf90f3964 + 0x7f99ae59 0xd80125d7 0x9961d6e5 0x41b3da06 + 0x65c254e4 0x787d2c61 0x16aafb02 0x157ab4a8 + 0xdee3674a 0x1ed1b601 0x2e36dae9 0xad57ad38 + 0xaaf25b15 0xd3c37a01 0x68ca9eba 0x2a1bc480 + 0xba157917 0xc00017c0 0x190bd74a 0xd6c6c1cd + 0x4efd4f71 0x388ed702 0xc8812950 0xd0019ca4 + 0xd44cc835 0xd838fd6a 0x1432ce88 0xce98d932 + 0xaea21cf4 0x54a44cdf 0xdb4dc5ad 0x1d23a7ae + 0x5ae126ad 0x100dcb50 0xa9727413 0xcf1c61cc + 0x72f9d2f8 0x4d32d201 0xe27586a8 0x0a1cc932 + 0x21858469 0xf1cda3f2 0x59703f35 0xbd81f9f4 + 0xad6ac9cc 0x25665703 0x1212d5cc 0x98a243d3 + 0x8f47e113 0xd98feef4 0x3c93e832 0xfd67097a + 0x0c73fea5 0x6132ec59 0x1dc9bdb7 0x791f79eb + 0x84d83574 0xbd5817e6 0x7d5a0f8d 0x18482a08 + 0x53ac8e4f 0xadd3378f 0xd48540ac 0x4082f5d2 + 0x3ff5badc 0x24855b3d 0x7bb948f8 0x72637822 + 0x0687e93b 0x61290b4b 0xd9f20b3f 0xcc0e5beb + 0x141ca01f 0xecd1337b 0x8576ec65 0xb6f825a2 + 0x8b84e8b6 0x5bac53f1 0xd4edd06a 0x76ae712b + 0xdc00a887 0x798c2ee1 0xe74a5ab5 0x1539fa68 + 0xa30817da 0x06f7c53a 0x1930c59d 0xd4232359 + 0x0dfb1427 0x58d7180b 0x53bf57f9 0x5f001d08 + 0xd08128ed 0x3208b7be 0x5c2aba8c 0x0abbd0d0 + 0x424f2041 0x7982f731 0x010ec811 0xa3489c82 + 0x71ffdfa7 0xda0ed41f 0x8a9e806b 0xfa9bddcb + 0x7a9e1a41 0x53c7603f 0x9e3df28d 0xd06dd100 + 0x2cc64f4a 0x0dfdccf2 0xb4eb9101 0xf56d506d + 0xdaeed218 0x45523a16 0x4d6d68ba 0xff9a8f72 + 0x5358b2f1 0x2511a591 0x9ea2c2fb 0x08cafc7d + 0x7ed34bb1 0x0cf2301e 0x62b6c05d 0xc05095ec + 0x52128c55 0x030576af 0xef5f37a5 0xdf5ae47a + 0x39e55496 0xb2c2129e 0xb2d67d77 0xc5adf049 + 0x15a1cb4f 0x981948e5 0x7d18acc0 0xec7abb43 + 0x23f7e366 0xa919a355 0x23872683 0xb7b6d84b + 0x4767dab1 0xd133feb1 0x2e5536cd 0x587683d4 + 0xa181575c 0x4329e640 0x1244ae40 0x5be82f66 + 0x4b28dc4b 0x4106c9a9 0x517fad7e 0x9e334ca8 + 0x3c3ba741 0xe902a475 0x91d046a8 0x31361f96 + 0x911b83bc 0x6607fac7 0xdfbc6390 0x7213aab0 + 0x8ca8a47a 0x4f3d1f3a 0x3ee76c84 0x22bac3f0 + 0x475f3cab 0x05d05569 0x92b3f912 0xc632a733 + 0xd79b7448 0x595b82fa 0x6013b96e 0x6d03b5eb + 0xe37045fb 0x6e4add26 0x11f116da 0x4ac8bd3b + 0xacb5f8a9 0x8fb943d6 0xa9ac31c7 0xf1ba9752 + 0x43a6b29a 0xf123766f 0x536fcc32 0xcf8168ad + 0xd8fb1e4d 0xb9562fa5 0xfe6d8dea 0xd31ab16c + 0xf7dfc381 0xb70f11cb 0x371c6688 0xac3fccee + 0xf130a51b 0xc5b8cad7 0x0cb13762 0x64ae00f2 + 0x45cfad12 0x753d6a4a 0xc6f69472 0x695fba60 + 0x49d1f754 0x9db947f2 0x2364ae20 0x197492e4 + 0xc5b9562e 0x34963cec 0xdc26402a 0xa1c88d01 + 0x58e27195 0x9d60f5c4 0x3e200a43 0x7e9827f2 + 0x0a4feee5 0xd401e139 0x17352152 0xd509564a + 0x4b3142ed 0xef7567fd 0x9a619dbf 0x56ec2cb7 + 0xc64bb290 0x3d69fd89 0x897325a1 0x74e2cb7c + 0xf270fdac 0x2beb6a4f 0x5b60de30 0x49df7517 + 0x294966cf 0x87f5f667 0x4a9e1f6a 0xabc332c3 + 0xfaf358aa 0x5baa6cfb 0x36b99bfa 0x40259687 + 0x584539e2 0x2710ce99 0xec1959aa 0x642c8413 + 0xfc005d36 0x2b2e6245 0x0012d041 0x09f6b626 + 0x70fe9e2b 0x3cf30c5c 0x69d0a3ed 0xfe621601 + 0xb6fa9267 0xe9b507dc 0x49f35866 0x4b97647a + 0x9e721adb 0x89e6e8d6 0x407a2f49 0xd977cbaa + 0xd9359f5d 0x7b69702d 0x22d6e818 0x57eaa5a3 + 0xdd5063b0 0x4d7d2312 0x7a865203 0xb7f0905f + 0xdd2c2b87 0x7215803c 0x1abe5307 0x2926f38b + 0xf6b0cacc 0x96f50647 0xb612feb7 0x6915bfcc + 0x058b5cb0 0xc39e47d5 0x7513abdd 0x9e43972a + 0x1e55f640 0x896db1c5 0xd9382d2c 0xa52c1f99 + 0x8afaf5cf 0x36500aa3 0x2e65fa1a 0xbb40d668 + 0x81188e3f 0x143fba69 0x3f61fc90 0x438d759c + 0x893bb96a 0x069f349f 0xffdc43c7 0x6ebfa943 + 0x671b4751 0x629cec23 0xe717fb9c 0x53fadc0a + 0xddc1e212 0xb99788ba 0x78378cf8 0x2ed91106 + 0xec1de376 0x98d86b3a 0x312a190f 0x0208a0da + 0x6dcb469f 0xe6407c6b 0x1c7fea86 0x83841afa + 0xa9caaffe 0x86e3fd0a 0x918af9b0 0x0fabdf39 + 0xdd9fc8f7 0xf9ddd98f 0x3dd0acce 0x2064360b + 0x29006620 0x5d7733c2 0x682c4093 0xf038a8b4 + 0x3a688845 0xf9d0b9d2 0x27f51a57 0xb63b063c + 0x533b082b 0x7f0d0dd1 0x7abdb018 0xea6f6176 + 0x13394ac6 0x825339bb 0x1835fd8d 0xaa46df84 + 0x0751fe4b 0xbc9fb7c7 0x233873ff 0xca200e1c + 0x668fd5a5 0xda059135 0x2baf8828 0x7a2efc0e + 0x7c63d98c 0xe71ea373 0x0f218e88 0xa031f88f + 0xf32bccf3 0xf15eadad 0x6df44be6 0xb2536e4b + 0x2903a9aa 0x42ef8689 0x444432f2 0xd27a6c4c + 0x0992a32e 0xaf6e65d2 0xcbefdf23 0xe602151e + 0x21beace6 0xd9b992b2 0xe43286cb 0xdb315c09 + 0x0de7672d 0x9d518ff0 0x75c4e9a0 0x64b2f70a + 0x9deb697d 0x5bcf59b8 0x2e4b9a8a 0xd9294b49 + 0x3fee760e 0xfba8fec6 0x1c140305 0xe400487f + 0xc4cd4a38 0x14e6f1c6 0xdf98e7f8 0xfa6c4992 + 0x62908c82 0x37393196 0xc02464b8 0x4b119742 + 0x83e5e79d 0x15ddd908 0xf75d1820 0x363025b9 + 0xd9e1a04b 0x9e110da7 0xd8caf954 0x30f62bc6 + 0x875fd2b7 0x8b67bc8e 0xd5c77d4c 0x1a8ce00a + 0x7cfb14dd 0x3a39fd65 0xaecc2b5f 0xb017dbb5 + 0x6a57b4f3 0xa27b6509 0xcdb06076 0x000d6366 + 0x66e4f311 0xf22e25d7 0xf91d9bc5 0x5f9d3a05 + 0x3b37c96c 0xb0596f50 0x53c24ede 0xb620106a + 0x5e675314 0xd98d5b02 0x75261f6e 0x5610c20f + 0xedcbe43f 0xbe85b8c2 0x16f7ffb4 0x55eb91fc + 0x2605ab1b 0x5ad3b426 0x3658d764 0x639c0560 + 0x987249ed 0xdc470fa2 0x0d112f6e 0xd8ab77f7 + 0xaed9455f 0xd9f6a341 0xb9b21249 0x3ff2b69f + 0x37ad61d4 0xdd6a089f 0x609233f7 0x46a923f4 + 0xe5c23e8b 0x6aff8687 0x5e8ece1e 0xc65e1e4f + 0xfb96cf51 0x9b697cce 0xb08e02e2 0xf874e0e9 + 0xbc983fa6 0x870375e3 0xc88bcd2b 0xc6bb19ae + 0xaa0c99e3 0xb301ab7f 0x024ba529 0x4449828a + 0xd226454a 0x0a610f3a 0xf302a0f4 0x021a3cc2 + 0xa9e4b6ea 0x0b690b92 0x3379c01c 0x36265ea4 + 0x29fbc8a3 0xe6279573 0x3cdb8a1e 0x005b5332 + 0xbab71a8e 0x9677db73 0xa8a6d6ea 0xf0afbd3d + 0x576fbee6 0x49a54473 0xfa7c6e95 0xcb914daf + 0x58266856 0xa6b53a63 0x7136515a 0x2a3da411 + 0xb1c994e0 0xbdaecd7b 0x5b436ff8 0x6334ec5f + 0x0172b5d2 0x57acd652 0xca4efacd 0x87e7d313 + 0x78ac87c8 0xaf7602aa 0x3769ff6e 0x86d39747 + 0xd32a7aa7 0x840cb30c 0x3e7da9b1 0x3c905b44 + 0x90290dd7 0xebc85f3e 0x32693a53 0xc7140058 + 0x6ca5cf6c 0xdabfbc3b 0x3d559486 0xe5ce93b9 + 0x8d3c428a 0x9d18b8ee 0x404f58d3 0x151b4a78 + 0x2f393e9e 0x69c59344 0x7879e974 0xc32217f5 + 0xb946562f 0x1d1b8745 0x3666cd1a 0xc6a1e2ef + 0xe22d2e5e 0x9e7ed504 0xe6c32118 0xb2919117 + 0xb2bad34c 0xe7177e87 0x47b68328 0xe579fe7b + 0xd0d33f00 0x96923c90 0x5ff2bf45 0xff074961 + 0x4dce1092 0xe8a89464 0xc0b1ea51 0xd65f0f12 + 0x6b2389bb 0x48fa0960 0x82722b27 0x62625540 + 0xd4ff4985 0x768b7c26 0xb36a4ec6 0xf6a66375 + 0x1c89e246 0xb629fce9 0x6aa72399 0xd783733f + 0x6478b123 0xa374412c 0x11b5cfc8 0x73cf2286 + 0x443f5601 0xd817fca7 0xb2ce2d63 0xf6c63479 + 0xd16b0550 0xf2a52ac4 0x7843803c 0x1ac3b58b + 0x7f96b915 0x732403a1 0x64634349 0xd2ec0bf9 + 0x10410c08 0xe95d8dfa 0xaaeb33a5 0x57893eaa + 0xb59afac2 0xe9fd6dd2 0x50d11a7f 0xde479c58 + 0x9dac27dc 0xebba7d8b 0x17fa1420 0x74a1678c + 0x71ccdaa3 0x5e44b0bb 0x5927a75a 0x7b7580a8 + 0x33330c9a 0x40192652 0xba6308de 0xecc81fbe + 0x41d48824 0x6ce4e0c7 0x145e9225 0xf8484bee + 0xc8675611 0x750ec207 0xfa5f5b85 0x618b9f8a + 0x007cdb05 0x67f98d4b 0x1035f305 0x8d700e9b + 0x9857a0bf 0x4b774ad8 0x8960c81e 0x344a9462 + 0xee2680d0 0xebb5f6cf 0x7397c9f2 0xcafa01ec + 0xaf69f3f4 0x0a1699cb 0x90ed82f8 0xc5c8ac04 + 0xe50bd06d 0xf75741c6 0xea52365c 0xd0c03f33 + 0xb5e4e95c 0xebf55379 0x0aae6e4a 0x29f8b91b + 0xef8ad2b9 0x7bebf2ca 0xb194b728 0x7df7b083 + 0x0ea527c4 0x6d55939f 0xb9242c58 0xb3e1f570 + 0x4fba0507 0x82d7259b 0xb5be7b54 0x0aff6ff9 + 0x88391023 0xfe352956 0x4a6bfb30 0xa00c9644 + 0xc478d534 0x0cdb509d 0x9611713c 0xd7c442be + 0x8d16889f 0x93abfefe 0x435fa757 0x40d95d3d + 0x11b7bdce 0xd074874b 0xdce6add2 0x0b652a4e + 0x595a88e6 0x307a223d 0xb624b9bd 0x855ba51f + 0xad43c800 0x1fcf6afd 0x4bdd921a 0xd6777384 + 0x8da9f15f 0x5fb03ee2 0x5e6d04e2 0xb33751cf + 0x55d9d38e 0x41589fad 0x6d311b4a 0x43046a7a + 0x8d9c7304 0xe25f9788 0x8b459e1b 0xc9a3cfe2 + 0xe6ab721e 0x4de3c89c 0x5c2d2398 0x085d8d69 + 0x4e27ce73 0x1cc1f44e 0x05aeaebe 0x8cedb916 + 0x370b4d46 0x1bc29579 0x33d08b75 0x06b77cff + 0x155693d7 0x125d3f0b 0xd8714e15 0x3b7427ba + 0x13f6684d 0x834ee449 0xc5a45189 0xb2ad214c + 0xa61be586 0x4e4727cd 0x563d1c31 0xd4ba1cc3 + 0xdb08cd16 0x4940a42c 0x43dfd0cc 0x9d43222c + 0x638a0d11 0xc33d3992 0x98bf11f0 0x1aebf6b5 + 0x1e206582 0x5647f772 0x9255ad74 0x75915665 + 0x0fe7dd12 0x9def740a 0x9361bdf1 0xc1409fc0 + 0xd3bac631 0x7492ee87 0xe1e99dde 0x2fbaf552 + 0xfc24f52c 0xc080882a 0x0a2417c8 0xcea3da70 + 0x4fe34fad 0xb4e55427 0xd5d54d76 0xf36686ba + 0xd6ab1798 0x1868e364 0xa380f948 0x0eaee02a + 0xad5a44e8 0xb6d119f4 0x82a43444 0xafad0e68 + 0x595c3ab7 0x385746b3 0x32df6d2a 0x0b01b2de + 0x51d3d6bc 0x107d8620 0x6d215143 0x29d0e901 + 0xbc57a3ec 0xd584ba34 0x8c244547 0x23d396fa + 0xffb03cb4 0x8396c1a7 0x3f251905 0x8bc769b3 + 0x68f4696c 0xfc297895 0x9ec65e40 0x22deb20b + 0x5d1def76 0xa7a095b1 0x3aa6a458 0x6ca11880 + 0xcde44ece 0x62b59f4c 0x067f272d 0x9a5aae97 + 0xc60a8d62 0xeb0f40c9 0x83ebae30 0x07dc9cb0 + 0x05dbdc76 0x0c108eb1 0x314f9247 0x7bfd6072 + 0xf648e1c0 0xae70bd5e 0x7c27b4d1 0xb0cff1c3 + 0x8c2dd93c 0x580a4b19 0xfaa1ee8b 0x4173a23f + 0x838fa15b 0x2b0fe3c5 0x8059250d 0x659a445d + 0x2a1c1968 0xbf13412b 0x1a9f915e 0xaf80263d + 0x24508a66 0xe381d252 0x4e0f55a2 0x7ce1f4fb + 0xc145da4d 0xbd4b29c3 0x27540ac2 0x23ad4b42 + 0x8e6bcda5 0x20061c20 0x1d3cb3fd 0x5c5498f3 + 0xc468681d 0x4c28ef55 0xf0165c1d 0x2dd6d032 + 0x7e347ccc 0xe04db59c 0x7caa883b 0x1f43df4f + 0xc300031c 0x85f19e9b 0x22811fa7 0x2622940e + 0x6299f57b 0x5c106568 0xd7da296e 0xccd36b39 + 0xe349afc0 0xd2c2463e 0xf7f55aef 0x0e0a7e3d + 0x6b6fc6d1 0x8854098e 0xc87edace 0x8190c437 + 0x333b8ec6 0xe49b3a5b 0x4aecd4e3 0x14cc5f22 + 0xa11faf96 0x3d1cd023 0xae614c70 0x0ab662b4 + 0x908d8082 0x76316cd0 0x3068ec32 0x829b047d + 0xf08d1b94 0x3b2b33f6 0x03df9ae8 0x40f632d0 + 0x3590085b 0xa33aad24 0x39597da2 0x99415f4e + 0x7aed6e11 0x61a920ab 0xca851d8b 0x2606f821 + 0xeb7c0e8b 0x8bd6edb1 0x725b39f6 0x3afa6248 + 0x03540044 0xfb118ecf 0x8e18bd5a 0x2a85cc05 + 0x4ecac12f 0xf53a4d25 0x8e3fc6fe 0x32233799 + 0xc7ebb5e6 0x058fdcaa 0xe6db17ed 0x2751405c + 0xa195a515 0x34410c51 0x4517154e 0xbbb5674f + 0x28050e40 0x8fd71724 0xbe78711c 0xc1b18693 + 0xd202b9d2 0xdf4e0b62 0x460349da 0x71463aef + 0xb2fb55d3 0x54a972dd 0x49379f09 0x7a7fdff3 + 0xbd82d4f8 0xd2894393 0xa82bca57 0xe61ca9b4 + 0x9e08e6a0 0x53dffe9d 0xe7ae1c5c 0x65bff365 + 0x7564aef8 0xd94abd3b 0x18d1ba52 0x64a759f0 + 0x65c5dd4f 0x6f9d433a 0x57cb5a25 0xc1862d25 + 0xcf50223f 0x90c2724d 0xf5527605 0xb085f18a + 0x41e2b17d 0xfb1cabc4 0xd8ab04cc 0x761c2166 + 0x8365afd4 0xc3276657 0x14f64be6 0x5dd779b7 + 0x3b3f1faa 0x358d01e8 0x4c821ddd 0x7ada9f95 + 0x2970bad5 0x3b54a4bd 0x3ca7f039 0xcb67aabc + 0x3b264655 0x96401a5e 0xa3990376 0x90834685 + 0x8ba56352 0xee98c564 0x4a0534ed 0x7d70fad6 + 0x5d73a1e7 0x23fd8de5 0x39c52296 0xefef1540 + 0x7bc934dc 0xeed157b4 0x898d8bfa 0x5761e88f + 0x73af2674 0x2fb88d9e 0x28de1281 0x9aa76119 + 0xa3ac21ea 0x28ce635c 0x7596d79a 0xd3295e0b + 0x7826630d 0xd815ef01 0x27cf2899 0xf3de6a01 + 0xcbb32e58 0x6c57be3c 0x292f819f 0xaa4623d6 + 0xb96ab772 0x90a6f778 0x44b9933b 0xa43e7543 + 0xb9f417b7 0x7a6537a5 0xf36a6da2 0x0a9bb3fb + 0x177c1f28 0x0512c07f 0xdda55932 0x060dda31 + 0x14465771 0xf3f96780 0xb459e5e3 0x49aaefbd + 0xb07db15d 0x2ac82807 0x8404060d 0x417d036b + 0x70946fb1 0xe39e68f5 0x5f9b3035 0xf0335e7f + 0x2ba457c6 0x2d97ba3a 0xc05156e7 0xbbc9afb2 + 0xd25981ea 0xe70d060b 0x805c231d 0xae471b34 + 0x31964d8d 0x3f34e35a 0x8355ee21 0x73822024 + 0x9ce5f2d6 0xdff19812 0xae55cbaa 0x55f5ecbd + 0xfe558210 0x09b95751 0x41ee7cb8 0xd2b9fa15 + 0x342c07e5 0x7ee50e8e 0xb6154e01 0xdbf4df3a + 0xd43e2c77 0xc3ff0498 0xd8106f33 0x9bdb25bd + 0x40cb843e 0x106b08a9 0x3227ce7b 0x58bb7cb6 + 0xb84e3244 0x3f1d0e20 0x76dcbcfd 0xb750bce7 + 0xa8c11f3f 0x161a8610 0xdc1ef5bd 0x14270b6e + 0x285e7898 0x68375db6 0x01d23b44 0x35a17fb0 + 0x7c9ad882 0x7bda2e0b 0xca67bfcf 0x6e2dd9ab + 0x227a6aba 0x5d295397 0x5061f96e 0x47a20c68 + 0xf5427e3d 0x3a0a3165 0x2438fd9c 0x2dc91147 + 0xeabab62a 0xdc358e4d 0x7e1fcc9b 0xdc2a328e + 0x6e6bf75c 0x68c45517 0x594fe5a7 0x2feac658 + 0x1f0a4d49 0x97575e83 0xcccbdab8 0xc13f3b64 + 0x8bfe659f 0xa4ebf545 0x2c3cf874 0x7d78ceba + 0x46ac5d6e 0x09309533 0x78ffb6e3 0x7336541e + 0x3d270f70 0xd71e72b4 0x9772402a 0x4ed185b7 + 0x213da698 0x78a54587 0x18054eb4 0x99179a25 + 0xf758337b 0x94629a30 0xec6bf4e0 0x255ac299 + 0xe56f52b1 0x1c2a6136 0xfb7cc1f6 0x87b53b53 + 0x079ca1f7 0x3a8c340f 0xeb70ef48 0xfd1caae4 + 0x564445e7 0xc1d5c663 0x658fb5fa 0x62d2debe + 0xc0907042 0xb5402269 0x16965193 0xc038c21f + 0x780f8b76 0x33ffeb3d 0x03ad9602 0x4a7b6432 + 0x93c2b2f5 0x40720fcd 0xf44c164f 0xcbd43d01 + 0xcf7098cd 0xc43242fa 0xc530a6b3 0xcc33c1f7 + 0xde3d648c 0xf1def13d 0x2a22f5d1 0x77704fc6 + 0x08ed5552 0x3e2295d0 0x00584764 0x6af8585e + 0x43f845da 0xa92e38df 0xd98c12b4 0xb4fac901 + 0x0b05a079 0xa05f215a 0x27d635c6 0x9fc897e5 + 0x0eb91a30 0x43bdad4c 0x705df05f 0x6b7864b7 + 0x1b6380ba 0x4a64e8ec 0x517b7b68 0x67336d4b + 0xc6d51eab 0xfac40c57 0xb977cbcd 0x0674e5dc + 0x74ce2339 0x891cc5f5 0x3230ca78 0xa8a653a0 + 0xa8d4b370 0x496d2f7f 0x6ca677c5 0x54260ac2 + 0x630e1143 0xcbf6f819 0x546b2874 0x02267559 + 0xa2e23914 0x7c9a0393 0x1704bcb3 0x6d680415 + 0x91da300d 0xe2ce21d2 0xc38faf3e 0xcc8be7cb + 0x14496036 0xc98e253a 0x05ca6582 0x8c566616 + 0xd26204dc 0x3335bd81 0xa94e5af0 0x76fbb455 + 0x23b27f08 0xc4db6f93 0x5cb5401c 0x7cb2ed29 + 0x7cbbad8b 0xfc1e8f5e 0x2bc79e28 0xf69228fe + 0xbde16357 0xc9ac3b53 0xa6afbc74 0x984bb3f4 + 0x98a8b9d6 0xdd21c848 0x33e65c3a 0xc53c772c + 0x633022f8 0xa324bd5a 0xd260a77a 0x668ca5d3 + 0x4b79a6b3 0xbfd19bbe 0xca2eb497 0x8e7eb5c9 + 0x169b2184 0x0503d4f6 0x24f35c00 0x0ac930ab + 0xf694120f 0xcee12db4 0x9305757c 0x798a2db2 + 0xed27ebec 0x2f35829b 0x4294e805 0xa7994ad7 + 0x49fd229c 0x5d63fe52 0xb7cd7641 0x1a68af3b + 0x6f952e97 0x1c02f4de 0xca3a1515 0xed5bf092 + 0x123c32ea 0x602030aa 0x7811cd1f 0x1b6c38dc + 0xeb7712b4 0x4aa767e1 0x6b49d384 0x7ba4ee1a + 0x87f02cd2 0xb8e6b0b1 0x090e9f89 0x95f8b90e + 0x8d76892c 0x0be06870 0x9ec963c1 0x75d67c9d + 0xdde23799 0xf9e3be20 0x549442fc 0x09cb0906 + 0x95ee6c4b 0x25a2d9b7 0x98154023 0xdda91829 + 0x0c46879b 0xfbf0e362 0xb7223786 0x7cfbc839 + 0x3b251e5c 0x8be187a6 0xa24f9da6 0xc3192693 + 0x7a8ac8b9 0xc493ca03 0xc736b974 0x369db725 + 0x85a6e92f 0x26dbef75 0xa61a71e9 0x38a08fb9 + 0x4a214ed6 0x57fc6f4b 0x9cf91617 0x322e13fe + 0x5ac816a3 0x748a9728 0xdc777bd6 0x69fb5335 + 0x258439e8 0xf171a221 0xfa7a07af 0x26447b9f + 0xadcf3734 0x5af34b97 0xf8b4b0dd 0x08c79517 + 0x28861618 0x64692555 0x19fe9897 0xe3bda02c + 0x77df51ff 0x93dedf7a 0xc7cb57c4 0x02ee5928 + 0xd4aeb644 0x01d511e6 0x6512bd02 0x5d8f90f8 + 0xe77ccfe0 0xe6ee3ecd 0x5403139e 0x6f7075e5 + 0xb6484511 0x3bd42a35 0x5dcea90c 0x5bb1c6e1 + 0xb69b5847 0xfe106914 0x74442ce9 0x10997c57 + 0x1595af7f 0x9f04a8bb 0xa7d2870e 0x19e57681 + 0x54b276be 0x11c3e3f9 0xc5401783 0x9c413cda + 0xa6aa9e8d 0x23ff8569 0xf1797ea7 0x86ce3e8e + 0x9ef0a776 0x56a1c30d 0xf5e18916 0xb11464d1 + 0x7f313c1e 0x49c15cff 0xe2dcfb73 0x637819d8 + 0x2d6ce0e2 0x2170cd43 0xb750902d 0x5eb02cd2 + 0x6cadb7d4 0x89b96f3b 0x8d749ca2 0x8ac7abb7 + 0x31fbdb51 0x7a6df774 0xfb9139f0 0x56f3d9c3 + 0x0f104f2f 0xfaba3c49 0xe53aefff 0x932237d0 + 0x8ee10e80 0xadad6e20 0x19883a1a 0xf45a543b + 0xd560ff0a 0x8c7b4e03 0xe35696d6 0x9e0ec159 + 0xfc2cbae5 0x6ce2cddc 0x14a72474 0x89757fe3 + 0x6b788e7b 0xc16fa200 0xad36bdf7 0x57bdc4d1 + 0x55146f2b 0xa57db4c5 0x313952e1 0x2c55d0d2 + 0x32ab0208 0x10f846bc 0xdcba1674 0x436485bb + 0x932704de 0xcd7e2e1c 0x59f78879 0x7ca21395 + 0xbcc07be6 0x2b101e5b 0x38924c37 0xb90928f4 + 0x8f824214 0x55699b67 0x54cba493 0xe71c27a3 + 0xdde01c05 0x48d822fd 0x734ed8fe 0x29dbf298 + 0x9ef3a499 0xfb517934 0x19c8ce8b 0x38b8bf00 + 0x75da50eb 0x237f3b1d 0xa8940707 0xa98a4149 + 0x35ec2d39 0xee862d31 0x36659949 0x8f3dffc2 + 0x70afb227 0x94f443c1 0xb6f9308e 0x0e8ebd54 + 0x92b8960f 0x56d21560 0x8453d1ca 0x74c680c0 + 0x2d706dfc 0xd0b81c18 0xbac65445 0x40a34988 + 0x498145a9 0xf436ae10 0x9b72fec6 0xb4100aed + 0xe305983c 0x349fe379 0xbf31cfa7 0xba624703 + 0x4a491754 0xf973a686 0xa2ba725c 0xd0a23615 + 0x31903086 0x4ae46e45 0x0f705e05 0x4ea6bbc8 + 0xbf299e43 0x0689709c 0x9fc93571 0x07cbc14f + 0x542ef992 0x80ce91f1 0xf86014aa 0x17d533d1 + 0xb55e63e2 0xe02e0e4c 0x88a5ed22 0x6302126a + 0x56b32e90 0x5fec4381 0xe2e98b3f 0x30693509 + 0x862e1d75 0x2da30e3c 0xad992d90 0xc62cae4b + 0x379c77ba 0x467ea8f1 0x8a820048 0x74cc474e + 0x6bca3803 0x18aaa3f3 0x1fafd26a 0x0865f360 + 0xe3479d10 0x6cefb2b9 0xf6612730 0x2e0f222a + 0x749a89e0 0x75b1fa05 0xe2ea0874 0x5d422c20 + 0x24707d46 0x6d475835 0xed1e556e 0x6aa4543e + 0x28b36c16 0x22d83c4a 0x8c3e6d51 0x42a94c9f + 0x0c603d0e 0xa8c7f417 0x845997ff 0xdc79494e + 0xa130d628 0xc2df082a 0xa3a2c27e 0x3f93b00f + 0x1521a7e5 0xca15bae4 0x57e4e836 0xb915a471 + 0xd9147115 0xad52f80e 0x5fd2a2be 0x15972ed7 + 0xb69ec21c 0x502f2627 0xfb46a1ca 0xea685d34 + 0x9226f7f2 0x4b41927d 0x7965eaa0 0xb702e76f + 0x79a54721 0x5b8e984a 0x37efcd59 0xfeabf30a + 0xd4ad7db5 0xbb2282ab 0x8a5c840b 0x2ba370c5 + 0xdef5758d 0xa69a9aa1 0x46082250 0x6e8e8477 + 0xf6280c61 0xf99e4a14 0xcf3c5cbd 0xcce657f0 + 0xca635eae 0x0be182b5 0x58e8b43a 0x5c717ce5 + 0xaa7aaff7 0xc329c6b6 0xf1cc91ef 0x8d7cc520 + 0xda155783 0xd5e2e54c 0xf466f010 0xc5dfac4a + 0x606ad5de 0xf4992f1a 0x1344c9ce 0x4aea9020 + 0xa30447c7 0x0a99ad18 0xd3caa96c 0xfe5b0b4e + 0x7b50bbd1 0x33e50575 0xa22d1d06 0x73a1820d + 0xce4c4c8c 0x2cde7764 0x511d1c26 0xad0cf826 + 0x086dc311 0x3060ef7d 0xe6fdc617 0x3050b179 + 0x1dbb5316 0x4145fcb7 0x2eb62505 0x2e1359e2 + 0x79cab612 0xaa9282c9 0x7eede562 0xb016f7ed + 0x1445fefb 0x809b2e00 0xfafaa754 0x69ac113c + 0x548a6e3a 0x6d444c14 0xb3d355d8 0xbbadcd2b + 0x3032d634 0x7df39948 0x4c1f9098 0xa9d138ce + 0x42823bbe 0x2ef39e3f 0xaaf9ef1d 0x63369afb + 0x2bb76c9d 0xb7d38558 0x354160ce 0xc04c6378 + 0x6c71ab10 0x7914af1a 0x1c1a4694 0x2f9fce8a + 0xe28f18d3 0x3acaa573 0x2503b236 0x90ca20e1 + 0xd2c77ccc 0xc3005311 0x836d9430 0xe91d8463 + 0xb53e4cb7 0x4e373c67 0xd06ef659 0x27e1a21c + 0x285c0391 0x32046fa9 0x8b1b9c92 0x49a22f4e + 0x81411430 0x050110e3 0x56144e6a 0x47fb824a + 0xdb2e9a6a 0xb5fe97a9 0xabd37259 0x93da3055 + 0x19fb35e6 0x66661115 0xa27149a2 0xfb7d94b5 + 0xa315f9af 0xd7d97596 0x134d7d09 0xd5cde0e9 + 0xbc3f143a 0x1b2061ea 0xd7b15227 0xe8f506e3 + 0x0aa17e92 0xc8565276 0xc7d90586 0x22a26c8e + 0x6d462029 0xe7b1ad73 0xd11fa609 0x67643f2c + 0x64f1ef34 0xa0e7e0b6 0x9687611d 0x09c2d32b + 0xb494937a 0xcc36510c 0x70555bfd 0xfa25e917 + 0x7d88b6da 0x30f3b531 0xd19b224a 0x999d0f7a + 0x9fe0da18 0x45947b87 0x536dbf3b 0xa6f5182d + 0xdf11f95d 0xa5abcdbf 0x7528110b 0xf54fe792 + 0x71a97619 0x680bd3ff 0x6981ea39 0x683ff854 + 0x302fbbe4 0x12129f84 0xf63cd448 0x69fe289b + 0x568da933 0x2f1e1146 0xe7404e52 0xcd329394 + 0x02e41762 0x94456d4d 0xe9416a20 0x4e5920e7 + 0xe8db71fe 0x527a5313 0xe42c7d9e 0x58c8c1fb + 0x28949bc1 0x312fdf97 0x3569f41f 0x3ed5f092 + 0x44baef39 0x5c11d5ad 0xb5d172cf 0xa9e4cfa3 + 0xbc5ed197 0x2f290ead 0x747f53ed 0xadf1b698 + 0x1b90440a 0x4cdfe154 0x9b24b832 0xeb97d794 + 0xc90fe91e 0x4fef1271 0x8bf96025 0xbdb49f79 + 0x63910640 0x26a05cce 0x3318e422 0xb2fc61de + 0xf14cedd1 0x4bd7687a 0x8c4c91dc 0x48a857a2 + 0xb47aac94 0x787526e2 0x99349c7a 0x0bd6ba75 + 0xbfbc4b0b 0x040fbec9 0xd00de44b 0xc4c7f0f5 + 0x74a8653b 0xbd3cc036 0xa601a4f3 0xb82c0da0 + 0x2709b674 0x73065351 0xaf4cd23f 0x3481ea0f + 0x6a1fa77c 0x26a9d280 0x95f4a170 0x393e7590 + 0x015b3d73 0x36d91e55 0x61a7f3f5 0xf6d39c21 + 0xd9ee4701 0xe57af451 0x5e141761 0xf6b6e472 + 0xa6efc965 0x9606aa1b 0xfb8ce005 0x831ab2d1 + 0xfe7a1af6 0x5e326881 0xa0ad32ae 0x15f86ecc + 0xa1a634d2 0x3a40c4a9 0x88e10130 0x2e6c4556 + 0x8526aa32 0xa81b0d30 0x19c83936 0xdcaa556b + 0x6dc8064e 0x5709ad31 0x1b6fba18 0x9ebe34b1 + 0x28abc3e6 0xd76c3908 0x4374657e 0x6f0fc085 + 0x4f19a108 0xb774421d 0x405228d5 0x123dbbab + 0x18535471 0xfc6bde41 0xd4b2d82e 0x65b85772 + 0x64731e41 0x29e886f6 0x4c2c7eda 0x91586a5f + 0x15b2407b 0x5fa08a72 0x56898e51 0x5424e976 + 0x19ce4a36 0x0ada4656 0xe634446a 0x478da533 + 0x36f1c763 0x01ec46c3 0x5e1d1040 0xf6da1918 + 0x831f8f94 0x43ddb630 0x80b5d4e5 0xfc403ba5 + 0x40dcdd4e 0xa19d0aa9 0x6c32fad7 0x7cdd6f3d + 0x8e9c123a 0x42c4edd0 0xc8247030 0xf0e6cebb + 0xf8d1425f 0xcfa8e403 0x67646391 0x9dee9f9b + 0x5683c4f6 0xd958ae1c 0xc62eedfa 0xbd67ea10 + 0x253398d4 0x18b7f92a 0xf101a7de 0x60066732 + 0x4ca1e3dc 0x6e1eb0a0 0x115aa9e1 0x8370aae0 + 0xe46756d8 0xa02eb1aa 0x854dbb8a 0x6334873e + 0x87613a81 0xb5bd56df 0x491371d1 0x02bbace8 + 0x2a2e45f9 0x91bdc460 0x2bcf90b6 0x81df2f07 + 0x34aa2dd5 0x5b54a117 0xb7a5bd42 0x713e2287 + 0x1ea184d6 0x176bdda0 0xa19c0d86 0x4180fd5c + 0xd018a4cc 0x60120a37 0x8f6e094b 0xfebe1b15 + 0x42866bb7 0x4a9f772e 0x0bcf9cad 0xd936a924 + 0xec6cf0a1 0x1f9ccf16 0x81f8229f 0xdcef1733 + 0xb4a31fca 0xefbf0a0a 0x057e0b4b 0x59491c96 + 0x70ce99bb 0x908ce274 0x637ae09c 0x479fdd52 + 0x11ea6250 0x7778cdf6 0xd0ffe2ca 0x539b18dc + 0xbcdab649 0x3066399b 0xd685edc0 0x79d8d588 + 0x32942aa1 0xd03531f7 0x5d024d56 0x4dc99729 + 0xd1efff53 0xdf3ce9a1 0x31462a0e 0xe5427113 + 0x395e2980 0xcf5c9d4e 0x91e11088 0x7e4d31e2 + 0x5ff91ae8 0x9340e815 0xfcb89789 0xcb1b2f58 + 0x655aa934 0x2eb022da 0x419104a9 0x6b648411 + 0x582048e2 0xa0db392a 0x1e1d6443 0xf3c7a401 + 0x1e737591 0x452af94c 0xfcb74331 0x2da70f75 + 0xa8b59eb9 0x736224c8 0x5ba81657 0xfb36eac0 + 0x4e0336b4 0x8925a32c 0xa4d60fde 0x8a95ff27 + 0x57a7e536 0x7e6a2f58 0xd9e9751e 0x817cc66a + 0xca4bd134 0x627382fe 0x00e56736 0x74844fbc + 0xab1f8265 0xa32955e3 0x41cd361a 0xb3ae6366 + 0x1f77ea37 0x2200c6ef 0x81854e76 0x49ed4e92 + 0xb57a7fbd 0x7b9de6d2 0x128feedf 0x57bb65fd + 0x20ccd650 0xdcde5458 0xd5461b27 0x465147f4 + 0x70719068 0x2cb48f5d 0x6edc0d43 0x83dbda97 + 0xf077ea64 0xf61423e2 0x39a55177 0xb23ff07c + 0xa02e4ca4 0x9e6250d3 0x77f1df9c 0x238c632e + 0xce253a6a 0x096327c5 0x87f1db29 0xd75ac0de + 0x456704b5 0x9ee7046e 0xd693dfe0 0xf995c6b9 + 0xa354d140 0xf16bf090 0xaf511cdd 0xdc56d21e + 0xd7cc4d4c 0x5398cc1e 0xe5444b3b 0xe192f473 + 0xd09ae67d 0x8af2775e 0xc1af44a9 0x57bc4586 + 0xa6ff5419 0xdd4ba49d 0xec4864fa 0xda9d0357 + 0x84dfbe33 0xf41ba9c4 0x99e2bda8 0x9fba720b + 0xa7dd9e92 0xa0d43386 0x3e0f9ef2 0x6e388282 + 0x8f47ea95 0xac920523 0xa98ae8a5 0xf6a6a4d4 + 0xc3fa2e55 0x74a21b36 0x9c0b14b2 0xc6b8a79a + 0x367b7036 0x24b9f255 0x0b543b75 0xb630fa41 + 0x1b260452 0x7daf6714 0xdb8a13d9 0xede8f6bc + 0x47a21d0c 0x01d9ca54 0x4a8e5cd4 0x257cd217 + 0x7504cecc 0x973bbf11 0x992b731e 0xaab55b65 + 0x77e2f058 0xf580b58e 0xb10419fe 0x679aa4df + 0x296c1d64 0x751380f0 0x8f70f0de 0x3f78bdb8 + 0x1ee68ad6 0x7d5d50e4 0x823710a4 0x18b98d13 + 0x86bdf798 0x953b8131 0xb5da3d24 0x2eccd3b1 + 0x828a154c 0xed51b913 0x566e58ef 0xab8ff1b4 + 0xc744d227 0xe705bbc6 0x6032eb64 0x5495e4a5 + 0xe83add11 0x08429de8 0xa2e397dc 0x4f00c90b + 0xcb7672e8 0xa1d55607 0x0741ca2a 0x323d64f2 + 0xa700ef1e 0x6ccb2967 0x07c29e41 0x018440a9 + 0xbb1880cc 0x35502720 0x8a13a96e 0xe2bfcd29 + 0xa76ad3aa 0xd95be915 0x6dd66033 0x41d655f3 + 0x02009028 0xb44ec634 0x82e61d87 0x216e624a + 0x7fc79105 0xac0307cb 0xd22fa331 0x63746b2f + 0xe51ab72d 0x9b550c82 0xb28dbc01 0xd569d017 + 0xd168d372 0x8d6bfe6b 0x5820751c 0x820a4e23 + 0x13cfd07a 0x678c8319 0xd1e65476 0x752967ee + 0xafb28392 0x390d5488 0x53668098 0xa0c92673 + 0xaf0549c2 0x644f51c3 0xd59df083 0x7cb37a42 + 0x12261017 0x038c15b3 0xccc30b03 0x85ee24ce + 0x1e029b23 0xb6bb2845 0xb62a305e 0x2d0cf4e9 + 0x182b887f 0xec423ce7 0x8c1c0b25 0xc83b4737 + 0x71fb9023 0x63d639f6 0x16c1ce44 0x66ac8331 + 0xd9aa0975 0xba3d445c 0x5d097729 0xb353a034 + 0x23811786 0xb81394b5 0x5323f1b3 0x7a3e1576 + 0x3f2867ad 0x0bc88c8e 0x74b60d63 0xd56335de + 0x0d40f71c 0x55ec2524 0xea3a2c78 0x19e5e0ae + 0x9bf3d033 0xf57bbc94 0x05b6ac55 0x4c368744 + 0xae8c68f2 0xf23aad06 0xcf94d185 0x2360ff3d + 0x0e8a87f9 0xb97c8d33 0xa7122e6e 0x5ad4dc50 + 0x6145ff8e 0x617389df 0xe8a0e09b 0x4d40ce6f + 0xee2b65fa 0x4104d368 0xf4bc9d85 0x0b67abbc + 0x7bbad9ff 0x26b293a2 0x06055372 0xbbb05665 + 0x0560311d 0x421dc535 0x9c451ac7 0x38c83a74 + 0xc8921ff8 0x634d52c5 0x6e66dae7 0x1c86fae3 + 0x5a0645bd 0x6e5fddc9 0x86852d55 0x76207d9a + 0x6a4b7990 0x661c00eb 0xb268e55b 0x17daec24 + 0xa2854da4 0x9b1f3f63 0xdd200bc5 0x0b50aecf + 0x8242f913 0xc7ab6eea 0xaa977c22 0x748d0d1b + 0x4490aae4 0xaa293e18 0x69aa0720 0x6115eb81 + 0xa5b187fe 0x828bfe34 0x5fb6d155 0xe764d755 + 0x08833186 0x8475cce3 0x718bfb48 0x063b287b + 0x7ea71b59 0xbedbfd29 0x3736aa07 0xe2dfd533 + 0xf2ea49a3 0x96b0983a 0xc1f60b14 0x511bed9e + 0xac976686 0x9c60ce3d 0xfffd0b07 0x59d7cf79 + 0x477942b4 0xff2f43cf 0xeb4b899b 0x37a47783 + 0x8e6602a7 0xb6bfc410 0x7685c6e4 0xb7ec103a + 0xd54fdb01 0x3933d261 0x725982d1 0x86ada0a9 + 0x83788370 0xbafb1498 0x13972979 0x2157be41 + 0x5e976c80 0x05501107 0xb3b66da9 0xeebcb8fb + 0x42ac1fee 0x1dba34a9 0x3f5a7582 0x362e7ed7 + 0xaa69be91 0x419f4d18 0xb09a9967 0x31aba127 + 0xaa247bff 0xb31f4958 0xe79562af 0xfb73878c + 0x47dc697a 0x5d08fa9b 0x91dcd3c2 0x53e52d33 + 0xc84ddc84 0xdb5f8e17 0xe51889e2 0xb1aff523 + 0x4ffa0702 0x2c72b35a 0x9a4246fc 0x62420517 + 0xaad11acc 0x18190bf9 0x11e140de 0xacc99086 + 0x39347992 0x191a53d7 0xbe92c4ef 0x9a934b5d + 0x64cf7353 0xe30a3e8d 0x0aa6db52 0xb0a7e26d + 0xc8fe2f52 0x2e274a07 0x0c94b6ba 0xf80eaf3c + 0x1ba3e94e 0x5853ffe3 0x11652833 0xce7b0839 + 0xd1893c23 0xd06d2078 0xa65f020e 0x281e6a7d + 0xdf1da5a2 0xcdf69d20 0x74fa9b92 0xd98d6000 + 0xb732496c 0xbd12f87e 0x561dc55a 0x651d42ff + 0x5736b74a 0x2c48a906 0xfdcbaf15 0xf76606e1 + 0x80dd0254 0x8105e60b 0x143200b2 0x0f02f524 + 0x1580d2c6 0x7281c6fc 0xc971cd31 0xd4a57180 + 0x5051e5ec 0x193c72eb 0x930332c4 0x488d7403 + 0xa93e425c 0x93e8ca97 0xa0a55070 0xafd8f8fc + 0xc424f1bf 0x11050ed2 0x855d0923 0xa0fcef35 + 0x61f9e84a 0xc2196706 0x7221d5f7 0x96d036a5 + 0x137ca3fb 0xfd632623 0x30b10850 0xdda390eb + 0x270fc9af 0xe6a8d748 0xf55bc288 0x8cc912d1 + 0xf2d9cd15 0x5ded2f07 0x2de9b076 0xf5088354 + 0x885becf4 0x959ef88a 0x0d9ea589 0x2ceb0a27 + 0x8925270e 0xca5ecd99 0x8ba9265c 0x209eb0b7 + 0x2e8b51d8 0xc598e096 0x23c17aa7 0xf600bcae + 0x7b33f831 0x223e1501 0x361c9f12 0xe6aeea94 + 0xa5c6948f 0xd1daf8cc 0x0b0e0b54 0xb0cea6c7 + 0xa437fbc8 0xdb4139ab 0xcbbad47a 0x124e2117 + 0xfb80c5dd 0xef085f4a 0xd24c5fa8 0x2548a1db + 0x5e6cdeb2 0x8e4f0290 0x78cd8245 0x1ebb5eb6 + 0xd9bf1208 0xf20eaf0a 0x544df94d 0xebc9c742 + 0xbc5b4bbe 0x33f6fcaf 0x32efb07a 0x55d91b59 + 0x2c0ed1bf 0x39985cb7 0x4cab882f 0x530cdaca + 0xccc78cfd 0xdd834c48 0x7ce7898d 0xf7458891 + 0x933c2ae8 0xa06c5762 0x2eb03e35 0x8e938b71 + 0x3636f142 0x0026efb8 0x183d71c4 0x7e8ff92a + 0x63265ea6 0x0f1352b8 0x73f8a8fa 0x6594e921 + 0x401f88db 0x64abd8e6 0x994140c7 0xb2258b0c + 0x9bd6e6a1 0x92bab589 0x5919a943 0x29ab4d8e + 0x33cbb8d4 0x57084d92 0x006c4d50 0x57c49e54 + 0xec1ecfe6 0xeaa8109a 0x269d94a5 0x4a664f84 + 0x2bda2944 0xdafb85c7 0x2a7b4b8c 0xd8f124d6 + 0xbbac0e70 0xeac5a129 0x308d7e39 0x99a023a9 + 0xf616fc22 0x76fcc40f 0x7f745409 0x83872303 + 0x0b067846 0xdf90a414 0xb6d9b6e1 0x8d0f93d8 + 0x6f76a627 0x02f89060 0x392cb9e0 0x6acf19a9 + 0x7cffe4d1 0x9928b4a0 0x87a031bf 0xecff42d5 + 0xa376e023 0x69d2e1e3 0x1fb67afd 0x5396049a + 0x45538549 0xec0e6f60 0xf1ab27e5 0xc679e764 + 0xee430c38 0xa6b0c2dc 0x92824db1 0x65d5ffe7 + 0x448b17d7 0x9c67c8e0 0x14b36e2a 0x283de0a8 + 0xc59bb35d 0x8faf1ca7 0x4265db7f 0xb0e74749 + 0x0924d389 0xc22bf3fa 0x017c143d 0x93b4e0d4 + 0xf8aa8e07 0x07e0293d 0x5b40bba8 0x619c8946 + 0xc817ee7a 0x82fd526b 0x3e5b0f9a 0x5b352d98 + 0xc786d63a 0xcbec5c0d 0xd05e9640 0x7cab758e + 0xaa9bd61d 0x205ff53f 0x2f093865 0x55ef390d + 0x4b008d12 0x0344c52d 0x64820f87 0x8e9c5202 + 0xdd3f2276 0xf3b46630 0x80e85ea0 0x9aea428f + 0xa205b11f 0xa8506b8f 0x2c89f419 0xb0b9694b + 0x21029e6a 0x5e05869b 0x3baf3c6f 0xde680ae1 + 0xd65b5eb0 0x99a6937c 0x52a78fe0 0x6f577b06 + 0x8dea8d63 0x2417d49c 0x1a0ecb5d 0x91f22002 + 0xc540298f 0xea9f8f6d 0x01ccfdb5 0x287138c1 + 0xef206774 0x9d5deed8 0xba844833 0xf612317d + 0xe0bd4bb4 0x595d0440 0x73643204 0x2c21370c + 0xf9d5df6e 0x05614527 0x73c4edee 0x33f45ded + 0xbc47170a 0x24b94b30 0xff304e54 0x4e0c3b53 + 0x658af390 0x402418bf 0x9db7318c 0x058721ed + 0x896bdd56 0xa956c5cd 0x3f928400 0x94c93146 + 0x56600758 0xf46f4f66 0xa5bf66d5 0x0e8b5870 + 0x8ba7e755 0x4177fee6 0x32cc8824 0x90b677d8 + 0x307e9dd3 0x853a7e3b 0xa2f064a4 0xa42dbd46 + 0x243ed6a9 0x7164eb1f 0x9e97212a 0x9757d142 + 0xde296a05 0x8699a74a 0xeb02fa7d 0xf80b41fa + 0xd9dd2198 0xd7ffbd00 0x21b15853 0x11b78093 + 0xbb329142 0x5260fb1f 0x22fb24fe 0x7a5e7e71 + 0x71434197 0xc5ddca32 0x930c8cb9 0x65192958 + 0xad1a41f1 0xc77442ca 0x72b64ff7 0xa90bcde5 + 0x184a19de 0x71df036e 0x1b69b0ed 0x023c391f + 0xd9847da5 0xca57d383 0x0d21255d 0x2ea68d9b + 0x0189eeb5 0x1ea62386 0x4c8d42f0 0xac20dd55 + 0xacceef1d 0x972f56e3 0x0bc40455 0x3853c5a7 + 0xcab0d1f5 0x0d2a990b 0x525be1ba 0x5cc6daf5 + 0x4d564f06 0x834d8f94 0xc0c055e1 0xef34557b + 0x354537de 0x7207e6b8 0x659c9298 0xa88ac04e + 0x80d8014a 0x7f4f6e7b 0x1136e621 0xb1b62f79 + 0x8d4613ec 0x673699ee 0xdd6d7741 0xdba1ffa9 + 0xe219e1b3 0x8bf64c21 0x14aadc3b 0xc4dc4e19 + 0x47ae1e52 0xc5409e4b 0xce8d29d8 0xe0b1cf25 + 0xcaf06411 0xd5450dcc 0xf14f29ee 0xf3611dd5 + 0x52bc02f3 0x886b68aa 0x3b2853ef 0x110aafb0 + 0x6b6d765a 0x87fbaa12 0xc79f134e 0x88b910fb + 0xe04aa148 0x33feeccf 0x3be43d3b 0x067854eb + 0xf22561e5 0x56c3abc3 0xcf0ff408 0x6291d940 + 0xe26819d9 0xcfd04da7 0x94ab2808 0x156dcd0a + 0xb6d1c47b 0xdca4aa76 0x877f870d 0x4e06ec17 + 0xbb560b01 0xbe1b62e7 0xd98b51b2 0x7083e3d5 + 0x427ab621 0xe5fce36f 0x606dc14a 0xe4b70b49 + 0x982d2446 0xf2d2e82a 0x60836061 0x681317fe + 0x1667e3c8 0xf6eef490 0x1ad768d2 0xbc86ae5c + 0xfbb392de 0x868caaaf 0x8429b5ff 0x266b6d5b + 0x372e8f2e 0x6e875cce 0x3a972f08 0xabddef20 + 0xc777c559 0xd8f924a4 0xad39137e 0x4c16a4f0 + 0x91d51877 0xae645599 0x4d09feb1 0x0cdededf + 0x5749b5b8 0x513c9745 0xf4da62f7 0x6583b20d + 0xb599bb89 0xaf6bea53 0x7275f6b3 0xdefc5092 + 0x01a3734f 0xd95f4c5f 0x37bce97c 0x63610b99 + 0x30555fe4 0x20af2f26 0xf84b2652 0x67ef6d87 + 0x2119805a 0xcc79747f 0xaa479405 0x63a02857 + 0x1953fc39 0x4f952879 0x886bfe97 0xf0067752 + 0xa08b5005 0xcd9a5ebb 0xb04486e6 0x560c79ae + 0xe8faf52c 0x64a9a961 0xae9a5f1b 0x74cb5ef7 + 0xf8d0269d 0x2fb63c57 0xd78a9a90 0x99cc0a42 + 0x46bb0252 0xe56b026b 0xfb5ff703 0xdc8e0588 + 0xe5d9e280 0xa73ec2b3 0xe21bccb0 0xe22ee743 + 0xd1bb3217 0x5d4b3f92 0x0a627d8b 0xf2fd974a + 0xad0a57c4 0x261ba12e 0x1670f842 0x996ab25d + 0xf6f8043d 0xa6cbb362 0xcac3044e 0x6fe01268 + 0xa54ab676 0x54d7444a 0xf3be5437 0x6b2b737c + 0xbe10300c 0xea505599 0xd60a15f6 0xd971ecc0 + 0x9c480c46 0x2233038d 0x66d38df9 0xcb566912 + 0x63cffade 0x75811ca6 0x8dbfa4cc 0xee5fc07b + 0x23329e49 0x39ee07e5 0x5de33ff1 0x601f8348 + 0xb60a8bc3 0x832d3660 0xd1bee11b 0x1a38d12c + 0xaf00744f 0x21c2639b 0x0fd34252 0xcd63a9f1 + 0x60f34993 0xf8728afe 0x75f8bb5c 0x74a250ca + 0xb9f51490 0x6ac643a6 0x4011a0e5 0x77288317 + 0x57f772b9 0x92c0715c 0xd5d0e030 0xde335025 + 0x669f6b14 0x55c74853 0xf3ac7cd5 0x38284e8c + 0xb0fda481 0xf9b7f045 0x839293cc 0xdf91a0a0 + 0x18d20454 0xf73214fc 0x09577b9d 0xb5febd00 + 0xd9b96c88 0xb454ea2c 0x6204a932 0x736edf8a + 0x9724f56e 0x3092f58d 0xac17cced 0x5ae87e39 + 0x28dd2a0d 0x3806d96f 0x5e7c8c68 0x72df4471 + 0x0207de38 0xf026ecac 0x13258e9a 0x34a8e8ce + 0xdd7d7286 0x8d7553af 0x11ebac36 0xfb9965ff + 0x9beda82d 0x1cd898cf 0x1b791830 0xe96ca8f0 + 0xa0d274d6 0xdd6fea3a 0x7537177f 0xdd93627c + 0x60b64e47 0x10f30724 0x12489cf7 0x4587e1ac + 0xe7835522 0x61d48d9d 0x6afd081d 0xafbbcf2c + 0xe31d79cd 0x49ae4218 0x7c2c4a33 0x4fdf949d + 0x52ccd576 0xef2c3d62 0xfd5b75db 0xe6a5c2e9 + 0x04fc9c6e 0x47fde414 0x8a87ebfa 0x850904e4 + 0x2f49b552 0xb5f186fd 0x772a4ba3 0x48d0be3c + 0x846c7d78 0xc1c2a1d7 0xb9375f9d 0x302ed828 + 0xf79208f1 0x8fdc4f71 0xc749ed51 0x1cd0c28c + 0xee5a5f7e 0x7f02b7ca 0xdc3b531f 0x99c0119d + 0x428e5474 0x10515459 0x8d804d27 0xb7c00220 + 0x264c2695 0x7aa6e5af 0xef807715 0xa444f446 + 0xe51c7755 0xcd825b6c 0x39afa440 0x88638e46 + 0x4ea4366d 0xddfc9854 0x99696f2d 0x210592ea + 0xf4763dcf 0x7358acdb 0xedfc8523 0xe46031c8 + 0xc9762414 0xa71a348b 0x084b6c82 0x9162e0d7 + 0xda6a5b8a 0x68ca14d5 0x6385741f 0xb103d4c2 + 0x44299ef8 0x9aba89fa 0x2c87dcfd 0x476865df + 0x1189dbb2 0xdcd9d19c 0xac2bbd51 0xa71526f5 + 0x745222d7 0x4813ca98 0xcfa5802c 0x5d2b3907 + 0x8a17d1b8 0xea56f907 0x3ea58d71 0x933fa242 + 0x021f46a7 0xab8d4e86 0xfa4eb33e 0xaecbd5c3 + 0xb3258e74 0xaac9f193 0x415a5518 0x28b13031 + 0xbae39e53 0x1072fd5a 0x4e0fbf55 0xb02c5d77 + 0x5949c780 0xbecf72df 0x15e52c72 0x3ffeb165 + 0xa8e73d50 0xa52fd918 0x2b3c4d7c 0xa1e9e021 + 0xd8e91949 0x63bf63ed 0x8f2e150a 0x9cbceca9 + 0x33b10a97 0x4d2c69f7 0xf26371bf 0x0b5214ec + 0x10eb7fca 0x1958b429 0x25f190be 0xafcfb396 + 0x7aec0c45 0xf9a0f163 0x9c966818 0x28f83619 + 0xe35c61d4 0x1ad8a656 0x576dba63 0x7aa44804 + 0xf941b7b8 0xc5faf3cc 0xdf1fd628 0xc009417b + 0x366ea78d 0xd3cb7030 0xf3f12e97 0x5298cc89 + 0xbb43c8ef 0xd0a8ef96 0x564bced6 0xbcbd865c + 0x5c80b1d7 0x131ccb04 0x7502d06e 0x465f5cb0 + 0x93320c4c 0x9df42986 0xbdb1fe26 0x48ae8bdd + 0xaf44e912 0x6aa468a5 0x67ecbb05 0x30b7c0a5 + 0x3ad75711 0xa2d5f63c 0x30150058 0x4d748121 + 0x70804875 0xf46b6ea6 0xa3fcbb7b 0x1af6b4c4 + 0x48496de1 0xdb1a2321 0x758eb79a 0xf35f697f + 0xb4ff9dfa 0x38ab5b31 0xc918f6f1 0xb3a259fb + 0x3610afe7 0xdfcaaa0b 0x00c747dc 0x96c40b4a + 0x5c815168 0x29198fee 0xc94eeea9 0x70432b55 + 0x5de7bbd4 0x0995652d 0x4b3e846c 0x7e4c9ca1 + 0x7c0e91e6 0x401a820e 0x3ca3429a 0xd3812f44 + 0x9cb6a5eb 0xf03ce395 0xefca548b 0x8943bc10 + 0x472b2108 0x82d4a386 0x1d0ef931 0x94cd70ef + 0x2d00d619 0x40d36f80 0x238ccc47 0xe0856568 + 0x9f06ad8b 0x95a4052f 0x287a57fb 0x9e9f9891 + 0x62bc3a31 0x24c3c1f8 0xbabdc3c4 0xfa40629d + 0xd16f1f33 0xa9f7600d 0xbcbdb2d9 0x214f24be + 0x623ea3b0 0x8d650418 0xe86635b7 0xb834745f + 0x20771340 0x3c69a0b2 0x8b7c84cc 0x740e475c + 0xe5a540eb 0x9e216852 0x1383201e 0xfbf1f572 + 0x9680d736 0x3d7f8d69 0x615ea313 0x87bc1297 + 0xe552725c 0x9bfee104 0xf2e87d90 0xde9188b4 + 0x028d268b 0x51c75c60 0xed93377f 0xc380d9d9 + 0xe858bf8c 0x5d0b4a40 0x05a3171f 0x76ae3ec0 + 0xf86e3fe6 0xc3d78254 0x7cd640c5 0x6835dacb + 0x983bd9a8 0x05d1e564 0xc5d5e9b3 0xf81c6560 + 0x8ecba474 0x071daa33 0xf5010276 0x5432ba59 + 0x10f2dbc1 0xbe892680 0x7e92d3d7 0x8d2f0113 + 0x37fa8034 0xb13058f4 0x44684553 0x2bd0e36a + 0x67ea83ef 0x815e7115 0x3cd123af 0xd9aec852 + 0x67c61c95 0x861d068a 0x60c7797e 0xd9733b31 + 0x9ed29f37 0x1ccc8e08 0x34bcfa7f 0x1c66914d + 0xc64dc834 0xad884c08 0x2b22b8de 0x53d6fd78 + 0x0355dcc8 0xfd363485 0x62370358 0x0dcb046d + 0x22fe7d2f 0x5fdd1117 0xccd6d8d1 0xe97925a4 + 0x309aca3d 0x56c31fb9 0xe6f81e08 0x24fc0560 + 0xa78d459b 0x4940b35b 0x9a4a2fdb 0x203eafb8 + 0x91e5fcab 0xfb9be08e 0x9cb903ac 0x31598d89 + 0x4f41986c 0x77206f4e 0x61811c9d 0xff51d95b + 0x2d7b4c66 0x84ceb768 0xfb135597 0x58087b13 + 0xa1681cc2 0x14009e31 0x778c3fec 0xe3faf2fb + 0x5092b2c9 0x8919c362 0x34e2b174 0x7bb04f44 + 0x63c39b5e 0x8ef696ff 0x2e4c612d 0x77d390e2 + 0x5dc958a1 0x528bb31a 0x1cb07e7a 0xe37c9c53 + 0x002856d7 0x6a10b962 0x423a7b39 0xc6da9227 + 0x207800e9 0xe200c119 0x0e5af6f3 0xfb580459 + 0x71dc40a0 0x70434cd9 0x13f7f455 0xdf3fd7ca + 0x37cbc698 0xf5a5808d 0xa7bfdf32 0x8a0774c7 + 0x75b67d50 0x5a6908c9 0x23611a6d 0x8b50c483 + 0xfe1e2eba 0x7ee1c732 0x2191e47f 0x9e63eb3a + 0x379cd875 0x4df7258d 0x166a8aa8 0x1c94586a + 0x2456c4d3 0x000185fa 0x7a196b46 0x914e789c + 0xf562c939 0xb3bad5db 0xc2c19b89 0x8a621ffd + 0x0c807ce0 0x701a938f 0x69234cdd 0x36a00f09 + 0x964c43f7 0xcf71cd85 0x5f504e16 0x446c6388 + 0x25742397 0xf1a375c8 0x6bcf822c 0x1b175fd7 + 0x0fe78e56 0xfe7817d6 0x66da0366 0x904e8327 + 0x5a0749fa 0xef3ede57 0xd0fa2ac8 0x89791771 + 0xa5cd616f 0xe9ef2860 0x9b533bc3 0x1d746f03 + 0xf4bb82b5 0xacae0438 0x840b3e34 0x30371a0d + 0x8590acf3 0xeb4ff7e4 0x40437052 0xba847bf6 + 0x24059538 0x44daca63 0x23b32e28 0x091386e0 + 0xc480e66a 0xe4a839f5 0x34929bcc 0xb9051207 + 0xd21252f9 0xc6524769 0x8c422851 0x36280aad + 0xbf00b1a1 0x4e36c85d 0x7949e8ef 0xf76be57e + 0x373a0ab9 0x1b7555a0 0x0c2caf56 0xc9241f75 + 0xbe5b0ee8 0x5a486f75 0xfb2c050d 0x6aeda464 + 0x3fa744ee 0xf6e055a1 0x0a7324ab 0xfab58776 + 0x09baaf66 0x459ce186 0xc6eb1894 0x56a4ce4a + 0x58ce1069 0xf4debf5e 0x04a145b9 0x1a246583 + 0x9b07fe23 0xd4d37068 0x7321e0bf 0x2dfe17f3 + 0x426dd8a7 0xc561a2d5 0x7f515a47 0xe57d37fa + 0xa85f0aa5 0xffb78cd7 0xf30c4551 0x3572c02b + 0x6f4a4cbd 0x7322ecc7 0x170a7b9a 0xa1e80d28 + 0x5a366af2 0x4f24a3a7 0xfefd29ca 0x0d7b02dc + 0x1adde2e1 0x5c426cc5 0xb1e53b76 0x5dba2c5c + 0x1458b6ca 0x73cea912 0x39626c25 0x7547e76d + 0xfcddbb97 0xf03d59ee 0x3cfdab3d 0x309db86e + 0x3de8df47 0x4a570e6d 0x09c9579a 0x19ac033e + 0x0a7a9a86 0x3662d261 0x048fa67f 0x4aa4009e + 0xc7660654 0x524d81f1 0x3157ec52 0x857d1f10 + 0x3770162e 0x3d1ff919 0x732d2b13 0x84187da0 + 0x95722d45 0x362cada5 0x5d67637f 0xdaae8465 + 0x9f5c0699 0xab9aba98 0x6f97d3fa 0xf9cc4120 + 0x0ca1872c 0x1a832c9e 0x7b74d6ae 0x98dca967 + 0x03eb7699 0x5fd02b54 0x962c6224 0xde1ab807 + 0x800af435 0x2458a4ca 0x717de910 0x31648afc + 0x871527de 0x3cb93892 0x45237e37 0x446b1315 + 0xecd807e8 0x70f38e30 0x140dc60e 0xaef7b7c1 + 0xadec312e 0x94d45820 0xb8960073 0xe8dd5bac + 0x7616ab11 0x0c3cc190 0x516003e3 0x323cdb39 + 0xd679f9f4 0xd7c179d2 0xdfbc5e24 0xaa1226df + 0x3cd41b0e 0x88f436f0 0xbd5b6cb1 0xb78c69aa + 0x982e0ca0 0x91f852a3 0xb331636a 0x28df67ee + 0x81b029a1 0x9e7375e3 0x56e874c0 0x8b93a735 + 0xa47eaa4e 0x772ad825 0xfb83ba8b 0xc08db79a + 0xcb7a34be 0x14214d72 0x7d6fa82e 0xe75c7002 + 0xa6290902 0x716d04c1 0xc75f0a97 0xb68e0912 + 0x08b5ef1b 0x507ecac3 0x2d740b08 0x43b6c7bf + 0x3965675a 0xf56dc4fd 0x1ba44239 0x36753f70 + 0x0b2452fc 0xe36bafe9 0xfc3134c3 0x2ac78286 + 0x69ba53b8 0x225b9bd9 0xaf426f79 0x99bd2d3e + 0x0bcb8e18 0x28c87047 0x2045b3b9 0x730ec870 + 0xe6558839 0x9ca3de82 0x263a41e7 0x1c8ea255 + 0x334eb3ad 0xc36d6793 0x66add8ee 0x652c8548 + 0x79dca1a8 0xc2526972 0xd10f03e2 0xdbae6f42 + 0xe223bf69 0x10082495 0x74ba4cf9 0xeb71ef5f + 0xafae5d4e 0x7b3663e9 0x9339468c 0x31edca72 + 0x65a07876 0xf336fc1a 0xaa505397 0x011d5253 + 0x99b88ade 0xa688f0fa 0xedac589d 0xab4d8f45 + 0x0ff866a1 0x61280e9b 0x65c5a63f 0x8b372073 + 0x7a4c88df 0xc74f7959 0x19597c51 0x97c8a27f + 0x33eb652a 0xffd40c86 0x57a2ca0c 0xaabc6cc8 + 0x54fd2280 0xd5b59006 0x2e00f009 0x72bd86c4 + 0x24936e04 0x877188de 0x91b60401 0xb949b337 + 0xdab93e69 0xdffeab2e 0xb3aa7c79 0xb8612f31 + 0xf0c53b58 0x8896833f 0xda35944a 0x1867027a + 0xef6bfce9 0x8213f320 0xac477eb2 0x92368362 + 0x606cfdc4 0x27c98907 0x50673ac5 0xec48f5f4 + 0x39e879f8 0x80d050c8 0x9febddbe 0x5d797725 + 0x06d8b755 0x0319d93d 0x7eae3ce5 0x8963ed64 + 0xc91772c9 0x4e031095 0x2fd03d3e 0xe774ea89 + 0x7dbc97ab 0xe8d8f361 0x6e167fa1 0xd1520c5a + 0xb3278325 0x8acaf913 0x6ea81dd4 0x9e3b2a97 + 0x0a5b8a09 0x84000db1 0x59a30fa9 0xf0b6868d + 0xfb62b0ed 0x8953057f 0xdbbca3c0 0xc103b876 + 0x47420e14 0x1eb22bed 0x58c8f65e 0x3a689da6 + 0x8ed1a99c 0x869ddc49 0x60015d09 0x2264c797 + 0xdc10c6ac 0x7275327e 0x8d47d2ab 0x87a75624 + 0x3dd8fcb6 0x40e67a31 0x98114b1f 0x7e3a5976 + 0x1d9e62a6 0x988c0398 0x0c7c0d8d 0x0aad4954 + 0x3c40a234 0x7b752b7b 0x79f94813 0xa0b86dec + 0xe3f646ac 0xa993f76a 0x6f9d1f99 0xe883dabf + 0xb8ab1b2d 0x6766ac8d 0x6b9a793a 0x02f55fa5 + 0x351a96ad 0xd190f768 0x35667fe0 0x6a85c938 + 0x72444e33 0x5140a848 0xd3062250 0xe4ce902a + 0x44e7d9d3 0x7c8d48fe 0x4d26a61d 0xbd013c4b + 0x540d32bb 0x9152cafd 0x09840a30 0xd7a8663a + 0xd5a3ca17 0xfd5dbe65 0x655b226f 0x7cb9debc + 0x59d300dd 0x13737132 0xdf0d004f 0xe98bbd9e + 0x5626fb54 0xb6d66fbd 0x273087a8 0x032969ea + 0xbd69c191 0x010cdfff 0xb2a9cea5 0xb8778e4c + 0x8f0dd084 0xc75b4ce6 0x9c027c6f 0x36c58105 + 0xac424eb8 0xa15d2883 0x9e73b7b8 0x54e9aade + 0xb9500a5a 0x97505e35 0x4c59b36c 0xb3ad1302 + 0x31e21ed1 0x78bcd74e 0x2d9fc122 0x49bae35e + 0x5c8f01c0 0x8d29829c 0x0c672566 0x37938db5 + 0x4959e71f 0x0d2365bf 0xaab666b9 0x52b2cffc + 0x200ee1f5 0x5dbb262b 0x9aae28df 0x3223780a + 0xb65218cd 0x633b797d 0x93f42423 0x3268b3ae + 0x141e506e 0xb1ed94b2 0x497b7973 0x9f2db9f6 + 0x5260bf9d 0xb30e4310 0x4a3539ec 0x275d2ae2 + 0xff43e500 0x645e30e5 0xf1527598 0xb76ec4cf + 0x88fc44e9 0xde68932c 0xe61aff6b 0x19d042b6 + 0x11981ff8 0xb0d595d9 0x52764f82 0x7e0ca214 + 0x8cc51237 0x581f2a1a 0x482420b3 0xd47ff971 + 0xcff78344 0xc019eca7 0x3146ab02 0x107a3ee4 + 0x16dc120d 0x33a239ec 0x0ea84236 0xebc7a1f4 + 0xd1f2fa2a 0x9464c008 0x2b76a4fd 0x9b4acb99 + 0x00f6a92a 0xd68b8d15 0x25e1e58d 0xe1fe3cd1 + 0x6fbce2cd 0xf78be2dd 0x09b9c08d 0x6b32d210 + 0xd06e7c95 0xd62f47f4 0x92c717ca 0x44fe3d2d + 0xaa13cc08 0x3d411f94 0xc2eba262 0x7521c9e4 + 0x77d6cdc7 0x22d76158 0xca2efacf 0x3e51004c + 0xef9a82d6 0x1508d20c 0x923f18ff 0x3eaa88e6 + 0xf2f32bc7 0xe74b8483 0x82529884 0x58b38ad8 + 0xdd9f2a5f 0xdf54adc3 0xd4497667 0x789c000b + 0x935d1743 0xa52d5f1a 0x4e27adf6 0x5c3334af + 0x6cf71ba0 0x501f8353 0x031fd6cd 0x4831ec4f + 0x08c847db 0x6a6e0657 0x0bd803d4 0xd7c48cfe + 0x94b7e25f 0xc6516ebe 0x1001c08a 0x0e165da9 + 0x4e39605f 0xe3f3637a 0x013daae9 0x217168b0 + 0x6013ab5f 0xd5b7eb97 0x8ce6b6ef 0xc4259f29 + 0x470e90a9 0x7a254ff5 0x8dcbf841 0xa2541a7f + 0x4880c5ea 0x28c750ea 0x043a0200 0xbeb9653c + 0x46e354d1 0x64f7104e 0x05a64bf3 0x7db42752 + 0xbbd38c7b 0xca7da1d9 0x916c7ebf 0x1df5e3e1 + 0xef0897f5 0xd0456a5c 0x629b50a3 0x8caefdc3 + 0xddbf8b94 0xf6e6b341 0xd8ce3e02 0x27c96419 + 0xb2659ab5 0xe8d576df 0x9f136353 0x6f5230f5 + 0x68417adc 0x39b65378 0x4b742f21 0x96d071b1 + 0xeb046da9 0x245ecb46 0xc17eeec3 0xd7c56615 + 0x07df9b8c 0x647ee4f4 0xf15f7e7b 0x825b87eb + 0xdc67dd20 0x43c38867 0x977868ca 0x3a299ef2 + 0xa75073f7 0x2dcd59e6 0xc6c78c75 0x63a00767 + 0x74dfba2d 0x7880c7da 0x83f72bc6 0xa9750166 + 0x716b3abe 0xc949a1ea 0x7e5fc036 0x574ee475 + 0x39c3cae9 0x8c1dacdb 0x640fcc41 0xc69437e8 + 0x5d33a950 0xa28e483a 0x4031cf9b 0x0007e3be + 0x6e3f277f 0xe25d3025 0xdcbc4a0a 0x7451a537 + 0xb372169f 0x21ff0e91 0x1978aa74 0x6471624e + 0x01a03f20 0xeb391a3c 0x70d18ad5 0x47c9ddcf + 0xd9415b2f 0xd9ea29ce 0xffa0677e 0xeff7a04d + 0x1d384ff4 0x66195704 0x22736810 0xad754f27 + 0x782ae9bb 0xffed05b6 0x5ae3f21d 0x5eb2c577 + 0x0101cf91 0xed0322ad 0x56ac50c8 0xc513b1c6 + 0x4f62ba8b 0xbaffd6b6 0x6649baa2 0x8702464e + 0x78947007 0xd6e97d6e 0xde7c6abf 0x2bdee498 + 0xcee1db1a 0xb98149de 0x47f32f5c 0xc6c354fc + 0x6e148fad 0xb343cf2f 0xeac6a9f0 0x33dd1560 + 0x923403bb 0x87d6e292 0x0b1cf653 0xe8b76402 + 0x5f21a955 0x236dec28 0x214663fd 0x1917539e + 0x3f11ce80 0x1bb35a2c 0x38a358f1 0x15f67224 + 0xc65394f9 0x63cd4887 0xe8e73d2b 0x51b6204a + 0x8eeae8f5 0x6e071c8f 0x55c23dca 0x4862eaee + 0x0afa0037 0xc98446f3 0x09181a1c 0x41e46e02 + 0xcf13d6b9 0x85907776 0x30116b18 0x27b8c7b1 + 0xd153a5ce 0xc95c90b2 0x34392718 0x8103dbe4 + 0xe012a7be 0x6aeb8c6a 0x5bbaddbe 0x221eab21 + 0xaf769239 0x2621a689 0xe8c41061 0x5890f76b + 0x2c4dadd4 0x2ad2e669 0x394209b5 0xb272b2ef + 0x560031cb 0x4ab7be9c 0xcc5e92e4 0xc0de0667 + 0x7a39cf63 0x03482c6e 0xd653de11 0xe14466e1 + 0xf2dbaf25 0xc34d1c0c 0x03eeb3e3 0x8260874f + 0xf6e2ef37 0x13626fba 0x15b7efe4 0x069cd153 + 0xbf631788 0x797668a9 0x724d831a 0x0ceeb589 + 0x9559cd31 0xb995d2d2 0x7564c4ef 0xfc45a3dc + 0x1cd999e3 0xbe090229 0xab4f9383 0x879156a0 + 0x06e1d37b 0x3796487a 0xaf1e3884 0x1f9a59ef + 0x6c2d8a7b 0x0a8a5ffc 0x4cd60f03 0xa60bfc63 + 0xf67c6872 0xf19b75cf 0x041cc864 0xc563566f + 0x58ae88a0 0x3747b0c1 0x64cd86fa 0xed185c5a + 0xb71533c9 0xf15672fa 0x2722d209 0xb71ec7d7 + 0x3143a8a5 0x61c18934 0x3a899ec5 0x4274f336 + 0xea7c52a9 0x9193cd11 0x44c471e7 0x57fff360 + 0x53923783 0x76d57ce6 0xbff32513 0x4dbe0d39 + 0xb9f80483 0x62ce4d25 0x5941e9fb 0x7dfedfe1 + 0xa33f9130 0x336e6539 0x1de31e79 0xb6855a41 + 0x4db2db67 0x02a9f1ed 0x019bcf20 0x53ad0ce3 + 0x4d049f95 0xa9de2c6f 0xa26f6997 0x28eafacb + 0xa5220548 0xb4675e1b 0xe776ee88 0xc93e6c37 + 0x7868630d 0x1690625e 0x6eba0fd4 0x78f598ff + 0x113fa1b7 0xcb025590 0x2ee34123 0x92241df5 + 0x6edbf0b2 0x3bc2e0a7 0x710ce59f 0x656f0eb7 + 0xa598424e 0xeca53268 0xb6a44542 0x5bf6674f + 0xad483960 0x35290b93 0xfba74c81 0x78141ea2 + 0xd6baf9e7 0x8e5a08e6 0x4910c5b0 0x7b140d21 + 0x1958c79e 0x0dbed125 0xcfbe41dc 0x089fc4ab + 0xbf014fa7 0xff961610 0x7a2ae6c3 0x560d3a9c + 0x2cd77620 0x3a7c15cb 0x9464d8f1 0x249a93ff + 0x96fe6c56 0x7231a31c 0x4bcdadd7 0x62edd9f4 + 0x8ad1916c 0x3a5fbc8d 0x2a2ccd7a 0x558980b1 + 0xb0137cfa 0x3cae6929 0x587c349c 0xbcfee701 + 0xbddd49df 0xa0da6dbe 0x4cb03dac 0x5f84ba2d + 0x7fb3063c 0x66de2150 0xbf7dbcf2 0x1c0892aa + 0x4be8b0ae 0x5d9845ab 0xa21455af 0xc42f2e68 + 0x9b6f438f 0x5eaf4941 0xabbf9079 0x94984a47 + 0x542bdea4 0x34cf3d67 0x854010a4 0xf39a9b19 + 0xd25ffb6a 0x04364e75 0x0af97ef8 0xe10e3620 + 0x2184d002 0x0c0ca683 0xc19963c6 0x4c428d15 + 0x47ae4151 0xd11ea57c 0x437a9ed6 0x50a6b8a2 + 0x141b16e9 0xeb4ae873 0xb51180fa 0xe3dc318d + 0x7744a06f 0x64d297d2 0x845fac66 0x5854d172 + 0xc14dbe9d 0xccba053f 0x4620a715 0x405d728f + 0x28b86cec 0xcba09cdc 0x92823f94 0xeae2664c + 0x48eda6ae 0x4b60f5f6 0x1772f309 0x8af285bf + 0x9c3ae474 0x13149ebf 0x2bc835c2 0xafcaa560 + 0xc11b6f91 0x94861d9a 0x089c0d82 0x1e04d66d + 0xf0e497fb 0x6b2d8b6a 0x9d7f0cae 0x4a93ba71 + 0x1c006123 0xed4b5f75 0x76e7826d 0x4f884ba9 + 0xbba28011 0x1e275278 0xfa72461d 0x7e70e215 + 0x1427ba3c 0x467e4f3c 0x781c5f92 0x357b7951 + 0x9de2cce4 0x524a0de6 0x12e15f95 0x7b64fae0 + 0xf27e93cf 0xc6f48158 0x9b71dbd6 0x081dc1b3 + 0x47c9c2c8 0xf110add7 0x7881b556 0x0404bf1c + 0x58e7d936 0x04442173 0xe1e7f0cc 0x128ce897 + 0x169c0a11 0xf30b5575 0xf2ac0bab 0x91515620 + 0xe8b809b0 0x2a73d5a0 0x9ed32dae 0xcf943a47 + 0xfc157bf9 0x1a53054d 0xf0657e2f 0xf39f6ea7 + 0x92a5834a 0xcdca0c13 0x40a7b40e 0xba0e0cdd + 0x72f595c3 0x6b7eeaf3 0x4d0fd8ed 0x9a856082 + 0xd75402c8 0xe0f8d3b9 0xee57a2a5 0xe1ccf4a7 + 0xa4fc4fa6 0x9f2407c7 0x75f94c0e 0xbf2361de + 0x2d3b4782 0x72c35e50 0xb97f7d4e 0xbc880223 + 0xb0b24073 0x08931201 0x40e0d18b 0x559db40c + 0x6216a921 0x031a379c 0x29bff1ac 0x1c522c12 + 0x583bfe94 0x2519ba2a 0xd691d08e 0x905dc62f + 0x43b421b0 0xd45caaa0 0x5f099da2 0x012fc4a5 + 0x509712b3 0x67e5d441 0xc843de50 0x7e1c756f + 0x91368900 0xc6ec0dd4 0xa41e838f 0x58eabda5 + 0xd6ad78a9 0xa037b655 0x8af4e767 0xa9b95900 + 0xdcf1780e 0x64e28d82 0x215ad981 0x292dfcc3 + 0x708d8557 0x0a507562 0x486022ad 0x8165bc7e + 0xabffce1d 0x78fbe480 0x77b916f6 0x88f8167d + 0xae8b8edb 0x62698ab6 0xdbc6bbbd 0x001819a6 + 0x8c096fb3 0x40a121e9 0x7b96a718 0xf6d256ed + 0xe5c0a484 0xa09bd764 0x6552b5a2 0x1847ae3f + 0x0669a650 0xccabc209 0x85246d20 0x61158f3c + 0x379d8086 0x02135988 0x1eccc6db 0xf8f38c67 + 0x8e1b0f3d 0x0f6e87e5 0x936bbb84 0xe04839eb + 0xe26b3e5c 0x3f35ffda 0x4920e752 0x014c876a + 0x25189061 0xbe2bc4ec 0xbb2ca0f2 0xe2c1c9b0 + 0x747df643 0x26da8dbd 0xdacc3c8a 0x7d93b22a + 0x922d9a0a 0xf82d65b6 0xd56e5f35 0x7aea7534 + 0xf1808648 0xdfa7ec9a 0xff00f8c6 0x69091da7 + 0xbb478c83 0x64e24ae6 0xf2371faf 0xcff5732a + 0x4da88e73 0x9c8494df 0x4c0da767 0x3e22bd67 + 0x059298eb 0x9d7611ce 0x74b4a198 0xbcbe440c + 0xe2bb1a9f 0x0ba3e5f7 0x65a5cf9c 0x8b24b6f4 + 0x7784ca5c 0x24ffc234 0xece71bbd 0x36f8e876 + 0x1b55d68b 0x2b9163a5 0xaf8be424 0x958eeaef + 0x5d711c41 0x66d11cbe 0xfce42868 0x4a3c819c + 0xf66d295c 0x629402f7 0x64b2ee3d 0xc0b74538 + 0xe93a735d 0x3b9e807f 0xd1d0d7c8 0x69588f34 + 0xae92b6fe 0xf5508d03 0x45b6ccd6 0xf85a18c6 + 0xe1a28a53 0x438f9a35 0xf4fe84dd 0xe3f95791 + 0x16860340 0xefe72aee 0xb13575c6 0x3d730481 + 0x3cf2a43e 0xa6ed239e 0xd7529176 0x8ad63f3f + 0x5efe8f4d 0xe9cad7df 0x44fefef4 0xc7198f50 + 0x85aabf5c 0x15c175c2 0x26f7a0cf 0xf06782f0 + 0x4dfadfa7 0xbc57a087 0x21406f0b 0x692a8f18 + 0xd17a358b 0x19d1b2a6 0x6c35022e 0x87d8c987 + 0xe7f2d06c 0x91c4daa6 0x4a132822 0x1e864671 + 0x5cbf0c4d 0x6a34f073 0x1c87a8e5 0xb38f1717 + 0x1cac430b 0xf733ee6e 0xdf73201f 0x71026328 + 0xee976531 0x661c9d28 0xdeefcd7f 0xdefb4607 + 0xfca9ef3a 0x3e1b9b38 0xd204c892 0x6b059f5f + 0xd5b8665f 0x4eec24fd 0x09b21b40 0x364c708c + 0xebe0d543 0xc3d64eed 0x8facb895 0x8f415f31 + 0x3dd25b0b 0x95f4072e 0x85e6f4c1 0x3345e2a5 + 0xa56e8dcf 0x3ed8df67 0xa8194a81 0xafe613c7 + 0x384b25b9 0xe7661836 0x5ad6476d 0xeb0ae982 + 0x19afdf2f 0x4efb8658 0xff07e358 0x96c469d2 + 0xf3030add 0xf5bf5b51 0xba03b24c 0xcb77143f + 0x134fba20 0xa126558a 0x193cd220 0x48f43727 + 0x156f2b18 0x4e599917 0xc3ac4eac 0xcc460648 + 0x67974a2a 0xe2917a7a 0x02998a74 0x470c60d1 + 0xbacbc868 0xfef38d84 0x3e4597a9 0xa1723ab7 + 0x8ffed7b2 0xe489b151 0x34b982fa 0xf67bf8ce + 0x043cbb33 0xe3927c98 0x3c8fb221 0xbff0644a + 0x886d333c 0x1f4cd6b7 0xe9b744f0 0x443ef364 + 0x04847d65 0xf3c2ba04 0x60a8e656 0xab4dca06 + 0x620dbf22 0x5b0221e5 0x877973ab 0x128b5a6a + 0x4696b5d7 0x8f034e85 0x18796215 0x8579ec7c + 0xf8917eae 0xa98bffce 0xfc67e9de 0xa897445e + 0x2f115777 0x990bfb90 0x1de53f71 0xfa2e5c1f + 0x24a5b882 0x0f871a5b 0xe7fc33a0 0x6927a106 + 0xb210bc90 0x2ef851de 0x09629147 0x2553882d + 0x77393353 0xeacf977e 0x470198f7 0xb7564a05 + 0x4d575fb4 0x1d980371 0x0feeebba 0x26ba3c12 + 0x17b21567 0xfb664d1d 0xcee1a603 0xa8881580 + 0x8a47e853 0x6511027f 0x734f6fd7 0x2977b345 + 0x7465e47c 0x0e3c4c8c 0x3185ac04 0x2450ea5d + 0xa6e97dba 0xf52b2f4b 0x328ac24f 0x5a507ad2 + 0xac05d4f7 0xca332e1e 0x44b6cdd5 0xe22b049b + 0x55b885d1 0x71144ba1 0xf57284d9 0x76cb0900 + 0x8266cfae 0x82bb0271 0xfe547080 0x53e4dac9 + 0x0546dcb9 0xa09a8de0 0xd55d15a9 0x7a3a96ad + 0xd23c33ed 0x7a8fa769 0xa0542b10 0xdaf92f2c + 0xd6433b0e 0xad7cf7b9 0x72c54814 0x38ff5c07 + 0xddee72d7 0x6c29582d 0xa1574da8 0x418272ea + 0x0a9e21f3 0xa34bb5ea 0x1e78630b 0x9238d5d2 + 0x7cfa682f 0x6e8e841b 0xa4b3d17d 0x70b6d075 + 0x704db3f8 0x76aa7d19 0x1cd3e85b 0x2ae7fa63 + 0x5ff0dad0 0xdd92c129 0xce7d884a 0xa7ba03ab + 0x3b366560 0xfeaf75c5 0xd08856c3 0x01ffbced + 0x089aa8a3 0x2e4b36f1 0x03955648 0x882468ba + 0x534abc87 0x28c08402 0xa7512f6a 0x1fab044e + 0x6595e159 0x92fdef27 0xa0b6093a 0x5fdb5f3e + 0xd0facb7d 0x512a8b83 0xd7f31adc 0x82166318 + 0xf9ad7f02 0x9120b349 0xab744947 0x2787d6bf + 0x489e3546 0x02a7ce3b 0xd3812409 0x819a092d + 0x94a48db8 0x49d8dff3 0xdd4e9b5f 0x330d32d0 + 0x203cad0d 0xace20075 0xfd019f42 0x1cc56871 + 0xe53e452b 0x51e7c9e6 0x1d6732c7 0x03694ca7 + 0x900ecdb4 0x3251d119 0x2c4a0669 0x3243bb5e + 0xb434326f 0xd6eb26b8 0x8ceb7328 0xff30d7e3 + 0x861fa43d 0x15386557 0x3fa11d24 0x86590299 + 0xc3cbd319 0x8d1031a5 0x80db9f63 0x9d957321 + 0xdec927f4 0x1468a2a1 0xff1b8842 0x4c403eed + 0x62140459 0x912ddd25 0x36252404 0x49052d26 + 0x22205558 0x53773ca0 0x3428d400 0x51002834 + 0x6b5baa18 0x838bcf14 0x30d09ce0 0xf1c456bd + 0xb1fc90c1 0x525dbb0f 0x64a9105e 0xe0a5cc89 + 0x293f2441 0x335b1c7d 0x55842eff 0x6c7f60dc + 0x903fd793 0x868589ef 0x50a596a6 0x337c6988 + 0xb7a670a9 0xa46b1a8d 0xdf8c013c 0x3dcdfd02 + 0x01075847 0x06c3a7e6 0xc8f22594 0xfcd94f04 + 0x8b6ddbbb 0x5a138f6a 0xf43d2cca 0xcf4df232 + 0x088cddf4 0x9adce26d 0xee803f2c 0xedf042d5 + 0x7d738c39 0x8f02cc34 0x3f964043 0xbfae17d7 + 0x5f2dd670 0x177a9f36 0xf0e1dc28 0x07082ed9 + 0x90534419 0xf03db66a 0xb8ccbbbf 0x739d2ae4 + 0x3509b32d 0xf0105125 0x2d603572 0xbd1a6b64 + 0x50959fe9 0x26100668 0x758e250c 0x9b372d1b + 0x0f1e1bde 0xd53edd46 0x0187d6e6 0xd0158da6 + 0x05dd0922 0x3fc0a182 0xd7f70ebd 0xeeda22e1 + 0x1c7f99ad 0x9b39bee9 0xf101d67c 0x1ffea21d + 0x5494b799 0x787a77ca 0xe8908c34 0xdd00d1db + 0x25e21bcc 0x30bf0b70 0xd8cd0350 0x96f2d414 + 0xa9a4cb6d 0xa3f3c207 0x2db5c7bf 0x88e8837b + 0xb157189a 0xb9fb869e 0x48c2a7b3 0xf5e0c692 + 0xf9103c12 0x6c590e9a 0x7e0aac34 0x97392b87 + 0x8e6c201b 0xc6d68ddb 0xb5fbaf0a 0x1f8e411f + 0x6355e9d9 0x05fcca55 0x9b0250dc 0xec9c5d7d + 0x668075bd 0xb93078f1 0xcefa1755 0x216c5e0c + 0xa83ae6b5 0x748bff79 0xfee9e797 0xc6acb230 + 0x1243bc06 0xfee350e0 0x3ee5f8e0 0x0508fb60 + 0x87d9d24d 0x0b54ac94 0xfc37c8fc 0xe9958f2f + 0x3a927f73 0x04933b6a 0xa195a6dd 0xda96dca3 + 0x9c1799c4 0xd055fc63 0x05deebbd 0x2b5400fb + 0xf157f110 0x80b1e79a 0xd7f1e4b7 0x5a1fab0d + 0xbaaa81c3 0xa42489e8 0x594a791a 0x29f18382 + 0xe86f0358 0x5aa5f4b0 0xa682993b 0xedbfc5b7 + 0xf1eac55d 0x9b1716bc 0x907d9d1e 0xb2205254 + 0x4fbba0f3 0xacea63a4 0xc518d83b 0x8449fef8 + 0x80b4f69b 0x95dc7429 0x16c22c9b 0x6e116239 + 0x4c4bfd11 0x56f159fa 0x60cbb0a5 0xa2f4721f + 0xa829cf9b 0x5ddbb3af 0x2db824cf 0xe82f3fd1 + 0xe5dcb2db 0x185fe7af 0x0775003d 0x38669aba + 0x7b540eea 0x94ce3d10 0xba77f357 0x63507853 + 0xb50ebb0c 0xb614739b 0xea3a3c47 0xf2b6176a + 0xf805b28d 0xdd0819b7 0x9f4b2799 0x18bdadb8 + 0x7d58d588 0xc4f0994a 0xef834870 0xef2d6ce4 + 0x97a36a52 0xb6e581e6 0xddd9aa9b 0x6437d4e8 + 0x43f74dc5 0x8cbbd744 0xf394a2a0 0x4a1e7f75 + 0x395bd36f 0x27a8f9e9 0xed62f4a5 0x7c2f0484 + 0xf394f837 0x5f69d50e 0x86ef57af 0x7af052f0 + 0x85dee180 0x125f56fa 0x87291494 0x141931ac + 0xabca9ae0 0xbc1e4e4d 0x541e2edf 0xa3551bb4 + 0xed2766fd 0xf6e778c2 0x3a82644f 0x67c47659 + 0xb81b826c 0xb11603ee 0xba6cc507 0x691fdb74 + 0x06507f6e 0x64ef2a0f 0xebd9b51d 0xee620487 + 0x82991d7c 0x1493fed5 0x08af819e 0x7066de45 + 0xdeee1600 0xde12b903 0xe572ced5 0x81b897be + 0x458d0db8 0xc9970232 0x7402dd05 0x44e1c70c + 0x1619441f 0x9ea0c392 0x1d13c3dc 0x34737cbb + 0xe1d726e1 0xbe7d749d 0x304892a5 0x71c7bb33 + 0x608bb696 0xd334cfd7 0x862e360e 0x868757ad + 0xb7d8aa70 0x81031f5e 0xdb64b80c 0x954ff4c1 + 0x5c66d432 0x08c77a67 0xd5e298af 0xb6074be1 + 0xd687a163 0xac2fd525 0x14e6ab5a 0x6ca4232d + 0x8a921092 0x0a19e936 0xd4464ee4 0x0da28777 + 0x6b6d4131 0x975111bc 0x3f26afae 0x5a6faf38 + 0x867d7956 0x554aa8be 0xf9898211 0x3afcde65 + 0x493dac6c 0x61d901b2 0xbaf3e9fe 0x2a3758fa + 0xc2ad3ee4 0x97d13dad 0xe84b02f9 0xaaf5ca63 + 0x41a94864 0x6d7b71be 0xd843e866 0x83c3193b + 0x972d4bbf 0x55c3a234 0x0d03b540 0x53396a64 + 0x98b5c0f3 0x36708484 0x38363c7a 0x0076dbf8 + 0x5edbd01a 0xf6e835d6 0xccb95e4f 0x2bd2907e + 0x210f9312 0xf4ec9221 0x343697d6 0x3913cd41 + 0xb02ced20 0xba991ee5 0x09c7893c 0x749da3c0 + 0x46e5ad3b 0x871b685d 0x02358659 0xca76706d + 0xe61524a2 0xf46ac4a9 0x4f6c9e19 0x68a86d0c + 0x9d16bc4f 0xa9157a1f 0x830993b8 0x3738896c + 0x7c821db5 0x02de8542 0xb17e3767 0x455a0b40 + 0x19b707eb 0xed81e63d 0x568e1e36 0xbf5cee00 + 0xaa12957f 0x67f65ecd 0xb940789c 0x0ab3bab8 + 0xd7e3a789 0x777b64ba 0x4e00d3be 0x46887a34 + 0x08f0127f 0xf5027e8f 0x9cdb4671 0xb7a7eac4 + 0x9be5cfb5 0xb1f57dbd 0xbce97b11 0x41525f56 + 0x5e847d16 0xf71585b3 0x1ce5047b 0x1bc2fa00 + 0x860aa4ca 0xf97ee77d 0xe7843ee6 0xf07bd865 + 0xfa059452 0x58a59ce9 0x24f03b1b 0xd18a52c2 + 0x180426ab 0x2ced0003 0x399234cd 0xe43f91e9 + 0xa0516a92 0x8088d598 0xc3a41365 0xd1f044ef + 0xfb3808f9 0x1770e594 0xf96c4185 0xc6b67b9f + 0x5c01c703 0x65c6ef8d 0xd49310f3 0x0f962bd1 + 0xfb3c96f1 0x4d501516 0xa09beeb5 0xce9df639 + 0xf792c71f 0x392b420d 0xc03c9099 0xcab5dc42 + 0xbdfea308 0x84c80c32 0xcd66ec3f 0x68932191 + 0x62b69b08 0xcacb4a8b 0x0415feff 0x84673edf + 0xe61b5ff3 0x6107a18e 0x6a7a206b 0xed64aa34 + 0x1bbaef36 0x22a3f0fa 0xb0945c72 0xd1a7f7f8 + 0x65fd1b29 0xa34d99a9 0xb6f2ea53 0x055ab055 + 0x433c3eb2 0xe591d68b 0xcabb8a71 0xfb055c2e + 0x37e1efec 0x558fd45e 0xa5358766 0xe0c450f3 + 0x78ed3061 0x8713e084 0x4b0d2ec4 0x24feb10e + 0x6689fc4e 0x0c83f1c9 0x7490df57 0x00d618bc + 0x2c510caa 0xc5e2838a 0xcfae6669 0xdc2fa4b0 + 0xa4569e3e 0xcee095c4 0xcb5f42ee 0xdc11393f + 0x69f1c5aa 0xa495fae6 0x64c53ea4 0x4477aeb8 + 0x2ff43cef 0x660aa186 0x5dec9e67 0xa59f6aab + 0x51504061 0x28279b5a 0x4e245278 0xdbf53c73 + 0x01a77ff9 0x7d771730 0xa8d19fc6 0xce3697dd + 0xecc405d8 0x22f1872a 0x683afa3f 0x725f7e03 + 0x14c7acb2 0x845efb20 0xf3e03095 0x8c9a7d04 + 0xa9f115d3 0xb93fa8ef 0xd2e78a32 0x91e3cc61 + 0x805d48de 0xc9fcc672 0x225d36f0 0xb32e7627 + 0x11b7a585 0xa7321798 0x9b40640f 0x0c3a6b7f + 0x3337c762 0xbbe54bb3 0xc8316a84 0x0d487a67 + 0xa6d6b86b 0xd1fb2b92 0x15805dfe 0x5cd49b21 + 0x9855f2c2 0x74e2a195 0xbdc0729f 0x29f680a9 + 0x092f47ad 0x0e7091d1 0x6e7d2020 0x0a7b5d47 + 0xc9c4065b 0xc4cacd97 0xcd7b4071 0x7986cc7a + 0xb1c29ef5 0x47ced57d 0xc08a8b40 0x12102685 + 0x685caae1 0x1ebf3635 0xdfe6af15 0x8a0496f4 + 0xb9c07f19 0x1f62a68f 0x0133de0a 0x993017d9 + 0xd0553b5c 0x0c8f1311 0x7d979028 0x6001db26 + 0x1caf7ffd 0x76ced0cf 0xc33d3f23 0x9fc27423 + 0x235fc137 0xf85a079b 0x78174474 0x1d15b725 + 0x20162abf 0x62e0712d 0xa03f9cf0 0x0f4ff140 + 0xaa389d0d 0xd58e1171 0x8f5d21f4 0x3ad5b3c4 + 0x03003b51 0x49b29d4f 0xa3d82796 0x9c7f3391 + 0xe34de3a8 0xab75e6f4 0x3f06b52d 0xb8092f83 + 0x01f14341 0x929a3b8a 0xa630aa03 0x4b7e055e + 0x90b06e58 0xeaf2ad79 0xe8c5b756 0xf46f44e3 + 0x6693ff09 0x499d2790 0xd0d81c69 0x72d7a2bd + 0x794d242b 0x9be19084 0xddd51a72 0xf4f60698 + 0xd1747d6a 0x24dc87dd 0x78ba7af6 0x548b43d0 + 0xa2b03ee8 0x100ef53b 0xe836488a 0xf4b9a443 + 0x41d61bdc 0xee4bedb1 0x8f0ec0b0 0xc0125983 + 0xaa919a7f 0x6677db37 0x78e7d366 0xc7bef834 + 0x967a54e7 0x5f78951a 0xc0fddf1f 0xbd5cf29a + 0x3fa13be8 0xca67a695 0xc13e8c23 0xaff54342 + 0x94f4bc22 0x85512c06 0x1439cd71 0x7d13b7b5 + 0x76f8bd59 0xffe02871 0xbd88ccb1 0x2597d721 + 0x80a52e2e 0x1f696120 0x689e73aa 0x7d085fa0 + 0x0e183650 0xe041d3fb 0x5a340dd0 0x26a6c10c + 0xe6fef6d0 0xdb18b3b8 0x2fc6df63 0xfa695c57 + 0xfb3e6a3a 0x64fb412f 0xc1cf1e32 0x6edd945f + 0xcee44d66 0xdfb2ec8c 0x5eb84515 0x177f031b + 0x56a9db8a 0x0e247577 0x99004862 0xa5805854 + 0x04b1afc9 0x9c649998 0x908a1424 0xb595099b + 0xb91fb0ce 0x8c4bdd8a 0x78de806e 0x65ff3cba + 0xb66aeda0 0xe22d3592 0x7c0cdebf 0xc15c0853 + 0x80f31d27 0x84dfc7ed 0xc96a5992 0x939b3d6c + 0xf0ffac53 0xe4be269e 0x4d56d528 0xb0477318 + 0x40a4b528 0xd938f1bb 0x2b25a6c2 0xc93b3c9f + 0x179c9571 0x999c2e91 0xe7280616 0xee6e0481 + 0xc30eae2a 0x7d6f0458 0x0b7a52ff 0xd44e0a23 + 0x81d661ee 0x9d0f857b 0xe7fa9d18 0xd499cb85 + 0x4e27e30a 0xd51d1f9a 0x14195d32 0xccca7d6e + 0xc1703a6e 0x15664170 0x7f51c821 0xf1363619 + 0x37dc27f5 0x6aea6223 0xd574e44c 0x4b683223 + 0x4135ad1a 0x7694390a 0x0bf4bddf 0x9522f11b + 0xc20797be 0x45fb151e 0x96f2a952 0xedfd5f2c + 0xdfbcac7f 0x58f5dba6 0x68204d0d 0x52eeb34a + 0x8313fd8b 0xda2f1243 0x195a1479 0x19bb2970 + 0x1c2131e5 0x6841c28c 0x1ec33cfd 0xd3e489de + 0xd9b70b18 0x81503d32 0x9642a53e 0x02470015 + 0xb8d1087f 0x4b629e77 0xd7ec9ee0 0x795ffd91 + 0xcfa71aeb 0x4bae649a 0x7f768123 0x69f501d5 + 0x56c19a0c 0x4bfaac57 0x90ea664a 0x4d428e1a + 0xaee71c90 0x198fc316 0x549f5572 0x07a22e58 + 0xe8f444e3 0xedc7fc23 0xe96c1595 0xc4bdad06 + 0x751a3df5 0x3bc4fba4 0x58cd19b3 0x3665000a + 0xe4371d96 0x6c50d4e6 0x5d1d6a57 0xf130eabf + 0x48fd82ad 0x42a8bee8 0x71f89c32 0x95fba6dc + 0x9150b601 0x72c361b0 0x71a3c317 0x149614f9 + 0x224e67fa 0xf6a3fea9 0x5461cefa 0x367bc566 + 0x2226ee83 0xaa13e83f 0x8d7dc705 0x417c7afd + 0x8a0f2e17 0xbb4003df 0xd1c27124 0xaaaede8d + 0xd4ed5bcd 0xd0102aa8 0x3b519bfa 0xb82d6932 + 0x50b8f966 0xec685a1d 0xffb18b64 0x538955b2 + 0xac4b6cf1 0x0a86d32f 0x34e4cc05 0x02adcf17 + 0x7c80379f 0xcfb5bcb5 0x842190e7 0x8348cd1f + 0xabf77742 0x3332866f 0xa56fb2e6 0x6c1fec47 + 0xf2fbb22c 0x7230d805 0xed17d8f5 0x3426e157 + 0x1d045cb2 0x6c1e349f 0x3a6116ca 0x4baf0bdb + 0xab68daad 0xc4867466 0x7bb15fd9 0x707a6a1a + 0x83157678 0x277cffd1 0x8d48e5d2 0xf829bd6d + 0x1fd2750e 0xb6bb8854 0x66d0a20a 0x38f47b92 + 0xa3568b90 0x0d091e16 0x65a8245b 0x238e4299 + 0xd0bc6bbe 0x8ef67730 0xf976b632 0x326d9d24 + 0x96833335 0x1d475e95 0x1f8f41b6 0x65c9dabe + 0x2133b931 0x43be592d 0xb887160c 0xf21fbfce + 0xd83ca306 0xa0fb3fe7 0x7da09bf9 0x3f464aa6 + 0x37a7e40a 0xbb0c85bc 0xb172ff01 0xee62de6f + 0x59d2d646 0x4262e938 0xcd96f5e3 0x0c1862cc + 0x438388c7 0x9f45d4b2 0xc65ab0b0 0xd24a381c + 0x1d6c6767 0xedaa1ae2 0xa93eaec0 0x662d776b + 0x192a88c9 0x6c9d860d 0x61106181 0x30027db0 + 0xa5ae7b76 0x73fc43da 0xd77472b0 0xf4ceba3d + 0x7cd642c6 0x903dd266 0xe33f58e9 0xbd088621 + 0x8e4c2c12 0xd8c4288e 0x24fdbb22 0xf72ee1f9 + 0xf291bd7e 0x94e68382 0xbbdd9240 0xb59602de + 0x1b59afd0 0xe5417cf5 0x20bbb538 0xe28fdee3 + 0x0bb16920 0x77d6712a 0x1a0ae5f6 0x0156c43e + 0x976b53c4 0xef856d7b 0x5a974cfe 0xec53404b + 0xc627c557 0x3318542a 0x8fd883e6 0x508562b3 + 0xe0ab7501 0x9ae57262 0x95611b5e 0x50c699fd + 0x984bb8ab 0x5983ed68 0x9947a7c5 0xc0d2374a + 0xe0845ab6 0x9ffec0fe 0x41873bf5 0xc85c1a4c + 0x7ef2b12d 0x9e1a3857 0x444da53d 0xb8947919 + 0x84c8588c 0x268f34e3 0x1974cf3d 0xfa67e03f + 0xc4478570 0xc1896f5c 0xf86de14a 0x9d27ddb7 + 0x5da1c695 0x73c74ab7 0x9123a47b 0x1c9d9563 + 0x7b96bb9f 0x98d20464 0x1f46fd8d 0x4bc35857 + 0xc221a75f 0x04b24c86 0xbe1c7271 0x21a7b19a + 0x9e050b54 0x8d93d0fb 0x98d7b55b 0xe5fe9502 + 0x9471bff8 0xb3825934 0x5f22d5b2 0x47f4ae9c + 0x62d7623f 0xfdeef9b6 0x38c64ff3 0x9268fd7b + 0xa7cfd22e 0x80eeed4c 0xf80a4a3e 0xc9a7e4f4 + 0x6f334b52 0x48e932a5 0xef8720eb 0xb9e86512 + 0xc4183682 0x08142405 0x0a32902d 0x34503fb5 + 0x4c7f132b 0x8db9be38 0x82c20236 0x80a79fa5 + 0x9a31e682 0xca61dd2c 0x2e354b63 0x8d5a4750 + 0x7a838960 0x24dffeb5 0xc7d19837 0xebfbc508 + 0x82e8dbdb 0xe732eaf4 0x109470c1 0xb012af6e + 0xe2ce17be 0x79db33be 0x281184f3 0xc813df9d + 0x9e6a771f 0x4a81882c 0xda5baf2c 0xfecbbb6b + 0x4621a151 0xf4cece92 0xfc230416 0x8d4e758e + 0xf69c296c 0x9fa2490a 0xeaa56785 0x3075ed95 + 0x4c2ffe06 0x817caf32 0x5a72f33a 0xc6d99da3 + 0x2bbc3dde 0xade463f7 0xb74af1a3 0x738d809d + 0xd244aeaa 0x7302a2db 0xcb6e9b1d 0xe297c027 + 0x15dbaff6 0xce99c273 0x2810eb0e 0xafbe1f09 + 0xd316d8ba 0x27b8af19 0xb66bdf45 0x3e3b5fbe + 0x318a4f05 0x2ea7807b 0xed6d40a0 0x58ba8267 + 0x1d1c9d15 0x29af51cd 0x04a46683 0x4b759694 + 0x20ce21e6 0x19ef8036 0x141a8064 0xca36f583 + 0x6d47da5f 0x3a8f6b9a 0x70a99a79 0x03677150 + 0x0feb8c70 0xf3509842 0xf33b5dde 0xbef320a3 + 0x932f9512 0x87497bf0 0xf521a0c8 0xa813483b + 0xcd6fae43 0xbb7e4dce 0xc7d039b3 0x2d1e6f8b + 0x1b19cb9e 0x8341c193 0xeffde49d 0x4c40621b + 0x19d60210 0x8846c540 0xea735ec0 0x0c995dbd + 0x9aefe2f3 0xbd46f954 0x9b315f98 0x2819307e + 0xebe2c1f5 0x05919533 0xa52921ee 0xa0bd6746 + 0xd754f5d1 0x39eb2ce6 0x8442d51e 0xb1f75159 + 0x1b617cd1 0x046fc90a 0x6452daca 0xe8d3e3e1 + 0x77406387 0xe3ffbfca 0x89387e91 0x7e348a53 + 0xa5bd3b60 0xc113e95f 0x2ad5a7c4 0x45c1f445 + 0x2a683930 0x3428246c 0x4b89cf6b 0x05e66b1a + 0x571737eb 0x6e55a8e1 0xbc96ce28 0x24d501f3 + 0x242c8191 0xde8c9472 0xbff946e4 0x551b5759 + 0x411e3420 0x0f0b9299 0x44aaaf70 0xacf2f3df + 0xe9c44a27 0x781ffdce 0xa39651a5 0xdb7b44a5 + 0xed0ec4d9 0xec17fca2 0xd3ccb15f 0x2b9bd010 + 0x0446a9ef 0x18df586c 0xe227ae08 0xbbaff527 + 0x7958fb15 0x03bfc823 0xc09b7b6b 0xce07b0b3 + 0x0161a359 0x8e21f733 0x8f8168bf 0xc1e2207e + 0xf9f65e93 0x831b4ba8 0x4b3677f9 0xf8342d03 + 0x03c10268 0xd07233c1 0x0df67d97 0x72434732 + 0x059c7679 0x96526a88 0xb54f9440 0x19e7327f + 0x6f7f52c1 0xb4b8d069 0xcc4681eb 0x26ea581b + 0xc26fe16e 0x4073cc56 0x6d252a42 0x689fd0fd + 0x5d93f1b3 0x070ad283 0xa07cb95b 0x6effe0d1 + 0xe303ed01 0xb8e9b3f4 0x0721647a 0x31f877c6 + 0x134518e5 0x08694d5a 0xb0e6ef3b 0xc7fdc67e + 0x6111276e 0x45185e0a 0xe13cb5c7 0x7c6ec9e9 + 0xfdee9721 0xc1fb8bcc 0xe25a2bc1 0x075f717e + 0xd37b7698 0xa9cbfeae 0x6b7d0a28 0x1f1c8bdf + 0x35d0e6b2 0x8b988b79 0x54f02ea3 0x3426ae01 + 0x5e402b08 0x840d3b8e 0x221527ff 0x906a86f8 + 0x411ce6dc 0xe4b3056e 0x26c9ed04 0xf3d8bc97 + 0x3b02cf67 0x11309c45 0x06ea08bd 0x1c698922 + 0x04e1e492 0x06e0c39d 0xed2937ab 0x83f1911b + 0x25a94599 0x75d365f0 0x98f191e9 0x845f5e0f + 0x49547aa4 0x42a0ae2e 0xb7e77fb7 0xe132bfb9 + 0x1cc087a2 0xb0435a85 0x4818ee36 0x4cd90b16 + 0xf56d5e22 0xdc49137b 0xb5f16e70 0x8f8ac784 + 0x84b020c7 0x83c26ace 0x090b3489 0xde14f529 + 0x6ee716ba 0x9deabba1 0x2c230ded 0xd6a68037 + 0xe626043f 0x33431885 0xd26423e7 0xcf259f47 + 0x335dfa6d 0xf052f836 0xcadf2fa5 0x6f2125d9 + 0xafbb23bf 0x19ec69ba 0x84d10bad 0x8cd3ebd5 + 0x36f0fbb1 0xbc1cbfbe 0x96c56812 0x0b05c939 + 0xbd79989d 0xffe74b98 0x6f99405a 0x9f10b14c + 0x9d8efef4 0x299d21b5 0x9dd2df5a 0xc7ea511b + 0xbdde106f 0xe5dc7d17 0xee136bc7 0xc4521b6b + 0x823d31d0 0xcc3c32eb 0xb35ffb33 0x84dd8acd + 0xe8ddf3d6 0x4611888c 0xfe469f52 0xf8e18215 + 0x768747f0 0x86379e46 0xd3cf9eb7 0x86f1e47d + 0x30e68652 0x740203fe 0x1031b14e 0x96ce6827 + 0x45f57455 0xe41b7656 0xaa8496d3 0xb99701d0 + 0x485f88ed 0x1d064ef7 0xc7e3348e 0x110d938f + 0x0c3c9604 0x786b0b35 0x2b2aa6ad 0xdcc45e0b + 0xe9b29146 0xdbb00ed2 0x0527d574 0xc8029ff1 + 0x5699dfd0 0xd627ff70 0x285fb3d8 0xcf2e6b75 + 0xefad87da 0x4fa21893 0xa391388c 0x5760b28e + 0x41a95b55 0x82001638 0x6f0e2d45 0xd30f70aa + 0x5eca612f 0x946317f4 0x24c44ef7 0x470d26f2 + 0xf7e65ef4 0x3a831857 0x53c5699e 0x1af6ff3f + 0x675b46c3 0x1bd5cfbb 0x03ab61be 0xa67a2b7b + 0xbae16286 0xe1522d53 0x076d8ec2 0x3a603daa + 0x0dbacfd9 0xd32acae8 0xe8a23399 0xdf3330bf + 0xe990c05d 0xfe56bcc3 0x165f868a 0xdf42a220 + 0x6587e194 0x0a31eb94 0xa72a98fb 0x5512801d + 0xc5fd9c69 0xf7210367 0xcc80f30c 0xc08755bc + 0x3afe8202 0xc47d603e 0xd17d2990 0xa4addd73 + 0xce89fcc5 0x55726cbd 0xeeb77a64 0x628b3d1c + 0x2297e332 0x6ecab8e4 0x9739c0d1 0xd53d619c + 0xbf1a3371 0xe29ea297 0x140436d5 0xfa4802f8 + 0x1b277664 0x4f101407 0xde441685 0x1d36bbf4 + 0x057d9f25 0x7949dbc2 0x57686ffc 0x12984cb7 + 0x0721d76b 0x81ac7aac 0xeb40577c 0x43aaa8d4 + 0xb4e06e63 0x7054a526 0x18bced57 0xa37d26a0 + 0xac039a34 0x156e6d9f 0x07ae4487 0x0e59f4db + 0x28aeb416 0xc1c4dafd 0xe0357fef 0x683adca7 + 0x93f2d62b 0x8f1f6ec6 0xd42fcbd8 0xfc4e3fad + 0x082e4bbe 0x578bdbee 0x42dcda04 0x7684e947 + 0x20853da1 0x207dd044 0x56e372bb 0x5ef4c033 + 0x83353865 0xb3b42465 0xb80c9c79 0xffedbed0 + 0x09e45d5b 0x794fe5c7 0x498d4fbd 0xb1cd7a48 + 0xfc89b057 0xc1d19df8 0x9654d056 0xc94cd085 + 0xd7cb03b5 0x13a52c5b 0x52471fd3 0x990aaebe + 0xe8bed6a7 0xa6960d01 0x68011da1 0x021bf151 + 0xaaa196f2 0x9e3b6188 0xbb28f2c5 0x559d3dd2 + 0xc38861b2 0xfd7242b1 0x716c29e2 0x270236a9 + 0xaaf33479 0x610a7d76 0xc0d564fc 0xf0bb1bd8 + 0x31fb232b 0xf19ebb3f 0xd62acd99 0x5e45578e + 0x467c587f 0x0ac00140 0x9c7c1705 0x61a8a1ea + 0x4c5e4e5d 0x0e0d846c 0xd199939c 0xb4c615ae + 0x4cfe60cd 0x6b4e5cf4 0xe97ad9ec 0xf325a456 + 0x6ca45a64 0xb88b4506 0x9f751f49 0x1d66e330 + 0x59b40444 0x00f530b0 0x9242124d 0xac6de2f9 + 0x7b7e7a67 0x64962ed3 0xfd0825bc 0xbdbcc113 + 0x38d8d589 0x3cedb53e 0x17d95495 0x020b8ac2 + 0xe9aa9bdf 0x0a5a2820 0x64670635 0x91a2a89e + 0x91bec6be 0xe9b4f902 0x1ef88ee7 0xec6e1208 + 0x149e39ca 0xb140ce3b 0x3210a2a7 0x8e489c45 + 0x59d3ebad 0x30275658 0xc20708d2 0xffdc3e00 + 0x96c700b8 0x3d03aea6 0xf0ce7ad3 0x232a5585 + 0xb0dc6620 0x1c1357b3 0xfb4c6d29 0xe5c5b7b7 + 0xc4bfe2aa 0x37f7ce13 0x433eb884 0x3dde220f + 0xc1c34602 0xea700f6f 0x37b79490 0xad5761a3 + 0xfc5917b1 0x22f7e1be 0xa90566d8 0x89e9db15 + 0xf91bfa1f 0xdad2260c 0x93eba86f 0x2d94c130 + 0x777290f1 0x2e656559 0x9be4a490 0x377a6ea0 + 0x1b4523e4 0xdca0c8a5 0xb00eed31 0x6baeb803 + 0x9601ee69 0x13d53e86 0xba8d6d8f 0xed6203ce + 0xc844f9c7 0x91e8a556 0x39974676 0x3b81329b + 0xdd7f10e1 0xbccb6558 0xb20de25c 0x448c44ee + 0x8932398a 0x76717b57 0xb20a667a 0x14e2df4a + 0xa57107f6 0x701b6c36 0x4b83a1ac 0xb39a1c9e + 0x2cc7e9fe 0xf5ae4a62 0x620687b6 0x2d6aef9d + 0x6672612c 0x168cdc7e 0x8b09abea 0x522692da + 0x6461676d 0x34ab3a9c 0x0d61a2ba 0x0590fef1 + 0xe9b4b475 0x2dfb6081 0xbcdafb25 0xdae642aa + 0x9a9230fd 0xfd67f346 0xdb9d66e1 0x5b307b61 + 0x9d4f1869 0x21133d6f 0x5157502f 0xcc8ccbc5 + 0xb6631100 0xa33f48db 0xc0172774 0x5cb276ac + 0xe6e5c560 0x07e126dd 0x42bcf23a 0x8064fd70 + 0x567ece78 0xbbc2fe32 0x9d5ee1bb 0x175b24be + 0xf0feac7a 0x57322618 0xfe9e893f 0xa9b2d67b + 0x36d03f5a 0xdf178831 0x4da346c5 0x843b1b10 + 0x0d688dca 0x41a475c6 0x4b7adf33 0x145a00dc + 0xcd226a4d 0x4c40cf2c 0xd4972929 0xbad5ea65 + 0xa96987fa 0xbe247d1c 0x49f2ce89 0xe09bbe72 + 0xee48486e 0x34b41435 0xb41dbb86 0xe58866c9 + 0xe848e228 0x18880947 0xd03cd275 0xca285915 + 0x53dd0097 0xff9069f9 0xaff6a8cd 0xbfe16ac5 + 0x5e88e076 0xac629a26 0x5a99bee9 0xea892a43 + 0x8d1d5ce8 0x806a38e3 0xc4d99fcd 0x331a4a01 + 0x0e586310 0xdd2dfabb 0xe7e6ad37 0x31d67fb1 + 0xbb985560 0xc969ce24 0x3a424634 0x20a2080e + 0xeb1b587c 0x5cf7da4b 0xdaec0133 0xc99abb17 + 0x63ab9c8f 0xef7e4042 0xca513c8a 0x4e15f5d9 + 0x7cf8fc96 0x464cea5a 0x2363577d 0xd21bb7db + 0x1d977a0f 0xb02f4878 0x4fd1a03b 0x435b9149 + 0xdfba062e 0xa2f7fc23 0x5ebde93c 0x28e9ed7a + 0x4023b147 0x9cac0cf9 0x7c5d5ca1 0xb7453148 + 0xa52197d9 0xb85dd94b 0x72ee7e51 0xb81f4f5c + 0x97a4b485 0x13d8858a 0xa0aabd28 0x9d381125 + 0x4960d2a7 0xa62787b2 0x865231c2 0xd637cc90 + 0x6d58f3b7 0xe2759f6e 0xa28af8da 0x5a005f20 + 0xc11c495b 0x85ecc413 0x657e7b91 0x10b39f7e + 0x3fcc394a 0x94b3fc3a 0xb359d60e 0x2e6c1555 + 0x67d6d21d 0xb0457bc4 0x004f329a 0x2e131d8b + 0xfbfbff2a 0x2c1bcbef 0x181f26b6 0x32ebda60 + 0xa0839e5a 0x241097df 0xb3f070a7 0xefbbd9f0 + 0x7c3669c7 0x265f2dbc 0x0bd00e42 0x80d6c4c2 + 0x44874336 0x0b6e7e0a 0xec590889 0xef865c09 + 0x1a02ac8a 0xfbf78784 0xaaf89d75 0xa86c9caa + 0xc626528d 0xfbcec50f 0x2955f18e 0xb5e9a833 + 0xae60f6bb 0xb3f4c51e 0x21bd6a6e 0x092a6861 + 0x162d73dd 0xacfa4f0e 0x4efed2bd 0x88980089 + 0xa2cee6d9 0xdf0953b8 0x6bf5208d 0x4364ed53 + 0x1a5f19ad 0x2ec7711e 0x7d18832b 0x0f1b28a6 + 0x0e127845 0x278a6a61 0x9e236436 0xf4646e82 + 0x07fff0f3 0x34ae92f9 0xec3e71af 0xf7ec7c67 + 0xdb9ddd62 0xe664e712 0xbb48a158 0x30a14ae6 + 0x0d93b021 0x83082cc8 0x68952311 0x001b0003 + 0xf0688e25 0x6c3b5161 0xfff18a53 0xbd1fb0c9 + 0xe3cc9013 0x1d1e553e 0xa85cdfb0 0x358afc14 + 0x61749007 0x6fad59bd 0xe85f4500 0x26a5ffa1 + 0xedd69e21 0x4c1db8ce 0xaf3be18f 0xcd75c259 + 0xd05f62ee 0x2f0ff1b7 0x717d9bd3 0x62e13392 + 0x159ce5ce 0xcd9e9bff 0x8964600e 0x57d85abb + 0x3f5ead09 0x2d5d4a55 0x87da8369 0xc7944933 + 0xcde9a717 0x55fa318d 0x112e1607 0x2ca832cb + 0xb1181bd5 0x7541a7d4 0xac1a1e20 0x6ad024c8 + 0x119378ec 0x60b6cbfb 0x068e2f24 0x83acecb1 + 0x87fd0df3 0x94c9552f 0x08c3d8dc 0x56f1b514 + 0x717d50e9 0x9680fc39 0xa1bdb28a 0x3dfa1c7c + 0x8fc84774 0xb72e06d7 0x42b7ad1e 0x93646393 + 0xd3632e4a 0x368d78f2 0x36a5ac5b 0x6576a4d8 + 0x8bc6856c 0xd447936a 0xbec6fb22 0xab285e59 + 0x3db2c781 0x72eda32a 0x9d654f18 0xdbd78e99 + 0xbba310ad 0x938ecfc6 0x72d5079a 0x49e2fad4 + 0x4b44dc75 0x81e82165 0xbe269c9c 0x2558ae80 + 0xa3bb693e 0x107d10fd 0x8e4fd977 0x22926b4f + 0x68c9a7f8 0x6b7439e0 0x5c71c127 0xff5d88b3 + 0x9d8cce8e 0x02982a71 0xf8fe1ceb 0x3ed3996b + 0x1e4f9957 0x63aca642 0xcc9db51b 0xbcb5af80 + 0x7b2bf393 0x2915079f 0x87f531c5 0xfb06b13a + 0x550b261c 0xf01fa342 0xcdf4dd86 0x76718f50 + 0x717c6bde 0xf460ef23 0x7f912022 0x54fe5b9b + 0xc7a5261b 0x073ea6e7 0x71504d55 0x91dd9b8e + 0x6d259452 0x2dc96e43 0x289959ca 0x128176a5 + 0x8d004371 0x835c494e 0x0efa1879 0xddc02e95 + 0xf0f4618e 0xc67656e2 0xd2bde6b1 0xccaa5e84 + 0xc6592f19 0x91d01db8 0x2b697d22 0x8adfa55f + 0x5a49e4e7 0x897d5c43 0xd326d94f 0xf5ff0c5b + 0x57976ca6 0xeff0db4e 0x6d49d466 0x7c054970 + 0xd3eb0f9f 0x0cbdce79 0x1beaf714 0xfe2df967 + 0x6a50895e 0x013167bf 0x6139e59c 0x0662ecee + 0x9a8d6b53 0xfffb8649 0xce0e685f 0xea5b2a7a + 0x8819a629 0x5f96afb4 0x8891acfe 0x545f1097 + 0x9f314e1b 0x248a5272 0xa40b8424 0xe42af07a + 0xa180f331 0x904f3c05 0x98455bc5 0x46198ed7 + 0x03e208e5 0xcf670099 0x7a85b08c 0xba921ae2 + 0x1e6947d0 0xddffa6ec 0xea6330d3 0xcda6957e + 0x19525cd3 0x311fb407 0x796c1ff4 0x3a2760fb + 0xde4bdd71 0xdb289b69 0x9811773c 0xa72cd839 + 0x03da90de 0xd42912e8 0x8da1fb0a 0x985d4132 + 0x5890ae40 0x1f7724d0 0xa336824f 0xca19df32 + 0xf8ac73d1 0x61c370a9 0xe152b073 0xdafc6461 + 0x23672042 0x9e6982b6 0x1256c6b4 0xe6bf2c9c + 0x9dae123e 0x30896b8f 0x99acf3a3 0xaa05d384 + 0xea3b7bb7 0xe711d473 0xa9053351 0x71a85cb4 + 0x3a0f5d25 0x2db3cb48 0x86314a6e 0xf7a2265b + 0xf7dc1cc3 0x548f56cf 0x4028a1ee 0x7d2e25d5 + 0x68c87e37 0xbced6b8c 0x536cc252 0x68bab5ca + 0x1158c6c5 0xae0e9509 0x66fa6885 0x22bf2b9a + 0xa7a60a97 0x18f4f609 0x348623eb 0x773e705f + 0xb3d6622f 0x8f348186 0x81cb9856 0x64bf21ba + 0x47e1f96d 0xc95a5843 0xeff6cfce 0x08cb092c + 0xf214e48d 0xce272fec 0x57bf90df 0x3c425ea8 + 0x856e1f5e 0x5c21d1b6 0x105488a3 0x553971eb + 0xde614ee5 0xdfa3ac81 0xc5eca5b1 0x69d02d23 + 0x2a0fefb7 0xf9a01854 0xdd99f277 0x75014d7d + 0x3830e3dd 0x7dd8f1e7 0xdac5ac92 0xbf57c03a + 0xa5e6a6c7 0xb7c1b7a9 0xc8c8405e 0xfd1977da + 0x1e6a7ca4 0x299e1025 0x651a0e55 0x53d624a7 + 0xccc9e861 0x901bce45 0x1de5a1ab 0x6140dcef + 0x3e09eafb 0x20c63cd0 0xff642faa 0xbc91a0a7 + 0xe373e111 0x857236e7 0xe3e61037 0x0b6cc497 + 0xca1da7e6 0x60e53803 0xb68663db 0x42e9956a + 0xbf4a1650 0xb43f25ec 0xc1232a3a 0x283c2ff3 + 0xcd233183 0x17ccdfc0 0x03ac3e6d 0xa68ced48 + 0xe38217d5 0x03c6472d 0x6a623afc 0xfce0d117 + 0x448ee829 0x0909efd4 0x843a3b4a 0x9ad07683 + 0x2250af2a 0x01ecc053 0x29684919 0x4ee0c62e + 0xa326a904 0x3ec83943 0xc42b0663 0x966379b2 + 0xc672ece4 0x39391ad3 0x689a10f9 0xd3e9cbd6 + 0x4bfa8446 0xd1ef6375 0xfe01b6a9 0xbda7d01a + 0x1e6879bf 0x05bdf46e 0x14ccab04 0xb02ae668 + 0x58b51752 0x5eb8e83c 0x753d99de 0x87e4235b + 0x80b2afe7 0x127439fe 0x127a98a4 0xe5934c92 + 0x86044bc0 0xa9664abb 0x91365b53 0x35b14bda + 0x67755842 0x7239651a 0x49e0b2e6 0xbb1d25fe + 0x51ca7213 0xaff2fd82 0xc1223aba 0x02941bcf + 0xb6ec2cfe 0xaa817dc0 0xe0475250 0x78098112 + 0x750ae102 0x0b3135fa 0x23b648d4 0xbc9d78bd + 0xc5d7e046 0xe90ef47c 0x7f21eb75 0xdb304b0b + 0xa2c12ee2 0xb45e62ed 0x9f50feb6 0xe036ff55 + 0x422f410b 0x2385de45 0xb37df6a5 0x4c2abf10 + 0x6a2c7370 0xf35197ac 0x381face9 0x694761c6 + 0xb2275097 0x208824c7 0x945300a0 0x4ad3f83d + 0x38a7aa12 0x00daaf41 0xcd4b2c19 0x25b2e8f7 + 0x60d3e39b 0xb3dd8220 0x152f86ab 0xd1ec4233 + 0x1c3df78a 0x5aeac74e 0xdeea2fe3 0xcfcf9b2e + 0x6efc8b2a 0x12a8c5c3 0xb56384e4 0x1b1fe549 + 0xc55acb4d 0x78e7306a 0x733b0f70 0xf4afe6be + 0x6d904b03 0x7ddd7862 0x4da02602 0xfce1e904 + 0x78773a4b 0x9083e908 0xda8a7593 0xafd8776e + 0x9e5ae37a 0xd6e7c557 0xad27adaa 0xd0f1a995 + 0x1c84e046 0x3319b21a 0xd24c0d03 0x1789df77 + 0x0f02b9ff 0xdb911f76 0xb2df7654 0x2e75a7bd + 0x8acc6fd3 0x3c16ec0b 0xe0d7ac22 0x3ddd1ce1 + 0xfa9ec67a 0x48f2c409 0xf8099606 0xd73a459d + 0x9b2b3fa5 0x8e3c3e9c 0x8b99286a 0x006c0e07 + 0xc299ded3 0x8a2bd400 0x74508dd4 0x609b4afc + 0x1a532838 0xb352a629 0xd390d8af 0x440a5798 + 0xd31f6ad5 0x161aa48e 0x24a4359f 0xf39f49f7 + 0xff160d2a 0x27a24637 0x84c46d40 0x988d026a + 0x5697a68f 0xeae970a0 0x42689e3d 0xc84ee62f + 0x764aabd5 0xb6d74ba5 0x8efc05a6 0xf2d0eccb + 0x2b4fa41c 0xad24799f 0xf73b8353 0x76bcd448 + 0x08172d5e 0x5c6be301 0x926ffdd6 0xfa31009f + 0x8339c5f9 0x9dde2840 0x00c2d730 0x6402335f + 0xf6f84eda 0x5b0e628a 0x140dbafb 0x0533ee67 + 0xa7523e60 0x20ca14b3 0x1145d280 0xb0c0ba41 + 0x81f174d1 0xb80fc64e 0xe8321cfe 0x5762e501 + 0x9e266b75 0x2695a738 0xe3104779 0x1d1ea19e + 0x15fd1d53 0xf0fbd4ee 0xc82f4552 0x4ea98e23 + 0xec892d69 0x66ccadeb 0x2fdf99b4 0xafffec15 + 0x2de5ee13 0x5e6ead7f 0x20b111cd 0x752254d1 + 0xc0126f43 0xe2695fd8 0x38651d40 0x15b708ce + 0xf2c2ffdc 0xec24c68c 0x04351ddc 0xceac029b + 0x0525fc89 0x90e28526 0x0a23a4c2 0xbb33a5c4 + 0x13f1fc38 0x66d79cd9 0x0acabe80 0x8d4ef5d8 + 0x4091808e 0x02f7150b 0xf550597e 0x52703c3f + 0xfc954b68 0xe9ebaccb 0xd4f35b2a 0x93793446 + 0xc40799e6 0xa963fc0c 0x92c8d8f1 0xbc8218dc + 0x9ec5c30a 0x8a6a2217 0x63d13dfe 0xea664e1e + 0x487192a7 0x1c8f8610 0x88e20f93 0xc54a6de3 + 0x0111ae79 0x1335f02e 0xa2e2d37d 0xc2563697 + 0x5fffcdec 0x233919ab 0x3bab1329 0x61943e99 + 0xea7940f7 0x3cc62cf4 0xaedc5bc4 0x41b63f2c + 0x6dbf285f 0xb4793534 0x0e1013f2 0xc54d8c2d + 0x23c587f7 0x75df0092 0xc055254a 0x55db2c71 + 0x518eaa5b 0x55c810d6 0x9c44ca37 0x034287ea + 0xe06a0567 0x221a0d8c 0x037a9164 0x36693ef9 + 0xb7d270a6 0xa8d84a63 0xe8862970 0x484077b7 + 0xab426cb7 0x37db7c9e 0xb34e1752 0x35444958 + 0x00d48e90 0x8142602d 0x8ca28e2c 0x714598c9 + 0xb1cce1be 0xbb98db74 0x400e1029 0x330cb2b6 + 0x1fd3f8ce 0x2abf7516 0xc2d07e5c 0x2b1d2b80 + 0xf06bd895 0x2fa7bc09 0xbdbdf893 0xd8466f85 + 0x61e551b0 0x5b99bfb8 0x86ea5ee7 0xfd82ff9a + 0xd7c6344a 0x1fa144d8 0x650f0f02 0x71bd73cf + 0x2825177d 0x56c76399 0x2e0b873e 0xc3bf939d + 0xf8bc3c1b 0x468482e7 0x33cb98a7 0xa679eaf4 + 0x32ba9b49 0xde86d50c 0x9eeeeee5 0x94a306e5 + 0x432e1c9c 0x37997d0c 0xa84d981f 0xbe07b56d + 0x4ab6d465 0xa3cd92c4 0x5dea82ab 0xf771249d + 0x78f87ba5 0x8105df1c 0x3d74e1c1 0xf48cd4c1 + 0x8ad010e1 0x9e9a2758 0x509c8953 0xeaaed79a + 0x97a4ecb7 0x23ffceb0 0xb3e42e61 0x5f41b4eb + 0x14d2804c 0x2d635ad3 0xe1314781 0x3921ec18 + 0x3dbebec3 0x94e0df22 0xb0b4724e 0x0e7f986b + 0x83dd7694 0x7041a22e 0x3c942757 0xd6ff5cbb + 0x048b0426 0xa5d6c4cb 0x1f4e3bbd 0x78d5924e + 0x6a857d77 0x1d115ecc 0x73c6a888 0xefb934ee + 0xa7d1702b 0x6794a668 0x03715b90 0xfbab19f9 + 0xd5a433df 0x12f4d421 0x40519650 0x636a093e + 0x1601be15 0xe0fbef6f 0x79d775bc 0x789c3a30 + 0x4d9fa618 0xedf8fa70 0xb0fa402d 0x692ee91b + 0x5a593e5c 0x0fa3667f 0x3f51a636 0x935e28c7 + 0x230b725a 0x4929bc83 0x76de40ad 0x2d9a5f7f + 0x8799e033 0xbf2700b0 0x5220159d 0x1ed71ca5 + 0xcc66f114 0x15fd868d 0x4236645a 0xded2558e + 0xa561cc0d 0x02822e5b 0xd0177f80 0xf09badd9 + 0xd5380ae3 0xcfc11a46 0x36713416 0x7f3d60cc + 0x4018797e 0xc6b23941 0xcb5a4861 0x614ce6df + 0xabfc0629 0xa519bcfc 0x911f04f0 0xe509b546 + 0xbb411eb9 0x9e6b921c 0xbf0b1c70 0x80c2901c + 0x85786713 0xad2aafec 0x62711ba7 0x6edb4971 + 0x214eb137 0x45b1b313 0x6742d5e9 0x7daf37a6 + 0x21d6a27a 0x059424f7 0x2c8c3dfb 0xe7a06c77 + 0x10815625 0xb4dc69e8 0x52767f66 0x44d48738 + 0x84d26c93 0x09008893 0xfc21394a 0x82155a72 + 0xc4fd7512 0x6d43cd2f 0xcae99e08 0x453175ae + 0xc6ee93a3 0x2fed0eac 0xe48fb73d 0x0afe2d2a + 0x5966735e 0xdc7e5fb6 0xed1ef13d 0x7e08a106 + 0xd3ca0e6b 0x4ce5ca02 0xa0beebed 0xe982c609 + 0x1ee9e5a2 0x24ae26cb 0xfd4c08d4 0x5e85e850 + 0x11b54b3b 0x87209692 0x4a5b0c35 0xcd25dd6f + 0xd9570253 0xaad0b9fe 0xaf984fee 0x6cf7ae2d + 0x45d9926c 0x07a66ac6 0x8e7aacdc 0xaf587d66 + 0x53972a4e 0x8da4a6c9 0x2bc311e5 0x36938ae8 + 0x179b965d 0x515743f7 0xb5bbbdcd 0xd8602715 + 0x9e43049f 0x4e78a080 0xba3f1750 0x68635cf0 + 0x85823047 0xbb03b5fd 0xb0d747c8 0x58d214af + 0x94b1ba85 0x6d2cf8ac 0x2bc1faeb 0x6bd7c1e3 + 0x127658e9 0x8b499020 0xab8f0f62 0xee665a6a + 0x89240e4d 0x8a95342b 0x00b38ccc 0xe6b14d9d + 0x32a2af71 0x4c9ecb69 0xc8de2685 0xd7385184 + 0x8e943872 0x809b2c79 0x108511da 0x08b4f54d + 0x95f52442 0x26fe296f 0xf7e037c0 0xa1aecdd3 + 0x89774a91 0xde67c55f 0x1f9816dc 0x1469a4c2 + 0x28240be2 0x5fd0ad14 0x0949db3a 0x451b94d3 + 0x637e6d49 0x8a4771c8 0xf65104b7 0xc3058c40 + 0x592fe4d0 0xe26129f0 0xe66e6ce9 0x26ab39b8 + 0x308da532 0x205afe77 0x6dc78664 0x84d4890f + 0x9d49fcb0 0xcac8f2ed 0xe713d798 0xfed7c75b + 0xe441a0d4 0xdf60df37 0xc2eed2f5 0x2d68b20e + 0x7827c89a 0x9d4cb9f2 0xb8912cce 0x07516335 + 0x976ffbb6 0x5cd0de48 0xed716f54 0x6f3c9f7f + 0x34cf42d1 0xc1027cbb 0xde67c065 0xe0a229af + 0xfc8bd2e8 0xd62ca176 0x8bfb76b2 0x54a1388f + 0xe0650bb6 0x6d60682b 0xe16cf130 0xbd7c3ca2 + 0xea642814 0xa25f4d44 0x27013786 0x7316aa38 + 0x571511c8 0xf1b6b789 0xb7bfe72b 0x8fd2652c + 0xbfc7771a 0x51a2e551 0x3bd738c2 0x2698b495 + 0xec69a196 0xd5ecb5c4 0x9bd3224c 0x6d9ab4cf + 0x326c9942 0x4d711191 0xde9be50a 0xa980ca0b + 0xe8e59dd0 0x4439e4ae 0x35de914d 0xee499a84 + 0xd1ca0c9d 0xfe6ee96d 0x5b1f4fd0 0xabf0621a + 0x0c8220c7 0xcb6dbb1e 0xa5116036 0xe858d3c3 + 0x728e3a56 0x3b33e818 0xbe2643c1 0x497bbcc7 + 0xeb369828 0x9a4a01be 0x8c7e72a6 0xaf052f25 + 0x8d3ca85b 0x4703e55e 0x45647d4c 0x86d1e3e8 + 0x40ab59f9 0x3259b195 0xf979a147 0xb8961870 + 0x88b024f9 0x366e26bc 0xd6811525 0x252910c2 + 0x4223a20e 0x7fc971a3 0x4a639bf3 0xb6550c3b + 0xfe05e552 0xbdc98897 0x509923ff 0xf51a5abc + 0xc6cc0891 0x61cdac05 0x03a68664 0x1b80cc76 + 0xe18d8ee1 0x798bb4d2 0xd7769bf9 0x9ab4c02d + 0x7484774b 0xa9ee2c8b 0x87d34c85 0x15697682 + 0x9f6a4a55 0x9d7a731c 0x10014d6a 0xb9798070 + 0xd42f79cb 0x89db59b3 0xd5b0a0b6 0xf60864a5 + 0x2d6fb084 0x1cb607b2 0x48232701 0x9310cbc6 + 0x5bc81c98 0x6b25016c 0x2014b99d 0x0836e60b + 0x0addbc4c 0x3b8bac7c 0x8d95ac77 0x1d56c3c7 + 0x58333104 0x3d6eb719 0x676eb951 0xd5c2d1a3 + 0x239dae86 0x92181ab8 0xbdde9741 0x7995d452 + 0xe0020661 0x2f80c8b7 0xeedcd4fc 0xe4bde175 + 0xb98fdf78 0x84b9228f 0x78ecb4f3 0xe99e5d46 + 0xa33b9b96 0xe2cbc71c 0xc19e2146 0xdc0ee758 + 0x2d8f8767 0x2036685b 0x149df155 0x2e7ab376 + 0xb13b4266 0xf5c8a3b0 0x02ca1e19 0x1badd81b + 0xb9c1832a 0x73b31f75 0x69979b55 0x567070a2 + 0x2edeb3dc 0x26b55921 0x461df49f 0xc1aba883 + 0x25d6faec 0x5260e9bf 0xa8ccdd4c 0x04291961 + 0xfaf7a1b8 0xbc2d36e3 0xd6c86385 0x2757fbb9 + 0x62c7107c 0x87dac461 0x0c006454 0x0e971e49 + 0x4749afca 0x7f1fb389 0xdc0b69d3 0xc69fab09 + 0x12c372c9 0x78480a51 0x8ab03a94 0xb37022ca + 0x1d00e893 0x0989de45 0x8c819503 0x8e0e1c06 + 0x11cfef86 0x3c2386a6 0x66c0e6c8 0x1befa478 + 0xd2e7a4a7 0x9a8b5917 0x2cfa1816 0xaf7e6c7a + 0xd6c9f0ff 0x1aada3e0 0xbe36a471 0x5a91f3c7 + 0x6c61ea95 0x5246ef7c 0x20bc86c4 0xcfd87abd + 0xdc61f595 0x8310a684 0x0477e35c 0xe59e776f + 0xfa403863 0xdaf7bcb1 0xd6084825 0xb90bb047 + 0xeb9ff684 0x7223fbca 0x6b4af987 0x6b2553f8 + 0xdaabc6d2 0x82e2ebc3 0xa7c1c054 0x667eb0a7 + 0x53a0c7d4 0x3fcba743 0x38170187 0x2a2e5830 + 0xee134608 0xcd6e0112 0xac0831f9 0x9537d532 + 0x1e176b9c 0xe3fcb69f 0x17a2eee9 0xa9e6467f + 0xbf6b0246 0x6a08c0fb 0x7fb943b6 0xb8f67c0e + 0x2b3b4ffc 0xb155d20c 0x4eb5de53 0xf078715b + >; diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts new file mode 100644 index 0000000000..8f34369753 --- /dev/null +++ b/arch/x86/dts/minnowmax.dts @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" +/include/ "serial.dtsi" + +/ { + model = "Intel Minnowboard Max"; + compatible = "intel,minnowmax", "intel,baytrail"; + + aliases { + serial0 = &serial; + }; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = "/serial"; + }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich"; + spi-flash@0 { + reg = <0>; + compatible = "sst,25vf016b", "spi-flash"; + memory-map = <0xff800000 0x00800000>; + }; + }; + + microcode { + update@0 { +#include "microcode/m0130673322.dtsi" + }; + }; + +}; diff --git a/arch/x86/dts/serial.dtsi b/arch/x86/dts/serial.dtsi index 9b097f4f9b..6865eed9dd 100644 --- a/arch/x86/dts/serial.dtsi +++ b/arch/x86/dts/serial.dtsi @@ -1,5 +1,5 @@ / { - serial { + serial: serial { compatible = "x86-uart"; reg = <0x3f8 8>; reg-shift = <0>; diff --git a/arch/x86/include/asm/arch-baytrail/fsp/azalia.h b/arch/x86/include/asm/arch-baytrail/fsp/azalia.h new file mode 100644 index 0000000000..d96a20fc8d --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/fsp/azalia.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _FSP_AZALIA_H_ +#define _FSP_AZALIA_H_ + +struct __packed pch_azalia_verb_table_header { + uint32_t vendor_device_id; + uint16_t sub_system_id; + uint8_t revision_id; /* 0xff applies to all steppings */ + uint8_t front_panel_support; + uint16_t number_of_rear_jacks; + uint16_t number_of_front_jacks; +}; + +struct __packed pch_azalia_verb_table { + struct pch_azalia_verb_table_header verb_table_header; + const uint32_t *verb_table_data; +}; + +struct __packed pch_azalia_config { + uint8_t pme_enable:1; + uint8_t docking_supported:1; + uint8_t docking_attached:1; + uint8_t hdmi_codec_enable:1; + uint8_t azalia_v_ci_enable:1; + uint8_t rsvdbits:3; + /* number of verb tables provided by platform */ + uint8_t azalia_verb_table_num; + const struct pch_azalia_verb_table *azalia_verb_table; + /* delay timer after azalia reset */ + uint16_t reset_wait_timer_us; +}; + +#endif diff --git a/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h new file mode 100644 index 0000000000..82862f626d --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: Intel + */ + +#ifndef __FSP_VPD_H +#define __FSP_VPD_H + +struct memory_down_data { + uint8_t enable_memory_down; + uint8_t dram_speed; + uint8_t dram_type; + uint8_t dimm_0_enable; + uint8_t dimm_1_enable; + uint8_t dimm_width; + uint8_t dimm_density; + uint8_t dimm_bus_width; + uint8_t dimm_sides; /* Ranks Per dimm_ */ + uint8_t dimm_tcl; /* tCL */ + /* tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc. */ + uint8_t dimm_trpt_rcd; + uint8_t dimm_twr; /* tWR in DRAM clk */ + uint8_t dimm_twtr; /* tWTR in DRAM clk */ + uint8_t dimm_trrd; /* tRRD in DRAM clk */ + uint8_t dimm_trtp; /* tRTP in DRAM clk */ + uint8_t dimm_tfaw; /* tFAW in DRAM clk */ +}; + +struct __packed upd_region { + uint64_t signature; /* Offset 0x0000 */ + uint8_t reserved0[24]; /* Offset 0x0008 */ + uint16_t mrc_init_tseg_size; /* Offset 0x0020 */ + uint16_t mrc_init_mmio_size; /* Offset 0x0022 */ + uint8_t mrc_init_spd_addr1; /* Offset 0x0024 */ + uint8_t mrc_init_spd_addr2; /* Offset 0x0025 */ + uint8_t emmc_boot_mode; /* Offset 0x0026 */ + uint8_t enable_sdio; /* Offset 0x0027 */ + uint8_t enable_sdcard; /* Offset 0x0028 */ + uint8_t enable_hsuart0; /* Offset 0x0029 */ + uint8_t enable_hsuart1; /* Offset 0x002a */ + uint8_t enable_spi; /* Offset 0x002b */ + uint8_t reserved1; /* Offset 0x002c */ + uint8_t enable_sata; /* Offset 0x002d */ + uint8_t sata_mode; /* Offset 0x002e */ + uint8_t enable_azalia; /* Offset 0x002f */ + uint32_t azalia_config_ptr; /* Offset 0x0030 */ + uint8_t enable_xhci; /* Offset 0x0034 */ + uint8_t enable_lpe; /* Offset 0x0035 */ + uint8_t lpss_sio_enable_pci_mode; /* Offset 0x0036 */ + uint8_t enable_dma0; /* Offset 0x0037 */ + uint8_t enable_dma1; /* Offset 0x0038 */ + uint8_t enable_i2_c0; /* Offset 0x0039 */ + uint8_t enable_i2_c1; /* Offset 0x003a */ + uint8_t enable_i2_c2; /* Offset 0x003b */ + uint8_t enable_i2_c3; /* Offset 0x003c */ + uint8_t enable_i2_c4; /* Offset 0x003d */ + uint8_t enable_i2_c5; /* Offset 0x003e */ + uint8_t enable_i2_c6; /* Offset 0x003f */ + uint8_t enable_pwm0; /* Offset 0x0040 */ + uint8_t enable_pwm1; /* Offset 0x0041 */ + uint8_t enable_hsi; /* Offset 0x0042 */ + uint8_t igd_dvmt50_pre_alloc; /* Offset 0x0043 */ + uint8_t aperture_size; /* Offset 0x0044 */ + uint8_t gtt_size; /* Offset 0x0045 */ + uint32_t serial_debug_port_address; /* Offset 0x0046 */ + uint8_t serial_debug_port_type; /* Offset 0x004a */ + uint8_t mrc_debug_msg; /* Offset 0x004b */ + uint8_t isp_enable; /* Offset 0x004c */ + uint8_t scc_enable_pci_mode; /* Offset 0x004d */ + uint8_t igd_render_standby; /* Offset 0x004e */ + uint8_t txe_uma_enable; /* Offset 0x004f */ + uint8_t os_selection; /* Offset 0x0050 */ + uint8_t emmc45_ddr50_enabled; /* Offset 0x0051 */ + uint8_t emmc45_hs200_enabled; /* Offset 0x0052 */ + uint8_t emmc45_retune_timer_value; /* Offset 0x0053 */ + uint8_t unused_upd_space1[156]; /* Offset 0x0054 */ + struct memory_down_data memory_params; /* Offset 0x00f0 */ + uint16_t terminator; /* Offset 0x0100 */ +}; + +#define VPD_IMAGE_ID 0x3157454956594C56 /* 'VLYVIEW1' */ +#define VPD_IMAGE_REV 0x00000303 + +struct __packed vpd_region { + uint64_t sign; /* Offset 0x0000 */ + uint32_t img_rev; /* Offset 0x0008 */ + uint32_t upd_offset; /* Offset 0x000c */ + uint8_t unused[16]; /* Offset 0x0010 */ + uint32_t fsp_res_memlen; /* Offset 0x0020 */ + uint8_t platform_type; /* Offset 0x0024 */ + uint8_t enable_secure_boot; /* Offset 0x0025 */ +}; +#endif diff --git a/arch/x86/include/asm/arch-baytrail/gpio.h b/arch/x86/include/asm/arch-baytrail/gpio.h new file mode 100644 index 0000000000..ab4e059131 --- /dev/null +++ b/arch/x86/include/asm/arch-baytrail/gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2014, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44 + +#endif /* _X86_ARCH_GPIO_H_ */ diff --git a/board/intel/minnowmax/Kconfig b/board/intel/minnowmax/Kconfig new file mode 100644 index 0000000000..43c50a519b --- /dev/null +++ b/board/intel/minnowmax/Kconfig @@ -0,0 +1,24 @@ +if TARGET_MINNOWMAX + +config SYS_BOARD + default "minnowmax" + +config SYS_VENDOR + default "intel" + +config SYS_SOC + default "baytrail" + +config SYS_CONFIG_NAME + default "minnowmax" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select INTEL_BAYTRAIL + select BOARD_ROMSIZE_KB_8192 + +config PCIE_ECAM_BASE + default 0xe0000000 + +endif diff --git a/board/intel/minnowmax/MAINTAINERS b/board/intel/minnowmax/MAINTAINERS new file mode 100644 index 0000000000..d655761d57 --- /dev/null +++ b/board/intel/minnowmax/MAINTAINERS @@ -0,0 +1,6 @@ +CircuitCo Minnowboard Max +M: Simon Glass +S: Maintained +F: board/intel/minnowmax +F: include/configs/minnowmax.h +F: configs/minnowmax_defconfig diff --git a/board/intel/minnowmax/Makefile b/board/intel/minnowmax/Makefile new file mode 100644 index 0000000000..1a614324a2 --- /dev/null +++ b/board/intel/minnowmax/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015, Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += minnowmax.o start.o diff --git a/board/intel/minnowmax/minnowmax.c b/board/intel/minnowmax/minnowmax.c new file mode 100644 index 0000000000..6e82b16335 --- /dev/null +++ b/board/intel/minnowmax/minnowmax.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015, Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#define SERIAL_DEV PNP_DEV(0x2e, 4) + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + lpc47m_enable_serial(SERIAL_DEV, UART0_BASE); + + return 0; +} + +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{ + return; +} + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} diff --git a/board/intel/minnowmax/start.S b/board/intel/minnowmax/start.S new file mode 100644 index 0000000000..2c941a4a51 --- /dev/null +++ b/board/intel/minnowmax/start.S @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2015, Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig new file mode 100644 index 0000000000..7bc9085b32 --- /dev/null +++ b/configs/minnowmax_defconfig @@ -0,0 +1,13 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff00000" +CONFIG_X86=y +CONFIG_TARGET_MINNOWMAX=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="minnowmax" +CONFIG_VIDEO_X86=y +CONFIG_FRAMEBUFFER_SET_VESA_MODE=y +CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_DEBUG_UART_NS16550=y +CONFIG_DEBUG_UART=y +CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 +CONFIG_HAVE_INTEL_ME=y diff --git a/doc/README.x86 b/doc/README.x86 index a9105f87c0..c699b795e2 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -18,11 +18,11 @@ U-Boot supports running as a coreboot [1] payload on x86. So far only Link on other x86 boards since coreboot deals with most of the low-level details. U-Boot also supports booting directly from x86 reset vector without coreboot, -aka raw support or bare support. Currently Link and Intel Crown Bay board -support running U-Boot 'bare metal'. +aka raw support or bare support. Currently Link, Intel Crown Bay and Intel +Minnowboard Max support running U-Boot 'bare metal'. -As for loading OS, U-Boot supports directly booting a 32-bit or 64-bit Linux -kernel as part of a FIT image. It also supports a compressed zImage. +As for loading an OS, U-Boot supports directly booting a 32-bit or 64-bit +Linux kernel as part of a FIT image. It also supports a compressed zImage. Build Instructions ------------------ @@ -47,7 +47,7 @@ Change the 'Board configuration file' and 'Board Device Tree Source (dts) file' to point to a new board. You can also change the Cache-As-RAM (CAR) related settings here if the default values do not fit your new board. -Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a +Building a ROM version of U-Boot (hereafter referred to as u-boot.rom) is a little bit tricky, as generally it requires several binary blobs which are not shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is not turned on by default in the U-Boot source tree. Firstly, you need turn it @@ -110,6 +110,33 @@ Now you can build U-Boot and obtain u-boot.rom $ make crownbay_defconfig $ make all + +Intel Minnowboard Max instructions: + +This uses as FSP as with Crown Bay, except it is for the Atom E3800 series. +Download this and get the .fd file (BAYTRAIL_FSP_GOLD_003_16-SEP-2014.fd at +the time of writing). Put it in the board directory: +board/intel/minnowmax/fsp.bin + +Obtain the VGA RAM (Vga.dat at the time of writing) and put it into the same +directory: board/intel/minnowmax/vga.bin + +You still need two more binary blobs. These come from the sample SPI image +provided in the FSP (SPI.bin at the time of writing). + +Use ifdtool in the U-Boot tools directory to extract the images from that +file, for example: + + $ ./tools/ifdtool -x BayleyBay/SPI.bin + $ cp flashregion_2_intel_me.bin board/intel/minnowmax/me.bin + $ cp flashregion_0_flashdescriptor.bin board/intel/minnowmax/descriptor.bin + +Now you can build U-Boot and obtain u-boot.rom + +$ make minnowmax_defconfig +$ make all + + Test with coreboot ------------------ For testing U-Boot as the coreboot payload, there are things that need be paid @@ -130,6 +157,16 @@ symbol address of _start (in arch/x86/cpu/start.S). If you want to use ELF as the coreboot payload, change U-Boot configuration to use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE. +To enable video you must enable these options in coreboot: + + - Set framebuffer graphics resolution (1280x1024 32k-color (1:5:5)) + - Keep VESA framebuffer + +At present it seems that for Minnowboard Max, coreboot does not pass through +the video information correctly (it always says the resolution is 0x0). This +works correctly for link though. + + CPU Microcode ------------- Modern CPUs usually require a special bit stream called microcode [5] to be diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h new file mode 100644 index 0000000000..823e051eb1 --- /dev/null +++ b/include/configs/minnowmax.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_X86_SERIAL +#define CONFIG_SMSC_LPC47M + +#define CONFIG_PCI_MEM_BUS 0xd0000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x10000000 + +#define CONFIG_PCI_PREF_BUS 0xc0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x10000000 + +#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000 + +#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP +#define CONFIG_RTL8169 +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ + "stdout=vga,serial\0" \ + "stderr=vga,serial\0" + +#define CONFIG_SCSI_DEV_LIST \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA} +#define CONFIG_SPI_FLASH_SST + +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC_SDMA +#define CONFIG_CMD_MMC + +#undef CONFIG_USB_MAX_CONTROLLER_COUNT +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 + +#define CONFIG_X86_OPTION_ROM_FILE vga.bin +#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000 + +#ifndef CONFIG_SYS_COREBOOT +#define CONFIG_VIDEO_VESA +#endif +#define VIDEO_IO_OFFSET 0 +#define CONFIG_X86EMU_RAW_IO +#define CONFIG_VGA_AS_SINGLE_DEVICE + +#define CONFIG_FIT_SIGNATURE +#define CONFIG_RSA + +/* Avoid a warning in the Realtek Ethernet driver */ +#define CONFIG_SYS_CACHELINE_SIZE 16 + +#endif /* __CONFIG_H */ -- cgit From 7df546a653462c91bc88bf9bf465ff2e39fde59e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 24 Jan 2015 17:17:08 +0800 Subject: x86: Remove CONFIG_SATA_INTEL from x86-common.h CONFIG_SATA_INTEL is not referenced anywhere, so remove it. Signed-off-by: Bin Meng Acked-by: Simon Glass --- include/configs/x86-common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 66d4894256..062e6c2219 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -39,7 +39,6 @@ /* SATA AHCI storage */ #define CONFIG_SCSI_AHCI -#define CONFIG_SATA_INTEL #ifdef CONFIG_SCSI_AHCI #define CONFIG_LIBATA #define CONFIG_SYS_64BIT_LBA -- cgit From b994efbd2d515ee0ec50c03191ffb348b197d4f3 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:23 +0800 Subject: x86: Add header files for Intel Quark SoC defines device.h for integrated pci devices' bdf on Quark SoC and quark.h for various memory-mapped and i/o-mapped base addresses within SoC. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/include/asm/arch-quark/device.h | 28 ++++++++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 arch/x86/include/asm/arch-quark/device.h create mode 100644 arch/x86/include/asm/arch-quark/quark.h diff --git a/arch/x86/include/asm/arch-quark/device.h b/arch/x86/include/asm/arch-quark/device.h new file mode 100644 index 0000000000..4af3dedc95 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/device.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_DEVICE_H_ +#define _QUARK_DEVICE_H_ + +#include + +#define QUARK_HOST_BRIDGE PCI_BDF(0, 0, 0) +#define QUARK_MMC_SDIO PCI_BDF(0, 20, 0) +#define QUARK_UART0 PCI_BDF(0, 20, 1) +#define QUARK_USB_DEVICE PCI_BDF(0, 20, 2) +#define QUARK_USB_EHCI PCI_BDF(0, 20, 3) +#define QUARK_USB_OHCI PCI_BDF(0, 20, 4) +#define QUARK_UART1 PCI_BDF(0, 20, 5) +#define QUARK_EMAC0 PCI_BDF(0, 20, 6) +#define QUARK_EMAC1 PCI_BDF(0, 20, 7) +#define QUARK_SPI0 PCI_BDF(0, 21, 0) +#define QUARK_SPI1 PCI_BDF(0, 21, 1) +#define QUARK_I2C_GPIO PCI_BDF(0, 21, 2) +#define QUARK_PCIE0 PCI_BDF(0, 23, 0) +#define QUARK_PCIE1 PCI_BDF(0, 23, 1) +#define QUARK_LEGACY_BRIDGE PCI_BDF(0, 31, 0) + +#endif /* _QUARK_DEVICE_H_ */ diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h new file mode 100644 index 0000000000..ebbcf7755d --- /dev/null +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_H_ +#define _QUARK_H_ + +/* Message Bus Ports */ +#define MSG_PORT_MEM_ARBITER 0x00 +#define MSG_PORT_HOST_BRIDGE 0x03 +#define MSG_PORT_RMU 0x04 +#define MSG_PORT_MEM_MGR 0x05 +#define MSG_PORT_SOC_UNIT 0x31 + +/* Host Memory I/O Boundary */ +#define HM_BOUND 0x08 + +/* eSRAM Block Page Control */ +#define ESRAM_BLK_CTRL 0x82 +#define ESRAM_BLOCK_MODE 0x10000000 + +/* DRAM */ +#define DRAM_BASE 0x00000000 +#define DRAM_MAX_SIZE 0x80000000 + +/* eSRAM */ +#define ESRAM_SIZE 0x80000 + +/* Memory BAR Enable */ +#define MEM_BAR_EN 0x00000001 + +/* I/O BAR Enable */ +#define IO_BAR_EN 0x80000000 + +/* 64KiB of RMU binary in flash */ +#define RMU_BINARY_SIZE 0x10000 + +#endif /* _QUARK_H_ */ -- cgit From faa832329932c4559a8d03d4212881b6146da5df Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:24 +0800 Subject: x86: quark: Add routines to access message bus registers In the Quark SoC, some chipset commands are accomplished by utilizing the internal message network within the host bridge (D0:F0). Accesses to this network are accomplished by populating the message control register (MCR), Message Control Register eXtension (MCRX) and the message data register (MDR). Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/msg_port.c | 77 +++++++++++++++++++++ arch/x86/include/asm/arch-quark/msg_port.h | 106 +++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 arch/x86/cpu/quark/msg_port.c create mode 100644 arch/x86/include/asm/arch-quark/msg_port.h diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c new file mode 100644 index 0000000000..31713e321f --- /dev/null +++ b/arch/x86/cpu/quark/msg_port.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +void msg_port_setup(int op, int port, int reg) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + (((op) << 24) | ((port) << 16) | + (((reg) << 8) & 0xff00) | MSG_BYTE_ENABLE)); +} + +u32 msg_port_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_READ, port, reg); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_WRITE, port, reg); +} + +u32 msg_port_alt_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_ALT_READ, port, reg); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_alt_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_ALT_WRITE, port, reg); +} + +u32 msg_port_io_read(u8 port, u32 reg) +{ + u32 value; + + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_IO_READ, port, reg); + pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + + return value; +} + +void msg_port_io_write(u8 port, u32 reg, u32 value) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); + msg_port_setup(MSG_OP_IO_WRITE, port, reg); +} diff --git a/arch/x86/include/asm/arch-quark/msg_port.h b/arch/x86/include/asm/arch-quark/msg_port.h new file mode 100644 index 0000000000..2e78a66725 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/msg_port.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _QUARK_MSG_PORT_H_ +#define _QUARK_MSG_PORT_H_ + +/* + * In the Quark SoC, some chipset commands are accomplished by utilizing + * the internal message network within the host bridge (D0:F0). Accesses + * to this network are accomplished by populating the message control + * register (MCR), Message Control Register eXtension (MCRX) and the + * message data register (MDR). + */ +#define MSG_CTRL_REG 0xd0 /* Message Control Register */ +#define MSG_DATA_REG 0xd4 /* Message Data Register */ +#define MSG_CTRL_EXT_REG 0xd8 /* Message Control Register EXT */ + +/* Normal Read/Write OpCodes */ +#define MSG_OP_READ 0x10 +#define MSG_OP_WRITE 0x11 + +/* Alternative Read/Write OpCodes */ +#define MSG_OP_ALT_READ 0x06 +#define MSG_OP_ALT_WRITE 0x07 + +/* IO Read/Write OpCodes */ +#define MSG_OP_IO_READ 0x02 +#define MSG_OP_IO_WRITE 0x03 + +/* All byte enables */ +#define MSG_BYTE_ENABLE 0xf0 + +#ifndef __ASSEMBLY__ + +/** + * msg_port_setup - set up the message port control register + * + * @op: message bus access opcode + * @port: port number on the message bus + * @reg: register number within a port + */ +void msg_port_setup(int op, int port, int reg); + +/** + * msg_port_read - read a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_read(u8 port, u32 reg); + +/** + * msg_port_write - write a message port register using normal opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_alt_read - read a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_alt_read(u8 port, u32 reg); + +/** + * msg_port_alt_write - write a message port register using alternative opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_alt_write(u8 port, u32 reg, u32 value); + +/** + * msg_port_io_read - read a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * + * @return: message port register value + */ +u32 msg_port_io_read(u8 port, u32 reg); + +/** + * msg_port_io_write - write a message port register using I/O opcode + * + * @port: port number on the message bus + * @reg: register number within a port + * @value: register value to write + */ +void msg_port_io_write(u8 port, u32 reg, u32 value); + +#endif /* __ASSEMBLY__ */ + +#endif /* _QUARK_MSG_PORT_H_ */ -- cgit From 3c8ae536ec26ffc7715e38876b43f88286a98fd8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:25 +0800 Subject: x86: Define macros for pci configuration space access Move PCI_REG_ADDR and PCI_REG_DATA from arch/x86/lib/pci_type1.c to arch/x86/include/asm/pci.h, also define PCI_CFG_EN so that these macros can be used for pci configuration space access. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/include/asm/pci.h | 13 +++++++++++-- arch/x86/lib/pci_type1.c | 7 ++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index c30dd4c218..a153dd1622 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -1,4 +1,3 @@ - /* * (C) Copyright 2002 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se @@ -9,6 +8,14 @@ #ifndef _PCI_I386_H_ #define _PCI_I386_H_ +/* bus mapping constants (used for PCI core initialization) */ +#define PCI_REG_ADDR 0xcf8 +#define PCI_REG_DATA 0xcfc + +#define PCI_CFG_EN 0x80000000 + +#ifndef __ASSEMBLY__ + #define DEFINE_PCI_DEVICE_TABLE(_table) \ const struct pci_device_id _table[] @@ -49,4 +56,6 @@ void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value); void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value); void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value); -#endif +#endif /* __ASSEMBLY__ */ + +#endif /* _PCI_I386_H_ */ diff --git a/arch/x86/lib/pci_type1.c b/arch/x86/lib/pci_type1.c index 13942a33f7..a251adcacd 100644 --- a/arch/x86/lib/pci_type1.c +++ b/arch/x86/lib/pci_type1.c @@ -12,6 +12,7 @@ #include #include #include +#include #define cfg_read(val, addr, op) (*val = op((int)(addr))) #define cfg_write(val, addr, op) op((val), (int)(addr)) @@ -21,7 +22,7 @@ static int \ type1_##rw##_config_##size(struct pci_controller *hose, \ pci_dev_t dev, int offset, type val) \ { \ - outl(dev | (offset & 0xfc) | 0x80000000, (int)hose->cfg_addr); \ + outl(dev | (offset & 0xfc) | PCI_CFG_EN, (int)hose->cfg_addr); \ cfg_##rw(val, hose->cfg_data + (offset & mask), op); \ return 0; \ } @@ -34,10 +35,6 @@ TYPE1_PCI_OP(write, byte, u8, outb, 3) TYPE1_PCI_OP(write, word, u16, outw, 2) TYPE1_PCI_OP(write, dword, u32, outl, 0) -/* bus mapping constants (used for PCI core initialization) */ -#define PCI_REG_ADDR 0x00000cf8 -#define PCI_REG_DATA 0x00000cfc - void pci_setup_type1(struct pci_controller *hose) { pci_set_ops(hose, -- cgit From 0fae4d24df15b9133643c37e1a1d0d832fff801c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:26 +0800 Subject: x86: quark: Add Cache-As-RAM initialization Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is initialized by hardware. eSRAM is the ideal place to be used for Cache-As-RAM (CAR) before system memory is available. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/car.S | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 arch/x86/cpu/quark/car.S diff --git a/arch/x86/cpu/quark/car.S b/arch/x86/cpu/quark/car.S new file mode 100644 index 0000000000..3432ffa081 --- /dev/null +++ b/arch/x86/cpu/quark/car.S @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +.globl car_init +car_init: + post_code(POST_CAR_START) + + /* + * Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is + * initialized by hardware. eSRAM is the ideal place to be used + * for Cache-As-RAM (CAR) before system memory is available. + * + * Relocate this eSRAM to a suitable location in the physical + * memory map and enable it. + */ + + /* Host Memory Bound Register P03h:R08h */ + mov $((MSG_PORT_HOST_BRIDGE << 16) | (HM_BOUND << 8)), %eax + mov $(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx + lea 1f, %esp + jmp msg_port_write +1: + + /* eSRAM Block Page Control Register P05h:R82h */ + mov $((MSG_PORT_MEM_MGR << 16) | (ESRAM_BLK_CTRL << 8)), %eax + mov $(ESRAM_BLOCK_MODE | (CONFIG_ESRAM_BASE >> 24)), %edx + lea 2f, %esp + jmp msg_port_write +2: + + post_code(POST_CAR_CPU_CACHE) + jmp car_init_ret + +msg_port_read: + /* + * Parameter: + * eax[23:16] - Message Port ID + * eax[15:08] - Register Address + * + * Return Value: + * eax - Message Port Register value + * + * Return Address: esp + */ + + or $((MSG_OP_READ << 24) | MSG_BYTE_ENABLE), %eax + mov %eax, %ebx + + /* Write MCR B0:D0:F0:RD0 */ + mov $(PCI_CFG_EN | MSG_CTRL_REG), %eax + mov $PCI_REG_ADDR, %dx + out %eax, %dx + mov $PCI_REG_DATA, %dx + mov %ebx, %eax + out %eax, %dx + + /* Read MDR B0:D0:F0:RD4 */ + mov $(PCI_CFG_EN | MSG_DATA_REG), %eax + mov $PCI_REG_ADDR, %dx + out %eax, %dx + mov $PCI_REG_DATA, %dx + in %dx, %eax + + jmp *%esp + +msg_port_write: + /* + * Parameter: + * eax[23:16] - Message Port ID + * eax[15:08] - Register Address + * edx - Message Port Register value to write + * + * Return Address: esp + */ + + or $((MSG_OP_WRITE << 24) | MSG_BYTE_ENABLE), %eax + mov %eax, %esi + mov %edx, %edi + + /* Write MDR B0:D0:F0:RD4 */ + mov $(PCI_CFG_EN | MSG_DATA_REG), %eax + mov $PCI_REG_ADDR, %dx + out %eax, %dx + mov $PCI_REG_DATA, %dx + mov %edi, %eax + out %eax, %dx + + /* Write MCR B0:D0:F0:RD0 */ + mov $(PCI_CFG_EN | MSG_CTRL_REG), %eax + mov $PCI_REG_ADDR, %dx + out %eax, %dx + mov $PCI_REG_DATA, %dx + mov %esi, %eax + out %eax, %dx + + jmp *%esp -- cgit From 828d9af5eca7404ded18e0ede453f8040fd01f78 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:27 +0800 Subject: x86: Add basic Intel Quark processor support Add minimum codes to support Intel Quark SoC. DRAM initialization is not ready yet so a hardcoded gd->ram_size is assigned. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/Kconfig | 121 +++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/Makefile | 8 +++ arch/x86/cpu/quark/dram.c | 39 +++++++++++ arch/x86/cpu/quark/pci.c | 70 +++++++++++++++++++ arch/x86/cpu/quark/quark.c | 44 ++++++++++++ arch/x86/include/asm/arch-quark/gpio.h | 13 ++++ 6 files changed, 295 insertions(+) create mode 100644 arch/x86/cpu/quark/Kconfig create mode 100644 arch/x86/cpu/quark/Makefile create mode 100644 arch/x86/cpu/quark/dram.c create mode 100644 arch/x86/cpu/quark/pci.c create mode 100644 arch/x86/cpu/quark/quark.c create mode 100644 arch/x86/include/asm/arch-quark/gpio.h diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig new file mode 100644 index 0000000000..163caac660 --- /dev/null +++ b/arch/x86/cpu/quark/Kconfig @@ -0,0 +1,121 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +config INTEL_QUARK + bool + select HAVE_RMU + +if INTEL_QUARK + +config HAVE_RMU + bool "Add a Remote Management Unit (RMU) binary" + help + Select this option to add a Remote Management Unit (RMU) binary + to the resulting U-Boot image. It is a data block (up to 64K) of + machine-specific code which must be put in the flash for the RMU + within the Quark SoC processor to access when powered up before + system BIOS is executed. + +config RMU_FILE + string "Remote Management Unit (RMU) binary filename" + depends on HAVE_RMU + default "rmu.bin" + help + The filename of the file to use as Remote Management Unit (RMU) + binary in the board directory. + +config RMU_ADDR + hex "Remote Management Unit (RMU) binary location" + depends on HAVE_RMU + default 0xfff00000 + help + The location of the RMU binary is determined by a strap. It must be + put in flash at a location matching the strap-determined base address. + + The default base address of 0xfff00000 indicates that the binary must + be located at offset 0 from the beginning of a 1MB flash device. + +config HAVE_CMC + bool + default HAVE_RMU + +config CMC_FILE + string + depends on HAVE_CMC + default RMU_FILE + +config CMC_ADDR + hex + depends on HAVE_CMC + default RMU_ADDR + +config ESRAM_BASE + hex + default 0x80000000 + help + Embedded SRAM (eSRAM) memory-mapped base address. + +config PCIE_ECAM_BASE + hex + default 0xe0000000 + +config RCBA_BASE + hex + default 0xfed1c000 + help + Root Complex register block memory-mapped base address. + +config ACPI_PM1_BASE + hex + default 0x1000 + help + ACPI Power Managment 1 (PM1) i/o-mapped base address. + This device is defined in ACPI specification, with 16 bytes in size. + +config ACPI_PBLK_BASE + hex + default 0x1010 + help + ACPI Processor Block (PBLK) i/o-mapped base address. + This device is defined in ACPI specification, with 16 bytes in size. + +config SPI_DMA_BASE + hex + default 0x1020 + help + SPI DMA i/o-mapped base address. + +config GPIO_BASE + hex + default 0x1080 + help + GPIO i/o-mapped base address. + +config ACPI_GPE0_BASE + hex + default 0x1100 + help + ACPI General Purpose Event 0 (GPE0) i/o-mapped base address. + This device is defined in ACPI specification, with 64 bytes in size. + +config WDT_BASE + hex + default 0x1140 + help + Watchdog timer i/o-mapped base address. + +config SYS_CAR_ADDR + hex + default ESRAM_BASE + +config SYS_CAR_SIZE + hex + default 0x8000 + help + Space in bytes in eSRAM used as Cache-As-ARM (CAR). + Note this size must not exceed eSRAM's total size. + +endif diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile new file mode 100644 index 0000000000..168c1e6c3a --- /dev/null +++ b/arch/x86/cpu/quark/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += car.o dram.o msg_port.o quark.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c new file mode 100644 index 0000000000..fbdc3cde05 --- /dev/null +++ b/arch/x86/cpu/quark/dram.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + /* hardcode the DRAM size for now */ + gd->ram_size = DRAM_MAX_SIZE; + post_code(POST_DRAM); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_size; +} diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c new file mode 100644 index 0000000000..354e15a990 --- /dev/null +++ b/arch/x86/cpu/quark/pci.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void board_pci_setup_hose(struct pci_controller *hose) +{ + hose->first_busno = 0; + hose->last_busno = 0; + + /* PCI memory space */ + pci_set_region(hose->regions + 0, + CONFIG_PCI_MEM_BUS, + CONFIG_PCI_MEM_PHYS, + CONFIG_PCI_MEM_SIZE, + PCI_REGION_MEM); + + /* PCI IO space */ + pci_set_region(hose->regions + 1, + CONFIG_PCI_IO_BUS, + CONFIG_PCI_IO_PHYS, + CONFIG_PCI_IO_SIZE, + PCI_REGION_IO); + + pci_set_region(hose->regions + 2, + CONFIG_PCI_PREF_BUS, + CONFIG_PCI_PREF_PHYS, + CONFIG_PCI_PREF_SIZE, + PCI_REGION_PREFETCH); + + pci_set_region(hose->regions + 3, + 0, + 0, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 4; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + return 0; +} + +int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) +{ + /* + * TODO: + * + * For some unknown reason, the PCI enumeration process hangs + * when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1). + * + * For now we just skip these two devices, and this needs to + * be revisited later. + */ + if (dev == QUARK_HOST_BRIDGE || + dev == QUARK_PCIE0 || dev == QUARK_PCIE1) { + return 1; + } + + return 0; +} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c new file mode 100644 index 0000000000..47ba15253f --- /dev/null +++ b/arch/x86/cpu/quark/quark.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int arch_cpu_init(void) +{ + struct pci_controller *hose; + int ret; + + post_code(POST_CPU_INIT); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(rdtsc()); +#endif + + ret = x86_cpu_init_f(); + if (ret) + return ret; + + ret = pci_early_init_hose(&hose); + if (ret) + return ret; + + return 0; +} + +int print_cpuinfo(void) +{ + post_code(POST_CPU_INFO); + return default_print_cpuinfo(); +} + +void reset_cpu(ulong addr) +{ + /* cold reset */ + outb(0x08, PORT_RESET); +} diff --git a/arch/x86/include/asm/arch-quark/gpio.h b/arch/x86/include/asm/arch-quark/gpio.h new file mode 100644 index 0000000000..ca8cba4f97 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44 + +#endif /* _X86_ARCH_GPIO_H_ */ -- cgit From afee3fb8c807e1ac9713ecb31d895008e3b5251a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:28 +0800 Subject: x86: Add basic Intel Galileo board support New board/intel/galileo board directory with minimum codes, plus board dts, defconfig and configuration files. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Acked-by: Simon Glass --- arch/x86/dts/Makefile | 1 + arch/x86/dts/galileo.dts | 43 +++++++++++++++++++++++++++++++++ board/intel/galileo/Kconfig | 21 ++++++++++++++++ board/intel/galileo/MAINTAINERS | 6 +++++ board/intel/galileo/Makefile | 7 ++++++ board/intel/galileo/galileo.c | 19 +++++++++++++++ board/intel/galileo/start.S | 9 +++++++ configs/galileo_defconfig | 6 +++++ include/configs/galileo.h | 53 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 165 insertions(+) create mode 100644 arch/x86/dts/galileo.dts create mode 100644 board/intel/galileo/Kconfig create mode 100644 board/intel/galileo/MAINTAINERS create mode 100644 board/intel/galileo/Makefile create mode 100644 board/intel/galileo/galileo.c create mode 100644 board/intel/galileo/start.S create mode 100644 configs/galileo_defconfig create mode 100644 include/configs/galileo.h diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 4e0171a058..7a66133555 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -1,5 +1,6 @@ dtb-y += chromebook_link.dtb \ crownbay.dtb \ + galileo.dtb \ minnowmax.dtb targets += $(dtb-y) diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts new file mode 100644 index 0000000000..14a19c3ec3 --- /dev/null +++ b/arch/x86/dts/galileo.dts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + model = "Intel Galileo"; + compatible = "intel,galileo", "intel,quark"; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = &pciuart0; + }; + + pci { + #address-cells = <3>; + #size-cells = <2>; + compatible = "intel,pci"; + device_type = "pci"; + + pciuart0: uart@14,5 { + compatible = "pci8086,0936.00", + "pci8086,0936", + "pciclass,070002", + "pciclass,0700", + "x86-uart"; + reg = <0x0000a500 0x0 0x0 0x0 0x0 + 0x0200a510 0x0 0x0 0x0 0x0>; + reg-shift = <2>; + clock-frequency = <44236800>; + current-speed = <115200>; + }; + }; + +}; diff --git a/board/intel/galileo/Kconfig b/board/intel/galileo/Kconfig new file mode 100644 index 0000000000..85afbbc8c5 --- /dev/null +++ b/board/intel/galileo/Kconfig @@ -0,0 +1,21 @@ +if TARGET_GALILEO + +config SYS_BOARD + default "galileo" + +config SYS_VENDOR + default "intel" + +config SYS_SOC + default "quark" + +config SYS_CONFIG_NAME + default "galileo" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select INTEL_QUARK + select BOARD_ROMSIZE_KB_1024 + +endif diff --git a/board/intel/galileo/MAINTAINERS b/board/intel/galileo/MAINTAINERS new file mode 100644 index 0000000000..dbbc82e8a1 --- /dev/null +++ b/board/intel/galileo/MAINTAINERS @@ -0,0 +1,6 @@ +INTEL GALILEO BOARD +M: Bin Meng +S: Maintained +F: board/intel/galileo/ +F: include/configs/galileo.h +F: configs/galileo_defconfig diff --git a/board/intel/galileo/Makefile b/board/intel/galileo/Makefile new file mode 100644 index 0000000000..8356df198c --- /dev/null +++ b/board/intel/galileo/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += galileo.o start.o diff --git a/board/intel/galileo/galileo.c b/board/intel/galileo/galileo.c new file mode 100644 index 0000000000..f2e74687ed --- /dev/null +++ b/board/intel/galileo/galileo.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_early_init_f(void) +{ + return 0; +} + +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) +{ + return; +} diff --git a/board/intel/galileo/start.S b/board/intel/galileo/start.S new file mode 100644 index 0000000000..a71db69be9 --- /dev/null +++ b/board/intel/galileo/start.S @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig new file mode 100644 index 0000000000..f2086514be --- /dev/null +++ b/configs/galileo_defconfig @@ -0,0 +1,6 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff10000" +CONFIG_X86=y +CONFIG_TARGET_GALILEO=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="galileo" diff --git a/include/configs/galileo.h b/include/configs/galileo.h new file mode 100644 index 0000000000..bead2fc64e --- /dev/null +++ b/include/configs/galileo.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) +#define CONFIG_BOARD_EARLY_INIT_F + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_X86_SERIAL + +/* ns16550 UART is memory-mapped in Quark SoC */ +#undef CONFIG_SYS_NS16550_PORT_MAPPED + +#define CONFIG_PCI_MEM_BUS 0x90000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x20000000 + +#define CONFIG_PCI_PREF_BUS 0xb0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x20000000 + +#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000 + +#define CONFIG_SYS_EARLY_PCI_INIT +#define CONFIG_PCI_PNP + +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" + +/* SATA is not supported in Quark SoC */ +#undef CONFIG_SCSI_AHCI +#undef CONFIG_CMD_SCSI + +/* Video is not supported in Quark SoC */ +#undef CONFIG_VIDEO +#undef CONFIG_CFB_CONSOLE + +#endif /* __CONFIG_H */ -- cgit From ef46bea02b7f0d840d18c1a26db6aa9da8488868 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 22:35:29 +0800 Subject: x86: Enable the Intel quark/galileo build Make the Intel quark/galileo support avaiable in Kconfig and Makefile. With this patch, we can generate u-boot.rom for Intel galileo board. Signed-off-by: Bin Meng Reviewed-by: Simon Glass Acked-by: Simon Glass --- arch/x86/Kconfig | 17 +++++++++++++++++ arch/x86/cpu/Makefile | 1 + 2 files changed, 18 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index defdce76b1..85dda2e1ea 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -52,6 +52,19 @@ config TARGET_MINNOWMAX Note that PCIE_ECAM_BASE is set up by the FSP so the value used by U-Boot matches that value. +config TARGET_GALILEO + bool "Support Intel Galileo" + help + This is the Intel Galileo board, which is the first in a family of + Arduino-certified development and prototyping boards based on Intel + architecture. It includes an Intel Quark SoC X1000 processor, a 32-bit + single-core, single-thread, Intel Pentium processor instrunction set + architecture (ISA) compatible, operating at speeds up to 400Mhz, + along with 256MB DDR3 memory. It supports a wide range of industry + standard I/O interfaces, including a full-sized mini-PCIe slot, + one 100Mb Ethernet port, a microSD card slot, a USB host port and + a USB client port. + endchoice config RAMBASE @@ -399,6 +412,8 @@ source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" +source "arch/x86/cpu/quark/Kconfig" + source "arch/x86/cpu/queensbay/Kconfig" source "board/coreboot/coreboot/Kconfig" @@ -409,6 +424,8 @@ source "board/intel/crownbay/Kconfig" source "board/intel/minnowmax/Kconfig" +source "board/intel/galileo/Kconfig" + config PCIE_ECAM_BASE hex default 0xe0000000 diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 5acf8bb427..6ded0a7f0f 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ +obj-$(CONFIG_INTEL_QUARK) += quark/ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ obj-y += lapic.o obj-y += mtrr.o -- cgit From f56aeaa4accf541641e14343adfd4614dc4b67d0 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:20 +0800 Subject: x86: Allow overriding TSC_FREQ_IN_MHZ We should allow the value of TSC_FREQ_IN_MHZ to be overridden by the one in arch/cpu//Kconfig. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/Kconfig | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 85dda2e1ea..2370c323ef 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -348,26 +348,6 @@ config FRAMEBUFFER_VESA_MODE endmenu -config TSC_CALIBRATION_BYPASS - bool "Bypass Time-Stamp Counter (TSC) calibration" - default n - help - By default U-Boot automatically calibrates Time-Stamp Counter (TSC) - running frequency via Model-Specific Register (MSR) and Programmable - Interval Timer (PIT). If the calibration does not work on your board, - select this option and provide a hardcoded TSC running frequency with - CONFIG_TSC_FREQ_IN_MHZ below. - - Normally this option should be turned on in a simulation environment - like qemu. - -config TSC_FREQ_IN_MHZ - int "Time-Stamp Counter (TSC) running frequency in MHz" - depends on TSC_CALIBRATION_BYPASS - default 1000 - help - The running frequency in MHz of Time-Stamp Counter (TSC). - config HAVE_FSP bool "Add an Firmware Support Package binary" help @@ -416,6 +396,26 @@ source "arch/x86/cpu/quark/Kconfig" source "arch/x86/cpu/queensbay/Kconfig" +config TSC_CALIBRATION_BYPASS + bool "Bypass Time-Stamp Counter (TSC) calibration" + default n + help + By default U-Boot automatically calibrates Time-Stamp Counter (TSC) + running frequency via Model-Specific Register (MSR) and Programmable + Interval Timer (PIT). If the calibration does not work on your board, + select this option and provide a hardcoded TSC running frequency with + CONFIG_TSC_FREQ_IN_MHZ below. + + Normally this option should be turned on in a simulation environment + like qemu. + +config TSC_FREQ_IN_MHZ + int "Time-Stamp Counter (TSC) running frequency in MHz" + depends on TSC_CALIBRATION_BYPASS + default 1000 + help + The running frequency in MHz of Time-Stamp Counter (TSC). + source "board/coreboot/coreboot/Kconfig" source "board/google/chromebook_link/Kconfig" -- cgit From ea94532461e166f6febdd9bda5caa8f1b127b39f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:21 +0800 Subject: x86: quark: Bypass TSC calibration For some unknown reason, the TSC calibration via PIT does not work on Quark. Enable bypassing TSC calibration and override TSC_FREQ_IN_MHZ to 400 per Quark datasheet in the Kconfig. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/cpu/quark/Kconfig b/arch/x86/cpu/quark/Kconfig index 163caac660..bc961ef07c 100644 --- a/arch/x86/cpu/quark/Kconfig +++ b/arch/x86/cpu/quark/Kconfig @@ -7,6 +7,7 @@ config INTEL_QUARK bool select HAVE_RMU + select TSC_CALIBRATION_BYPASS if INTEL_QUARK @@ -118,4 +119,8 @@ config SYS_CAR_SIZE Space in bytes in eSRAM used as Cache-As-ARM (CAR). Note this size must not exceed eSRAM's total size. +config TSC_FREQ_IN_MHZ + int + default 400 + endif -- cgit From 0a391b1c797ba9deb8d746cf98a08b394f42e0ee Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:22 +0800 Subject: x86: quark: Add Memory Reference Code (MRC) main routines Add the main routines for Quark Memory Reference Code (MRC). Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/mrc.c | 204 ++++++++++++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/mrc.h | 187 +++++++++++++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 arch/x86/cpu/quark/mrc.c create mode 100644 arch/x86/include/asm/arch-quark/mrc.h diff --git a/arch/x86/cpu/quark/mrc.c b/arch/x86/cpu/quark/mrc.c new file mode 100644 index 0000000000..7eb34c5302 --- /dev/null +++ b/arch/x86/cpu/quark/mrc.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +/* + * This is the main Quark Memory Reference Code (MRC) + * + * These functions are generic and should work for any Quark-based board. + * + * MRC requires two data structures to be passed in which are initialized by + * mrc_adjust_params(). + * + * The basic flow is as follows: + * 01) Check for supported DDR speed configuration + * 02) Set up Memory Manager buffer as pass-through (POR) + * 03) Set Channel Interleaving Mode and Channel Stride to the most aggressive + * setting possible + * 04) Set up the Memory Controller logic + * 05) Set up the DDR_PHY logic + * 06) Initialise the DRAMs (JEDEC) + * 07) Perform the Receive Enable Calibration algorithm + * 08) Perform the Write Leveling algorithm + * 09) Perform the Read Training algorithm (includes internal Vref) + * 10) Perform the Write Training algorithm + * 11) Set Channel Interleaving Mode and Channel Stride to the desired settings + * + * DRAM unit configuration based on Valleyview MRC. + */ + +#include +#include +#include +#include "mrc_util.h" +#include "smc.h" + +static const struct mem_init init[] = { + { 0x0101, BM_COLD | BM_FAST | BM_WARM | BM_S3, clear_self_refresh }, + { 0x0200, BM_COLD | BM_FAST | BM_WARM | BM_S3, prog_ddr_timing_control }, + { 0x0103, BM_COLD | BM_FAST , prog_decode_before_jedec }, + { 0x0104, BM_COLD | BM_FAST , perform_ddr_reset }, + { 0x0300, BM_COLD | BM_FAST | BM_S3, ddrphy_init }, + { 0x0400, BM_COLD | BM_FAST , perform_jedec_init }, + { 0x0105, BM_COLD | BM_FAST , set_ddr_init_complete }, + { 0x0106, BM_FAST | BM_WARM | BM_S3, restore_timings }, + { 0x0106, BM_COLD , default_timings }, + { 0x0500, BM_COLD , rcvn_cal }, + { 0x0600, BM_COLD , wr_level }, + { 0x0120, BM_COLD , prog_page_ctrl }, + { 0x0700, BM_COLD , rd_train }, + { 0x0800, BM_COLD , wr_train }, + { 0x010b, BM_COLD , store_timings }, + { 0x010c, BM_COLD | BM_FAST | BM_WARM | BM_S3, enable_scrambling }, + { 0x010d, BM_COLD | BM_FAST | BM_WARM | BM_S3, prog_ddr_control }, + { 0x010e, BM_COLD | BM_FAST | BM_WARM | BM_S3, prog_dra_drb }, + { 0x010f, BM_WARM | BM_S3, perform_wake }, + { 0x0110, BM_COLD | BM_FAST | BM_WARM | BM_S3, change_refresh_period }, + { 0x0111, BM_COLD | BM_FAST | BM_WARM | BM_S3, set_auto_refresh }, + { 0x0112, BM_COLD | BM_FAST | BM_WARM | BM_S3, ecc_enable }, + { 0x0113, BM_COLD | BM_FAST , memory_test }, + { 0x0114, BM_COLD | BM_FAST | BM_WARM | BM_S3, lock_registers } +}; + +/* Adjust configuration parameters before initialization sequence */ +static void mrc_adjust_params(struct mrc_params *mrc_params) +{ + const struct dram_params *dram_params; + uint8_t dram_width; + uint32_t rank_enables; + uint32_t channel_width; + + ENTERFN(); + + /* initially expect success */ + mrc_params->status = MRC_SUCCESS; + + dram_width = mrc_params->dram_width; + rank_enables = mrc_params->rank_enables; + channel_width = mrc_params->channel_width; + + /* + * Setup board layout (must be reviewed as is selecting static timings) + * 0 == R0 (DDR3 x16), 1 == R1 (DDR3 x16), + * 2 == DV (DDR3 x8), 3 == SV (DDR3 x8). + */ + if (dram_width == X8) + mrc_params->board_id = 2; /* select x8 layout */ + else + mrc_params->board_id = 0; /* select x16 layout */ + + /* initially no memory */ + mrc_params->mem_size = 0; + + /* begin of channel settings */ + dram_params = &mrc_params->params; + + /* + * Determine column bits: + * + * Column: 11 for 8Gbx8, else 10 + */ + mrc_params->column_bits[0] = + ((dram_params[0].density == 4) && + (dram_width == X8)) ? (11) : (10); + + /* + * Determine row bits: + * + * 512Mbx16=12 512Mbx8=13 + * 1Gbx16=13 1Gbx8=14 + * 2Gbx16=14 2Gbx8=15 + * 4Gbx16=15 4Gbx8=16 + * 8Gbx16=16 8Gbx8=16 + */ + mrc_params->row_bits[0] = 12 + (dram_params[0].density) + + (((dram_params[0].density < 4) && + (dram_width == X8)) ? (1) : (0)); + + /* + * Determine per-channel memory size: + * + * (For 2 RANKs, multiply by 2) + * (For 16 bit data bus, divide by 2) + * + * DENSITY WIDTH MEM_AVAILABLE + * 512Mb x16 0x008000000 ( 128MB) + * 512Mb x8 0x010000000 ( 256MB) + * 1Gb x16 0x010000000 ( 256MB) + * 1Gb x8 0x020000000 ( 512MB) + * 2Gb x16 0x020000000 ( 512MB) + * 2Gb x8 0x040000000 (1024MB) + * 4Gb x16 0x040000000 (1024MB) + * 4Gb x8 0x080000000 (2048MB) + */ + mrc_params->channel_size[0] = (1 << dram_params[0].density); + mrc_params->channel_size[0] *= (dram_width == X8) ? 2 : 1; + mrc_params->channel_size[0] *= (rank_enables == 0x3) ? 2 : 1; + mrc_params->channel_size[0] *= (channel_width == X16) ? 1 : 2; + + /* Determine memory size (convert number of 64MB/512Mb units) */ + mrc_params->mem_size += mrc_params->channel_size[0] << 26; + + LEAVEFN(); +} + +static void mrc_mem_init(struct mrc_params *mrc_params) +{ + int i; + + ENTERFN(); + + /* MRC started */ + mrc_post_code(0x01, 0x00); + + if (mrc_params->boot_mode != BM_COLD) { + if (mrc_params->ddr_speed != mrc_params->timings.ddr_speed) { + /* full training required as frequency changed */ + mrc_params->boot_mode = BM_COLD; + } + } + + for (i = 0; i < ARRAY_SIZE(init); i++) { + uint64_t my_tsc; + + if (mrc_params->boot_mode & init[i].boot_path) { + uint8_t major = init[i].post_code >> 8 & 0xff; + uint8_t minor = init[i].post_code >> 0 & 0xff; + mrc_post_code(major, minor); + + my_tsc = rdtsc(); + init[i].init_fn(mrc_params); + DPF(D_TIME, "Execution time %llx", rdtsc() - my_tsc); + } + } + + /* display the timings */ + print_timings(mrc_params); + + /* MRC complete */ + mrc_post_code(0x01, 0xff); + + LEAVEFN(); +} + +void mrc_init(struct mrc_params *mrc_params) +{ + ENTERFN(); + + DPF(D_INFO, "MRC Version %04x %s %s\n", MRC_VERSION, + __DATE__, __TIME__); + + /* Set up the data structures used by mrc_mem_init() */ + mrc_adjust_params(mrc_params); + + /* Initialize system memory */ + mrc_mem_init(mrc_params); + + LEAVEFN(); +} diff --git a/arch/x86/include/asm/arch-quark/mrc.h b/arch/x86/include/asm/arch-quark/mrc.h new file mode 100644 index 0000000000..150fbea0e0 --- /dev/null +++ b/arch/x86/include/asm/arch-quark/mrc.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _MRC_H_ +#define _MRC_H_ + +#define MRC_VERSION 0x0111 + +/* architectural definitions */ +#define NUM_CHANNELS 1 /* number of channels */ +#define NUM_RANKS 2 /* number of ranks per channel */ +#define NUM_BYTE_LANES 4 /* number of byte lanes per channel */ + +/* software limitations */ +#define MAX_CHANNELS 1 +#define MAX_RANKS 2 +#define MAX_BYTE_LANES 4 + +#define MAX_SOCKETS 1 +#define MAX_SIDES 1 +#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS) + +/* Specify DRAM and channel width */ +enum { + X8, /* DRAM width */ + X16, /* DRAM width & Channel Width */ + X32 /* Channel Width */ +}; + +/* Specify DRAM speed */ +enum { + DDRFREQ_800, + DDRFREQ_1066 +}; + +/* Specify DRAM type */ +enum { + DDR3, + DDR3L +}; + +/* + * density: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb + * cl: DRAM CAS Latency in clocks + * ras: ACT to PRE command period + * wtr: Delay from start of internal write transaction to internal read command + * rrd: ACT to ACT command period (JESD79 specific to page size 1K/2K) + * faw: Four activate window (JESD79 specific to page size 1K/2K) + * + * ras/wtr/rrd/faw timings are in picoseconds + * + * Refer to JEDEC spec (or DRAM datasheet) when changing these values. + */ +struct dram_params { + uint8_t density; + uint8_t cl; + uint32_t ras; + uint32_t wtr; + uint32_t rrd; + uint32_t faw; +}; + +/* + * Delay configuration for individual signals + * Vref setting + * Scrambler seed + */ +struct mrc_timings { + uint32_t rcvn[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t rdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t wdqs[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t wdq[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t vref[NUM_CHANNELS][NUM_BYTE_LANES]; + uint32_t wctl[NUM_CHANNELS][NUM_RANKS]; + uint32_t wcmd[NUM_CHANNELS]; + uint32_t scrambler_seed; + /* need to save for the case of frequency change */ + uint8_t ddr_speed; +}; + +/* Boot mode defined as bit mask (1< Date: Thu, 5 Feb 2015 23:42:23 +0800 Subject: x86: quark: Add utility codes needed for MRC Add various utility codes needed for Quark MRC. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/hte.c | 396 +++++++++++ arch/x86/cpu/quark/hte.h | 44 ++ arch/x86/cpu/quark/mrc_util.c | 1475 +++++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/mrc_util.h | 153 +++++ 4 files changed, 2068 insertions(+) create mode 100644 arch/x86/cpu/quark/hte.c create mode 100644 arch/x86/cpu/quark/hte.h create mode 100644 arch/x86/cpu/quark/mrc_util.c create mode 100644 arch/x86/cpu/quark/mrc_util.h diff --git a/arch/x86/cpu/quark/hte.c b/arch/x86/cpu/quark/hte.c new file mode 100644 index 0000000000..372815d8c1 --- /dev/null +++ b/arch/x86/cpu/quark/hte.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#include +#include +#include +#include "mrc_util.h" +#include "hte.h" + +/** + * Enable HTE to detect all possible errors for the given training parameters + * (per-bit or full byte lane). + */ +static void hte_enable_all_errors(void) +{ + msg_port_write(HTE, 0x000200A2, 0xFFFFFFFF); + msg_port_write(HTE, 0x000200A3, 0x000000FF); + msg_port_write(HTE, 0x000200A4, 0x00000000); +} + +/** + * Go and read the HTE register in order to find any error + * + * @return: The errors detected in the HTE status register + */ +static u32 hte_check_errors(void) +{ + return msg_port_read(HTE, 0x000200A7); +} + +/** + * Wait until HTE finishes + */ +static void hte_wait_for_complete(void) +{ + u32 tmp; + + ENTERFN(); + + do {} while ((msg_port_read(HTE, 0x00020012) & BIT30) != 0); + + tmp = msg_port_read(HTE, 0x00020011); + tmp |= BIT9; + tmp &= ~(BIT12 | BIT13); + msg_port_write(HTE, 0x00020011, tmp); + + LEAVEFN(); +} + +/** + * Clear registers related with errors in the HTE + */ +static void hte_clear_error_regs(void) +{ + u32 tmp; + + /* + * Clear all HTE errors and enable error checking + * for burst and chunk. + */ + tmp = msg_port_read(HTE, 0x000200A1); + tmp |= BIT8; + msg_port_write(HTE, 0x000200A1, tmp); +} + +/** + * Execute a basic single-cache-line memory write/read/verify test using simple + * constant pattern, different for READ_TRAIN and WRITE_TRAIN modes. + * + * See hte_basic_write_read() which is the external visible wrapper. + * + * @mrc_params: host structure for all MRC global data + * @addr: memory adress being tested (must hit specific channel/rank) + * @first_run: if set then the HTE registers are configured, otherwise it is + * assumed configuration is done and we just re-run the test + * @mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern) + * + * @return: byte lane failure on each bit (for Quark only bit0 and bit1) + */ +static u16 hte_basic_data_cmp(struct mrc_params *mrc_params, u32 addr, + u8 first_run, u8 mode) +{ + u32 pattern; + u32 offset; + + if (first_run) { + msg_port_write(HTE, 0x00020020, 0x01B10021); + msg_port_write(HTE, 0x00020021, 0x06000000); + msg_port_write(HTE, 0x00020022, addr >> 6); + msg_port_write(HTE, 0x00020062, 0x00800015); + msg_port_write(HTE, 0x00020063, 0xAAAAAAAA); + msg_port_write(HTE, 0x00020064, 0xCCCCCCCC); + msg_port_write(HTE, 0x00020065, 0xF0F0F0F0); + msg_port_write(HTE, 0x00020061, 0x00030008); + + if (mode == WRITE_TRAIN) + pattern = 0xC33C0000; + else /* READ_TRAIN */ + pattern = 0xAA5555AA; + + for (offset = 0x80; offset <= 0x8F; offset++) + msg_port_write(HTE, offset, pattern); + } + + msg_port_write(HTE, 0x000200A1, 0xFFFF1000); + msg_port_write(HTE, 0x00020011, 0x00011000); + msg_port_write(HTE, 0x00020011, 0x00011100); + + hte_wait_for_complete(); + + /* + * Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for + * any bytelane errors. + */ + return (hte_check_errors() >> 8) & 0xFF; +} + +/** + * Examine a single-cache-line memory with write/read/verify test using multiple + * data patterns (victim-aggressor algorithm). + * + * See hte_write_stress_bit_lanes() which is the external visible wrapper. + * + * @mrc_params: host structure for all MRC global data + * @addr: memory adress being tested (must hit specific channel/rank) + * @loop_cnt: number of test iterations + * @seed_victim: victim data pattern seed + * @seed_aggressor: aggressor data pattern seed + * @victim_bit: should be 0 as auto-rotate feature is in use + * @first_run: if set then the HTE registers are configured, otherwise it is + * assumed configuration is done and we just re-run the test + * + * @return: byte lane failure on each bit (for Quark only bit0 and bit1) + */ +static u16 hte_rw_data_cmp(struct mrc_params *mrc_params, u32 addr, + u8 loop_cnt, u32 seed_victim, u32 seed_aggressor, + u8 victim_bit, u8 first_run) +{ + u32 offset; + u32 tmp; + + if (first_run) { + msg_port_write(HTE, 0x00020020, 0x00910024); + msg_port_write(HTE, 0x00020023, 0x00810024); + msg_port_write(HTE, 0x00020021, 0x06070000); + msg_port_write(HTE, 0x00020024, 0x06070000); + msg_port_write(HTE, 0x00020022, addr >> 6); + msg_port_write(HTE, 0x00020025, addr >> 6); + msg_port_write(HTE, 0x00020062, 0x0000002A); + msg_port_write(HTE, 0x00020063, seed_victim); + msg_port_write(HTE, 0x00020064, seed_aggressor); + msg_port_write(HTE, 0x00020065, seed_victim); + + /* + * Write the pattern buffers to select the victim bit + * + * Start with bit0 + */ + for (offset = 0x80; offset <= 0x8F; offset++) { + if ((offset % 8) == victim_bit) + msg_port_write(HTE, offset, 0x55555555); + else + msg_port_write(HTE, offset, 0xCCCCCCCC); + } + + msg_port_write(HTE, 0x00020061, 0x00000000); + msg_port_write(HTE, 0x00020066, 0x03440000); + msg_port_write(HTE, 0x000200A1, 0xFFFF1000); + } + + tmp = 0x10001000 | (loop_cnt << 16); + msg_port_write(HTE, 0x00020011, tmp); + msg_port_write(HTE, 0x00020011, tmp | BIT8); + + hte_wait_for_complete(); + + /* + * Return bits 15:8 of HTE_CH0_ERR_XSTAT to check for + * any bytelane errors. + */ + return (hte_check_errors() >> 8) & 0xFF; +} + +/** + * Use HW HTE engine to initialize or test all memory attached to a given DUNIT. + * If flag is MRC_MEM_INIT, this routine writes 0s to all memory locations to + * initialize ECC. If flag is MRC_MEM_TEST, this routine will send an 5AA55AA5 + * pattern to all memory locations on the RankMask and then read it back. + * Then it sends an A55AA55A pattern to all memory locations on the RankMask + * and reads it back. + * + * @mrc_params: host structure for all MRC global data + * @flag: MRC_MEM_INIT or MRC_MEM_TEST + * + * @return: errors register showing HTE failures. Also prints out which rank + * failed the HTE test if failure occurs. For rank detection to work, + * the address map must be left in its default state. If MRC changes + * the address map, this function must be modified to change it back + * to default at the beginning, then restore it at the end. + */ +u32 hte_mem_init(struct mrc_params *mrc_params, u8 flag) +{ + u32 offset; + int test_num; + int i; + + /* + * Clear out the error registers at the start of each memory + * init or memory test run. + */ + hte_clear_error_regs(); + + msg_port_write(HTE, 0x00020062, 0x00000015); + + for (offset = 0x80; offset <= 0x8F; offset++) + msg_port_write(HTE, offset, ((offset & 1) ? 0xA55A : 0x5AA5)); + + msg_port_write(HTE, 0x00020021, 0x00000000); + msg_port_write(HTE, 0x00020022, (mrc_params->mem_size >> 6) - 1); + msg_port_write(HTE, 0x00020063, 0xAAAAAAAA); + msg_port_write(HTE, 0x00020064, 0xCCCCCCCC); + msg_port_write(HTE, 0x00020065, 0xF0F0F0F0); + msg_port_write(HTE, 0x00020066, 0x03000000); + + switch (flag) { + case MRC_MEM_INIT: + /* + * Only 1 write pass through memory is needed + * to initialize ECC + */ + test_num = 1; + break; + case MRC_MEM_TEST: + /* Write/read then write/read with inverted pattern */ + test_num = 4; + break; + default: + DPF(D_INFO, "Unknown parameter for flag: %d\n", flag); + return 0xFFFFFFFF; + } + + DPF(D_INFO, "hte_mem_init"); + + for (i = 0; i < test_num; i++) { + DPF(D_INFO, "."); + + if (i == 0) { + msg_port_write(HTE, 0x00020061, 0x00000000); + msg_port_write(HTE, 0x00020020, 0x00110010); + } else if (i == 1) { + msg_port_write(HTE, 0x00020061, 0x00000000); + msg_port_write(HTE, 0x00020020, 0x00010010); + } else if (i == 2) { + msg_port_write(HTE, 0x00020061, 0x00010100); + msg_port_write(HTE, 0x00020020, 0x00110010); + } else { + msg_port_write(HTE, 0x00020061, 0x00010100); + msg_port_write(HTE, 0x00020020, 0x00010010); + } + + msg_port_write(HTE, 0x00020011, 0x00111000); + msg_port_write(HTE, 0x00020011, 0x00111100); + + hte_wait_for_complete(); + + /* If this is a READ pass, check for errors at the end */ + if ((i % 2) == 1) { + /* Return immediately if error */ + if (hte_check_errors()) + break; + } + } + + DPF(D_INFO, "done\n"); + + return hte_check_errors(); +} + +/** + * Execute a basic single-cache-line memory write/read/verify test using simple + * constant pattern, different for READ_TRAIN and WRITE_TRAIN modes. + * + * @mrc_params: host structure for all MRC global data + * @addr: memory adress being tested (must hit specific channel/rank) + * @first_run: if set then the HTE registers are configured, otherwise it is + * assumed configuration is done and we just re-run the test + * @mode: READ_TRAIN or WRITE_TRAIN (the difference is in the pattern) + * + * @return: byte lane failure on each bit (for Quark only bit0 and bit1) + */ +u16 hte_basic_write_read(struct mrc_params *mrc_params, u32 addr, + u8 first_run, u8 mode) +{ + u16 errors; + + ENTERFN(); + + /* Enable all error reporting in preparation for HTE test */ + hte_enable_all_errors(); + hte_clear_error_regs(); + + errors = hte_basic_data_cmp(mrc_params, addr, first_run, mode); + + LEAVEFN(); + + return errors; +} + +/** + * Examine a single-cache-line memory with write/read/verify test using multiple + * data patterns (victim-aggressor algorithm). + * + * @mrc_params: host structure for all MRC global data + * @addr: memory adress being tested (must hit specific channel/rank) + * @first_run: if set then the HTE registers are configured, otherwise it is + * assumed configuration is done and we just re-run the test + * + * @return: byte lane failure on each bit (for Quark only bit0 and bit1) + */ +u16 hte_write_stress_bit_lanes(struct mrc_params *mrc_params, + u32 addr, u8 first_run) +{ + u16 errors; + u8 victim_bit = 0; + + ENTERFN(); + + /* Enable all error reporting in preparation for HTE test */ + hte_enable_all_errors(); + hte_clear_error_regs(); + + /* + * Loop through each bit in the bytelane. + * + * Each pass creates a victim bit while keeping all other bits the same + * as aggressors. AVN HTE adds an auto-rotate feature which allows us + * to program the entire victim/aggressor sequence in 1 step. + * + * The victim bit rotates on each pass so no need to have software + * implement a victim bit loop like on VLV. + */ + errors = hte_rw_data_cmp(mrc_params, addr, HTE_LOOP_CNT, + HTE_LFSR_VICTIM_SEED, HTE_LFSR_AGRESSOR_SEED, + victim_bit, first_run); + + LEAVEFN(); + + return errors; +} + +/** + * Execute a basic single-cache-line memory write or read. + * This is just for receive enable / fine write-levelling purpose. + * + * @addr: memory adress being tested (must hit specific channel/rank) + * @first_run: if set then the HTE registers are configured, otherwise it is + * assumed configuration is done and we just re-run the test + * @is_write: when non-zero memory write operation executed, otherwise read + */ +void hte_mem_op(u32 addr, u8 first_run, u8 is_write) +{ + u32 offset; + u32 tmp; + + hte_enable_all_errors(); + hte_clear_error_regs(); + + if (first_run) { + tmp = is_write ? 0x01110021 : 0x01010021; + msg_port_write(HTE, 0x00020020, tmp); + + msg_port_write(HTE, 0x00020021, 0x06000000); + msg_port_write(HTE, 0x00020022, addr >> 6); + msg_port_write(HTE, 0x00020062, 0x00800015); + msg_port_write(HTE, 0x00020063, 0xAAAAAAAA); + msg_port_write(HTE, 0x00020064, 0xCCCCCCCC); + msg_port_write(HTE, 0x00020065, 0xF0F0F0F0); + msg_port_write(HTE, 0x00020061, 0x00030008); + + for (offset = 0x80; offset <= 0x8F; offset++) + msg_port_write(HTE, offset, 0xC33C0000); + } + + msg_port_write(HTE, 0x000200A1, 0xFFFF1000); + msg_port_write(HTE, 0x00020011, 0x00011000); + msg_port_write(HTE, 0x00020011, 0x00011100); + + hte_wait_for_complete(); +} diff --git a/arch/x86/cpu/quark/hte.h b/arch/x86/cpu/quark/hte.h new file mode 100644 index 0000000000..6577796fd6 --- /dev/null +++ b/arch/x86/cpu/quark/hte.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _HTE_H_ +#define _HTE_H_ + +enum { + MRC_MEM_INIT, + MRC_MEM_TEST +}; + +enum { + READ_TRAIN, + WRITE_TRAIN +}; + +/* + * EXP_LOOP_CNT field of HTE_CMD_CTL + * + * This CANNOT be less than 4! + */ +#define HTE_LOOP_CNT 5 + +/* random seed for victim */ +#define HTE_LFSR_VICTIM_SEED 0xF294BA21 + +/* random seed for aggressor */ +#define HTE_LFSR_AGRESSOR_SEED 0xEBA7492D + +u32 hte_mem_init(struct mrc_params *mrc_params, u8 flag); +u16 hte_basic_write_read(struct mrc_params *mrc_params, u32 addr, + u8 first_run, u8 mode); +u16 hte_write_stress_bit_lanes(struct mrc_params *mrc_params, + u32 addr, u8 first_run); +void hte_mem_op(u32 addr, u8 first_run, u8 is_write); + +#endif /* _HTE_H_ */ diff --git a/arch/x86/cpu/quark/mrc_util.c b/arch/x86/cpu/quark/mrc_util.c new file mode 100644 index 0000000000..3a79ae551b --- /dev/null +++ b/arch/x86/cpu/quark/mrc_util.c @@ -0,0 +1,1475 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#include +#include +#include +#include +#include "mrc_util.h" +#include "hte.h" +#include "smc.h" + +static const uint8_t vref_codes[64] = { + /* lowest to highest */ + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, + 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F +}; + +void mrc_write_mask(u32 unit, u32 addr, u32 data, u32 mask) +{ + msg_port_write(unit, addr, + (msg_port_read(unit, addr) & ~(mask)) | + ((data) & (mask))); +} + +void mrc_alt_write_mask(u32 unit, u32 addr, u32 data, u32 mask) +{ + msg_port_alt_write(unit, addr, + (msg_port_alt_read(unit, addr) & ~(mask)) | + ((data) & (mask))); +} + +void mrc_post_code(uint8_t major, uint8_t minor) +{ + /* send message to UART */ + DPF(D_INFO, "POST: 0x%01x%02x\n", major, minor); + + /* error check */ + if (major == 0xee) + hang(); +} + +/* Delay number of nanoseconds */ +void delay_n(uint32_t ns) +{ + /* 1000 MHz clock has 1ns period --> no conversion required */ + uint64_t final_tsc = rdtsc(); + + final_tsc += ((get_tbclk_mhz() * ns) / 1000); + + while (rdtsc() < final_tsc) + ; +} + +/* Delay number of microseconds */ +void delay_u(uint32_t ms) +{ + /* 64-bit math is not an option, just use loops */ + while (ms--) + delay_n(1000); +} + +/* Select Memory Manager as the source for PRI interface */ +void select_mem_mgr(void) +{ + u32 dco; + + ENTERFN(); + + dco = msg_port_read(MEM_CTLR, DCO); + dco &= ~BIT28; + msg_port_write(MEM_CTLR, DCO, dco); + + LEAVEFN(); +} + +/* Select HTE as the source for PRI interface */ +void select_hte(void) +{ + u32 dco; + + ENTERFN(); + + dco = msg_port_read(MEM_CTLR, DCO); + dco |= BIT28; + msg_port_write(MEM_CTLR, DCO, dco); + + LEAVEFN(); +} + +/* + * Send DRAM command + * data should be formated using DCMD_Xxxx macro or emrsXCommand structure + */ +void dram_init_command(uint32_t data) +{ + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, data); + pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, 0); + msg_port_setup(MSG_OP_DRAM_INIT, MEM_CTLR, 0); + + DPF(D_REGWR, "WR32 %03X %08X %08X\n", MEM_CTLR, 0, data); +} + +/* Send DRAM wake command using special MCU side-band WAKE opcode */ +void dram_wake_command(void) +{ + ENTERFN(); + + msg_port_setup(MSG_OP_DRAM_WAKE, MEM_CTLR, 0); + + LEAVEFN(); +} + +void training_message(uint8_t channel, uint8_t rank, uint8_t byte_lane) +{ + /* send message to UART */ + DPF(D_INFO, "CH%01X RK%01X BL%01X\n", channel, rank, byte_lane); +} + +/* + * This function will program the RCVEN delays + * + * (currently doesn't comprehend rank) + */ +void set_rcvn(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + DPF(D_TRN, "Rcvn ch%d rnk%d ln%d : pi=%03X\n", + channel, rank, byte_lane, pi_count); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[11:08] (0x0-0xF) + * BL1 -> B01PTRCTL0[23:20] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = (byte_lane & BIT0) ? (BIT23 | BIT22 | BIT21 | BIT20) : + (BIT11 | BIT10 | BIT9 | BIT8); + temp = (byte_lane & BIT0) ? ((pi_count / HALF_CLK) << 20) : + ((pi_count / HALF_CLK) << 8); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24); + temp = pi_count << 24; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * BL0/1 -> B01DBCTL1[08/11] (+1 select) + * BL0/1 -> B01DBCTL1[02/05] (enable) + */ + reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= (byte_lane & BIT0) ? BIT5 : BIT2; + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= (byte_lane & BIT0) ? BIT11 : BIT8; + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) { + training_message(channel, rank, byte_lane); + mrc_post_code(0xee, 0xe0); + } + + LEAVEFN(); +} + +/* + * This function will return the current RCVEN delay on the given + * channel, rank, byte_lane as an absolute PI count. + * + * (currently doesn't comprehend rank) + */ +uint32_t get_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[11:08] (0x0-0xF) + * BL1 -> B01PTRCTL0[23:20] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= (byte_lane & BIT0) ? 20 : 8; + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = temp * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 24; + temp &= 0x3F; + + /* Adjust PI_COUNT */ + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the RDQS delays based on an absolute + * amount of PIs. + * + * (currently doesn't comprehend rank) + */ +void set_rdqs(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + DPF(D_TRN, "Rdqs ch%d rnk%d ln%d : pi=%03X\n", + channel, rank, byte_lane, pi_count); + + /* + * PI (1/128 MCLK) + * BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47) + * BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47) + */ + reg = (byte_lane & BIT0) ? B1RXDQSPICODE : B0RXDQSPICODE; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + msk = (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0); + temp = pi_count << 0; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check (shouldn't go above 0x3F) */ + if (pi_count > 0x47) { + training_message(channel, rank, byte_lane); + mrc_post_code(0xee, 0xe1); + } + + LEAVEFN(); +} + +/* + * This function will return the current RDQS delay on the given + * channel, rank, byte_lane as an absolute PI count. + * + * (currently doesn't comprehend rank) + */ +uint32_t get_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * PI (1/128 MCLK) + * BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47) + * BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47) + */ + reg = (byte_lane & BIT0) ? B1RXDQSPICODE : B0RXDQSPICODE; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + temp = msg_port_alt_read(DDRPHY, reg); + + /* Adjust PI_COUNT */ + pi_count = temp & 0x7F; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the WDQS delays based on an absolute + * amount of PIs. + * + * (currently doesn't comprehend rank) + */ +void set_wdqs(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + DPF(D_TRN, "Wdqs ch%d rnk%d ln%d : pi=%03X\n", + channel, rank, byte_lane, pi_count); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[07:04] (0x0-0xF) + * BL1 -> B01PTRCTL0[19:16] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = (byte_lane & BIT0) ? (BIT19 | BIT18 | BIT17 | BIT16) : + (BIT7 | BIT6 | BIT5 | BIT4); + temp = pi_count / HALF_CLK; + temp <<= (byte_lane & BIT0) ? 16 : 4; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16); + temp = pi_count << 16; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * BL0/1 -> B01DBCTL1[07/10] (+1 select) + * BL0/1 -> B01DBCTL1[01/04] (enable) + */ + reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= (byte_lane & BIT0) ? BIT4 : BIT1; + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= (byte_lane & BIT0) ? BIT10 : BIT7; + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) { + training_message(channel, rank, byte_lane); + mrc_post_code(0xee, 0xe2); + } + + LEAVEFN(); +} + +/* + * This function will return the amount of WDQS delay on the given + * channel, rank, byte_lane as an absolute PI count. + * + * (currently doesn't comprehend rank) + */ +uint32_t get_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[07:04] (0x0-0xF) + * BL1 -> B01PTRCTL0[19:16] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= (byte_lane & BIT0) ? 16 : 4; + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = (temp * HALF_CLK); + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 16; + temp &= 0x3F; + + /* Adjust PI_COUNT */ + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the WDQ delays based on an absolute + * number of PIs. + * + * (currently doesn't comprehend rank) + */ +void set_wdq(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + DPF(D_TRN, "Wdq ch%d rnk%d ln%d : pi=%03X\n", + channel, rank, byte_lane, pi_count); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[03:00] (0x0-0xF) + * BL1 -> B01PTRCTL0[15:12] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = (byte_lane & BIT0) ? (BIT15 | BIT14 | BIT13 | BIT12) : + (BIT3 | BIT2 | BIT1 | BIT0); + temp = pi_count / HALF_CLK; + temp <<= (byte_lane & BIT0) ? 12 : 0; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + msk = (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8); + temp = pi_count << 8; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * BL0/1 -> B01DBCTL1[06/09] (+1 select) + * BL0/1 -> B01DBCTL1[00/03] (enable) + */ + reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= (byte_lane & BIT0) ? BIT3 : BIT0; + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= (byte_lane & BIT0) ? BIT9 : BIT6; + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) { + training_message(channel, rank, byte_lane); + mrc_post_code(0xee, 0xe3); + } + + LEAVEFN(); +} + +/* + * This function will return the amount of WDQ delay on the given + * channel, rank, byte_lane as an absolute PI count. + * + * (currently doesn't comprehend rank) + */ +uint32_t get_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * BL0 -> B01PTRCTL0[03:00] (0x0-0xF) + * BL1 -> B01PTRCTL0[15:12] (0x0-0xF) + */ + reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= (byte_lane & BIT0) ? (12) : (0); + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = temp * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F) + * BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F) + */ + reg = (byte_lane & BIT0) ? B1DLLPICODER0 : B0DLLPICODER0; + reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 8; + temp &= 0x3F; + + /* Adjust PI_COUNT */ + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the WCMD delays based on an absolute + * number of PIs. + */ +void set_wcmd(uint8_t channel, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CMDPTRREG[11:08] (0x0-0xF) + */ + reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET); + msk = (BIT11 | BIT10 | BIT9 | BIT8); + temp = pi_count / HALF_CLK; + temp <<= 8; + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused) + * CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused) + * CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused) + * CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused) + * CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused) + * CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F) + * CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused) + * CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused) + */ + reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); + + msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24 | + BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | + BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0); + + temp = (pi_count << 24) | (pi_count << 16) | + (pi_count << 8) | (pi_count << 0); + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = CMDDLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); /* PO */ + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * CMDCFGREG0[17] (+1 select) + * CMDCFGREG0[16] (enable) + */ + reg = CMDCFGREG0 + (channel * DDRIOCCC_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= BIT16; + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= BIT17; + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) + mrc_post_code(0xee, 0xe4); + + LEAVEFN(); +} + +/* + * This function will return the amount of WCMD delay on the given + * channel as an absolute PI count. + */ +uint32_t get_wcmd(uint8_t channel) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CMDPTRREG[11:08] (0x0-0xF) + */ + reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 8; + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = temp * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused) + * CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused) + * CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused) + * CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused) + * CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused) + * CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F) + * CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused) + * CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused) + */ + reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 16; + temp &= 0x3F; + + /* Adjust PI_COUNT */ + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the WCLK delays based on an absolute + * number of PIs. + */ +void set_wclk(uint8_t channel, uint8_t rank, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CCPTRREG[15:12] -> CLK1 (0x0-0xF) + * CCPTRREG[11:08] -> CLK0 (0x0-0xF) + */ + reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); + msk = (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8); + temp = ((pi_count / HALF_CLK) << 12) | ((pi_count / HALF_CLK) << 8); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F) + * ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F) + */ + reg = rank ? ECCB1DLLPICODER0 : ECCB1DLLPICODER0; + reg += (channel * DDRIOCCC_CH_OFFSET); + msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | + BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8); + temp = (pi_count << 16) | (pi_count << 8); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = rank ? ECCB1DLLPICODER1 : ECCB1DLLPICODER1; + reg += (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = rank ? ECCB1DLLPICODER2 : ECCB1DLLPICODER2; + reg += (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = rank ? ECCB1DLLPICODER3 : ECCB1DLLPICODER3; + reg += (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * CCCFGREG1[11:08] (+1 select) + * CCCFGREG1[03:00] (enable) + */ + reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= (BIT3 | BIT2 | BIT1 | BIT0); + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= (BIT11 | BIT10 | BIT9 | BIT8); + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) + mrc_post_code(0xee, 0xe5); + + LEAVEFN(); +} + +/* + * This function will return the amout of WCLK delay on the given + * channel, rank as an absolute PI count. + */ +uint32_t get_wclk(uint8_t channel, uint8_t rank) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CCPTRREG[15:12] -> CLK1 (0x0-0xF) + * CCPTRREG[11:08] -> CLK0 (0x0-0xF) + */ + reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= rank ? 12 : 8; + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = temp * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F) + * ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F) + */ + reg = rank ? ECCB1DLLPICODER0 : ECCB1DLLPICODER0; + reg += (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= rank ? 16 : 8; + temp &= 0x3F; + + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the WCTL delays based on an absolute + * number of PIs. + * + * (currently doesn't comprehend rank) + */ +void set_wctl(uint8_t channel, uint8_t rank, uint32_t pi_count) +{ + uint32_t reg; + uint32_t msk; + uint32_t temp; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CCPTRREG[31:28] (0x0-0xF) + * CCPTRREG[27:24] (0x0-0xF) + */ + reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); + msk = (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24); + temp = ((pi_count / HALF_CLK) << 28) | ((pi_count / HALF_CLK) << 24); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* Adjust PI_COUNT */ + pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * ECCB1DLLPICODER?[29:24] (0x00-0x3F) + * ECCB1DLLPICODER?[29:24] (0x00-0x3F) + */ + reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); + msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24); + temp = (pi_count << 24); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = ECCB1DLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = ECCB1DLLPICODER2 + (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + reg = ECCB1DLLPICODER3 + (channel * DDRIOCCC_CH_OFFSET); + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* + * DEADBAND + * CCCFGREG1[13:12] (+1 select) + * CCCFGREG1[05:04] (enable) + */ + reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET); + msk = 0x00; + temp = 0x00; + + /* enable */ + msk |= (BIT5 | BIT4); + if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) + temp |= msk; + + /* select */ + msk |= (BIT13 | BIT12); + if (pi_count < EARLY_DB) + temp |= msk; + + mrc_alt_write_mask(DDRPHY, reg, temp, msk); + + /* error check */ + if (pi_count > 0x3F) + mrc_post_code(0xee, 0xe6); + + LEAVEFN(); +} + +/* + * This function will return the amount of WCTL delay on the given + * channel, rank as an absolute PI count. + * + * (currently doesn't comprehend rank) + */ +uint32_t get_wctl(uint8_t channel, uint8_t rank) +{ + uint32_t reg; + uint32_t temp; + uint32_t pi_count; + + ENTERFN(); + + /* + * RDPTR (1/2 MCLK, 64 PIs) + * CCPTRREG[31:28] (0x0-0xF) + * CCPTRREG[27:24] (0x0-0xF) + */ + reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 24; + temp &= 0xF; + + /* Adjust PI_COUNT */ + pi_count = temp * HALF_CLK; + + /* + * PI (1/64 MCLK, 1 PIs) + * ECCB1DLLPICODER?[29:24] (0x00-0x3F) + * ECCB1DLLPICODER?[29:24] (0x00-0x3F) + */ + reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); + temp = msg_port_alt_read(DDRPHY, reg); + temp >>= 24; + temp &= 0x3F; + + /* Adjust PI_COUNT */ + pi_count += temp; + + LEAVEFN(); + + return pi_count; +} + +/* + * This function will program the internal Vref setting in a given + * byte lane in a given channel. + */ +void set_vref(uint8_t channel, uint8_t byte_lane, uint32_t setting) +{ + uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL); + + ENTERFN(); + + DPF(D_TRN, "Vref ch%d ln%d : val=%03X\n", + channel, byte_lane, setting); + + mrc_alt_write_mask(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)), + (vref_codes[setting] << 2), + (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2)); + + /* + * need to wait ~300ns for Vref to settle + * (check that this is necessary) + */ + delay_n(300); + + /* ??? may need to clear pointers ??? */ + + LEAVEFN(); +} + +/* + * This function will return the internal Vref setting for the given + * channel, byte_lane. + */ +uint32_t get_vref(uint8_t channel, uint8_t byte_lane) +{ + uint8_t j; + uint32_t ret_val = sizeof(vref_codes) / 2; + uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL); + uint32_t temp; + + ENTERFN(); + + temp = msg_port_alt_read(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET))); + temp >>= 2; + temp &= 0x3F; + + for (j = 0; j < sizeof(vref_codes); j++) { + if (vref_codes[j] == temp) { + ret_val = j; + break; + } + } + + LEAVEFN(); + + return ret_val; +} + +/* + * This function will return a 32-bit address in the desired + * channel and rank. + */ +uint32_t get_addr(uint8_t channel, uint8_t rank) +{ + uint32_t offset = 0x02000000; /* 32MB */ + + /* Begin product specific code */ + if (channel > 0) { + DPF(D_ERROR, "ILLEGAL CHANNEL\n"); + DEAD_LOOP(); + } + + if (rank > 1) { + DPF(D_ERROR, "ILLEGAL RANK\n"); + DEAD_LOOP(); + } + + /* use 256MB lowest density as per DRP == 0x0003 */ + offset += rank * (256 * 1024 * 1024); + + return offset; +} + +/* + * This function will sample the DQTRAINSTS registers in the given + * channel/rank SAMPLE_SIZE times looking for a valid '0' or '1'. + * + * It will return an encoded 32-bit date in which each bit corresponds to + * the sampled value on the byte lane. + */ +uint32_t sample_dqs(struct mrc_params *mrc_params, uint8_t channel, + uint8_t rank, bool rcvn) +{ + uint8_t j; /* just a counter */ + uint8_t bl; /* which BL in the module (always 2 per module) */ + uint8_t bl_grp; /* which BL module */ + /* byte lane divisor */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; + uint32_t msk[2]; /* BLx in module */ + /* DQTRAINSTS register contents for each sample */ + uint32_t sampled_val[SAMPLE_SIZE]; + uint32_t num_0s; /* tracks the number of '0' samples */ + uint32_t num_1s; /* tracks the number of '1' samples */ + uint32_t ret_val = 0x00; /* assume all '0' samples */ + uint32_t address = get_addr(channel, rank); + + /* initialise msk[] */ + msk[0] = rcvn ? BIT1 : BIT9; /* BL0 */ + msk[1] = rcvn ? BIT0 : BIT8; /* BL1 */ + + /* cycle through each byte lane group */ + for (bl_grp = 0; bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2; bl_grp++) { + /* take SAMPLE_SIZE samples */ + for (j = 0; j < SAMPLE_SIZE; j++) { + hte_mem_op(address, mrc_params->first_run, + rcvn ? 0 : 1); + mrc_params->first_run = 0; + + /* + * record the contents of the proper + * DQTRAINSTS register + */ + sampled_val[j] = msg_port_alt_read(DDRPHY, + (DQTRAINSTS + + (bl_grp * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET))); + } + + /* + * look for a majority value (SAMPLE_SIZE / 2) + 1 + * on the byte lane and set that value in the corresponding + * ret_val bit + */ + for (bl = 0; bl < 2; bl++) { + num_0s = 0x00; /* reset '0' tracker for byte lane */ + num_1s = 0x00; /* reset '1' tracker for byte lane */ + for (j = 0; j < SAMPLE_SIZE; j++) { + if (sampled_val[j] & msk[bl]) + num_1s++; + else + num_0s++; + } + if (num_1s > num_0s) + ret_val |= (1 << (bl + (bl_grp * 2))); + } + } + + /* + * "ret_val.0" contains the status of BL0 + * "ret_val.1" contains the status of BL1 + * "ret_val.2" contains the status of BL2 + * etc. + */ + return ret_val; +} + +/* This function will find the rising edge transition on RCVN or WDQS */ +void find_rising_edge(struct mrc_params *mrc_params, uint32_t delay[], + uint8_t channel, uint8_t rank, bool rcvn) +{ + bool all_edges_found; /* determines stop condition */ + bool direction[NUM_BYTE_LANES]; /* direction indicator */ + uint8_t sample; /* sample counter */ + uint8_t bl; /* byte lane counter */ + /* byte lane divisor */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; + uint32_t sample_result[SAMPLE_CNT]; /* results of sample_dqs() */ + uint32_t temp; + uint32_t transition_pattern; + + ENTERFN(); + + /* select hte and request initial configuration */ + select_hte(); + mrc_params->first_run = 1; + + /* Take 3 sample points (T1,T2,T3) to obtain a transition pattern */ + for (sample = 0; sample < SAMPLE_CNT; sample++) { + /* program the desired delays for sample */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + /* increase sample delay by 26 PI (0.2 CLK) */ + if (rcvn) { + set_rcvn(channel, rank, bl, + delay[bl] + (sample * SAMPLE_DLY)); + } else { + set_wdqs(channel, rank, bl, + delay[bl] + (sample * SAMPLE_DLY)); + } + } + + /* take samples (Tsample_i) */ + sample_result[sample] = sample_dqs(mrc_params, + channel, rank, rcvn); + + DPF(D_TRN, + "Find rising edge %s ch%d rnk%d: #%d dly=%d dqs=%02X\n", + (rcvn ? "RCVN" : "WDQS"), channel, rank, sample, + sample * SAMPLE_DLY, sample_result[sample]); + } + + /* + * This pattern will help determine where we landed and ultimately + * how to place RCVEN/WDQS. + */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + /* build transition_pattern (MSB is 1st sample) */ + transition_pattern = 0; + for (sample = 0; sample < SAMPLE_CNT; sample++) { + transition_pattern |= + ((sample_result[sample] & (1 << bl)) >> bl) << + (SAMPLE_CNT - 1 - sample); + } + + DPF(D_TRN, "=== transition pattern %d\n", transition_pattern); + + /* + * set up to look for rising edge based on + * transition_pattern + */ + switch (transition_pattern) { + case 0: /* sampled 0->0->0 */ + /* move forward from T3 looking for 0->1 */ + delay[bl] += 2 * SAMPLE_DLY; + direction[bl] = FORWARD; + break; + case 1: /* sampled 0->0->1 */ + case 5: /* sampled 1->0->1 (bad duty cycle) *HSD#237503* */ + /* move forward from T2 looking for 0->1 */ + delay[bl] += 1 * SAMPLE_DLY; + direction[bl] = FORWARD; + break; + case 2: /* sampled 0->1->0 (bad duty cycle) *HSD#237503* */ + case 3: /* sampled 0->1->1 */ + /* move forward from T1 looking for 0->1 */ + delay[bl] += 0 * SAMPLE_DLY; + direction[bl] = FORWARD; + break; + case 4: /* sampled 1->0->0 (assumes BL8, HSD#234975) */ + /* move forward from T3 looking for 0->1 */ + delay[bl] += 2 * SAMPLE_DLY; + direction[bl] = FORWARD; + break; + case 6: /* sampled 1->1->0 */ + case 7: /* sampled 1->1->1 */ + /* move backward from T1 looking for 1->0 */ + delay[bl] += 0 * SAMPLE_DLY; + direction[bl] = BACKWARD; + break; + default: + mrc_post_code(0xee, 0xee); + break; + } + + /* program delays */ + if (rcvn) + set_rcvn(channel, rank, bl, delay[bl]); + else + set_wdqs(channel, rank, bl, delay[bl]); + } + + /* + * Based on the observed transition pattern on the byte lane, + * begin looking for a rising edge with single PI granularity. + */ + do { + all_edges_found = true; /* assume all byte lanes passed */ + /* take a sample */ + temp = sample_dqs(mrc_params, channel, rank, rcvn); + /* check all each byte lane for proper edge */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (temp & (1 << bl)) { + /* sampled "1" */ + if (direction[bl] == BACKWARD) { + /* + * keep looking for edge + * on this byte lane + */ + all_edges_found = false; + delay[bl] -= 1; + if (rcvn) { + set_rcvn(channel, rank, + bl, delay[bl]); + } else { + set_wdqs(channel, rank, + bl, delay[bl]); + } + } + } else { + /* sampled "0" */ + if (direction[bl] == FORWARD) { + /* + * keep looking for edge + * on this byte lane + */ + all_edges_found = false; + delay[bl] += 1; + if (rcvn) { + set_rcvn(channel, rank, + bl, delay[bl]); + } else { + set_wdqs(channel, rank, + bl, delay[bl]); + } + } + } + } + } while (!all_edges_found); + + /* restore DDR idle state */ + dram_init_command(DCMD_PREA(rank)); + + DPF(D_TRN, "Delay %03X %03X %03X %03X\n", + delay[0], delay[1], delay[2], delay[3]); + + LEAVEFN(); +} + +/* + * This function will return a 32 bit mask that will be used to + * check for byte lane failures. + */ +uint32_t byte_lane_mask(struct mrc_params *mrc_params) +{ + uint32_t j; + uint32_t ret_val = 0x00; + + /* + * set ret_val based on NUM_BYTE_LANES such that you will check + * only BL0 in result + * + * (each bit in result represents a byte lane) + */ + for (j = 0; j < MAX_BYTE_LANES; j += NUM_BYTE_LANES) + ret_val |= (1 << ((j / NUM_BYTE_LANES) * NUM_BYTE_LANES)); + + /* + * HSD#235037 + * need to adjust the mask for 16-bit mode + */ + if (mrc_params->channel_width == X16) + ret_val |= (ret_val << 2); + + return ret_val; +} + +/* + * Check memory executing simple write/read/verify at the specified address. + * + * Bits in the result indicate failure on specific byte lane. + */ +uint32_t check_rw_coarse(struct mrc_params *mrc_params, uint32_t address) +{ + uint32_t result = 0; + uint8_t first_run = 0; + + if (mrc_params->hte_setup) { + mrc_params->hte_setup = 0; + first_run = 1; + select_hte(); + } + + result = hte_basic_write_read(mrc_params, address, first_run, + WRITE_TRAIN); + + DPF(D_TRN, "check_rw_coarse result is %x\n", result); + + return result; +} + +/* + * Check memory executing write/read/verify of many data patterns + * at the specified address. Bits in the result indicate failure + * on specific byte lane. + */ +uint32_t check_bls_ex(struct mrc_params *mrc_params, uint32_t address) +{ + uint32_t result; + uint8_t first_run = 0; + + if (mrc_params->hte_setup) { + mrc_params->hte_setup = 0; + first_run = 1; + select_hte(); + } + + result = hte_write_stress_bit_lanes(mrc_params, address, first_run); + + DPF(D_TRN, "check_bls_ex result is %x\n", result); + + return result; +} + +/* + * 32-bit LFSR with characteristic polynomial: X^32 + X^22 +X^2 + X^1 + * + * The function takes pointer to previous 32 bit value and + * modifies it to next value. + */ +void lfsr32(uint32_t *lfsr_ptr) +{ + uint32_t bit; + uint32_t lfsr; + int i; + + lfsr = *lfsr_ptr; + + for (i = 0; i < 32; i++) { + bit = 1 ^ (lfsr & BIT0); + bit = bit ^ ((lfsr & BIT1) >> 1); + bit = bit ^ ((lfsr & BIT2) >> 2); + bit = bit ^ ((lfsr & BIT22) >> 22); + + lfsr = ((lfsr >> 1) | (bit << 31)); + } + + *lfsr_ptr = lfsr; +} + +/* Clear the pointers in a given byte lane in a given channel */ +void clear_pointers(void) +{ + uint8_t channel; + uint8_t bl; + + ENTERFN(); + + for (channel = 0; channel < NUM_CHANNELS; channel++) { + for (bl = 0; bl < NUM_BYTE_LANES; bl++) { + mrc_alt_write_mask(DDRPHY, + (B01PTRCTL1 + + (channel * DDRIODQ_CH_OFFSET) + + ((bl >> 1) * DDRIODQ_BL_OFFSET)), + ~BIT8, BIT8); + + mrc_alt_write_mask(DDRPHY, + (B01PTRCTL1 + + (channel * DDRIODQ_CH_OFFSET) + + ((bl >> 1) * DDRIODQ_BL_OFFSET)), + BIT8, BIT8); + } + } + + LEAVEFN(); +} + +static void print_timings_internal(uint8_t algo, uint8_t channel, uint8_t rank, + uint8_t bl_divisor) +{ + uint8_t bl; + + switch (algo) { + case RCVN: + DPF(D_INFO, "\nRCVN[%02d:%02d]", channel, rank); + break; + case WDQS: + DPF(D_INFO, "\nWDQS[%02d:%02d]", channel, rank); + break; + case WDQX: + DPF(D_INFO, "\nWDQx[%02d:%02d]", channel, rank); + break; + case RDQS: + DPF(D_INFO, "\nRDQS[%02d:%02d]", channel, rank); + break; + case VREF: + DPF(D_INFO, "\nVREF[%02d:%02d]", channel, rank); + break; + case WCMD: + DPF(D_INFO, "\nWCMD[%02d:%02d]", channel, rank); + break; + case WCTL: + DPF(D_INFO, "\nWCTL[%02d:%02d]", channel, rank); + break; + case WCLK: + DPF(D_INFO, "\nWCLK[%02d:%02d]", channel, rank); + break; + default: + break; + } + + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + switch (algo) { + case RCVN: + DPF(D_INFO, " %03d", get_rcvn(channel, rank, bl)); + break; + case WDQS: + DPF(D_INFO, " %03d", get_wdqs(channel, rank, bl)); + break; + case WDQX: + DPF(D_INFO, " %03d", get_wdq(channel, rank, bl)); + break; + case RDQS: + DPF(D_INFO, " %03d", get_rdqs(channel, rank, bl)); + break; + case VREF: + DPF(D_INFO, " %03d", get_vref(channel, bl)); + break; + case WCMD: + DPF(D_INFO, " %03d", get_wcmd(channel)); + break; + case WCTL: + DPF(D_INFO, " %03d", get_wctl(channel, rank)); + break; + case WCLK: + DPF(D_INFO, " %03d", get_wclk(channel, rank)); + break; + default: + break; + } + } +} + +void print_timings(struct mrc_params *mrc_params) +{ + uint8_t algo; + uint8_t channel; + uint8_t rank; + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; + + DPF(D_INFO, "\n---------------------------"); + DPF(D_INFO, "\nALGO[CH:RK] BL0 BL1 BL2 BL3"); + DPF(D_INFO, "\n==========================="); + + for (algo = 0; algo < MAX_ALGOS; algo++) { + for (channel = 0; channel < NUM_CHANNELS; channel++) { + if (mrc_params->channel_enables & (1 << channel)) { + for (rank = 0; rank < NUM_RANKS; rank++) { + if (mrc_params->rank_enables & + (1 << rank)) { + print_timings_internal(algo, + channel, rank, + bl_divisor); + } + } + } + } + } + + DPF(D_INFO, "\n---------------------------"); + DPF(D_INFO, "\n"); +} diff --git a/arch/x86/cpu/quark/mrc_util.h b/arch/x86/cpu/quark/mrc_util.h new file mode 100644 index 0000000000..f0ddbce3c5 --- /dev/null +++ b/arch/x86/cpu/quark/mrc_util.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _MRC_UTIL_H_ +#define _MRC_UTIL_H_ + +/* Turn on this macro to enable MRC debugging output */ +#undef MRC_DEBUG + +/* MRC Debug Support */ +#define DPF debug_cond + +/* debug print type */ + +#ifdef MRC_DEBUG +#define D_ERROR 0x0001 +#define D_INFO 0x0002 +#define D_REGRD 0x0004 +#define D_REGWR 0x0008 +#define D_FCALL 0x0010 +#define D_TRN 0x0020 +#define D_TIME 0x0040 +#else +#define D_ERROR 0 +#define D_INFO 0 +#define D_REGRD 0 +#define D_REGWR 0 +#define D_FCALL 0 +#define D_TRN 0 +#define D_TIME 0 +#endif + +#define ENTERFN(...) debug_cond(D_FCALL, "<%s>\n", __func__) +#define LEAVEFN(...) debug_cond(D_FCALL, "\n", __func__) +#define REPORTFN(...) debug_cond(D_FCALL, "<%s/>\n", __func__) + +/* Generic Register Bits */ +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +/* Message Bus Port */ +#define MEM_CTLR 0x01 +#define HOST_BRIDGE 0x03 +#define MEM_MGR 0x05 +#define HTE 0x11 +#define DDRPHY 0x12 + +/* number of sample points */ +#define SAMPLE_CNT 3 +/* number of PIs to increment per sample */ +#define SAMPLE_DLY 26 + +enum { + /* indicates to decrease delays when looking for edge */ + BACKWARD, + /* indicates to increase delays when looking for edge */ + FORWARD +}; + +enum { + RCVN, + WDQS, + WDQX, + RDQS, + VREF, + WCMD, + WCTL, + WCLK, + MAX_ALGOS, +}; + +void mrc_write_mask(u32 unit, u32 addr, u32 data, u32 mask); +void mrc_alt_write_mask(u32 unit, u32 addr, u32 data, u32 mask); +void mrc_post_code(uint8_t major, uint8_t minor); +void delay_n(uint32_t ns); +void delay_u(uint32_t ms); +void select_mem_mgr(void); +void select_hte(void); +void dram_init_command(uint32_t data); +void dram_wake_command(void); +void training_message(uint8_t channel, uint8_t rank, uint8_t byte_lane); + +void set_rcvn(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count); +uint32_t get_rcvn(uint8_t channel, uint8_t rank, uint8_t byte_lane); +void set_rdqs(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count); +uint32_t get_rdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane); +void set_wdqs(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count); +uint32_t get_wdqs(uint8_t channel, uint8_t rank, uint8_t byte_lane); +void set_wdq(uint8_t channel, uint8_t rank, + uint8_t byte_lane, uint32_t pi_count); +uint32_t get_wdq(uint8_t channel, uint8_t rank, uint8_t byte_lane); +void set_wcmd(uint8_t channel, uint32_t pi_count); +uint32_t get_wcmd(uint8_t channel); +void set_wclk(uint8_t channel, uint8_t rank, uint32_t pi_count); +uint32_t get_wclk(uint8_t channel, uint8_t rank); +void set_wctl(uint8_t channel, uint8_t rank, uint32_t pi_count); +uint32_t get_wctl(uint8_t channel, uint8_t rank); +void set_vref(uint8_t channel, uint8_t byte_lane, uint32_t setting); +uint32_t get_vref(uint8_t channel, uint8_t byte_lane); + +uint32_t get_addr(uint8_t channel, uint8_t rank); +uint32_t sample_dqs(struct mrc_params *mrc_params, uint8_t channel, + uint8_t rank, bool rcvn); +void find_rising_edge(struct mrc_params *mrc_params, uint32_t delay[], + uint8_t channel, uint8_t rank, bool rcvn); +uint32_t byte_lane_mask(struct mrc_params *mrc_params); +uint32_t check_rw_coarse(struct mrc_params *mrc_params, uint32_t address); +uint32_t check_bls_ex(struct mrc_params *mrc_params, uint32_t address); +void lfsr32(uint32_t *lfsr_ptr); +void clear_pointers(void); +void print_timings(struct mrc_params *mrc_params); + +#endif /* _MRC_UTIL_H_ */ -- cgit From b829f12afa768633502a546f678441391c1d76e4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:24 +0800 Subject: x86: quark: Add System Memory Controller support The codes are actually doing the memory initialization stuff. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/smc.c | 2764 ++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/cpu/quark/smc.h | 446 ++++++++ 2 files changed, 3210 insertions(+) create mode 100644 arch/x86/cpu/quark/smc.c create mode 100644 arch/x86/cpu/quark/smc.h diff --git a/arch/x86/cpu/quark/smc.c b/arch/x86/cpu/quark/smc.c new file mode 100644 index 0000000000..e34bec4c80 --- /dev/null +++ b/arch/x86/cpu/quark/smc.c @@ -0,0 +1,2764 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#include +#include +#include +#include +#include +#include "mrc_util.h" +#include "hte.h" +#include "smc.h" + +/* t_rfc values (in picoseconds) per density */ +static const uint32_t t_rfc[5] = { + 90000, /* 512Mb */ + 110000, /* 1Gb */ + 160000, /* 2Gb */ + 300000, /* 4Gb */ + 350000, /* 8Gb */ +}; + +/* t_ck clock period in picoseconds per speed index 800, 1066, 1333 */ +static const uint32_t t_ck[3] = { + 2500, + 1875, + 1500 +}; + +/* Global variables */ +static const uint16_t ddr_wclk[] = {193, 158}; +static const uint16_t ddr_wctl[] = {1, 217}; +static const uint16_t ddr_wcmd[] = {1, 220}; + +#ifdef BACKUP_RCVN +static const uint16_t ddr_rcvn[] = {129, 498}; +#endif + +#ifdef BACKUP_WDQS +static const uint16_t ddr_wdqs[] = {65, 289}; +#endif + +#ifdef BACKUP_RDQS +static const uint8_t ddr_rdqs[] = {32, 24}; +#endif + +#ifdef BACKUP_WDQ +static const uint16_t ddr_wdq[] = {32, 257}; +#endif + +/* Stop self refresh driven by MCU */ +void clear_self_refresh(struct mrc_params *mrc_params) +{ + ENTERFN(); + + /* clear the PMSTS Channel Self Refresh bits */ + mrc_write_mask(MEM_CTLR, PMSTS, BIT0, BIT0); + + LEAVEFN(); +} + +/* It will initialize timing registers in the MCU (DTR0..DTR4) */ +void prog_ddr_timing_control(struct mrc_params *mrc_params) +{ + uint8_t tcl, wl; + uint8_t trp, trcd, tras, twr, twtr, trrd, trtp, tfaw; + uint32_t tck; + u32 dtr0, dtr1, dtr2, dtr3, dtr4; + u32 tmp1, tmp2; + + ENTERFN(); + + /* mcu_init starts */ + mrc_post_code(0x02, 0x00); + + dtr0 = msg_port_read(MEM_CTLR, DTR0); + dtr1 = msg_port_read(MEM_CTLR, DTR1); + dtr2 = msg_port_read(MEM_CTLR, DTR2); + dtr3 = msg_port_read(MEM_CTLR, DTR3); + dtr4 = msg_port_read(MEM_CTLR, DTR4); + + tck = t_ck[mrc_params->ddr_speed]; /* Clock in picoseconds */ + tcl = mrc_params->params.cl; /* CAS latency in clocks */ + trp = tcl; /* Per CAT MRC */ + trcd = tcl; /* Per CAT MRC */ + tras = MCEIL(mrc_params->params.ras, tck); + + /* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */ + twr = MCEIL(15000, tck); + + twtr = MCEIL(mrc_params->params.wtr, tck); + trrd = MCEIL(mrc_params->params.rrd, tck); + trtp = 4; /* Valid for 800 and 1066, use 5 for 1333 */ + tfaw = MCEIL(mrc_params->params.faw, tck); + + wl = 5 + mrc_params->ddr_speed; + + dtr0 &= ~(BIT0 | BIT1); + dtr0 |= mrc_params->ddr_speed; + dtr0 &= ~(BIT12 | BIT13 | BIT14); + tmp1 = tcl - 5; + dtr0 |= ((tcl - 5) << 12); + dtr0 &= ~(BIT4 | BIT5 | BIT6 | BIT7); + dtr0 |= ((trp - 5) << 4); /* 5 bit DRAM Clock */ + dtr0 &= ~(BIT8 | BIT9 | BIT10 | BIT11); + dtr0 |= ((trcd - 5) << 8); /* 5 bit DRAM Clock */ + + dtr1 &= ~(BIT0 | BIT1 | BIT2); + tmp2 = wl - 3; + dtr1 |= (wl - 3); + dtr1 &= ~(BIT8 | BIT9 | BIT10 | BIT11); + dtr1 |= ((wl + 4 + twr - 14) << 8); /* Change to tWTP */ + dtr1 &= ~(BIT28 | BIT29 | BIT30); + dtr1 |= ((MMAX(trtp, 4) - 3) << 28); /* 4 bit DRAM Clock */ + dtr1 &= ~(BIT24 | BIT25); + dtr1 |= ((trrd - 4) << 24); /* 4 bit DRAM Clock */ + dtr1 &= ~(BIT4 | BIT5); + dtr1 |= (1 << 4); + dtr1 &= ~(BIT20 | BIT21 | BIT22 | BIT23); + dtr1 |= ((tras - 14) << 20); /* 6 bit DRAM Clock */ + dtr1 &= ~(BIT16 | BIT17 | BIT18 | BIT19); + dtr1 |= ((((tfaw + 1) >> 1) - 5) << 16);/* 4 bit DRAM Clock */ + /* Set 4 Clock CAS to CAS delay (multi-burst) */ + dtr1 &= ~(BIT12 | BIT13); + + dtr2 &= ~(BIT0 | BIT1 | BIT2); + dtr2 |= 1; + dtr2 &= ~(BIT8 | BIT9 | BIT10); + dtr2 |= (2 << 8); + dtr2 &= ~(BIT16 | BIT17 | BIT18 | BIT19); + dtr2 |= (2 << 16); + + dtr3 &= ~(BIT0 | BIT1 | BIT2); + dtr3 |= 2; + dtr3 &= ~(BIT4 | BIT5 | BIT6); + dtr3 |= (2 << 4); + + dtr3 &= ~(BIT8 | BIT9 | BIT10 | BIT11); + if (mrc_params->ddr_speed == DDRFREQ_800) { + /* Extended RW delay (+1) */ + dtr3 |= ((tcl - 5 + 1) << 8); + } else if (mrc_params->ddr_speed == DDRFREQ_1066) { + /* Extended RW delay (+1) */ + dtr3 |= ((tcl - 5 + 1) << 8); + } + + dtr3 &= ~(BIT13 | BIT14 | BIT15 | BIT16); + dtr3 |= ((4 + wl + twtr - 11) << 13); + + dtr3 &= ~(BIT22 | BIT23); + if (mrc_params->ddr_speed == DDRFREQ_800) + dtr3 |= ((MMAX(0, 1 - 1)) << 22); + else + dtr3 |= ((MMAX(0, 2 - 1)) << 22); + + dtr4 &= ~(BIT0 | BIT1); + dtr4 |= 1; + dtr4 &= ~(BIT4 | BIT5 | BIT6); + dtr4 |= (1 << 4); + dtr4 &= ~(BIT8 | BIT9 | BIT10); + dtr4 |= ((1 + tmp1 - tmp2 + 2) << 8); + dtr4 &= ~(BIT12 | BIT13 | BIT14); + dtr4 |= ((1 + tmp1 - tmp2 + 2) << 12); + dtr4 &= ~(BIT15 | BIT16); + + msg_port_write(MEM_CTLR, DTR0, dtr0); + msg_port_write(MEM_CTLR, DTR1, dtr1); + msg_port_write(MEM_CTLR, DTR2, dtr2); + msg_port_write(MEM_CTLR, DTR3, dtr3); + msg_port_write(MEM_CTLR, DTR4, dtr4); + + LEAVEFN(); +} + +/* Configure MCU before jedec init sequence */ +void prog_decode_before_jedec(struct mrc_params *mrc_params) +{ + u32 drp; + u32 drfc; + u32 dcal; + u32 dsch; + u32 dpmc0; + + ENTERFN(); + + /* Disable power saving features */ + dpmc0 = msg_port_read(MEM_CTLR, DPMC0); + dpmc0 |= (BIT24 | BIT25); + dpmc0 &= ~(BIT16 | BIT17 | BIT18); + dpmc0 &= ~BIT23; + msg_port_write(MEM_CTLR, DPMC0, dpmc0); + + /* Disable out of order transactions */ + dsch = msg_port_read(MEM_CTLR, DSCH); + dsch |= (BIT8 | BIT12); + msg_port_write(MEM_CTLR, DSCH, dsch); + + /* Disable issuing the REF command */ + drfc = msg_port_read(MEM_CTLR, DRFC); + drfc &= ~(BIT12 | BIT13 | BIT14); + msg_port_write(MEM_CTLR, DRFC, drfc); + + /* Disable ZQ calibration short */ + dcal = msg_port_read(MEM_CTLR, DCAL); + dcal &= ~(BIT8 | BIT9 | BIT10); + dcal &= ~(BIT12 | BIT13); + msg_port_write(MEM_CTLR, DCAL, dcal); + + /* + * Training performed in address mode 0, rank population has limited + * impact, however simulator complains if enabled non-existing rank. + */ + drp = 0; + if (mrc_params->rank_enables & 1) + drp |= BIT0; + if (mrc_params->rank_enables & 2) + drp |= BIT1; + msg_port_write(MEM_CTLR, DRP, drp); + + LEAVEFN(); +} + +/* + * After Cold Reset, BIOS should set COLDWAKE bit to 1 before + * sending the WAKE message to the Dunit. + * + * For Standby Exit, or any other mode in which the DRAM is in + * SR, this bit must be set to 0. + */ +void perform_ddr_reset(struct mrc_params *mrc_params) +{ + ENTERFN(); + + /* Set COLDWAKE bit before sending the WAKE message */ + mrc_write_mask(MEM_CTLR, DRMC, BIT16, BIT16); + + /* Send wake command to DUNIT (MUST be done before JEDEC) */ + dram_wake_command(); + + /* Set default value */ + msg_port_write(MEM_CTLR, DRMC, + (mrc_params->rd_odt_value == 0 ? BIT12 : 0)); + + LEAVEFN(); +} + + +/* + * This function performs some initialization on the DDRIO unit. + * This function is dependent on BOARD_ID, DDR_SPEED, and CHANNEL_ENABLES. + */ +void ddrphy_init(struct mrc_params *mrc_params) +{ + uint32_t temp; + uint8_t ch; /* channel counter */ + uint8_t rk; /* rank counter */ + uint8_t bl_grp; /* byte lane group counter (2 BLs per module) */ + uint8_t bl_divisor = 1; /* byte lane divisor */ + /* For DDR3 --> 0 == 800, 1 == 1066, 2 == 1333 */ + uint8_t speed = mrc_params->ddr_speed & (BIT1 | BIT0); + uint8_t cas; + uint8_t cwl; + + ENTERFN(); + + cas = mrc_params->params.cl; + cwl = 5 + mrc_params->ddr_speed; + + /* ddrphy_init starts */ + mrc_post_code(0x03, 0x00); + + /* + * HSD#231531 + * Make sure IOBUFACT is deasserted before initializing the DDR PHY + * + * HSD#234845 + * Make sure WRPTRENABLE is deasserted before initializing the DDR PHY + */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* Deassert DDRPHY Initialization Complete */ + mrc_alt_write_mask(DDRPHY, + (CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)), + ~BIT20, BIT20); /* SPID_INIT_COMPLETE=0 */ + /* Deassert IOBUFACT */ + mrc_alt_write_mask(DDRPHY, + (CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)), + ~BIT2, BIT2); /* IOBUFACTRST_N=0 */ + /* Disable WRPTR */ + mrc_alt_write_mask(DDRPHY, + (CMDPTRREG + (ch * DDRIOCCC_CH_OFFSET)), + ~BIT0, BIT0); /* WRPTRENABLE=0 */ + } + } + + /* Put PHY in reset */ + mrc_alt_write_mask(DDRPHY, MASTERRSTN, 0, BIT0); + + /* Initialize DQ01, DQ23, CMD, CLK-CTL, COMP modules */ + + /* STEP0 */ + mrc_post_code(0x03, 0x10); + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* DQ01-DQ23 */ + for (bl_grp = 0; + bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2); + bl_grp++) { + /* Analog MUX select - IO2xCLKSEL */ + mrc_alt_write_mask(DDRPHY, + (DQOBSCKEBBCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + ((bl_grp) ? (0x00) : (BIT22)), (BIT22)); + + /* ODT Strength */ + switch (mrc_params->rd_odt_value) { + case 1: + temp = 0x3; + break; /* 60 ohm */ + case 2: + temp = 0x3; + break; /* 120 ohm */ + case 3: + temp = 0x3; + break; /* 180 ohm */ + default: + temp = 0x3; + break; /* 120 ohm */ + } + + /* ODT strength */ + mrc_alt_write_mask(DDRPHY, + (B0RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (temp << 5), (BIT6 | BIT5)); + /* ODT strength */ + mrc_alt_write_mask(DDRPHY, + (B1RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (temp << 5), (BIT6 | BIT5)); + + /* Dynamic ODT/DIFFAMP */ + temp = (((cas) << 24) | ((cas) << 16) | + ((cas) << 8) | ((cas) << 0)); + switch (speed) { + case 0: + temp -= 0x01010101; + break; /* 800 */ + case 1: + temp -= 0x02020202; + break; /* 1066 */ + case 2: + temp -= 0x03030303; + break; /* 1333 */ + case 3: + temp -= 0x04040404; + break; /* 1600 */ + } + + /* Launch Time: ODT, DIFFAMP, ODT, DIFFAMP */ + mrc_alt_write_mask(DDRPHY, + (B01LATCTL1 + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, + (BIT28 | BIT27 | BIT26 | BIT25 | BIT24 | + BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | + BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT4 | BIT3 | BIT2 | BIT1 | BIT0)); + switch (speed) { + /* HSD#234715 */ + case 0: + temp = ((0x06 << 16) | (0x07 << 8)); + break; /* 800 */ + case 1: + temp = ((0x07 << 16) | (0x08 << 8)); + break; /* 1066 */ + case 2: + temp = ((0x09 << 16) | (0x0A << 8)); + break; /* 1333 */ + case 3: + temp = ((0x0A << 16) | (0x0B << 8)); + break; /* 1600 */ + } + + /* On Duration: ODT, DIFFAMP */ + mrc_alt_write_mask(DDRPHY, + (B0ONDURCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT13 | BIT12 | BIT11 | BIT10 | + BIT9 | BIT8)); + /* On Duration: ODT, DIFFAMP */ + mrc_alt_write_mask(DDRPHY, + (B1ONDURCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT13 | BIT12 | BIT11 | BIT10 | + BIT9 | BIT8)); + + switch (mrc_params->rd_odt_value) { + case 0: + /* override DIFFAMP=on, ODT=off */ + temp = ((0x3F << 16) | (0x3f << 10)); + break; + default: + /* override DIFFAMP=on, ODT=on */ + temp = ((0x3F << 16) | (0x2A << 10)); + break; + } + + /* Override: DIFFAMP, ODT */ + mrc_alt_write_mask(DDRPHY, + (B0OVRCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT15 | BIT14 | BIT13 | BIT12 | + BIT11 | BIT10)); + /* Override: DIFFAMP, ODT */ + mrc_alt_write_mask(DDRPHY, + (B1OVRCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT15 | BIT14 | BIT13 | BIT12 | + BIT11 | BIT10)); + + /* DLL Setup */ + + /* 1xCLK Domain Timings: tEDP,RCVEN,WDQS (PO) */ + mrc_alt_write_mask(DDRPHY, + (B0LATCTL0 + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (((cas + 7) << 16) | ((cas - 4) << 8) | + ((cwl - 2) << 0)), + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT12 | BIT11 | BIT10 | BIT9 | + BIT8 | BIT4 | BIT3 | BIT2 | BIT1 | + BIT0)); + mrc_alt_write_mask(DDRPHY, + (B1LATCTL0 + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (((cas + 7) << 16) | ((cas - 4) << 8) | + ((cwl - 2) << 0)), + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT12 | BIT11 | BIT10 | BIT9 | + BIT8 | BIT4 | BIT3 | BIT2 | BIT1 | + BIT0)); + + /* RCVEN Bypass (PO) */ + mrc_alt_write_mask(DDRPHY, + (B0RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + ((0x0 << 7) | (0x0 << 0)), + (BIT7 | BIT0)); + mrc_alt_write_mask(DDRPHY, + (B1RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + ((0x0 << 7) | (0x0 << 0)), + (BIT7 | BIT0)); + + /* TX */ + mrc_alt_write_mask(DDRPHY, + (DQCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT16), (BIT16)); + mrc_alt_write_mask(DDRPHY, + (B01PTRCTL1 + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT8), (BIT8)); + + /* RX (PO) */ + /* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */ + mrc_alt_write_mask(DDRPHY, + (B0VREFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + ((0x03 << 2) | (0x0 << 1) | (0x0 << 0)), + (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | + BIT2 | BIT1 | BIT0)); + /* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */ + mrc_alt_write_mask(DDRPHY, + (B1VREFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + ((0x03 << 2) | (0x0 << 1) | (0x0 << 0)), + (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | + BIT2 | BIT1 | BIT0)); + /* Per-Bit De-Skew Enable */ + mrc_alt_write_mask(DDRPHY, + (B0RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (0), (BIT4)); + /* Per-Bit De-Skew Enable */ + mrc_alt_write_mask(DDRPHY, + (B1RXIOBUFCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (0), (BIT4)); + } + + /* CLKEBB */ + mrc_alt_write_mask(DDRPHY, + (CMDOBSCKEBBCTL + (ch * DDRIOCCC_CH_OFFSET)), + 0, (BIT23)); + + /* Enable tristate control of cmd/address bus */ + mrc_alt_write_mask(DDRPHY, + (CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)), + 0, (BIT1 | BIT0)); + + /* ODT RCOMP */ + mrc_alt_write_mask(DDRPHY, + (CMDRCOMPODT + (ch * DDRIOCCC_CH_OFFSET)), + ((0x03 << 5) | (0x03 << 0)), + (BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | + BIT3 | BIT2 | BIT1 | BIT0)); + + /* CMDPM* registers must be programmed in this order */ + + /* Turn On Delays: SFR (regulator), MPLL */ + mrc_alt_write_mask(DDRPHY, + (CMDPMDLYREG4 + (ch * DDRIOCCC_CH_OFFSET)), + ((0xFFFFU << 16) | (0xFFFF << 0)), + 0xFFFFFFFF); + /* + * Delays: ASSERT_IOBUFACT_to_ALLON0_for_PM_MSG_3, + * VREG (MDLL) Turn On, ALLON0_to_DEASSERT_IOBUFACT + * for_PM_MSG_gt0, MDLL Turn On + */ + mrc_alt_write_mask(DDRPHY, + (CMDPMDLYREG3 + (ch * DDRIOCCC_CH_OFFSET)), + ((0xFU << 28) | (0xFFF << 16) | (0xF << 12) | + (0x616 << 0)), 0xFFFFFFFF); + /* MPLL Divider Reset Delays */ + mrc_alt_write_mask(DDRPHY, + (CMDPMDLYREG2 + (ch * DDRIOCCC_CH_OFFSET)), + ((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) | + (0xFF << 0)), 0xFFFFFFFF); + /* Turn Off Delays: VREG, Staggered MDLL, MDLL, PI */ + mrc_alt_write_mask(DDRPHY, + (CMDPMDLYREG1 + (ch * DDRIOCCC_CH_OFFSET)), + ((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) | + (0xFF << 0)), 0xFFFFFFFF); + /* Turn On Delays: MPLL, Staggered MDLL, PI, IOBUFACT */ + mrc_alt_write_mask(DDRPHY, + (CMDPMDLYREG0 + (ch * DDRIOCCC_CH_OFFSET)), + ((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) | + (0xFF << 0)), 0xFFFFFFFF); + /* Allow PUnit signals */ + mrc_alt_write_mask(DDRPHY, + (CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)), + ((0x6 << 8) | BIT6 | (0x4 << 0)), + (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | + BIT25 | BIT24 | BIT23 | BIT22 | BIT21 | BIT11 | + BIT10 | BIT9 | BIT8 | BIT6 | BIT3 | BIT2 | + BIT1 | BIT0)); + /* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */ + mrc_alt_write_mask(DDRPHY, + (CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + ((0x3 << 4) | (0x7 << 0)), + (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | + BIT0)); + + /* CLK-CTL */ + mrc_alt_write_mask(DDRPHY, + (CCOBSCKEBBCTL + (ch * DDRIOCCC_CH_OFFSET)), + 0, BIT24); /* CLKEBB */ + /* Buffer Enable: CS,CKE,ODT,CLK */ + mrc_alt_write_mask(DDRPHY, + (CCCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)), + ((0x0 << 16) | (0x0 << 12) | (0x0 << 8) | + (0xF << 4) | BIT0), + (BIT19 | BIT18 | BIT17 | BIT16 | BIT15 | BIT14 | + BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT7 | BIT6 | BIT5 | BIT4 | BIT0)); + /* ODT RCOMP */ + mrc_alt_write_mask(DDRPHY, + (CCRCOMPODT + (ch * DDRIOCCC_CH_OFFSET)), + ((0x03 << 8) | (0x03 << 0)), + (BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | BIT4 | + BIT3 | BIT2 | BIT1 | BIT0)); + /* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */ + mrc_alt_write_mask(DDRPHY, + (CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + ((0x3 << 4) | (0x7 << 0)), + (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | + BIT0)); + + /* + * COMP (RON channel specific) + * - DQ/DQS/DM RON: 32 Ohm + * - CTRL/CMD RON: 27 Ohm + * - CLK RON: 26 Ohm + */ + /* RCOMP Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (DQVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x08 << 24) | (0x03 << 16)), + (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | + BIT24 | BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16)); + /* RCOMP Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (CMDVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x0C << 24) | (0x03 << 16)), + (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | + BIT24 | BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16)); + /* RCOMP Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (CLKVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x0F << 24) | (0x03 << 16)), + (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | + BIT24 | BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16)); + /* RCOMP Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (DQSVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x08 << 24) | (0x03 << 16)), + (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | + BIT24 | BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16)); + /* RCOMP Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (CTLVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x0C << 24) | (0x03 << 16)), + (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | + BIT24 | BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16)); + + /* DQS Swapped Input Enable */ + mrc_alt_write_mask(DDRPHY, + (COMPEN1CH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT19 | BIT17), + (BIT31 | BIT30 | BIT19 | BIT17 | + BIT15 | BIT14)); + + /* ODT VREF = 1.5 x 274/360+274 = 0.65V (code of ~50) */ + /* ODT Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (DQVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x32 << 8) | (0x03 << 0)), + (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)); + /* ODT Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (DQSVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x32 << 8) | (0x03 << 0)), + (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)); + /* ODT Vref PU/PD */ + mrc_alt_write_mask(DDRPHY, + (CLKVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x0E << 8) | (0x05 << 0)), + (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)); + + /* + * Slew rate settings are frequency specific, + * numbers below are for 800Mhz (speed == 0) + * - DQ/DQS/DM/CLK SR: 4V/ns, + * - CTRL/CMD SR: 1.5V/ns + */ + temp = (0x0E << 16) | (0x0E << 12) | (0x08 << 8) | + (0x0B << 4) | (0x0B << 0); + /* DCOMP Delay Select: CTL,CMD,CLK,DQS,DQ */ + mrc_alt_write_mask(DDRPHY, + (DLYSELCH0 + (ch * DDRCOMP_CH_OFFSET)), + temp, + (BIT19 | BIT18 | BIT17 | BIT16 | BIT15 | + BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | + BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | + BIT3 | BIT2 | BIT1 | BIT0)); + /* TCO Vref CLK,DQS,DQ */ + mrc_alt_write_mask(DDRPHY, + (TCOVREFCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x05 << 16) | (0x05 << 8) | (0x05 << 0)), + (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT13 | BIT12 | BIT11 | BIT10 | + BIT9 | BIT8 | BIT5 | BIT4 | BIT3 | BIT2 | + BIT1 | BIT0)); + /* ODTCOMP CMD/CTL PU/PD */ + mrc_alt_write_mask(DDRPHY, + (CCBUFODTCH0 + (ch * DDRCOMP_CH_OFFSET)), + ((0x03 << 8) | (0x03 << 0)), + (BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | + BIT4 | BIT3 | BIT2 | BIT1 | BIT0)); + /* COMP */ + mrc_alt_write_mask(DDRPHY, + (COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)), + 0, (BIT31 | BIT30 | BIT8)); + +#ifdef BACKUP_COMPS + /* DQ COMP Overrides */ + /* RCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* RCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x10 << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x10 << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + + /* DQS COMP Overrides */ + /* RCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQSDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* RCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQSDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQSDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x10 << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQSDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x10 << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQSODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQSODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQSTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQSTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + + /* CLK COMP Overrides */ + /* RCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CLKDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0C << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* RCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CLKDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0C << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CLKDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x07 << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CLKDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x07 << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CLKODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* ODTCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CLKODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0B << 16)), + (BIT31 | (0x0B << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CLKTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CLKTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31), (BIT31)); + + /* CMD COMP Overrides */ + /* RCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CMDDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0D << 16)), + (BIT31 | BIT21 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* RCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CMDDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0D << 16)), + (BIT31 | BIT21 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CMDDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CMDDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + + /* CTL COMP Overrides */ + /* RCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CTLDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0D << 16)), + (BIT31 | BIT21 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* RCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CTLDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0D << 16)), + (BIT31 | BIT21 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CTLDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* DCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CTLDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x0A << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); +#else + /* DQ TCOCOMP Overrides */ + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + + /* DQS TCOCOMP Overrides */ + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (DQSTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (DQSTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + + /* CLK TCOCOMP Overrides */ + /* TCOCOMP PU */ + mrc_alt_write_mask(DDRPHY, + (CLKTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); + /* TCOCOMP PD */ + mrc_alt_write_mask(DDRPHY, + (CLKTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)), + (BIT31 | (0x1F << 16)), + (BIT31 | BIT20 | BIT19 | + BIT18 | BIT17 | BIT16)); +#endif + + /* program STATIC delays */ +#ifdef BACKUP_WCMD + set_wcmd(ch, ddr_wcmd[PLATFORM_ID]); +#else + set_wcmd(ch, ddr_wclk[PLATFORM_ID] + HALF_CLK); +#endif + + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1<channel_enables & (1 << ch)) { + /* DQ01-DQ23 */ + for (bl_grp = 0; + bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2); + bl_grp++) { + mrc_alt_write_mask(DDRPHY, + (DQMDLLCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT13), + (BIT13)); /* Enable VREG */ + delay_n(3); + } + + /* ECC */ + mrc_alt_write_mask(DDRPHY, (ECCMDLLCTL), + (BIT13), (BIT13)); /* Enable VREG */ + delay_n(3); + /* CMD */ + mrc_alt_write_mask(DDRPHY, + (CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + (BIT13), (BIT13)); /* Enable VREG */ + delay_n(3); + /* CLK-CTL */ + mrc_alt_write_mask(DDRPHY, + (CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + (BIT13), (BIT13)); /* Enable VREG */ + delay_n(3); + } + } + + /* STEP2 */ + mrc_post_code(0x03, 0x12); + delay_n(200); + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* DQ01-DQ23 */ + for (bl_grp = 0; + bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2); + bl_grp++) { + mrc_alt_write_mask(DDRPHY, + (DQMDLLCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT17), + (BIT17)); /* Enable MCDLL */ + delay_n(50); + } + + /* ECC */ + mrc_alt_write_mask(DDRPHY, (ECCMDLLCTL), + (BIT17), (BIT17)); /* Enable MCDLL */ + delay_n(50); + /* CMD */ + mrc_alt_write_mask(DDRPHY, + (CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + (BIT18), (BIT18)); /* Enable MCDLL */ + delay_n(50); + /* CLK-CTL */ + mrc_alt_write_mask(DDRPHY, + (CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)), + (BIT18), (BIT18)); /* Enable MCDLL */ + delay_n(50); + } + } + + /* STEP3: */ + mrc_post_code(0x03, 0x13); + delay_n(100); + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* DQ01-DQ23 */ + for (bl_grp = 0; + bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2); + bl_grp++) { +#ifdef FORCE_16BIT_DDRIO + temp = ((bl_grp) && + (mrc_params->channel_width == X16)) ? + ((0x1 << 12) | (0x1 << 8) | + (0xF << 4) | (0xF << 0)) : + ((0xF << 12) | (0xF << 8) | + (0xF << 4) | (0xF << 0)); +#else + temp = ((0xF << 12) | (0xF << 8) | + (0xF << 4) | (0xF << 0)); +#endif + /* Enable TXDLL */ + mrc_alt_write_mask(DDRPHY, + (DQDLLTXCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + temp, 0xFFFF); + delay_n(3); + /* Enable RXDLL */ + mrc_alt_write_mask(DDRPHY, + (DQDLLRXCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT3 | BIT2 | BIT1 | BIT0), + (BIT3 | BIT2 | BIT1 | BIT0)); + delay_n(3); + /* Enable RXDLL Overrides BL0 */ + mrc_alt_write_mask(DDRPHY, + (B0OVRCTL + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (BIT3 | BIT2 | BIT1 | BIT0), + (BIT3 | BIT2 | BIT1 | BIT0)); + } + + /* ECC */ + temp = ((0xF << 12) | (0xF << 8) | + (0xF << 4) | (0xF << 0)); + mrc_alt_write_mask(DDRPHY, (ECCDLLTXCTL), + temp, 0xFFFF); + delay_n(3); + + /* CMD (PO) */ + mrc_alt_write_mask(DDRPHY, + (CMDDLLTXCTL + (ch * DDRIOCCC_CH_OFFSET)), + temp, 0xFFFF); + delay_n(3); + } + } + + /* STEP4 */ + mrc_post_code(0x03, 0x14); + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* Host To Memory Clock Alignment (HMC) for 800/1066 */ + for (bl_grp = 0; + bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2); + bl_grp++) { + /* CLK_ALIGN_MOD_ID */ + mrc_alt_write_mask(DDRPHY, + (DQCLKALIGNREG2 + + (bl_grp * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + (bl_grp) ? (0x3) : (0x1), + (BIT3 | BIT2 | BIT1 | BIT0)); + } + + mrc_alt_write_mask(DDRPHY, + (ECCCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)), + 0x2, + (BIT3 | BIT2 | BIT1 | BIT0)); + mrc_alt_write_mask(DDRPHY, + (CMDCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)), + 0x0, + (BIT3 | BIT2 | BIT1 | BIT0)); + mrc_alt_write_mask(DDRPHY, + (CCCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)), + 0x2, + (BIT3 | BIT2 | BIT1 | BIT0)); + mrc_alt_write_mask(DDRPHY, + (CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET)), + (0x2 << 4), (BIT5 | BIT4)); + /* + * NUM_SAMPLES, MAX_SAMPLES, + * MACRO_PI_STEP, MICRO_PI_STEP + */ + mrc_alt_write_mask(DDRPHY, + (CMDCLKALIGNREG1 + (ch * DDRIOCCC_CH_OFFSET)), + ((0x18 << 16) | (0x10 << 8) | + (0x8 << 2) | (0x1 << 0)), + (BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | + BIT16 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | + BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | + BIT2 | BIT1 | BIT0)); + /* TOTAL_NUM_MODULES, FIRST_U_PARTITION */ + mrc_alt_write_mask(DDRPHY, + (CMDCLKALIGNREG2 + (ch * DDRIOCCC_CH_OFFSET)), + ((0x10 << 16) | (0x4 << 8) | (0x2 << 4)), + (BIT20 | BIT19 | BIT18 | BIT17 | BIT16 | + BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | + BIT5 | BIT4)); +#ifdef HMC_TEST + /* START_CLK_ALIGN=1 */ + mrc_alt_write_mask(DDRPHY, + (CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET)), + BIT24, BIT24); + while (msg_port_alt_read(DDRPHY, + (CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET))) & + BIT24) + ; /* wait for START_CLK_ALIGN=0 */ +#endif + + /* Set RD/WR Pointer Seperation & COUNTEN & FIFOPTREN */ + mrc_alt_write_mask(DDRPHY, + (CMDPTRREG + (ch * DDRIOCCC_CH_OFFSET)), + BIT0, BIT0); /* WRPTRENABLE=1 */ + + /* COMP initial */ + /* enable bypass for CLK buffer (PO) */ + mrc_alt_write_mask(DDRPHY, + (COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)), + BIT5, BIT5); + /* Initial COMP Enable */ + mrc_alt_write_mask(DDRPHY, (CMPCTRL), + (BIT0), (BIT0)); + /* wait for Initial COMP Enable = 0 */ + while (msg_port_alt_read(DDRPHY, (CMPCTRL)) & BIT0) + ; + /* disable bypass for CLK buffer (PO) */ + mrc_alt_write_mask(DDRPHY, + (COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)), + ~BIT5, BIT5); + + /* IOBUFACT */ + + /* STEP4a */ + mrc_alt_write_mask(DDRPHY, + (CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)), + BIT2, BIT2); /* IOBUFACTRST_N=1 */ + + /* DDRPHY initialization complete */ + mrc_alt_write_mask(DDRPHY, + (CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)), + BIT20, BIT20); /* SPID_INIT_COMPLETE=1 */ + } + } + + LEAVEFN(); +} + +/* This function performs JEDEC initialization on all enabled channels */ +void perform_jedec_init(struct mrc_params *mrc_params) +{ + uint8_t twr, wl, rank; + uint32_t tck; + u32 dtr0; + u32 drp; + u32 drmc; + u32 mrs0_cmd = 0; + u32 emrs1_cmd = 0; + u32 emrs2_cmd = 0; + u32 emrs3_cmd = 0; + + ENTERFN(); + + /* jedec_init starts */ + mrc_post_code(0x04, 0x00); + + /* DDR3_RESET_SET=0, DDR3_RESET_RESET=1 */ + mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, BIT1, (BIT8 | BIT1)); + + /* Assert RESET# for 200us */ + delay_u(200); + + /* DDR3_RESET_SET=1, DDR3_RESET_RESET=0 */ + mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, BIT8, (BIT8 | BIT1)); + + dtr0 = msg_port_read(MEM_CTLR, DTR0); + + /* + * Set CKEVAL for populated ranks + * then send NOP to each rank (#4550197) + */ + + drp = msg_port_read(MEM_CTLR, DRP); + drp &= 0x3; + + drmc = msg_port_read(MEM_CTLR, DRMC); + drmc &= 0xFFFFFFFC; + drmc |= (BIT4 | drp); + + msg_port_write(MEM_CTLR, DRMC, drmc); + + for (rank = 0; rank < NUM_RANKS; rank++) { + /* Skip to next populated rank */ + if ((mrc_params->rank_enables & (1 << rank)) == 0) + continue; + + dram_init_command(DCMD_NOP(rank)); + } + + msg_port_write(MEM_CTLR, DRMC, + (mrc_params->rd_odt_value == 0 ? BIT12 : 0)); + + /* + * setup for emrs 2 + * BIT[15:11] --> Always "0" + * BIT[10:09] --> Rtt_WR: want "Dynamic ODT Off" (0) + * BIT[08] --> Always "0" + * BIT[07] --> SRT: use sr_temp_range + * BIT[06] --> ASR: want "Manual SR Reference" (0) + * BIT[05:03] --> CWL: use oem_tCWL + * BIT[02:00] --> PASR: want "Full Array" (0) + */ + emrs2_cmd |= (2 << 3); + wl = 5 + mrc_params->ddr_speed; + emrs2_cmd |= ((wl - 5) << 9); + emrs2_cmd |= (mrc_params->sr_temp_range << 13); + + /* + * setup for emrs 3 + * BIT[15:03] --> Always "0" + * BIT[02] --> MPR: want "Normal Operation" (0) + * BIT[01:00] --> MPR_Loc: want "Predefined Pattern" (0) + */ + emrs3_cmd |= (3 << 3); + + /* + * setup for emrs 1 + * BIT[15:13] --> Always "0" + * BIT[12:12] --> Qoff: want "Output Buffer Enabled" (0) + * BIT[11:11] --> TDQS: want "Disabled" (0) + * BIT[10:10] --> Always "0" + * BIT[09,06,02] --> Rtt_nom: use rtt_nom_value + * BIT[08] --> Always "0" + * BIT[07] --> WR_LVL: want "Disabled" (0) + * BIT[05,01] --> DIC: use ron_value + * BIT[04:03] --> AL: additive latency want "0" (0) + * BIT[00] --> DLL: want "Enable" (0) + * + * (BIT5|BIT1) set Ron value + * 00 --> RZQ/6 (40ohm) + * 01 --> RZQ/7 (34ohm) + * 1* --> RESERVED + * + * (BIT9|BIT6|BIT2) set Rtt_nom value + * 000 --> Disabled + * 001 --> RZQ/4 ( 60ohm) + * 010 --> RZQ/2 (120ohm) + * 011 --> RZQ/6 ( 40ohm) + * 1** --> RESERVED + */ + emrs1_cmd |= (1 << 3); + emrs1_cmd &= ~BIT6; + + if (mrc_params->ron_value == 0) + emrs1_cmd |= BIT7; + else + emrs1_cmd &= ~BIT7; + + if (mrc_params->rtt_nom_value == 0) + emrs1_cmd |= (DDR3_EMRS1_RTTNOM_40 << 6); + else if (mrc_params->rtt_nom_value == 1) + emrs1_cmd |= (DDR3_EMRS1_RTTNOM_60 << 6); + else if (mrc_params->rtt_nom_value == 2) + emrs1_cmd |= (DDR3_EMRS1_RTTNOM_120 << 6); + + /* save MRS1 value (excluding control fields) */ + mrc_params->mrs1 = emrs1_cmd >> 6; + + /* + * setup for mrs 0 + * BIT[15:13] --> Always "0" + * BIT[12] --> PPD: for Quark (1) + * BIT[11:09] --> WR: use oem_tWR + * BIT[08] --> DLL: want "Reset" (1, self clearing) + * BIT[07] --> MODE: want "Normal" (0) + * BIT[06:04,02] --> CL: use oem_tCAS + * BIT[03] --> RD_BURST_TYPE: want "Interleave" (1) + * BIT[01:00] --> BL: want "8 Fixed" (0) + * WR: + * 0 --> 16 + * 1 --> 5 + * 2 --> 6 + * 3 --> 7 + * 4 --> 8 + * 5 --> 10 + * 6 --> 12 + * 7 --> 14 + * CL: + * BIT[02:02] "0" if oem_tCAS <= 11 (1866?) + * BIT[06:04] use oem_tCAS-4 + */ + mrs0_cmd |= BIT14; + mrs0_cmd |= BIT18; + mrs0_cmd |= ((((dtr0 >> 12) & 7) + 1) << 10); + + tck = t_ck[mrc_params->ddr_speed]; + /* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */ + twr = MCEIL(15000, tck); + mrs0_cmd |= ((twr - 4) << 15); + + for (rank = 0; rank < NUM_RANKS; rank++) { + /* Skip to next populated rank */ + if ((mrc_params->rank_enables & (1 << rank)) == 0) + continue; + + emrs2_cmd |= (rank << 22); + dram_init_command(emrs2_cmd); + + emrs3_cmd |= (rank << 22); + dram_init_command(emrs3_cmd); + + emrs1_cmd |= (rank << 22); + dram_init_command(emrs1_cmd); + + mrs0_cmd |= (rank << 22); + dram_init_command(mrs0_cmd); + + dram_init_command(DCMD_ZQCL(rank)); + } + + LEAVEFN(); +} + +/* + * Dunit Initialization Complete + * + * Indicates that initialization of the Dunit has completed. + * + * Memory accesses are permitted and maintenance operation begins. + * Until this bit is set to a 1, the memory controller will not accept + * DRAM requests from the MEMORY_MANAGER or HTE. + */ +void set_ddr_init_complete(struct mrc_params *mrc_params) +{ + u32 dco; + + ENTERFN(); + + dco = msg_port_read(MEM_CTLR, DCO); + dco &= ~BIT28; + dco |= BIT31; + msg_port_write(MEM_CTLR, DCO, dco); + + LEAVEFN(); +} + +/* + * This function will retrieve relevant timing data + * + * This data will be used on subsequent boots to speed up boot times + * and is required for Suspend To RAM capabilities. + */ +void restore_timings(struct mrc_params *mrc_params) +{ + uint8_t ch, rk, bl; + const struct mrc_timings *mt = &mrc_params->timings; + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + for (rk = 0; rk < NUM_RANKS; rk++) { + for (bl = 0; bl < NUM_BYTE_LANES; bl++) { + set_rcvn(ch, rk, bl, mt->rcvn[ch][rk][bl]); + set_rdqs(ch, rk, bl, mt->rdqs[ch][rk][bl]); + set_wdqs(ch, rk, bl, mt->wdqs[ch][rk][bl]); + set_wdq(ch, rk, bl, mt->wdq[ch][rk][bl]); + if (rk == 0) { + /* VREF (RANK0 only) */ + set_vref(ch, bl, mt->vref[ch][bl]); + } + } + set_wctl(ch, rk, mt->wctl[ch][rk]); + } + set_wcmd(ch, mt->wcmd[ch]); + } +} + +/* + * Configure default settings normally set as part of read training + * + * Some defaults have to be set earlier as they may affect earlier + * training steps. + */ +void default_timings(struct mrc_params *mrc_params) +{ + uint8_t ch, rk, bl; + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + for (rk = 0; rk < NUM_RANKS; rk++) { + for (bl = 0; bl < NUM_BYTE_LANES; bl++) { + set_rdqs(ch, rk, bl, 24); + if (rk == 0) { + /* VREF (RANK0 only) */ + set_vref(ch, bl, 32); + } + } + } + } +} + +/* + * This function will perform our RCVEN Calibration Algorithm. + * We will only use the 2xCLK domain timings to perform RCVEN Calibration. + * All byte lanes will be calibrated "simultaneously" per channel per rank. + */ +void rcvn_cal(struct mrc_params *mrc_params) +{ + uint8_t ch; /* channel counter */ + uint8_t rk; /* rank counter */ + uint8_t bl; /* byte lane counter */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; + +#ifdef R2R_SHARING + /* used to find placement for rank2rank sharing configs */ + uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; +#ifndef BACKUP_RCVN + /* used to find placement for rank2rank sharing configs */ + uint32_t num_ranks_enabled = 0; +#endif +#endif + +#ifdef BACKUP_RCVN +#else + uint32_t temp; + /* absolute PI value to be programmed on the byte lane */ + uint32_t delay[NUM_BYTE_LANES]; + u32 dtr1, dtr1_save; +#endif + + ENTERFN(); + + /* rcvn_cal starts */ + mrc_post_code(0x05, 0x00); + +#ifndef BACKUP_RCVN + /* need separate burst to sample DQS preamble */ + dtr1 = msg_port_read(MEM_CTLR, DTR1); + dtr1_save = dtr1; + dtr1 |= BIT12; + msg_port_write(MEM_CTLR, DTR1, dtr1); +#endif + +#ifdef R2R_SHARING + /* need to set "final_delay[][]" elements to "0" */ + memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay)); +#endif + + /* loop through each enabled channel */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* perform RCVEN Calibration on a per rank basis */ + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + /* + * POST_CODE here indicates the current + * channel and rank being calibrated + */ + mrc_post_code(0x05, (0x10 + ((ch << 4) | rk))); + +#ifdef BACKUP_RCVN + /* et hard-coded timing values */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) + set_rcvn(ch, rk, bl, ddr_rcvn[PLATFORM_ID]); +#else + /* enable FIFORST */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) { + mrc_alt_write_mask(DDRPHY, + (B01PTRCTL1 + + ((bl >> 1) * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + 0, BIT8); + } + /* initialize the starting delay to 128 PI (cas +1 CLK) */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + /* 1x CLK domain timing is cas-4 */ + delay[bl] = (4 + 1) * FULL_CLK; + + set_rcvn(ch, rk, bl, delay[bl]); + } + + /* now find the rising edge */ + find_rising_edge(mrc_params, delay, ch, rk, true); + + /* Now increase delay by 32 PI (1/4 CLK) to place in center of high pulse */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + delay[bl] += QRTR_CLK; + set_rcvn(ch, rk, bl, delay[bl]); + } + /* Now decrement delay by 128 PI (1 CLK) until we sample a "0" */ + do { + temp = sample_dqs(mrc_params, ch, rk, true); + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (temp & (1 << bl)) { + if (delay[bl] >= FULL_CLK) { + delay[bl] -= FULL_CLK; + set_rcvn(ch, rk, bl, delay[bl]); + } else { + /* not enough delay */ + training_message(ch, rk, bl); + mrc_post_code(0xEE, 0x50); + } + } + } + } while (temp & 0xFF); + +#ifdef R2R_SHARING + /* increment "num_ranks_enabled" */ + num_ranks_enabled++; + /* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + delay[bl] += QRTR_CLK; + /* add "delay[]" values to "final_delay[][]" for rolling average */ + final_delay[ch][bl] += delay[bl]; + /* set timing based on rolling average values */ + set_rcvn(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled)); + } +#else + /* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + delay[bl] += QRTR_CLK; + set_rcvn(ch, rk, bl, delay[bl]); + } +#endif + + /* disable FIFORST */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) { + mrc_alt_write_mask(DDRPHY, + (B01PTRCTL1 + + ((bl >> 1) * DDRIODQ_BL_OFFSET) + + (ch * DDRIODQ_CH_OFFSET)), + BIT8, BIT8); + } +#endif + } + } + } + } + +#ifndef BACKUP_RCVN + /* restore original */ + msg_port_write(MEM_CTLR, DTR1, dtr1_save); +#endif + + LEAVEFN(); +} + +/* + * This function will perform the Write Levelling algorithm + * (align WCLK and WDQS). + * + * This algorithm will act on each rank in each channel separately. + */ +void wr_level(struct mrc_params *mrc_params) +{ + uint8_t ch; /* channel counter */ + uint8_t rk; /* rank counter */ + uint8_t bl; /* byte lane counter */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; + +#ifdef R2R_SHARING + /* used to find placement for rank2rank sharing configs */ + uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; +#ifndef BACKUP_WDQS + /* used to find placement for rank2rank sharing configs */ + uint32_t num_ranks_enabled = 0; +#endif +#endif + +#ifdef BACKUP_WDQS +#else + /* determines stop condition for CRS_WR_LVL */ + bool all_edges_found; + /* absolute PI value to be programmed on the byte lane */ + uint32_t delay[NUM_BYTE_LANES]; + /* + * static makes it so the data is loaded in the heap once by shadow(), + * where non-static copies the data onto the stack every time this + * function is called + */ + uint32_t address; /* address to be checked during COARSE_WR_LVL */ + u32 dtr4, dtr4_save; +#endif + + ENTERFN(); + + /* wr_level starts */ + mrc_post_code(0x06, 0x00); + +#ifdef R2R_SHARING + /* need to set "final_delay[][]" elements to "0" */ + memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay)); +#endif + + /* loop through each enabled channel */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + /* perform WRITE LEVELING algorithm on a per rank basis */ + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + /* + * POST_CODE here indicates the current + * rank and channel being calibrated + */ + mrc_post_code(0x06, (0x10 + ((ch << 4) | rk))); + +#ifdef BACKUP_WDQS + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + set_wdqs(ch, rk, bl, ddr_wdqs[PLATFORM_ID]); + set_wdq(ch, rk, bl, (ddr_wdqs[PLATFORM_ID] - QRTR_CLK)); + } +#else + /* + * perform a single PRECHARGE_ALL command to + * make DRAM state machine go to IDLE state + */ + dram_init_command(DCMD_PREA(rk)); + + /* + * enable Write Levelling Mode + * (EMRS1 w/ Write Levelling Mode Enable) + */ + dram_init_command(DCMD_MRS1(rk, 0x0082)); + + /* + * set ODT DRAM Full Time Termination + * disable in MCU + */ + + dtr4 = msg_port_read(MEM_CTLR, DTR4); + dtr4_save = dtr4; + dtr4 |= BIT15; + msg_port_write(MEM_CTLR, DTR4, dtr4); + + for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) { + /* + * Enable Sandy Bridge Mode (WDQ Tri-State) & + * Ensure 5 WDQS pulses during Write Leveling + */ + mrc_alt_write_mask(DDRPHY, + DQCTL + (DDRIODQ_BL_OFFSET * bl) + (DDRIODQ_CH_OFFSET * ch), + (BIT28 | BIT8 | BIT6 | BIT4 | BIT2), + (BIT28 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2)); + } + + /* Write Leveling Mode enabled in IO */ + mrc_alt_write_mask(DDRPHY, + CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * ch), + BIT16, BIT16); + + /* Initialize the starting delay to WCLK */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + /* + * CLK0 --> RK0 + * CLK1 --> RK1 + */ + delay[bl] = get_wclk(ch, rk); + + set_wdqs(ch, rk, bl, delay[bl]); + } + + /* now find the rising edge */ + find_rising_edge(mrc_params, delay, ch, rk, false); + + /* disable Write Levelling Mode */ + mrc_alt_write_mask(DDRPHY, + CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * ch), + 0, BIT16); + + for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) { + /* Disable Sandy Bridge Mode & Ensure 4 WDQS pulses during normal operation */ + mrc_alt_write_mask(DDRPHY, + DQCTL + (DDRIODQ_BL_OFFSET * bl) + (DDRIODQ_CH_OFFSET * ch), + (BIT8 | BIT6 | BIT4 | BIT2), + (BIT28 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2)); + } + + /* restore original DTR4 */ + msg_port_write(MEM_CTLR, DTR4, dtr4_save); + + /* + * restore original value + * (Write Levelling Mode Disable) + */ + dram_init_command(DCMD_MRS1(rk, mrc_params->mrs1)); + + /* + * perform a single PRECHARGE_ALL command to + * make DRAM state machine go to IDLE state + */ + dram_init_command(DCMD_PREA(rk)); + + mrc_post_code(0x06, (0x30 + ((ch << 4) | rk))); + + /* + * COARSE WRITE LEVEL: + * check that we're on the correct clock edge + */ + + /* hte reconfiguration request */ + mrc_params->hte_setup = 1; + + /* start CRS_WR_LVL with WDQS = WDQS + 128 PI */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + delay[bl] = get_wdqs(ch, rk, bl) + FULL_CLK; + set_wdqs(ch, rk, bl, delay[bl]); + /* + * program WDQ timings based on WDQS + * (WDQ = WDQS - 32 PI) + */ + set_wdq(ch, rk, bl, (delay[bl] - QRTR_CLK)); + } + + /* get an address in the targeted channel/rank */ + address = get_addr(ch, rk); + do { + uint32_t coarse_result = 0x00; + uint32_t coarse_result_mask = byte_lane_mask(mrc_params); + /* assume pass */ + all_edges_found = true; + + mrc_params->hte_setup = 1; + coarse_result = check_rw_coarse(mrc_params, address); + + /* check for failures and margin the byte lane back 128 PI (1 CLK) */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (coarse_result & (coarse_result_mask << bl)) { + all_edges_found = false; + delay[bl] -= FULL_CLK; + set_wdqs(ch, rk, bl, delay[bl]); + /* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */ + set_wdq(ch, rk, bl, (delay[bl] - QRTR_CLK)); + } + } + } while (!all_edges_found); + +#ifdef R2R_SHARING + /* increment "num_ranks_enabled" */ + num_ranks_enabled++; + /* accumulate "final_delay[][]" values from "delay[]" values for rolling average */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + final_delay[ch][bl] += delay[bl]; + set_wdqs(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled)); + /* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */ + set_wdq(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled) - QRTR_CLK); + } +#endif +#endif + } + } + } + } + + LEAVEFN(); +} + +void prog_page_ctrl(struct mrc_params *mrc_params) +{ + u32 dpmc0; + + ENTERFN(); + + dpmc0 = msg_port_read(MEM_CTLR, DPMC0); + dpmc0 &= ~(BIT16 | BIT17 | BIT18); + dpmc0 |= (4 << 16); + dpmc0 |= BIT21; + msg_port_write(MEM_CTLR, DPMC0, dpmc0); +} + +/* + * This function will perform the READ TRAINING Algorithm on all + * channels/ranks/byte_lanes simultaneously to minimize execution time. + * + * The idea here is to train the VREF and RDQS (and eventually RDQ) values + * to achieve maximum READ margins. The algorithm will first determine the + * X coordinate (RDQS setting). This is done by collapsing the VREF eye + * until we find a minimum required RDQS eye for VREF_MIN and VREF_MAX. + * Then we take the averages of the RDQS eye at VREF_MIN and VREF_MAX, + * then average those; this will be the final X coordinate. The algorithm + * will then determine the Y coordinate (VREF setting). This is done by + * collapsing the RDQS eye until we find a minimum required VREF eye for + * RDQS_MIN and RDQS_MAX. Then we take the averages of the VREF eye at + * RDQS_MIN and RDQS_MAX, then average those; this will be the final Y + * coordinate. + * + * NOTE: this algorithm assumes the eye curves have a one-to-one relationship, + * meaning for each X the curve has only one Y and vice-a-versa. + */ +void rd_train(struct mrc_params *mrc_params) +{ + uint8_t ch; /* channel counter */ + uint8_t rk; /* rank counter */ + uint8_t bl; /* byte lane counter */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; +#ifdef BACKUP_RDQS +#else + uint8_t side_x; /* tracks LEFT/RIGHT approach vectors */ + uint8_t side_y; /* tracks BOTTOM/TOP approach vectors */ + /* X coordinate data (passing RDQS values) for approach vectors */ + uint8_t x_coordinate[2][2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + /* Y coordinate data (passing VREF values) for approach vectors */ + uint8_t y_coordinate[2][2][NUM_CHANNELS][NUM_BYTE_LANES]; + /* centered X (RDQS) */ + uint8_t x_center[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + /* centered Y (VREF) */ + uint8_t y_center[NUM_CHANNELS][NUM_BYTE_LANES]; + uint32_t address; /* target address for check_bls_ex() */ + uint32_t result; /* result of check_bls_ex() */ + uint32_t bl_mask; /* byte lane mask for result checking */ +#ifdef R2R_SHARING + /* used to find placement for rank2rank sharing configs */ + uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; + /* used to find placement for rank2rank sharing configs */ + uint32_t num_ranks_enabled = 0; +#endif +#endif + + /* rd_train starts */ + mrc_post_code(0x07, 0x00); + + ENTERFN(); + +#ifdef BACKUP_RDQS + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + set_rdqs(ch, rk, bl, ddr_rdqs[PLATFORM_ID]); + } + } + } + } + } +#else + /* initialize x/y_coordinate arrays */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + /* x_coordinate */ + x_coordinate[L][B][ch][rk][bl] = RDQS_MIN; + x_coordinate[R][B][ch][rk][bl] = RDQS_MAX; + x_coordinate[L][T][ch][rk][bl] = RDQS_MIN; + x_coordinate[R][T][ch][rk][bl] = RDQS_MAX; + /* y_coordinate */ + y_coordinate[L][B][ch][bl] = VREF_MIN; + y_coordinate[R][B][ch][bl] = VREF_MIN; + y_coordinate[L][T][ch][bl] = VREF_MAX; + y_coordinate[R][T][ch][bl] = VREF_MAX; + } + } + } + } + } + + /* initialize other variables */ + bl_mask = byte_lane_mask(mrc_params); + address = get_addr(0, 0); + +#ifdef R2R_SHARING + /* need to set "final_delay[][]" elements to "0" */ + memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay)); +#endif + + /* look for passing coordinates */ + for (side_y = B; side_y <= T; side_y++) { + for (side_x = L; side_x <= R; side_x++) { + mrc_post_code(0x07, (0x10 + (side_y * 2) + (side_x))); + + /* find passing values */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (0x1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & + (0x1 << rk)) { + /* set x/y_coordinate search starting settings */ + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + set_rdqs(ch, rk, bl, + x_coordinate[side_x][side_y][ch][rk][bl]); + set_vref(ch, bl, + y_coordinate[side_x][side_y][ch][bl]); + } + + /* get an address in the target channel/rank */ + address = get_addr(ch, rk); + + /* request HTE reconfiguration */ + mrc_params->hte_setup = 1; + + /* test the settings */ + do { + /* result[07:00] == failing byte lane (MAX 8) */ + result = check_bls_ex(mrc_params, address); + + /* check for failures */ + if (result & 0xFF) { + /* at least 1 byte lane failed */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (result & + (bl_mask << bl)) { + /* adjust the RDQS values accordingly */ + if (side_x == L) + x_coordinate[L][side_y][ch][rk][bl] += RDQS_STEP; + else + x_coordinate[R][side_y][ch][rk][bl] -= RDQS_STEP; + + /* check that we haven't closed the RDQS_EYE too much */ + if ((x_coordinate[L][side_y][ch][rk][bl] > (RDQS_MAX - MIN_RDQS_EYE)) || + (x_coordinate[R][side_y][ch][rk][bl] < (RDQS_MIN + MIN_RDQS_EYE)) || + (x_coordinate[L][side_y][ch][rk][bl] == + x_coordinate[R][side_y][ch][rk][bl])) { + /* + * not enough RDQS margin available at this VREF + * update VREF values accordingly + */ + if (side_y == B) + y_coordinate[side_x][B][ch][bl] += VREF_STEP; + else + y_coordinate[side_x][T][ch][bl] -= VREF_STEP; + + /* check that we haven't closed the VREF_EYE too much */ + if ((y_coordinate[side_x][B][ch][bl] > (VREF_MAX - MIN_VREF_EYE)) || + (y_coordinate[side_x][T][ch][bl] < (VREF_MIN + MIN_VREF_EYE)) || + (y_coordinate[side_x][B][ch][bl] == y_coordinate[side_x][T][ch][bl])) { + /* VREF_EYE collapsed below MIN_VREF_EYE */ + training_message(ch, rk, bl); + mrc_post_code(0xEE, (0x70 + (side_y * 2) + (side_x))); + } else { + /* update the VREF setting */ + set_vref(ch, bl, y_coordinate[side_x][side_y][ch][bl]); + /* reset the X coordinate to begin the search at the new VREF */ + x_coordinate[side_x][side_y][ch][rk][bl] = + (side_x == L) ? (RDQS_MIN) : (RDQS_MAX); + } + } + + /* update the RDQS setting */ + set_rdqs(ch, rk, bl, x_coordinate[side_x][side_y][ch][rk][bl]); + } + } + } + } while (result & 0xFF); + } + } + } + } + } + } + + mrc_post_code(0x07, 0x20); + + /* find final RDQS (X coordinate) & final VREF (Y coordinate) */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + uint32_t temp1; + uint32_t temp2; + + /* x_coordinate */ + DPF(D_INFO, + "RDQS T/B eye rank%d lane%d : %d-%d %d-%d\n", + rk, bl, + x_coordinate[L][T][ch][rk][bl], + x_coordinate[R][T][ch][rk][bl], + x_coordinate[L][B][ch][rk][bl], + x_coordinate[R][B][ch][rk][bl]); + + /* average the TOP side LEFT & RIGHT values */ + temp1 = (x_coordinate[R][T][ch][rk][bl] + x_coordinate[L][T][ch][rk][bl]) / 2; + /* average the BOTTOM side LEFT & RIGHT values */ + temp2 = (x_coordinate[R][B][ch][rk][bl] + x_coordinate[L][B][ch][rk][bl]) / 2; + /* average the above averages */ + x_center[ch][rk][bl] = (uint8_t) ((temp1 + temp2) / 2); + + /* y_coordinate */ + DPF(D_INFO, + "VREF R/L eye lane%d : %d-%d %d-%d\n", + bl, + y_coordinate[R][B][ch][bl], + y_coordinate[R][T][ch][bl], + y_coordinate[L][B][ch][bl], + y_coordinate[L][T][ch][bl]); + + /* average the RIGHT side TOP & BOTTOM values */ + temp1 = (y_coordinate[R][T][ch][bl] + y_coordinate[R][B][ch][bl]) / 2; + /* average the LEFT side TOP & BOTTOM values */ + temp2 = (y_coordinate[L][T][ch][bl] + y_coordinate[L][B][ch][bl]) / 2; + /* average the above averages */ + y_center[ch][bl] = (uint8_t) ((temp1 + temp2) / 2); + } + } + } + } + } + +#ifdef RX_EYE_CHECK + /* perform an eye check */ + for (side_y = B; side_y <= T; side_y++) { + for (side_x = L; side_x <= R; side_x++) { + mrc_post_code(0x07, (0x30 + (side_y * 2) + (side_x))); + + /* update the settings for the eye check */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (side_x == L) + set_rdqs(ch, rk, bl, (x_center[ch][rk][bl] - (MIN_RDQS_EYE / 2))); + else + set_rdqs(ch, rk, bl, (x_center[ch][rk][bl] + (MIN_RDQS_EYE / 2))); + + if (side_y == B) + set_vref(ch, bl, (y_center[ch][bl] - (MIN_VREF_EYE / 2))); + else + set_vref(ch, bl, (y_center[ch][bl] + (MIN_VREF_EYE / 2))); + } + } + } + } + } + + /* request HTE reconfiguration */ + mrc_params->hte_setup = 1; + + /* check the eye */ + if (check_bls_ex(mrc_params, address) & 0xFF) { + /* one or more byte lanes failed */ + mrc_post_code(0xEE, (0x74 + (side_x * 2) + (side_y))); + } + } + } +#endif + + mrc_post_code(0x07, 0x40); + + /* set final placements */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { +#ifdef R2R_SHARING + /* increment "num_ranks_enabled" */ + num_ranks_enabled++; +#endif + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + /* x_coordinate */ +#ifdef R2R_SHARING + final_delay[ch][bl] += x_center[ch][rk][bl]; + set_rdqs(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled)); +#else + set_rdqs(ch, rk, bl, x_center[ch][rk][bl]); +#endif + /* y_coordinate */ + set_vref(ch, bl, y_center[ch][bl]); + } + } + } + } + } +#endif + + LEAVEFN(); +} + +/* + * This function will perform the WRITE TRAINING Algorithm on all + * channels/ranks/byte_lanes simultaneously to minimize execution time. + * + * The idea here is to train the WDQ timings to achieve maximum WRITE margins. + * The algorithm will start with WDQ at the current WDQ setting (tracks WDQS + * in WR_LVL) +/- 32 PIs (+/- 1/4 CLK) and collapse the eye until all data + * patterns pass. This is because WDQS will be aligned to WCLK by the + * Write Leveling algorithm and WDQ will only ever have a 1/2 CLK window + * of validity. + */ +void wr_train(struct mrc_params *mrc_params) +{ + uint8_t ch; /* channel counter */ + uint8_t rk; /* rank counter */ + uint8_t bl; /* byte lane counter */ + uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1; +#ifdef BACKUP_WDQ +#else + uint8_t side; /* LEFT/RIGHT side indicator (0=L, 1=R) */ + uint32_t temp; /* temporary DWORD */ + /* 2 arrays, for L & R side passing delays */ + uint32_t delay[2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES]; + uint32_t address; /* target address for check_bls_ex() */ + uint32_t result; /* result of check_bls_ex() */ + uint32_t bl_mask; /* byte lane mask for result checking */ +#ifdef R2R_SHARING + /* used to find placement for rank2rank sharing configs */ + uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES]; + /* used to find placement for rank2rank sharing configs */ + uint32_t num_ranks_enabled = 0; +#endif +#endif + + /* wr_train starts */ + mrc_post_code(0x08, 0x00); + + ENTERFN(); + +#ifdef BACKUP_WDQ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + set_wdq(ch, rk, bl, ddr_wdq[PLATFORM_ID]); + } + } + } + } + } +#else + /* initialize "delay" */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + /* + * want to start with + * WDQ = (WDQS - QRTR_CLK) + * +/- QRTR_CLK + */ + temp = get_wdqs(ch, rk, bl) - QRTR_CLK; + delay[L][ch][rk][bl] = temp - QRTR_CLK; + delay[R][ch][rk][bl] = temp + QRTR_CLK; + } + } + } + } + } + + /* initialize other variables */ + bl_mask = byte_lane_mask(mrc_params); + address = get_addr(0, 0); + +#ifdef R2R_SHARING + /* need to set "final_delay[][]" elements to "0" */ + memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay)); +#endif + + /* + * start algorithm on the LEFT side and train each channel/bl + * until no failures are observed, then repeat for the RIGHT side. + */ + for (side = L; side <= R; side++) { + mrc_post_code(0x08, (0x10 + (side))); + + /* set starting values */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & + (1 << rk)) { + for (bl = 0; + bl < (NUM_BYTE_LANES / bl_divisor); + bl++) { + set_wdq(ch, rk, bl, delay[side][ch][rk][bl]); + } + } + } + } + } + + /* find passing values */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & + (1 << rk)) { + /* get an address in the target channel/rank */ + address = get_addr(ch, rk); + + /* request HTE reconfiguration */ + mrc_params->hte_setup = 1; + + /* check the settings */ + do { + /* result[07:00] == failing byte lane (MAX 8) */ + result = check_bls_ex(mrc_params, address); + /* check for failures */ + if (result & 0xFF) { + /* at least 1 byte lane failed */ + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + if (result & + (bl_mask << bl)) { + if (side == L) + delay[L][ch][rk][bl] += WDQ_STEP; + else + delay[R][ch][rk][bl] -= WDQ_STEP; + + /* check for algorithm failure */ + if (delay[L][ch][rk][bl] != delay[R][ch][rk][bl]) { + /* + * margin available + * update delay setting + */ + set_wdq(ch, rk, bl, + delay[side][ch][rk][bl]); + } else { + /* + * no margin available + * notify the user and halt + */ + training_message(ch, rk, bl); + mrc_post_code(0xEE, (0x80 + side)); + } + } + } + } + /* stop when all byte lanes pass */ + } while (result & 0xFF); + } + } + } + } + } + + /* program WDQ to the middle of passing window */ + for (ch = 0; ch < NUM_CHANNELS; ch++) { + if (mrc_params->channel_enables & (1 << ch)) { + for (rk = 0; rk < NUM_RANKS; rk++) { + if (mrc_params->rank_enables & (1 << rk)) { +#ifdef R2R_SHARING + /* increment "num_ranks_enabled" */ + num_ranks_enabled++; +#endif + for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) { + DPF(D_INFO, + "WDQ eye rank%d lane%d : %d-%d\n", + rk, bl, + delay[L][ch][rk][bl], + delay[R][ch][rk][bl]); + + temp = (delay[R][ch][rk][bl] + delay[L][ch][rk][bl]) / 2; + +#ifdef R2R_SHARING + final_delay[ch][bl] += temp; + set_wdq(ch, rk, bl, + ((final_delay[ch][bl]) / num_ranks_enabled)); +#else + set_wdq(ch, rk, bl, temp); +#endif + } + } + } + } + } +#endif + + LEAVEFN(); +} + +/* + * This function will store relevant timing data + * + * This data will be used on subsequent boots to speed up boot times + * and is required for Suspend To RAM capabilities. + */ +void store_timings(struct mrc_params *mrc_params) +{ + uint8_t ch, rk, bl; + struct mrc_timings *mt = &mrc_params->timings; + + for (ch = 0; ch < NUM_CHANNELS; ch++) { + for (rk = 0; rk < NUM_RANKS; rk++) { + for (bl = 0; bl < NUM_BYTE_LANES; bl++) { + mt->rcvn[ch][rk][bl] = get_rcvn(ch, rk, bl); + mt->rdqs[ch][rk][bl] = get_rdqs(ch, rk, bl); + mt->wdqs[ch][rk][bl] = get_wdqs(ch, rk, bl); + mt->wdq[ch][rk][bl] = get_wdq(ch, rk, bl); + + if (rk == 0) + mt->vref[ch][bl] = get_vref(ch, bl); + } + + mt->wctl[ch][rk] = get_wctl(ch, rk); + } + + mt->wcmd[ch] = get_wcmd(ch); + } + + /* need to save for a case of changing frequency after warm reset */ + mt->ddr_speed = mrc_params->ddr_speed; +} + +/* + * The purpose of this function is to ensure the SEC comes out of reset + * and IA initiates the SEC enabling Memory Scrambling. + */ +void enable_scrambling(struct mrc_params *mrc_params) +{ + uint32_t lfsr = 0; + uint8_t i; + + if (mrc_params->scrambling_enables == 0) + return; + + ENTERFN(); + + /* 32 bit seed is always stored in BIOS NVM */ + lfsr = mrc_params->timings.scrambler_seed; + + if (mrc_params->boot_mode == BM_COLD) { + /* + * factory value is 0 and in first boot, + * a clock based seed is loaded. + */ + if (lfsr == 0) { + /* + * get seed from system clock + * and make sure it is not all 1's + */ + lfsr = rdtsc() & 0x0FFFFFFF; + } else { + /* + * Need to replace scrambler + * + * get next 32bit LFSR 16 times which is the last + * part of the previous scrambler vector + */ + for (i = 0; i < 16; i++) + lfsr32(&lfsr); + } + + /* save new seed */ + mrc_params->timings.scrambler_seed = lfsr; + } + + /* + * In warm boot or S3 exit, we have the previous seed. + * In cold boot, we have the last 32bit LFSR which is the new seed. + */ + lfsr32(&lfsr); /* shift to next value */ + msg_port_write(MEM_CTLR, SCRMSEED, (lfsr & 0x0003FFFF)); + + for (i = 0; i < 2; i++) + msg_port_write(MEM_CTLR, SCRMLO + i, (lfsr & 0xAAAAAAAA)); + + LEAVEFN(); +} + +/* + * Configure MCU Power Management Control Register + * and Scheduler Control Register + */ +void prog_ddr_control(struct mrc_params *mrc_params) +{ + u32 dsch; + u32 dpmc0; + + ENTERFN(); + + dsch = msg_port_read(MEM_CTLR, DSCH); + dsch &= ~(BIT8 | BIT9 | BIT12); + msg_port_write(MEM_CTLR, DSCH, dsch); + + dpmc0 = msg_port_read(MEM_CTLR, DPMC0); + dpmc0 &= ~BIT25; + dpmc0 |= (mrc_params->power_down_disable << 25); + dpmc0 &= ~BIT24; + dpmc0 &= ~(BIT16 | BIT17 | BIT18); + dpmc0 |= (4 << 16); + dpmc0 |= BIT21; + msg_port_write(MEM_CTLR, DPMC0, dpmc0); + + /* CMDTRIST = 2h - CMD/ADDR are tristated when no valid command */ + mrc_write_mask(MEM_CTLR, DPMC1, 2 << 4, BIT4 | BIT5); + + LEAVEFN(); +} + +/* + * After training complete configure MCU Rank Population Register + * specifying: ranks enabled, device width, density, address mode + */ +void prog_dra_drb(struct mrc_params *mrc_params) +{ + u32 drp; + u32 dco; + u8 density = mrc_params->params.density; + + ENTERFN(); + + dco = msg_port_read(MEM_CTLR, DCO); + dco &= ~BIT31; + msg_port_write(MEM_CTLR, DCO, dco); + + drp = 0; + if (mrc_params->rank_enables & 1) + drp |= BIT0; + if (mrc_params->rank_enables & 2) + drp |= BIT1; + if (mrc_params->dram_width == X16) { + drp |= (1 << 4); + drp |= (1 << 9); + } + + /* + * Density encoding in struct dram_params: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb + * has to be mapped RANKDENSx encoding (0=1Gb) + */ + if (density == 0) + density = 4; + + drp |= ((density - 1) << 6); + drp |= ((density - 1) << 11); + + /* Address mode can be overwritten if ECC enabled */ + drp |= (mrc_params->address_mode << 14); + + msg_port_write(MEM_CTLR, DRP, drp); + + dco &= ~BIT28; + dco |= BIT31; + msg_port_write(MEM_CTLR, DCO, dco); + + LEAVEFN(); +} + +/* Send DRAM wake command */ +void perform_wake(struct mrc_params *mrc_params) +{ + ENTERFN(); + + dram_wake_command(); + + LEAVEFN(); +} + +/* + * Configure refresh rate and short ZQ calibration interval + * Activate dynamic self refresh + */ +void change_refresh_period(struct mrc_params *mrc_params) +{ + u32 drfc; + u32 dcal; + u32 dpmc0; + + ENTERFN(); + + drfc = msg_port_read(MEM_CTLR, DRFC); + drfc &= ~(BIT12 | BIT13 | BIT14); + drfc |= (mrc_params->refresh_rate << 12); + drfc |= BIT21; + msg_port_write(MEM_CTLR, DRFC, drfc); + + dcal = msg_port_read(MEM_CTLR, DCAL); + dcal &= ~(BIT8 | BIT9 | BIT10); + dcal |= (3 << 8); /* 63ms */ + msg_port_write(MEM_CTLR, DCAL, dcal); + + dpmc0 = msg_port_read(MEM_CTLR, DPMC0); + dpmc0 |= (BIT23 | BIT29); + msg_port_write(MEM_CTLR, DPMC0, dpmc0); + + LEAVEFN(); +} + +/* + * Configure DDRPHY for Auto-Refresh, Periodic Compensations, + * Dynamic Diff-Amp, ZQSPERIOD, Auto-Precharge, CKE Power-Down + */ +void set_auto_refresh(struct mrc_params *mrc_params) +{ + uint32_t channel; + uint32_t rank; + uint32_t bl; + uint32_t bl_divisor = 1; + uint32_t temp; + + ENTERFN(); + + /* + * Enable Auto-Refresh, Periodic Compensations, Dynamic Diff-Amp, + * ZQSPERIOD, Auto-Precharge, CKE Power-Down + */ + for (channel = 0; channel < NUM_CHANNELS; channel++) { + if (mrc_params->channel_enables & (1 << channel)) { + /* Enable Periodic RCOMPS */ + mrc_alt_write_mask(DDRPHY, CMPCTRL, BIT1, BIT1); + + /* Enable Dynamic DiffAmp & Set Read ODT Value */ + switch (mrc_params->rd_odt_value) { + case 0: + temp = 0x3F; /* OFF */ + break; + default: + temp = 0x00; /* Auto */ + break; + } + + for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) { + /* Override: DIFFAMP, ODT */ + mrc_alt_write_mask(DDRPHY, + (B0OVRCTL + (bl * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)), + (0x00 << 16) | (temp << 10), + (BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16 | BIT15 | BIT14 | + BIT13 | BIT12 | BIT11 | BIT10)); + + /* Override: DIFFAMP, ODT */ + mrc_alt_write_mask(DDRPHY, + (B1OVRCTL + (bl * DDRIODQ_BL_OFFSET) + + (channel * DDRIODQ_CH_OFFSET)), + (0x00 << 16) | (temp << 10), + (BIT21 | BIT20 | BIT19 | BIT18 | + BIT17 | BIT16 | BIT15 | BIT14 | + BIT13 | BIT12 | BIT11 | BIT10)); + } + + /* Issue ZQCS command */ + for (rank = 0; rank < NUM_RANKS; rank++) { + if (mrc_params->rank_enables & (1 << rank)) + dram_init_command(DCMD_ZQCS(rank)); + } + } + } + + clear_pointers(); + + LEAVEFN(); +} + +/* + * Depending on configuration enables ECC support + * + * Available memory size is decreased, and updated with 0s + * in order to clear error status. Address mode 2 forced. + */ +void ecc_enable(struct mrc_params *mrc_params) +{ + u32 drp; + u32 dsch; + u32 ecc_ctrl; + + if (mrc_params->ecc_enables == 0) + return; + + ENTERFN(); + + /* Configuration required in ECC mode */ + drp = msg_port_read(MEM_CTLR, DRP); + drp &= ~(BIT14 | BIT15); + drp |= BIT15; + drp |= BIT13; + msg_port_write(MEM_CTLR, DRP, drp); + + /* Disable new request bypass */ + dsch = msg_port_read(MEM_CTLR, DSCH); + dsch |= BIT12; + msg_port_write(MEM_CTLR, DSCH, dsch); + + /* Enable ECC */ + ecc_ctrl = (BIT0 | BIT1 | BIT17); + msg_port_write(MEM_CTLR, DECCCTRL, ecc_ctrl); + + /* Assume 8 bank memory, one bank is gone for ECC */ + mrc_params->mem_size -= mrc_params->mem_size / 8; + + /* For S3 resume memory content has to be preserved */ + if (mrc_params->boot_mode != BM_S3) { + select_hte(); + hte_mem_init(mrc_params, MRC_MEM_INIT); + select_mem_mgr(); + } + + LEAVEFN(); +} + +/* + * Execute memory test + * if error detected it is indicated in mrc_params->status + */ +void memory_test(struct mrc_params *mrc_params) +{ + uint32_t result = 0; + + ENTERFN(); + + select_hte(); + result = hte_mem_init(mrc_params, MRC_MEM_TEST); + select_mem_mgr(); + + DPF(D_INFO, "Memory test result %x\n", result); + mrc_params->status = ((result == 0) ? MRC_SUCCESS : MRC_E_MEMTEST); + LEAVEFN(); +} + +/* Lock MCU registers at the end of initialization sequence */ +void lock_registers(struct mrc_params *mrc_params) +{ + u32 dco; + + ENTERFN(); + + dco = msg_port_read(MEM_CTLR, DCO); + dco &= ~(BIT28 | BIT29); + dco |= (BIT0 | BIT8); + msg_port_write(MEM_CTLR, DCO, dco); + + LEAVEFN(); +} diff --git a/arch/x86/cpu/quark/smc.h b/arch/x86/cpu/quark/smc.h new file mode 100644 index 0000000000..46017a1ccb --- /dev/null +++ b/arch/x86/cpu/quark/smc.h @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2015, Bin Meng + * + * Ported from Intel released Quark UEFI BIOS + * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei + * + * SPDX-License-Identifier: Intel + */ + +#ifndef _SMC_H_ +#define _SMC_H_ + +/* System Memory Controller Register Defines */ + +/* Memory Controller Message Bus Registers Offsets */ +#define DRP 0x00 +#define DTR0 0x01 +#define DTR1 0x02 +#define DTR2 0x03 +#define DTR3 0x04 +#define DTR4 0x05 +#define DPMC0 0x06 +#define DPMC1 0x07 +#define DRFC 0x08 +#define DSCH 0x09 +#define DCAL 0x0A +#define DRMC 0x0B +#define PMSTS 0x0C +#define DCO 0x0F +#define DSTAT 0x20 +#define SSKPD0 0x4A +#define SSKPD1 0x4B +#define DECCCTRL 0x60 +#define DECCSTAT 0x61 +#define DECCSBECNT 0x62 +#define DECCSBECA 0x68 +#define DECCSBECS 0x69 +#define DECCDBECA 0x6A +#define DECCDBECS 0x6B +#define DFUSESTAT 0x70 +#define SCRMSEED 0x80 +#define SCRMLO 0x81 +#define SCRMHI 0x82 + +/* DRAM init command */ +#define DCMD_MRS1(rnk, dat) (0 | ((rnk) << 22) | (1 << 3) | ((dat) << 6)) +#define DCMD_REF(rnk) (1 | ((rnk) << 22)) +#define DCMD_PRE(rnk) (2 | ((rnk) << 22)) +#define DCMD_PREA(rnk) (2 | ((rnk) << 22) | (BIT10 << 6)) +#define DCMD_ACT(rnk, row) (3 | ((rnk) << 22) | ((row) << 6)) +#define DCMD_WR(rnk, col) (4 | ((rnk) << 22) | ((col) << 6)) +#define DCMD_RD(rnk, col) (5 | ((rnk) << 22) | ((col) << 6)) +#define DCMD_ZQCS(rnk) (6 | ((rnk) << 22)) +#define DCMD_ZQCL(rnk) (6 | ((rnk) << 22) | (BIT10 << 6)) +#define DCMD_NOP(rnk) (7 | ((rnk) << 22)) + +#define DDR3_EMRS1_DIC_40 (0) +#define DDR3_EMRS1_DIC_34 (1) + +#define DDR3_EMRS1_RTTNOM_0 (0) +#define DDR3_EMRS1_RTTNOM_60 (0x04) +#define DDR3_EMRS1_RTTNOM_120 (0x40) +#define DDR3_EMRS1_RTTNOM_40 (0x44) +#define DDR3_EMRS1_RTTNOM_20 (0x200) +#define DDR3_EMRS1_RTTNOM_30 (0x204) + +#define DDR3_EMRS2_RTTWR_60 (1 << 9) +#define DDR3_EMRS2_RTTWR_120 (1 << 10) + +/* BEGIN DDRIO Registers */ + +/* DDR IOs & COMPs */ +#define DDRIODQ_BL_OFFSET 0x0800 +#define DDRIODQ_CH_OFFSET ((NUM_BYTE_LANES / 2) * DDRIODQ_BL_OFFSET) +#define DDRIOCCC_CH_OFFSET 0x0800 +#define DDRCOMP_CH_OFFSET 0x0100 + +/* CH0-BL01-DQ */ +#define DQOBSCKEBBCTL 0x0000 +#define DQDLLTXCTL 0x0004 +#define DQDLLRXCTL 0x0008 +#define DQMDLLCTL 0x000C +#define B0RXIOBUFCTL 0x0010 +#define B0VREFCTL 0x0014 +#define B0RXOFFSET1 0x0018 +#define B0RXOFFSET0 0x001C +#define B1RXIOBUFCTL 0x0020 +#define B1VREFCTL 0x0024 +#define B1RXOFFSET1 0x0028 +#define B1RXOFFSET0 0x002C +#define DQDFTCTL 0x0030 +#define DQTRAINSTS 0x0034 +#define B1DLLPICODER0 0x0038 +#define B0DLLPICODER0 0x003C +#define B1DLLPICODER1 0x0040 +#define B0DLLPICODER1 0x0044 +#define B1DLLPICODER2 0x0048 +#define B0DLLPICODER2 0x004C +#define B1DLLPICODER3 0x0050 +#define B0DLLPICODER3 0x0054 +#define B1RXDQSPICODE 0x0058 +#define B0RXDQSPICODE 0x005C +#define B1RXDQPICODER32 0x0060 +#define B1RXDQPICODER10 0x0064 +#define B0RXDQPICODER32 0x0068 +#define B0RXDQPICODER10 0x006C +#define B01PTRCTL0 0x0070 +#define B01PTRCTL1 0x0074 +#define B01DBCTL0 0x0078 +#define B01DBCTL1 0x007C +#define B0LATCTL0 0x0080 +#define B1LATCTL0 0x0084 +#define B01LATCTL1 0x0088 +#define B0ONDURCTL 0x008C +#define B1ONDURCTL 0x0090 +#define B0OVRCTL 0x0094 +#define B1OVRCTL 0x0098 +#define DQCTL 0x009C +#define B0RK2RKCHGPTRCTRL 0x00A0 +#define B1RK2RKCHGPTRCTRL 0x00A4 +#define DQRK2RKCTL 0x00A8 +#define DQRK2RKPTRCTL 0x00AC +#define B0RK2RKLAT 0x00B0 +#define B1RK2RKLAT 0x00B4 +#define DQCLKALIGNREG0 0x00B8 +#define DQCLKALIGNREG1 0x00BC +#define DQCLKALIGNREG2 0x00C0 +#define DQCLKALIGNSTS0 0x00C4 +#define DQCLKALIGNSTS1 0x00C8 +#define DQCLKGATE 0x00CC +#define B0COMPSLV1 0x00D0 +#define B1COMPSLV1 0x00D4 +#define B0COMPSLV2 0x00D8 +#define B1COMPSLV2 0x00DC +#define B0COMPSLV3 0x00E0 +#define B1COMPSLV3 0x00E4 +#define DQVISALANECR0TOP 0x00E8 +#define DQVISALANECR1TOP 0x00EC +#define DQVISACONTROLCRTOP 0x00F0 +#define DQVISALANECR0BL 0x00F4 +#define DQVISALANECR1BL 0x00F8 +#define DQVISACONTROLCRBL 0x00FC +#define DQTIMINGCTRL 0x010C + +/* CH0-ECC */ +#define ECCDLLTXCTL 0x2004 +#define ECCDLLRXCTL 0x2008 +#define ECCMDLLCTL 0x200C +#define ECCB1DLLPICODER0 0x2038 +#define ECCB1DLLPICODER1 0x2040 +#define ECCB1DLLPICODER2 0x2048 +#define ECCB1DLLPICODER3 0x2050 +#define ECCB01DBCTL0 0x2078 +#define ECCB01DBCTL1 0x207C +#define ECCCLKALIGNREG0 0x20B8 +#define ECCCLKALIGNREG1 0x20BC +#define ECCCLKALIGNREG2 0x20C0 + +/* CH0-CMD */ +#define CMDOBSCKEBBCTL 0x4800 +#define CMDDLLTXCTL 0x4808 +#define CMDDLLRXCTL 0x480C +#define CMDMDLLCTL 0x4810 +#define CMDRCOMPODT 0x4814 +#define CMDDLLPICODER0 0x4820 +#define CMDDLLPICODER1 0x4824 +#define CMDCFGREG0 0x4840 +#define CMDPTRREG 0x4844 +#define CMDCLKALIGNREG0 0x4850 +#define CMDCLKALIGNREG1 0x4854 +#define CMDCLKALIGNREG2 0x4858 +#define CMDPMCONFIG0 0x485C +#define CMDPMDLYREG0 0x4860 +#define CMDPMDLYREG1 0x4864 +#define CMDPMDLYREG2 0x4868 +#define CMDPMDLYREG3 0x486C +#define CMDPMDLYREG4 0x4870 +#define CMDCLKALIGNSTS0 0x4874 +#define CMDCLKALIGNSTS1 0x4878 +#define CMDPMSTS0 0x487C +#define CMDPMSTS1 0x4880 +#define CMDCOMPSLV 0x4884 +#define CMDBONUS0 0x488C +#define CMDBONUS1 0x4890 +#define CMDVISALANECR0 0x4894 +#define CMDVISALANECR1 0x4898 +#define CMDVISACONTROLCR 0x489C +#define CMDCLKGATE 0x48A0 +#define CMDTIMINGCTRL 0x48A4 + +/* CH0-CLK-CTL */ +#define CCOBSCKEBBCTL 0x5800 +#define CCRCOMPIO 0x5804 +#define CCDLLTXCTL 0x5808 +#define CCDLLRXCTL 0x580C +#define CCMDLLCTL 0x5810 +#define CCRCOMPODT 0x5814 +#define CCDLLPICODER0 0x5820 +#define CCDLLPICODER1 0x5824 +#define CCDDR3RESETCTL 0x5830 +#define CCCFGREG0 0x5838 +#define CCCFGREG1 0x5840 +#define CCPTRREG 0x5844 +#define CCCLKALIGNREG0 0x5850 +#define CCCLKALIGNREG1 0x5854 +#define CCCLKALIGNREG2 0x5858 +#define CCPMCONFIG0 0x585C +#define CCPMDLYREG0 0x5860 +#define CCPMDLYREG1 0x5864 +#define CCPMDLYREG2 0x5868 +#define CCPMDLYREG3 0x586C +#define CCPMDLYREG4 0x5870 +#define CCCLKALIGNSTS0 0x5874 +#define CCCLKALIGNSTS1 0x5878 +#define CCPMSTS0 0x587C +#define CCPMSTS1 0x5880 +#define CCCOMPSLV1 0x5884 +#define CCCOMPSLV2 0x5888 +#define CCCOMPSLV3 0x588C +#define CCBONUS0 0x5894 +#define CCBONUS1 0x5898 +#define CCVISALANECR0 0x589C +#define CCVISALANECR1 0x58A0 +#define CCVISACONTROLCR 0x58A4 +#define CCCLKGATE 0x58A8 +#define CCTIMINGCTL 0x58AC + +/* COMP */ +#define CMPCTRL 0x6800 +#define SOFTRSTCNTL 0x6804 +#define MSCNTR 0x6808 +#define NMSCNTRL 0x680C +#define LATCH1CTL 0x6814 +#define COMPVISALANECR0 0x681C +#define COMPVISALANECR1 0x6820 +#define COMPVISACONTROLCR 0x6824 +#define COMPBONUS0 0x6830 +#define TCOCNTCTRL 0x683C +#define DQANAODTPUCTL 0x6840 +#define DQANAODTPDCTL 0x6844 +#define DQANADRVPUCTL 0x6848 +#define DQANADRVPDCTL 0x684C +#define DQANADLYPUCTL 0x6850 +#define DQANADLYPDCTL 0x6854 +#define DQANATCOPUCTL 0x6858 +#define DQANATCOPDCTL 0x685C +#define CMDANADRVPUCTL 0x6868 +#define CMDANADRVPDCTL 0x686C +#define CMDANADLYPUCTL 0x6870 +#define CMDANADLYPDCTL 0x6874 +#define CLKANAODTPUCTL 0x6880 +#define CLKANAODTPDCTL 0x6884 +#define CLKANADRVPUCTL 0x6888 +#define CLKANADRVPDCTL 0x688C +#define CLKANADLYPUCTL 0x6890 +#define CLKANADLYPDCTL 0x6894 +#define CLKANATCOPUCTL 0x6898 +#define CLKANATCOPDCTL 0x689C +#define DQSANAODTPUCTL 0x68A0 +#define DQSANAODTPDCTL 0x68A4 +#define DQSANADRVPUCTL 0x68A8 +#define DQSANADRVPDCTL 0x68AC +#define DQSANADLYPUCTL 0x68B0 +#define DQSANADLYPDCTL 0x68B4 +#define DQSANATCOPUCTL 0x68B8 +#define DQSANATCOPDCTL 0x68BC +#define CTLANADRVPUCTL 0x68C8 +#define CTLANADRVPDCTL 0x68CC +#define CTLANADLYPUCTL 0x68D0 +#define CTLANADLYPDCTL 0x68D4 +#define CHNLBUFSTATIC 0x68F0 +#define COMPOBSCNTRL 0x68F4 +#define COMPBUFFDBG0 0x68F8 +#define COMPBUFFDBG1 0x68FC +#define CFGMISCCH0 0x6900 +#define COMPEN0CH0 0x6904 +#define COMPEN1CH0 0x6908 +#define COMPEN2CH0 0x690C +#define STATLEGEN0CH0 0x6910 +#define STATLEGEN1CH0 0x6914 +#define DQVREFCH0 0x6918 +#define CMDVREFCH0 0x691C +#define CLKVREFCH0 0x6920 +#define DQSVREFCH0 0x6924 +#define CTLVREFCH0 0x6928 +#define TCOVREFCH0 0x692C +#define DLYSELCH0 0x6930 +#define TCODRAMBUFODTCH0 0x6934 +#define CCBUFODTCH0 0x6938 +#define RXOFFSETCH0 0x693C +#define DQODTPUCTLCH0 0x6940 +#define DQODTPDCTLCH0 0x6944 +#define DQDRVPUCTLCH0 0x6948 +#define DQDRVPDCTLCH0 0x694C +#define DQDLYPUCTLCH0 0x6950 +#define DQDLYPDCTLCH0 0x6954 +#define DQTCOPUCTLCH0 0x6958 +#define DQTCOPDCTLCH0 0x695C +#define CMDDRVPUCTLCH0 0x6968 +#define CMDDRVPDCTLCH0 0x696C +#define CMDDLYPUCTLCH0 0x6970 +#define CMDDLYPDCTLCH0 0x6974 +#define CLKODTPUCTLCH0 0x6980 +#define CLKODTPDCTLCH0 0x6984 +#define CLKDRVPUCTLCH0 0x6988 +#define CLKDRVPDCTLCH0 0x698C +#define CLKDLYPUCTLCH0 0x6990 +#define CLKDLYPDCTLCH0 0x6994 +#define CLKTCOPUCTLCH0 0x6998 +#define CLKTCOPDCTLCH0 0x699C +#define DQSODTPUCTLCH0 0x69A0 +#define DQSODTPDCTLCH0 0x69A4 +#define DQSDRVPUCTLCH0 0x69A8 +#define DQSDRVPDCTLCH0 0x69AC +#define DQSDLYPUCTLCH0 0x69B0 +#define DQSDLYPDCTLCH0 0x69B4 +#define DQSTCOPUCTLCH0 0x69B8 +#define DQSTCOPDCTLCH0 0x69BC +#define CTLDRVPUCTLCH0 0x69C8 +#define CTLDRVPDCTLCH0 0x69CC +#define CTLDLYPUCTLCH0 0x69D0 +#define CTLDLYPDCTLCH0 0x69D4 +#define FNLUPDTCTLCH0 0x69F0 + +/* PLL */ +#define MPLLCTRL0 0x7800 +#define MPLLCTRL1 0x7808 +#define MPLLCSR0 0x7810 +#define MPLLCSR1 0x7814 +#define MPLLCSR2 0x7820 +#define MPLLDFT 0x7828 +#define MPLLMON0CTL 0x7830 +#define MPLLMON1CTL 0x7838 +#define MPLLMON2CTL 0x783C +#define SFRTRIM 0x7850 +#define MPLLDFTOUT0 0x7858 +#define MPLLDFTOUT1 0x785C +#define MASTERRSTN 0x7880 +#define PLLLOCKDEL 0x7884 +#define SFRDEL 0x7888 +#define CRUVISALANECR0 0x78F0 +#define CRUVISALANECR1 0x78F4 +#define CRUVISACONTROLCR 0x78F8 +#define IOSFVISALANECR0 0x78FC +#define IOSFVISALANECR1 0x7900 +#define IOSFVISACONTROLCR 0x7904 + +/* END DDRIO Registers */ + +/* DRAM Specific Message Bus OpCodes */ +#define MSG_OP_DRAM_INIT 0x68 +#define MSG_OP_DRAM_WAKE 0xCA + +#define SAMPLE_SIZE 6 + +/* must be less than this number to enable early deadband */ +#define EARLY_DB 0x12 +/* must be greater than this number to enable late deadband */ +#define LATE_DB 0x34 + +#define CHX_REGS (11 * 4) +#define FULL_CLK 128 +#define HALF_CLK 64 +#define QRTR_CLK 32 + +#define MCEIL(num, den) ((uint8_t)((num + den - 1) / den)) +#define MMAX(a, b) ((a) > (b) ? (a) : (b)) +#define DEAD_LOOP() for (;;); + +#define MIN_RDQS_EYE 10 /* in PI Codes */ +#define MIN_VREF_EYE 10 /* in VREF Codes */ +/* how many RDQS codes to jump while margining */ +#define RDQS_STEP 1 +/* how many VREF codes to jump while margining */ +#define VREF_STEP 1 +/* offset into "vref_codes[]" for minimum allowed VREF setting */ +#define VREF_MIN 0x00 +/* offset into "vref_codes[]" for maximum allowed VREF setting */ +#define VREF_MAX 0x3F +#define RDQS_MIN 0x00 /* minimum RDQS delay value */ +#define RDQS_MAX 0x3F /* maximum RDQS delay value */ + +/* how many WDQ codes to jump while margining */ +#define WDQ_STEP 1 + +enum { + B, /* BOTTOM VREF */ + T /* TOP VREF */ +}; + +enum { + L, /* LEFT RDQS */ + R /* RIGHT RDQS */ +}; + +/* Memory Options */ + +/* enable STATIC timing settings for RCVN (BACKUP_MODE) */ +#undef BACKUP_RCVN +/* enable STATIC timing settings for WDQS (BACKUP_MODE) */ +#undef BACKUP_WDQS +/* enable STATIC timing settings for RDQS (BACKUP_MODE) */ +#undef BACKUP_RDQS +/* enable STATIC timing settings for WDQ (BACKUP_MODE) */ +#undef BACKUP_WDQ +/* enable *COMP overrides (BACKUP_MODE) */ +#undef BACKUP_COMPS +/* enable the RD_TRAIN eye check */ +#undef RX_EYE_CHECK + +/* enable Host to Memory Clock Alignment */ +#define HMC_TEST +/* enable multi-rank support via rank2rank sharing */ +#define R2R_SHARING +/* disable signals not used in 16bit mode of DDRIO */ +#define FORCE_16BIT_DDRIO + +#define PLATFORM_ID 1 + +void clear_self_refresh(struct mrc_params *mrc_params); +void prog_ddr_timing_control(struct mrc_params *mrc_params); +void prog_decode_before_jedec(struct mrc_params *mrc_params); +void perform_ddr_reset(struct mrc_params *mrc_params); +void ddrphy_init(struct mrc_params *mrc_params); +void perform_jedec_init(struct mrc_params *mrc_params); +void set_ddr_init_complete(struct mrc_params *mrc_params); +void restore_timings(struct mrc_params *mrc_params); +void default_timings(struct mrc_params *mrc_params); +void rcvn_cal(struct mrc_params *mrc_params); +void wr_level(struct mrc_params *mrc_params); +void prog_page_ctrl(struct mrc_params *mrc_params); +void rd_train(struct mrc_params *mrc_params); +void wr_train(struct mrc_params *mrc_params); +void store_timings(struct mrc_params *mrc_params); +void enable_scrambling(struct mrc_params *mrc_params); +void prog_ddr_control(struct mrc_params *mrc_params); +void prog_dra_drb(struct mrc_params *mrc_params); +void perform_wake(struct mrc_params *mrc_params); +void change_refresh_period(struct mrc_params *mrc_params); +void set_auto_refresh(struct mrc_params *mrc_params); +void ecc_enable(struct mrc_params *mrc_params); +void memory_test(struct mrc_params *mrc_params); +void lock_registers(struct mrc_params *mrc_params); + +#endif /* _SMC_H_ */ -- cgit From 236b711e89b529758ab474660b936140dbab3842 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:25 +0800 Subject: x86: quark: Enable the Memory Reference Code build Turn on the Memory Reference code build in the quark Makefile. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile index 168c1e6c3a..e87b4248e6 100644 --- a/arch/x86/cpu/quark/Makefile +++ b/arch/x86/cpu/quark/Makefile @@ -5,4 +5,5 @@ # obj-y += car.o dram.o msg_port.o quark.o +obj-y += mrc.o mrc_util.o hte.o smc.o obj-$(CONFIG_PCI) += pci.o -- cgit From c89ada017fe24891818c08a9e4b7c5ae4a9224e5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:26 +0800 Subject: fdtdec: Add compatible id and string for Intel Quark MRC Add COMPAT_INTEL_QRK_MRC and "intel,quark-mrc" so that fdtdec can decode Intel Quark MRC node. Signed-off-by: Bin Meng Acked-by: Simon Glass --- include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/fdtdec.h b/include/fdtdec.h index 231eed7892..1bc70dba21 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -167,6 +167,7 @@ enum fdt_compat_id { COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */ COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */ COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */ + COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */ COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 5bf8f29b13..dd58bbb482 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -75,6 +75,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_GMA, "intel,gma"), COMPAT(AMS_AS3722, "ams,as3722"), COMPAT(INTEL_ICH_SPI, "intel,ich-spi"), + COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) -- cgit From b1420c813074d39cd2452d7bc45374561d1cf223 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:27 +0800 Subject: dt-bindings: Add Intel Quark MRC bindings Add standard dt-bindings macros to be used by Intel Quark MRC node. Signed-off-by: Bin Meng Acked-by: Simon Glass --- include/dt-bindings/mrc/quark.h | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 include/dt-bindings/mrc/quark.h diff --git a/include/dt-bindings/mrc/quark.h b/include/dt-bindings/mrc/quark.h new file mode 100644 index 0000000000..e3ca8a25a3 --- /dev/null +++ b/include/dt-bindings/mrc/quark.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Intel Quark MRC bindings include several properties + * as part of an Intel Quark MRC node. In most cases, + * the value of these properties uses the standard values + * defined in this header. + */ + +#ifndef _DT_BINDINGS_QRK_MRC_H_ +#define _DT_BINDINGS_QRK_MRC_H_ + +/* MRC platform data flags */ +#define MRC_FLAG_ECC_EN 0x00000001 +#define MRC_FLAG_SCRAMBLE_EN 0x00000002 +#define MRC_FLAG_MEMTEST_EN 0x00000004 +/* 0b DDR "fly-by" topology else 1b DDR "tree" topology */ +#define MRC_FLAG_TOP_TREE_EN 0x00000008 +/* If set ODR signal is asserted to DRAM devices on writes */ +#define MRC_FLAG_WR_ODT_EN 0x00000010 + +/* DRAM width */ +#define DRAM_WIDTH_X8 0 +#define DRAM_WIDTH_X16 1 +#define DRAM_WIDTH_X32 2 + +/* DRAM speed */ +#define DRAM_FREQ_800 0 +#define DRAM_FREQ_1066 1 + +/* DRAM type */ +#define DRAM_TYPE_DDR3 0 +#define DRAM_TYPE_DDR3L 1 + +/* DRAM rank mask */ +#define DRAM_RANK(n) (1 << (n)) + +/* DRAM channel mask */ +#define DRAM_CHANNEL(n) (1 << (n)) + +/* DRAM channel width */ +#define DRAM_CHANNEL_WIDTH_X8 0 +#define DRAM_CHANNEL_WIDTH_X16 1 +#define DRAM_CHANNEL_WIDTH_X32 2 + +/* DRAM address mode */ +#define DRAM_ADDR_MODE0 0 +#define DRAM_ADDR_MODE1 1 +#define DRAM_ADDR_MODE2 2 + +/* DRAM refresh rate */ +#define DRAM_REFRESH_RATE_195US 1 +#define DRAM_REFRESH_RATE_39US 2 +#define DRAM_REFRESH_RATE_785US 3 + +/* DRAM SR temprature range */ +#define DRAM_SRT_RANGE_NORMAL 0 +#define DRAM_SRT_RANGE_EXTENDED 1 + +/* DRAM ron value */ +#define DRAM_RON_34OHM 0 +#define DRAM_RON_40OHM 1 + +/* DRAM rtt nom value */ +#define DRAM_RTT_NOM_40OHM 0 +#define DRAM_RTT_NOM_60OHM 1 +#define DRAM_RTT_NOM_120OHM 2 + +/* DRAM rd odt value */ +#define DRAM_RD_ODT_OFF 0 +#define DRAM_RD_ODT_60OHM 1 +#define DRAM_RD_ODT_120OHM 2 +#define DRAM_RD_ODT_180OHM 3 + +/* DRAM density */ +#define DRAM_DENSITY_512M 0 +#define DRAM_DENSITY_1G 1 +#define DRAM_DENSITY_2G 2 +#define DRAM_DENSITY_4G 3 + +#endif /* _DT_BINDINGS_QRK_MRC_H_ */ -- cgit From 20c34115d603745cf276c683168292d02056791a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 5 Feb 2015 23:42:28 +0800 Subject: x86: quark: Call MRC in dram_init() Now that we have added Quark MRC codes, call MRC in dram_init() so that DRAM can be initialized on a Quark based board. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/dram.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++- arch/x86/dts/galileo.dts | 25 ++++++++++++ 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c index fbdc3cde05..9cac846c69 100644 --- a/arch/x86/cpu/quark/dram.c +++ b/arch/x86/cpu/quark/dram.c @@ -5,15 +5,110 @@ */ #include +#include +#include #include +#include #include DECLARE_GLOBAL_DATA_PTR; +static int mrc_configure_params(struct mrc_params *mrc_params) +{ + const void *blob = gd->fdt_blob; + int node; + int mrc_flags; + + node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_QRK_MRC); + if (node < 0) { + debug("%s: Cannot find MRC node\n", __func__); + return -EINVAL; + } + + /* + * TODO: + * + * We need support fast boot (MRC cache) in the future. + * + * Set boot mode to cold boot for now + */ + mrc_params->boot_mode = BM_COLD; + + /* + * TODO: + * + * We need determine ECC by pin strap state + * + * Disable ECC by default for now + */ + mrc_params->ecc_enables = 0; + + mrc_flags = fdtdec_get_int(blob, node, "flags", 0); + if (mrc_flags & MRC_FLAG_SCRAMBLE_EN) + mrc_params->scrambling_enables = 1; + else + mrc_params->scrambling_enables = 0; + + mrc_params->dram_width = fdtdec_get_int(blob, node, "dram-width", 0); + mrc_params->ddr_speed = fdtdec_get_int(blob, node, "dram-speed", 0); + mrc_params->ddr_type = fdtdec_get_int(blob, node, "dram-type", 0); + + mrc_params->rank_enables = fdtdec_get_int(blob, node, "rank-mask", 0); + mrc_params->channel_enables = fdtdec_get_int(blob, node, + "chan-mask", 0); + mrc_params->channel_width = fdtdec_get_int(blob, node, + "chan-width", 0); + mrc_params->address_mode = fdtdec_get_int(blob, node, "addr-mode", 0); + + mrc_params->refresh_rate = fdtdec_get_int(blob, node, + "refresh-rate", 0); + mrc_params->sr_temp_range = fdtdec_get_int(blob, node, + "sr-temp-range", 0); + mrc_params->ron_value = fdtdec_get_int(blob, node, + "ron-value", 0); + mrc_params->rtt_nom_value = fdtdec_get_int(blob, node, + "rtt-nom-value", 0); + mrc_params->rd_odt_value = fdtdec_get_int(blob, node, + "rd-odt-value", 0); + + mrc_params->params.density = fdtdec_get_int(blob, node, + "dram-density", 0); + mrc_params->params.cl = fdtdec_get_int(blob, node, "dram-cl", 0); + mrc_params->params.ras = fdtdec_get_int(blob, node, "dram-ras", 0); + mrc_params->params.wtr = fdtdec_get_int(blob, node, "dram-wtr", 0); + mrc_params->params.rrd = fdtdec_get_int(blob, node, "dram-rrd", 0); + mrc_params->params.faw = fdtdec_get_int(blob, node, "dram-faw", 0); + + debug("MRC dram_width %d\n", mrc_params->dram_width); + debug("MRC rank_enables %d\n", mrc_params->rank_enables); + debug("MRC ddr_speed %d\n", mrc_params->ddr_speed); + debug("MRC flags: %s\n", + (mrc_params->scrambling_enables) ? "SCRAMBLE_EN" : ""); + + debug("MRC density=%d tCL=%d tRAS=%d tWTR=%d tRRD=%d tFAW=%d\n", + mrc_params->params.density, mrc_params->params.cl, + mrc_params->params.ras, mrc_params->params.wtr, + mrc_params->params.rrd, mrc_params->params.faw); + + return 0; +} + int dram_init(void) { - /* hardcode the DRAM size for now */ - gd->ram_size = DRAM_MAX_SIZE; + struct mrc_params mrc_params; + int ret; + + memset(&mrc_params, 0, sizeof(struct mrc_params)); + ret = mrc_configure_params(&mrc_params); + if (ret) + return ret; + + /* Set up the DRAM by calling the memory reference code */ + mrc_init(&mrc_params); + if (mrc_params.status) + return -EIO; + + gd->ram_size = mrc_params.mem_size; post_code(POST_DRAM); return 0; diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index 14a19c3ec3..d462221a9d 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -6,6 +6,8 @@ /dts-v1/; +#include + /include/ "skeleton.dtsi" / { @@ -20,6 +22,29 @@ stdout-path = &pciuart0; }; + mrc { + compatible = "intel,quark-mrc"; + flags = ; + dram-width = ; + dram-speed = ; + dram-type = ; + rank-mask = ; + chan-mask = ; + chan-width = ; + addr-mode = ; + refresh-rate = ; + sr-temp-range = ; + ron-value = ; + rtt-nom-value = ; + rd-odt-value = ; + dram-density = ; + dram-cl = <6>; + dram-ras = <0x0000927c>; + dram-wtr = <0x00002710>; + dram-rrd = <0x00002710>; + dram-faw = <0x00009c40>; + }; + pci { #address-cells = <3>; #size-cells = <2>; -- cgit From b162257d4f175b59ebedd9c2db930d29317ffe16 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:09 +0800 Subject: x86: quark: Initialize non-standard BARs Quark SoC has some non-standard BARs (excluding PCI standard BARs) which need be initialized with suggested values. This includes GPIO, WDT, RCBA, PCIe ECAM and some ACPI register block base addresses. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/quark.c | 46 +++++++++++++++++++++++++++++++++ arch/x86/include/asm/arch-quark/quark.h | 32 +++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 47ba15253f..cf596e45e1 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -9,6 +9,46 @@ #include #include #include +#include +#include +#include + +static void quark_setup_bars(void) +{ + /* GPIO - D31:F0:R44h */ + pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA, + CONFIG_GPIO_BASE | IO_BAR_EN); + + /* ACPI PM1 Block - D31:F0:R48h */ + pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK, + CONFIG_ACPI_PM1_BASE | IO_BAR_EN); + + /* GPE0 - D31:F0:R4Ch */ + pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK, + CONFIG_ACPI_GPE0_BASE | IO_BAR_EN); + + /* WDT - D31:F0:R84h */ + pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA, + CONFIG_WDT_BASE | IO_BAR_EN); + + /* RCBA - D31:F0:RF0h */ + pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, + CONFIG_RCBA_BASE | MEM_BAR_EN); + + /* ACPI P Block - Msg Port 04:R70h */ + msg_port_write(MSG_PORT_RMU, PBLK_BA, + CONFIG_ACPI_PBLK_BASE | IO_BAR_EN); + + /* SPI DMA - Msg Port 04:R7Ah */ + msg_port_write(MSG_PORT_RMU, SPI_DMA_BA, + CONFIG_SPI_DMA_BASE | IO_BAR_EN); + + /* PCIe ECAM */ + msg_port_write(MSG_PORT_MEM_ARBITER, AEC_CTRL, + CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN); + msg_port_write(MSG_PORT_HOST_BRIDGE, HEC_REG, + CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN); +} int arch_cpu_init(void) { @@ -28,6 +68,12 @@ int arch_cpu_init(void) if (ret) return ret; + /* + * Quark SoC has some non-standard BARs (excluding PCI standard BARs) + * which need be initialized with suggested values + */ + quark_setup_bars(); + return 0; } diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h index ebbcf7755d..ceb583e3f0 100644 --- a/arch/x86/include/asm/arch-quark/quark.h +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -14,9 +14,29 @@ #define MSG_PORT_MEM_MGR 0x05 #define MSG_PORT_SOC_UNIT 0x31 +/* Port 0x00: Memory Arbiter Message Port Registers */ + +/* Enhanced Configuration Space */ +#define AEC_CTRL 0x00 + +/* Port 0x03: Host Bridge Message Port Registers */ + /* Host Memory I/O Boundary */ #define HM_BOUND 0x08 +/* Extended Configuration Space */ +#define HEC_REG 0x09 + +/* Port 0x04: Remote Management Unit Message Port Registers */ + +/* ACPI PBLK Base Address Register */ +#define PBLK_BA 0x70 + +/* SPI DMA Base Address Register */ +#define SPI_DMA_BA 0x7a + +/* Port 0x05: Memory Manager Message Port Registers */ + /* eSRAM Block Page Control */ #define ESRAM_BLK_CTRL 0x82 #define ESRAM_BLOCK_MODE 0x10000000 @@ -37,4 +57,16 @@ /* 64KiB of RMU binary in flash */ #define RMU_BINARY_SIZE 0x10000 +/* Legacy Bridge PCI Configuration Registers */ +#define LB_GBA 0x44 +#define LB_PM1BLK 0x48 +#define LB_GPE0BLK 0x4c +#define LB_ACTL 0x58 +#define LB_PABCDRC 0x60 +#define LB_PEFGHRC 0x64 +#define LB_WDTBA 0x84 +#define LB_BCE 0xd4 +#define LB_BC 0xd8 +#define LB_RCBA 0xf0 + #endif /* _QUARK_H_ */ -- cgit From d8b1d225129298f3320530730c781a11e839c21c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:10 +0800 Subject: x86: galileo: Add GPIO support Quark SoC has a legacy GPIO block in the legacy bridge (D0:F31), which is just the same one found in other x86 chipset. Since we programmed the GPIO register block base address, we should be able to enable the GPIO support on Intel Galileo board. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/dts/galileo.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index d462221a9d..2f60aeb82d 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -65,4 +65,18 @@ }; }; + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + }; -- cgit From 38fc1cdae0fb7a429222b7b85f8cdaefbd078e21 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:11 +0800 Subject: x86: pci: Add pci ids for Quark SoC Add pci ids for Intel Quark SoC. Signed-off-by: Bin Meng Acked-by: Simon Glass --- include/pci_ids.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/pci_ids.h b/include/pci_ids.h index 1012abecef..dc2ca218a6 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2592,6 +2592,10 @@ #define PCI_DEVICE_ID_INTEL_MFD_EMMC0 0x0823 #define PCI_DEVICE_ID_INTEL_MFD_EMMC1 0x0824 #define PCI_DEVICE_ID_INTEL_MRST_SD2 0x084F +#define PCI_DEVICE_ID_INTEL_QRK_SDIO 0x08A7 +#define PCI_DEVICE_ID_INTEL_QRK_UART 0x0936 +#define PCI_DEVICE_ID_INTEL_QRK_EMAC 0x0937 +#define PCI_DEVICE_ID_INTEL_QRK_ILB 0x095E #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 #define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60 -- cgit From 728b393f3b012ac46505151b80af1d4334786845 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:12 +0800 Subject: x86: Add SPI support to quark/galileo The Quark SoC contains a legacy SPI controller in the legacy bridge which is ICH7 compatible. Like Tunnel Creek and BayTrail, the BIOS control register offset in the ICH SPI driver is wrong for the Quark SoC too, unprotect_spi_flash() is added to enable the flash write. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/quark.c | 17 +++++++++++++++++ arch/x86/dts/galileo.dts | 13 +++++++++++++ drivers/spi/ich.c | 3 ++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index cf596e45e1..0d593d9a86 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -13,6 +13,21 @@ #include #include +/* + * TODO: + * + * This whole routine should be removed until we fully convert the ICH SPI + * driver to DM and make use of DT to pass the bios control register offset + */ +static void unprotect_spi_flash(void) +{ + u32 bc; + + bc = pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8); + bc |= 0x1; /* unprotect the flash */ + pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc); +} + static void quark_setup_bars(void) { /* GPIO - D31:F0:R44h */ @@ -74,6 +89,8 @@ int arch_cpu_init(void) */ quark_setup_bars(); + unprotect_spi_flash(); + return 0; } diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index 2f60aeb82d..66af64abda 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -79,4 +79,17 @@ bank-name = "B"; }; + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich-spi"; + spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + reg = <0>; + compatible = "winbond,w25q64", "spi-flash"; + memory-map = <0xff800000 0x00800000>; + }; + }; + }; diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index da857791e0..194e882302 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -177,7 +177,8 @@ void spi_free_slave(struct spi_slave *slave) static int get_ich_version(uint16_t device_id) { if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC || - device_id == PCI_DEVICE_ID_INTEL_ITC_LPC) + device_id == PCI_DEVICE_ID_INTEL_ITC_LPC || + device_id == PCI_DEVICE_ID_INTEL_QRK_ILB) return 7; if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && -- cgit From 6df7ffea1399de57e5b3be6e3cd0986869087663 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:13 +0800 Subject: x86: Add SD/MMC support to quark/galileo Intel Galileo board has a microSD slot which is routed from Quark SoC SDIO controller. Enable SD/MMC support so that we can use an SD card. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/cpu/quark/quark.c | 11 +++++++++++ include/configs/galileo.h | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 0d593d9a86..dccf7ac5f5 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -13,6 +14,10 @@ #include #include +static struct pci_device_id mmc_supported[] = { + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_SDIO }, +}; + /* * TODO: * @@ -105,3 +110,9 @@ void reset_cpu(ulong addr) /* cold reset */ outb(0x08, PORT_RESET); } + +int cpu_mmc_init(bd_t *bis) +{ + return pci_mmc_init("Quark SDHCI", mmc_supported, + ARRAY_SIZE(mmc_supported)); +} diff --git a/include/configs/galileo.h b/include/configs/galileo.h index bead2fc64e..d745f4eb89 100644 --- a/include/configs/galileo.h +++ b/include/configs/galileo.h @@ -50,4 +50,11 @@ #undef CONFIG_VIDEO #undef CONFIG_CFB_CONSOLE +/* SD/MMC support */ +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC_SDMA +#define CONFIG_CMD_MMC + #endif /* __CONFIG_H */ -- cgit From 67582c00d788c150bb717671f988f234bd73ce5e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 4 Feb 2015 16:26:14 +0800 Subject: x86: Add Intel Galileo instructions in README.x86 Add some instructions about building U-Boot for Intel Galileo board. Signed-off-by: Bin Meng Acked-by: Simon Glass --- doc/README.x86 | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/doc/README.x86 b/doc/README.x86 index c699b795e2..fb87682e05 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -18,8 +18,8 @@ U-Boot supports running as a coreboot [1] payload on x86. So far only Link on other x86 boards since coreboot deals with most of the low-level details. U-Boot also supports booting directly from x86 reset vector without coreboot, -aka raw support or bare support. Currently Link, Intel Crown Bay and Intel -Minnowboard Max support running U-Boot 'bare metal'. +aka raw support or bare support. Currently Link, Intel Crown Bay, Intel +Minnowboard Max and Intel Galileo support running U-Boot 'bare metal'. As for loading an OS, U-Boot supports directly booting a 32-bit or 64-bit Linux kernel as part of a FIT image. It also supports a compressed zImage. @@ -110,7 +110,6 @@ Now you can build U-Boot and obtain u-boot.rom $ make crownbay_defconfig $ make all - Intel Minnowboard Max instructions: This uses as FSP as with Crown Bay, except it is for the Atom E3800 series. @@ -136,6 +135,24 @@ Now you can build U-Boot and obtain u-boot.rom $ make minnowmax_defconfig $ make all +Intel Galileo instructions: + +Only one binary blob is needed for Remote Management Unit (RMU) within Intel +Quark SoC. Not like FSP, U-Boot does not call into the binary. The binary is +needed by the Quark SoC itself. + +You can get the binary blob from Quark Board Support Package from Intel website: + +* ./QuarkSocPkg/QuarkNorthCluster/Binary/QuarkMicrocode/RMU.bin + +Rename the file and put it to the board directory by: + + $ cp RMU.bin board/intel/galileo/rmu.bin + +Now you can build U-Boot and obtain u-boot.rom + +$ make galileo_defconfig +$ make all Test with coreboot ------------------ @@ -203,7 +220,6 @@ mtrr - List and set the Memory Type Range Registers (MTRR). These are used to Development Flow ---------------- - These notes are for those who want to port U-Boot to a new x86 platform. Since x86 CPUs boot from SPI flash, a SPI flash emulator is a good investment. -- cgit From 1b15fac15d9720b4a31a54fe07fd181ff0a28a80 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 21:25:08 +0800 Subject: bootstage: Fix typos in the comment There are two typos in the comment block in bootstage.h, fix them. Signed-off-by: Bin Meng Acked-by: Simon Glass --- include/bootstage.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bootstage.h b/include/bootstage.h index 6b7588d38f..0276cb3f60 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -86,9 +86,9 @@ enum bootstage_id { BOOTSTAGE_ID_POST_FAIL_R, /* Post failure reported after reloc */ /* - * This set is reported ony by x86, and the meaning is different. In + * This set is reported only by x86, and the meaning is different. In * this case we are reporting completion of a particular stage. - * This should probably change in he x86 code (which doesn't report + * This should probably change in the x86 code (which doesn't report * errors in any case), but discussion this can perhaps wait until we * have a generic board implementation. */ -- cgit From ba877efb802edb7080703e4dd99e51a437e44f26 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 2 Feb 2015 21:25:09 +0800 Subject: x86: Use tab instead of space to indent in PCIE_ECAM_BASE Space is used before 'default' in PCIE_ECAM_BASE in arch/x86/Kconfig so it looks misaligned. Replace the space with tab to indent. Signed-off-by: Bin Meng Acked-by: Simon Glass --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2370c323ef..fef11f3552 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -428,7 +428,7 @@ source "board/intel/galileo/Kconfig" config PCIE_ECAM_BASE hex - default 0xe0000000 + default 0xe0000000 help This is the memory-mapped address of PCI configuration space, which is only available through the Enhanced Configuration Access -- cgit From e35c6c797888b9b4361a8cfdc3a4aecacfece74c Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 7 Feb 2015 07:03:00 -0500 Subject: kwbimage: Make the Makefile pass in CONFIG_SYS_SPI_U_BOOT_OFFS We can't use config.h directly as some platforms include headers that aren't safe to use in normal Linux userland. Signed-off-by: Tom Rini --- tools/Makefile | 4 ++++ tools/kwbimage.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index 6e1ce79f2f..e4b23eb5b8 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -115,6 +115,10 @@ ifdef CONFIG_FIT_SIGNATURE HOST_EXTRACFLAGS += -DCONFIG_FIT_SIGNATURE endif +ifdef CONFIG_SYS_SPI_U_BOOT_OFFS +HOSTCFLAGS_kwbimage.o += -DCONFIG_SYS_SPI_U_BOOT_OFFS=$(CONFIG_SYS_SPI_U_BOOT_OFFS) +endif + # MXSImage needs LibSSL ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_FIT_SIGNATURE),) HOSTLOADLIBES_mkimage += -lssl -lcrypto diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 28ce1e4f08..de5c80847e 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -16,7 +16,6 @@ #include #include #include "kwbimage.h" -#include #define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1)) -- cgit From 05084443f02ecc3b74f6604edb69f199c804ffb9 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:27 +0800 Subject: ARM: atmel: clock: make it possible to configure HMX32 Signed-off-by: Bo Shen --- arch/arm/cpu/armv7/at91/clock.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c index 2cdddb2504..0bf453eff5 100644 --- a/arch/arm/cpu/armv7/at91/clock.c +++ b/arch/arm/cpu/armv7/at91/clock.c @@ -130,10 +130,18 @@ void at91_mck_init(u32 mckr) AT91_PMC_MCKR_PRES_MASK | AT91_PMC_MCKR_MDIV_MASK | AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp &= ~AT91_PMC_MCKR_H32MXDIV; +#endif + tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK | AT91_PMC_MCKR_PRES_MASK | AT91_PMC_MCKR_MDIV_MASK | AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp |= mckr & AT91_PMC_MCKR_H32MXDIV; +#endif + writel(tmp, &pmc->mckr); while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) -- cgit From 406202dffd91b248ff021b9cf1a17d42ba2b5eeb Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:28 +0800 Subject: ARM: atmel: sama5: add bus matrix header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matrix header file can be shared between sama5d3 and sama5d4 soc. Signed-off-by: Bo Shen [whitespace adaptions for 80 char compliance] Signed-off-by: Andreas Bießmann --- arch/arm/include/asm/arch-at91/sama5_matrix.h | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 arch/arm/include/asm/arch-at91/sama5_matrix.h diff --git a/arch/arm/include/asm/arch-at91/sama5_matrix.h b/arch/arm/include/asm/arch-at91/sama5_matrix.h new file mode 100644 index 0000000000..e324766733 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/sama5_matrix.h @@ -0,0 +1,37 @@ +/* + * Bus Matrix header file for the SAMA5 family + * + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SAMA5_MATRIX_H +#define __SAMA5_MATRIX_H + +struct atmel_matrix { + u32 mcfg[16]; /* 0x00 ~ 0x3c: Master Configuration Register */ + u32 scfg[16]; /* 0x40 ~ 0x7c: Slave Configuration Register */ + u32 pras[16][2];/* 0x80 ~ 0xfc: Priority Register A/B */ + u32 res1[20]; /* 0x100 ~ 0x14c */ + u32 meier; /* 0x150: Master Error Interrupt Enable Register */ + u32 meidr; /* 0x154: Master Error Interrupt Disable Register */ + u32 meimr; /* 0x158: Master Error Interrupt Mask Register */ + u32 mesr; /* 0x15c: Master Error Status Register */ + u32 mear[16]; /* 0x160 ~ 0x19c: Master Error Address Register */ + u32 res2[17]; /* 0x1A0 ~ 0x1E0 */ + u32 wpmr; /* 0x1E4: Write Protection Mode Register */ + u32 wpsr; /* 0x1E8: Write Protection Status Register */ + u32 res3[5]; /* 0x1EC ~ 0x1FC */ + u32 ssr[16]; /* 0x200 ~ 0x23c: Security Slave Register */ + u32 sassr[16]; /* 0x240 ~ 0x27c: Security Areas Split Slave Register */ + u32 srtsr[16]; /* 0x280 ~ 0x2bc: Security Region Top Slave */ + u32 spselr[3]; /* 0x2c0 ~ 0x2c8: Security Peripheral Select Register */ +}; + +/* Bit field in WPMR */ +#define ATMEL_MATRIX_WPMR_WPKEY 0x4D415400 +#define ATMEL_MATRIX_WPMR_WPEN 0x00000001 + +#endif -- cgit From abb44081a5f754b80acf5a97d648e731b75d22fc Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:29 +0800 Subject: ARM: atmel: sama5: add sfr register header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFR (special function registers) can be shared bwteen sama5d3 and sama5d4 soc. Signed-off-by: Bo Shen [whitespace adoptions for 80 char compliance] Signed-off-by: Andreas Bießmann --- arch/arm/include/asm/arch-at91/sama5_sfr.h | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 arch/arm/include/asm/arch-at91/sama5_sfr.h diff --git a/arch/arm/include/asm/arch-at91/sama5_sfr.h b/arch/arm/include/asm/arch-at91/sama5_sfr.h new file mode 100644 index 0000000000..3081d37571 --- /dev/null +++ b/arch/arm/include/asm/arch-at91/sama5_sfr.h @@ -0,0 +1,38 @@ +/* + * Special Function Register (SFR) + * + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SAMA5_SFR_H +#define __SAMA5_SFR_H + +struct atmel_sfr { + u32 reserved1; /* 0x00 */ + u32 ddrcfg; /* 0x04: DDR Configuration Register */ + u32 reserved2; /* 0x08 */ + u32 reserved3; /* 0x0c */ + u32 ohciicr; /* 0x10: OHCI Interrupt Configuration Register */ + u32 ohciisr; /* 0x14: OHCI Interrupt Status Register */ + u32 reserved4[4]; /* 0x18 ~ 0x24 */ + u32 secure; /* 0x28: Security Configuration Register */ + u32 reserved5[5]; /* 0x2c ~ 0x3c */ + u32 ebicfg; /* 0x40: EBI Configuration Register */ + u32 reserved6[2]; /* 0x44 ~ 0x48 */ + u32 sn0; /* 0x4c */ + u32 sn1; /* 0x50 */ + u32 aicredir; /* 0x54 */ +}; + +/* Bit field in DDRCFG */ +#define ATMEL_SFR_DDRCFG_FDQIEN 0x00010000 +#define ATMEL_SFR_DDRCFG_FDQSIEN 0x00020000 + +/* Bit field in AICREDIR */ +#define ATMEL_SFR_AICREDIR_KEY 0x5F67B102 +#define ATMEL_SFR_AICREDIR_NSAIC 0x00000001 + +#endif -- cgit From 433be902f3a7e8b40b349e3d9dacdf0a69982ede Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:30 +0800 Subject: ARM: atmel: spl: add weak bus matrix init function Some SoC need to configure the bus matrix, add an weak function to be replace by real function. Signed-off-by: Bo Shen --- arch/arm/cpu/at91-common/spl_atmel.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/cpu/at91-common/spl_atmel.c b/arch/arm/cpu/at91-common/spl_atmel.c index 7297530e7d..9cb5770852 100644 --- a/arch/arm/cpu/at91-common/spl_atmel.c +++ b/arch/arm/cpu/at91-common/spl_atmel.c @@ -58,6 +58,11 @@ static void switch_to_main_crystal_osc(void) writel(tmp, &pmc->mor); } +__weak void matrix_init(void) +{ + /* This only be used for sama5d4 soc now */ +} + void s_init(void) { switch_to_main_crystal_osc(); @@ -70,6 +75,8 @@ void s_init(void) at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); + matrix_init(); + timer_init(); board_early_init_f(); -- cgit From 4514b5f46a27df0843a8504273ee0cb0749ea86e Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:31 +0800 Subject: ARM: atmel: spl: add saic to aic redirect function Some SoC need to redirect the saic to aic to make the interrupt to work, here add a weak function to be replaced by real function. Signed-off-by: Bo Shen --- arch/arm/cpu/at91-common/spl_atmel.c | 7 +++++++ arch/arm/include/asm/arch-at91/at91_common.h | 1 + 2 files changed, 8 insertions(+) diff --git a/arch/arm/cpu/at91-common/spl_atmel.c b/arch/arm/cpu/at91-common/spl_atmel.c index 9cb5770852..fdea46665f 100644 --- a/arch/arm/cpu/at91-common/spl_atmel.c +++ b/arch/arm/cpu/at91-common/spl_atmel.c @@ -63,6 +63,11 @@ __weak void matrix_init(void) /* This only be used for sama5d4 soc now */ } +__weak void redirect_int_from_saic_to_aic(void) +{ + /* This only be used for sama5d4 soc now */ +} + void s_init(void) { switch_to_main_crystal_osc(); @@ -77,6 +82,8 @@ void s_init(void) matrix_init(); + redirect_int_from_saic_to_aic(); + timer_init(); board_early_init_f(); diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h index 912e55c8de..efcd74ed90 100644 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ b/arch/arm/include/asm/arch-at91/at91_common.h @@ -33,5 +33,6 @@ void at91_mck_init(u32 mckr); void at91_spl_board_init(void); void at91_disable_wdt(void); void matrix_init(void); +void redirect_int_from_saic_to_aic(void); #endif /* AT91_COMMON_H */ -- cgit From 0246b7c3b7b974182cc5795b01261d6dd24dde71 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:32 +0800 Subject: ARM: atmel: spl: can not disable osc for sama5d4 The SAMA5D4 SoC on chip rc oscillator can not be disabled. Signed-off-by: Bo Shen --- arch/arm/cpu/at91-common/spl_atmel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/cpu/at91-common/spl_atmel.c b/arch/arm/cpu/at91-common/spl_atmel.c index fdea46665f..9cc1111234 100644 --- a/arch/arm/cpu/at91-common/spl_atmel.c +++ b/arch/arm/cpu/at91-common/spl_atmel.c @@ -51,11 +51,13 @@ static void switch_to_main_crystal_osc(void) while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY)) ; +#ifndef CONFIG_SAMA5D4 tmp = readl(&pmc->mor); tmp &= ~AT91_PMC_MOR_MOSCRCEN; tmp &= ~AT91_PMC_MOR_KEY(0xff); tmp |= AT91_PMC_MOR_KEY(0x37); writel(tmp, &pmc->mor); +#endif } __weak void matrix_init(void) -- cgit From 5c756bbc9dd9c59bdf1a60159081c0f25fd0cb0b Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:33 +0800 Subject: ARM: atmel: sama5d4: add matrix1 base addr definition Signed-off-by: Bo Shen --- arch/arm/include/asm/arch-at91/sama5d4.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/include/asm/arch-at91/sama5d4.h b/arch/arm/include/asm/arch-at91/sama5d4.h index d85156816f..f30cb5fed1 100644 --- a/arch/arm/include/asm/arch-at91/sama5d4.h +++ b/arch/arm/include/asm/arch-at91/sama5d4.h @@ -126,6 +126,8 @@ #define ATMEL_BASE_ADC 0xfc034000 #define ATMEL_BASE_TWI3 0xfc038000 +#define ATMEL_BASE_MATRIX1 0xfc054000 + #define ATMEL_BASE_SMC 0xfc05c000 #define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) #define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) -- cgit From 09f5c9745b15ea6ab008092ace6f01f7b108c79d Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:34 +0800 Subject: ARM: atmel: sama5d4: add bus matrix init function Signed-off-by: Bo Shen --- arch/arm/cpu/armv7/at91/sama5d4_devices.c | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/cpu/armv7/at91/sama5d4_devices.c b/arch/arm/cpu/armv7/at91/sama5d4_devices.c index 7469825565..9c63e99899 100644 --- a/arch/arm/cpu/armv7/at91/sama5d4_devices.c +++ b/arch/arm/cpu/armv7/at91/sama5d4_devices.c @@ -10,6 +10,7 @@ #include #include #include +#include #include char *get_cpu_name() @@ -44,3 +45,37 @@ void at91_udp_hw_init(void) at91_periph_clk_enable(ATMEL_ID_UDPHS); } #endif + +#ifdef CONFIG_SPL_BUILD +void matrix_init(void) +{ + struct atmel_matrix *h64mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX0; + struct atmel_matrix *h32mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX1; + int i; + + /* Disable the write protect */ + writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); + writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); + + /* DDR port 1 ~ poart 7, slave number is: 4 ~ 10 */ + for (i = 4; i <= 10; i++) { + writel(0x000f0f0f, &h64mx->ssr[i]); + writel(0x0000ffff, &h64mx->sassr[i]); + writel(0x0000000f, &h64mx->srtsr[i]); + } + + /* CS3 */ + writel(0x00c0c0c0, &h32mx->ssr[3]); + writel(0xff000000, &h32mx->sassr[3]); + writel(0xff000000, &h32mx->srtsr[3]); + + /* NFC SRAM */ + writel(0x00010101, &h32mx->ssr[4]); + writel(0x00000001, &h32mx->sassr[4]); + writel(0x00000001, &h32mx->srtsr[4]); + + /* Enable the write protect */ + writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); + writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); +} +#endif -- cgit From 569bbd3ceb1f3ca9d1f448178cd67f3eea4e01c4 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:35 +0800 Subject: ARM: atmel: sama5d4: add interrupt redirect function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bo Shen [fix subject] Signed-off-by: Andreas Bießmann --- arch/arm/cpu/armv7/at91/sama5d4_devices.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/cpu/armv7/at91/sama5d4_devices.c b/arch/arm/cpu/armv7/at91/sama5d4_devices.c index 9c63e99899..ef39cb7e08 100644 --- a/arch/arm/cpu/armv7/at91/sama5d4_devices.c +++ b/arch/arm/cpu/armv7/at91/sama5d4_devices.c @@ -11,6 +11,7 @@ #include #include #include +#include #include char *get_cpu_name() @@ -78,4 +79,15 @@ void matrix_init(void) writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); } + +void redirect_int_from_saic_to_aic(void) +{ + struct atmel_sfr *sfr = (struct atmel_sfr *)ATMEL_BASE_SFR; + u32 key32; + + if (!(readl(&sfr->aicredir) & ATMEL_SFR_AICREDIR_NSAIC)) { + key32 = readl(&sfr->sn1) ^ ATMEL_SFR_AICREDIR_KEY; + writel((key32 | ATMEL_SFR_AICREDIR_NSAIC), &sfr->aicredir); + } +} #endif -- cgit From b54dd1b3adad4613bb8aa471b12f88bede699775 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:36 +0800 Subject: ARM: atmel: sama5d4: can access DDR in interleave mode The SAMAA5D4 SoC can access DDR in interleave mode. Signed-off-by: Bo Shen --- arch/arm/cpu/at91-common/mpddrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/cpu/at91-common/mpddrc.c b/arch/arm/cpu/at91-common/mpddrc.c index 44798e612c..beec13db8c 100644 --- a/arch/arm/cpu/at91-common/mpddrc.c +++ b/arch/arm/cpu/at91-common/mpddrc.c @@ -19,7 +19,7 @@ static inline void atmel_mpddr_op(int mode, u32 ram_address) static int ddr2_decodtype_is_seq(u32 cr) { -#if defined(CONFIG_SAMA5D3) +#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED) return 0; #endif -- cgit From 01c073c013551aa3461a96a23617e2179bda1f5b Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:37 +0800 Subject: ARM: atmel: sama5d4: build related file when enable SPL Signed-off-by: Bo Shen --- arch/arm/cpu/at91-common/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/cpu/at91-common/Makefile b/arch/arm/cpu/at91-common/Makefile index 89e15775fb..03614d4140 100644 --- a/arch/arm/cpu/at91-common/Makefile +++ b/arch/arm/cpu/at91-common/Makefile @@ -13,5 +13,6 @@ ifneq ($(CONFIG_SPL_BUILD),) obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o +obj-$(CONFIG_SAMA5D4) += mpddrc.o spl_atmel.o obj-y += spl.o endif -- cgit From 5a4c9c22872725d9b02fb11fdcec063ccea9536f Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:38 +0800 Subject: ARM: atmel: sama5d4ek: enable SPL support The sama5d4ek support boot up from NAND flash, SD/MMC card and also the SPI flash. Signed-off-by: Bo Shen --- arch/arm/Kconfig | 1 + board/atmel/sama5d4ek/sama5d4ek.c | 85 +++++++++++++++++++++++++++++++++++ configs/sama5d4ek_mmc_defconfig | 1 + configs/sama5d4ek_nandflash_defconfig | 1 + configs/sama5d4ek_spiflash_defconfig | 1 + include/configs/sama5d4ek.h | 56 +++++++++++++++++++++++ 6 files changed, 145 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 986b4c5d81..8be14fe8e3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -529,6 +529,7 @@ config TARGET_SAMA5D4_XPLAINED config TARGET_SAMA5D4EK bool "Support sama5d4ek" select CPU_V7 + select SUPPORT_SPL config TARGET_BCM28155_AP bool "Support bcm28155_ap" diff --git a/board/atmel/sama5d4ek/sama5d4ek.c b/board/atmel/sama5d4ek/sama5d4ek.c index d8ff648957..46e504131c 100644 --- a/board/atmel/sama5d4ek/sama5d4ek.c +++ b/board/atmel/sama5d4ek/sama5d4ek.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -325,3 +326,87 @@ int board_eth_init(bd_t *bis) return rc; } + +/* SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ +#ifdef CONFIG_SYS_USE_MMC + sama5d4ek_mci1_hw_init(); +#elif CONFIG_SYS_USE_NANDFLASH + sama5d4ek_nand_hw_init(); +#elif CONFIG_SYS_USE_SERIALFLASH + sama5d4ek_spi0_hw_init(); +#endif +} + +static void ddr2_conf(struct atmel_mpddr *ddr2) +{ + ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); + + ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_DDR_CAS3 | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_NDQS_DISABLED | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + + ddr2->rtr = 0x2b0; + + ddr2->tpr0 = (8 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | + 10 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); + + ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | + 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | + 25 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | + 23 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET); + + ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | + 3 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | + 8 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET); +} + +void mem_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + struct atmel_mpddr ddr2; + + ddr2_conf(&ddr2); + + /* enable MPDDR clock */ + at91_periph_clk_enable(ATMEL_ID_MPDDRC); + writel(0x4, &pmc->scer); + + /* DDRAM2 Controller initialize */ + ddr2_init(ATMEL_BASE_DDRCS, &ddr2); +} + +void at91_pmc_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = AT91_PMC_PLLAR_29 | + AT91_PMC_PLLXR_PLLCOUNT(0x3f) | + AT91_PMC_PLLXR_MUL(87) | + AT91_PMC_PLLXR_DIV(1); + at91_plla_init(tmp); + + writel(0x0 << 8, &pmc->pllicpr); + + tmp = AT91_PMC_MCKR_H32MXDIV | + AT91_PMC_MCKR_PLLADIV_2 | + AT91_PMC_MCKR_MDIV_3 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp); +} +#endif diff --git a/configs/sama5d4ek_mmc_defconfig b/configs/sama5d4ek_mmc_defconfig index 16a5ed7ef5..aafb4c2247 100644 --- a/configs/sama5d4ek_mmc_defconfig +++ b/configs/sama5d4ek_mmc_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_MMC" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/configs/sama5d4ek_nandflash_defconfig b/configs/sama5d4ek_nandflash_defconfig index 8b7fbc33f4..d430fa768f 100644 --- a/configs/sama5d4ek_nandflash_defconfig +++ b/configs/sama5d4ek_nandflash_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/configs/sama5d4ek_spiflash_defconfig b/configs/sama5d4ek_spiflash_defconfig index 63e9b6c0c6..796fa4b15a 100644 --- a/configs/sama5d4ek_spiflash_defconfig +++ b/configs/sama5d4ek_spiflash_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_SERIALFLASH" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/include/configs/sama5d4ek.h b/include/configs/sama5d4ek.h index 09ab4d7f25..9e1b86a347 100644 --- a/include/configs/sama5d4ek.h +++ b/include/configs/sama5d4ek.h @@ -20,7 +20,9 @@ #define CONFIG_ARCH_CPU_INIT +#ifndef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT +#endif #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_DISPLAY_CPUINFO @@ -66,8 +68,12 @@ #define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS #define CONFIG_SYS_SDRAM_SIZE 0x20000000 +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_INIT_SP_ADDR 0x210000 +#else #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) +#endif #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ @@ -219,4 +225,54 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) + +/* SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x200000 +#define CONFIG_SPL_MAX_SIZE 0x10000 +#define CONFIG_SPL_BSS_START_ADDR 0x20000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 +#define CONFIG_SYS_SPL_MALLOC_START 0x20080000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT + +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_MONITOR_LEN (512 << 10) + +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +#define CONFIG_SPL_FAT_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT + +#elif CONFIG_SYS_USE_NANDFLASH +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_DRIVERS +#define CONFIG_SPL_NAND_BASE +#define CONFIG_PMECC_CAP 8 +#define CONFIG_PMECC_SECTOR_SIZE 512 +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_SYS_NAND_PAGE_SIZE 0x1000 +#define CONFIG_SYS_NAND_PAGE_COUNT 64 +#define CONFIG_SYS_NAND_OOBSIZE 224 +#define CONFIG_SYS_NAND_BLOCK_SIZE 0x40000 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0x0 +#define CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER + +#elif CONFIG_SYS_USE_SERIALFLASH +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 + +#endif #endif -- cgit From 0b2a9824203deccf8e5ffd0db69f6aa9b771eb26 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 15 Dec 2014 13:24:39 +0800 Subject: ARM: atmel: sama5d4_xplained: enable spl support Signed-off-by: Bo Shen --- arch/arm/Kconfig | 1 + board/atmel/sama5d4_xplained/sama5d4_xplained.c | 85 +++++++++++++++++++++++++ configs/sama5d4_xplained_mmc_defconfig | 1 + configs/sama5d4_xplained_nandflash_defconfig | 1 + configs/sama5d4_xplained_spiflash_defconfig | 1 + include/configs/sama5d4_xplained.h | 56 ++++++++++++++++ 6 files changed, 145 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8be14fe8e3..5cfca1b831 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -525,6 +525,7 @@ config TARGET_SAMA5D3XEK config TARGET_SAMA5D4_XPLAINED bool "Support sama5d4_xplained" select CPU_V7 + select SUPPORT_SPL config TARGET_SAMA5D4EK bool "Support sama5d4ek" diff --git a/board/atmel/sama5d4_xplained/sama5d4_xplained.c b/board/atmel/sama5d4_xplained/sama5d4_xplained.c index 1c5b92c8b5..bc2aa38b92 100644 --- a/board/atmel/sama5d4_xplained/sama5d4_xplained.c +++ b/board/atmel/sama5d4_xplained/sama5d4_xplained.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -326,3 +327,87 @@ int board_eth_init(bd_t *bis) return rc; } + +/* SPL */ +#ifdef CONFIG_SPL_BUILD +void spl_board_init(void) +{ +#ifdef CONFIG_SYS_USE_MMC + sama5d4_xplained_mci1_hw_init(); +#elif CONFIG_SYS_USE_NANDFLASH + sama5d4_xplained_nand_hw_init(); +#elif CONFIG_SYS_USE_SERIALFLASH + sama5d4_xplained_spi0_hw_init(); +#endif +} + +static void ddr2_conf(struct atmel_mpddr *ddr2) +{ + ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); + + ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | + ATMEL_MPDDRC_CR_NR_ROW_14 | + ATMEL_MPDDRC_CR_CAS_DDR_CAS3 | + ATMEL_MPDDRC_CR_NB_8BANKS | + ATMEL_MPDDRC_CR_NDQS_DISABLED | + ATMEL_MPDDRC_CR_DECOD_INTERLEAVED | + ATMEL_MPDDRC_CR_UNAL_SUPPORTED); + + ddr2->rtr = 0x2b0; + + ddr2->tpr0 = (8 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | + 10 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | + 3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | + 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); + + ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | + 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | + 25 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | + 23 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET); + + ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | + 3 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | + 2 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | + 8 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET); +} + +void mem_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + struct atmel_mpddr ddr2; + + ddr2_conf(&ddr2); + + /* enable MPDDR clock */ + at91_periph_clk_enable(ATMEL_ID_MPDDRC); + writel(0x4, &pmc->scer); + + /* DDRAM2 Controller initialize */ + ddr2_init(ATMEL_BASE_DDRCS, &ddr2); +} + +void at91_pmc_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = AT91_PMC_PLLAR_29 | + AT91_PMC_PLLXR_PLLCOUNT(0x3f) | + AT91_PMC_PLLXR_MUL(87) | + AT91_PMC_PLLXR_DIV(1); + at91_plla_init(tmp); + + writel(0x0 << 8, &pmc->pllicpr); + + tmp = AT91_PMC_MCKR_H32MXDIV | + AT91_PMC_MCKR_PLLADIV_2 | + AT91_PMC_MCKR_MDIV_3 | + AT91_PMC_MCKR_CSS_PLLA; + at91_mck_init(tmp); +} +#endif diff --git a/configs/sama5d4_xplained_mmc_defconfig b/configs/sama5d4_xplained_mmc_defconfig index 3720f3cfb4..73df28ccff 100644 --- a/configs/sama5d4_xplained_mmc_defconfig +++ b/configs/sama5d4_xplained_mmc_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_MMC" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/configs/sama5d4_xplained_nandflash_defconfig b/configs/sama5d4_xplained_nandflash_defconfig index 5e13da7908..046fe0682e 100644 --- a/configs/sama5d4_xplained_nandflash_defconfig +++ b/configs/sama5d4_xplained_nandflash_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/configs/sama5d4_xplained_spiflash_defconfig b/configs/sama5d4_xplained_spiflash_defconfig index 3a4607c676..755dd8b55f 100644 --- a/configs/sama5d4_xplained_spiflash_defconfig +++ b/configs/sama5d4_xplained_spiflash_defconfig @@ -1,3 +1,4 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_SERIALFLASH" +S:CONFIG_ARM=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/include/configs/sama5d4_xplained.h b/include/configs/sama5d4_xplained.h index 996973d99b..6493d567b4 100644 --- a/include/configs/sama5d4_xplained.h +++ b/include/configs/sama5d4_xplained.h @@ -20,7 +20,9 @@ #define CONFIG_ARCH_CPU_INIT +#ifndef CONFIG_SPL_BUILD #define CONFIG_SKIP_LOWLEVEL_INIT +#endif #define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_DISPLAY_CPUINFO @@ -66,8 +68,12 @@ #define CONFIG_SYS_SDRAM_BASE ATMEL_BASE_DDRCS #define CONFIG_SYS_SDRAM_SIZE 0x20000000 +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_INIT_SP_ADDR 0x210000 +#else #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 4 * 1024 - GENERATED_GBL_DATA_SIZE) +#endif #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ @@ -221,4 +227,54 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) + +/* SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_TEXT_BASE 0x200000 +#define CONFIG_SPL_MAX_SIZE 0x10000 +#define CONFIG_SPL_BSS_START_ADDR 0x20000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 +#define CONFIG_SYS_SPL_MALLOC_START 0x20080000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT + +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_MONITOR_LEN (512 << 10) + +#ifdef CONFIG_SYS_USE_MMC +#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +#define CONFIG_SPL_FAT_SUPPORT +#define CONFIG_SPL_LIBDISK_SUPPORT + +#elif CONFIG_SYS_USE_NANDFLASH +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_DRIVERS +#define CONFIG_SPL_NAND_BASE +#define CONFIG_PMECC_CAP 8 +#define CONFIG_PMECC_SECTOR_SIZE 512 +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_SYS_NAND_PAGE_SIZE 0x1000 +#define CONFIG_SYS_NAND_PAGE_COUNT 64 +#define CONFIG_SYS_NAND_OOBSIZE 224 +#define CONFIG_SYS_NAND_BLOCK_SIZE 0x40000 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0x0 +#define CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER + +#elif CONFIG_SYS_USE_SERIALFLASH +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 + +#endif #endif -- cgit From c6941e120386b06b21566b560cd51882b0d1a51a Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Fri, 16 Jan 2015 10:55:46 +0800 Subject: ARM: atmel: cleanup: remove at91cap9 related code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the at91cap9adk board is removed by commit: b5508344 (ARM: remove broken "at91cap9adk" board), so the at91cap9 code is not used anymore, and also the document for at91cap9 can not be found on www.atmel.com, so remove the at91cap9 related code. Signed-off-by: Bo Shen Acked-by: Andreas Bießmann --- arch/arm/cpu/arm926ejs/at91/Makefile | 1 - arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c | 189 ----------------------- arch/arm/include/asm/arch-at91/at91_pmc.h | 9 +- arch/arm/include/asm/arch-at91/at91cap9.h | 78 ---------- arch/arm/include/asm/arch-at91/at91cap9_matrix.h | 129 ---------------- arch/arm/include/asm/arch-at91/at91sam9_matrix.h | 2 - arch/arm/include/asm/arch-at91/hardware.h | 2 - drivers/video/atmel_lcdfb.c | 2 +- 8 files changed, 4 insertions(+), 408 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c delete mode 100644 arch/arm/include/asm/arch-at91/at91cap9.h delete mode 100644 arch/arm/include/asm/arch-at91/at91cap9_matrix.h diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile index 698a28dc5d..ddc323f641 100644 --- a/arch/arm/cpu/arm926ejs/at91/Makefile +++ b/arch/arm/cpu/arm926ejs/at91/Makefile @@ -5,7 +5,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_AT91CAP9) += at91cap9_devices.o obj-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o obj-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o obj-$(CONFIG_AT91SAM9XE) += at91sam9260_devices.o diff --git a/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c b/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c deleted file mode 100644 index 16eeca7378..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91cap9_devices.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2009 - * Daniel Gorsulowski - * esd electronic system design gmbh - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 23, 0); /* RXD0 */ - writel(1 << AT91CAP9_ID_US0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */ - writel(1 << AT91CAP9_ID_US1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */ - writel(1 << AT91CAP9_ID_US2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ - writel(1 << AT91_ID_SYS, &pmc->pcer); -} - -void at91_serial_hw_init(void) -{ -#ifdef CONFIG_USART0 - at91_serial0_hw_init(); -#endif - -#ifdef CONFIG_USART1 - at91_serial1_hw_init(); -#endif - -#ifdef CONFIG_USART2 - at91_serial2_hw_init(); -#endif - -#ifdef CONFIG_USART3 /* DBGU */ - at91_serial3_hw_init(); -#endif -} - -#ifdef CONFIG_HAS_DATAFLASH -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_b_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTD, 0, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 1, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 0, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 1, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 1); - } - -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTB, 21, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTB, 22, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTB, 25, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 26, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 27, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTB, 23, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 24, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ -#endif -} -#endif - -#ifdef CONFIG_AT91_CAN -void at91_can_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE; - - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* CAN_TX */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* CAN_RX */ - - /* Enable clock */ - writel(1 << AT91CAP9_ID_CAN, &pmc->pcer); -} -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h index 53b5b2e0fb..65691aba01 100644 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ b/arch/arm/include/asm/arch-at91/at91_pmc.h @@ -157,10 +157,8 @@ typedef struct at91_pmc { #define AT91_PMC_PCK (1 << 0) /* Processor Clock */ #define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ -#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [AT91CAP9 revC only] */ #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ -#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ #define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ #define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ @@ -175,7 +173,7 @@ typedef struct at91_pmc { #define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */ #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ -#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */ #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ @@ -210,7 +208,7 @@ typedef struct at91_pmc { #define AT91RM9200_PMC_MDIV_2 (1 << 8) #define AT91RM9200_PMC_MDIV_3 (2 << 8) #define AT91RM9200_PMC_MDIV_4 (3 << 8) -#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */ +#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */ #define AT91SAM9_PMC_MDIV_2 (1 << 8) #define AT91SAM9_PMC_MDIV_4 (2 << 8) #define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */ @@ -230,8 +228,7 @@ typedef struct at91_pmc { #define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ #define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ #define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ -#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */ -#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock */ #define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ diff --git a/arch/arm/include/asm/arch-at91/at91cap9.h b/arch/arm/include/asm/arch-at91/at91cap9.h deleted file mode 100644 index 63870bc65d..0000000000 --- a/arch/arm/include/asm/arch-at91/at91cap9.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91cap9.h] - * - * Copyright (C) 2007 Stelian Pop - * Copyright (C) 2007 Lead Tech Design - * Copyright (C) 2007 Atmel Corporation. - * - * Common definitions. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91CAP9_H -#define AT91CAP9_H - -/* - * Peripheral identifiers/interrupts. - */ -#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define AT91_ID_SYS 1 /* System Peripherals */ -#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */ -#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */ -#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */ -#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */ -#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */ -#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */ -#define AT91CAP9_ID_US0 8 /* USART 0 */ -#define AT91CAP9_ID_US1 9 /* USART 1 */ -#define AT91CAP9_ID_US2 10 /* USART 2 */ -#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */ -#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */ -#define AT91CAP9_ID_CAN 13 /* CAN */ -#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */ -#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */ -#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */ -#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */ -#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */ -#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */ -#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */ -#define AT91CAP9_ID_EMAC 22 /* Ethernet */ -#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */ -#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */ -#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */ -#define AT91CAP9_ID_LCDC 26 /* LCD Controller */ -#define AT91CAP9_ID_DMA 27 /* DMA Controller */ -#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */ -#define AT91CAP9_ID_UHP 29 /* USB Host Port */ -#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ -#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ - -#define AT91_PIO_BASE 0xfffff200 -#define AT91_PMC_BASE 0xfffffc00 -#define AT91_RSTC_BASE 0xfffffd00 -#define AT91_PIT_BASE 0xfffffd30 - -/* - * Internal Memory. - */ -#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */ -#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */ - -#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */ -#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ - -#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91CAP9_UDPHS_BASE 0x00600000 /* USB High Speed Device Port */ -#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ - -#define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 - -/* - * Cpu Name - */ -#define CONFIG_SYS_AT91_CPU_NAME "AT91CAP9" - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91cap9_matrix.h b/arch/arm/include/asm/arch-at91/at91cap9_matrix.h deleted file mode 100644 index 009a19daf4..0000000000 --- a/arch/arm/include/asm/arch-at91/at91cap9_matrix.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91cap9_matrix.h] - * - * Copyright (C) 2007 Stelian Pop - * Copyright (C) 2007 Lead Tech Design - * Copyright (C) 2006 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91CAP9 datasheet revision B (Preliminary). - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91CAP9_MATRIX_H -#define AT91CAP9_MATRIX_H - -#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ -#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ -#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ -#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ -#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ -#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ -#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ -#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ -#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ -#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ -#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ -#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ -#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ -#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ -#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ -#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ -#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ -#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ -#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ -#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ -#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */ -#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */ -#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */ -#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ -#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */ -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ -#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ -#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ -#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ -#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ -#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ -#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ -#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ -#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ -#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ -#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ -#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ -#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ -#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ -#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ -#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ -#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */ -#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */ -#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */ -#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */ -#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ -#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ -#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ -#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ -#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ -#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ -#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ -#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ -#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ -#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ -#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ -#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ - -#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ -#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_RCB2 (1 << 2) -#define AT91_MATRIX_RCB3 (1 << 3) -#define AT91_MATRIX_RCB4 (1 << 4) -#define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_RCB6 (1 << 6) -#define AT91_MATRIX_RCB7 (1 << 7) -#define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_RCB9 (1 << 9) -#define AT91_MATRIX_RCB10 (1 << 10) -#define AT91_MATRIX_RCB11 (1 << 11) - -#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ -#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ - -#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ -#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ -#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1) -#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ -#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ -#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) -#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ -#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) -#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ -#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */ -#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ -#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) - -#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */ -#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */ -#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */ - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9_matrix.h index 1b59cc6e4e..d0bf0c2e2b 100644 --- a/arch/arm/include/asm/arch-at91/at91sam9_matrix.h +++ b/arch/arm/include/asm/arch-at91/at91sam9_matrix.h @@ -15,8 +15,6 @@ #include #elif defined(CONFIG_AT91SAM9RL) #include -#elif defined(CONFIG_AT91CAP9) -#include #elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) #include #elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h index bf0a1bd6a3..ff6b71b135 100644 --- a/arch/arm/include/asm/arch-at91/hardware.h +++ b/arch/arm/include/asm/arch-at91/hardware.h @@ -23,8 +23,6 @@ # include #elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) # include -#elif defined(CONFIG_AT91CAP9) -# include #elif defined(CONFIG_SAMA5D3) # include #elif defined(CONFIG_SAMA5D4) diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 3cf008ce6b..712d7454e4 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -20,7 +20,7 @@ #define ATMEL_LCDC_GUARD_TIME 1 #endif -#if defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91CAP9) +#if defined(CONFIG_AT91SAM9263) #define ATMEL_LCDC_FIFO_SIZE 2048 #else #define ATMEL_LCDC_FIFO_SIZE 512 -- cgit From 0e48dc5e416f031c8eb05143f2dfab3111ec3b29 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Fri, 16 Jan 2015 11:54:46 +0800 Subject: mtd: atmel_nand: according to pmecc version to perform 0xff page correction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the PMECC hardware has different version. In SAMA5D4 chip, the PMECC ip can generate 0xff pmecc ECC value for all 0xff sector. According to this, add PMECC version check, if it's SAMA5D4 then we always let PMECC hardware to correct it. Signed-off-by: Josh Wu Acked-by: Bo Shen Acked-by: Andreas Bießmann --- drivers/mtd/nand/atmel_nand.c | 9 +++++++++ drivers/mtd/nand/atmel_nand_ecc.h | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 620b6e8ff9..b16e3aa157 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -44,6 +44,7 @@ struct atmel_nand_host { u8 pmecc_corr_cap; u16 pmecc_sector_size; u32 pmecc_index_table_offset; + u32 pmecc_version; int pmecc_bytes_per_sector; int pmecc_sector_number; @@ -486,6 +487,10 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, int i, err_nbr, eccbytes; uint8_t *buf_pos; + /* SAMA5D4 PMECC IP can correct errors for all 0xff page */ + if (host->pmecc_version >= PMECC_VERSION_SAMA5D4) + goto normal_check; + eccbytes = nand_chip->ecc.bytes; for (i = 0; i < eccbytes; i++) if (ecc[i] != 0xff) @@ -961,6 +966,10 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand, nand->ecc.write_page = atmel_nand_pmecc_write_page; nand->ecc.strength = cap; + /* Check the PMECC ip version */ + host->pmecc_version = pmecc_readl(host->pmerrloc, version); + dev_dbg(host->dev, "PMECC IP version is: %x\n", host->pmecc_version); + atmel_pmecc_core_init(mtd); return 0; diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index eac860d13c..b2d2682a88 100644 --- a/drivers/mtd/nand/atmel_nand_ecc.h +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -123,6 +123,20 @@ struct pmecc_errloc_regs { u32 sigma[25]; /* 0x28-0x88 Error Location Sigma Registers */ u32 el[24]; /* 0x8C-0xE8 Error Location Registers */ u32 reserved1[5]; /* 0xEC-0xFC Reserved */ + + /* + * 0x100-0x1F8: + * Reserved for AT91SAM9X5, AT91SAM9N12. + * HSMC registers for SAMA5D3, SAMA5D4. + */ + u32 reserved2[63]; + + /* + * 0x1FC: + * PMECC version for AT91SAM9X5, AT91SAM9N12. + * HSMC version for SAMA5D3, SAMA5D4. Can refer as PMECC version. + */ + u32 version; }; /* For Error Location Configuration Register */ @@ -137,6 +151,12 @@ struct pmecc_errloc_regs { #define PMERRLOC_ERR_NUM_MASK (0x1f << 8) #define PMERRLOC_CALC_DONE (1 << 0) +/* PMECC IP version */ +#define PMECC_VERSION_SAMA5D4 0x113 +#define PMECC_VERSION_SAMA5D3 0x112 +#define PMECC_VERSION_AT91SAM9N12 0x102 +#define PMECC_VERSION_AT91SAM9X5 0x101 + /* Galois field dimension */ #define PMECC_GF_DIMENSION_13 13 #define PMECC_GF_DIMENSION_14 14 -- cgit From f5702d7d7fcb2c6668ebb131454bec8f4db82be5 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Mon, 19 Jan 2015 15:25:56 +0800 Subject: ARM: at91: mmc portA support is only for at91sam9g20ek_2mmc board Current the MMC support will enable MCI port A, Which is only exist for 2mmc board. So by default we need to disable MMC (port A) support. And only enable it for 2mmc board. Otherwise, dataflash won't work in at91sam9260ek board as MMC has confliction with Dataflash in the CLK pin. Signed-off-by: Josh Wu --- configs/at91sam9g20ek_2mmc_defconfig | 3 +++ configs/at91sam9g20ek_mmc_defconfig | 3 --- include/configs/at91sam9260ek.h | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 configs/at91sam9g20ek_2mmc_defconfig delete mode 100644 configs/at91sam9g20ek_mmc_defconfig diff --git a/configs/at91sam9g20ek_2mmc_defconfig b/configs/at91sam9g20ek_2mmc_defconfig new file mode 100644 index 0000000000..4eef04f179 --- /dev/null +++ b/configs/at91sam9g20ek_2mmc_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,AT91SAM9G20EK_2MMC,SYS_USE_MMC" +CONFIG_ARM=y +CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9g20ek_mmc_defconfig b/configs/at91sam9g20ek_mmc_defconfig deleted file mode 100644 index 8cca2e575e..0000000000 --- a/configs/at91sam9g20ek_mmc_defconfig +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_MMC" -CONFIG_ARM=y -CONFIG_TARGET_AT91SAM9260EK=y diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index a6a80de88a..c4b2e1666f 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -90,7 +90,6 @@ #define CONFIG_CMD_PING 1 #define CONFIG_CMD_DHCP 1 #define CONFIG_CMD_NAND 1 -#define CONFIG_CMD_MMC #define CONFIG_CMD_FAT #define CONFIG_CMD_USB 1 @@ -133,14 +132,17 @@ # define CONFIG_MACH_TYPE MACH_TYPE_AT91SAM9260EK #endif -/* DataFlash */ #ifndef CONFIG_AT91SAM9G20EK_2MMC +/* DataFlash */ #define CONFIG_ATMEL_DATAFLASH_SPI #define CONFIG_HAS_DATAFLASH 1 #define CONFIG_SYS_MAX_DATAFLASH_BANKS 2 #define CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 /* CS0 */ #define CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS1 0xD0000000 /* CS1 */ #define AT91_SPI_CLK 15000000 +#else +/* Enable MMC. The MCCK is conflicted with DataFlash */ +#define CONFIG_CMD_MMC #endif #ifdef CONFIG_AT91SAM9G20EK -- cgit From c3814406b064f1910461bddd14bc09701353ceed Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Tue, 20 Jan 2015 10:33:31 +0800 Subject: ARM: at91: sama5d3_xplained: save environment in a FAT file in MMC card This patch will save U-Boot environment as a file: uboot.env, in FAT partition instead of saving it in raw sector of MMC card. This make us easier to manage the environment file. Signed-off-by: Josh Wu Acked-by: Bo Shen --- include/configs/sama5d3_xplained.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/configs/sama5d3_xplained.h b/include/configs/sama5d3_xplained.h index 9458047c06..5a0ab284ab 100644 --- a/include/configs/sama5d3_xplained.h +++ b/include/configs/sama5d3_xplained.h @@ -169,13 +169,14 @@ "bootz 0x22000000 - 0x21000000" #elif CONFIG_SYS_USE_MMC /* bootstrap + u-boot + env in sd card */ -#define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET 0x2000 -#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_FAT +#define FAT_ENV_INTERFACE "mmc" +#define FAT_ENV_FILE "uboot.env" +#define FAT_ENV_DEVICE_AND_PART "0" +#define CONFIG_ENV_SIZE 0x4000 #define CONFIG_BOOTCOMMAND "fatload mmc 0:1 0x21000000 at91-sama5d3_xplained.dtb; " \ "fatload mmc 0:1 0x22000000 zImage; " \ "bootz 0x22000000 - 0x21000000" -#define CONFIG_SYS_MMC_ENV_DEV 0 #else #define CONFIG_ENV_IS_NOWHERE #endif -- cgit From a248558ae2894dd7a5a18480dd7011b70ed4bc50 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Tue, 20 Jan 2015 10:33:32 +0800 Subject: ARM: at91: sama5d3xek: save enviroment as a FAT file in MMC card This patch will save U-Boot environment as a file: uboot.env, in FAT partition instead of in raw sector of MMC card. This make us easier to manage the environment file. Signed-off-by: Josh Wu Acked-by: Bo Shen --- include/configs/sama5d3xek.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h index f2849d794e..cccc1edbb8 100644 --- a/include/configs/sama5d3xek.h +++ b/include/configs/sama5d3xek.h @@ -191,6 +191,7 @@ #if defined(CONFIG_CMD_USB) || defined(CONFIG_CMD_MMC) #define CONFIG_CMD_FAT +#define CONFIG_FAT_WRITE #endif #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ @@ -215,13 +216,14 @@ "bootm 0x22000000 - 0x21000000" #elif CONFIG_SYS_USE_MMC /* bootstrap + u-boot + env in sd card */ -#define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET 0x2000 -#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_FAT +#define FAT_ENV_INTERFACE "mmc" +#define FAT_ENV_FILE "uboot.env" +#define FAT_ENV_DEVICE_AND_PART "0" +#define CONFIG_ENV_SIZE 0x4000 #define CONFIG_BOOTCOMMAND "fatload mmc 0:1 0x21000000 dtb; " \ "fatload mmc 0:1 0x22000000 uImage; " \ "bootm 0x22000000 - 0x21000000" -#define CONFIG_SYS_MMC_ENV_DEV 0 #else #define CONFIG_ENV_IS_NOWHERE #endif -- cgit From 26961772ff2abd89dddf6232a458f8ff7d49c4f8 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Tue, 20 Jan 2015 10:33:33 +0800 Subject: ARM: at91: at91sam9x5: save environment to a FAT file in MMC card This patch will save U-Boot environment as a file: uboot.env, in FAT partition instead of saving it in raw sector of MMC card. This make us easier to manage the environment file. Signed-off-by: Josh Wu Acked-by: Bo Shen --- include/configs/at91sam9x5ek.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/configs/at91sam9x5ek.h b/include/configs/at91sam9x5ek.h index b1d4baaff9..6d8b71dced 100644 --- a/include/configs/at91sam9x5ek.h +++ b/include/configs/at91sam9x5ek.h @@ -203,11 +203,12 @@ "bootm 0x22000000" #else /* CONFIG_SYS_USE_MMC */ /* bootstrap + u-boot + env + linux in mmc */ -#define CONFIG_ENV_IS_IN_MMC -/* For FAT system, most cases it should be in the reserved sector */ -#define CONFIG_ENV_OFFSET 0x2000 -#define CONFIG_ENV_SIZE 0x1000 -#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_IS_IN_FAT +#define CONFIG_FAT_WRITE +#define FAT_ENV_INTERFACE "mmc" +#define FAT_ENV_FILE "uboot.env" +#define FAT_ENV_DEVICE_AND_PART "0" +#define CONFIG_ENV_SIZE 0x4000 #endif #ifdef CONFIG_SYS_USE_MMC -- cgit From 49b461f34a29fa88565c8cffa57a42a04ff36848 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 08:38:20 +0100 Subject: arm, at91, wdt: do not disable WDT in SPL if CONFIG_AT91SAM9_WATCHDOG is set, do not disable WDT in SPL Signed-off-by: Heiko Schocher --- arch/arm/cpu/at91-common/spl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/cpu/at91-common/spl.c b/arch/arm/cpu/at91-common/spl.c index 6473320097..aaa5eec2e6 100644 --- a/arch/arm/cpu/at91-common/spl.c +++ b/arch/arm/cpu/at91-common/spl.c @@ -12,12 +12,16 @@ #include #include +#if defined(CONFIG_AT91SAM9_WATCHDOG) +void at91_disable_wdt(void) { } +#else void at91_disable_wdt(void) { struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; writel(AT91_WDT_MR_WDDIS, &wdt->mr); } +#endif u32 spl_boot_device(void) { -- cgit From 2b8b38eacad9bd8dd0e30f324f2aa2b9d717e97a Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 08:38:21 +0100 Subject: common/board_f: add at91 wdt call hw_watchdog_init() also if CONFIG_AT91SAM9_WATCHDOG is used. Signed-off-by: Heiko Schocher Reviewed-by: Simon Glass --- common/board_f.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/board_f.c b/common/board_f.c index 79531377a7..6c44dee217 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -111,7 +111,7 @@ static int init_func_watchdog_init(void) { # if defined(CONFIG_HW_WATCHDOG) && (defined(CONFIG_BLACKFIN) || \ defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \ - defined(CONFIG_SH)) + defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG)) hw_watchdog_init(); # endif puts(" Watchdog enabled\n"); -- cgit From 7bae0d6f62723bdfba50ffbd7491ebd282573c0a Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 08:38:22 +0100 Subject: arm, at91, wdt: make timeout configurable make the HW WDT timeout configurable through the define CONFIG_AT91_HW_WDT_TIMEOUT. Signed-off-by: Heiko Schocher --- README | 3 +++ drivers/watchdog/at91sam9_wdt.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/README b/README index a28ff133ee..ba57dc5617 100644 --- a/README +++ b/README @@ -1257,6 +1257,9 @@ The following options need to be configured: SoC, then define this variable and provide board specific code for the "hw_watchdog_reset" function. + CONFIG_AT91_HW_WDT_TIMEOUT + specify the timeout in seconds. default 2 seconds. + - U-Boot Version: CONFIG_VERSION_VARIABLE If this variable is defined, an environment variable diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index ffd49a2bef..03c786c53b 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -30,7 +30,11 @@ #define ticks_to_ms(t) (((t + 1) * 1000) >> 8) /* Hardware timeout in seconds */ +#if !defined(CONFIG_AT91_HW_WDT_TIMEOUT) #define WDT_HW_TIMEOUT 2 +#else +#define WDT_HW_TIMEOUT CONFIG_AT91_HW_WDT_TIMEOUT +#endif /* * Set the watchdog time interval in 1/256Hz (write-once) -- cgit From f624162f954b2f8ed31b8f00b548b89e23f5d1bb Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 08:38:23 +0100 Subject: arm, at91, taurus: enable WDT enable WDT for the taurus board. Signed-off-by: Heiko Schocher --- include/configs/taurus.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/configs/taurus.h b/include/configs/taurus.h index 65468ad165..b61dc2d115 100644 --- a/include/configs/taurus.h +++ b/include/configs/taurus.h @@ -121,6 +121,12 @@ #define CONFIG_RMII #define CONFIG_AT91_WANTS_COMMON_PHY +#define CONFIG_AT91SAM9_WATCHDOG +#if !defined(CONFIG_SPL_BUILD) +/* Enable the watchdog */ +#define CONFIG_HW_WATCHDOG +#endif + /* USB */ #if defined(CONFIG_BOARD_TAURUS) #define CONFIG_USB_ATMEL -- cgit From f4e1886df5690a98419d04aaaa77b3027c60c901 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 08:42:53 +0100 Subject: arm, at91: add reset controller status register add reset controller status register Signed-off-by: Heiko Schocher Acked-by: Bo Shen --- arch/arm/include/asm/arch-at91/at91_rstc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/include/asm/arch-at91/at91_rstc.h b/arch/arm/include/asm/arch-at91/at91_rstc.h index a9423428e7..e4eb3da03f 100644 --- a/arch/arm/include/asm/arch-at91/at91_rstc.h +++ b/arch/arm/include/asm/arch-at91/at91_rstc.h @@ -13,6 +13,8 @@ #ifndef AT91_RSTC_H #define AT91_RSTC_H +/* Reset Controller Status Register */ +#define AT91_ASM_RSTC_SR (ATMEL_BASE_RSTC + 0x04) #define AT91_ASM_RSTC_MR (ATMEL_BASE_RSTC + 0x08) #ifndef __ASSEMBLY__ -- cgit From 657006a1c46f11784757f9437ffaaa5e0c4dea72 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 21 Jan 2015 09:22:20 +0100 Subject: arm, at91: taurus remove MACH_TYPE definitions in config file remove MACH_TYPE definitions in config file, as they come from the defconfig. Signed-off-by: Heiko Schocher --- include/configs/taurus.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/taurus.h b/include/configs/taurus.h index b61dc2d115..2cf4558daa 100644 --- a/include/configs/taurus.h +++ b/include/configs/taurus.h @@ -21,9 +21,6 @@ */ #include -#define MACH_TYPE_TAURUS 2067 -#define MACH_TYPE_AXM 2068 - #define CONFIG_SYS_GENERIC_BOARD #if defined(CONFIG_SPL_BUILD) -- cgit From f958a91fa5cefd0cda76c887ee0488fb9158496e Mon Sep 17 00:00:00 2001 From: Igor Guryanov Date: Tue, 3 Feb 2015 13:58:09 +0300 Subject: arc: memcmp - fix zero-delay loop utilization It's prohibited to put branch instruction in the very end of zero-delay loop. On execution this causes "Illegal instruction" exception. Signed-off-by: Alexey Brodkin Signed-off-by: Igor Guryanov --- arch/arc/lib/memcmp.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S index fa5aac5f67..87bccab51d 100644 --- a/arch/arc/lib/memcmp.S +++ b/arch/arc/lib/memcmp.S @@ -29,6 +29,7 @@ memcmp: ld.a %r4, [%r0, 8] ld.a %r5, [%r1, 8] brne WORD2, %r12, .Lodd + nop .Loop_end: asl_s SHIFT, SHIFT, 3 bhs_s .Last_cmp @@ -105,6 +106,7 @@ memcmp: ldb.a %r4, [%r0, 2] ldb.a %r5, [%r1, 2] brne %r3, %r12, .Lbyte_odd + nop .Lbyte_end: bcc .Lbyte_even brne %r4, %r5, .Lbyte_even -- cgit From 832325c18d1d68e0ee46810f788421865f6372d9 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:10 +0300 Subject: arc: remove CPU hard-coded selection from board description in include/configs With switch to Kconfig we only need very board-specific descriptions in include/configs. CPU selection is performed with either defconfig or manually via menuconfig. Signed-off-by: Alexey Brodkin --- include/configs/arcangel4-be.h | 1 - include/configs/arcangel4.h | 1 - include/configs/axs101.h | 1 - include/configs/tb100.h | 1 - 4 files changed, 4 deletions(-) diff --git a/include/configs/arcangel4-be.h b/include/configs/arcangel4-be.h index 76163ab2a0..2ca209e1e4 100644 --- a/include/configs/arcangel4-be.h +++ b/include/configs/arcangel4-be.h @@ -11,7 +11,6 @@ * CPU configuration */ #define CONFIG_SYS_BIG_ENDIAN -#define CONFIG_ARC700 #define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 81934a45a8..2afb63d80d 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -10,7 +10,6 @@ /* * CPU configuration */ -#define CONFIG_ARC700 #define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/axs101.h b/include/configs/axs101.h index c61ddd6fb7..a8a9cb3cba 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -10,7 +10,6 @@ /* * CPU configuration */ -#define CONFIG_ARC700 #define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/tb100.h b/include/configs/tb100.h index e9218f7d81..a59834383a 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -12,7 +12,6 @@ /* * CPU configuration */ -#define CONFIG_ARC700 #define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -- cgit From 812980bdd6c9112014f3946d1cb2728a2121ba34 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:11 +0300 Subject: arc: add more flavours of ARC700 series CPU Now we may select a particular version of ARC700: * ARC750D or * ARC770D It allows more flexible (or more fine tuned) configuration of U-Boot. Before that change we relied on minimal configuration but now we may use specific features of each CPU. Moreover allows us to escape manual selection of options that exist in both CPUs but may have say different version like MMUv2 in ARC750D vs MMUv3 in ARC770D. Signed-off-by: Alexey Brodkin --- arch/arc/Kconfig | 40 ++++++++++++++++++++++++++++++++++++++++ arch/arc/config.mk | 4 ++++ arch/arc/include/asm/arcregs.h | 2 ++ arch/arc/include/asm/cache.h | 6 ++++++ include/configs/arcangel4-be.h | 1 - include/configs/arcangel4.h | 1 - include/configs/axs101.h | 1 - include/configs/tb100.h | 1 - 8 files changed, 52 insertions(+), 4 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index c6b1efeb8b..f7d2964144 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -7,6 +7,46 @@ config SYS_ARCH config SYS_CPU default "arcv1" +choice + prompt "CPU selection" + default CPU_ARC770D + +config CPU_ARC750D + bool "ARC 750D" + select ARC_MMU_V2 + help + Choose this option to build an U-Boot for ARC750D CPU. + +config CPU_ARC770D + bool "ARC 770D" + select ARC_MMU_V3 + help + Choose this option to build an U-Boot for ARC770D CPU. + +endchoice + +choice + prompt "MMU Version" + default ARC_MMU_V3 if CPU_ARC770D + default ARC_MMU_V2 if CPU_ARC750D + +config ARC_MMU_V2 + bool "MMU v2" + depends on CPU_ARC750D + help + Fixed the deficiency of v1 - possible thrashing in memcpy sceanrio + when 2 D-TLB and 1 I-TLB entries index into same 2way set. + +config ARC_MMU_V3 + bool "MMU v3" + depends on CPU_ARC770D + help + Introduced with ARC700 4.10: New Features + Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) + Shared Address Spaces (SASID) + +endchoice + choice prompt "Target select" diff --git a/arch/arc/config.mk b/arch/arc/config.mk index 5321987a56..dd180ef187 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -25,6 +25,10 @@ ifdef CONFIG_ARC_MMU_VER CONFIG_MMU = 1 endif +ifdef CONFIG_CPU_ARC770D +PLATFORM_CPPFLAGS += -mlock -mswape +endif + PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 # Needed for relocation diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 8ace87fa0f..31627e65b9 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -7,6 +7,8 @@ #ifndef _ASM_ARC_ARCREGS_H #define _ASM_ARC_ARCREGS_H +#include + /* * ARC architecture has additional address space - auxiliary registers. * These registers are mostly used for configuration purposes. diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 16e7568ef0..368d1f016e 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -20,4 +20,10 @@ #define ARCH_DMA_MINALIGN 128 #endif +#if defined(CONFIG_ARC_MMU_V2) +#define CONFIG_ARC_MMU_VER 2 +#elif defined(CONFIG_ARC_MMU_V3) +#define CONFIG_ARC_MMU_VER 3 +#endif + #endif /* __ASM_ARC_CACHE_H */ diff --git a/include/configs/arcangel4-be.h b/include/configs/arcangel4-be.h index 2ca209e1e4..a43590bef5 100644 --- a/include/configs/arcangel4-be.h +++ b/include/configs/arcangel4-be.h @@ -11,7 +11,6 @@ * CPU configuration */ #define CONFIG_SYS_BIG_ENDIAN -#define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 2afb63d80d..565f70e165 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -10,7 +10,6 @@ /* * CPU configuration */ -#define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/axs101.h b/include/configs/axs101.h index a8a9cb3cba..b94687c230 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -10,7 +10,6 @@ /* * CPU configuration */ -#define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ diff --git a/include/configs/tb100.h b/include/configs/tb100.h index a59834383a..f3539506c2 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -12,7 +12,6 @@ /* * CPU configuration */ -#define CONFIG_ARC_MMU_VER 3 #define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -- cgit From 5ff40f3d4226d45c78f3bb9db276f6685b24a89a Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:12 +0300 Subject: arc: define and use PTAG AUX regs for MMUv3 only DC_PTAG and IC_PTAG registers only exist in MMUv3. Signed-off-by: Alexey Brodkin --- arch/arc/include/asm/arcregs.h | 4 ++-- arch/arc/lib/cache.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 31627e65b9..6a36a81c0f 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -23,7 +23,7 @@ #define ARC_AUX_IC_IVIC 0x10 #define ARC_AUX_IC_CTRL 0x11 #define ARC_AUX_IC_IVIL 0x19 -#if (CONFIG_ARC_MMU_VER > 2) +#if (CONFIG_ARC_MMU_VER == 3) #define ARC_AUX_IC_PTAG 0x1E #endif #define ARC_BCR_IC_BUILD 0x77 @@ -42,7 +42,7 @@ #define ARC_AUX_DC_IVDL 0x4A #define ARC_AUX_DC_FLSH 0x4B #define ARC_AUX_DC_FLDL 0x4C -#if (CONFIG_ARC_MMU_VER > 2) +#if (CONFIG_ARC_MMU_VER == 3) #define ARC_AUX_DC_PTAG 0x5C #endif #define ARC_BCR_DC_BUILD 0x72 diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index fa19a13b7e..fa2a1e77a2 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -101,7 +101,7 @@ void flush_dcache_all(void) #ifndef CONFIG_SYS_DCACHE_OFF static void dcache_flush_line(unsigned addr) { -#if (CONFIG_ARC_MMU_VER > 2) +#if (CONFIG_ARC_MMU_VER == 3) write_aux_reg(ARC_AUX_DC_PTAG, addr); #endif write_aux_reg(ARC_AUX_DC_FLDL, addr); @@ -115,7 +115,7 @@ static void dcache_flush_line(unsigned addr) * Invalidate I$ for addresses range just flushed from D$. * If we try to execute data flushed above it will be valid/correct */ -#if (CONFIG_ARC_MMU_VER > 2) +#if (CONFIG_ARC_MMU_VER == 3) write_aux_reg(ARC_AUX_IC_PTAG, addr); #endif write_aux_reg(ARC_AUX_IC_IVIL, addr); @@ -145,7 +145,7 @@ void invalidate_dcache_range(unsigned long start, unsigned long end) end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { -#if (CONFIG_ARC_MMU_VER > 2) +#if (CONFIG_ARC_MMU_VER == 3) write_aux_reg(ARC_AUX_DC_PTAG, addr); #endif write_aux_reg(ARC_AUX_DC_IVDL, addr); -- cgit From 205e7a7b77726abeff57576e2ecf2c6d4dc07ccf Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:13 +0300 Subject: arc: select cache settings via menuconfig This change allows to keep board description clean and minimalistic. This is especially helpful if one board may house different CPUs with different features. It is applicable to both FPGA-based boards or those that have CPUs mounted on interchnagable daughter-boards. Signed-off-by: Alexey Brodkin --- arch/arc/Kconfig | 19 +++++++++++++++++++ arch/arc/include/asm/cache.h | 13 +++++-------- arch/arc/lib/cache.c | 1 + configs/axs101_defconfig | 4 +++- configs/tb100_defconfig | 3 ++- include/configs/arcangel4-be.h | 1 - include/configs/arcangel4.h | 1 - include/configs/axs101.h | 4 ---- include/configs/tb100.h | 1 - 9 files changed, 30 insertions(+), 17 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index f7d2964144..397b179198 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -47,6 +47,25 @@ config ARC_MMU_V3 endchoice +config SYS_ICACHE_OFF + bool "Do not use Instruction Cache" + default n + +config SYS_DCACHE_OFF + bool "Do not use Data Cache" + default n + +config ARC_CACHE_LINE_SHIFT + int "Cache Line Length (as power of 2)" + range 5 7 + default "6" + depends on !SYS_DCACHE_OFF || !SYS_DCACHE_OFF + help + Starting with ARC700 4.9, Cache line length is configurable, + This option specifies "N", with Line-len = 2 power N + So line lengths of 32, 64, 128 are specified by 5,6,7, respectively + Linux only supports same line lengths for I and D caches. + choice prompt "Target select" diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 368d1f016e..2725961221 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -9,15 +9,12 @@ #include -/* - * The current upper bound for ARC L1 data cache line sizes is 128 bytes. - * We use that value for aligning DMA buffers unless the board config has - * specified an alternate cache line size. - */ -#ifdef CONFIG_SYS_CACHELINE_SIZE -#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#ifdef CONFIG_ARC_CACHE_LINE_SHIFT +#define CONFIG_SYS_CACHELINE_SIZE (1 << CONFIG_ARC_CACHE_LINE_SHIFT) +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE #else -#define ARCH_DMA_MINALIGN 128 +/* Satisfy users of ARCH_DMA_MINALIGN */ +#define ARCH_DMA_MINALIGN 128 #endif #if defined(CONFIG_ARC_MMU_V2) diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index fa2a1e77a2..a2277231ba 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -6,6 +6,7 @@ #include #include +#include /* Bit values in IC_CTRL */ #define IC_CTRL_CACHE_DISABLE (1 << 0) diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index 5c0ca11fa5..d165e411ca 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -1,3 +1,5 @@ CONFIG_ARC=y CONFIG_TARGET_AXS101=y -CONFIG_SYS_CLK_FREQ=750000000 \ No newline at end of file +CONFIG_SYS_CLK_FREQ=750000000 +CONFIG_ARC_CACHE_LINE_SHIFT=5 +CONFIG_SYS_DCACHE_OFF=y \ No newline at end of file diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig index d2de03b649..e17a4958f5 100644 --- a/configs/tb100_defconfig +++ b/configs/tb100_defconfig @@ -1,3 +1,4 @@ CONFIG_ARC=y CONFIG_TARGET_TB100=y -CONFIG_SYS_CLK_FREQ=500000000 \ No newline at end of file +CONFIG_SYS_CLK_FREQ=500000000 +CONFIG_ARC_CACHE_LINE_SHIFT=5 diff --git a/include/configs/arcangel4-be.h b/include/configs/arcangel4-be.h index a43590bef5..b0bc8bc081 100644 --- a/include/configs/arcangel4-be.h +++ b/include/configs/arcangel4-be.h @@ -11,7 +11,6 @@ * CPU configuration */ #define CONFIG_SYS_BIG_ENDIAN -#define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ /* diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 565f70e165..3268c56f7d 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -10,7 +10,6 @@ /* * CPU configuration */ -#define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ /* diff --git a/include/configs/axs101.h b/include/configs/axs101.h index b94687c230..ff3fad312e 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -10,12 +10,8 @@ /* * CPU configuration */ -#define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -/* NAND controller DMA doesn't work correctly with D$ enabled */ -#define CONFIG_SYS_DCACHE_OFF - /* * Board configuration */ diff --git a/include/configs/tb100.h b/include/configs/tb100.h index f3539506c2..32675c43d4 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -12,7 +12,6 @@ /* * CPU configuration */ -#define CONFIG_SYS_CACHELINE_SIZE 32 #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ /* -- cgit From 1f9ad44546ea872fc6671602eb411377dd424c9e Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:14 +0300 Subject: arc: add selection of endianess in Kconfig This change allows to keep board description clean and minimalistic. This is especially helpful if one board may house different CPUs with different features. It is applicable to both FPGA-based boards or those that have CPUs mounted on interchnagable daughter-boards. Signed-off-by: Alexey Brodkin --- arch/arc/Kconfig | 9 +++-- arch/arc/config.mk | 4 +- board/synopsys/Kconfig | 10 ----- board/synopsys/MAINTAINERS | 1 - configs/arcangel4-be_defconfig | 3 +- include/configs/arcangel4-be.h | 88 ------------------------------------------ 6 files changed, 11 insertions(+), 104 deletions(-) delete mode 100644 include/configs/arcangel4-be.h diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 397b179198..04fc7b6ab2 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -47,6 +47,12 @@ config ARC_MMU_V3 endchoice +config CPU_BIG_ENDIAN + bool "Enable Big Endian Mode" + default n + help + Build kernel for Big Endian Mode of ARC CPU + config SYS_ICACHE_OFF bool "Do not use Instruction Cache" default n @@ -75,9 +81,6 @@ config TARGET_TB100 config TARGET_ARCANGEL4 bool "Support arcangel4" -config TARGET_ARCANGEL4_BE - bool "Support arcangel4-be" - config TARGET_AXS101 bool "Support axs101" diff --git a/arch/arc/config.mk b/arch/arc/config.mk index dd180ef187..4f2d31feb3 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -4,8 +4,10 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifndef CONFIG_SYS_BIG_ENDIAN +ifndef CONFIG_CPU_BIG_ENDIAN CONFIG_SYS_LITTLE_ENDIAN = 1 +else +CONFIG_SYS_BIG_ENDIAN = 1 endif ifdef CONFIG_SYS_LITTLE_ENDIAN diff --git a/board/synopsys/Kconfig b/board/synopsys/Kconfig index f614f88cc6..8ab48cd91c 100644 --- a/board/synopsys/Kconfig +++ b/board/synopsys/Kconfig @@ -7,13 +7,3 @@ config SYS_CONFIG_NAME default "arcangel4" endif - -if TARGET_ARCANGEL4_BE - -config SYS_VENDOR - default "synopsys" - -config SYS_CONFIG_NAME - default "arcangel4-be" - -endif diff --git a/board/synopsys/MAINTAINERS b/board/synopsys/MAINTAINERS index 720edd8893..43114cea5e 100644 --- a/board/synopsys/MAINTAINERS +++ b/board/synopsys/MAINTAINERS @@ -3,5 +3,4 @@ M: Alexey Brodkin S: Maintained F: include/configs/arcangel4.h F: configs/arcangel4_defconfig -F: include/configs/arcangel4-be.h F: configs/arcangel4-be_defconfig diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig index 0c3ab4e4fc..5d2e126e2e 100644 --- a/configs/arcangel4-be_defconfig +++ b/configs/arcangel4-be_defconfig @@ -1,3 +1,4 @@ CONFIG_ARC=y -CONFIG_TARGET_ARCANGEL4_BE=y +CONFIG_TARGET_ARCANGEL4=y CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_CPU_BIG_ENDIAN=y diff --git a/include/configs/arcangel4-be.h b/include/configs/arcangel4-be.h deleted file mode 100644 index b0bc8bc081..0000000000 --- a/include/configs/arcangel4-be.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _CONFIG_ARCANGEL4_H_ -#define _CONFIG_ARCANGEL4_H_ - -/* - * CPU configuration - */ -#define CONFIG_SYS_BIG_ENDIAN -#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ - -/* - * Board configuration - */ -#define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ - -#define CONFIG_ARCH_EARLY_INIT_R - -/* - * Memory configuration - */ -#define CONFIG_SYS_TEXT_BASE 0x81000000 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE - -#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 -#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE -#define CONFIG_SYS_SDRAM_SIZE 0x10000000 /* 256 Mb */ - -#define CONFIG_SYS_INIT_SP_ADDR \ - (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) - -#define CONFIG_SYS_MALLOC_LEN 0x200000 /* 2 MB */ -#define CONFIG_SYS_BOOTM_LEN 0x2000000 /* 32 MB */ -#define CONFIG_SYS_LOAD_ADDR 0x82000000 - -#define CONFIG_SYS_NO_FLASH - -/* - * UART configuration - * - */ -#define CONFIG_ARC_SERIAL -#define CONFIG_ARC_UART_BASE 0xC0FC1000 -#define CONFIG_BAUDRATE 115200 - -/* - * Command line configuration - */ -#include - -#define CONFIG_CMD_ELF - -#define CONFIG_OF_LIBFDT - -#define CONFIG_AUTO_COMPLETE -#define CONFIG_SYS_MAXARGS 16 - -/* - * Environment settings - */ -#define CONFIG_ENV_IS_NOWHERE -#define CONFIG_ENV_SIZE 0x00200 /* 512 bytes */ -#define CONFIG_ENV_OFFSET 0 - -/* - * Environment configuration - */ -#define CONFIG_BOOTDELAY 3 -#define CONFIG_BOOTFILE "uImage" -#define CONFIG_BOOTARGS "console=ttyARC0,115200n8" -#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR - -/* - * Console configuration - */ -#define CONFIG_SYS_LONGHELP -#define CONFIG_SYS_PROMPT "arcangel4# " -#define CONFIG_SYS_CBSIZE 256 -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ - sizeof(CONFIG_SYS_PROMPT) + 16) - -#endif /* _CONFIG_ARCANGEL4_H_ */ -- cgit From 6eb651ad29636682067f76de4f40c45119269f8b Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:15 +0300 Subject: arc: hard-code CONFIG_SYS_GENERIC_BOARD into asm/config.h There're no other options for ARC except "generic board" so ther's no point to define CONFIG_SYS_GENERIC_BOARD per board. We now have it set fo all ARC boards. Signed-off-by: Alexey Brodkin --- arch/arc/include/asm/config.h | 1 + include/configs/arcangel4.h | 1 - include/configs/axs101.h | 1 - include/configs/tb100.h | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h index e5be078c19..c1e9b44239 100644 --- a/arch/arc/include/asm/config.h +++ b/arch/arc/include/asm/config.h @@ -7,6 +7,7 @@ #ifndef __ASM_ARC_CONFIG_H_ #define __ASM_ARC_CONFIG_H_ +#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_GENERIC_GLOBAL_DATA #define CONFIG_SYS_BOOT_RAMDISK_HIGH diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 3268c56f7d..60f30777dc 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -15,7 +15,6 @@ /* * Board configuration */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ #define CONFIG_ARCH_EARLY_INIT_R diff --git a/include/configs/axs101.h b/include/configs/axs101.h index ff3fad312e..2340d99346 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -15,7 +15,6 @@ /* * Board configuration */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ #define CONFIG_ARCH_EARLY_INIT_R diff --git a/include/configs/tb100.h b/include/configs/tb100.h index 32675c43d4..c6878fc08e 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -17,7 +17,6 @@ /* * Board configuration */ -#define CONFIG_SYS_GENERIC_BOARD #define CONFIG_ARCH_EARLY_INIT_R /* -- cgit From bcba9742ce39e96b36b8dfc96066ee3a71561bab Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:16 +0300 Subject: arc: get rid of useless CONFIG_SKIP_LOWLEVEL_INIT Currently there's nothing related to really low-level init on ARC so CONFIG_SKIP_LOWLEVEL_INIT definition makes no sense. Signed-off-by: Alexey Brodkin --- include/configs/arcangel4.h | 2 -- include/configs/axs101.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 60f30777dc..003a45d96d 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -15,8 +15,6 @@ /* * Board configuration */ -#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ - #define CONFIG_ARCH_EARLY_INIT_R /* diff --git a/include/configs/axs101.h b/include/configs/axs101.h index 2340d99346..4064ed2331 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -15,8 +15,6 @@ /* * Board configuration */ -#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is in RAM already */ - #define CONFIG_ARCH_EARLY_INIT_R #define ARC_FPGA_PERIPHERAL_BASE 0xE0000000 -- cgit From a1dbe57d2d45d311e402c357831bbf5c5157a32c Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:17 +0300 Subject: arc: hard-code CONFIG_ARCH_EARLY_INIT_R in asm/config.h Common arch_early_init_r() is used in "arc/lib/cpu.c" for all ARC boards so there's no sense in separate per-board definitions. Signed-off-by: Alexey Brodkin --- arch/arc/include/asm/config.h | 1 + include/configs/arcangel4.h | 5 ----- include/configs/axs101.h | 5 ----- include/configs/tb100.h | 5 ----- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/arch/arc/include/asm/config.h b/arch/arc/include/asm/config.h index c1e9b44239..b4e9099fb1 100644 --- a/arch/arc/include/asm/config.h +++ b/arch/arc/include/asm/config.h @@ -10,6 +10,7 @@ #define CONFIG_SYS_GENERIC_BOARD #define CONFIG_SYS_GENERIC_GLOBAL_DATA #define CONFIG_SYS_BOOT_RAMDISK_HIGH +#define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_LMB diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 003a45d96d..80d6438ba1 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -12,11 +12,6 @@ */ #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -/* - * Board configuration - */ -#define CONFIG_ARCH_EARLY_INIT_R - /* * Memory configuration */ diff --git a/include/configs/axs101.h b/include/configs/axs101.h index 4064ed2331..e9a32314fd 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -12,11 +12,6 @@ */ #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -/* - * Board configuration - */ -#define CONFIG_ARCH_EARLY_INIT_R - #define ARC_FPGA_PERIPHERAL_BASE 0xE0000000 #define ARC_APB_PERIPHERAL_BASE 0xF0000000 #define ARC_DWMMC_BASE (ARC_FPGA_PERIPHERAL_BASE + 0x15000) diff --git a/include/configs/tb100.h b/include/configs/tb100.h index c6878fc08e..54eca6f574 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -14,11 +14,6 @@ */ #define CONFIG_SYS_TIMER_RATE CONFIG_SYS_CLK_FREQ -/* - * Board configuration - */ -#define CONFIG_ARCH_EARLY_INIT_R - /* * Memory configuration */ -- cgit From 836d2cc2eef58c0d42d3112725dac475d0bd553e Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:18 +0300 Subject: arc: move SYS_MONITOR_BASE setup in Konfig Following SPARK ARC now has SYS_MONITOR_BASE setup via Kconfig. This makes "include/configs/*.h" cleaner and more flexible. Signed-off-by: Alexey Brodkin --- Kconfig | 2 +- configs/arcangel4-be_defconfig | 1 + configs/arcangel4_defconfig | 1 + configs/axs101_defconfig | 3 ++- configs/tb100_defconfig | 1 + include/configs/arcangel4.h | 1 - include/configs/axs101.h | 1 - include/configs/tb100.h | 1 - 8 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Kconfig b/Kconfig index fed488fdaf..9af31e3e77 100644 --- a/Kconfig +++ b/Kconfig @@ -139,7 +139,7 @@ config SYS_EXTRA_OPTIONS new boards should not use this option. config SYS_TEXT_BASE - depends on SPARC + depends on SPARC || ARC hex "Text Base" help TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig index 5d2e126e2e..979f26e6dc 100644 --- a/configs/arcangel4-be_defconfig +++ b/configs/arcangel4-be_defconfig @@ -2,3 +2,4 @@ CONFIG_ARC=y CONFIG_TARGET_ARCANGEL4=y CONFIG_SYS_CLK_FREQ=70000000 CONFIG_CPU_BIG_ENDIAN=y +CONFIG_SYS_TEXT_BASE=0x81000000 diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig index a63ef21de8..797595f2c3 100644 --- a/configs/arcangel4_defconfig +++ b/configs/arcangel4_defconfig @@ -1,3 +1,4 @@ CONFIG_ARC=y CONFIG_TARGET_ARCANGEL4=y CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_SYS_TEXT_BASE=0x81000000 diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index d165e411ca..34ed9633a1 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -2,4 +2,5 @@ CONFIG_ARC=y CONFIG_TARGET_AXS101=y CONFIG_SYS_CLK_FREQ=750000000 CONFIG_ARC_CACHE_LINE_SHIFT=5 -CONFIG_SYS_DCACHE_OFF=y \ No newline at end of file +CONFIG_SYS_DCACHE_OFF=y +CONFIG_SYS_TEXT_BASE=0x81000000 \ No newline at end of file diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig index e17a4958f5..b0e8c9f602 100644 --- a/configs/tb100_defconfig +++ b/configs/tb100_defconfig @@ -2,3 +2,4 @@ CONFIG_ARC=y CONFIG_TARGET_TB100=y CONFIG_SYS_CLK_FREQ=500000000 CONFIG_ARC_CACHE_LINE_SHIFT=5 +CONFIG_SYS_TEXT_BASE=0x84000000 diff --git a/include/configs/arcangel4.h b/include/configs/arcangel4.h index 80d6438ba1..5e4097fb82 100644 --- a/include/configs/arcangel4.h +++ b/include/configs/arcangel4.h @@ -15,7 +15,6 @@ /* * Memory configuration */ -#define CONFIG_SYS_TEXT_BASE 0x81000000 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 diff --git a/include/configs/axs101.h b/include/configs/axs101.h index e9a32314fd..5fb8aca4bc 100644 --- a/include/configs/axs101.h +++ b/include/configs/axs101.h @@ -20,7 +20,6 @@ /* * Memory configuration */ -#define CONFIG_SYS_TEXT_BASE 0x81000000 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 diff --git a/include/configs/tb100.h b/include/configs/tb100.h index 54eca6f574..46df40661d 100644 --- a/include/configs/tb100.h +++ b/include/configs/tb100.h @@ -17,7 +17,6 @@ /* * Memory configuration */ -#define CONFIG_SYS_TEXT_BASE 0x84000000 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000 -- cgit From 51f4999bc5ad5f8430da0297d12c1abef9c05568 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:19 +0300 Subject: arc: move CPU flags selection to the main "config.mk" As a preparation to ARCv2 port submission we're moving CPU slection flags to a common location. Also it will allow us to have more flexible CPU specification, not only ISA version but CPU family as well checking CONFIG_ARC_CPU_xxx. Signed-off-by: Alexey Brodkin --- arch/arc/config.mk | 6 +++++- arch/arc/cpu/arcv1/config.mk | 7 ------- 2 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 arch/arc/cpu/arcv1/config.mk diff --git a/arch/arc/config.mk b/arch/arc/config.mk index 4f2d31feb3..3e75e606b3 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -27,8 +27,12 @@ ifdef CONFIG_ARC_MMU_VER CONFIG_MMU = 1 endif +ifdef CONFIG_CPU_ARC750D +PLATFORM_CPPFLAGS += -marc700 +endif + ifdef CONFIG_CPU_ARC770D -PLATFORM_CPPFLAGS += -mlock -mswape +PLATFORM_CPPFLAGS += -marc700 -mlock -mswape endif PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 diff --git a/arch/arc/cpu/arcv1/config.mk b/arch/arc/cpu/arcv1/config.mk deleted file mode 100644 index 3206ff47e3..0000000000 --- a/arch/arc/cpu/arcv1/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -PLATFORM_CPPFLAGS += -mA7 -- cgit From a67ef280f46803e319639f5380ff8da6c6b7fbe7 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 3 Feb 2015 13:58:20 +0300 Subject: arc: build libgcc in U-Boot This way we may have very limited set of functions implemented so we save some space. Also it allows us to build U-Boot for any ARC core with the same one toolchain because we don't rely on pre-built libgcc. For example: * we may use little-endian toolchain but build U-Boot for ether endianess * we may use non-multilibbed uClibc toolchain but build U-Boot for whatever ARC CPU flavour that current GCC supports Private libgcc built from generic C implementation contributes only 144 bytes to .text section so we don't see significant degradation of size: --->8--- $ arc-linux-size u-boot.libgcc-prebuilt text data bss dec hex filename 222217 24912 214820 461949 70c7d u-boot.libgcc-prebuilt $ arc-linux-size u-boot.libgcc-private text data bss dec hex filename 222361 24912 214820 462093 70d0d u-boot.libgcc-private --->8--- Also I don't notice visible performance degradation compared to pre-built libgcc (where at least "*div*" functions are had-written in assembly) on typical operations of downloading 10Mb uImage over TFTP and bootm. Signed-off-by: Alexey Brodkin --- arch/Kconfig | 1 + arch/arc/Kconfig | 3 + arch/arc/config.mk | 3 + arch/arc/lib/Makefile | 2 + arch/arc/lib/_millicodethunk.S | 226 +++++++++++++++++++++++++++++++++++++++++ arch/arc/lib/libgcc2.c | 161 +++++++++++++++++++++++++++++ arch/arc/lib/libgcc2.h | 132 ++++++++++++++++++++++++ 7 files changed, 528 insertions(+) create mode 100644 arch/arc/lib/_millicodethunk.S create mode 100644 arch/arc/lib/libgcc2.c create mode 100644 arch/arc/lib/libgcc2.h diff --git a/arch/Kconfig b/arch/Kconfig index f63cc5a7e9..132123bcaf 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -4,6 +4,7 @@ choice config ARC bool "ARC architecture" + select HAVE_PRIVATE_LIBGCC config ARM bool "ARM architecture" diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 04fc7b6ab2..a8dc4e2336 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -4,6 +4,9 @@ menu "ARC architecture" config SYS_ARCH default "arc" +config USE_PRIVATE_LIBGCC + default y + config SYS_CPU default "arcv1" diff --git a/arch/arc/config.mk b/arch/arc/config.mk index 3e75e606b3..f1e81b6895 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -12,11 +12,14 @@ endif ifdef CONFIG_SYS_LITTLE_ENDIAN ARC_CROSS_COMPILE := arc-buildroot-linux-uclibc- +PLATFORM_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -mlittle-endian endif ifdef CONFIG_SYS_BIG_ENDIAN ARC_CROSS_COMPILE := arceb-buildroot-linux-uclibc- PLATFORM_LDFLAGS += -EB +PLATFORM_CPPFLAGS += -mbig-endian endif ifeq ($(CROSS_COMPILE),) diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile index bae44199a4..b8028c91e1 100644 --- a/arch/arc/lib/Makefile +++ b/arch/arc/lib/Makefile @@ -20,3 +20,5 @@ obj-y += reset.o obj-y += timer.o obj-$(CONFIG_CMD_BOOTM) += bootm.o + +lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _millicodethunk.o libgcc2.o diff --git a/arch/arc/lib/_millicodethunk.S b/arch/arc/lib/_millicodethunk.S new file mode 100644 index 0000000000..b3324167d4 --- /dev/null +++ b/arch/arc/lib/_millicodethunk.S @@ -0,0 +1,226 @@ +/* + * Copyright (C) 1995, 1997, 2007-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /* ANSI concatenation macros. */ + + #define CONCAT1(a, b) CONCAT2(a, b) + #define CONCAT2(a, b) a ## b + + /* Use the right prefix for global labels. */ + + #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +#ifndef WORKING_ASSEMBLER +#define abs_l abs +#define asl_l asl +#define mov_l mov +#endif + +#define FUNC(X) .type SYM(X),@function +#define HIDDEN_FUNC(X) FUNC(X)` .hidden X +#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X +#define ENDFUNC(X) ENDFUNC0(X) + + .section .text + .align 4 + .global SYM(__st_r13_to_r15) + .global SYM(__st_r13_to_r16) + .global SYM(__st_r13_to_r17) + .global SYM(__st_r13_to_r18) + .global SYM(__st_r13_to_r19) + .global SYM(__st_r13_to_r20) + .global SYM(__st_r13_to_r21) + .global SYM(__st_r13_to_r22) + .global SYM(__st_r13_to_r23) + .global SYM(__st_r13_to_r24) + .global SYM(__st_r13_to_r25) + HIDDEN_FUNC(__st_r13_to_r15) + HIDDEN_FUNC(__st_r13_to_r16) + HIDDEN_FUNC(__st_r13_to_r17) + HIDDEN_FUNC(__st_r13_to_r18) + HIDDEN_FUNC(__st_r13_to_r19) + HIDDEN_FUNC(__st_r13_to_r20) + HIDDEN_FUNC(__st_r13_to_r21) + HIDDEN_FUNC(__st_r13_to_r22) + HIDDEN_FUNC(__st_r13_to_r23) + HIDDEN_FUNC(__st_r13_to_r24) + HIDDEN_FUNC(__st_r13_to_r25) + .align 4 +SYM(__st_r13_to_r25): + st r25, [sp,48] +SYM(__st_r13_to_r24): + st r24, [sp,44] +SYM(__st_r13_to_r23): + st r23, [sp,40] +SYM(__st_r13_to_r22): + st r22, [sp,36] +SYM(__st_r13_to_r21): + st r21, [sp,32] +SYM(__st_r13_to_r20): + st r20, [sp,28] +SYM(__st_r13_to_r19): + st r19, [sp,24] +SYM(__st_r13_to_r18): + st r18, [sp,20] +SYM(__st_r13_to_r17): + st r17, [sp,16] +SYM(__st_r13_to_r16): + st r16, [sp,12] +SYM(__st_r13_to_r15): +#ifdef __ARC700__ + st r15, [sp,8] ; minimum function size to avoid stall: 6 bytes. +#else + st_s r15, [sp,8] +#endif + st_s r14, [sp,4] + j_s.d [%blink] + st_s r13, [sp,0] + ENDFUNC(__st_r13_to_r15) + ENDFUNC(__st_r13_to_r16) + ENDFUNC(__st_r13_to_r17) + ENDFUNC(__st_r13_to_r18) + ENDFUNC(__st_r13_to_r19) + ENDFUNC(__st_r13_to_r20) + ENDFUNC(__st_r13_to_r21) + ENDFUNC(__st_r13_to_r22) + ENDFUNC(__st_r13_to_r23) + ENDFUNC(__st_r13_to_r24) + ENDFUNC(__st_r13_to_r25) + + .section .text + .align 4 +; ================================== +; the loads + + .global SYM(__ld_r13_to_r15) + .global SYM(__ld_r13_to_r16) + .global SYM(__ld_r13_to_r17) + .global SYM(__ld_r13_to_r18) + .global SYM(__ld_r13_to_r19) + .global SYM(__ld_r13_to_r20) + .global SYM(__ld_r13_to_r21) + .global SYM(__ld_r13_to_r22) + .global SYM(__ld_r13_to_r23) + .global SYM(__ld_r13_to_r24) + .global SYM(__ld_r13_to_r25) + HIDDEN_FUNC(__ld_r13_to_r15) + HIDDEN_FUNC(__ld_r13_to_r16) + HIDDEN_FUNC(__ld_r13_to_r17) + HIDDEN_FUNC(__ld_r13_to_r18) + HIDDEN_FUNC(__ld_r13_to_r19) + HIDDEN_FUNC(__ld_r13_to_r20) + HIDDEN_FUNC(__ld_r13_to_r21) + HIDDEN_FUNC(__ld_r13_to_r22) + HIDDEN_FUNC(__ld_r13_to_r23) + HIDDEN_FUNC(__ld_r13_to_r24) + HIDDEN_FUNC(__ld_r13_to_r25) +SYM(__ld_r13_to_r25): + ld r25, [sp,48] +SYM(__ld_r13_to_r24): + ld r24, [sp,44] +SYM(__ld_r13_to_r23): + ld r23, [sp,40] +SYM(__ld_r13_to_r22): + ld r22, [sp,36] +SYM(__ld_r13_to_r21): + ld r21, [sp,32] +SYM(__ld_r13_to_r20): + ld r20, [sp,28] +SYM(__ld_r13_to_r19): + ld r19, [sp,24] +SYM(__ld_r13_to_r18): + ld r18, [sp,20] +SYM(__ld_r13_to_r17): + ld r17, [sp,16] +SYM(__ld_r13_to_r16): + ld r16, [sp,12] +SYM(__ld_r13_to_r15): +#ifdef __ARC700__ + ld r15, [sp,8] ; minimum function size to avoid stall: 6 bytes. +#else + ld_s r15, [sp,8] +#endif + ld_s r14, [sp,4] + j_s.d [%blink] + ld_s r13, [sp,0] + ENDFUNC(__ld_r13_to_r15) + ENDFUNC(__ld_r13_to_r16) + ENDFUNC(__ld_r13_to_r17) + ENDFUNC(__ld_r13_to_r18) + ENDFUNC(__ld_r13_to_r19) + ENDFUNC(__ld_r13_to_r20) + ENDFUNC(__ld_r13_to_r21) + ENDFUNC(__ld_r13_to_r22) + ENDFUNC(__ld_r13_to_r23) + ENDFUNC(__ld_r13_to_r24) + ENDFUNC(__ld_r13_to_r25) + + .global SYM(__ld_r13_to_r14_ret) + .global SYM(__ld_r13_to_r15_ret) + .global SYM(__ld_r13_to_r16_ret) + .global SYM(__ld_r13_to_r17_ret) + .global SYM(__ld_r13_to_r18_ret) + .global SYM(__ld_r13_to_r19_ret) + .global SYM(__ld_r13_to_r20_ret) + .global SYM(__ld_r13_to_r21_ret) + .global SYM(__ld_r13_to_r22_ret) + .global SYM(__ld_r13_to_r23_ret) + .global SYM(__ld_r13_to_r24_ret) + .global SYM(__ld_r13_to_r25_ret) + HIDDEN_FUNC(__ld_r13_to_r14_ret) + HIDDEN_FUNC(__ld_r13_to_r15_ret) + HIDDEN_FUNC(__ld_r13_to_r16_ret) + HIDDEN_FUNC(__ld_r13_to_r17_ret) + HIDDEN_FUNC(__ld_r13_to_r18_ret) + HIDDEN_FUNC(__ld_r13_to_r19_ret) + HIDDEN_FUNC(__ld_r13_to_r20_ret) + HIDDEN_FUNC(__ld_r13_to_r21_ret) + HIDDEN_FUNC(__ld_r13_to_r22_ret) + HIDDEN_FUNC(__ld_r13_to_r23_ret) + HIDDEN_FUNC(__ld_r13_to_r24_ret) + HIDDEN_FUNC(__ld_r13_to_r25_ret) + .section .text + .align 4 +SYM(__ld_r13_to_r25_ret): + ld r25, [sp,48] +SYM(__ld_r13_to_r24_ret): + ld r24, [sp,44] +SYM(__ld_r13_to_r23_ret): + ld r23, [sp,40] +SYM(__ld_r13_to_r22_ret): + ld r22, [sp,36] +SYM(__ld_r13_to_r21_ret): + ld r21, [sp,32] +SYM(__ld_r13_to_r20_ret): + ld r20, [sp,28] +SYM(__ld_r13_to_r19_ret): + ld r19, [sp,24] +SYM(__ld_r13_to_r18_ret): + ld r18, [sp,20] +SYM(__ld_r13_to_r17_ret): + ld r17, [sp,16] +SYM(__ld_r13_to_r16_ret): + ld r16, [sp,12] +SYM(__ld_r13_to_r15_ret): + ld r15, [sp,8] +SYM(__ld_r13_to_r14_ret): + ld blink,[sp,r12] + ld_s r14, [sp,4] + ld.ab r13, [sp,r12] + j_s.d [%blink] + add_s sp,sp,4 + ENDFUNC(__ld_r13_to_r14_ret) + ENDFUNC(__ld_r13_to_r15_ret) + ENDFUNC(__ld_r13_to_r16_ret) + ENDFUNC(__ld_r13_to_r17_ret) + ENDFUNC(__ld_r13_to_r18_ret) + ENDFUNC(__ld_r13_to_r19_ret) + ENDFUNC(__ld_r13_to_r20_ret) + ENDFUNC(__ld_r13_to_r21_ret) + ENDFUNC(__ld_r13_to_r22_ret) + ENDFUNC(__ld_r13_to_r23_ret) + ENDFUNC(__ld_r13_to_r24_ret) + ENDFUNC(__ld_r13_to_r25_ret) diff --git a/arch/arc/lib/libgcc2.c b/arch/arc/lib/libgcc2.c new file mode 100644 index 0000000000..d5ad327f65 --- /dev/null +++ b/arch/arc/lib/libgcc2.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 1989-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "libgcc2.h" + +DWtype +__ashldi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + w.s.low = 0; + w.s.high = (UWtype)uu.s.low << -bm; + } else { + const UWtype carries = (UWtype) uu.s.low >> bm; + + w.s.low = (UWtype)uu.s.low << b; + w.s.high = ((UWtype)uu.s.high << b) | carries; + } + + return w.ll; +} + +DWtype +__ashrdi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (W_TYPE_SIZE - 1); + w.s.low = uu.s.high >> -bm; + } else { + const UWtype carries = (UWtype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UWtype)uu.s.low >> b) | carries; + } + + return w.ll; +} + +DWtype +__lshrdi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + w.s.high = 0; + w.s.low = (UWtype)uu.s.high >> -bm; + } else { + const UWtype carries = (UWtype)uu.s.high << bm; + + w.s.high = (UWtype)uu.s.high >> b; + w.s.low = ((UWtype)uu.s.low >> b) | carries; + } + + return w.ll; +} + +unsigned long +udivmodsi4(unsigned long num, unsigned long den, int modwanted) +{ + unsigned long bit = 1; + unsigned long res = 0; + + while (den < num && bit && !(den & (1L<<31))) { + den <<= 1; + bit <<= 1; + } + + while (bit) { + if (num >= den) { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + + if (modwanted) + return num; + + return res; +} + +long +__divsi3(long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) { + a = -a; + neg = !neg; + } + + if (b < 0) { + b = -b; + neg = !neg; + } + + res = udivmodsi4(a, b, 0); + + if (neg) + res = -res; + + return res; +} + +long +__modsi3(long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4(a, b, 1); + + if (neg) + res = -res; + + return res; +} + +long +__udivsi3(long a, long b) +{ + return udivmodsi4(a, b, 0); +} + +long +__umodsi3(long a, long b) +{ + return udivmodsi4(a, b, 1); +} diff --git a/arch/arc/lib/libgcc2.h b/arch/arc/lib/libgcc2.h new file mode 100644 index 0000000000..8813c3bf4c --- /dev/null +++ b/arch/arc/lib/libgcc2.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1989-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#define UNITS_PER_WORD 4 /* for ARC */ +#define BITS_PER_UNIT 8 /* for ARC */ + +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) + +#define MIN_UNITS_PER_WORD UNITS_PER_WORD + +/* Work out the largest "word" size that we can deal with on this target. */ +#if MIN_UNITS_PER_WORD > 4 +# define LIBGCC2_MAX_UNITS_PER_WORD 8 +#elif (MIN_UNITS_PER_WORD > 2 \ + || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4)) +# define LIBGCC2_MAX_UNITS_PER_WORD 4 +#else +# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD +#endif + +/* Work out what word size we are using for this compilation. + The value can be set on the command line. */ +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD +#endif + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +#if MIN_UNITS_PER_WORD > 1 +/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +#if __SIZEOF_LONG_LONG__ > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2. */ +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#if MIN_UNITS_PER_WORD > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4. */ +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif +#endif +#endif + +#if LIBGCC2_UNITS_PER_WORD == 8 +#define W_TYPE_SIZE (8 * BITS_PER_UNIT) +#define Wtype DItype +#define UWtype UDItype +#define HWtype DItype +#define UHWtype UDItype +#define DWtype TItype +#define UDWtype UTItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## di ## b +#define __NDW(a,b) __gnu_ ## a ## ti ## b +#else +#define __NW(a,b) __ ## a ## di ## b +#define __NDW(a,b) __ ## a ## ti ## b +#endif +#elif LIBGCC2_UNITS_PER_WORD == 4 +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## si ## b +#define __NDW(a,b) __gnu_ ## a ## di ## b +#else +#define __NW(a,b) __ ## a ## si ## b +#define __NDW(a,b) __ ## a ## di ## b +#endif +#elif LIBGCC2_UNITS_PER_WORD == 2 +#define W_TYPE_SIZE (2 * BITS_PER_UNIT) +#define Wtype HItype +#define UWtype UHItype +#define HWtype HItype +#define UHWtype UHItype +#define DWtype SItype +#define UDWtype USItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## hi ## b +#define __NDW(a,b) __gnu_ ## a ## si ## b +#else +#define __NW(a,b) __ ## a ## hi ## b +#define __NDW(a,b) __ ## a ## si ## b +#endif +#else +#define W_TYPE_SIZE BITS_PER_UNIT +#define Wtype QItype +#define UWtype UQItype +#define HWtype QItype +#define UHWtype UQItype +#define DWtype HItype +#define UDWtype UHItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## qi ## b +#define __NDW(a,b) __gnu_ ## a ## hi ## b +#else +#define __NW(a,b) __ ## a ## qi ## b +#define __NDW(a,b) __ ## a ## hi ## b +#endif +#endif + +typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__))); + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + struct DWstruct {Wtype high, low;}; +#else + struct DWstruct {Wtype low, high;}; +#endif + +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ + +typedef union { + struct DWstruct s; + DWtype ll; +} DWunion; + +#endif /* __ASM_LIBGCC_H */ -- cgit From 0267ba5d869cdc482c0b947ef8de89ce7403ac8c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Jan 2015 10:51:46 +0100 Subject: common: Move dram_init() declaration to common location Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- arch/arm/include/asm/u-boot-arm.h | 1 - arch/nds32/include/asm/u-boot-nds32.h | 1 - arch/sandbox/include/asm/u-boot-sandbox.h | 1 - arch/x86/include/asm/u-boot-x86.h | 6 ------ include/common.h | 1 + 5 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h index f97f3dd149..414042d403 100644 --- a/arch/arm/include/asm/u-boot-arm.h +++ b/arch/arm/include/asm/u-boot-arm.h @@ -36,7 +36,6 @@ int arch_early_init_r(void); /* board/.../... */ int board_init(void); -int dram_init (void); void dram_init_banksize (void); /* cpu/.../interrupt.c */ diff --git a/arch/nds32/include/asm/u-boot-nds32.h b/arch/nds32/include/asm/u-boot-nds32.h index b07908692a..dee5f43ae1 100644 --- a/arch/nds32/include/asm/u-boot-nds32.h +++ b/arch/nds32/include/asm/u-boot-nds32.h @@ -22,7 +22,6 @@ int cleanup_before_linux(void); /* board/.../... */ int board_init(void); -int dram_init(void); /* cpu/.../interrupt.c */ void reset_timer_masked(void); diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index d2f1b6566d..770ab5c9cc 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -17,7 +17,6 @@ /* board/.../... */ int board_init(void); -int dram_init(void); /* start.c */ int sandbox_early_getopt_check(void); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index b98afa801d..c24846b3ed 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -26,15 +26,9 @@ unsigned long get_tbclk_mhz(void); void timer_set_base(uint64_t base); int pcat_timer_init(void); -/* Architecture specific DRAM init */ -int dram_init(void); - /* cpu/.../interrupts.c */ int cpu_init_interrupts(void); -/* board/.../... */ -int dram_init(void); - int cleanup_before_linux(void); int x86_cleanup_before_linux(void); void x86_enable_caches(void); diff --git a/include/common.h b/include/common.h index 97c8f79fc7..91294547f5 100644 --- a/include/common.h +++ b/include/common.h @@ -183,6 +183,7 @@ typedef void (interrupt_handler_t)(void *); /* * Function Prototypes */ +int dram_init(void); void hang (void) __attribute__ ((noreturn)); -- cgit From 61d7b1bb5fb35c49e7391d511a282295949f260b Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Tue, 20 Jan 2015 00:29:05 +0100 Subject: common/board_r: manual relocation for cmd table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required for architectures still need manual relocation like avr32, mk68 and others. Signed-off-by: Andreas Bießmann Reviewed-by: Simon Glass Tested-by: Michal Simek --- common/board_r.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 68a9448b55..f7a3b55193 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -294,6 +294,15 @@ static int initr_announce(void) return 0; } +#ifdef CONFIG_NEEDS_MANUAL_RELOC +static int initr_manual_reloc_cmdtable(void) +{ + fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd), + ll_entry_count(cmd_tbl_t, cmd)); + return 0; +} +#endif + #if !defined(CONFIG_SYS_NO_FLASH) static int initr_flash(void) { @@ -702,6 +711,9 @@ init_fnc_t init_sequence_r[] = { initr_serial, initr_announce, INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_NEEDS_MANUAL_RELOC + initr_manual_reloc_cmdtable, +#endif #ifdef CONFIG_PPC initr_trap, #endif -- cgit From cd8574c0a7b087e85b464779ab5d486644d5013b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 14:24:08 +0100 Subject: microblaze: Fix stack usage in interrupt handler Do not save registers below r1 stack pointer because it is not checked by stack undeflow is not able to detect it. Signed-off-by: Michal Simek --- arch/microblaze/cpu/irq.S | 121 +++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/arch/microblaze/cpu/irq.S b/arch/microblaze/cpu/irq.S index 24015898b0..5cfe1516bf 100644 --- a/arch/microblaze/cpu/irq.S +++ b/arch/microblaze/cpu/irq.S @@ -11,71 +11,70 @@ .text .global _interrupt_handler _interrupt_handler: - swi r2, r1, -4 - swi r3, r1, -8 - swi r4, r1, -12 - swi r5, r1, -16 - swi r6, r1, -20 - swi r7, r1, -24 - swi r8, r1, -28 - swi r9, r1, -32 - swi r10, r1, -36 - swi r11, r1, -40 - swi r12, r1, -44 - swi r13, r1, -48 - swi r14, r1, -52 - swi r15, r1, -56 - swi r16, r1, -60 - swi r17, r1, -64 - swi r18, r1, -68 - swi r19, r1, -72 - swi r20, r1, -76 - swi r21, r1, -80 - swi r22, r1, -84 - swi r23, r1, -88 - swi r24, r1, -92 - swi r25, r1, -96 - swi r26, r1, -100 - swi r27, r1, -104 - swi r28, r1, -108 - swi r29, r1, -112 - swi r30, r1, -116 - swi r31, r1, -120 addik r1, r1, -124 + swi r2, r1, 4 + swi r3, r1, 8 + swi r4, r1, 12 + swi r5, r1, 16 + swi r6, r1, 20 + swi r7, r1, 24 + swi r8, r1, 28 + swi r9, r1, 32 + swi r10, r1, 36 + swi r11, r1, 40 + swi r12, r1, 44 + swi r13, r1, 48 + swi r14, r1, 52 + swi r15, r1, 56 + swi r16, r1, 60 + swi r17, r1, 64 + swi r18, r1, 68 + swi r19, r1, 72 + swi r20, r1, 76 + swi r21, r1, 80 + swi r22, r1, 84 + swi r23, r1, 88 + swi r24, r1, 92 + swi r25, r1, 96 + swi r26, r1, 100 + swi r27, r1, 104 + swi r28, r1, 108 + swi r29, r1, 112 + swi r30, r1, 116 + swi r31, r1, 120 brlid r15, interrupt_handler nop + lwi r31, r1, 120 + lwi r30, r1, 116 + lwi r29, r1, 112 + lwi r28, r1, 108 + lwi r27, r1, 104 + lwi r26, r1, 100 + lwi r25, r1, 96 + lwi r24, r1, 92 + lwi r23, r1, 88 + lwi r22, r1, 84 + lwi r21, r1, 80 + lwi r20, r1, 76 + lwi r19, r1, 72 + lwi r18, r1, 68 + lwi r17, r1, 64 + lwi r16, r1, 60 + lwi r15, r1, 56 + lwi r14, r1, 52 + lwi r13, r1, 48 + lwi r12, r1, 44 + lwi r11, r1, 40 + lwi r10, r1, 36 + lwi r9, r1, 32 + lwi r8, r1, 28 + lwi r7, r1, 24 + lwi r6, r1, 20 + lwi r5, r1, 16 + lwi r4, r1, 12 + lwi r3, r1, 8 + lwi r2, r1, 4 addik r1, r1, 124 - lwi r31, r1, -120 - lwi r30, r1, -116 - lwi r29, r1, -112 - lwi r28, r1, -108 - lwi r27, r1, -104 - lwi r26, r1, -100 - lwi r25, r1, -96 - lwi r24, r1, -92 - lwi r23, r1, -88 - lwi r22, r1, -84 - lwi r21, r1, -80 - lwi r20, r1, -76 - lwi r19, r1, -72 - lwi r18, r1, -68 - lwi r17, r1, -64 - lwi r16, r1, -60 - lwi r15, r1, -56 - lwi r14, r1, -52 - lwi r13, r1, -48 - lwi r12, r1, -44 - lwi r11, r1, -40 - lwi r10, r1, -36 - lwi r9, r1, -32 - lwi r8, r1, -28 - lwi r7, r1, -24 - lwi r6, r1, -20 - lwi r5, r1, -16 - lwi r4, r1, -12 - lwi r3, r1, -8 - lwi r2, r1, -4 - rtid r14, 0 nop .size _interrupt_handler,.-_interrupt_handler -- cgit From 1c424d26975345dec30e525319056cdb2280b170 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 14:32:23 +0100 Subject: microblaze: Show return address from exception Show also return address from exception which should suggest where the problem is. Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 2 ++ arch/microblaze/include/asm/asm.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index 227842f6a4..45729331f3 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -18,6 +18,8 @@ void _hw_exception_handler (void) /* loading excetpion state register ESR */ MFS (state, resr); printf ("Hardware exception at 0x%x address\n", address); + R17(address); + printf("Return address from exception 0x%x\n", address); switch (state & 0x1f) { /* mask on exception cause */ case 0x1: puts ("Unaligned data access exception\n"); diff --git a/arch/microblaze/include/asm/asm.h b/arch/microblaze/include/asm/asm.h index c1c3b03985..11f3dd0f0e 100644 --- a/arch/microblaze/include/asm/asm.h +++ b/arch/microblaze/include/asm/asm.h @@ -43,6 +43,10 @@ #define R14(val) \ __asm__ __volatile__ ("addi %0, r14, 0":"=r" (val)); +/* get return address from interrupt */ +#define R17(val) \ + __asm__ __volatile__ ("addi %0, r17, 0" : "=r" (val)); + #define NOP __asm__ __volatile__ ("nop"); /* use machine status registe USE_MSR_REG */ -- cgit From 5e2fc801ff2da9f799b0ad416a379c25aa7b7fe8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 14:36:13 +0100 Subject: microblaze: Fix coding style in exception.c Just coding style cleanup - no functional changes. Signed-off-by: Michal Simek --- arch/microblaze/cpu/exception.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index 45729331f3..aa34f45bef 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -13,51 +13,52 @@ void _hw_exception_handler (void) { int address = 0; int state = 0; + /* loading address of exception EAR */ - MFS (address, rear); + MFS(address, rear); /* loading excetpion state register ESR */ - MFS (state, resr); - printf ("Hardware exception at 0x%x address\n", address); + MFS(state, resr); + printf("Hardware exception at 0x%x address\n", address); R17(address); printf("Return address from exception 0x%x\n", address); switch (state & 0x1f) { /* mask on exception cause */ case 0x1: - puts ("Unaligned data access exception\n"); + puts("Unaligned data access exception\n"); break; case 0x2: - puts ("Illegal op-code exception\n"); + puts("Illegal op-code exception\n"); break; case 0x3: - puts ("Instruction bus error exception\n"); + puts("Instruction bus error exception\n"); break; case 0x4: - puts ("Data bus error exception\n"); + puts("Data bus error exception\n"); break; case 0x5: - puts ("Divide by zero exception\n"); + puts("Divide by zero exception\n"); break; #ifdef MICROBLAZE_V5 case 0x7: puts("Priviledged or stack protection violation exception\n"); break; case 0x1000: - puts ("Exception in delay slot\n"); + puts("Exception in delay slot\n"); break; #endif default: - puts ("Undefined cause\n"); + puts("Undefined cause\n"); break; } - printf ("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); - printf ("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); - printf ("Register R%x\n", (state & 0x3E) >> 5); - hang (); + printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); + printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); + printf("Register R%x\n", (state & 0x3E) >> 5); + hang(); } #ifdef CONFIG_SYS_USR_EXCEP void _exception_handler (void) { - puts ("User vector_exception\n"); - hang (); + puts("User vector_exception\n"); + hang(); } #endif -- cgit From 4c0922f367a652a59ee0fa768212ec3bd78953ee Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 14:37:52 +0100 Subject: microblaze: Remove DEBUG_INT macro and use debug() instead Do not use specific macros for debugging. Also remove compilation warning: w+../arch/microblaze/cpu/interrupts.c: In function 'interrupt_handler': w+../arch/microblaze/cpu/interrupts.c:153:2: warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'void (*)(void *)' [-Wformat] w+../arch/microblaze/cpu/interrupts.c:153:2: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'void *' [-Wformat] Signed-off-by: Michal Simek --- arch/microblaze/cpu/interrupts.c | 57 ++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index 9364e2fa9c..030e9147dc 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -14,8 +14,6 @@ #include #include -#undef DEBUG_INT - void enable_interrupts(void) { MSRSET(0x2); @@ -50,12 +48,11 @@ static void enable_one_interrupt(int irq) offset <<= irq; mask = intc->ier; intc->ier = (mask | offset); -#ifdef DEBUG_INT - printf("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, - intc->ier); - printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -#endif + + debug("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, + intc->ier); + debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); } static void disable_one_interrupt(int irq) @@ -66,12 +63,11 @@ static void disable_one_interrupt(int irq) offset <<= irq; mask = intc->ier; intc->ier = (mask & ~offset); -#ifdef DEBUG_INT - printf("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, - intc->ier); - printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -#endif + + debug("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, + intc->ier); + debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); } int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) @@ -107,10 +103,9 @@ static void intc_init(void) intc->iar = 0xFFFFFFFF; /* XIntc_Start - hw_interrupt enable and all interrupt enable */ intc->mer = 0x3; -#ifdef DEBUG_INT - printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); -#endif + + debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); } int interrupts_init(void) @@ -147,31 +142,29 @@ void interrupt_handler(void) { int irqs = intc->ivr; /* find active interrupt */ int mask = 1; -#ifdef DEBUG_INT int value; - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, - intc->iar, intc->mer); - R14(value); - printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); -#endif struct irq_action *act = vecs + irqs; -#ifdef DEBUG_INT - printf - ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", - act->handler, act->count, act->arg); + debug("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + intc->iar, intc->mer); +#ifdef DEBUG + R14(value); #endif + debug("Interrupt handler on %x line, r14 %x\n", irqs, value); + + debug("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", + (u32)act->handler, act->count, (u32)act->arg); act->handler (act->arg); act->count++; intc->iar = mask << irqs; -#ifdef DEBUG_INT - printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, - intc->ier, intc->iar, intc->mer); + debug("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, + intc->ier, intc->iar, intc->mer); +#ifdef DEBUG R14(value); - printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); #endif + debug("Interrupt handler on %x line, r14 %x\n", irqs, value); } #if defined(CONFIG_CMD_IRQ) -- cgit From e217b0d50dd38e0fffb1168d9eaf64086bcb3b51 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 14:39:22 +0100 Subject: microblaze: Fix coding style No functional changes just to pass checkpatch.pl. Signed-off-by: Michal Simek --- arch/microblaze/cpu/interrupts.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index 030e9147dc..771bbd0ca6 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -84,12 +84,12 @@ int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) act->handler = hdlr; act->arg = arg; act->count = 0; - enable_one_interrupt (irq); + enable_one_interrupt(irq); return 0; } /* Disable */ - act->handler = (interrupt_handler_t *) def_hdlr; + act->handler = (interrupt_handler_t *)def_hdlr; act->arg = (void *)irq; disable_one_interrupt(irq); return 1; @@ -113,7 +113,7 @@ int interrupts_init(void) int i; #if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM) - intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR); + intc = (microblaze_intc_t *)CONFIG_SYS_INTC_0_ADDR; irq_no = CONFIG_SYS_INTC_0_NUM; #endif if (irq_no) { @@ -125,7 +125,7 @@ int interrupts_init(void) /* initialize irq list */ for (i = 0; i < irq_no; i++) { - vecs[i].handler = (interrupt_handler_t *) def_hdlr; + vecs[i].handler = (interrupt_handler_t *)def_hdlr; vecs[i].arg = (void *)i; vecs[i].count = 0; } @@ -154,7 +154,7 @@ void interrupt_handler(void) debug("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n", (u32)act->handler, act->count, (u32)act->arg); - act->handler (act->arg); + act->handler(act->arg); act->count++; intc->iar = mask << irqs; @@ -179,10 +179,10 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[]) "-----------------------------\n"); for (i = 0; i < irq_no; i++) { - if (act->handler != (interrupt_handler_t *) def_hdlr) { + if (act->handler != (interrupt_handler_t *)def_hdlr) { printf("%02d %08x %08x %d\n", i, - (int)act->handler, (int)act->arg, - act->count); + (int)act->handler, (int)act->arg, + act->count); } act++; } -- cgit From 070b8e0da23ab344153d3d1d1b5ef6caac3134dd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 15:25:32 +0100 Subject: microblaze: Add debug message about enabling interrupts Add one more debug message about enabling global interrupts. Signed-off-by: Michal Simek --- arch/microblaze/cpu/interrupts.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index 771bbd0ca6..f66ec69ee2 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -16,6 +16,7 @@ void enable_interrupts(void) { + debug("Enable interrupts for the whole CPU\n"); MSRSET(0x2); } -- cgit From 7c6814f184ca455f45684cbcbf108596ecbe00c6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 26 Jan 2015 15:52:48 +0100 Subject: microblaze: Remove unneeded data section adding from DTB DTB is added to rodata section: [ 2] .rodata PROGBITS 84c5b60c 05c60c 00c618 00 A 0 0 4 [ 3] .dtb.init.rodata PROGBITS 84c67c30 068c30 003c80 00 A 0 0 16 [ 4] .rela.dyn RELA 84c6b8b0 06c8b0 000534 0c A 0 0 4 [ 5] .data PROGBITS 84c6bde4 06cde4 001536 00 WA 0 0 16 Signed-off-by: Michal Simek --- arch/microblaze/cpu/u-boot.lds | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index fdad20753d..44bc036172 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -29,9 +29,6 @@ SECTIONS .data ALIGN(0x4): { __data_start = .; -#ifdef CONFIG_OF_EMBED - dts/built-in.o (.data) -#endif *(.data) __data_end = .; } -- cgit From 2c7c32fa7f025a87cfdb4afce4a6dda78a8c5582 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 12:44:12 +0100 Subject: microblaze: Use standard interrupt_init() function Do not use microblaze specific interrupt init function. Signed-off-by: Michal Simek --- arch/microblaze/cpu/interrupts.c | 2 +- arch/microblaze/include/asm/microblaze_intc.h | 2 -- arch/microblaze/lib/board.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index f66ec69ee2..b6d6610f2f 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -109,7 +109,7 @@ static void intc_init(void) intc->iar, intc->mer); } -int interrupts_init(void) +int interrupt_init(void) { int i; diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h index 0fb9207882..65868386b0 100644 --- a/arch/microblaze/include/asm/microblaze_intc.h +++ b/arch/microblaze/include/asm/microblaze_intc.h @@ -34,5 +34,3 @@ struct irq_action { */ int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg); - -int interrupts_init(void); diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index 600c80ab76..bd028a63c0 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -55,7 +55,7 @@ init_fnc_t *init_sequence[] = { #endif display_banner, #ifndef CONFIG_SPL_BUILD - interrupts_init, + interrupt_init, timer_init, #endif NULL, -- cgit From e4a4743e487f758cfc37528a8d6d4066cf781bc6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 12:46:07 +0100 Subject: microblaze: Remove unused asm label It is not used at all that's why remove it. Signed-off-by: Michal Simek --- arch/microblaze/cpu/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 84c29e5409..e0e3470a18 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -129,7 +129,7 @@ _start: /* Flush cache before enable cache */ addik r5, r0, 0 addik r6, r0, XILINX_DCACHE_BYTE_SIZE -flush: bralid r15, flush_cache + bralid r15, flush_cache nop /* enable instruction and data cache */ -- cgit From 9cef20b10929d7ad047b071c3dcb924401bf78e8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 14:06:14 +0100 Subject: microblaze: Fix gd_t address which is placed at the end of BRAM Setup gd from ASM to be availalbe for board_init_r. Setting it up in spl_board_init is too late when MALLOC is used. Space for gd is located behind MALLOC area at the end of BRAM. Signed-off-by: Michal Simek --- arch/microblaze/cpu/spl.c | 2 -- arch/microblaze/cpu/start.S | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/microblaze/cpu/spl.c b/arch/microblaze/cpu/spl.c index 091226133e..2cc0a2da89 100644 --- a/arch/microblaze/cpu/spl.c +++ b/arch/microblaze/cpu/spl.c @@ -25,8 +25,6 @@ u32 spl_boot_device(void) /* Board initialization after bss clearance */ void spl_board_init(void) { - gd = (gd_t *)CONFIG_SPL_STACK_ADDR; - /* enable console uart printing */ preloader_console_init(); } diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index e0e3470a18..14c2f12da0 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -152,6 +152,7 @@ clear_bss: #ifndef CONFIG_SPL_BUILD brai board_init_f #else + addi r31, r0, CONFIG_SYS_SPL_MALLOC_END brai board_init_r #endif 1: bri 1b -- cgit From 4dd097427aeb6848fcb19c31b805abe1a3906913 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 14:25:38 +0100 Subject: microblaze: Enable SPL_NOR support when FLASH_BASE is setup Simplify SPL NOR init. Signed-off-by: Michal Simek --- include/configs/microblaze-generic.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index bb07060002..2e1e64247f 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -452,7 +452,10 @@ #define CONFIG_SPL_LDSCRIPT "arch/microblaze/cpu/u-boot-spl.lds" #define CONFIG_SPL_RAM_DEVICE -#define CONFIG_SPL_NOR_SUPPORT +#ifdef CONFIG_SYS_FLASH_BASE +# define CONFIG_SPL_NOR_SUPPORT +# define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_FLASH_BASE +#endif /* for booting directly linux */ #define CONFIG_SPL_OS_BOOT @@ -491,7 +494,6 @@ /* Just for sure that there is a space for stack */ #define CONFIG_SPL_STACK_SIZE 0x100 -#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_FLASH_BASE #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE #define CONFIG_SPL_MAX_FOOTPRINT (CONFIG_SYS_INIT_RAM_SIZE - \ -- cgit From e945f6dc2814f5f0d30b5b7e23821b3fd4faff5b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 8 May 2014 16:08:44 +0200 Subject: microblaze: Move architecture to use generic board init Compile code with -fPIC to get GOT. Do not build SPL with fPIC because it increasing SPL size for nothing. Signed-off-by: Michal Simek --- arch/microblaze/config.mk | 5 + arch/microblaze/cpu/start.S | 103 +++++++++++ arch/microblaze/cpu/u-boot.lds | 9 + arch/microblaze/include/asm/config.h | 8 + arch/microblaze/include/asm/u-boot.h | 11 +- arch/microblaze/lib/Makefile | 1 - arch/microblaze/lib/board.c | 201 --------------------- .../xilinx/microblaze-generic/microblaze-generic.c | 46 +++++ common/board_f.c | 4 +- common/board_r.c | 2 +- common/cmd_bdinfo.c | 13 +- include/configs/microblaze-generic.h | 64 +------ 12 files changed, 195 insertions(+), 272 deletions(-) delete mode 100644 arch/microblaze/lib/board.c diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index 98bbf794fa..2b817be61a 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -15,3 +15,8 @@ endif CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ + +ifeq ($(CONFIG_SPL_BUILD),) +PLATFORM_CPPFLAGS += -fPIC +endif +__HAVE_ARCH_GENERIC_BOARD := y diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 14c2f12da0..3de0e12090 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -150,6 +150,7 @@ clear_bss: bnei r6, 2b 3: /* jumping to board_init */ #ifndef CONFIG_SPL_BUILD + or r5, r0, r0 /* flags - empty */ brai board_init_f #else addi r31, r0, CONFIG_SYS_SPL_MALLOC_END @@ -190,4 +191,106 @@ out16: bslli r3, r6, 8 rtsd r15, 8 or r0, r0, r0 .end out16 + +/* + * Relocate u-boot + */ + .text + .global relocate_code + .ent relocate_code + .align 2 +relocate_code: + /* + * r5 - start_addr_sp + * r6 - new_gd + * r7 - reloc_addr + */ + addi r1, r5, 0 /* Start to use new SP */ + addi r31, r6, 0 /* Start to use new GD */ + + add r23, r0, r7 /* Move reloc addr to r23 */ + /* Relocate text and data - r12 temp value */ + addi r21, r0, _start + addi r22, r0, __end - 4 /* Include BSS too */ +1: lwi r12, r21, 0 /* Load u-boot data */ + swi r12, r23, 0 /* Write zero to loc */ + addi r21, r21, 4 /* Increment to next loc - origin code */ + cmp r12, r21, r22 /* Check if we have reach the end */ + bneid r12, 1b + addi r23, r23, 4 /* Increment to next loc - relocate code */ + + /* R23 points to the base address. */ + add r23, r0, r7 /* Move reloc addr to r23 */ + addi r24, r0, CONFIG_SYS_TEXT_BASE /* Get reloc offset */ + rsub r23, r24, r23 /* keep - this is already here gd->reloc_off */ + + addik r6, r0, 0x2 /* BIG/LITTLE endian offset */ + lwi r7, r0, 0x28 + swi r6, r0, 0x28 /* used first unused MB vector */ + lbui r10, r0, 0x28 /* used first unused MB vector */ + swi r7, r0, 0x28 + +#ifdef CONFIG_SYS_USR_EXCEP + addik r6, r0, _exception_handler + addk r6, r6, r23 /* add offset */ + sw r6, r1, r0 + lhu r7, r1, r10 + rsubi r8, r10, 0xa + sh r7, r0, r8 + rsubi r8, r10, 0xe + sh r6, r0, r8 +#endif + addik r6, r0, _hw_exception_handler + addk r6, r6, r23 /* add offset */ + sw r6, r1, r0 + lhu r7, r1, r10 + rsubi r8, r10, 0x22 + sh r7, r0, r8 + rsubi r8, r10, 0x26 + sh r6, r0, r8 + + addik r6, r0, _interrupt_handler + addk r6, r6, r23 /* add offset */ + sw r6, r1, r0 + lhu r7, r1, r10 + rsubi r8, r10, 0x12 + sh r7, r0, r8 + rsubi r8, r10, 0x16 + sh r6, r0, r8 + + /* Check if GOT exist */ + addik r21, r23, _got_start + addik r22, r23, _got_end + cmpu r12, r21, r22 + beqi r12, 2f /* No GOT table - jump over */ + + /* Skip last 3 entries plus 1 because of loop boundary below */ + addik r22, r22, -0x10 + + /* Relocate the GOT. */ +3: lw r12, r21, r0 /* Load entry */ + addk r12, r12, r23 /* Add reloc offset */ + sw r12, r21, r0 /* Save entry back */ + + cmpu r12, r21, r22 /* Check if this cross boundary */ + bneid r12, 3b + addik r21. r21, 4 + + /* Update pointer to GOT */ + mfs r20, rpc + addik r20, r20, _GLOBAL_OFFSET_TABLE_ + 8 + addk r20, r20, r23 + + /* Flush caches to ensure consistency */ + addik r5, r0, 0 + addik r6, r0, XILINX_DCACHE_BYTE_SIZE + bralid r15, flush_cache + nop + +2: addi r5, r31, 0 /* gd is initialized in board_r.c */ + addi r6, r0, CONFIG_SYS_TEXT_BASE + addi r12, r23, board_init_r + bra r12 /* Jump to relocated code */ + + .end relocate_code #endif diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index 44bc036172..2502a0db2b 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -33,10 +33,19 @@ SECTIONS __data_end = .; } + .got ALIGN(4): + { + _got_start = .; + *(.got*) + . = ALIGN(4); + _got_end = .; + } + . = ALIGN(4); .u_boot_list : { KEEP(*(SORT(.u_boot_list*))); } + __init_end = . ; .bss ALIGN(0x4): { diff --git a/arch/microblaze/include/asm/config.h b/arch/microblaze/include/asm/config.h index cd29734789..468673460b 100644 --- a/arch/microblaze/include/asm/config.h +++ b/arch/microblaze/include/asm/config.h @@ -7,4 +7,12 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ +#ifndef CONFIG_SPL_BUILD +#define CONFIG_NEEDS_MANUAL_RELOC +#endif + +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SYS_GENERIC_GLOBAL_DATA + #endif diff --git a/arch/microblaze/include/asm/u-boot.h b/arch/microblaze/include/asm/u-boot.h index 54d415ebb5..66f8f952c9 100644 --- a/arch/microblaze/include/asm/u-boot.h +++ b/arch/microblaze/include/asm/u-boot.h @@ -16,16 +16,7 @@ #ifndef _U_BOOT_H_ #define _U_BOOT_H_ -typedef struct bd_info { - unsigned long bi_memstart; /* start of DRAM memory */ - phys_size_t bi_memsize; /* size of DRAM memory in bytes */ - unsigned long bi_flashstart; /* start of FLASH memory */ - unsigned long bi_flashsize; /* size of FLASH memory */ - unsigned long bi_flashoffset; /* reserved area for startup monitor */ - unsigned long bi_sramstart; /* start of SRAM memory */ - unsigned long bi_sramsize; /* size of SRAM memory */ - ulong bi_boot_params; /* where this board expects params */ -} bd_t; +#include /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_MICROBLAZE diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 339dd153a0..0289d0cd60 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -5,6 +5,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += board.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += muldi3.o diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c deleted file mode 100644 index bd028a63c0..0000000000 --- a/arch/microblaze/lib/board.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Michal SIMEK - * Yasushi SHOJI - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static int display_banner(void) -{ - printf("\n\n%s\n\n", version_string); - return 0; -} - -/* - * All attempts to come up with a "common" initialization sequence - * that works for all boards and architectures failed: some of the - * requirements are just _too_ different. To get rid of the resulting - * mess of board dependend #ifdef'ed code we now make the whole - * initialization sequence configurable to the user. - * - * The requirements for any new initalization function is simple: it - * receives a pointer to the "global data" structure as it's only - * argument, and returns an integer return code, where 0 means - * "continue" and != 0 means "fatal error, hang the system". - */ -typedef int (init_fnc_t) (void); - -init_fnc_t *init_sequence[] = { - env_init, -#ifdef CONFIG_OF_CONTROL - fdtdec_check_fdt, -#endif - serial_init, -#ifndef CONFIG_SPL_BUILD - console_init_f, -#endif - display_banner, -#ifndef CONFIG_SPL_BUILD - interrupt_init, - timer_init, -#endif - NULL, -}; - -unsigned long monitor_flash_len; - -void board_init_f(ulong not_used) -{ - bd_t *bd; - init_fnc_t **init_fnc_ptr; - gd = (gd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); - bd = (bd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET - - GENERATED_BD_INFO_SIZE); -#if defined(CONFIG_CMD_FLASH) && !defined(CONFIG_SPL_BUILD) - ulong flash_size = 0; -#endif - asm ("nop"); /* FIXME gd is not initialize - wait */ - memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE); - memset((void *)bd, 0, GENERATED_BD_INFO_SIZE); - gd->bd = bd; - gd->baudrate = CONFIG_BAUDRATE; - bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; - bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; - gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ - - monitor_flash_len = __end - __text_start; - -#ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; -#elif defined CONFIG_OF_SEPARATE - /* FDT is at end of image */ - gd->fdt_blob = (void *)__end; -#endif - -#ifndef CONFIG_SPL_BUILD - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, - (uintptr_t)gd->fdt_blob); -#endif - - /* - * The Malloc area is immediately below the monitor copy in DRAM - * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off - * as our monitory code is run from SDRAM - */ - mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); - - serial_initialize(); - -#ifdef CONFIG_XILINX_TB_WATCHDOG - hw_watchdog_init(); -#endif - for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { - WATCHDOG_RESET(); - if ((*init_fnc_ptr) () != 0) - hang(); - } - -#ifndef CONFIG_SPL_BUILD -#ifdef CONFIG_OF_CONTROL - /* For now, put this check after the console is ready */ - if (fdtdec_prepare_fdt()) - panic("** No FDT - please see doc/README.fdt-control"); - else - printf("DTB: 0x%x\n", (u32)gd->fdt_blob); -#endif - - puts("SDRAM :\n"); - printf("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); - printf("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); - printf("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE); - -#if defined(CONFIG_CMD_FLASH) - puts("Flash: "); - bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; - flash_size = flash_init(); - if (bd->bi_flashstart && flash_size > 0) { -# ifdef CONFIG_SYS_FLASH_CHECKSUM - print_size(flash_size, ""); - /* - * Compute and print flash CRC if flashchecksum is set to 'y' - * - * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX - */ - if (getenv_yesno("flashchecksum") == 1) { - printf(" CRC: %08X", - crc32(0, (const u8 *)bd->bi_flashstart, - flash_size) - ); - } - putc('\n'); -# else /* !CONFIG_SYS_FLASH_CHECKSUM */ - print_size(flash_size, "\n"); -# endif /* CONFIG_SYS_FLASH_CHECKSUM */ - bd->bi_flashsize = flash_size; - bd->bi_flashoffset = bd->bi_flashstart + flash_size; - } else { - puts("Flash init FAILED"); - bd->bi_flashstart = 0; - bd->bi_flashsize = 0; - bd->bi_flashoffset = 0; - } -#endif - -#ifdef CONFIG_SPI - spi_init(); -#endif - - /* relocate environment function pointers etc. */ - env_relocate(); - - /* Initialize stdio devices */ - stdio_init(); - - /* Initialize the jump table for applications */ - jumptable_init(); - - /* Initialize the console (after the relocation and devices init) */ - console_init_r(); - - board_init(); - - /* Initialize from environment */ - load_addr = getenv_ulong("loadaddr", 16, load_addr); - -#if defined(CONFIG_CMD_NET) - printf("Net: "); - eth_initialize(gd->bd); - - uchar enetaddr[6]; - eth_getenv_enetaddr("ethaddr", enetaddr); - printf("MAC: %pM\n", enetaddr); -#endif - - /* main_loop */ - for (;;) { - WATCHDOG_RESET(); - main_loop(); - } -#endif /* CONFIG_SPL_BUILD */ -} diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 42a8d0c400..3110405a1b 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -11,16 +11,62 @@ #include #include +#include #include #include #include #include #include +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_XILINX_GPIO static int reset_pin = -1; #endif +#ifdef CONFIG_OF_CONTROL +ulong ram_base; + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = ram_base; + gd->bd->bi_dram[0].size = get_effective_memsize(); +} + +int dram_init(void) +{ + int node; + fdt_addr_t addr; + fdt_size_t size; + const void *blob = gd->fdt_blob; + + node = fdt_node_offset_by_prop_value(blob, -1, "device_type", + "memory", 7); + if (node == -FDT_ERR_NOTFOUND) { + debug("DRAM: Can't get memory node\n"); + return 1; + } + addr = fdtdec_get_addr_size(blob, node, "reg", &size); + if (addr == FDT_ADDR_T_NONE || size == 0) { + debug("DRAM: Can't get base address or size\n"); + return 1; + } + ram_base = addr; + + gd->ram_top = addr; /* In setup_dest_addr() is done +ram_size */ + gd->ram_size = size; + + return 0; +}; +#else +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} +#endif + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifdef CONFIG_XILINX_GPIO diff --git a/common/board_f.c b/common/board_f.c index 79531377a7..d25329a0aa 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -262,7 +262,7 @@ static int zero_global_data(void) static int setup_mon_len(void) { -#ifdef __ARM__ +#if defined(__ARM__) || defined(__MICROBLAZE__) gd->mon_len = (ulong)&__bss_end - (ulong)_start; #elif defined(CONFIG_SANDBOX) gd->mon_len = (ulong)&_end - (ulong)_init; @@ -909,7 +909,7 @@ static init_fnc_t init_sequence_f[] = { #endif announce_dram_init, /* TODO: unify all these dram functions? */ -#if defined(CONFIG_ARM) || defined(CONFIG_X86) +#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) dram_init, /* configure available RAM banks */ #endif #if defined(CONFIG_MIPS) || defined(CONFIG_PPC) diff --git a/common/board_r.c b/common/board_r.c index f7a3b55193..907b33cca7 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -813,7 +813,7 @@ init_fnc_t init_sequence_r[] = { #if defined(CONFIG_ARM) initr_enable_interrupts, #endif -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) timer_init, /* initialize timer */ #endif #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index e6d8a7ae2c..4c51059c1b 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -183,8 +183,14 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; - print_num("mem start ", (ulong)bd->bi_memstart); - print_lnum("mem size ", (u64)bd->bi_memsize); + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + print_num("DRAM bank", i); + print_num("-> start", bd->bi_dram[i].start); + print_num("-> size", bd->bi_dram[i].size); + } + print_num("flash start ", (ulong)bd->bi_flashstart); print_num("flash size ", (ulong)bd->bi_flashsize); print_num("flash offset ", (ulong)bd->bi_flashoffset); @@ -196,6 +202,9 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_eths(); #endif printf("baudrate = %u bps\n", gd->baudrate); + print_num("relocaddr", gd->relocaddr); + print_num("reloc off", gd->reloc_off); + return 0; } diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 2e1e64247f..622bc95104 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -106,62 +106,16 @@ # define CONFIG_XILINX_TB_WATCHDOG #endif -/* - * memory layout - Example - * CONFIG_SYS_TEXT_BASE = 0x1200_0000; defined in config.mk - * CONFIG_SYS_SRAM_BASE = 0x1000_0000; - * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; 64MB - * - * CONFIG_SYS_MONITOR_LEN = 0x40000 - * CONFIG_SYS_MALLOC_LEN = 3 * CONFIG_SYS_MONITOR_LEN = 0xC0000 - * - * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 - * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - CONFIG_SYS_MONITOR_LEN = 0x13FB_F000 - * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - CONFIG_SYS_MALLOC_LEN = 0x13EF_F000 - * - * 0x1000_0000 CONFIG_SYS_SDRAM_BASE - * MEMTEST_AREA 64kB - * FREE - * 0x1200_0000 CONFIG_SYS_TEXT_BASE - * U-BOOT code - * 0x1202_0000 - * FREE - * - * STACK - * 0x13EF_F000 CONFIG_SYS_MALLOC_BASE - * MALLOC_AREA 768kB Alloc - * 0x13FB_F000 CONFIG_SYS_MONITOR_BASE - * MONITOR_CODE 256kB Env - * 0x13FF_F000 CONFIG_SYS_GBL_DATA_OFFSET - * GLOBAL_DATA 4kB bd, gd - * 0x1400_0000 CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - */ - +#ifndef CONFIG_OF_CONTROL /* ddr sdram - main memory */ -#define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START -#define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE -#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE -#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1000) - -/* global pointer */ -/* start of global data */ -#define CONFIG_SYS_GBL_DATA_OFFSET \ - (CONFIG_SYS_SDRAM_SIZE - GENERATED_GBL_DATA_SIZE) - -/* monitor code */ -#define SIZE 0x40000 -#define CONFIG_SYS_MONITOR_LEN SIZE -#define CONFIG_SYS_MONITOR_BASE \ - (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ - - CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE) -#define CONFIG_SYS_MONITOR_END \ - (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) -#define CONFIG_SYS_MALLOC_LEN (SIZE * 3) -#define CONFIG_SYS_MALLOC_BASE \ - (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) - -/* stack */ -#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_MALLOC_BASE +# define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START +# define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE +#endif + +#define CONFIG_SYS_MALLOC_LEN 0xC0000 + +/* Stack location before relocation */ +#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_TEXT_BASE /* * CFI flash memory layout - Example -- cgit From 7c4dd542551dc146b6e3da0c1b519d95dd124d6c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 15:10:37 +0100 Subject: microblaze: Speedup code copy Remove one instruction in the loop which speedup code copying. Signed-off-by: Michal Simek --- arch/microblaze/cpu/start.S | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 3de0e12090..4023ec0675 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -212,12 +212,14 @@ relocate_code: /* Relocate text and data - r12 temp value */ addi r21, r0, _start addi r22, r0, __end - 4 /* Include BSS too */ -1: lwi r12, r21, 0 /* Load u-boot data */ - swi r12, r23, 0 /* Write zero to loc */ - addi r21, r21, 4 /* Increment to next loc - origin code */ - cmp r12, r21, r22 /* Check if we have reach the end */ + + rsub r6, r21, r22 + or r5, r0, r0 +1: lw r12, r21, r5 /* Load u-boot data */ + sw r12, r23, r5 /* Write zero to loc */ + cmp r12, r5, r6 /* Check if we have reach the end */ bneid r12, 1b - addi r23, r23, 4 /* Increment to next loc - relocate code */ + addi r5, r5, 4 /* Increment to next loc - relocate code */ /* R23 points to the base address. */ add r23, r0, r7 /* Move reloc addr to r23 */ -- cgit From de86765bc4854e7961c8d0b0bd4646e90dedf864 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 27 Jan 2015 15:41:08 +0100 Subject: bdinfo: Show information about fdt blob via bdinfo Microblaze target supports both OF and !OF cases and from log is not clear which version is running. Signed-off-by: Michal Simek --- common/cmd_bdinfo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 4c51059c1b..e9eab232f9 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -204,6 +204,9 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("baudrate = %u bps\n", gd->baudrate); print_num("relocaddr", gd->relocaddr); print_num("reloc off", gd->reloc_off); + print_num("fdt_blob", (ulong)gd->fdt_blob); + print_num("new_fdt", (ulong)gd->new_fdt); + print_num("fdt_size", (ulong)gd->fdt_size); return 0; } -- cgit From 0510b14b73cbe7e1c2b43272c7a3210af21dff31 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Jan 2015 15:45:02 +0100 Subject: microblaze: Do not use CONFIG_SYS_GENERIC_GLOBAL_DATA Because it is not compatible with DM where malloc_base has to be available early and init has to be done in ASM. Signed-off-by: Michal Simek --- arch/microblaze/cpu/start.S | 6 ++++++ arch/microblaze/include/asm/config.h | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 4023ec0675..3eeeab4b88 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -151,6 +151,7 @@ clear_bss: 3: /* jumping to board_init */ #ifndef CONFIG_SPL_BUILD or r5, r0, r0 /* flags - empty */ + addi r31, r0, _gd brai board_init_f #else addi r31, r0, CONFIG_SYS_SPL_MALLOC_END @@ -158,6 +159,11 @@ clear_bss: #endif 1: bri 1b + .section .bss +.align 4 +_gd: + .space GENERATED_GBL_DATA_SIZE + #ifndef CONFIG_SPL_BUILD /* * Read 16bit little endian diff --git a/arch/microblaze/include/asm/config.h b/arch/microblaze/include/asm/config.h index 468673460b..32fd636b61 100644 --- a/arch/microblaze/include/asm/config.h +++ b/arch/microblaze/include/asm/config.h @@ -13,6 +13,5 @@ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_SYS_GENERIC_GLOBAL_DATA #endif -- cgit From 405e651d705e197babe423ef88e8224e2737fc06 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Jan 2015 15:46:43 +0100 Subject: microblaze: Add support for CONFIG_SYS_MALLOC_F_LEN Create space for dm_init where calloc is called and malloc_base has to be initialized. Signed-off-by: Michal Simek --- arch/microblaze/cpu/start.S | 8 ++++++++ include/configs/microblaze-generic.h | 1 + 2 files changed, 9 insertions(+) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 3eeeab4b88..cf9ee7e3e6 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -29,8 +29,12 @@ _start: addi r1, r0, CONFIG_SPL_STACK_ADDR mts rshr, r1 addi r1, r1, -4 /* Decrement SP to top of memory */ +#else +#if defined(CONFIG_SYS_MALLOC_F_LEN) + addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_SYS_MALLOC_F_LEN #else addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET +#endif mts rshr, r1 addi r1, r1, -4 /* Decrement SP to top of memory */ @@ -152,6 +156,10 @@ clear_bss: #ifndef CONFIG_SPL_BUILD or r5, r0, r0 /* flags - empty */ addi r31, r0, _gd +#if defined(CONFIG_SYS_MALLOC_F_LEN) + addi r6, r0, CONFIG_SYS_INIT_SP_OFFSET + swi r6, r31, GD_MALLOC_BASE +#endif brai board_init_f #else addi r31, r0, CONFIG_SYS_SPL_MALLOC_END diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 622bc95104..770acbea69 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -113,6 +113,7 @@ #endif #define CONFIG_SYS_MALLOC_LEN 0xC0000 +#define CONFIG_SYS_MALLOC_F_LEN 1024 /* Stack location before relocation */ #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_TEXT_BASE -- cgit From ca7d22662e1ca1b05fd4cd3d1f80efec93c499ef Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 3 Feb 2015 16:24:48 +0100 Subject: microblaze: spl: Do not call mem_malloc_init and use early alloc This patch has some parts connected together: - Use _gd in bss section which is automatically cleared Location at SPL_MALLOC_END wasn't cleared at all - Use MALLOC_F_LEN(early alloc) instead of FULL MALLOC (mem_malloc_init is not called at all) - Simplify malloc and stack init. At the end of SPL addr is malloc area and below is stack Signed-off-by: Michal Simek --- arch/microblaze/cpu/start.S | 6 +++++- include/configs/microblaze-generic.h | 32 +++++++++++--------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index cf9ee7e3e6..953d3a15ee 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -162,7 +162,11 @@ clear_bss: #endif brai board_init_f #else - addi r31, r0, CONFIG_SYS_SPL_MALLOC_END + addi r31, r0, _gd +#if defined(CONFIG_SYS_MALLOC_F_LEN) + addi r6, r0, CONFIG_SPL_STACK_ADDR + swi r6, r31, GD_MALLOC_BASE +#endif brai board_init_r #endif 1: bri 1b diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 770acbea69..166ab4f056 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -113,7 +113,12 @@ #endif #define CONFIG_SYS_MALLOC_LEN 0xC0000 -#define CONFIG_SYS_MALLOC_F_LEN 1024 +#ifndef CONFIG_SPL_BUILD +# define CONFIG_SYS_MALLOC_F_LEN 1024 +#else +# define CONFIG_SYS_MALLOC_SIMPLE +# define CONFIG_SYS_MALLOC_F_LEN 0x150 +#endif /* Stack location before relocation */ #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_TEXT_BASE @@ -426,25 +431,11 @@ /* BRAM start */ #define CONFIG_SYS_INIT_RAM_ADDR 0x0 /* BRAM size - will be generated */ -#define CONFIG_SYS_INIT_RAM_SIZE 0x10000 -/* Stack pointer prior relocation, must situated at on-chip RAM */ -#define CONFIG_SYS_SPL_MALLOC_END (CONFIG_SYS_INIT_RAM_ADDR + \ - CONFIG_SYS_INIT_RAM_SIZE - \ - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_RAM_SIZE 0x100000 -#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100 - -/* - * The main reason to do it in this way is that MALLOC_START - * can't be defined - common/spl/spl.c - */ -#if (CONFIG_SYS_SPL_MALLOC_SIZE != 0) -# define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_SPL_MALLOC_END - \ - CONFIG_SYS_SPL_MALLOC_SIZE) -# define CONFIG_SPL_STACK_ADDR CONFIG_SYS_SPL_MALLOC_START -#else -# define CONFIG_SPL_STACK_ADDR CONFIG_SYS_SPL_MALLOC_END -#endif +# define CONFIG_SPL_STACK_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + CONFIG_SYS_MALLOC_F_LEN) /* Just for sure that there is a space for stack */ #define CONFIG_SPL_STACK_SIZE 0x100 @@ -453,8 +444,7 @@ #define CONFIG_SPL_MAX_FOOTPRINT (CONFIG_SYS_INIT_RAM_SIZE - \ CONFIG_SYS_INIT_RAM_ADDR - \ - GENERATED_GBL_DATA_SIZE - \ - CONFIG_SYS_SPL_MALLOC_SIZE - \ + CONFIG_SYS_MALLOC_F_LEN - \ CONFIG_SPL_STACK_SIZE) #endif /* __CONFIG_H */ -- cgit From 7f33899221e4235900760add69ffbb5f66f1229d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 3 Feb 2015 15:09:52 +0100 Subject: microblaze: spl: Add LISTS to linker script This is required for driver model. Signed-off-by: Michal Simek --- arch/microblaze/cpu/u-boot-spl.lds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/microblaze/cpu/u-boot-spl.lds b/arch/microblaze/cpu/u-boot-spl.lds index 96353cd96c..c60336ca5c 100644 --- a/arch/microblaze/cpu/u-boot-spl.lds +++ b/arch/microblaze/cpu/u-boot-spl.lds @@ -37,6 +37,12 @@ SECTIONS __data_end = .; } + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + __init_end = . ; + .bss ALIGN(0x4): { __bss_start = .; -- cgit From 1730af1bbde28e5fcf327eea1cdc29bc590e7478 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 9 Jan 2015 16:59:40 +0800 Subject: imx:mx6 update fuse_bank0_regs Update fuse_bank0_regs structure according reference mannual. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-mx6/imx-regs.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index c968600b77..22f371d253 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -624,12 +624,16 @@ struct fuse_bank0_regs { u32 rsvd1[3]; u32 uid_high; u32 rsvd2[3]; - u32 rsvd3[4]; - u32 rsvd4[4]; - u32 rsvd5[4]; + u32 cfg2; + u32 rsvd3[3]; + u32 cfg3; + u32 rsvd4[3]; + u32 cfg4; + u32 rsvd5[3]; u32 cfg5; u32 rsvd6[3]; - u32 rsvd7[4]; + u32 cfg6; + u32 rsvd7[3]; }; #ifdef CONFIG_MX6SX -- cgit From ee52f1a5fedcb261f75054352a2ef52f7a6e6dbc Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 9 Jan 2015 16:59:41 +0800 Subject: pmic:pfuze add macro for setting voltage "#define PFUZE100_SW1ABC_SETP(x) ((x - 3000) / 250)" This macro is for configuring SW1A/B/C Output Voltage easily. Signed-off-by: Peng Fan --- include/power/pfuze100_pmic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h index 11184893bf..a00fde0168 100644 --- a/include/power/pfuze100_pmic.h +++ b/include/power/pfuze100_pmic.h @@ -41,6 +41,8 @@ enum { * Buck Regulators */ +#define PFUZE100_SW1ABC_SETP(x) ((x - 3000) / 250) + /* SW1A/B/C Output Voltage Configuration */ #define SW1x_0_300V 0 #define SW1x_0_325V 1 -- cgit From ccbb18713b279f1326479cc10664d247206e9e76 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 8 Jan 2015 21:00:36 +0800 Subject: pmic:pfuz100 add switch mode and more registers Add more pfuze register offset. And switch mode definition. Signed-off-by: Peng Fan --- include/power/pfuze100_pmic.h | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h index a00fde0168..d304658b9a 100644 --- a/include/power/pfuze100_pmic.h +++ b/include/power/pfuze100_pmic.h @@ -16,14 +16,34 @@ enum { PFUZE100_SW1ABVOL = 0x20, PFUZE100_SW1ABSTBY = 0x21, + PFUZE100_SW1ABOFF = 0x22, + PFUZE100_SW1ABMODE = 0x23, PUZE_100_SW1ABCONF = 0x24, PFUZE100_SW1CVOL = 0x2e, PFUZE100_SW1CSTBY = 0x2f, + PFUZE100_SW1COFF = 0x30, + PFUZE100_SW1CMODE = 0x31, PFUZE100_SW1CCONF = 0x32, PFUZE100_SW2VOL = 0x35, + PFUZE100_SW2STBY = 0x36, + PFUZE100_SW2OFF = 0x37, + PFUZE100_SW2MODE = 0x38, + PFUZE100_SW2CONF = 0x39, PFUZE100_SW3AVOL = 0x3c, + PFUZE100_SW3ASTBY = 0x3D, + PFUZE100_SW3AOFF = 0x3E, + PFUZE100_SW3AMODE = 0x3F, + PFUZE100_SW3ACONF = 0x40, PFUZE100_SW3BVOL = 0x43, + PFUZE100_SW3BSTBY = 0x44, + PFUZE100_SW3BOFF = 0x45, + PFUZE100_SW3BMODE = 0x46, + PFUZE100_SW3BCONF = 0x47, PFUZE100_SW4VOL = 0x4a, + PFUZE100_SW4STBY = 0x4b, + PFUZE100_SW4OFF = 0x4c, + PFUZE100_SW4MODE = 0x4d, + PFUZE100_SW4CONF = 0x4e, PFUZE100_SWBSTCON1 = 0x66, PFUZE100_VREFDDRCON = 0x6a, PFUZE100_VSNVSVOL = 0x6b, @@ -179,5 +199,38 @@ enum { #define SWBST_MODE_AUTO (2 << 2) #define SWBST_MODE_APS (2 << 3) +/* + * Regulator Mode Control + * + * OFF: The regulator is switched off and the output voltage is discharged. + * PFM: In this mode, the regulator is always in PFM mode, which is useful + * at light loads for optimized efficiency. + * PWM: In this mode, the regulator is always in PWM mode operation + * regardless of load conditions. + * APS: In this mode, the regulator moves automatically between pulse + * skipping mode and PWM mode depending on load conditions. + * + * SWxMODE[3:0] + * Normal Mode | Standby Mode | value + * OFF OFF 0x0 + * PWM OFF 0x1 + * PFM OFF 0x3 + * APS OFF 0x4 + * PWM PWM 0x5 + * PWM APS 0x6 + * APS APS 0x8 + * APS PFM 0xc + * PWM PFM 0xd + */ +#define OFF_OFF 0x0 +#define PWM_OFF 0x1 +#define PFM_OFF 0x3 +#define APS_OFF 0x4 +#define PWM_PWM 0x5 +#define PWM_APS 0x6 +#define APS_APS 0x8 +#define APS_PFM 0xc +#define PWM_PFM 0xd + int power_pfuze100_init(unsigned char bus); #endif -- cgit From 5f22d88f82082019ce631bb7cb635bb075170c9c Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Mon, 12 Jan 2015 17:37:13 +0800 Subject: imx: mx6qsabreauto: Change to use common GPMI IO clock function Since a clock function setup_gpmi_io_clk is implemented for GPMI IO clock settings, change to use this common function in GPMI setup. Signed-off-by: Ye.Li Acked-by: Stefano Babic --- board/freescale/mx6qsabreauto/mx6qsabreauto.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c index 59387ffaaa..a90360f2df 100644 --- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c +++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c @@ -311,30 +311,9 @@ static void setup_gpmi_nand(void) /* config gpmi nand iomux */ imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads)); - /* gate ENFC_CLK_ROOT clock first,before clk source switch */ - clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); - clrbits_le32(&mxc_ccm->CCGR4, - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); - - /* config gpmi and bch clock to 100 MHz */ - clrsetbits_le32(&mxc_ccm->cs2cdr, - MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | - MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | - MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, - MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | + setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | - MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)); - - /* enable ENFC_CLK_ROOT clock */ - setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); - - /* enable gpmi and bch clock gating */ - setbits_le32(&mxc_ccm->CCGR4, - MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | - MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET); + MXC_CCM_CS2CDR_ENFC_CLK_SEL(3))); /* enable apbh clock gating */ setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); -- cgit From 9598f8c30cb3535b96c8b33638f016d67691e076 Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Tue, 13 Jan 2015 15:53:06 +0800 Subject: imx: imximage: Add QuadSPI boot support Add QuadSPI boot support to imximage tool. Note: The QuadSPI configuration parameters at offset 0x400 are not included in this patch. Need other tools to generate the parameters part. Signed-off-by: Ye.Li --- tools/imximage.c | 2 ++ tools/imximage.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tools/imximage.c b/tools/imximage.c index 526b7d490d..f880edd96b 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -38,6 +38,7 @@ static table_entry_t imximage_boot_offset[] = { {FLASH_OFFSET_SATA, "sata", "SATA Disk", }, {FLASH_OFFSET_SD, "sd", "SD Card", }, {FLASH_OFFSET_SPI, "spi", "SPI Flash", }, + {FLASH_OFFSET_QSPI, "qspi", "QSPI NOR Flash",}, {-1, "", "Invalid", }, }; @@ -52,6 +53,7 @@ static table_entry_t imximage_boot_loadsize[] = { {FLASH_LOADSIZE_SATA, "sata", "SATA Disk", }, {FLASH_LOADSIZE_SD, "sd", "SD Card", }, {FLASH_LOADSIZE_SPI, "spi", "SPI Flash", }, + {FLASH_LOADSIZE_QSPI, "qspi", "QSPI NOR Flash",}, {-1, "", "Invalid", }, }; diff --git a/tools/imximage.h b/tools/imximage.h index 5b5ad0edf4..36fe0958fe 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -29,6 +29,7 @@ #define FLASH_OFFSET_ONENAND 0x100 #define FLASH_OFFSET_NOR 0x1000 #define FLASH_OFFSET_SATA FLASH_OFFSET_STANDARD +#define FLASH_OFFSET_QSPI 0x1000 /* Initial Load Region Size */ #define FLASH_LOADSIZE_UNDEFINED 0xFFFFFFFF @@ -39,6 +40,7 @@ #define FLASH_LOADSIZE_ONENAND 0x400 #define FLASH_LOADSIZE_NOR 0x0 /* entire image */ #define FLASH_LOADSIZE_SATA FLASH_LOADSIZE_STANDARD +#define FLASH_LOADSIZE_QSPI 0x0 /* entire image */ #define IVT_HEADER_TAG 0xD1 #define IVT_VERSION 0x40 -- cgit From e8cdeefc222ff32a80282dd571be0426156cd9d9 Mon Sep 17 00:00:00 2001 From: "Ye.Li" Date: Wed, 14 Jan 2015 17:18:12 +0800 Subject: imx: mx6: Fixed AIPS3 base address issue Should use AIPS3 configuration address 0x0227C000 to set AIPS3, not the AIPS3 base address. Additional, replace AIPS1_BASE_ADDR to AIPS3_ARB_BASE_ADDR to align with AIPS1 and AIPS2, and resolve the AIPS3_ARB_BASE_ADDR undefine problem. Signed-off-by: Ye.Li --- arch/arm/cpu/armv7/mx6/soc.c | 2 +- arch/arm/include/asm/arch-mx6/imx-regs.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 5f5f497201..e599a12b3a 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -109,7 +109,7 @@ void init_aips(void) aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR; aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR; #ifdef CONFIG_MX6SX - aips3 = (struct aipstz_regs *)AIPS3_BASE_ADDR; + aips3 = (struct aipstz_regs *)AIPS3_CONFIG_BASE_ADDR; #endif /* diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 22f371d253..ae88b6ecab 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -88,8 +88,8 @@ #define AIPS2_ARB_BASE_ADDR 0x02100000 #define AIPS2_ARB_END_ADDR 0x021FFFFF #ifdef CONFIG_MX6SX -#define AIPS3_BASE_ADDR 0x02200000 -#define AIPS3_END_ADDR 0x022FFFFF +#define AIPS3_ARB_BASE_ADDR 0x02200000 +#define AIPS3_ARB_END_ADDR 0x022FFFFF #define WEIM_ARB_BASE_ADDR 0x50000000 #define WEIM_ARB_END_ADDR 0x57FFFFFF #define QSPI0_AMBA_BASE 0x60000000 -- cgit From 950eaf6230496585e72ebb965c458d35c6c7eac1 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sun, 25 Jan 2015 12:07:51 +1100 Subject: arm: mxs: Add debug outputs and comments to mxs SPL source files It is difficult to track down fail to boot issues in the mxs SPL. Implement the following to make it easier: - Add debug outputs to allow tracing of SPL progress in order to track where failure to boot occurs. DEUBUG and CONFIG_SPL_SERIAL_SUPPORT must be defined to enable debug output in SPL - Add TODO comments where it is not clear if the code is doing what it is meant to be doing, even tough the board boots properly (these comments refer to existing code, not to any code added by this patch) Signed-off-by: Graeme Russ --- arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 1 + arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c | 13 +++- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 18 +++++ arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 100 +++++++++++++++++++++++++++- 4 files changed, 127 insertions(+), 5 deletions(-) diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index d29b9aaf3d..2a5f8175d0 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -147,6 +147,7 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size); mxs_spl_console_init(); + debug("SPL: Serial Console Initialised\n"); mxs_power_init(); diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c index cdfcddd824..96bd32f8ad 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c @@ -18,6 +18,8 @@ void mxs_lradc_init(void) { struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE; + debug("SPL: Initialisating LRADC\n"); + writel(LRADC_CTRL0_SFTRST, ®s->hw_lradc_ctrl0_clr); writel(LRADC_CTRL0_CLKGATE, ®s->hw_lradc_ctrl0_clr); writel(LRADC_CTRL0_ONCHIP_GROUNDREF, ®s->hw_lradc_ctrl0_clr); @@ -37,9 +39,15 @@ void mxs_lradc_enable_batt_measurement(void) { struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE; + debug("SPL: Enabling LRADC battery measurement\n"); + /* Check if the channel is present at all. */ - if (!(readl(®s->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) + if (!(readl(®s->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) { + debug("SPL: LRADC channel 7 is not present - aborting\n"); return; + } + + debug("SPL: LRADC channel 7 is present - configuring\n"); writel(LRADC_CTRL1_LRADC7_IRQ_EN, ®s->hw_lradc_ctrl1_clr); writel(LRADC_CTRL1_LRADC7_IRQ, ®s->hw_lradc_ctrl1_clr); @@ -65,6 +73,7 @@ void mxs_lradc_enable_batt_measurement(void) 100, ®s->hw_lradc_delay3); writel(0xffffffff, ®s->hw_lradc_ch7_clr); - writel(LRADC_DELAY_KICK, ®s->hw_lradc_delay3_set); + + debug("SPL: LRADC channel 7 configuration complete\n"); } diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index 97ef67d8c5..a744e5d499 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -92,6 +92,7 @@ static uint32_t dram_vals[] = { __weak void mxs_adjust_memory_params(uint32_t *dram_vals) { + debug("SPL: Using default SDRAM parameters\n"); } #ifdef CONFIG_MX28 @@ -99,8 +100,10 @@ static void initialize_dram_values(void) { int i; + debug("SPL: Setting mx28 board specific SDRAM parameters\n"); mxs_adjust_memory_params(dram_vals); + debug("SPL: Applying SDRAM parameters\n"); for (i = 0; i < ARRAY_SIZE(dram_vals); i++) writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); } @@ -109,6 +112,7 @@ static void initialize_dram_values(void) { int i; + debug("SPL: Setting mx23 board specific SDRAM parameters\n"); mxs_adjust_memory_params(dram_vals); /* @@ -120,6 +124,7 @@ static void initialize_dram_values(void) * HW_DRAM_CTL8 is setup as the last element. * So skip the initialization of these HW_DRAM_CTL registers. */ + debug("SPL: Applying SDRAM parameters\n"); for (i = 0; i < ARRAY_SIZE(dram_vals); i++) { if (i == 8 || i == 27 || i == 28 || i == 35) continue; @@ -146,6 +151,8 @@ static void mxs_mem_init_clock(void) const unsigned char divider = 21; #endif + debug("SPL: Initialising FRAC0\n"); + /* Gate EMI clock */ writeb(CLKCTRL_FRAC_CLKGATE, &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]); @@ -170,6 +177,7 @@ static void mxs_mem_init_clock(void) &clkctrl_regs->hw_clkctrl_clkseq_clr); early_delay(10000); + debug("SPL: FRAC0 Initialised\n"); } static void mxs_mem_setup_cpu_and_hbus(void) @@ -177,6 +185,8 @@ static void mxs_mem_setup_cpu_and_hbus(void) struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + debug("SPL: Setting CPU and HBUS clock frequencies\n"); + /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz * and ungate CPU clock */ writeb(19 & CLKCTRL_FRAC_FRAC_MASK, @@ -209,6 +219,8 @@ static void mxs_mem_setup_vdda(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Configuring VDDA\n"); + writel((0xc << POWER_VDDACTRL_TRG_OFFSET) | (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) | POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW, @@ -240,6 +252,8 @@ static void mx23_mem_setup_vddmem(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Setting mx23 VDDMEM\n"); + /* We must wait before and after disabling the current limiter! */ early_delay(10000); @@ -252,6 +266,8 @@ static void mx23_mem_setup_vddmem(void) static void mx23_mem_init(void) { + debug("SPL: Initialising mx23 SDRAM Controller\n"); + /* * Reset/ungate the EMI block. This is essential, otherwise the system * suffers from memory instability. This thing is mx23 specific and is @@ -297,6 +313,8 @@ static void mx28_mem_init(void) struct mxs_pinctrl_regs *pinctrl_regs = (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE; + debug("SPL: Initialising mx28 SDRAM Controller\n"); + /* Set DDR2 mode */ writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2, &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set); diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index 1c54ab7de3..7fb734e9dc 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -26,6 +26,8 @@ static void mxs_power_clock2xtal(void) struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + debug("SPL: Switching CPU clock to 24MHz XTAL\n"); + /* Set XTAL as CPU reference clock */ writel(CLKCTRL_CLKSEQ_BYPASS_CPU, &clkctrl_regs->hw_clkctrl_clkseq_set); @@ -43,9 +45,23 @@ static void mxs_power_clock2pll(void) struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + debug("SPL: Switching CPU core clock source to PLL\n"); + + /* + * TODO: Are we really? It looks like we turn on PLL0, but we then + * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already + * set by mxs_power_clock2xtal()). Clearing this bit here seems to + * introduce some instability (causing the CPU core to hang). Maybe + * we aren't giving PLL0 enough time to stabilise? + */ setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0, CLKCTRL_PLL0CTRL0_POWER); early_delay(100); + + /* + * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a + * wait on the PLL0 LOCK bit? + */ setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq, CLKCTRL_CLKSEQ_BYPASS_CPU); } @@ -62,6 +78,8 @@ static void mxs_power_set_auto_restart(void) struct mxs_rtc_regs *rtc_regs = (struct mxs_rtc_regs *)MXS_RTC_BASE; + debug("SPL: Setting auto-restart bit\n"); + writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr); while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST) ; @@ -101,14 +119,17 @@ static void mxs_power_set_linreg(void) (struct mxs_power_regs *)MXS_POWER_BASE; /* Set linear regulator 25mV below switching converter */ + debug("SPL: Setting VDDD 25mV below DC-DC converters\n"); clrsetbits_le32(&power_regs->hw_power_vdddctrl, POWER_VDDDCTRL_LINREG_OFFSET_MASK, POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); + debug("SPL: Setting VDDA 25mV below DC-DC converters\n"); clrsetbits_le32(&power_regs->hw_power_vddactrl, POWER_VDDACTRL_LINREG_OFFSET_MASK, POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW); + debug("SPL: Setting VDDIO 25mV below DC-DC converters\n"); clrsetbits_le32(&power_regs->hw_power_vddioctrl, POWER_VDDIOCTRL_LINREG_OFFSET_MASK, POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); @@ -127,6 +148,8 @@ static int mxs_get_batt_volt(void) volt &= POWER_BATTMONITOR_BATT_VAL_MASK; volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET; volt *= 8; + + debug("SPL: Battery Voltage = %dmV\n", volt); return volt; } @@ -154,8 +177,10 @@ static int mxs_is_batt_good(void) (struct mxs_power_regs *)MXS_POWER_BASE; uint32_t volt = mxs_get_batt_volt(); - if ((volt >= 2400) && (volt <= 4300)) + if ((volt >= 2400) && (volt <= 4300)) { + debug("SPL: Battery is good\n"); return 1; + } clrsetbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, @@ -175,16 +200,21 @@ static int mxs_is_batt_good(void) volt = mxs_get_batt_volt(); - if (volt >= 3500) + if (volt >= 3500) { + debug("SPL: Battery Voltage too high\n"); return 0; + } - if (volt >= 2400) + if (volt >= 2400) { + debug("SPL: Battery is good\n"); return 1; + } writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, &power_regs->hw_power_charge_clr); writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set); + debug("SPL: Battery Voltage too low\n"); return 0; } @@ -203,6 +233,7 @@ static void mxs_power_setup_5v_detect(void) (struct mxs_power_regs *)MXS_POWER_BASE; /* Start 5V detection */ + debug("SPL: Starting 5V input detection comparator\n"); clrsetbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_VBUSVALID_TRSH_MASK, POWER_5VCTRL_VBUSVALID_TRSH_4V4 | @@ -220,6 +251,8 @@ static void mxs_src_power_init(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Pre-Configuring power block\n"); + /* Improve efficieny and reduce transient ripple */ writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST | POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set); @@ -257,6 +290,8 @@ static void mxs_power_init_4p2_params(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Configuring common 4P2 regulator params\n"); + /* Setup 4P2 parameters */ clrsetbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, @@ -289,6 +324,8 @@ static void mxs_enable_4p2_dcdc_input(int xfer) uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo; uint32_t prev_5v_brnout, prev_5v_droop; + debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling"); + prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) & POWER_5VCTRL_PWDN_5VBRNOUT; prev_5v_droop = readl(&power_regs->hw_power_ctrl) & @@ -390,6 +427,8 @@ static void mxs_power_init_4p2_regulator(void) (struct mxs_power_regs *)MXS_POWER_BASE; uint32_t tmp, tmp2; + debug("SPL: Enabling 4P2 regulator\n"); + setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set); @@ -407,6 +446,7 @@ static void mxs_power_init_4p2_regulator(void) * gradually to avoid large inrush current from the 5V cable which can * cause transients/problems */ + debug("SPL: Charging 4P2 capacitor\n"); mxs_enable_4p2_dcdc_input(0); if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { @@ -420,6 +460,8 @@ static void mxs_power_init_4p2_regulator(void) POWER_DCDC4P2_ENABLE_DCDC); writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, &power_regs->hw_power_5vctrl_set); + + debug("SPL: Unable to recover from mx23 errata 5837\n"); hang(); } @@ -433,6 +475,7 @@ static void mxs_power_init_4p2_regulator(void) * current limit until the brownout status is false or until we've * reached our maximum defined 4p2 current limit. */ + debug("SPL: Setting 4P2 brownout level\n"); clrsetbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK, 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */ @@ -479,8 +522,11 @@ static void mxs_power_init_dcdc_4p2_source(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Switching DC-DC converters to 4P2\n"); + if (!(readl(&power_regs->hw_power_dcdc4p2) & POWER_DCDC4P2_ENABLE_DCDC)) { + debug("SPL: Already switched - aborting\n"); hang(); } @@ -509,6 +555,8 @@ static void mxs_power_enable_4p2(void) uint32_t vdddctrl, vddactrl, vddioctrl; uint32_t tmp; + debug("SPL: Powering up 4P2 regulator\n"); + vdddctrl = readl(&power_regs->hw_power_vdddctrl); vddactrl = readl(&power_regs->hw_power_vddactrl); vddioctrl = readl(&power_regs->hw_power_vddioctrl); @@ -559,6 +607,8 @@ static void mxs_power_enable_4p2(void) if (tmp) writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr); + + debug("SPL: 4P2 regulator powered-up\n"); } /** @@ -574,6 +624,8 @@ static void mxs_boot_valid_5v(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Booting from 5V supply\n"); + /* * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V * disconnect event. FIXME @@ -601,6 +653,9 @@ static void mxs_powerdown(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("Powering Down\n"); + writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset); writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, &power_regs->hw_power_reset); @@ -617,6 +672,8 @@ static void mxs_batt_boot(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Configuring power block to boot from battery\n"); + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC); @@ -672,6 +729,8 @@ static void mxs_handle_5v_conflict(void) (struct mxs_power_regs *)MXS_POWER_BASE; uint32_t tmp; + debug("SPL: Resolving 5V conflict\n"); + setbits_le32(&power_regs->hw_power_vddioctrl, POWER_VDDIOCTRL_BO_OFFSET_MASK); @@ -683,19 +742,27 @@ static void mxs_handle_5v_conflict(void) * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes * unreliable */ + debug("SPL: VDDIO has a brownout\n"); mxs_powerdown(); break; } if (tmp & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n"); mxs_boot_valid_5v(); break; } else { + debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n"); mxs_powerdown(); break; } + /* + * TODO: I can't see this being reached. We'll either + * powerdown or boot from a stable 5V supply. + */ if (tmp & POWER_STS_PSWITCH_MASK) { + debug("SPL: POWER_STS_PSWITCH_MASK is set\n"); mxs_batt_boot(); break; } @@ -713,21 +780,26 @@ static void mxs_5v_boot(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Configuring power block to boot from 5V input\n"); + /* * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID, * but their implementation always returns 1 so we omit it here. */ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: 5V VDD good\n"); mxs_boot_valid_5v(); return; } early_delay(1000); if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: 5V VDD good (after delay)\n"); mxs_boot_valid_5v(); return; } + debug("SPL: 5V VDD not good\n"); mxs_handle_5v_conflict(); } @@ -742,6 +814,8 @@ static void mxs_init_batt_bo(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Initialising battery brown-out level to 3.0V\n"); + /* Brownout at 3V */ clrsetbits_le32(&power_regs->hw_power_battmonitor, POWER_BATTMONITOR_BRWNOUT_LVL_MASK, @@ -762,6 +836,8 @@ static void mxs_switch_vddd_to_dcdc_source(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Switching VDDD to DC-DC converters\n"); + clrsetbits_le32(&power_regs->hw_power_vdddctrl, POWER_VDDDCTRL_LINREG_OFFSET_MASK, POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); @@ -788,6 +864,8 @@ static void mxs_power_configure_power_source(void) struct mxs_lradc_regs *lradc_regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE; + debug("SPL: Configuring power source\n"); + mxs_src_power_init(); if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { @@ -811,6 +889,10 @@ static void mxs_power_configure_power_source(void) mxs_batt_boot(); } + /* + * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced + * from USB VBUS + */ mxs_power_clock2pll(); mxs_init_batt_bo(); @@ -819,6 +901,7 @@ static void mxs_power_configure_power_source(void) #ifdef CONFIG_MX23 /* Fire up the VDDMEM LinReg now that we're all set. */ + debug("SPL: Enabling mx23 VDDMEM linear regulator\n"); writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT, &power_regs->hw_power_vddmemctrl); #endif @@ -838,6 +921,8 @@ static void mxs_enable_output_rail_protection(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Enabling output rail protection\n"); + writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr); @@ -1077,6 +1162,8 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, */ static void mxs_setup_batt_detect(void) { + debug("SPL: Starting battery voltage measurement logic\n"); + mxs_lradc_init(); mxs_lradc_enable_batt_measurement(); early_delay(10); @@ -1111,6 +1198,8 @@ void mxs_power_init(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Initialising Power Block\n"); + mxs_ungate_power(); mxs_power_clock2xtal(); @@ -1123,9 +1212,13 @@ void mxs_power_init(void) mxs_power_configure_power_source(); mxs_enable_output_rail_protection(); + debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n"); mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); + + debug("SPL: Setting VDDD to 1V5 (brownout @ 1v0)\n"); mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); #ifdef CONFIG_MX23 + debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n"); mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); #endif writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | @@ -1150,6 +1243,7 @@ void mxs_power_wait_pswitch(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + debug("SPL: Waiting for power switch input\n"); while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK)) ; } -- cgit From 7a086037071401ee781425c382846dddfe80df68 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sun, 25 Jan 2015 12:07:52 +1100 Subject: arm: mxs: Enable booting of mx28 without battery Section 4.1.2 of Freescale Application Note AN4199 describes the configuration required to operate the mx28 from a 5V source without a battery. This patch changes the behaviour of the dropout control of the DC-DC converter (refer to section 11.12.9 of the mx28 Application Processor Reference Manual - Document Number: MCIMX28RM, Rev 2, 08/2013) to the following: - Always use 4P2 Linear Regulator if CONFIG_SYS_MXS_VDD5V_ONLY is defined - Switch between 4P2 Linear Regulator and Battery, using whichever has the highest voltage if CONFIG_SYS_MXS_VDD5V_ONLY isnot set (this is the same as the pre-patch behaviour) Signed-off-by: Graeme Russ Signed-off-by: Damien Gotfroi --- arch/arm/cpu/arm926ejs/mxs/spl_power_init.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index 7fb734e9dc..c342217fa9 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -14,6 +14,13 @@ #include "mxs_init.h" +#ifdef CONFIG_SYS_MXS_VDD5V_ONLY +#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ + POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2 +#else +#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ + POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL +#endif /** * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL * @@ -303,8 +310,7 @@ static void mxs_power_init_4p2_params(void) clrsetbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_DROPOUT_CTRL_MASK, - POWER_DCDC4P2_DROPOUT_CTRL_100MV | - POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); + DCDC4P2_DROPOUT_CONFIG); clrsetbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, -- cgit From 2d6286ab7983b1fca45b7cc2d670286ec4898ffd Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sun, 25 Jan 2015 12:07:53 +1100 Subject: arm: mxs: Add 'Wait for JTAG user' if booted in JTAG mode When booting in JTAG mode, there is no way to use soft break-points, and no way of knowing when SPL has finished executing (so the user can issue a 'halt' command to load u-boot.bin for example) Add a debug output and simple loop to stop execution at the completion of the SPL initialisation as a pseudo break-point when booting in JTAG mode Signed-off-by: Graeme Russ --- arch/arm/cpu/arm926ejs/mxs/spl_boot.c | 5 +++++ arch/arm/include/asm/arch-mxs/sys_proto.h | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 2a5f8175d0..d7956e57de 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -157,6 +157,11 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, data->boot_mode_idx = bootmode; mxs_power_wait_pswitch(); + + if (mxs_boot_modes[data->boot_mode_idx].boot_pads == MXS_BM_JTAG) { + debug("SPL: Waiting for JTAG user\n"); + asm volatile ("x: b x"); + } } /* Support aparatus */ diff --git a/arch/arm/include/asm/arch-mxs/sys_proto.h b/arch/arm/include/asm/arch-mxs/sys_proto.h index 062f3de1d0..4678723754 100644 --- a/arch/arm/include/asm/arch-mxs/sys_proto.h +++ b/arch/arm/include/asm/arch-mxs/sys_proto.h @@ -74,6 +74,23 @@ static const struct mxs_pair mxs_boot_modes[] = { #endif }; +#define MXS_BM_USB 0x00 +#define MXS_BM_I2C_MASTER_3V3 0x01 +#define MXS_BM_I2C_MASTER_1V8 0x11 +#define MXS_BM_SPI2_MASTER_3V3_NOR 0x02 +#define MXS_BM_SPI2_MASTER_1V8_NOR 0x12 +#define MXS_BM_SPI3_MASTER_3V3_NOR 0x03 +#define MXS_BM_SPI3_MASTER_1V8_NOR 0x13 +#define MXS_BM_NAND_3V3 0x04 +#define MXS_BM_NAND_1V8 0x14 +#define MXS_BM_JTAG 0x06 +#define MXS_BM_SPI3_MASTER_3V3_EEPROM 0x08 +#define MXS_BM_SPI3_MASTER_1V8_EEPROM 0x18 +#define MXS_BM_SDMMC0_3V3 0x09 +#define MXS_BM_SDMMC0_1V8 0x19 +#define MXS_BM_SDMMC1_3V3 0x0a +#define MXS_BM_SDMMC1_1V8 0x1a + struct mxs_spl_data { uint8_t boot_mode_idx; uint32_t mem_dram_size; -- cgit From aee0013e53b339a573e2a8d66062fe87765aa3bd Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 9 Feb 2015 07:29:33 -0200 Subject: mx53loco: Fix boot hang during reboot stress test Currently by running the following test: => setenv bootcmd reset => save => reset , we observe a hang after approximately 20-30 minutes of stress reboot test. Investigation of this issue revealed that when a single DDR chip select is used, the hang does not happen. It only happens when the two chip selects are active. MX53 reference manual states at "28.6.2 Memory ZQ calibration sequence": "The controller must keep the memory lines quiet (except for CK) for the ZQ calibration time as defined in the Jedec (512 cycles for ZQCL after reset, 256 for other ZQCL and 64 for ZQCS)." According to the SDE_0 and SDE_1 bit descriptions from register ESDCTL_ESDCTL: "Writing 1 to SDE0 or SDE1 will initiate power up delays as JEDEC defines. Power up delays are a function of the configured memory type (DDR2/DDR3/LPDDR2)" So make sure to activate one chip select at time (CS0 first and then CS1 later), so that the required JEDEC delay is respected for each chip select. With this change applied the board has gone through three days of reboot stress test without any hang. Signed-off-by: Fabio Estevam Acked-by: Stefano Babic --- board/freescale/mx53loco/imximage.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/freescale/mx53loco/imximage.cfg b/board/freescale/mx53loco/imximage.cfg index d1c1931e46..a5f1d98bd1 100644 --- a/board/freescale/mx53loco/imximage.cfg +++ b/board/freescale/mx53loco/imximage.cfg @@ -59,7 +59,7 @@ DATA 4 0x63fd9090 0x4d444c44 DATA 4 0x63fd907c 0x01370138 DATA 4 0x63fd9080 0x013b013c DATA 4 0x63fd9018 0x00011740 -DATA 4 0x63fd9000 0xc3190000 +DATA 4 0x63fd9000 0x83190000 DATA 4 0x63fd900c 0x9f5152e3 DATA 4 0x63fd9010 0xb68e8a63 DATA 4 0x63fd9014 0x01ff00db @@ -72,6 +72,7 @@ DATA 4 0x63fd901c 0x00008033 DATA 4 0x63fd901c 0x00028031 DATA 4 0x63fd901c 0x052080b0 DATA 4 0x63fd901c 0x04008040 +DATA 4 0x63fd9000 0xc3190000 DATA 4 0x63fd901c 0x0000803a DATA 4 0x63fd901c 0x0000803b DATA 4 0x63fd901c 0x00028039 -- cgit From baaa7dd7061521509792ca158508b2c4554a7184 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:20 +0200 Subject: lcd: move platform-specific structs to their own headers common/lcd code is full of platform-specific code and definitions, which ideally should reside with the respective driver code. Take a step towards that goal by moving platform-specific structs from lcd.h to their own header files. The structs for the generic case (the #else for all the platform-specific cases) is retained in lcd.h as the default case. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- include/atmel_lcd.h | 38 ++++++++++ include/exynos_lcd.h | 81 +++++++++++++++++++++ include/lcd.h | 201 ++------------------------------------------------- include/mpc823_lcd.h | 43 +++++++++++ include/pxa_lcd.h | 80 ++++++++++++++++++++ 5 files changed, 247 insertions(+), 196 deletions(-) create mode 100644 include/atmel_lcd.h create mode 100644 include/exynos_lcd.h create mode 100644 include/mpc823_lcd.h create mode 100644 include/pxa_lcd.h diff --git a/include/atmel_lcd.h b/include/atmel_lcd.h new file mode 100644 index 0000000000..fa8aa29454 --- /dev/null +++ b/include/atmel_lcd.h @@ -0,0 +1,38 @@ +/* + * atmel_lcd.h - Atmel LCD Controller structures + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ATMEL_LCD_H_ +#define _ATMEL_LCD_H_ + +typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 640) */ + ushort vl_row; /* Number of rows (i.e. 480) */ + u_long vl_clk; /* pixel clock in ps */ + + /* LCD configuration register */ + u_long vl_sync; /* Horizontal / vertical sync */ + u_long vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ + u_long vl_tft; /* 0 = passive, 1 = TFT */ + u_long vl_cont_pol_low; /* contrast polarity is low */ + u_long vl_clk_pol; /* clock polarity */ + + /* Horizontal control register. */ + u_long vl_hsync_len; /* Length of horizontal sync */ + u_long vl_left_margin; /* Time from sync to picture */ + u_long vl_right_margin; /* Time from picture to sync */ + + /* Vertical control register. */ + u_long vl_vsync_len; /* Length of vertical sync */ + u_long vl_upper_margin; /* Time from sync to picture */ + u_long vl_lower_margin; /* Time from picture to sync */ + + u_long mmio; /* Memory mapped registers */ +} vidinfo_t; + +#endif diff --git a/include/exynos_lcd.h b/include/exynos_lcd.h new file mode 100644 index 0000000000..cf389dac69 --- /dev/null +++ b/include/exynos_lcd.h @@ -0,0 +1,81 @@ +/* + * exynos_lcd.h - Exynos LCD Controller structures + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _EXYNOS_LCD_H_ +#define _EXYNOS_LCD_H_ + +enum { + FIMD_RGB_INTERFACE = 1, + FIMD_CPU_INTERFACE = 2, +}; + +enum exynos_fb_rgb_mode_t { + MODE_RGB_P = 0, + MODE_BGR_P = 1, + MODE_RGB_S = 2, + MODE_BGR_S = 3, +}; + +typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 640) */ + ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_width; /* Width of display area in millimeters */ + ushort vl_height; /* Height of display area in millimeters */ + + /* LCD configuration register */ + u_char vl_freq; /* Frequency */ + u_char vl_clkp; /* Clock polarity */ + u_char vl_oep; /* Output Enable polarity */ + u_char vl_hsp; /* Horizontal Sync polarity */ + u_char vl_vsp; /* Vertical Sync polarity */ + u_char vl_dp; /* Data polarity */ + u_char vl_bpix; /* Bits per pixel */ + + /* Horizontal control register. Timing from data sheet */ + u_char vl_hspw; /* Horz sync pulse width */ + u_char vl_hfpd; /* Wait before of line */ + u_char vl_hbpd; /* Wait end of line */ + + /* Vertical control register. */ + u_char vl_vspw; /* Vertical sync pulse width */ + u_char vl_vfpd; /* Wait before of frame */ + u_char vl_vbpd; /* Wait end of frame */ + u_char vl_cmd_allow_len; /* Wait end of frame */ + + unsigned int win_id; + unsigned int init_delay; + unsigned int power_on_delay; + unsigned int reset_delay; + unsigned int interface_mode; + unsigned int mipi_enabled; + unsigned int dp_enabled; + unsigned int cs_setup; + unsigned int wr_setup; + unsigned int wr_act; + unsigned int wr_hold; + unsigned int logo_on; + unsigned int logo_width; + unsigned int logo_height; + int logo_x_offset; + int logo_y_offset; + unsigned long logo_addr; + unsigned int rgb_mode; + unsigned int resolution; + + /* parent clock name(MPLL, EPLL or VPLL) */ + unsigned int pclk_name; + /* ratio value for source clock from parent clock. */ + unsigned int sclk_div; + + unsigned int dual_lcd_enabled; +} vidinfo_t; + +void init_panel_info(vidinfo_t *vid); + +#endif diff --git a/include/lcd.h b/include/lcd.h index 160f940d2a..fbba6a27f9 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -41,205 +41,15 @@ int bmp_display(ulong addr, int x, int y); void lcd_set_flush_dcache(int flush); #if defined CONFIG_MPC823 -/* - * LCD controller stucture for MPC823 CPU - */ -typedef struct vidinfo { - ushort vl_col; /* Number of columns (i.e. 640) */ - ushort vl_row; /* Number of rows (i.e. 480) */ - ushort vl_width; /* Width of display area in millimeters */ - ushort vl_height; /* Height of display area in millimeters */ - - /* LCD configuration register */ - u_char vl_clkp; /* Clock polarity */ - u_char vl_oep; /* Output Enable polarity */ - u_char vl_hsp; /* Horizontal Sync polarity */ - u_char vl_vsp; /* Vertical Sync polarity */ - u_char vl_dp; /* Data polarity */ - u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */ - u_char vl_lbw; /* LCD Bus width, 0 = 4, 1 = 8 */ - u_char vl_splt; /* Split display, 0 = single-scan, 1 = dual-scan */ - u_char vl_clor; /* Color, 0 = mono, 1 = color */ - u_char vl_tft; /* 0 = passive, 1 = TFT */ - - /* Horizontal control register. Timing from data sheet */ - ushort vl_wbl; /* Wait between lines */ - - /* Vertical control register */ - u_char vl_vpw; /* Vertical sync pulse width */ - u_char vl_lcdac; /* LCD AC timing */ - u_char vl_wbf; /* Wait between frames */ -} vidinfo_t; - +#include #elif defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \ defined CONFIG_CPU_MONAHANS -/* - * PXA LCD DMA descriptor - */ -struct pxafb_dma_descriptor { - u_long fdadr; /* Frame descriptor address register */ - u_long fsadr; /* Frame source address register */ - u_long fidr; /* Frame ID register */ - u_long ldcmd; /* Command register */ -}; - -/* - * PXA LCD info - */ -struct pxafb_info { - - /* Misc registers */ - u_long reg_lccr3; - u_long reg_lccr2; - u_long reg_lccr1; - u_long reg_lccr0; - u_long fdadr0; - u_long fdadr1; - - /* DMA descriptors */ - struct pxafb_dma_descriptor * dmadesc_fblow; - struct pxafb_dma_descriptor * dmadesc_fbhigh; - struct pxafb_dma_descriptor * dmadesc_palette; - - u_long screen; /* physical address of frame buffer */ - u_long palette; /* physical address of palette memory */ - u_int palette_size; -}; - -/* - * LCD controller stucture for PXA CPU - */ -typedef struct vidinfo { - ushort vl_col; /* Number of columns (i.e. 640) */ - ushort vl_row; /* Number of rows (i.e. 480) */ - ushort vl_width; /* Width of display area in millimeters */ - ushort vl_height; /* Height of display area in millimeters */ - - /* LCD configuration register */ - u_char vl_clkp; /* Clock polarity */ - u_char vl_oep; /* Output Enable polarity */ - u_char vl_hsp; /* Horizontal Sync polarity */ - u_char vl_vsp; /* Vertical Sync polarity */ - u_char vl_dp; /* Data polarity */ - u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ - u_char vl_lbw; /* LCD Bus width, 0 = 4, 1 = 8 */ - u_char vl_splt; /* Split display, 0 = single-scan, 1 = dual-scan */ - u_char vl_clor; /* Color, 0 = mono, 1 = color */ - u_char vl_tft; /* 0 = passive, 1 = TFT */ - - /* Horizontal control register. Timing from data sheet */ - ushort vl_hpw; /* Horz sync pulse width */ - u_char vl_blw; /* Wait before of line */ - u_char vl_elw; /* Wait end of line */ - - /* Vertical control register. */ - u_char vl_vpw; /* Vertical sync pulse width */ - u_char vl_bfw; /* Wait before of frame */ - u_char vl_efw; /* Wait end of frame */ - - /* PXA LCD controller params */ - struct pxafb_info pxa; -} vidinfo_t; - +#include #elif defined(CONFIG_ATMEL_LCD) || defined(CONFIG_ATMEL_HLCD) - -typedef struct vidinfo { - ushort vl_col; /* Number of columns (i.e. 640) */ - ushort vl_row; /* Number of rows (i.e. 480) */ - u_long vl_clk; /* pixel clock in ps */ - - /* LCD configuration register */ - u_long vl_sync; /* Horizontal / vertical sync */ - u_long vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ - u_long vl_tft; /* 0 = passive, 1 = TFT */ - u_long vl_cont_pol_low; /* contrast polarity is low */ - u_long vl_clk_pol; /* clock polarity */ - - /* Horizontal control register. */ - u_long vl_hsync_len; /* Length of horizontal sync */ - u_long vl_left_margin; /* Time from sync to picture */ - u_long vl_right_margin; /* Time from picture to sync */ - - /* Vertical control register. */ - u_long vl_vsync_len; /* Length of vertical sync */ - u_long vl_upper_margin; /* Time from sync to picture */ - u_long vl_lower_margin; /* Time from picture to sync */ - - u_long mmio; /* Memory mapped registers */ -} vidinfo_t; - +#include #elif defined(CONFIG_EXYNOS_FB) - -enum { - FIMD_RGB_INTERFACE = 1, - FIMD_CPU_INTERFACE = 2, -}; - -enum exynos_fb_rgb_mode_t { - MODE_RGB_P = 0, - MODE_BGR_P = 1, - MODE_RGB_S = 2, - MODE_BGR_S = 3, -}; - -typedef struct vidinfo { - ushort vl_col; /* Number of columns (i.e. 640) */ - ushort vl_row; /* Number of rows (i.e. 480) */ - ushort vl_width; /* Width of display area in millimeters */ - ushort vl_height; /* Height of display area in millimeters */ - - /* LCD configuration register */ - u_char vl_freq; /* Frequency */ - u_char vl_clkp; /* Clock polarity */ - u_char vl_oep; /* Output Enable polarity */ - u_char vl_hsp; /* Horizontal Sync polarity */ - u_char vl_vsp; /* Vertical Sync polarity */ - u_char vl_dp; /* Data polarity */ - u_char vl_bpix; /* Bits per pixel */ - - /* Horizontal control register. Timing from data sheet */ - u_char vl_hspw; /* Horz sync pulse width */ - u_char vl_hfpd; /* Wait before of line */ - u_char vl_hbpd; /* Wait end of line */ - - /* Vertical control register. */ - u_char vl_vspw; /* Vertical sync pulse width */ - u_char vl_vfpd; /* Wait before of frame */ - u_char vl_vbpd; /* Wait end of frame */ - u_char vl_cmd_allow_len; /* Wait end of frame */ - - unsigned int win_id; - unsigned int init_delay; - unsigned int power_on_delay; - unsigned int reset_delay; - unsigned int interface_mode; - unsigned int mipi_enabled; - unsigned int dp_enabled; - unsigned int cs_setup; - unsigned int wr_setup; - unsigned int wr_act; - unsigned int wr_hold; - unsigned int logo_on; - unsigned int logo_width; - unsigned int logo_height; - int logo_x_offset; - int logo_y_offset; - unsigned long logo_addr; - unsigned int rgb_mode; - unsigned int resolution; - - /* parent clock name(MPLL, EPLL or VPLL) */ - unsigned int pclk_name; - /* ratio value for source clock from parent clock. */ - unsigned int sclk_div; - - unsigned int dual_lcd_enabled; -} vidinfo_t; - -void init_panel_info(vidinfo_t *vid); - +#include #else - typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 160) */ ushort vl_row; /* Number of rows (i.e. 100) */ @@ -250,8 +60,7 @@ typedef struct vidinfo { void *priv; /* Pointer to driver-specific data */ } vidinfo_t; - -#endif /* CONFIG_MPC823, CONFIG_CPU_PXA25X, CONFIG_ATMEL_LCD */ +#endif extern vidinfo_t panel_info; diff --git a/include/mpc823_lcd.h b/include/mpc823_lcd.h new file mode 100644 index 0000000000..7e210e3296 --- /dev/null +++ b/include/mpc823_lcd.h @@ -0,0 +1,43 @@ +/* + * mpc823_lcd.h - MPC823 LCD Controller structures + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MPC823_LCD_H_ +#define _MPC823_LCD_H_ + +/* + * LCD controller stucture for MPC823 CPU + */ +typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 640) */ + ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_width; /* Width of display area in millimeters */ + ushort vl_height; /* Height of display area in millimeters */ + + /* LCD configuration register */ + u_char vl_clkp; /* Clock polarity */ + u_char vl_oep; /* Output Enable polarity */ + u_char vl_hsp; /* Horizontal Sync polarity */ + u_char vl_vsp; /* Vertical Sync polarity */ + u_char vl_dp; /* Data polarity */ + u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */ + u_char vl_lbw; /* LCD Bus width, 0 = 4, 1 = 8 */ + u_char vl_splt; /* Split display, 0 = single-scan, 1 = dual-scan */ + u_char vl_clor; /* Color, 0 = mono, 1 = color */ + u_char vl_tft; /* 0 = passive, 1 = TFT */ + + /* Horizontal control register. Timing from data sheet */ + ushort vl_wbl; /* Wait between lines */ + + /* Vertical control register */ + u_char vl_vpw; /* Vertical sync pulse width */ + u_char vl_lcdac; /* LCD AC timing */ + u_char vl_wbf; /* Wait between frames */ +} vidinfo_t; + +#endif diff --git a/include/pxa_lcd.h b/include/pxa_lcd.h new file mode 100644 index 0000000000..723f6ab766 --- /dev/null +++ b/include/pxa_lcd.h @@ -0,0 +1,80 @@ +/* + * pxa_lcd.h - PXA LCD Controller structures + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _PXA_LCD_H_ +#define _PXA_LCD_H_ + +/* + * PXA LCD DMA descriptor + */ +struct pxafb_dma_descriptor { + u_long fdadr; /* Frame descriptor address register */ + u_long fsadr; /* Frame source address register */ + u_long fidr; /* Frame ID register */ + u_long ldcmd; /* Command register */ +}; + +/* + * PXA LCD info + */ +struct pxafb_info { + /* Misc registers */ + u_long reg_lccr3; + u_long reg_lccr2; + u_long reg_lccr1; + u_long reg_lccr0; + u_long fdadr0; + u_long fdadr1; + + /* DMA descriptors */ + struct pxafb_dma_descriptor *dmadesc_fblow; + struct pxafb_dma_descriptor *dmadesc_fbhigh; + struct pxafb_dma_descriptor *dmadesc_palette; + + u_long screen; /* physical address of frame buffer */ + u_long palette; /* physical address of palette memory */ + u_int palette_size; +}; + +/* + * LCD controller stucture for PXA CPU + */ +typedef struct vidinfo { + ushort vl_col; /* Number of columns (i.e. 640) */ + ushort vl_row; /* Number of rows (i.e. 480) */ + ushort vl_width; /* Width of display area in millimeters */ + ushort vl_height; /* Height of display area in millimeters */ + + /* LCD configuration register */ + u_char vl_clkp; /* Clock polarity */ + u_char vl_oep; /* Output Enable polarity */ + u_char vl_hsp; /* Horizontal Sync polarity */ + u_char vl_vsp; /* Vertical Sync polarity */ + u_char vl_dp; /* Data polarity */ + u_char vl_bpix;/* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ + u_char vl_lbw; /* LCD Bus width, 0 = 4, 1 = 8 */ + u_char vl_splt;/* Split display, 0 = single-scan, 1 = dual-scan */ + u_char vl_clor; /* Color, 0 = mono, 1 = color */ + u_char vl_tft; /* 0 = passive, 1 = TFT */ + + /* Horizontal control register. Timing from data sheet */ + ushort vl_hpw; /* Horz sync pulse width */ + u_char vl_blw; /* Wait before of line */ + u_char vl_elw; /* Wait end of line */ + + /* Vertical control register. */ + u_char vl_vpw; /* Vertical sync pulse width */ + u_char vl_bfw; /* Wait before of frame */ + u_char vl_efw; /* Wait end of frame */ + + /* PXA LCD controller params */ + struct pxafb_info pxa; +} vidinfo_t; + +#endif -- cgit From 38b550877fd819ce7842b73530dcbacc098c9f0f Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:21 +0200 Subject: lcd: split configuration_get_cmap configuration_get_cmap() is multiple platform-specific functions stuffed into one function. Split it into multiple versions, and move each version to the appropriate driver to reduce the #ifdef complexity. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 19 ------------------- drivers/video/atmel_hlcdfb.c | 13 +++++++++++++ drivers/video/atmel_lcdfb.c | 5 +++++ drivers/video/exynos_fb.c | 9 +++++++++ drivers/video/mpc8xx_lcd.c | 7 +++++++ drivers/video/pxa_lcd.c | 6 ++++++ include/lcd.h | 7 +++++++ 7 files changed, 47 insertions(+), 19 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 1195a54efc..0f6c2e4c25 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -383,25 +383,6 @@ int lcd_getbgcolor(void) /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ -static inline ushort *configuration_get_cmap(void) -{ -#if defined CONFIG_CPU_PXA - struct pxafb_info *fbi = &panel_info.pxa; - return (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - cpm8xx_t *cp = &(immr->im_cpm); - return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); -#elif defined(CONFIG_ATMEL_LCD) - return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); -#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) - return panel_info.cmap; -#elif defined(CONFIG_LCD_LOGO) - return bmp_logo_palette; -#else - return NULL; -#endif -} #ifdef CONFIG_LCD_LOGO void bitmap_plot(int x, int y) diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c index 935ae42a9c..0ce237094d 100644 --- a/drivers/video/atmel_hlcdfb.c +++ b/drivers/video/atmel_hlcdfb.c @@ -13,6 +13,10 @@ #include #include +#if defined(CONFIG_LCD_LOGO) +#include +#endif + /* configurable parameters */ #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 #define ATMEL_LCDC_DMA_BURST_LEN 8 @@ -37,6 +41,15 @@ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) panel_info.mmio + ATMEL_LCDC_LUT(regno)); } +ushort *configuration_get_cmap(void) +{ +#if defined(CONFIG_LCD_LOGO) + return bmp_logo_palette; +#else + return NULL; +#endif +} + void lcd_ctrl_init(void *lcdbase) { unsigned long value; diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 3cf008ce6b..fa6a82cfaf 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -29,6 +29,11 @@ #define lcdc_readl(mmio, reg) __raw_readl((mmio)+(reg)) #define lcdc_writel(mmio, reg, val) __raw_writel((val), (mmio)+(reg)) +ushort *configuration_get_cmap(void) +{ + return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +} + void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) { #if defined(CONFIG_ATMEL_LCD_BGR555) diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index be35b982ac..c5d7330804 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -37,6 +37,15 @@ vidinfo_t panel_info = { }; #endif +ushort *configuration_get_cmap(void) +{ +#if defined(CONFIG_LCD_LOGO) + return bmp_logo_palette; +#else + return NULL; +#endif +} + static void exynos_lcd_init_mem(void *lcdbase, vidinfo_t *vid) { unsigned long palette_size; diff --git a/drivers/video/mpc8xx_lcd.c b/drivers/video/mpc8xx_lcd.c index add7215992..9d2e5edc72 100644 --- a/drivers/video/mpc8xx_lcd.c +++ b/drivers/video/mpc8xx_lcd.c @@ -357,6 +357,13 @@ lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue) /*----------------------------------------------------------------------*/ +ushort *configuration_get_cmap(void) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); + return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); +} + void lcd_enable (void) { volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; diff --git a/drivers/video/pxa_lcd.c b/drivers/video/pxa_lcd.c index f66f615df5..04105d4eaa 100644 --- a/drivers/video/pxa_lcd.c +++ b/drivers/video/pxa_lcd.c @@ -342,6 +342,12 @@ static int pxafb_init (vidinfo_t *vid); /* --------------- PXA chipset specific functions ------------------- */ /************************************************************************/ +ushort *configuration_get_cmap(void) +{ + struct pxafb_info *fbi = &panel_info.pxa; + return (ushort *)fbi->palette; +} + void lcd_ctrl_init (void *lcdbase) { pxafb_init_mem(lcdbase, &panel_info); diff --git a/include/lcd.h b/include/lcd.h index fbba6a27f9..4ada617e02 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -60,8 +60,15 @@ typedef struct vidinfo { void *priv; /* Pointer to driver-specific data */ } vidinfo_t; + +static __maybe_unused ushort *configuration_get_cmap(void) +{ + return panel_info.cmap; +} #endif +ushort *configuration_get_cmap(void); + extern vidinfo_t panel_info; /* Video functions */ -- cgit From b3d12e9bca1b23a537d77af2ae019cddc59f2031 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:22 +0200 Subject: lcd: atmel: move atmel-specific fb_put_word to atmel_lcdfb Reduce the amount of platform-specific code in common/lcd.c by moving Atmel implementation of fb_put_word() to atmel_lcdfb.c. Since we must also have a default implementation for everybody else, make the remainder of the code into a weak function. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Acked-by: Bo Shen Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 11 +---------- drivers/video/atmel_lcdfb.c | 9 +++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 0f6c2e4c25..f17b35b7fe 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -642,20 +642,11 @@ static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, #endif #if defined(CONFIG_BMP_16BPP) -#if defined(CONFIG_ATMEL_LCD_BGR555) -static inline void fb_put_word(uchar **fb, uchar **from) -{ - *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); - *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); - *from += 2; -} -#else -static inline void fb_put_word(uchar **fb, uchar **from) +__weak void fb_put_word(uchar **fb, uchar **from) { *(*fb)++ = *(*from)++; *(*fb)++ = *(*from)++; } -#endif #endif /* CONFIG_BMP_16BPP */ int lcd_display_bitmap(ulong bmp_image, int x, int y) diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index fa6a82cfaf..c7991cd034 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -34,6 +34,15 @@ ushort *configuration_get_cmap(void) return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); } +#if defined(CONFIG_BMP_16BPP) && defined(CONFIG_ATMEL_LCD_BGR555) +void fb_put_word(uchar **fb, uchar **from) +{ + *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); + *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); + *from += 2; +} +#endif + void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) { #if defined(CONFIG_ATMEL_LCD_BGR555) -- cgit From 27fad01b7fca1ed9ae946ced37c3d4bde828ba14 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:23 +0200 Subject: lcd: mpc8xx: move mpc823-specific fb_put_byte to mpc8xx_lcd.c Reduce the amount of platform-specific code in common/lcd.c by moving MPC823 implementation of fb_put_byte() to mpc8xx_lcd.c. Since we must also have a default implementation for everybody else, make the remainder of the code into a weak function. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 11 +++++------ drivers/video/mpc8xx_lcd.c | 7 +++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index f17b35b7fe..efd9a87545 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -635,11 +635,10 @@ static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, } #endif -#if defined(CONFIG_MPC823) -#define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) -#else -#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ -#endif +__weak void fb_put_byte(uchar **fb, uchar **from) +{ + *(*fb)++ = *(*from)++; +} #if defined(CONFIG_BMP_16BPP) __weak void fb_put_word(uchar **fb, uchar **from) @@ -764,7 +763,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) WATCHDOG_RESET(); for (j = 0; j < width; j++) { if (bpix != 16) { - FB_PUT_BYTE(fb, bmap); + fb_put_byte(&fb, &bmap); } else { *(uint16_t *)fb = cmap_base[*(bmap++)]; fb += sizeof(uint16_t) / sizeof(*fb); diff --git a/drivers/video/mpc8xx_lcd.c b/drivers/video/mpc8xx_lcd.c index 9d2e5edc72..190c05a598 100644 --- a/drivers/video/mpc8xx_lcd.c +++ b/drivers/video/mpc8xx_lcd.c @@ -364,6 +364,13 @@ ushort *configuration_get_cmap(void) return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); } +#if defined(CONFIG_MPC823) +void fb_put_byte(uchar **fb, uchar **from) +{ + *(*fb)++ = (255 - *(*from)++); +} +#endif + void lcd_enable (void) { volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; -- cgit From a02e9481396bbd831d9bd970515f277de516fa28 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:24 +0200 Subject: lcd: atmel: introduce lcd_logo_set_cmap Reduce the bitmap_plot #ifdef complexity by extracting Atmel-specific code for setting cmap into a new function lcd_logo_set_cmap(), which is implemented in atmel_lcdfb driver and defined as part of common/lcd.c api with a weak dummy version. In the Atmel implementation, ARRAY_SIZE(bmp_logo_palette) is switched for BMP_LOGO_COLORS to avoid having to include bmp_logo_data.h, which would cause a compilation error because the logo data and palette arrays would be defined twice. This is a step towards cleaning bitmap_plot() of platform-specific code. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 29 ++++++++--------------------- drivers/video/atmel_lcdfb.c | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index efd9a87545..7fcac1d9fb 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -385,13 +385,13 @@ int lcd_getbgcolor(void) /************************************************************************/ #ifdef CONFIG_LCD_LOGO +__weak void lcd_logo_set_cmap(void) +{ +} + void bitmap_plot(int x, int y) { -#ifdef CONFIG_ATMEL_LCD - uint *cmap = (uint *)bmp_logo_palette; -#else ushort *cmap = (ushort *)bmp_logo_palette; -#endif ushort i, j; uchar *bmap; uchar *fb; @@ -417,8 +417,6 @@ void bitmap_plot(int x, int y) */ #if defined(CONFIG_MPC823) cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); -#elif defined(CONFIG_ATMEL_LCD) - cmap = (uint *)configuration_get_cmap(); #else cmap = configuration_get_cmap(); #endif @@ -426,25 +424,14 @@ void bitmap_plot(int x, int y) WATCHDOG_RESET(); /* Set color map */ +#ifdef CONFIG_ATMEL_LCD + lcd_logo_set_cmap(); +#else for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) { ushort colreg = bmp_logo_palette[i]; -#ifdef CONFIG_ATMEL_LCD - uint lut_entry; -#ifdef CONFIG_ATMEL_LCD_BGR555 - lut_entry = ((colreg & 0x000F) << 11) | - ((colreg & 0x00F0) << 2) | - ((colreg & 0x0F00) >> 7); -#else /* CONFIG_ATMEL_LCD_RGB565 */ - lut_entry = ((colreg & 0x000F) << 1) | - ((colreg & 0x00F0) << 3) | - ((colreg & 0x0F00) << 4); -#endif - *(cmap + BMP_LOGO_OFFSET) = lut_entry; - cmap++; -#else /* !CONFIG_ATMEL_LCD */ *cmap++ = colreg; -#endif /* CONFIG_ATMEL_LCD */ } +#endif WATCHDOG_RESET(); diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c7991cd034..2a71ebae16 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -43,6 +43,32 @@ void fb_put_word(uchar **fb, uchar **from) } #endif +#ifdef CONFIG_LCD_LOGO +#include +void lcd_logo_set_cmap(void) +{ + int i; + uint lut_entry; + ushort colreg; + uint *cmap = (uint *)configuration_get_cmap(); + + for (i = 0; i < BMP_LOGO_COLORS; ++i) { + colreg = bmp_logo_palette[i]; +#ifdef CONFIG_ATMEL_LCD_BGR555 + lut_entry = ((colreg & 0x000F) << 11) | + ((colreg & 0x00F0) << 2) | + ((colreg & 0x0F00) >> 7); +#else + lut_entry = ((colreg & 0x000F) << 1) | + ((colreg & 0x00F0) << 3) | + ((colreg & 0x0F00) << 4); +#endif + *(cmap + BMP_LOGO_OFFSET) = lut_entry; + cmap++; + } +} +#endif + void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) { #if defined(CONFIG_ATMEL_LCD_BGR555) -- cgit From 0ee261f6d3f387a33687bff29342e9321e2f8194 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:25 +0200 Subject: lcd: mpc823: move mpc823-specific lcd_logo_set_cmap code to mpc8xx_lcd.c Reduce the bitmap_plot #ifdef complexity by extracting MPC823-specific code for setting cmap into its own implementation of lcd_logo_set_cmap(), implemented in mpc8xx_lcd.c. In the MPC823 implementation, ARRAY_SIZE(bmp_logo_palette) is switched for BMP_LOGO_COLORS to avoid having to include bmp_logo_data.h, which would cause a compilation error because the logo data and palette arrays would be defined twice. This is a step towards cleaning bitmap_plot() of platform-specific code. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 10 +--------- drivers/video/mpc8xx_lcd.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 7fcac1d9fb..355c1442fd 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -396,10 +396,6 @@ void bitmap_plot(int x, int y) uchar *bmap; uchar *fb; ushort *fb16; -#if defined(CONFIG_MPC823) - immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - cpm8xx_t *cp = &(immr->im_cpm); -#endif unsigned bpix = NBITS(panel_info.vl_bpix); debug("Logo: width %d height %d colors %d cmap %d\n", @@ -415,16 +411,12 @@ void bitmap_plot(int x, int y) * cmap was set to the source palette, so no change is done. * This avoids even more ifdefs in the next stanza */ -#if defined(CONFIG_MPC823) - cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); -#else cmap = configuration_get_cmap(); -#endif WATCHDOG_RESET(); /* Set color map */ -#ifdef CONFIG_ATMEL_LCD +#if defined(CONFIG_ATMEL_LCD) || defined(CONFIG_MPC823) lcd_logo_set_cmap(); #else for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) { diff --git a/drivers/video/mpc8xx_lcd.c b/drivers/video/mpc8xx_lcd.c index 190c05a598..faa58c020b 100644 --- a/drivers/video/mpc8xx_lcd.c +++ b/drivers/video/mpc8xx_lcd.c @@ -371,6 +371,21 @@ void fb_put_byte(uchar **fb, uchar **from) } #endif +#ifdef CONFIG_LCD_LOGO +#include +void lcd_logo_set_cmap(void) +{ + int i; + ushort *cmap; + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); + cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); + + for (i = 0; i < BMP_LOGO_COLORS; ++i) + *cmap++ = bmp_logo_palette[i]; +} +#endif + void lcd_enable (void) { volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; -- cgit From 2306457c4534d5cbadb834a2a185db3ef38e12c8 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:26 +0200 Subject: lcd: logo: move generic cmap setting to lcd_logo_set_cmap() Get rid of platform-specific #ifdefs in bitmap_plot() by moving the generic case of setting cmap into the weak lcd_logo_set_cmap(). Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 355c1442fd..dcee3c0aab 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -387,44 +387,30 @@ int lcd_getbgcolor(void) #ifdef CONFIG_LCD_LOGO __weak void lcd_logo_set_cmap(void) { + int i; + ushort *cmap = configuration_get_cmap(); + + for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) + *cmap++ = bmp_logo_palette[i]; } void bitmap_plot(int x, int y) { - ushort *cmap = (ushort *)bmp_logo_palette; ushort i, j; uchar *bmap; uchar *fb; ushort *fb16; unsigned bpix = NBITS(panel_info.vl_bpix); - debug("Logo: width %d height %d colors %d cmap %d\n", - BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS, - ARRAY_SIZE(bmp_logo_palette)); + debug("Logo: width %d height %d colors %d\n", + BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); bmap = &bmp_logo_bitmap[0]; fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); if (bpix < 12) { - /* Leave room for default color map - * default case: generic system with no cmap (most likely 16bpp) - * cmap was set to the source palette, so no change is done. - * This avoids even more ifdefs in the next stanza - */ - cmap = configuration_get_cmap(); - WATCHDOG_RESET(); - - /* Set color map */ -#if defined(CONFIG_ATMEL_LCD) || defined(CONFIG_MPC823) lcd_logo_set_cmap(); -#else - for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) { - ushort colreg = bmp_logo_palette[i]; - *cmap++ = colreg; - } -#endif - WATCHDOG_RESET(); for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { -- cgit From 0b29a8969e918d6c09d0798d381cf74594bdf3a0 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:27 +0200 Subject: lcd: introduce lcd_set_cmap Reduce the lcd_display_bitmap #ifdef complexity by extracting Atmel-specific code for setting cmap for bitmap images into a new function lcd_set_cmap(). A default version is implemented with the remainder of the code. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 46 ++++++++++++++++++++++----------------------- drivers/video/atmel_lcdfb.c | 11 +++++++++++ 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index dcee3c0aab..8a8d6c3e94 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -613,9 +613,27 @@ __weak void fb_put_word(uchar **fb, uchar **from) } #endif /* CONFIG_BMP_16BPP */ +__weak void lcd_set_cmap(bmp_image_t *bmp, unsigned colors) +{ + int i; + bmp_color_table_entry_t cte; + ushort *cmap = configuration_get_cmap(); + + for (i = 0; i < colors; ++i) { + cte = bmp->color_table[i]; + *cmap = (((cte.red) << 8) & 0xf800) | + (((cte.green) << 3) & 0x07e0) | + (((cte.blue) >> 3) & 0x001f); +#if defined(CONFIG_MPC823) + cmap--; +#else + cmap++; +#endif + } +} + int lcd_display_bitmap(ulong bmp_image, int x, int y) { - ushort *cmap = NULL; ushort *cmap_base = NULL; ushort i, j; uchar *fb; @@ -663,29 +681,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) debug("Display-bmp: %d x %d with %d colors\n", (int)width, (int)height, (int)colors); - if (bmp_bpix == 8) { - cmap = configuration_get_cmap(); - cmap_base = cmap; - - /* Set color map */ - for (i = 0; i < colors; ++i) { - bmp_color_table_entry_t cte = bmp->color_table[i]; -#if !defined(CONFIG_ATMEL_LCD) - ushort colreg = - ( ((cte.red) << 8) & 0xf800) | - ( ((cte.green) << 3) & 0x07e0) | - ( ((cte.blue) >> 3) & 0x001f) ; - *cmap = colreg; -#if defined(CONFIG_MPC823) - cmap--; -#else - cmap++; -#endif -#else /* CONFIG_ATMEL_LCD */ - lcd_setcolreg(i, cte.red, cte.green, cte.blue); -#endif - } - } + if (bmp_bpix == 8) + lcd_set_cmap(bmp, colors); padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width); @@ -706,6 +703,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) switch (bmp_bpix) { case 1: /* pass through */ case 8: { + cmap_base = configuration_get_cmap(); #ifdef CONFIG_LCD_BMP_RLE8 u32 compression = get_unaligned_le32(&bmp->header.compression); if (compression == BMP_BI_RLE8) { diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 2a71ebae16..5add1369ef 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include /* configurable parameters */ @@ -80,6 +81,16 @@ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) #endif } +void lcd_set_cmap(bmp_image_t *bmp, unsigned colors) +{ + int i; + + for (i = 0; i < colors; ++i) { + bmp_color_table_entry_t cte = bmp->color_table[i]; + lcd_setcolreg(i, cte.red, cte.green, cte.blue); + } +} + void lcd_ctrl_init(void *lcdbase) { unsigned long value; -- cgit From 8ddfe2fad806b6d1bac66ec1f28695690af50ab0 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:28 +0200 Subject: lcd: remove unused includes Remove unused includes. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 8a8d6c3e94..7a519234b9 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -16,14 +16,9 @@ #include #include #include -#include -#include #include #include #include -#if defined(CONFIG_POST) -#include -#endif #include #include #include @@ -32,19 +27,6 @@ #include #include -#if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \ - defined(CONFIG_CPU_MONAHANS) -#include -#endif - -#if defined(CONFIG_MPC823) -#include -#endif - -#if defined(CONFIG_ATMEL_LCD) -#include -#endif - #if defined(CONFIG_LCD_DT_SIMPLEFB) #include #endif -- cgit From c8d2febcc7e328d1c4bb11131ecd0b9cbab2f4fb Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:29 +0200 Subject: lcd: various cleanups This cleanup mostly focuses on removing unnecessary whitespace and comments which are superfluous and/or do not conform to the coding style. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 90 +++++++++------------------------------------------ include/lcd.h | 102 ++++++++++++++++++++-------------------------------------- 2 files changed, 49 insertions(+), 143 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 7a519234b9..06eec4508c 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -1,5 +1,5 @@ /* - * Common LCD routines for supported CPUs + * Common LCD routines * * (C) Copyright 2001-2002 * Wolfgang Denk, DENX Software Engineering -- wd@denx.de @@ -7,12 +7,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ -/************************************************************************/ -/* ** HEADER FILES */ -/************************************************************************/ - /* #define DEBUG */ - #include #include #include @@ -26,25 +21,18 @@ #include #include #include +#include #if defined(CONFIG_LCD_DT_SIMPLEFB) #include #endif -/************************************************************************/ -/* ** FONT DATA */ -/************************************************************************/ -#include /* Get font data, width and height */ - -/************************************************************************/ -/* ** LOGO DATA */ -/************************************************************************/ #ifdef CONFIG_LCD_LOGO -# include /* Get logo data, width and height */ -# include -# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16) -# error Default Color Map overlaps with Logo Color Map -# endif +#include +#include +#if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16) +#error Default Color Map overlaps with Logo Color Map +#endif #endif #ifdef CONFIG_SANDBOX @@ -57,30 +45,23 @@ #if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \ (LCD_BPP != LCD_COLOR32) -# error Unsupported LCD BPP. +#error Unsupported LCD BPP. #endif DECLARE_GLOBAL_DATA_PTR; static int lcd_init(void *lcdbase); - static void *lcd_logo(void); - static void lcd_setfgcolor(int color); static void lcd_setbgcolor(int color); static int lcd_color_fg; static int lcd_color_bg; int lcd_line_length; - char lcd_is_enabled = 0; - static void *lcd_base; /* Start of framebuffer memory */ - static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ -/************************************************************************/ - /* Flush LCD activity to the caches */ void lcd_sync(void) { @@ -110,8 +91,6 @@ void lcd_set_flush_dcache(int flush) lcd_flush_dcache = (flush != 0); } -/*----------------------------------------------------------------------*/ - static void lcd_stub_putc(struct stdio_dev *dev, const char c) { lcd_putc(c); @@ -122,9 +101,7 @@ static void lcd_stub_puts(struct stdio_dev *dev, const char *s) lcd_puts(s); } -/************************************************************************/ -/** Small utility to check that you got the colours right */ -/************************************************************************/ +/* Small utility to check that you got the colours right */ #ifdef LCD_TEST_PATTERN #define N_BLK_VERT 2 @@ -158,10 +135,6 @@ static void test_pattern(void) } #endif /* LCD_TEST_PATTERN */ - -/************************************************************************/ -/* ** GENERIC Initialization Routines */ -/************************************************************************/ /* * With most lcd drivers the line length is set up * by calculating it from panel_info parameters. Some @@ -181,7 +154,7 @@ int drv_lcd_init(void) lcd_base = map_sysmem(gd->fb_base, 0); - lcd_init(lcd_base); /* LCD initialization */ + lcd_init(lcd_base); /* Device initialization */ memset(&lcddev, 0, sizeof(lcddev)); @@ -197,7 +170,6 @@ int drv_lcd_init(void) return (rc == 0) ? 1 : rc; } -/*----------------------------------------------------------------------*/ void lcd_clear(void) { short console_rows, console_cols; @@ -261,20 +233,11 @@ static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, lcd_clear(); return 0; } - -U_BOOT_CMD( - cls, 1, 1, do_lcd_clear, - "clear screen", - "" -); - -/*----------------------------------------------------------------------*/ +U_BOOT_CMD(cls, 1, 1, do_lcd_clear, "clear screen", ""); static int lcd_init(void *lcdbase) { - /* Initialize the lcd controller */ debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); - lcd_ctrl_init(lcdbase); /* @@ -304,10 +267,6 @@ static int lcd_init(void *lcdbase) return 0; } - -/************************************************************************/ -/* ** ROM capable initialization part - needed to reserve FB memory */ -/************************************************************************/ /* * This is called early in the system initialization to grab memory * for the LCD controller. @@ -338,8 +297,6 @@ ulong lcd_setmem(ulong addr) return addr; } -/*----------------------------------------------------------------------*/ - static void lcd_setfgcolor(int color) { lcd_color_fg = color; @@ -350,8 +307,6 @@ int lcd_getfgcolor(void) return lcd_color_fg; } -/*----------------------------------------------------------------------*/ - static void lcd_setbgcolor(int color) { lcd_color_bg = color; @@ -362,10 +317,6 @@ int lcd_getbgcolor(void) return lcd_color_bg; } -/************************************************************************/ -/* ** Chipset depending Bitmap / Logo stuff... */ -/************************************************************************/ - #ifdef CONFIG_LCD_LOGO __weak void lcd_logo_set_cmap(void) { @@ -379,17 +330,14 @@ __weak void lcd_logo_set_cmap(void) void bitmap_plot(int x, int y) { ushort i, j; - uchar *bmap; - uchar *fb; - ushort *fb16; + uchar *bmap = &bmp_logo_bitmap[0]; unsigned bpix = NBITS(panel_info.vl_bpix); + uchar *fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); + ushort *fb16; debug("Logo: width %d height %d colors %d\n", BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); - bmap = &bmp_logo_bitmap[0]; - fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); - if (bpix < 12) { WATCHDOG_RESET(); lcd_logo_set_cmap(); @@ -424,13 +372,7 @@ void bitmap_plot(int x, int y) static inline void bitmap_plot(int x, int y) {} #endif /* CONFIG_LCD_LOGO */ -/*----------------------------------------------------------------------*/ #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) -/* - * Display the BMP file located at address bmp_image. - * Only uncompressed. - */ - #ifdef CONFIG_SPLASH_SCREEN_ALIGN #define BMP_ALIGN_CENTER 0x7FFF @@ -451,9 +393,7 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif - #ifdef CONFIG_LCD_BMP_RLE8 - #define BMP_RLE8_ESCAPE 0 #define BMP_RLE8_EOL 0 #define BMP_RLE8_EOBMP 1 @@ -683,7 +623,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) (y + height - 1) * lcd_line_length + x * bpix / 8); switch (bmp_bpix) { - case 1: /* pass through */ + case 1: case 8: { cmap_base = configuration_get_cmap(); #ifdef CONFIG_LCD_BMP_RLE8 diff --git a/include/lcd.h b/include/lcd.h index 4ada617e02..b0423205bf 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -13,21 +13,19 @@ #ifndef _LCD_H_ #define _LCD_H_ #include +#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) +#include +#include +#endif extern char lcd_is_enabled; - extern int lcd_line_length; - extern struct vidinfo panel_info; void lcd_ctrl_init(void *lcdbase); void lcd_enable(void); - -/* setcolreg used in 8bpp/16bpp; initcolregs used in monochrome */ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue); -void lcd_initcolregs(void); -/* gunzip_bmp used if CONFIG_VIDEO_BMP_GZIP */ struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp, void **alloc_addr); int bmp_display(ulong addr, int x, int y); @@ -53,11 +51,8 @@ void lcd_set_flush_dcache(int flush); typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 160) */ ushort vl_row; /* Number of rows (i.e. 100) */ - u_char vl_bpix; /* Bits per pixel, 0 = 1 */ - ushort *cmap; /* Pointer to the colormap */ - void *priv; /* Pointer to driver-specific data */ } vidinfo_t; @@ -71,13 +66,11 @@ ushort *configuration_get_cmap(void); extern vidinfo_t panel_info; -/* Video functions */ - -void lcd_putc(const char c); -void lcd_puts(const char *s); -void lcd_printf(const char *fmt, ...); -void lcd_clear(void); -int lcd_display_bitmap(ulong bmp_image, int x, int y); +void lcd_putc(const char c); +void lcd_puts(const char *s); +void lcd_printf(const char *fmt, ...); +void lcd_clear(void); +int lcd_display_bitmap(ulong bmp_image, int x, int y); /** * Get the width of the LCD in pixels @@ -141,14 +134,6 @@ int lcd_dt_simplefb_enable_existing_node(void *blob); /* Update the LCD / flush the cache */ void lcd_sync(void); -/************************************************************************/ -/* ** BITMAP DISPLAY SUPPORT */ -/************************************************************************/ -#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) -# include -# include -#endif - /* * Information about displays we are using. This is for configuring * the LCD controller and memory allocation. Someone has to know what @@ -163,38 +148,32 @@ void lcd_sync(void); #define LCD_COLOR8 3 #define LCD_COLOR16 4 #define LCD_COLOR32 5 -/*----------------------------------------------------------------------*/ + #if defined(CONFIG_LCD_INFO_BELOW_LOGO) -# define LCD_INFO_X 0 -# define LCD_INFO_Y (BMP_LOGO_HEIGHT + VIDEO_FONT_HEIGHT) +#define LCD_INFO_X 0 +#define LCD_INFO_Y (BMP_LOGO_HEIGHT + VIDEO_FONT_HEIGHT) #elif defined(CONFIG_LCD_LOGO) -# define LCD_INFO_X (BMP_LOGO_WIDTH + 4 * VIDEO_FONT_WIDTH) -# define LCD_INFO_Y VIDEO_FONT_HEIGHT +#define LCD_INFO_X (BMP_LOGO_WIDTH + 4 * VIDEO_FONT_WIDTH) +#define LCD_INFO_Y VIDEO_FONT_HEIGHT #else -# define LCD_INFO_X VIDEO_FONT_WIDTH -# define LCD_INFO_Y VIDEO_FONT_HEIGHT +#define LCD_INFO_X VIDEO_FONT_WIDTH +#define LCD_INFO_Y VIDEO_FONT_HEIGHT #endif /* Default to 8bpp if bit depth not specified */ #ifndef LCD_BPP -# define LCD_BPP LCD_COLOR8 +#define LCD_BPP LCD_COLOR8 #endif + #ifndef LCD_DF -# define LCD_DF 1 +#define LCD_DF 1 #endif /* Calculate nr. of bits per pixel and nr. of colors */ #define NBITS(bit_code) (1 << (bit_code)) #define NCOLORS(bit_code) (1 << NBITS(bit_code)) -/************************************************************************/ -/* ** CONSOLE CONSTANTS */ -/************************************************************************/ #if LCD_BPP == LCD_COLOR8 - -/* - * 8bpp color definitions - */ # define CONSOLE_COLOR_BLACK 0 # define CONSOLE_COLOR_RED 1 # define CONSOLE_COLOR_GREEN 2 @@ -203,38 +182,25 @@ void lcd_sync(void); # define CONSOLE_COLOR_MAGENTA 5 # define CONSOLE_COLOR_CYAN 6 # define CONSOLE_COLOR_GREY 14 -# define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */ - +# define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */ #elif LCD_BPP == LCD_COLOR32 -/* - * 32bpp color definitions - */ -# define CONSOLE_COLOR_RED 0x00ff0000 -# define CONSOLE_COLOR_GREEN 0x0000ff00 -# define CONSOLE_COLOR_YELLOW 0x00ffff00 -# define CONSOLE_COLOR_BLUE 0x000000ff -# define CONSOLE_COLOR_MAGENTA 0x00ff00ff -# define CONSOLE_COLOR_CYAN 0x0000ffff -# define CONSOLE_COLOR_GREY 0x00aaaaaa -# define CONSOLE_COLOR_BLACK 0x00000000 -# define CONSOLE_COLOR_WHITE 0x00ffffff /* Must remain last / highest*/ -# define NBYTES(bit_code) (NBITS(bit_code) >> 3) - -#else - -/* - * 16bpp color definitions - */ -# define CONSOLE_COLOR_BLACK 0x0000 -# define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */ - +#define CONSOLE_COLOR_RED 0x00ff0000 +#define CONSOLE_COLOR_GREEN 0x0000ff00 +#define CONSOLE_COLOR_YELLOW 0x00ffff00 +#define CONSOLE_COLOR_BLUE 0x000000ff +#define CONSOLE_COLOR_MAGENTA 0x00ff00ff +#define CONSOLE_COLOR_CYAN 0x0000ffff +#define CONSOLE_COLOR_GREY 0x00aaaaaa +#define CONSOLE_COLOR_BLACK 0x00000000 +#define CONSOLE_COLOR_WHITE 0x00ffffff /* Must remain last / highest */ +#define NBYTES(bit_code) (NBITS(bit_code) >> 3) +#else /* 16bpp color definitions */ +#define CONSOLE_COLOR_BLACK 0x0000 +#define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */ #endif /* color definitions */ -/************************************************************************/ #ifndef PAGE_SIZE -# define PAGE_SIZE 4096 +#define PAGE_SIZE 4096 #endif -/************************************************************************/ - #endif /* _LCD_H_ */ -- cgit From bf21a5deb9614898b1f9f12292950ee55f72bedf Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:30 +0200 Subject: lcd: rename bitmap_plot to better represent its functionality The name "bitmap_plot" is misleading because it implies that this is a generic function capable of dealing with any bitmap, but its implementation only works with the logo data. Rename the function to better reflect this. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 06eec4508c..2dce45c134 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -327,7 +327,7 @@ __weak void lcd_logo_set_cmap(void) *cmap++ = bmp_logo_palette[i]; } -void bitmap_plot(int x, int y) +void lcd_logo_plot(int x, int y) { ushort i, j; uchar *bmap = &bmp_logo_bitmap[0]; @@ -369,7 +369,7 @@ void bitmap_plot(int x, int y) lcd_sync(); } #else -static inline void bitmap_plot(int x, int y) {} +static inline void lcd_logo_plot(int x, int y) {} #endif /* CONFIG_LCD_LOGO */ #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) @@ -729,7 +729,7 @@ static void *lcd_logo(void) } #endif /* CONFIG_SPLASH_SCREEN */ - bitmap_plot(0, 0); + lcd_logo_plot(0, 0); #ifdef CONFIG_LCD_INFO lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH); -- cgit From 033167c4c5a9a31768f690353ce26be021ad9c36 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:31 +0200 Subject: lcd: dt: extract simplefb support We now have api functions that can support compiling simplefb code as its own module. Since this code is not part of the display functionality, extract it to its own file. Raspberry Pi is updated to accommodate the changes. Signed-off-by: Nikita Kiryanov Acked-by: Stephen Warren Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Simon Glass Cc: Anatolij Gustschin Cc: Stephen Warren --- board/raspberrypi/rpi/rpi.c | 1 + common/Makefile | 1 + common/lcd.c | 50 -------------------------------------- common/lcd_simplefb.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ include/fdt_simplefb.h | 14 +++++++++++ include/lcd.h | 3 --- 6 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 common/lcd_simplefb.c create mode 100644 include/fdt_simplefb.h diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index c18271fce8..948078b958 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/common/Makefile b/common/Makefile index 9579ab4c98..71f16dc5a0 100644 --- a/common/Makefile +++ b/common/Makefile @@ -199,6 +199,7 @@ obj-$(CONFIG_I2C_EDID) += edid.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o obj-$(CONFIG_LCD) += lcd.o lcd_console.o +obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_MODEM_SUPPORT) += modem.o diff --git a/common/lcd.c b/common/lcd.c index 2dce45c134..d0c0affc90 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -20,13 +20,8 @@ #include #include #include -#include #include -#if defined(CONFIG_LCD_DT_SIMPLEFB) -#include -#endif - #ifdef CONFIG_LCD_LOGO #include #include @@ -777,48 +772,3 @@ int lcd_get_pixel_height(void) { return panel_info.vl_row; } - -#if defined(CONFIG_LCD_DT_SIMPLEFB) -static int lcd_dt_simplefb_configure_node(void *blob, int off) -{ -#if LCD_BPP == LCD_COLOR16 - return fdt_setup_simplefb_node(blob, off, gd->fb_base, - panel_info.vl_col, panel_info.vl_row, - panel_info.vl_col * 2, "r5g6b5"); -#else - return -1; -#endif -} - -int lcd_dt_simplefb_add_node(void *blob) -{ - static const char compat[] = "simple-framebuffer"; - static const char disabled[] = "disabled"; - int off, ret; - - off = fdt_add_subnode(blob, 0, "framebuffer"); - if (off < 0) - return -1; - - ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); - if (ret < 0) - return -1; - - ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); - if (ret < 0) - return -1; - - return lcd_dt_simplefb_configure_node(blob, off); -} - -int lcd_dt_simplefb_enable_existing_node(void *blob) -{ - int off; - - off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); - if (off < 0) - return -1; - - return lcd_dt_simplefb_configure_node(blob, off); -} -#endif diff --git a/common/lcd_simplefb.c b/common/lcd_simplefb.c new file mode 100644 index 0000000000..8db2adde01 --- /dev/null +++ b/common/lcd_simplefb.c @@ -0,0 +1,59 @@ +/* + * Simplefb device tree support + * + * (C) Copyright 2015 + * Stephen Warren + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int lcd_dt_simplefb_configure_node(void *blob, int off) +{ +#if LCD_BPP == LCD_COLOR16 + int vl_col = lcd_get_pixel_width(); + int vl_row = lcd_get_pixel_height(); + return fdt_setup_simplefb_node(blob, off, gd->fb_base, vl_col, vl_row, + vl_col * 2, "r5g6b5"); +#else + return -1; +#endif +} + +int lcd_dt_simplefb_add_node(void *blob) +{ + static const char compat[] = "simple-framebuffer"; + static const char disabled[] = "disabled"; + int off, ret; + + off = fdt_add_subnode(blob, 0, "framebuffer"); + if (off < 0) + return -1; + + ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); + if (ret < 0) + return -1; + + ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); + if (ret < 0) + return -1; + + return lcd_dt_simplefb_configure_node(blob, off); +} + +int lcd_dt_simplefb_enable_existing_node(void *blob) +{ + int off; + + off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); + if (off < 0) + return -1; + + return lcd_dt_simplefb_configure_node(blob, off); +} diff --git a/include/fdt_simplefb.h b/include/fdt_simplefb.h new file mode 100644 index 0000000000..8c89a19b8e --- /dev/null +++ b/include/fdt_simplefb.h @@ -0,0 +1,14 @@ +/* + * Simplefb device tree support + * + * (C) Copyright 2015 + * Stephen Warren + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FDT_SIMPLEFB_H_ +#define _FDT_SIMPLEFB_H_ +int lcd_dt_simplefb_add_node(void *blob); +int lcd_dt_simplefb_enable_existing_node(void *blob); +#endif diff --git a/include/lcd.h b/include/lcd.h index b0423205bf..f049fd3489 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -128,9 +128,6 @@ void lcd_show_board_info(void); /* Return the size of the LCD frame buffer, and the line length */ int lcd_get_size(int *line_length); -int lcd_dt_simplefb_add_node(void *blob); -int lcd_dt_simplefb_enable_existing_node(void *blob); - /* Update the LCD / flush the cache */ void lcd_sync(void); -- cgit From 7bf71d1f55d31a81ade8dd0fc72f06e4672689d0 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Tue, 3 Feb 2015 13:32:32 +0200 Subject: lcd: split splash code into its own function lcd_logo() currently performs tasks well beyond just displaying the logo. It has code which displays splash image, it has logic which determines when the different display features are displayed, and it is coupled with the lcd console because it holds the responsibility of returning the lcd console base address. Make lcd_logo() just about the logo by: * Moving splash image display code into a dedicated function * Moving the logic regarding when various features are displayed to lcd_clear() (which is arguably not the correct name for housing such code either, but it is currently the most fitting location code wise) * Move the responsibility of setting the console base address to lcd_clear() too. Signed-off-by: Nikita Kiryanov Reviewed-by: Simon Glass Tested-by: Bo Shen Tested-by: Josh Wu Cc: Bo Shen Cc: Simon Glass Cc: Anatolij Gustschin --- common/lcd.c | 52 ++++++++++++++++++++++------------------------------ common/splash.c | 16 ++++++++++++++++ include/splash.h | 11 ++++++++++- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index d0c0affc90..f33942c617 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; static int lcd_init(void *lcdbase); -static void *lcd_logo(void); +static void lcd_logo(void); static void lcd_setfgcolor(int color); static void lcd_setbgcolor(int color); @@ -169,6 +169,9 @@ void lcd_clear(void) { short console_rows, console_cols; int bg_color; + char *s; + ulong addr; + static int do_splash = 1; #if LCD_BPP == LCD_COLOR8 /* Setting the palette */ lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0); @@ -218,7 +221,23 @@ void lcd_clear(void) #endif console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH; lcd_init_console(lcd_base, console_rows, console_cols); - lcd_init_console(lcd_logo(), console_rows, console_cols); + if (do_splash) { + s = getenv("splashimage"); + if (s) { + do_splash = 0; + addr = simple_strtoul(s, NULL, 16); + if (lcd_splash(addr) == 0) { + lcd_sync(); + return; + } + } + } + + lcd_logo(); +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) + addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length; + lcd_init_console((void *)addr, console_rows, console_cols); +#endif lcd_sync(); } @@ -701,29 +720,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif -static void *lcd_logo(void) +static void lcd_logo(void) { -#ifdef CONFIG_SPLASH_SCREEN - char *s; - ulong addr; - static int do_splash = 1; - - if (do_splash && (s = getenv("splashimage")) != NULL) { - int x = 0, y = 0; - do_splash = 0; - - if (splash_screen_prepare()) - return (void *)lcd_base; - - addr = simple_strtoul (s, NULL, 16); - - splash_get_pos(&x, &y); - - if (bmp_display(addr, x, y) == 0) - return (void *)lcd_base; - } -#endif /* CONFIG_SPLASH_SCREEN */ - lcd_logo_plot(0, 0); #ifdef CONFIG_LCD_INFO @@ -731,12 +729,6 @@ static void *lcd_logo(void) lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT); lcd_show_board_info(); #endif /* CONFIG_LCD_INFO */ - -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length); -#else - return (void *)lcd_base; -#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */ } #ifdef CONFIG_SPLASHIMAGE_GUARD diff --git a/common/splash.c b/common/splash.c index 144fb10ddd..561d35b4e4 100644 --- a/common/splash.c +++ b/common/splash.c @@ -22,6 +22,7 @@ #include #include +#include __weak int splash_screen_prepare(void) { @@ -50,3 +51,18 @@ void splash_get_pos(int *x, int *y) } } #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ + +#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_LCD) +int lcd_splash(ulong addr) +{ + int x = 0, y = 0, ret; + + ret = splash_screen_prepare(); + if (ret) + return ret; + + splash_get_pos(&x, &y); + + return bmp_display(addr, x, y); +} +#endif diff --git a/include/splash.h b/include/splash.h index 89ee7b22ec..4dbf754ace 100644 --- a/include/splash.h +++ b/include/splash.h @@ -21,7 +21,7 @@ #ifndef _SPLASH_H_ #define _SPLASH_H_ - +#include int splash_screen_prepare(void); @@ -31,6 +31,15 @@ void splash_get_pos(int *x, int *y); static inline void splash_get_pos(int *x, int *y) { } #endif +#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_LCD) +int lcd_splash(ulong addr); +#else +static inline int lcd_splash(ulong addr) +{ + return -ENOSYS; +} +#endif + #define BMP_ALIGN_CENTER 0x7FFF #endif -- cgit From 478b02f1a7043b673565075ea5016376f3293b23 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 7 Feb 2015 22:52:40 +0100 Subject: Add linux/compiler-gcc5.h to fix builds with gcc5 Add linux/compiler-gcc5/h from the kernel sources at: commit 5631b8fba640a4ab2f8a954f63a603fa34eda96b Author: Steven Noonan Date: Sat Oct 25 15:09:42 2014 -0700 compiler/gcc4+: Remove inaccurate comment about 'asm goto' miscompiles Signed-off-by: Hans de Goede --- include/linux/compiler-gcc5.h | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 include/linux/compiler-gcc5.h diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h new file mode 100644 index 0000000000..c8c5659525 --- /dev/null +++ b/include/linux/compiler-gcc5.h @@ -0,0 +1,65 @@ +#ifndef __LINUX_COMPILER_H +#error "Please don't include directly, include instead." +#endif + +#define __used __attribute__((__used__)) +#define __must_check __attribute__((warn_unused_result)) +#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) + +/* Mark functions as cold. gcc will assume any path leading to a call + to them will be unlikely. This means a lot of manual unlikely()s + are unnecessary now for any paths leading to the usual suspects + like BUG(), printk(), panic() etc. [but let's keep them for now for + older compilers] + + Early snapshots of gcc 4.3 don't support this and we can't detect this + in the preprocessor, but we can live with this because they're unreleased. + Maketime probing would be overkill here. + + gcc also has a __attribute__((__hot__)) to move hot functions into + a special section, but I don't see any sense in this right now in + the kernel context */ +#define __cold __attribute__((__cold__)) + +#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) + +#ifndef __CHECKER__ +# define __compiletime_warning(message) __attribute__((warning(message))) +# define __compiletime_error(message) __attribute__((error(message))) +#endif /* __CHECKER__ */ + +/* + * Mark a position in code as unreachable. This can be used to + * suppress control flow warnings after asm blocks that transfer + * control elsewhere. + * + * Early snapshots of gcc 4.5 don't support this and we can't detect + * this in the preprocessor, but we can live with this because they're + * unreleased. Really, we need to have autoconf for the kernel. + */ +#define unreachable() __builtin_unreachable() + +/* Mark a function definition as prohibited from being cloned. */ +#define __noclone __attribute__((__noclone__)) + +/* + * Tell the optimizer that something else uses this function or variable. + */ +#define __visible __attribute__((externally_visible)) + +/* + * GCC 'asm goto' miscompiles certain code sequences: + * + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 + * + * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. + * + * (asm goto is automatically volatile - the naming reflects this.) + */ +#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) + +#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP +#define __HAVE_BUILTIN_BSWAP32__ +#define __HAVE_BUILTIN_BSWAP64__ +#define __HAVE_BUILTIN_BSWAP16__ +#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ -- cgit From bd2a4888b123713adec271d6c8040ca9f609aa2f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Feb 2015 00:43:36 +0100 Subject: sunxi: configs/sunxi-common.h: Enable CONFIG_CMD_PART The recent changes to config_distro_bootcmd.h require CONFIG_CMD_PART to be defined, as the default bootcmd not uses the "part" command. This fixes sunxi boards not booting with v2015.04-rc1. Signed-off-by: Hans de Goede --- include/configs/sunxi-common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 6cfd7e1489..cea52dbf7b 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -85,6 +85,9 @@ #define CONFIG_CMD_MEMORY #define CONFIG_CMD_SETEXPR +#define CONFIG_PARTITION_UUIDS +#define CONFIG_CMD_PART + #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_CMDLINE_TAG #define CONFIG_INITRD_TAG -- cgit From bc2ad9f04dd9d15e7134f7e1b6386d1995772d69 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Sun, 8 Feb 2015 20:06:05 +0100 Subject: lsxl: use default load addresses for legacy boot The load addresses for the bootcmd_legacy script were taken from the original bootloader from Buffalo. But newer kernels are too big and the uncompressing will overwrite parts of the initial ramdisk. Therefore, we switch to the load addresses which are also used by the other boot script. Signed-off-by: Michael Walle --- include/configs/lsxl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h index a14bfe3a85..6c8e369861 100644 --- a/include/configs/lsxl.h +++ b/include/configs/lsxl.h @@ -127,9 +127,9 @@ "ramdisk_addr=0x01000000\0" \ "fdt_addr=0x01ff0000\0" \ "bootcmd_legacy=ide reset " \ - "&& load ide ${hdpart} 0x00100000 /uImage.buffalo " \ - "&& load ide ${hdpart} 0x00800000 /initrd.buffalo " \ - "&& bootm 0x00100000 0x00800000\0" \ + "&& load ide ${hdpart} ${kernel_addr} /uImage.buffalo " \ + "&& load ide ${hdpart} ${ramdisk_addr} /initrd.buffalo "\ + "&& bootm ${kernel_addr} ${ramdisk_addr}\0" \ "bootcmd_net=bootp ${kernel_addr} uImage " \ "&& tftpboot ${ramdisk_addr} uInitrd " \ "&& tftpboot ${fdt_addr} " CONFIG_FDTFILE " " \ -- cgit From 145df6fe2a5897cfda0ca2992d0e08cdb9cc0cde Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Sun, 8 Feb 2015 20:06:06 +0100 Subject: lsxl: place the dtb below the inital ramdisk The dtb was loaded at a memory address after the initial ramdisk. Thus a large ramdisk would overwrite the dtb. Move it to "ramdisk_start - 64k". 64k should be enough for the device tree blob. Also the kernel documentation arm/Booting suggests to put the dtb before the initial ramdisk. Signed-off-by: Michael Walle --- include/configs/lsxl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h index 6c8e369861..dff90250a0 100644 --- a/include/configs/lsxl.h +++ b/include/configs/lsxl.h @@ -125,7 +125,7 @@ "hdpart=0:1\0" \ "kernel_addr=0x00800000\0" \ "ramdisk_addr=0x01000000\0" \ - "fdt_addr=0x01ff0000\0" \ + "fdt_addr=0x00ff0000\0" \ "bootcmd_legacy=ide reset " \ "&& load ide ${hdpart} ${kernel_addr} /uImage.buffalo " \ "&& load ide ${hdpart} ${ramdisk_addr} /initrd.buffalo "\ -- cgit From 4fe49d7becc2dfb7288f8b265e0976428b64323c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Sun, 8 Feb 2015 20:06:07 +0100 Subject: lsxl: switch from bootm to bootz for boot commands Use the bootz command to load zImages in case of any new boot scripts. Only the legacy one will still use bootm. Apart form the fact, that this will simplify the image generation process, it saves one copy of the kernel image: Common practice is to generate an uImage with a loading address of 0x8000. This uImage contains a compressed zImage, which will unpack the kernel image to the beginning of the RAM. But because there is already the compressed image the uncompressor first relocates the compressed image to a higher location. The load address is encoded into the uImage which is generated by the distributions and thus cannot be easily changed. By using the bootz command we can load the compressed image to a higher memory address and the decompressor doesn't have to reloacte the image. Signed-off-by: Michael Walle --- include/configs/lsxl.h | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h index dff90250a0..c354c29296 100644 --- a/include/configs/lsxl.h +++ b/include/configs/lsxl.h @@ -56,6 +56,7 @@ * Commands configuration */ #include +#define CONFIG_CMD_BOOTZ #define CONFIG_CMD_DHCP #define CONFIG_CMD_ELF #define CONFIG_CMD_ENV @@ -78,6 +79,9 @@ */ #include "mv-common.h" +/* loading initramfs images without uimage header */ +#define CONFIG_SUPPORT_RAW_INITRD + /* ST M25P40 */ #undef CONFIG_SPI_FLASH_MACRONIX #define CONFIG_SPI_FLASH_STMICRO @@ -130,22 +134,26 @@ "&& load ide ${hdpart} ${kernel_addr} /uImage.buffalo " \ "&& load ide ${hdpart} ${ramdisk_addr} /initrd.buffalo "\ "&& bootm ${kernel_addr} ${ramdisk_addr}\0" \ - "bootcmd_net=bootp ${kernel_addr} uImage " \ - "&& tftpboot ${ramdisk_addr} uInitrd " \ + "bootcmd_net=bootp ${kernel_addr} vmlinuz " \ + "&& tftpboot ${ramdisk_addr} initrd.img " \ + "&& setenv ramdisk_len ${filesize} " \ "&& tftpboot ${fdt_addr} " CONFIG_FDTFILE " " \ - "&& bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0" \ + "&& bootz ${kernel_addr} " \ + "${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \ "bootcmd_hdd=ide reset " \ - "&& load ide ${hdpart} ${kernel_addr} /uImage " \ - "&& load ide ${hdpart} ${ramdisk_addr} /uInitrd " \ - "&& load ide ${hdpart} ${fdt_addr} " \ - "/" CONFIG_FDTFILE " " \ - "&& bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0" \ + "&& load ide ${hdpart} ${kernel_addr} /vmlinuz " \ + "&& load ide ${hdpart} ${ramdisk_addr} /initrd.img " \ + "&& setenv ramdisk_len ${filesize} " \ + "&& load ide ${hdpart} ${fdt_addr} /dtb " \ + "&& bootz ${kernel_addr} " \ + "${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \ "bootcmd_usb=usb start " \ - "&& load usb 0:1 ${kernel_addr} /uImage " \ - "&& load usb 0:1 ${ramdisk_addr} /uInitrd " \ - "&& load usb 0:1 ${fdt_addr} " \ - "/" CONFIG_FDTFILE " " \ - "&& bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0" \ + "&& load usb 0:1 ${kernel_addr} /vmlinuz " \ + "&& load usb 0:1 ${ramdisk_addr} /initrd.img " \ + "&& setenv ramdisk_len ${filesize} " \ + "&& load usb 0:1 ${fdt_addr} " CONFIG_FDTFILE " " \ + "&& bootz ${kernel_addr} " \ + "${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \ "bootcmd_rescue=run config_nc_dhcp; run nc\0" \ "eraseenv=sf probe 0 " \ "&& sf erase " __stringify(CONFIG_ENV_OFFSET) \ -- cgit From 9009798df20f60fd53679b537fcb4df3460b7cf8 Mon Sep 17 00:00:00 2001 From: Chris Kuethe Date: Wed, 4 Feb 2015 19:16:14 -0800 Subject: RSA depends on DM Discovered while experimenting with signature checking on vexpress which doesn't typically use DM. Acked-by: Simon Glass --- Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/Kconfig b/Kconfig index 9af31e3e77..09e2bbe66a 100644 --- a/Kconfig +++ b/Kconfig @@ -118,6 +118,7 @@ config FIT_VERBOSE config FIT_SIGNATURE bool "Enable signature verification of FIT uImages" depends on FIT + depends on DM select RSA help This option enables signature verification of FIT uImages, -- cgit From b922a5f94d960b0464f81b439c34707071095565 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 3 Feb 2015 13:18:49 -0600 Subject: dm: Prevent "demo hello" and "demo status" segfaults Segfaults can occur when a mandatory argument is not provided to "demo hello" and "demo status". Eg: => demo hello Segmentation fault (core dumped) Add a check to ensure all required arguments are provided. Signed-off-by: Peter Tyser Acked-by: Simon Glass --- common/cmd_demo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/cmd_demo.c b/common/cmd_demo.c index bcb34d9045..8a10bdf42a 100644 --- a/common/cmd_demo.c +++ b/common/cmd_demo.c @@ -97,7 +97,9 @@ static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ARRAY_SIZE(demo_commands)); argc -= 2; argv += 2; - if (!demo_cmd || argc > demo_cmd->maxargs) + + if ((!demo_cmd || argc > demo_cmd->maxargs) || + ((demo_cmd->name[0] != 'l') && (argc < 1))) return CMD_RET_USAGE; if (argc) { -- cgit From d895821f4c3c21f034780814cb73842b7219c4f2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 31 Jan 2015 14:47:34 +0800 Subject: gpio: at91: Fix getting address of private data Use dev_get_priv() rather than dev_get_platdata() to get correct address of private data. Signed-off-by: Axel Lin Acked-by: Simon Glass --- drivers/gpio/at91_gpio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index 6129c020ea..22fbd63098 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -451,7 +451,7 @@ struct at91_port_priv { /* set GPIO pin 'gpio' as an input */ static int at91_gpio_direction_input(struct udevice *dev, unsigned offset) { - struct at91_port_priv *port = dev_get_platdata(dev); + struct at91_port_priv *port = dev_get_priv(dev); at91_set_port_input(port->regs, offset, 0); @@ -462,7 +462,7 @@ static int at91_gpio_direction_input(struct udevice *dev, unsigned offset) static int at91_gpio_direction_output(struct udevice *dev, unsigned offset, int value) { - struct at91_port_priv *port = dev_get_platdata(dev); + struct at91_port_priv *port = dev_get_priv(dev); at91_set_port_output(port->regs, offset, value); @@ -472,7 +472,7 @@ static int at91_gpio_direction_output(struct udevice *dev, unsigned offset, /* read GPIO IN value of pin 'gpio' */ static int at91_gpio_get_value(struct udevice *dev, unsigned offset) { - struct at91_port_priv *port = dev_get_platdata(dev); + struct at91_port_priv *port = dev_get_priv(dev); return at91_get_port_value(port->regs, offset); } @@ -481,7 +481,7 @@ static int at91_gpio_get_value(struct udevice *dev, unsigned offset) static int at91_gpio_set_value(struct udevice *dev, unsigned offset, int value) { - struct at91_port_priv *port = dev_get_platdata(dev); + struct at91_port_priv *port = dev_get_priv(dev); at91_set_port_value(port->regs, offset, value); @@ -490,7 +490,7 @@ static int at91_gpio_set_value(struct udevice *dev, unsigned offset, static int at91_gpio_get_function(struct udevice *dev, unsigned offset) { - struct at91_port_priv *port = dev_get_platdata(dev); + struct at91_port_priv *port = dev_get_priv(dev); /* GPIOF_FUNC is not implemented yet */ if (at91_get_port_output(port->regs, offset)) -- cgit From 26c0472cb07bc23e21fc8148565f7f2be746a8a0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 31 Jan 2015 22:23:38 +0800 Subject: gpio: omap: Pass correct argument to _get_gpio_direction() Pass bank rather than bank->base to _get_gpio_direction(). Signed-off-by: Axel Lin Acked-by: Simon Glass --- drivers/gpio/omap_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index f3a7ccb51e..19fc451079 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -291,7 +291,7 @@ static int omap_gpio_get_function(struct udevice *dev, unsigned offset) struct gpio_bank *bank = dev_get_priv(dev); /* GPIOF_FUNC is not implemented yet */ - if (_get_gpio_direction(bank->base, offset) == OMAP_GPIO_DIR_OUT) + if (_get_gpio_direction(bank, offset) == OMAP_GPIO_DIR_OUT) return GPIOF_OUTPUT; else return GPIOF_INPUT; -- cgit From a3e757a5d295329b504123f0995b35cf694c7613 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:35 +0100 Subject: i2c: s3c24x0: reduce transmission status timeout If no device is connected to I2C bus, the i2c probe command can take a lot of time for probe each address. This commit reduces the busy timeout to 10ms for standard and high speed modes. This doesn't break the transmission an also allow for properly probe the devices. Signed-off-by: Przemyslaw Marczak Changes v3: - new commit, after split the next one Tested-by: Simon Glass --- drivers/i2c/s3c24x0_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 0dd1abcf80..b4ee33f7da 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -112,9 +112,9 @@ #define I2C_START_STOP 0x20 /* START / STOP */ #define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */ -#define I2C_TIMEOUT_MS 1000 /* 1 second */ +#define I2C_TIMEOUT_MS 10 /* 10 ms */ -#define HSI2C_TIMEOUT_US 100000 /* 100 ms, finer granularity */ +#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */ /* To support VCMA9 boards and other who dont define max_i2c_num */ -- cgit From 2c8571703a3aacfb09defc35c42c6250a6746d58 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Feb 2015 13:05:50 +0100 Subject: malloc_simple: Return NULL on malloc failure rather then calling panic() All callers of malloc should already do error checking, and may even be able to continue without the alloc succeeding. Moreover, common/malloc_simple.c is the only user of .rodata.str1.1 in common/built-in.o when building the SPL, triggering this gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54303 Causing .rodata to grow with e.g. 0xc21 bytes, nullifying all benefits of using malloc_simple in the first place. Signed-off-by: Hans de Goede Acked-by: Simon Glass --- common/malloc_simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/malloc_simple.c b/common/malloc_simple.c index afdacff80d..64ae0365af 100644 --- a/common/malloc_simple.c +++ b/common/malloc_simple.c @@ -19,7 +19,7 @@ void *malloc_simple(size_t bytes) new_ptr = gd->malloc_ptr + bytes; if (new_ptr > gd->malloc_limit) - panic("Out of pre-reloc memory"); + return NULL; ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes); gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr)); return ptr; -- cgit From 74d0186766a3899d3838286dcdb40fd6bdcbd49a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:34 -0700 Subject: Introduce board_init_f_mem() to handle early memory layout At present on some architectures we set up the following before calling board_init_f(): - global_data - stack - early malloc memory Adding the code to support early malloc and global data setup to every arch's assembler start-up is a pain. Also this code is not actually architecture-specific. We can use common code for all architectures and with a bit of care we can write this code in C. Add a new function to deal with this. It should be called after memory is available, with a pointer to the top of the area that should be used before relocation. The function will set things up and return the lowest memory address that it allocated/used. That can then be set as the top of the stack. Note that on some archs this function will use the stack, so the stack pointer should be set to same value as is pased to board_init_f_mem(). A margin of 128 bytes will be left for this stack, so that it is not overwritten. This means that 64 bytes is wasted by this early call. This is not strictly necessary on several more modern archs, so we could remove this at the cost of some arch-dependent code. With this function there is no-longer any need for the assembler code to zero global_data or set up the early malloc pointers. Signed-off-by: Simon Glass --- common/board_f.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/common/board_f.c b/common/board_f.c index bdad36b260..2c10215a17 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -1075,4 +1075,22 @@ void board_init_f_r(void) /* NOTREACHED - board_init_r() does not return */ hang(); } +#else +ulong board_init_f_mem(ulong top) +{ + /* Leave space for the stack we are running with now */ + top -= 0x40; + + top -= sizeof(struct global_data); + top = ALIGN(top, 16); + gd = (struct global_data *)top; + memset((void *)gd, '\0', sizeof(*gd)); + +#ifdef CONFIG_SYS_MALLOC_F_LEN + top -= CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_base = top; +#endif + + return top; +} #endif /* CONFIG_X86 */ -- cgit From c1c615735f5f3348a9df0623e366c7182506aebd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:35 -0700 Subject: powerpc: Permit device tree control of U-Boot (CONFIG_OF_CONTROL) Enable this in the Kconfig so that PowerPC boards can use device tree to configure U-Boot. Signed-off-by: Simon Glass --- arch/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/Kconfig b/arch/Kconfig index 132123bcaf..3d419bca3e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -40,6 +40,7 @@ config OPENRISC config PPC bool "PowerPC architecture" select HAVE_PRIVATE_LIBGCC + select SUPPORT_OF_CONTROL config SANDBOX bool "Sandbox" -- cgit From 0bca284b1795942ac8fdd1646f04f49e478f0bcc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:36 -0700 Subject: powerpc: ppc4xx: canyonlands: config: Tidy up CONFIGs and config.mk Many CONFIG options have an unnecessary value of 1. CONFIG_440 is set in the various board config files. Also simplify the CONFIG_440 check in config.mk Signed-off-by: Simon Glass --- arch/powerpc/cpu/ppc4xx/config.mk | 5 +---- board/amcc/canyonlands/config.mk | 2 -- include/configs/canyonlands.h | 34 +++++++++++++++++----------------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/cpu/ppc4xx/config.mk b/arch/powerpc/cpu/ppc4xx/config.mk index f87c9dc49b..9cb41bb3b5 100644 --- a/arch/powerpc/cpu/ppc4xx/config.mk +++ b/arch/powerpc/cpu/ppc4xx/config.mk @@ -7,10 +7,7 @@ PLATFORM_CPPFLAGS += -mstring -msoft-float -cfg=$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME:"%"=%).h -is440:=$(shell grep CONFIG_440 $(cfg)) - -ifneq (,$(findstring CONFIG_440,$(is440))) +ifneq (,$(CONFIG_440)) PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440 else PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405 diff --git a/board/amcc/canyonlands/config.mk b/board/amcc/canyonlands/config.mk index 63b8973700..5cc90d2050 100644 --- a/board/amcc/canyonlands/config.mk +++ b/board/amcc/canyonlands/config.mk @@ -8,8 +8,6 @@ # AMCC 460EX/460GT Evaluation Board (Canyonlands) board # -PLATFORM_CPPFLAGS += -DCONFIG_440=1 - ifeq ($(debug),1) PLATFORM_CPPFLAGS += -DDEBUG endif diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index 8eeb15c0e1..7b1f368375 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -19,10 +19,10 @@ * and Arches dual (460GT) */ #ifdef CONFIG_CANYONLANDS -#define CONFIG_460EX 1 /* Specific PPC460EX */ +#define CONFIG_460EX /* Specific PPC460EX */ #define CONFIG_HOSTNAME canyonlands #else -#define CONFIG_460GT 1 /* Specific PPC460GT */ +#define CONFIG_460GT /* Specific PPC460GT */ #ifdef CONFIG_GLACIER #define CONFIG_HOSTNAME glacier #else @@ -32,7 +32,7 @@ #endif #endif -#define CONFIG_440 1 +#define CONFIG_440 #ifndef CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_TEXT_BASE 0xFFF80000 @@ -45,10 +45,10 @@ #define CONFIG_SYS_CLK_FREQ 66666667 /* external freq to pll */ -#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ -#define CONFIG_BOARD_EARLY_INIT_R 1 /* Call board_early_init_r */ -#define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */ -#define CONFIG_BOARD_TYPES 1 /* support board types */ +#define CONFIG_BOARD_EARLY_INIT_F /* Call board_early_init_f */ +#define CONFIG_BOARD_EARLY_INIT_R /* Call board_early_init_r */ +#define CONFIG_MISC_INIT_R /* Call misc_init_r */ +#define CONFIG_BOARD_TYPES /* support board types */ /*----------------------------------------------------------------------- * Base addresses -- Note these are effective addresses where the @@ -134,7 +134,7 @@ *----------------------------------------------------------------------*/ #define CONFIG_SYS_FLASH_CFI /* The flash is CFI compatible */ #define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ -#define CONFIG_SYS_FLASH_CFI_AMD_RESET 1 /* Use AMD (Spansion) reset cmd */ +#define CONFIG_SYS_FLASH_CFI_AMD_RESET /* Use AMD (Spansion) reset cmd */ #define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE} #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */ @@ -172,9 +172,9 @@ * I2C SPD DIMM autodetection/calibration doesn't fit into the 4k of boot * code. */ -#define CONFIG_SPD_EEPROM 1 /* Use SPD EEPROM for setup */ +#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for setup */ #define SPD_EEPROM_ADDRESS {0x50, 0x51} /* SPD i2c spd addresses*/ -#define CONFIG_DDR_ECC 1 /* with ECC support */ +#define CONFIG_DDR_ECC /* with ECC support */ #define CONFIG_DDR_RQDC_FIXED 0x80000038 /* fixed value for RQDC */ #else /* defined(CONFIG_ARCHES) */ @@ -262,8 +262,8 @@ #define CONFIG_4xx_CONFIG_BLOCKSIZE 16 /* I2C SYSMON (LM75, AD7414 is almost compatible) */ -#define CONFIG_DTT_LM75 1 /* ON Semi's LM75 */ -#define CONFIG_DTT_AD7414 1 /* use AD7414 */ +#define CONFIG_DTT_LM75 /* ON Semi's LM75 */ +#define CONFIG_DTT_AD7414 /* use AD7414 */ #define CONFIG_DTT_SENSORS {0} /* Sensor addresses */ #define CONFIG_SYS_DTT_MAX_TEMP 70 #define CONFIG_SYS_DTT_LOW_TEMP -30 @@ -275,14 +275,14 @@ #if !defined(CONFIG_ARCHES) /* RTC configuration */ -#define CONFIG_RTC_M41T62 1 +#define CONFIG_RTC_M41T62 #define CONFIG_SYS_I2C_RTC_ADDR 0x68 #endif /*----------------------------------------------------------------------- * Ethernet *----------------------------------------------------------------------*/ -#define CONFIG_IBM_EMAC4_V4 1 +#define CONFIG_IBM_EMAC4_V4 #define CONFIG_HAS_ETH0 #define CONFIG_HAS_ETH1 @@ -322,9 +322,9 @@ #define CONFIG_GPCS_PHY2_ADDR 0xC #endif /* !defined(CONFIG_ARCHES) */ -#define CONFIG_PHY_RESET 1 /* reset phy upon startup */ -#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ -#define CONFIG_PHY_DYNAMIC_ANEG 1 +#define CONFIG_PHY_RESET /* reset phy upon startup */ +#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */ +#define CONFIG_PHY_DYNAMIC_ANEG /*----------------------------------------------------------------------- * USB-OHCI -- cgit From 6566041c0bf9523becf5292e45a0f5c3686ebdd4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:37 -0700 Subject: powerpc: ppc4xx: Move CANYONLANDS/GLACIER/ARCHES to Kconfig Move these options to Kconfig and remove them from the CONFIG files. Signed-off-by: Simon Glass --- board/amcc/canyonlands/Kconfig | 20 ++++++++++++++++++++ configs/arches_defconfig | 2 +- configs/canyonlands_defconfig | 2 +- configs/glacier_defconfig | 2 +- include/configs/canyonlands.h | 2 ++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/board/amcc/canyonlands/Kconfig b/board/amcc/canyonlands/Kconfig index 530a6efd60..0fc687739c 100644 --- a/board/amcc/canyonlands/Kconfig +++ b/board/amcc/canyonlands/Kconfig @@ -9,4 +9,24 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "canyonlands" +choice BOARD_TYPE + prompt "Select which board to build for" + +config CANYONLANDS + bool "Glacier" + help + Select this to build for the Canyonlands 460EX board. + +config GLACIER + bool "Glacier" + help + Select this to build for the Glacier 460GT board. + +config ARCHES + bool "Arches" + help + Select this to build for the Arches dual 460GT board. + +endchoice + endif diff --git a/configs/arches_defconfig b/configs/arches_defconfig index 18d0a140da..60e6ef9098 100644 --- a/configs/arches_defconfig +++ b/configs/arches_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="ARCHES" CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y +CONFIG_ARCHES=y diff --git a/configs/canyonlands_defconfig b/configs/canyonlands_defconfig index 09b9ab9330..37a2b4d796 100644 --- a/configs/canyonlands_defconfig +++ b/configs/canyonlands_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="CANYONLANDS" CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y +CONFIG_CANYONLANDS=y diff --git a/configs/glacier_defconfig b/configs/glacier_defconfig index 2a66bfb08c..436b9f8d03 100644 --- a/configs/glacier_defconfig +++ b/configs/glacier_defconfig @@ -1,4 +1,4 @@ -CONFIG_SYS_EXTRA_OPTIONS="GLACIER" CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y +CONFIG_GLACIER=y diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index 7b1f368375..ed790ccaf3 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -11,6 +11,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include + /*----------------------------------------------------------------------- * High Level Configuration Options *----------------------------------------------------------------------*/ -- cgit From 00cca639d56e791e5bea16b0e77d9540651132fe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:38 -0700 Subject: powerpc: ppc4xx: Add ramboot config for glacier Add a new ramboot config for glacier so that it is possible to test U-Boot loaded over Ethernet instead of using JTAG. Signed-off-by: Simon Glass --- arch/powerpc/cpu/ppc4xx/44x_spd_ddr2.c | 8 ++++ board/amcc/canyonlands/MAINTAINERS | 1 + board/amcc/canyonlands/u-boot-ram.lds | 79 ++++++++++++++++++++++++++++++++++ configs/glacier_ramboot_defconfig | 5 +++ 4 files changed, 93 insertions(+) create mode 100644 board/amcc/canyonlands/u-boot-ram.lds create mode 100644 configs/glacier_ramboot_defconfig diff --git a/arch/powerpc/cpu/ppc4xx/44x_spd_ddr2.c b/arch/powerpc/cpu/ppc4xx/44x_spd_ddr2.c index 71bb9d776f..7202c3fc46 100644 --- a/arch/powerpc/cpu/ppc4xx/44x_spd_ddr2.c +++ b/arch/powerpc/cpu/ppc4xx/44x_spd_ddr2.c @@ -424,6 +424,14 @@ phys_size_t initdram(int board_type) int write_recovery; phys_size_t dram_size = 0; + if (IS_ENABLED(CONFIG_SYS_RAMBOOT)) { + /* + * Reduce RAM size to avoid overwriting memory used by + * current stack? Not sure what is happening. + */ + return sdram_memsize() / 2; + } + num_dimm_banks = sizeof(iic0_dimm_addr); /*------------------------------------------------------------------ diff --git a/board/amcc/canyonlands/MAINTAINERS b/board/amcc/canyonlands/MAINTAINERS index 52bf004f6c..8be8a52a3a 100644 --- a/board/amcc/canyonlands/MAINTAINERS +++ b/board/amcc/canyonlands/MAINTAINERS @@ -6,3 +6,4 @@ F: include/configs/canyonlands.h F: configs/arches_defconfig F: configs/canyonlands_defconfig F: configs/glacier_defconfig +F: configs/glacier_ramboot_defconfig diff --git a/board/amcc/canyonlands/u-boot-ram.lds b/board/amcc/canyonlands/u-boot-ram.lds new file mode 100644 index 0000000000..67652569f4 --- /dev/null +++ b/board/amcc/canyonlands/u-boot-ram.lds @@ -0,0 +1,79 @@ +/* + * (C) Copyright 2009 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .text : + { + arch/powerpc/cpu/ppc4xx/start.o (.text*) + board/amcc/canyonlands/init.o (.text*) + + *(.text*) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + KEEP(*(.got)) + _GOT2_TABLE_ = .; + KEEP(*(.got2)) + _FIXUP_TABLE_ = .; + KEEP(*(.fixup)) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data*) + *(.sdata*) + } + _edata = .; + PROVIDE (edata = .); + + . = .; + + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + } + + __bss_end = . ; + PROVIDE (end = .); +} diff --git a/configs/glacier_ramboot_defconfig b/configs/glacier_ramboot_defconfig new file mode 100644 index 0000000000..4fc23038e8 --- /dev/null +++ b/configs/glacier_ramboot_defconfig @@ -0,0 +1,5 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_RAMBOOT,SYS_TEXT_BASE=0x01000000,SYS_LDSCRIPT=board/amcc/canyonlands/u-boot-ram.lds" +CONFIG_PPC=y +CONFIG_4xx=y +CONFIG_TARGET_CANYONLANDS=y +CONFIG_GLACIER=y -- cgit From 1d60f2b9860d3ba3563718d479a455495197f00d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:39 -0700 Subject: powerpc: ppc4xx: canyonlands: Move to generic board Switch to generic board so that this board will not be broken/removed. Signed-off-by: Simon Glass --- arch/powerpc/cpu/ppc4xx/cpu_init.c | 2 ++ include/configs/canyonlands.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/cpu/ppc4xx/cpu_init.c b/arch/powerpc/cpu/ppc4xx/cpu_init.c index e5a0e21e36..5f5c72002e 100644 --- a/arch/powerpc/cpu/ppc4xx/cpu_init.c +++ b/arch/powerpc/cpu/ppc4xx/cpu_init.c @@ -450,10 +450,12 @@ cpu_init_f (void) PLB4Ax_ACR_RDP_4DEEP); #endif /* CONFIG_440SP/SPE || CONFIG_460EX/GT || CONFIG_405EX */ +#ifndef CONFIG_SYS_GENERIC_BOARD gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); /* Clear initial global data */ memset((void *)gd, 0, sizeof(gd_t)); +#endif } /* diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index ed790ccaf3..7a1499d2e3 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -13,6 +13,8 @@ #include +#define CONFIG_SYS_GENERIC_BOARD + /*----------------------------------------------------------------------- * High Level Configuration Options *----------------------------------------------------------------------*/ -- cgit From 281aea45f8a237a1072116d4910cd86f4586f24b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:41 -0700 Subject: powerpc: ppc4xx: dts: Bring in canyonlands device tree files The canyonlands.h config file works with canyonlands, glacier and arches boards. Bring in the device tree files for these from Linux 3.17. Signed-off-by: Simon Glass --- arch/powerpc/dts/Makefile | 11 + arch/powerpc/dts/arches.dts | 339 +++++++++++++++++++++++ arch/powerpc/dts/canyonlands.dts | 555 +++++++++++++++++++++++++++++++++++++ arch/powerpc/dts/glacier.dts | 579 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 1484 insertions(+) create mode 100644 arch/powerpc/dts/Makefile create mode 100644 arch/powerpc/dts/arches.dts create mode 100644 arch/powerpc/dts/canyonlands.dts create mode 100644 arch/powerpc/dts/glacier.dts diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile new file mode 100644 index 0000000000..ad104b9315 --- /dev/null +++ b/arch/powerpc/dts/Makefile @@ -0,0 +1,11 @@ +dtb-$(CONFIG_TARGET_CANYONLANDS) += arches.dtb canyonlands.dtb glacier.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/powerpc/dts/arches.dts b/arch/powerpc/dts/arches.dts new file mode 100644 index 0000000000..bd5ebfde2b --- /dev/null +++ b/arch/powerpc/dts/arches.dts @@ -0,0 +1,339 @@ +/* + * Device Tree Source for AMCC Arches (dual 460GT board) + * + * (C) Copyright 2008 Applied Micro Circuits Corporation + * Victor Gallardo + * Adam Graham + * + * Based on the glacier.dts file + * Stefan Roese + * Copyright 2008 DENX Software Engineering + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "amcc,arches"; + compatible = "amcc,arches"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + ethernet1 = &EMAC1; + ethernet2 = &EMAC2; + serial0 = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,460GT"; + reg = <0x00000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0>; /* Filled in by U-Boot */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + next-level-cache = <&L2C0>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller0 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + UIC1: interrupt-controller1 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x0d0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC2: interrupt-controller2 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <2>; + dcr-reg = <0x0e0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC3: interrupt-controller3 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <3>; + dcr-reg = <0x0f0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + SDR0: sdr { + compatible = "ibm,sdr-460gt"; + dcr-reg = <0x00e 0x002>; + }; + + CPR0: cpr { + compatible = "ibm,cpr-460gt"; + dcr-reg = <0x00c 0x002>; + }; + + L2C0: l2c { + compatible = "ibm,l2-cache-460gt", "ibm,l2-cache"; + dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */ + 0x030 0x008>; /* L2 cache DCR's */ + cache-line-size = <32>; /* 32 bytes */ + cache-size = <262144>; /* L2, 256K */ + interrupt-parent = <&UIC1>; + interrupts = <11 1>; + }; + + plb { + compatible = "ibm,plb-460gt", "ibm,plb4"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by U-Boot */ + + SDRAM0: sdram { + compatible = "ibm,sdram-460gt", "ibm,sdram-405gp"; + dcr-reg = <0x010 0x002>; + }; + + CRYPTO: crypto@180000 { + compatible = "amcc,ppc460gt-crypto", "amcc,ppc4xx-crypto"; + reg = <4 0x00180000 0x80400>; + interrupt-parent = <&UIC0>; + interrupts = <0x1d 0x4>; + }; + + MAL0: mcmal { + compatible = "ibm,mcmal-460gt", "ibm,mcmal2"; + dcr-reg = <0x180 0x062>; + num-tx-chans = <3>; + num-rx-chans = <24>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-parent = <&UIC2>; + interrupts = < /*TXEOB*/ 0x6 0x4 + /*RXEOB*/ 0x7 0x4 + /*SERR*/ 0x3 0x4 + /*TXDE*/ 0x4 0x4 + /*RXDE*/ 0x5 0x4>; + desc-base-addr-high = <0x8>; + }; + + POB0: opb { + compatible = "ibm,opb-460gt", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + + EBC0: ebc { + compatible = "ibm,ebc-460gt", "ibm,ebc"; + dcr-reg = <0x012 0x002>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by U-Boot */ + /* ranges property is supplied by U-Boot */ + interrupts = <0x6 0x4>; + interrupt-parent = <&UIC1>; + + nor_flash@0,0 { + compatible = "amd,s29gl256n", "cfi-flash"; + bank-width = <2>; + reg = <0x00000000 0x00000000 0x02000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "kernel"; + reg = <0x00000000 0x001e0000>; + }; + partition@1e0000 { + label = "dtb"; + reg = <0x001e0000 0x00020000>; + }; + partition@200000 { + label = "root"; + reg = <0x00200000 0x00200000>; + }; + partition@400000 { + label = "user"; + reg = <0x00400000 0x01b60000>; + }; + partition@1f60000 { + label = "env"; + reg = <0x01f60000 0x00040000>; + }; + partition@1fa0000 { + label = "u-boot"; + reg = <0x01fa0000 0x00060000>; + }; + }; + }; + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC1>; + interrupts = <0x1 0x4>; + }; + + IIC0: i2c@ef600700 { + compatible = "ibm,iic-460gt", "ibm,iic"; + reg = <0xef600700 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x2 0x4>; + #address-cells = <1>; + #size-cells = <0>; + sttm@4a { + compatible = "ad,ad7414"; + reg = <0x4a>; + interrupt-parent = <&UIC1>; + interrupts = <0x0 0x8>; + }; + }; + + IIC1: i2c@ef600800 { + compatible = "ibm,iic-460gt", "ibm,iic"; + reg = <0xef600800 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x3 0x4>; + }; + + TAH0: emac-tah@ef601350 { + compatible = "ibm,tah-460gt", "ibm,tah"; + reg = <0xef601350 0x00000030>; + }; + + TAH1: emac-tah@ef601450 { + compatible = "ibm,tah-460gt", "ibm,tah"; + reg = <0xef601450 0x00000030>; + }; + + EMAC0: ethernet@ef600e00 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC0>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600e00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "sgmii"; + phy-map = <0xffffffff>; + gpcs-address = <0x0000000a>; + tah-device = <&TAH0>; + tah-channel = <0>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + }; + + EMAC1: ethernet@ef600f00 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC1>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600f00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <1>; + mal-rx-channel = <8>; + cell-index = <1>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "sgmii"; + phy-map = <0x00000000>; + gpcs-address = <0x0000000b>; + tah-device = <&TAH1>; + tah-channel = <1>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + + EMAC2: ethernet@ef601100 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC2>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef601100 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <2>; + mal-rx-channel = <16>; + cell-index = <2>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + tx-fifo-size-gige = <16384>; /* emac2&3 only */ + phy-mode = "sgmii"; + phy-map = <0x00000001>; + gpcs-address = <0x0000000C>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + }; + }; +}; diff --git a/arch/powerpc/dts/canyonlands.dts b/arch/powerpc/dts/canyonlands.dts new file mode 100644 index 0000000000..2ec9762e48 --- /dev/null +++ b/arch/powerpc/dts/canyonlands.dts @@ -0,0 +1,555 @@ +/* + * Device Tree Source for AMCC Canyonlands (460EX) + * + * Copyright 2008-2009 DENX Software Engineering, Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0 + */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "amcc,canyonlands"; + compatible = "amcc,canyonlands"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + ethernet1 = &EMAC1; + serial0 = &UART0; + serial1 = &UART1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,460EX"; + reg = <0x00000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0>; /* Filled in by U-Boot */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + next-level-cache = <&L2C0>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller0 { + compatible = "ibm,uic-460ex","ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + UIC1: interrupt-controller1 { + compatible = "ibm,uic-460ex","ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x0d0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC2: interrupt-controller2 { + compatible = "ibm,uic-460ex","ibm,uic"; + interrupt-controller; + cell-index = <2>; + dcr-reg = <0x0e0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC3: interrupt-controller3 { + compatible = "ibm,uic-460ex","ibm,uic"; + interrupt-controller; + cell-index = <3>; + dcr-reg = <0x0f0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + SDR0: sdr { + compatible = "ibm,sdr-460ex"; + dcr-reg = <0x00e 0x002>; + }; + + CPR0: cpr { + compatible = "ibm,cpr-460ex"; + dcr-reg = <0x00c 0x002>; + }; + + CPM0: cpm { + compatible = "ibm,cpm"; + dcr-access-method = "native"; + dcr-reg = <0x160 0x003>; + unused-units = <0x00000100>; + idle-doze = <0x02000000>; + standby = <0xfeff791d>; + }; + + L2C0: l2c { + compatible = "ibm,l2-cache-460ex", "ibm,l2-cache"; + dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */ + 0x030 0x008>; /* L2 cache DCR's */ + cache-line-size = <32>; /* 32 bytes */ + cache-size = <262144>; /* L2, 256K */ + interrupt-parent = <&UIC1>; + interrupts = <11 1>; + }; + + plb { + compatible = "ibm,plb-460ex", "ibm,plb4"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by U-Boot */ + + SDRAM0: sdram { + compatible = "ibm,sdram-460ex", "ibm,sdram-405gp"; + dcr-reg = <0x010 0x002>; + }; + + CRYPTO: crypto@180000 { + compatible = "amcc,ppc460ex-crypto", "amcc,ppc4xx-crypto"; + reg = <4 0x00180000 0x80400>; + interrupt-parent = <&UIC0>; + interrupts = <0x1d 0x4>; + }; + + HWRNG: hwrng@110000 { + compatible = "amcc,ppc460ex-rng", "ppc4xx-rng"; + reg = <4 0x00110000 0x50>; + }; + + MAL0: mcmal { + compatible = "ibm,mcmal-460ex", "ibm,mcmal2"; + dcr-reg = <0x180 0x062>; + num-tx-chans = <2>; + num-rx-chans = <16>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-parent = <&UIC2>; + interrupts = < /*TXEOB*/ 0x6 0x4 + /*RXEOB*/ 0x7 0x4 + /*SERR*/ 0x3 0x4 + /*TXDE*/ 0x4 0x4 + /*RXDE*/ 0x5 0x4>; + }; + + USB0: ehci@bffd0400 { + compatible = "ibm,usb-ehci-460ex", "usb-ehci"; + interrupt-parent = <&UIC2>; + interrupts = <0x1d 4>; + reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>; + }; + + USB1: usb@bffd0000 { + compatible = "ohci-le"; + reg = <4 0xbffd0000 0x60>; + interrupt-parent = <&UIC2>; + interrupts = <0x1e 4>; + }; + + USBOTG0: usbotg@bff80000 { + compatible = "amcc,dwc-otg"; + reg = <0x4 0xbff80000 0x10000>; + interrupt-parent = <&USBOTG0>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupts = <0x0 0x1 0x2>; + interrupt-map = ; + }; + + SATA0: sata@bffd1000 { + compatible = "amcc,sata-460ex"; + reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>; + interrupt-parent = <&UIC3>; + interrupts = <0x0 0x4 /* SATA */ + 0x5 0x4>; /* AHBDMA */ + }; + + POB0: opb { + compatible = "ibm,opb-460ex", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + + EBC0: ebc { + compatible = "ibm,ebc-460ex", "ibm,ebc"; + dcr-reg = <0x012 0x002>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by U-Boot */ + /* ranges property is supplied by U-Boot */ + interrupts = <0x6 0x4>; + interrupt-parent = <&UIC1>; + + nor_flash@0,0 { + compatible = "amd,s29gl512n", "cfi-flash"; + bank-width = <2>; + reg = <0x00000000 0x00000000 0x04000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "kernel"; + reg = <0x00000000 0x001e0000>; + }; + partition@1e0000 { + label = "dtb"; + reg = <0x001e0000 0x00020000>; + }; + partition@200000 { + label = "ramdisk"; + reg = <0x00200000 0x01400000>; + }; + partition@1600000 { + label = "jffs2"; + reg = <0x01600000 0x00400000>; + }; + partition@1a00000 { + label = "user"; + reg = <0x01a00000 0x02560000>; + }; + partition@3f60000 { + label = "env"; + reg = <0x03f60000 0x00040000>; + }; + partition@3fa0000 { + label = "u-boot"; + reg = <0x03fa0000 0x00060000>; + }; + }; + + cpld@2,0 { + compatible = "amcc,ppc460ex-bcsr"; + reg = <2 0x0 0x9>; + }; + + ndfc@3,0 { + compatible = "ibm,ndfc"; + reg = <0x00000003 0x00000000 0x00002000>; + ccr = <0x00001000>; + bank-settings = <0x80002222>; + #address-cells = <1>; + #size-cells = <1>; + + nand { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x00000000 0x00100000>; + }; + partition@100000 { + label = "user"; + reg = <0x00000000 0x03f00000>; + }; + }; + }; + }; + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC1>; + interrupts = <0x1 0x4>; + }; + + UART1: serial@ef600400 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC0>; + interrupts = <0x1 0x4>; + }; + + IIC0: i2c@ef600700 { + compatible = "ibm,iic-460ex", "ibm,iic"; + reg = <0xef600700 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x2 0x4>; + #address-cells = <1>; + #size-cells = <0>; + rtc@68 { + compatible = "stm,m41t80"; + reg = <0x68>; + interrupt-parent = <&UIC2>; + interrupts = <0x19 0x8>; + }; + sttm@48 { + compatible = "ad,ad7414"; + reg = <0x48>; + interrupt-parent = <&UIC1>; + interrupts = <0x14 0x8>; + }; + }; + + IIC1: i2c@ef600800 { + compatible = "ibm,iic-460ex", "ibm,iic"; + reg = <0xef600800 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x3 0x4>; + }; + + GPIO0: gpio@ef600b00 { + compatible = "ibm,ppc4xx-gpio"; + reg = <0xef600b00 0x00000048>; + gpio-controller; + }; + + ZMII0: emac-zmii@ef600d00 { + compatible = "ibm,zmii-460ex", "ibm,zmii"; + reg = <0xef600d00 0x0000000c>; + }; + + RGMII0: emac-rgmii@ef601500 { + compatible = "ibm,rgmii-460ex", "ibm,rgmii"; + reg = <0xef601500 0x00000008>; + has-mdio; + }; + + TAH0: emac-tah@ef601350 { + compatible = "ibm,tah-460ex", "ibm,tah"; + reg = <0xef601350 0x00000030>; + }; + + TAH1: emac-tah@ef601450 { + compatible = "ibm,tah-460ex", "ibm,tah"; + reg = <0xef601450 0x00000030>; + }; + + EMAC0: ethernet@ef600e00 { + device_type = "network"; + compatible = "ibm,emac-460ex", "ibm,emac4sync"; + interrupt-parent = <&EMAC0>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600e00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII0>; + rgmii-channel = <0>; + tah-device = <&TAH0>; + tah-channel = <0>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + }; + + EMAC1: ethernet@ef600f00 { + device_type = "network"; + compatible = "ibm,emac-460ex", "ibm,emac4sync"; + interrupt-parent = <&EMAC1>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600f00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <1>; + mal-rx-channel = <8>; + cell-index = <1>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII0>; + rgmii-channel = <1>; + tah-device = <&TAH1>; + tah-channel = <1>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + }; + + PCIX0: pci@c0ec00000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix"; + primary; + large-inbound-windows; + enable-msi-hole; + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 0 to 0x3f */ + bus-range = <0x0 0x3f>; + + /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */ + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >; + }; + + PCIE0: pciex@d00000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; + primary; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x08010000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 40 to 0x7f */ + bus-range = <0x40 0x7f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; + }; + + PCIE1: pciex@d20000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; + primary; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x08011000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 80 to 0xbf */ + bus-range = <0x80 0xbf>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x10 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x11 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>; + }; + + MSI: ppc4xx-msi@C10000000 { + compatible = "amcc,ppc4xx-msi", "ppc4xx-msi"; + reg = < 0xC 0x10000000 0x100>; + sdr-base = <0x36C>; + msi-data = <0x00000000>; + msi-mask = <0x44440000>; + interrupt-count = <3>; + interrupts = <0 1 2 3>; + interrupt-parent = <&UIC3>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0 &UIC3 0x18 1 + 1 &UIC3 0x19 1 + 2 &UIC3 0x1A 1 + 3 &UIC3 0x1B 1>; + }; + }; +}; diff --git a/arch/powerpc/dts/glacier.dts b/arch/powerpc/dts/glacier.dts new file mode 100644 index 0000000000..3e7ce2c9e6 --- /dev/null +++ b/arch/powerpc/dts/glacier.dts @@ -0,0 +1,579 @@ +/* + * Device Tree Source for AMCC Glacier (460GT) + * + * Copyright 2008-2010 DENX Software Engineering, Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0 + */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "amcc,glacier"; + compatible = "amcc,glacier"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + ethernet1 = &EMAC1; + ethernet2 = &EMAC2; + ethernet3 = &EMAC3; + serial0 = &UART0; + serial1 = &UART1; + }; + + chosen { + stdout-path = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,460GT"; + reg = <0x00000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0>; /* Filled in by U-Boot */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + next-level-cache = <&L2C0>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller0 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <0>; + dcr-reg = <0x0c0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + UIC1: interrupt-controller1 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <1>; + dcr-reg = <0x0d0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC2: interrupt-controller2 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <2>; + dcr-reg = <0x0e0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0xa 0x4 0xb 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + UIC3: interrupt-controller3 { + compatible = "ibm,uic-460gt","ibm,uic"; + interrupt-controller; + cell-index = <3>; + dcr-reg = <0x0f0 0x009>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + interrupts = <0x10 0x4 0x11 0x4>; /* cascade */ + interrupt-parent = <&UIC0>; + }; + + SDR0: sdr { + compatible = "ibm,sdr-460gt"; + dcr-reg = <0x00e 0x002>; + }; + + CPR0: cpr { + compatible = "ibm,cpr-460gt"; + dcr-reg = <0x00c 0x002>; + }; + + L2C0: l2c { + compatible = "ibm,l2-cache-460gt", "ibm,l2-cache"; + dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */ + 0x030 0x008>; /* L2 cache DCR's */ + cache-line-size = <32>; /* 32 bytes */ + cache-size = <262144>; /* L2, 256K */ + interrupt-parent = <&UIC1>; + interrupts = <11 1>; + }; + + plb { + compatible = "ibm,plb-460gt", "ibm,plb4"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by U-Boot */ + + SDRAM0: sdram { + compatible = "ibm,sdram-460gt", "ibm,sdram-405gp"; + dcr-reg = <0x010 0x002>; + }; + + CRYPTO: crypto@180000 { + compatible = "amcc,ppc460gt-crypto", "amcc,ppc460ex-crypto", + "amcc,ppc4xx-crypto"; + reg = <4 0x00180000 0x80400>; + interrupt-parent = <&UIC0>; + interrupts = <0x1d 0x4>; + }; + + HWRNG: hwrng@110000 { + compatible = "amcc,ppc460ex-rng", "ppc4xx-rng"; + reg = <4 0x00110000 0x50>; + }; + + MAL0: mcmal { + compatible = "ibm,mcmal-460gt", "ibm,mcmal2"; + dcr-reg = <0x180 0x062>; + num-tx-chans = <4>; + num-rx-chans = <32>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-parent = <&UIC2>; + interrupts = < /*TXEOB*/ 0x6 0x4 + /*RXEOB*/ 0x7 0x4 + /*SERR*/ 0x3 0x4 + /*TXDE*/ 0x4 0x4 + /*RXDE*/ 0x5 0x4>; + desc-base-addr-high = <0x8>; + }; + + POB0: opb { + compatible = "ibm,opb-460gt", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>; + clock-frequency = <0>; /* Filled in by U-Boot */ + + EBC0: ebc { + compatible = "ibm,ebc-460gt", "ibm,ebc"; + dcr-reg = <0x012 0x002>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by U-Boot */ + /* ranges property is supplied by U-Boot */ + interrupts = <0x6 0x4>; + interrupt-parent = <&UIC1>; + + nor_flash@0,0 { + compatible = "amd,s29gl512n", "cfi-flash"; + bank-width = <2>; + reg = <0x00000000 0x00000000 0x04000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "kernel"; + reg = <0x00000000 0x001e0000>; + }; + partition@1e0000 { + label = "dtb"; + reg = <0x001e0000 0x00020000>; + }; + partition@200000 { + label = "ramdisk"; + reg = <0x00200000 0x01400000>; + }; + partition@1600000 { + label = "jffs2"; + reg = <0x01600000 0x00400000>; + }; + partition@1a00000 { + label = "user"; + reg = <0x01a00000 0x02560000>; + }; + partition@3f60000 { + label = "env"; + reg = <0x03f60000 0x00040000>; + }; + partition@3fa0000 { + label = "u-boot"; + reg = <0x03fa0000 0x00060000>; + }; + }; + + ndfc@3,0 { + compatible = "ibm,ndfc"; + reg = <0x00000003 0x00000000 0x00002000>; + ccr = <0x00001000>; + bank-settings = <0x80002222>; + #address-cells = <1>; + #size-cells = <1>; + + nand { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x00000000 0x00100000>; + }; + partition@100000 { + label = "user"; + reg = <0x00000000 0x03f00000>; + }; + }; + }; + }; + + UART0: serial@ef600300 { + device_type = "serial"; + reg-shift = <0>; + compatible = "ns16550"; + reg = <0xef600300 0x00000008>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC1>; + interrupts = <0x1 0x4>; + }; + + UART1: serial@ef600400 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600400 0x00000008>; + virtual-reg = <0xef600400>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC0>; + interrupts = <0x1 0x4>; + }; + + UART2: serial@ef600500 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600500 0x00000008>; + virtual-reg = <0xef600500>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC1>; + interrupts = <28 0x4>; + }; + + UART3: serial@ef600600 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600600 0x00000008>; + virtual-reg = <0xef600600>; + clock-frequency = <0>; /* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <&UIC1>; + interrupts = <29 0x4>; + }; + + IIC0: i2c@ef600700 { + compatible = "ibm,iic-460gt", "ibm,iic"; + reg = <0xef600700 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x2 0x4>; + #address-cells = <1>; + #size-cells = <0>; + rtc@68 { + compatible = "stm,m41t80"; + reg = <0x68>; + interrupt-parent = <&UIC2>; + interrupts = <0x19 0x8>; + }; + sttm@48 { + compatible = "ad,ad7414"; + reg = <0x48>; + interrupt-parent = <&UIC1>; + interrupts = <0x14 0x8>; + }; + }; + + IIC1: i2c@ef600800 { + compatible = "ibm,iic-460gt", "ibm,iic"; + reg = <0xef600800 0x00000014>; + interrupt-parent = <&UIC0>; + interrupts = <0x3 0x4>; + }; + + ZMII0: emac-zmii@ef600d00 { + compatible = "ibm,zmii-460gt", "ibm,zmii"; + reg = <0xef600d00 0x0000000c>; + }; + + RGMII0: emac-rgmii@ef601500 { + compatible = "ibm,rgmii-460gt", "ibm,rgmii"; + reg = <0xef601500 0x00000008>; + has-mdio; + }; + + RGMII1: emac-rgmii@ef601600 { + compatible = "ibm,rgmii-460gt", "ibm,rgmii"; + reg = <0xef601600 0x00000008>; + has-mdio; + }; + + TAH0: emac-tah@ef601350 { + compatible = "ibm,tah-460gt", "ibm,tah"; + reg = <0xef601350 0x00000030>; + }; + + TAH1: emac-tah@ef601450 { + compatible = "ibm,tah-460gt", "ibm,tah"; + reg = <0xef601450 0x00000030>; + }; + + EMAC0: ethernet@ef600e00 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC0>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600e00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII0>; + rgmii-channel = <0>; + tah-device = <&TAH0>; + tah-channel = <0>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + }; + + EMAC1: ethernet@ef600f00 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC1>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef600f00 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <1>; + mal-rx-channel = <8>; + cell-index = <1>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII0>; + rgmii-channel = <1>; + tah-device = <&TAH1>; + tah-channel = <1>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + + EMAC2: ethernet@ef601100 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC2>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef601100 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <2>; + mal-rx-channel = <16>; + cell-index = <2>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + tx-fifo-size-gige = <16384>; /* emac2&3 only */ + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII1>; + rgmii-channel = <0>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + + EMAC3: ethernet@ef601200 { + device_type = "network"; + compatible = "ibm,emac-460gt", "ibm,emac4sync"; + interrupt-parent = <&EMAC3>; + interrupts = <0x0 0x1>; + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = ; + reg = <0xef601200 0x000000c4>; + local-mac-address = [000000000000]; /* Filled in by U-Boot */ + mal-device = <&MAL0>; + mal-tx-channel = <3>; + mal-rx-channel = <24>; + cell-index = <3>; + max-frame-size = <9000>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + rx-fifo-size-gige = <16384>; + tx-fifo-size-gige = <16384>; /* emac2&3 only */ + phy-mode = "rgmii"; + phy-map = <0x00000000>; + rgmii-device = <&RGMII1>; + rgmii-channel = <1>; + has-inverted-stacr-oc; + has-new-stacr-staopc; + mdio-device = <&EMAC0>; + }; + }; + + PCIX0: pci@c0ec00000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pcix-460gt", "ibm,plb-pcix"; + primary; + large-inbound-windows; + enable-msi-hole; + reg = <0x0000000c 0x0ec00000 0x00000008 /* Config space access */ + 0x00000000 0x00000000 0x00000000 /* no IACK cycles */ + 0x0000000c 0x0ed00000 0x00000004 /* Special cycles */ + 0x0000000c 0x0ec80000 0x00000100 /* Internal registers */ + 0x0000000c 0x0ec80100 0x000000fc>; /* Internal messaging registers */ + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 0x80000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000c 0x0ee00000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000c 0x08000000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 0 to 0x3f */ + bus-range = <0x0 0x3f>; + + /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 */ + interrupt-map-mask = <0x0 0x0 0x0 0x0>; + interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >; + }; + + PCIE0: pciex@d00000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; + primary; + port = <0x0>; /* port number */ + reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ + 0x0000000c 0x08010000 0x00001000>; /* Registers */ + dcr-reg = <0x100 0x020>; + sdr-base = <0x300>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000f 0x00000000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 40 to 0x7f */ + bus-range = <0x40 0x7f>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D */>; + }; + + PCIE1: pciex@d20000000 { + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex"; + primary; + port = <0x1>; /* port number */ + reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ + 0x0000000c 0x08011000 0x00001000>; /* Registers */ + dcr-reg = <0x120 0x020>; + sdr-base = <0x340>; + + /* Outbound ranges, one memory and one IO, + * later cannot be changed + */ + ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 + 0x02000000 0x00000000 0x00000000 0x0000000f 0x00100000 0x00000000 0x00100000 + 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; + + /* Inbound 2GB range starting at 0 */ + dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; + + /* This drives busses 80 to 0xbf */ + bus-range = <0x80 0xbf>; + + /* Legacy interrupts (note the weird polarity, the bridge seems + * to invert PCIe legacy interrupts). + * We are de-swizzling here because the numbers are actually for + * port of the root complex virtual P2P bridge. But I want + * to avoid putting a node for it in the tree, so the numbers + * below are basically de-swizzled numbers. + * The real slot is on idsel 0, so the swizzling is 1:1 + */ + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = < + 0x0 0x0 0x0 0x1 &UIC3 0x10 0x4 /* swizzled int A */ + 0x0 0x0 0x0 0x2 &UIC3 0x11 0x4 /* swizzled int B */ + 0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */ + 0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>; + }; + }; +}; -- cgit From 36ec4c021a56209be87b9fe7c2865fd95a820f63 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:42 -0700 Subject: powerpc: ppc4xx: Call board_init_f_mem() for generic board Call this function to set up our early memory. Signed-off-by: Simon Glass --- arch/powerpc/cpu/ppc4xx/start.S | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S index 09a02d771c..7a0f0d25d1 100644 --- a/arch/powerpc/cpu/ppc4xx/start.S +++ b/arch/powerpc/cpu/ppc4xx/start.S @@ -760,6 +760,15 @@ _start: #endif bl cpu_init_f /* run low-level CPU init code (from Flash) */ +#ifdef CONFIG_SYS_GENERIC_BOARD + mr r3, r1 + bl board_init_f_mem + mr r1, r3 + li r0,0 + stwu r0, -4(r1) + stwu r0, -4(r1) +#endif + li r3, 0 bl board_init_f /* NOTREACHED - board_init_f() does not return */ @@ -1027,7 +1036,14 @@ _start: GET_GOT /* initialize GOT access */ bl cpu_init_f /* run low-level CPU init code (from Flash) */ - +#ifdef CONFIG_SYS_GENERIC_BOARD + mr r3, r1 + bl board_init_f_mem + mr r1, r3 + stwu r0, -4(r1) + stwu r0, -4(r1) +#endif + li r3, 0 bl board_init_f /* run first part of init code (from Flash) */ /* NOTREACHED - board_init_f() does not return */ -- cgit From 86bedaebb570c2a111cdcafbf310f95b1bd58a14 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:43 -0700 Subject: powerpc: ppc4xx: Add a gpio.h header file This is required at present for device tree control. The ppc4xx does support GPIOs but does not seem to have a proper driver. So this file is empty. Signed-off-by: Simon Glass --- arch/powerpc/include/asm/arch-ppc4xx/gpio.h | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 arch/powerpc/include/asm/arch-ppc4xx/gpio.h diff --git a/arch/powerpc/include/asm/arch-ppc4xx/gpio.h b/arch/powerpc/include/asm/arch-ppc4xx/gpio.h new file mode 100644 index 0000000000..3d960c3f1f --- /dev/null +++ b/arch/powerpc/include/asm/arch-ppc4xx/gpio.h @@ -0,0 +1,7 @@ +/* + * (C) Copyright 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* This is empty for now as we don't support the generic GPIO interface */ -- cgit From 0de36f8b62f5f9897f9434f4c3f5739117370694 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:44 -0700 Subject: powerpc: ppc4xx: Allow the end of u-boot.bin to be found Define an _end symbol indicating the end of u-boot.bin. Also add some dummy words into the link script to ensure that u-boot.bin will always extend that far. There may be a better way of doing this. Signed-off-by: Simon Glass --- arch/powerpc/cpu/ppc4xx/u-boot.lds | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/cpu/ppc4xx/u-boot.lds b/arch/powerpc/cpu/ppc4xx/u-boot.lds index 87731785ec..198050853a 100644 --- a/arch/powerpc/cpu/ppc4xx/u-boot.lds +++ b/arch/powerpc/cpu/ppc4xx/u-boot.lds @@ -76,9 +76,13 @@ SECTIONS . = ALIGN(256); __init_begin = .; .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); + .data.init : { + *(.data.init) + . = ALIGN(256); + LONG(0) LONG(0) /* Extend u-boot.bin to here */ + } __init_end = .; + _end = .; #ifndef CONFIG_SPL #ifdef CONFIG_440 -- cgit From 43301741fc3455704204df100bf73a4c2f15b697 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:45 -0700 Subject: powerpc: ppc4xx: Use CONFIG_OF_CONTROL for canyonlands boards Enable CONFIG_OF_CONTROL so that U-Boot on these three boards uses a device tree for its configuration. Signed-off-by: Simon Glass --- board/amcc/canyonlands/u-boot-ram.lds | 10 ++++++++-- configs/arches_defconfig | 3 +++ configs/canyonlands_defconfig | 3 +++ configs/glacier_defconfig | 3 +++ configs/glacier_ramboot_defconfig | 3 +++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/board/amcc/canyonlands/u-boot-ram.lds b/board/amcc/canyonlands/u-boot-ram.lds index 67652569f4..1750c74a19 100644 --- a/board/amcc/canyonlands/u-boot-ram.lds +++ b/board/amcc/canyonlands/u-boot-ram.lds @@ -12,6 +12,7 @@ SECTIONS . = + SIZEOF_HEADERS; .text : { + _image_copy_start = .; arch/powerpc/cpu/ppc4xx/start.o (.text*) board/amcc/canyonlands/init.o (.text*) @@ -61,9 +62,14 @@ SECTIONS . = ALIGN(256); __init_begin = .; .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(256); + .data.init : { + *(.data.init) + . = ALIGN(256); + LONG(0) LONG(0) /* Extend u-boot.bin to here */ + } __init_end = .; + _end = .; + _image_binary_end = .; __bss_start = .; .bss (NOLOAD) : diff --git a/configs/arches_defconfig b/configs/arches_defconfig index 60e6ef9098..30c6932358 100644 --- a/configs/arches_defconfig +++ b/configs/arches_defconfig @@ -2,3 +2,6 @@ CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y CONFIG_ARCHES=y +CONFIG_DEFAULT_DEVICE_TREE="arches" +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y diff --git a/configs/canyonlands_defconfig b/configs/canyonlands_defconfig index 37a2b4d796..6f6cf14811 100644 --- a/configs/canyonlands_defconfig +++ b/configs/canyonlands_defconfig @@ -2,3 +2,6 @@ CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y CONFIG_CANYONLANDS=y +CONFIG_DEFAULT_DEVICE_TREE="canyonlands" +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y diff --git a/configs/glacier_defconfig b/configs/glacier_defconfig index 436b9f8d03..e67fa32f56 100644 --- a/configs/glacier_defconfig +++ b/configs/glacier_defconfig @@ -2,3 +2,6 @@ CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y CONFIG_GLACIER=y +CONFIG_DEFAULT_DEVICE_TREE="glacier" +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y diff --git a/configs/glacier_ramboot_defconfig b/configs/glacier_ramboot_defconfig index 4fc23038e8..e5b402e747 100644 --- a/configs/glacier_ramboot_defconfig +++ b/configs/glacier_ramboot_defconfig @@ -3,3 +3,6 @@ CONFIG_PPC=y CONFIG_4xx=y CONFIG_TARGET_CANYONLANDS=y CONFIG_GLACIER=y +CONFIG_DEFAULT_DEVICE_TREE="glacier" +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y -- cgit From 0e7806d24a77179053c64ba481b3857805e061c8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:46 -0700 Subject: ppc: amcc: Omit unneeded ns16550 CONFIG if using driver model This comes from the device tree or a call to get_uart_clock(). Signed-off-by: Simon Glass --- arch/powerpc/include/asm/ppc460ex_gt.h | 2 ++ include/configs/amcc-common.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/include/asm/ppc460ex_gt.h b/arch/powerpc/include/asm/ppc460ex_gt.h index f41df0da6a..ea019aafdb 100644 --- a/arch/powerpc/include/asm/ppc460ex_gt.h +++ b/arch/powerpc/include/asm/ppc460ex_gt.h @@ -19,10 +19,12 @@ /* Memory mapped registers */ #define CONFIG_SYS_PERIPHERAL_BASE 0xef600000 /* Internal Peripherals */ +#ifndef CONFIG_DM_SERIAL #define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_PERIPHERAL_BASE + 0x0300) #define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_PERIPHERAL_BASE + 0x0400) #define CONFIG_SYS_NS16550_COM3 (CONFIG_SYS_PERIPHERAL_BASE + 0x0500) #define CONFIG_SYS_NS16550_COM4 (CONFIG_SYS_PERIPHERAL_BASE + 0x0600) +#endif #define GPIO0_BASE (CONFIG_SYS_PERIPHERAL_BASE + 0x0b00) #define GPIO1_BASE (CONFIG_SYS_PERIPHERAL_BASE + 0x0c00) diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h index 2aea89937a..73e1b0afa8 100644 --- a/include/configs/amcc-common.h +++ b/include/configs/amcc-common.h @@ -20,8 +20,10 @@ */ #define CONFIG_SYS_NS16550 #define CONFIG_SYS_NS16550_SERIAL +#ifndef CONFIG_DM_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE 1 #define CONFIG_SYS_NS16550_CLK get_serial_clock() +#endif #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} -- cgit From fad486ce51b7ae96f5004e50249c675d5ac20136 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:47 -0700 Subject: powerpc: Add serial driver for driver model This uses the ns16550 driver but sets up the clock at run-time. It does not seem to be available in the device tree. Signed-off-by: Simon Glass --- drivers/serial/Makefile | 1 + drivers/serial/serial_ppc.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 drivers/serial/serial_ppc.c diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 4cc00cd2f8..63b0cbf5da 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -8,6 +8,7 @@ ifdef CONFIG_DM_SERIAL obj-y += serial-uclass.o obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o +obj-$(CONFIG_PPC) += serial_ppc.o else obj-y += serial.o obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o diff --git a/drivers/serial/serial_ppc.c b/drivers/serial/serial_ppc.c new file mode 100644 index 0000000000..47141c64eb --- /dev/null +++ b/drivers/serial/serial_ppc.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static const struct udevice_id ppc_serial_ids[] = { + { .compatible = "ns16550" }, + { } +}; + +static int ppc_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = get_serial_clock(); + + return 0; +} + +U_BOOT_DRIVER(serial_ns16550) = { + .name = "serial_ppc", + .id = UCLASS_SERIAL, + .of_match = ppc_serial_ids, + .ofdata_to_platdata = ppc_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit From 5d418fdb99abb1f8e165c358087b90c46dcb5c00 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:48 -0700 Subject: dm: powerpc: ppc4xx: Move glacier to use driver model for serial Adjust Kconfig to default to driver model for glacier, canyonlands and arches. Signed-off-by: Simon Glass --- board/amcc/canyonlands/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/board/amcc/canyonlands/Kconfig b/board/amcc/canyonlands/Kconfig index 0fc687739c..de709148b3 100644 --- a/board/amcc/canyonlands/Kconfig +++ b/board/amcc/canyonlands/Kconfig @@ -29,4 +29,18 @@ config ARCHES endchoice +config DM + default y + +config DM_SERIAL + default y + +config SYS_MALLOC_F + bool + default y + +config SYS_MALLOC_F_LEN + hex + default 0x400 + endif -- cgit From 0df09047fadc7f3d097a132120da8f10278e4a0d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 11:51:49 -0700 Subject: powerpc: Add linkage.h file This permits us to use linux/linkage.h on PowerPC machines. Signed-off-by: Simon Glass --- arch/powerpc/include/asm/linkage.h | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 arch/powerpc/include/asm/linkage.h diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h new file mode 100644 index 0000000000..559b42ed3b --- /dev/null +++ b/arch/powerpc/include/asm/linkage.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* We don't need anything here at present */ -- cgit From f693e7f5140382ba6cb76e532852efb5ccfb7c9a Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 7 Feb 2015 11:51:50 -0700 Subject: powerpc: ppc4xx: Change from OF_SEPARATE to OF_EMBED This is necessary, as ppc4xx has the reset vector located at the end of the U-Boot image. This needs to be flashed to the end of the NOR flash. Adding the dtb to the main U-Boot image will break booting on ppc4xx. This patch now embeds the dtb in the U-Boot image instead. Signed-off-by: Stefan Roese Cc: Simon Glass Reviewed-by: Simon Glass Signed-off-by: Simon Glass --- configs/canyonlands_defconfig | 2 +- configs/glacier_defconfig | 2 +- configs/glacier_ramboot_defconfig | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/canyonlands_defconfig b/configs/canyonlands_defconfig index 6f6cf14811..44d4fbdb9d 100644 --- a/configs/canyonlands_defconfig +++ b/configs/canyonlands_defconfig @@ -4,4 +4,4 @@ CONFIG_TARGET_CANYONLANDS=y CONFIG_CANYONLANDS=y CONFIG_DEFAULT_DEVICE_TREE="canyonlands" CONFIG_OF_CONTROL=y -CONFIG_OF_SEPARATE=y +CONFIG_OF_EMBED=y diff --git a/configs/glacier_defconfig b/configs/glacier_defconfig index e67fa32f56..d318f82c4c 100644 --- a/configs/glacier_defconfig +++ b/configs/glacier_defconfig @@ -4,4 +4,4 @@ CONFIG_TARGET_CANYONLANDS=y CONFIG_GLACIER=y CONFIG_DEFAULT_DEVICE_TREE="glacier" CONFIG_OF_CONTROL=y -CONFIG_OF_SEPARATE=y +CONFIG_OF_EMBED=y diff --git a/configs/glacier_ramboot_defconfig b/configs/glacier_ramboot_defconfig index e5b402e747..f8363b2e23 100644 --- a/configs/glacier_ramboot_defconfig +++ b/configs/glacier_ramboot_defconfig @@ -5,4 +5,4 @@ CONFIG_TARGET_CANYONLANDS=y CONFIG_GLACIER=y CONFIG_DEFAULT_DEVICE_TREE="glacier" CONFIG_OF_CONTROL=y -CONFIG_OF_SEPARATE=y +CONFIG_OF_EMBED=y -- cgit From 275029074d0adeece0c9e38be0cc61bdfa390b18 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 7 Feb 2015 11:51:51 -0700 Subject: powerpc: ppc4xx: Add defaults for DT based booting to really work These additional nodes need to be provided to get U-Boot to boot correctly on the Canyonlands / Glacier board: - chosen path to the console-uart - reg-shift set to 0 in the uart device nodes Signed-off-by: Stefan Roese Cc: Simon Glass Reviewed-by: Simon Glass Signed-off-by: Simon Glass --- arch/powerpc/dts/canyonlands.dts | 6 ++++++ arch/powerpc/dts/glacier.dts | 3 +++ 2 files changed, 9 insertions(+) diff --git a/arch/powerpc/dts/canyonlands.dts b/arch/powerpc/dts/canyonlands.dts index 2ec9762e48..0a2f5d7649 100644 --- a/arch/powerpc/dts/canyonlands.dts +++ b/arch/powerpc/dts/canyonlands.dts @@ -22,6 +22,10 @@ serial1 = &UART1; }; + chosen { + stdout-path = &UART0; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -280,6 +284,7 @@ UART0: serial@ef600300 { device_type = "serial"; + reg-shift = <0>; compatible = "ns16550"; reg = <0xef600300 0x00000008>; virtual-reg = <0xef600300>; @@ -291,6 +296,7 @@ UART1: serial@ef600400 { device_type = "serial"; + reg-shift = <0>; compatible = "ns16550"; reg = <0xef600400 0x00000008>; virtual-reg = <0xef600400>; diff --git a/arch/powerpc/dts/glacier.dts b/arch/powerpc/dts/glacier.dts index 3e7ce2c9e6..bb4e819e91 100644 --- a/arch/powerpc/dts/glacier.dts +++ b/arch/powerpc/dts/glacier.dts @@ -251,6 +251,7 @@ UART1: serial@ef600400 { device_type = "serial"; + reg-shift = <0>; compatible = "ns16550"; reg = <0xef600400 0x00000008>; virtual-reg = <0xef600400>; @@ -262,6 +263,7 @@ UART2: serial@ef600500 { device_type = "serial"; + reg-shift = <0>; compatible = "ns16550"; reg = <0xef600500 0x00000008>; virtual-reg = <0xef600500>; @@ -273,6 +275,7 @@ UART3: serial@ef600600 { device_type = "serial"; + reg-shift = <0>; compatible = "ns16550"; reg = <0xef600600 0x00000008>; virtual-reg = <0xef600600>; -- cgit From 360334a1786c2ef8753239818ca295211b2d5aa8 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 7 Feb 2015 11:51:52 -0700 Subject: powerpc: ppc4xx: Enable CONFIG_DISPLAY_BOARDINFO This also displays the "Board:" line in the bootup text with the generic board support code. Signed-off-by: Stefan Roese Cc: Simon Glass Reviewed-by: Simon Glass Signed-off-by: Simon Glass --- board/amcc/canyonlands/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/board/amcc/canyonlands/Kconfig b/board/amcc/canyonlands/Kconfig index de709148b3..848e08fbba 100644 --- a/board/amcc/canyonlands/Kconfig +++ b/board/amcc/canyonlands/Kconfig @@ -29,6 +29,10 @@ config ARCHES endchoice +config DISPLAY_BOARDINFO + bool + default y + config DM default y -- cgit From 0da0fcd51f6566d84eb24cbbd4c8ad784c702849 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:08 -0700 Subject: net: Use new checksum functions Drop the old checksum functions in favour of the new ones. Signed-off-by: Simon Glass Acked-by: Joe Hershberger --- include/net.h | 4 ---- net/net.c | 25 ++----------------------- net/ping.c | 10 ++++------ 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/include/net.h b/include/net.h index 73ea88b42d..43e3d28729 100644 --- a/include/net.h +++ b/include/net.h @@ -512,10 +512,6 @@ unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum); */ int ip_checksum_ok(const void *addr, unsigned nbytes); -/* Checksum */ -extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ -extern uint NetCksum(uchar *, int); /* Calculate the checksum */ - /* Callbacks */ extern rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */ extern void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */ diff --git a/net/net.c b/net/net.c index 2bea07b3cd..b60ce6242c 100644 --- a/net/net.c +++ b/net/net.c @@ -1086,7 +1086,7 @@ NetReceive(uchar *inpkt, int len) if ((ip->ip_hl_v & 0x0f) > 0x05) return; /* Check the Checksum of the header */ - if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE / 2)) { + if (!ip_checksum_ok((uchar *)ip, IP_HDR_SIZE)) { debug("checksum bad\n"); return; } @@ -1290,27 +1290,6 @@ common: } /**********************************************************************/ -int -NetCksumOk(uchar *ptr, int len) -{ - return !((NetCksum(ptr, len) + 1) & 0xfffe); -} - - -unsigned -NetCksum(uchar *ptr, int len) -{ - ulong xsum; - ushort *p = (ushort *)ptr; - - xsum = 0; - while (len-- > 0) - xsum += *p++; - xsum = (xsum & 0xffff) + (xsum >> 16); - xsum = (xsum & 0xffff) + (xsum >> 16); - return xsum & 0xffff; -} - int NetEthHdrSize(void) { @@ -1410,7 +1389,7 @@ void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, net_set_ip_header(pkt, dest, NetOurIP); ip->ip_len = htons(IP_UDP_HDR_SIZE + len); ip->ip_p = IPPROTO_UDP; - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); ip->udp_src = htons(sport); ip->udp_dst = htons(dport); diff --git a/net/ping.c b/net/ping.c index 2be56ed929..366f51825f 100644 --- a/net/ping.c +++ b/net/ping.c @@ -29,14 +29,14 @@ static void set_icmp_header(uchar *pkt, IPaddr_t dest) ip->ip_len = htons(IP_ICMP_HDR_SIZE); ip->ip_p = IPPROTO_ICMP; - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE >> 1); + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); icmp->type = ICMP_ECHO_REQUEST; icmp->code = 0; icmp->checksum = 0; icmp->un.echo.id = 0; icmp->un.echo.sequence = htons(PingSeqNo++); - icmp->checksum = ~NetCksum((uchar *)icmp, ICMP_HDR_SIZE >> 1); + icmp->checksum = compute_ip_checksum(icmp, ICMP_HDR_SIZE); } static int ping_send(void) @@ -101,13 +101,11 @@ void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len) ip->ip_off = 0; NetCopyIP((void *)&ip->ip_dst, &ip->ip_src); NetCopyIP((void *)&ip->ip_src, &NetOurIP); - ip->ip_sum = ~NetCksum((uchar *)ip, - IP_HDR_SIZE >> 1); + ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE); icmph->type = ICMP_ECHO_REPLY; icmph->checksum = 0; - icmph->checksum = ~NetCksum((uchar *)icmph, - (len - IP_HDR_SIZE) >> 1); + icmph->checksum = compute_ip_checksum(icmph, len - IP_HDR_SIZE); NetSendPacket((uchar *)et, eth_hdr_size + len); return; /* default: -- cgit From ca88b9b93916f66c6737527aa955d2c1b4758080 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:32 -0700 Subject: dm: i2c: Add a dm_ prefix to driver model bus speed functions As with i2c_read() and i2c_write(), add a dm_ prefix to the driver model versions of these functions to avoid conflicts. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- common/cmd_i2c.c | 4 ++-- drivers/i2c/i2c-uclass.c | 11 +++-------- include/i2c.h | 8 ++++---- test/dm/i2c.c | 6 +++--- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 7c3ad00fdf..fe8f77aaec 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1730,7 +1730,7 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const #endif if (argc == 1) { #ifdef CONFIG_DM_I2C - speed = i2c_get_bus_speed(bus); + speed = dm_i2c_get_bus_speed(bus); #else speed = i2c_get_bus_speed(); #endif @@ -1740,7 +1740,7 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const speed = simple_strtoul(argv[1], NULL, 10); printf("Setting bus speed to %d Hz\n", speed); #ifdef CONFIG_DM_I2C - ret = i2c_set_bus_speed(bus, speed); + ret = dm_i2c_set_bus_speed(bus, speed); #else ret = i2c_set_bus_speed(speed); #endif diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index eafa457845..a6991bf875 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -325,7 +325,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, return ret; } -int i2c_set_bus_speed(struct udevice *bus, unsigned int speed) +int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) { struct dm_i2c_ops *ops = i2c_get_ops(bus); struct dm_i2c_bus *i2c = bus->uclass_priv; @@ -346,12 +346,7 @@ int i2c_set_bus_speed(struct udevice *bus, unsigned int speed) return 0; } -/* - * i2c_get_bus_speed: - * - * Returns speed of selected I2C bus in Hz - */ -int i2c_get_bus_speed(struct udevice *bus) +int dm_i2c_get_bus_speed(struct udevice *bus) { struct dm_i2c_ops *ops = i2c_get_ops(bus); struct dm_i2c_bus *i2c = bus->uclass_priv; @@ -440,7 +435,7 @@ static int i2c_post_probe(struct udevice *dev) i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock-frequency", 100000); - return i2c_set_bus_speed(dev, i2c->speed_hz); + return dm_i2c_set_bus_speed(dev, i2c->speed_hz); } static int i2c_post_bind(struct udevice *dev) diff --git a/include/i2c.h b/include/i2c.h index 27fe00f173..1635e9ac06 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -125,21 +125,21 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, struct udevice **devp); /** - * i2c_set_bus_speed() - set the speed of a bus + * dm_i2c_set_bus_speed() - set the speed of a bus * * @bus: Bus to adjust * @speed: Requested speed in Hz * @return 0 if OK, -EINVAL for invalid values */ -int i2c_set_bus_speed(struct udevice *bus, unsigned int speed); +int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed); /** - * i2c_get_bus_speed() - get the speed of a bus + * dm_i2c_get_bus_speed() - get the speed of a bus * * @bus: Bus to check * @return speed of selected I2C bus in Hz, -ve on error */ -int i2c_get_bus_speed(struct udevice *bus); +int dm_i2c_get_bus_speed(struct udevice *bus); /** * i2c_set_chip_flags() - set flags for a chip diff --git a/test/dm/i2c.c b/test/dm/i2c.c index ef88372d56..541b73b803 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -67,10 +67,10 @@ static int dm_test_i2c_speed(struct dm_test_state *dms) ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus)); ut_assertok(i2c_get_chip(bus, chip, 1, &dev)); - ut_assertok(i2c_set_bus_speed(bus, 100000)); + ut_assertok(dm_i2c_set_bus_speed(bus, 100000)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); - ut_assertok(i2c_set_bus_speed(bus, 400000)); - ut_asserteq(400000, i2c_get_bus_speed(bus)); + ut_assertok(dm_i2c_set_bus_speed(bus, 400000)); + ut_asserteq(400000, dm_i2c_get_bus_speed(bus)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5)); -- cgit From fffff7268b6c30dc7058d3615021628d4f60fac5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:33 -0700 Subject: dm: i2c: Make API accessible even without CONFIG_DM Make the driver model I2C API available always, even if driver model is not enabled. This allows for a 'soft' switch-over, where drivers can use the new structures in code which is compiled but not yet used. This makes migration easier in some cases. Fix up the existing drivers which define their own 'struct i2c_msg'. Signed-off-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/adi_i2c.c | 6 +++--- drivers/i2c/kona_i2c.c | 16 ++++++++-------- drivers/i2c/mv_i2c.c | 10 +++++----- include/i2c.h | 5 +---- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c index 20495b1d7f..c58f14a36e 100644 --- a/drivers/i2c/adi_i2c.c +++ b/drivers/i2c/adi_i2c.c @@ -63,7 +63,7 @@ struct twi_regs { #endif /* All transfers are described by this data structure */ -struct i2c_msg { +struct adi_i2c_msg { u8 flags; #define I2C_M_COMBO 0x4 #define I2C_M_STOP 0x2 @@ -81,7 +81,7 @@ struct i2c_msg { * wait_for_completion - manage the actual i2c transfer * @msg: the i2c msg */ -static int wait_for_completion(struct twi_regs *twi, struct i2c_msg *msg) +static int wait_for_completion(struct twi_regs *twi, struct adi_i2c_msg *msg) { u16 int_stat, ctl; ulong timebase = get_timer(0); @@ -151,7 +151,7 @@ static int i2c_transfer(struct i2c_adapter *adap, uint8_t chip, uint addr, (addr >> 8), (addr >> 16), }; - struct i2c_msg msg = { + struct adi_i2c_msg msg = { .flags = flags | (len >= 0xff ? I2C_M_STOP : 0), .buf = buffer, .len = len, diff --git a/drivers/i2c/kona_i2c.c b/drivers/i2c/kona_i2c.c index 5eab338cfc..9af496bbb1 100644 --- a/drivers/i2c/kona_i2c.c +++ b/drivers/i2c/kona_i2c.c @@ -156,7 +156,7 @@ static struct bcm_kona_i2c_dev g_i2c_devs[CONFIG_SYS_MAX_I2C_BUS] = { #define I2C_M_RD 0x0001 /* read data */ #define I2C_M_NOSTART 0x4000 /* no restart between msgs */ -struct i2c_msg { +struct kona_i2c_msg { uint16_t addr; uint16_t flags; uint16_t len; @@ -297,7 +297,7 @@ static int bcm_kona_i2c_read_fifo_single(struct bcm_kona_i2c_dev *dev, /* Read any amount of data using the RX FIFO from the i2c bus */ static int bcm_kona_i2c_read_fifo(struct bcm_kona_i2c_dev *dev, - struct i2c_msg *msg) + struct kona_i2c_msg *msg) { unsigned int bytes_to_read = MAX_RX_FIFO_SIZE; unsigned int last_byte_nak = 0; @@ -392,7 +392,7 @@ static int bcm_kona_i2c_write_fifo_single(struct bcm_kona_i2c_dev *dev, /* Write any amount of data using TX FIFO to the i2c bus */ static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev, - struct i2c_msg *msg) + struct kona_i2c_msg *msg) { unsigned int bytes_to_write = MAX_TX_FIFO_SIZE; unsigned int bytes_written = 0; @@ -418,7 +418,7 @@ static int bcm_kona_i2c_write_fifo(struct bcm_kona_i2c_dev *dev, /* Send i2c address */ static int bcm_kona_i2c_do_addr(struct bcm_kona_i2c_dev *dev, - struct i2c_msg *msg) + struct kona_i2c_msg *msg) { unsigned char addr; @@ -480,9 +480,9 @@ static void bcm_kona_i2c_config_timing(struct bcm_kona_i2c_dev *dev) /* Master transfer function */ static int bcm_kona_i2c_xfer(struct bcm_kona_i2c_dev *dev, - struct i2c_msg msgs[], int num) + struct kona_i2c_msg msgs[], int num) { - struct i2c_msg *pmsg; + struct kona_i2c_msg *pmsg; int rc = 0; int i; @@ -635,7 +635,7 @@ static int kona_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int alen, uchar *buffer, int len) { /* msg[0] writes the addr, msg[1] reads the data */ - struct i2c_msg msg[2]; + struct kona_i2c_msg msg[2]; unsigned char msgbuf0[64]; struct bcm_kona_i2c_dev *dev = kona_get_dev(adap); @@ -663,7 +663,7 @@ static int kona_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, static int kona_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, int alen, uchar *buffer, int len) { - struct i2c_msg msg[1]; + struct kona_i2c_msg msg[1]; unsigned char msgbuf0[64]; unsigned int i; struct bcm_kona_i2c_dev *dev = kona_get_dev(adap); diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c index dac346334d..e65cce0d8e 100644 --- a/drivers/i2c/mv_i2c.c +++ b/drivers/i2c/mv_i2c.c @@ -31,7 +31,7 @@ #endif /* All transfers are described by this data structure */ -struct i2c_msg { +struct mv_i2c_msg { u8 condition; u8 acknack; u8 direction; @@ -157,7 +157,7 @@ static int i2c_isr_set_cleared(unsigned long set_mask, * -5: illegal parameters * -6: bus is busy and couldn't be aquired */ -int i2c_transfer(struct i2c_msg *msg) +int i2c_transfer(struct mv_i2c_msg *msg) { int ret; @@ -286,7 +286,7 @@ void i2c_init(int speed, int slaveaddr) */ int i2c_probe(uchar chip) { - struct i2c_msg msg; + struct mv_i2c_msg msg; i2c_reset(); @@ -322,7 +322,7 @@ int i2c_probe(uchar chip) */ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { - struct i2c_msg msg; + struct mv_i2c_msg msg; u8 addr_bytes[3]; /* lowest...highest byte of data address */ PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, " @@ -410,7 +410,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) */ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { - struct i2c_msg msg; + struct mv_i2c_msg msg; u8 addr_bytes[3]; /* lowest...highest byte of data address */ PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, " diff --git a/include/i2c.h b/include/i2c.h index 1635e9ac06..31b038991e 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -25,14 +25,13 @@ * enough as to be incompatible for compilation purposes. */ -#ifdef CONFIG_DM_I2C - enum dm_i2c_chip_flags { DM_I2C_CHIP_10BIT = 1 << 0, /* Use 10-bit addressing */ DM_I2C_CHIP_RD_ADDRESS = 1 << 1, /* Send address for each read byte */ DM_I2C_CHIP_WR_ADDRESS = 1 << 2, /* Send address for each write byte */ }; +struct udevice; /** * struct dm_i2c_chip - information about an i2c chip * @@ -439,8 +438,6 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len, int i2c_chip_ofdata_to_platdata(const void *blob, int node, struct dm_i2c_chip *chip); -#endif - #ifndef CONFIG_DM_I2C /* -- cgit From 2a4eeadd56e0760b33c7ebef383c105479a93cac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:34 -0700 Subject: dm: Add Kconfig for driver/demo Add a suitable Kconfig for this directory. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/Kconfig | 2 ++ drivers/demo/Kconfig | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 drivers/demo/Kconfig diff --git a/drivers/Kconfig b/drivers/Kconfig index 128736dae3..021293e798 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -2,6 +2,8 @@ menu "Device Drivers" source "drivers/core/Kconfig" +source "drivers/demo/Kconfig" + source "drivers/pci/Kconfig" source "drivers/pcmcia/Kconfig" diff --git a/drivers/demo/Kconfig b/drivers/demo/Kconfig new file mode 100644 index 0000000000..7a8ce18555 --- /dev/null +++ b/drivers/demo/Kconfig @@ -0,0 +1,26 @@ +config DM_DEMO + bool "Enable demo uclass support" + depends on DM + help + This uclass allows you to play around with driver model. It provides + an interface to a couple of demo devices. You can access it using + the 'demo' command or by calling the uclass functions from your + own code. + +config DM_DEMO_SIMPLE + bool "Enable simple demo device for driver model" + depends on DM_DEMO + help + This device allows you to play around with driver model. It prints + a message when the 'demo hello' command is executed which targets + this device. It can be used to help understand how driver model + works. + +config DM_DEMO_SHAPE + bool "Enable shape demo device for driver model" + depends on DM_DEMO + help + This device allows you to play around with driver model. It prints + a shape when the 'demo hello' command is executed which targets + this device. It can be used to help understand how driver model + works. -- cgit From f94a1bed07e2af1c46ddcf2046cddd979ebfd994 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:35 -0700 Subject: dm: Expand and complete Kconfig in drivers/ Expand the help messages for each driver. Add missing Kconfig for I2C, SPI flash and thermal. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- doc/driver-model/spi-howto.txt | 4 ++-- drivers/Kconfig | 2 ++ drivers/core/Kconfig | 6 ++++-- drivers/gpio/Kconfig | 7 +++++-- drivers/i2c/Kconfig | 12 ++++++++++-- drivers/misc/Kconfig | 9 +++++++++ drivers/mtd/Kconfig | 2 ++ drivers/mtd/spi/Kconfig | 14 ++++++++++++++ drivers/serial/Kconfig | 6 ++++-- drivers/spi/Kconfig | 10 ++++++++-- drivers/thermal/Kconfig | 7 +++++++ 11 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 drivers/mtd/spi/Kconfig create mode 100644 drivers/thermal/Kconfig diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt index 5bc29ad65c..ee4abf4a8b 100644 --- a/doc/driver-model/spi-howto.txt +++ b/doc/driver-model/spi-howto.txt @@ -40,8 +40,8 @@ with only minor changes: Add these to your board config: -#define CONFIG_DM_SPI -#define CONFIG_DM_SPI_FLASH +CONFIG_DM_SPI +CONFIG_DM_SPI_FLASH 2. Add the skeleton diff --git a/drivers/Kconfig b/drivers/Kconfig index 021293e798..dcce532e2d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,4 +50,6 @@ source "drivers/dma/Kconfig" source "drivers/crypto/Kconfig" +source "drivers/thermal/Kconfig" + endmenu diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index d2799dc861..dc32385e85 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -2,5 +2,7 @@ config DM bool "Enable Driver Model" depends on !SPL_BUILD help - This config option enables Driver Model. - To use legacy drivers, say N. + This config option enables Driver Model. This brings in the core + support, including scanning of platform data on start-up. If + CONFIG_OF_CONTROL is enabled, the device tree will be scanned also + when available. diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d21302f8da..b609e73bba 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -2,5 +2,8 @@ config DM_GPIO bool "Enable Driver Model for GPIO drivers" depends on DM help - If you want to use driver model for GPIO drivers, say Y. - To use legacy GPIO drivers, say N. + Enable driver model for GPIO access. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 202ea5d679..2cc776c73f 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -2,8 +2,16 @@ config DM_I2C bool "Enable Driver Model for I2C drivers" depends on DM help - If you want to use driver model for I2C drivers, say Y. - To use legacy I2C drivers, say N. + Enable driver model for I2C. This SPI flash interface + (spi_flash_probe(), spi_flash_write(), etc.) is then + implemented by the SPI flash uclass. There is one standard + SPI flash driver which knows how to probe most chips + supported by U-Boot. The uclass interface is defined in + include/spi_flash.h, but is currently fully compatible + with the old interface to avoid confusion and duplication + during the transition parent. SPI and SPI flash must be + enabled together (it is not possible to use driver model + for one and not the other). config SYS_I2C_UNIPHIER bool "UniPhier I2C driver" diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index e69de29bb2..813d1c24b9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -0,0 +1,9 @@ +config DM_CROS_EC + bool "Enable Driver Model for Chrome OS EC" + depends on DM + help + Enable driver model for the Chrome OS EC interface. This + allows the cros_ec SPI driver to operate with CONFIG_DM_SPI + but otherwise makes few changes. Since cros_ec also supports + I2C and LPC (which don't support driver model yet), a full + conversion is not yet possible. diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 415ab4eba9..59278d1eef 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -1 +1,3 @@ source "drivers/mtd/nand/Kconfig" + +source "drivers/mtd/spi/Kconfig" diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig new file mode 100644 index 0000000000..2dc46b4b34 --- /dev/null +++ b/drivers/mtd/spi/Kconfig @@ -0,0 +1,14 @@ +config DM_SPI_FLASH + bool "Enable Driver Model for SPI flash" + depends on DM && SPI + help + Enable driver model for SPI flash. This SPI flash interface + (spi_flash_probe(), spi_flash_write(), etc.) is then + implemented by the SPI flash uclass. There is one standard + SPI flash driver which knows how to probe most chips + supported by U-Boot. The uclass interface is defined in + include/spi_flash.h, but is currently fully compatible + with the old interface to avoid confusion and duplication + during the transition parent. SPI and SPI flash must be + enabled together (it is not possible to use driver model + for one and not the other). diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index a0b6e02b54..c94353ba6a 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -2,8 +2,10 @@ config DM_SERIAL bool "Enable Driver Model for serial drivers" depends on DM help - If you want to use driver model for serial drivers, say Y. - To use legacy serial drivers, say N. + Enable driver model for serial. This replaces + drivers/serial/serial.c with the serial uclass, which + implements serial_putc() etc. The uclass interface is + defined in include/serial.h. config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e1678e63e6..7ae2727cf7 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -2,5 +2,11 @@ config DM_SPI bool "Enable Driver Model for SPI drivers" depends on DM help - If you want to use driver model for SPI drivers, say Y. - To use legacy SPI drivers, say N. + Enable driver model for SPI. The SPI slave interface + (spi_setup_slave(), spi_xfer(), etc.) is then implemented by + the SPI uclass. Drivers provide methods to access the SPI + buses that they control. The uclass interface is defined in + include/spi.h. The existing spi_slave structure is attached + as 'parent data' to every slave on each bus. Slaves + typically use driver-private data instead of extending the + spi_slave structure. diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig new file mode 100644 index 0000000000..3c6b36d1cf --- /dev/null +++ b/drivers/thermal/Kconfig @@ -0,0 +1,7 @@ +config DM_THERMAL + bool "Driver support for thermal devices" + help + Enable support for temporary-sensing devices. Some SoCs have on-chip + temperature sensors to permit warnings, speed throttling or even + automatic power-off when the temperature gets too high or low. Other + devices may be discrete but connected on a suitable bus. -- cgit From 91a91ff804d50d7a4b7560d10fa6863fc4c04307 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:36 -0700 Subject: dm: Add Kconfig options for driver model SPL support The SPL support cannot be enabled yet, but we can add the Kconfig options in preparation for this. Signed-off-by: Simon Glass --- drivers/core/Kconfig | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/config_defaults.h | 6 ++++++ 2 files changed, 50 insertions(+) diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index dc32385e85..f0d611007a 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -6,3 +6,47 @@ config DM support, including scanning of platform data on start-up. If CONFIG_OF_CONTROL is enabled, the device tree will be scanned also when available. + +config SPL_DM + bool "Enable Driver Model for SPL" + depends on DM && SPL + help + Enable driver model in SPL. You will need to provide a + suitable malloc() implementation. If you are not using the + full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START, + consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you + must provide CONFIG_SYS_MALLOC_F_LEN to set the size. + In most cases driver model will only allocate a few uclasses + and devices in SPL, so 1KB should be enable. See + CONFIG_SYS_MALLOC_F_LEN for more details on how to enable it. + +config DM_WARN + bool "Enable warnings in driver model" + help + The dm_warn() function can use up quite a bit of space for its + strings. By default this is disabled for SPL builds to save space. + This will cause dm_warn() to be compiled out - it will do nothing + when called. + depends on DM + default y if !SPL_BUILD + default n if SPL_BUILD + +config DM_DEVICE_REMOVE + bool "Support device removal" + help + We can save some code space by dropping support for removing a + device. This is not normally required in SPL, so by default this + option is disabled for SPL. + depends on DM + default y if !SPL_BUILD + default n if SPL_BUILD + +config DM_STDIO + bool "Support stdio registration" + help + Normally serial drivers register with stdio so that they can be used + as normal output devices. In SPL we don't normally use stdio, so + we can omit this feature. + depends on DM + default y if !SPL_BUILD + default n if SPL_BUILD diff --git a/include/config_defaults.h b/include/config_defaults.h index 4d49315044..fa99838957 100644 --- a/include/config_defaults.h +++ b/include/config_defaults.h @@ -21,9 +21,15 @@ #define CONFIG_PARTITIONS 1 #ifndef CONFIG_SPL_BUILD +#ifndef CONFIG_DM_WARN #define CONFIG_DM_WARN +#endif +#ifndef CONFIG_DM_DEVICE_REMOVE #define CONFIG_DM_DEVICE_REMOVE +#endif +#ifndef CONFIG_DM_STDIO #define CONFIG_DM_STDIO #endif +#endif #endif -- cgit From 1967982a959609d663a1c25e4473a3209671e3aa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:37 -0700 Subject: dm: test: Add a Kconfig file Add a file to control driver model test features. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- Kconfig | 2 ++ test/Kconfig | 1 + test/dm/Kconfig | 8 ++++++++ 3 files changed, 11 insertions(+) create mode 100644 test/Kconfig create mode 100644 test/dm/Kconfig diff --git a/Kconfig b/Kconfig index 09e2bbe66a..6112a7778e 100644 --- a/Kconfig +++ b/Kconfig @@ -166,3 +166,5 @@ source "drivers/Kconfig" source "fs/Kconfig" source "lib/Kconfig" + +source "test/Kconfig" diff --git a/test/Kconfig b/test/Kconfig new file mode 100644 index 0000000000..1fb1716a4a --- /dev/null +++ b/test/Kconfig @@ -0,0 +1 @@ +source "test/dm/Kconfig" diff --git a/test/dm/Kconfig b/test/dm/Kconfig new file mode 100644 index 0000000000..a9d0298e0d --- /dev/null +++ b/test/dm/Kconfig @@ -0,0 +1,8 @@ +config DM_TEST + bool "Enable driver model test command" + depends on SANDBOX && CMD_DM + help + This enables the 'dm test' command which runs a series of unit + tests on the driver model code. Each subsystem (uclass) is tested. + If all is well then all tests pass although there will be a few + messages printed along the way. -- cgit From f058f154a9cad41b8cc97ce85b9308051ff297b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:38 -0700 Subject: dm: Add CMD_DM and CMD_DEMO to Kconfig Add Kconfig settings for these two options. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- common/Kconfig | 23 +++++++++++++++++++++++ include/configs/sandbox.h | 1 - include/configs/sunxi-common.h | 1 - include/configs/ti_am335x_common.h | 1 - include/configs/uniphier.h | 2 -- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index fd84fa08bd..2ca002de27 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -153,6 +153,29 @@ endmenu menu "Device access commands" +config CMD_DM + bool "dm - Access to driver model information" + depends on DM + default y + help + Provides access to driver model data structures and information, + such as a list of devices, list of uclasses and the state of each + device (e.g. activated). This is not required for operation, but + can be useful to see the state of driver model for debugging or + interest. + +config CMD_DEMO + bool "demo - Demonstration commands for driver model" + depends on DM + help + Provides a 'demo' command which can be used to play around with + driver model. To use this properly you will need to enable one or + both of the demo devices (DM_DEMO_SHAPE and DM_DEMO_SIMPLE). + Otherwise you will always get an empty list of devices. The demo + devices are defined in the sandbox device tree, so the easiest + option is to use sandbox and pass the -d point to sandbox's + u-boot.dtb file. + config CMD_LOADB bool "loadb" help diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index e9d3f3226b..deff4d648c 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -24,7 +24,6 @@ #define CONFIG_BOOTSTAGE #define CONFIG_BOOTSTAGE_REPORT #define CONFIG_CMD_DEMO -#define CONFIG_CMD_DM #define CONFIG_DM_DEMO #define CONFIG_DM_DEMO_SIMPLE #define CONFIG_DM_DEMO_SHAPE diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index cea52dbf7b..325120da2e 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -28,7 +28,6 @@ #define CONFIG_SYS_TEXT_BASE 0x4a000000 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM) -# define CONFIG_CMD_DM # define CONFIG_DM_GPIO # define CONFIG_DM_SERIAL # define CONFIG_DW_SERIAL diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 598526bf95..35332b5ed8 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -23,7 +23,6 @@ #ifndef CONFIG_DM # define CONFIG_DM #endif -# define CONFIG_CMD_DM # define CONFIG_DM_GPIO # define CONFIG_DM_SERIAL # define CONFIG_OMAP_SERIAL diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 9420e6b48b..6f4ecc9b04 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -192,8 +192,6 @@ #define CONFIG_FAT_WRITE #define CONFIG_DOS_PARTITION -#define CONFIG_CMD_DM - /* memtest works on */ #define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x01000000) -- cgit From 34e609ca82d8846dc1fcee485e9a2ad71060f77f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:39 -0700 Subject: dm: Move Raspberry Pi driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config header and use Kconfig instead. Signed-off-by: Simon Glass --- arch/arm/Kconfig | 2 ++ arch/arm/cpu/arm1176/bcm2835/Kconfig | 12 ++++++++++++ include/configs/rpi.h | 6 ------ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 arch/arm/cpu/arm1176/bcm2835/Kconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1f1ccad10a..41f3220580 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -839,6 +839,8 @@ endchoice source "arch/arm/cpu/arm926ejs/davinci/Kconfig" +source "arch/arm/cpu/arm1176/bcm2835/Kconfig" + source "arch/arm/cpu/armv7/exynos/Kconfig" source "arch/arm/cpu/armv7/highbank/Kconfig" diff --git a/arch/arm/cpu/arm1176/bcm2835/Kconfig b/arch/arm/cpu/arm1176/bcm2835/Kconfig new file mode 100644 index 0000000000..94f57d732f --- /dev/null +++ b/arch/arm/cpu/arm1176/bcm2835/Kconfig @@ -0,0 +1,12 @@ +if TARGET_RPI + +config DM + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +endif diff --git a/include/configs/rpi.h b/include/configs/rpi.h index c94f411202..ea19ad8d07 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -30,12 +30,6 @@ */ #define CONFIG_MACH_TYPE MACH_TYPE_BCM2708 -/* Enable driver model */ -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL - /* Memory layout */ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_SDRAM_BASE 0x00000000 -- cgit From aab7e80d5fbc3aeb5feddae88c9cbb649d23345a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:40 -0700 Subject: dm: exynos: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- arch/arm/cpu/armv7/exynos/Kconfig | 15 +++++++++++++++ board/samsung/goni/Kconfig | 9 +++++++++ board/samsung/smdk5420/Kconfig | 6 ++++++ board/samsung/smdkc100/Kconfig | 9 +++++++++ include/configs/exynos-common.h | 6 ------ include/configs/peach-pi.h | 1 - include/configs/peach-pit.h | 1 - include/configs/s5p_goni.h | 4 ---- include/configs/smdkc100.h | 4 ---- 9 files changed, 39 insertions(+), 16 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index 7fcb5d2094..17ad567c19 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -65,6 +65,21 @@ endchoice config SYS_SOC default "exynos" +config DM + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + +config DM_SPI + default y if !SPL_BUILD + +config DM_SPI_FLASH + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + source "board/samsung/smdkv310/Kconfig" source "board/samsung/trats/Kconfig" source "board/samsung/universal_c210/Kconfig" diff --git a/board/samsung/goni/Kconfig b/board/samsung/goni/Kconfig index cbbf5a9315..2c5d3fc3be 100644 --- a/board/samsung/goni/Kconfig +++ b/board/samsung/goni/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "s5p_goni" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/samsung/smdk5420/Kconfig b/board/samsung/smdk5420/Kconfig index a9d62fffa5..576abaea69 100644 --- a/board/samsung/smdk5420/Kconfig +++ b/board/samsung/smdk5420/Kconfig @@ -22,6 +22,9 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "peach-pi" +config DM_CROS_EC + default y + endif if TARGET_PEACH_PIT @@ -35,6 +38,9 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "peach-pit" +config DM_CROS_EC + default y + endif if TARGET_SMDK5420 diff --git a/board/samsung/smdkc100/Kconfig b/board/samsung/smdkc100/Kconfig index d2157b4d05..996fe3cc45 100644 --- a/board/samsung/smdkc100/Kconfig +++ b/board/samsung/smdkc100/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "smdkc100" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index 1f3ee55098..2c4f35af9f 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -17,12 +17,6 @@ #include #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL -#define CONFIG_DM_SPI -#define CONFIG_DM_SPI_FLASH #define CONFIG_ARCH_CPU_INIT #define CONFIG_DISPLAY_CPUINFO diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index a1c980d320..f724164d89 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -44,7 +44,6 @@ #define CONFIG_POWER_TPS65090_EC #define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ -#define CONFIG_DM_CROS_EC #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index 6516a72764..de12a9e1b1 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -44,7 +44,6 @@ #define CONFIG_POWER_TPS65090_EC #define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ -#define CONFIG_DM_CROS_EC #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index dfa2e07948..26167a4ece 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -290,9 +290,5 @@ #define CONFIG_OF_LIBFDT #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL #endif /* __CONFIG_H */ diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index 982d0dcea3..a7eb33ed43 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -224,9 +224,5 @@ #define CONFIG_OF_LIBFDT #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL #endif /* __CONFIG_H */ -- cgit From 9a89d50d8eca3db64ecd71db2d3273a5c57bbdb1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:41 -0700 Subject: dm: x86: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- arch/x86/Kconfig | 9 +++++++++ include/configs/x86-common.h | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fef11f3552..bb3ff4393e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -67,6 +67,15 @@ config TARGET_GALILEO endchoice +config DM + default y + +config DM_GPIO + default y + +config DM_SERIAL + default y + config RAMBASE hex default 0x100000 diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 062e6c2219..277a95c199 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -22,11 +22,6 @@ #define CONFIG_DISPLAY_BOARDINFO_LATE #define CONFIG_DISPLAY_CPUINFO -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL - #define CONFIG_LMB #define CONFIG_OF_LIBFDT -- cgit From d7a4b2e42e6f782c304e2ba0d6d48c2c77ccd8bf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:42 -0700 Subject: dm: tegra: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- arch/arm/cpu/armv7/tegra-common/Kconfig | 18 ++++++++++++++++++ include/configs/tegra-common.h | 10 ---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/armv7/tegra-common/Kconfig b/arch/arm/cpu/armv7/tegra-common/Kconfig index 1446452c23..93dc7320c9 100644 --- a/arch/arm/cpu/armv7/tegra-common/Kconfig +++ b/arch/arm/cpu/armv7/tegra-common/Kconfig @@ -20,6 +20,24 @@ endchoice config USE_PRIVATE_LIBGCC default y if SPL_BUILD +config DM + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + +config DM_SPI + default y if !SPL_BUILD + +config DM_SPI_FLASH + default y if !SPL_BUILD + +config DM_I2C + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + source "arch/arm/cpu/armv7/tegra20/Kconfig" source "arch/arm/cpu/armv7/tegra30/Kconfig" source "arch/arm/cpu/armv7/tegra114/Kconfig" diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index 8f1e370915..ef25980252 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -18,16 +18,6 @@ #include /* get chip and board defs */ -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#ifndef CONFIG_SPL_BUILD -#define CONFIG_DM_SERIAL -#endif -#define CONFIG_DM_SPI -#define CONFIG_DM_SPI_FLASH -#define CONFIG_DM_I2C - #define CONFIG_SYS_TIMER_RATE 1000000 #define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE -- cgit From 001646c478429f7ee1e9a4aff667ad9ed3bc4ee4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:44 -0700 Subject: dm: omap3: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- arch/arm/cpu/armv7/omap3/Kconfig | 9 +++++++++ board/compulab/cm_t335/Kconfig | 9 +++++++++ board/gumstix/pepper/Kconfig | 9 +++++++++ board/isee/igep0033/Kconfig | 9 +++++++++ board/phytec/pcm051/Kconfig | 9 +++++++++ board/silica/pengwyn/Kconfig | 9 +++++++++ board/ti/am335x/Kconfig | 10 ++++++++++ configs/am3517_crane_defconfig | 3 +++ configs/am3517_evm_defconfig | 3 +++ configs/cm_t3517_defconfig | 3 +++ configs/cm_t35_defconfig | 3 +++ configs/devkit8000_defconfig | 3 +++ configs/dig297_defconfig | 3 +++ configs/eco5pk_defconfig | 3 +++ configs/mcx_defconfig | 3 +++ configs/mt_ventoux_defconfig | 3 +++ configs/nokia_rx51_defconfig | 3 +++ configs/omap3_beagle_defconfig | 3 +++ configs/omap3_evm_defconfig | 3 +++ configs/omap3_evm_quick_mmc_defconfig | 3 +++ configs/omap3_evm_quick_nand_defconfig | 3 +++ configs/omap3_ha_defconfig | 3 +++ configs/omap3_logic_defconfig | 3 +++ configs/omap3_mvblx_defconfig | 3 +++ configs/omap3_pandora_defconfig | 3 +++ configs/omap3_sdp3430_defconfig | 3 +++ configs/tao3530_defconfig | 3 +++ configs/tricorder_defconfig | 3 +++ configs/tricorder_flash_defconfig | 3 +++ configs/twister_defconfig | 3 +++ include/configs/nokia_rx51.h | 1 + include/configs/ti_am335x_common.h | 5 ----- include/configs/ti_omap3_common.h | 4 ---- 33 files changed, 134 insertions(+), 9 deletions(-) diff --git a/arch/arm/cpu/armv7/omap3/Kconfig b/arch/arm/cpu/armv7/omap3/Kconfig index a029379a4f..2fe323230f 100644 --- a/arch/arm/cpu/armv7/omap3/Kconfig +++ b/arch/arm/cpu/armv7/omap3/Kconfig @@ -93,6 +93,15 @@ config TARGET_TWISTER endchoice +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if DM && !SPL_BUILD + +config DM_SERIAL + default y if DM && !SPL_BUILD + config SYS_SOC default "omap3" diff --git a/board/compulab/cm_t335/Kconfig b/board/compulab/cm_t335/Kconfig index 683efde764..aadbfbc84d 100644 --- a/board/compulab/cm_t335/Kconfig +++ b/board/compulab/cm_t335/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "cm_t335" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/gumstix/pepper/Kconfig b/board/gumstix/pepper/Kconfig index 6f94612fe2..3099a9eae1 100644 --- a/board/gumstix/pepper/Kconfig +++ b/board/gumstix/pepper/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "pepper" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/isee/igep0033/Kconfig b/board/isee/igep0033/Kconfig index e989e4b15c..2fe2ef1706 100644 --- a/board/isee/igep0033/Kconfig +++ b/board/isee/igep0033/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "am335x_igep0033" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/phytec/pcm051/Kconfig b/board/phytec/pcm051/Kconfig index 2cc0d8872d..65094cf9fd 100644 --- a/board/phytec/pcm051/Kconfig +++ b/board/phytec/pcm051/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "pcm051" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/silica/pengwyn/Kconfig b/board/silica/pengwyn/Kconfig index f2e1098f62..6ecda8041c 100644 --- a/board/silica/pengwyn/Kconfig +++ b/board/silica/pengwyn/Kconfig @@ -12,4 +12,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "pengwyn" +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + endif diff --git a/board/ti/am335x/Kconfig b/board/ti/am335x/Kconfig index 1ddbb2c67c..d6581ac468 100644 --- a/board/ti/am335x/Kconfig +++ b/board/ti/am335x/Kconfig @@ -37,4 +37,14 @@ config NOR_BOOT booted via NOR. In this case we will enable certain pinmux early as the ROM only partially sets up pinmux. We also default to using NOR for environment. + +config DM + default y if !SPL_BUILD + +config DM_GPIO + default y if DM && !SPL_BUILD + +config DM_SERIAL + default y if DM && !SPL_BUILD + endif diff --git a/configs/am3517_crane_defconfig b/configs/am3517_crane_defconfig index cf9d8c7120..33b63c7e0e 100644 --- a/configs/am3517_crane_defconfig +++ b/configs/am3517_crane_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_AM3517_CRANE=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig index 2336f1ed82..7558b89e49 100644 --- a/configs/am3517_evm_defconfig +++ b/configs/am3517_evm_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_AM3517_EVM=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/cm_t3517_defconfig b/configs/cm_t3517_defconfig index 4000d2c75d..6eb37c0695 100644 --- a/configs/cm_t3517_defconfig +++ b/configs/cm_t3517_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=n +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_CM_T3517=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/cm_t35_defconfig b/configs/cm_t35_defconfig index 2bb616fb90..84a6fb0efa 100644 --- a/configs/cm_t35_defconfig +++ b/configs/cm_t35_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_CM_T35=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/devkit8000_defconfig b/configs/devkit8000_defconfig index 578ae74bba..05a8700759 100644 --- a/configs/devkit8000_defconfig +++ b/configs/devkit8000_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_DEVKIT8000=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DM_GPIO=y diff --git a/configs/dig297_defconfig b/configs/dig297_defconfig index 95bc353926..0d182900f9 100644 --- a/configs/dig297_defconfig +++ b/configs/dig297_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_DIG297=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/eco5pk_defconfig b/configs/eco5pk_defconfig index e45bdadf3f..e07df8bbd4 100644 --- a/configs/eco5pk_defconfig +++ b/configs/eco5pk_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_ECO5PK=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/mcx_defconfig b/configs/mcx_defconfig index c2031f85b7..6566d40c19 100644 --- a/configs/mcx_defconfig +++ b/configs/mcx_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_MCX=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/mt_ventoux_defconfig b/configs/mt_ventoux_defconfig index a0678bb823..a4747c6256 100644 --- a/configs/mt_ventoux_defconfig +++ b/configs/mt_ventoux_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_MT_VENTOUX=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index e03f586880..20a51e1d2f 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_NOKIA_RX51=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig index a3e4c2c6d6..5a2d20b0df 100644 --- a/configs/omap3_beagle_defconfig +++ b/configs/omap3_beagle_defconfig @@ -3,3 +3,6 @@ CONFIG_SYS_EXTRA_OPTIONS="NAND" +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_OMAP3_BEAGLE=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig index c749aa74b7..3bb191135e 100644 --- a/configs/omap3_evm_defconfig +++ b/configs/omap3_evm_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_OMAP3_EVM=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_evm_quick_mmc_defconfig b/configs/omap3_evm_quick_mmc_defconfig index e89bb82ac9..4e1471bac8 100644 --- a/configs/omap3_evm_quick_mmc_defconfig +++ b/configs/omap3_evm_quick_mmc_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_OMAP3_EVM_QUICK_MMC=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_evm_quick_nand_defconfig b/configs/omap3_evm_quick_nand_defconfig index e70fddd794..f98672f862 100644 --- a/configs/omap3_evm_quick_nand_defconfig +++ b/configs/omap3_evm_quick_nand_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_OMAP3_EVM_QUICK_NAND=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_ha_defconfig b/configs/omap3_ha_defconfig index 50bffa90a2..1a8b1b4e9e 100644 --- a/configs/omap3_ha_defconfig +++ b/configs/omap3_ha_defconfig @@ -3,3 +3,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_BOARD_OMAP3_HA" +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_TAO3530=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 5f2c063b6e..790ccbaa34 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_LOGIC=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_mvblx_defconfig b/configs/omap3_mvblx_defconfig index fb6edc252a..b75f51323e 100644 --- a/configs/omap3_mvblx_defconfig +++ b/configs/omap3_mvblx_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_MVBLX=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_pandora_defconfig b/configs/omap3_pandora_defconfig index bf285378a3..dd0f17c20c 100644 --- a/configs/omap3_pandora_defconfig +++ b/configs/omap3_pandora_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_PANDORA=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/omap3_sdp3430_defconfig b/configs/omap3_sdp3430_defconfig index 1172c2adc5..b3a8745a02 100644 --- a/configs/omap3_sdp3430_defconfig +++ b/configs/omap3_sdp3430_defconfig @@ -1,3 +1,6 @@ CONFIG_ARM=y CONFIG_OMAP34XX=y CONFIG_TARGET_OMAP3_SDP3430=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/tao3530_defconfig b/configs/tao3530_defconfig index a5113890ef..39ed872349 100644 --- a/configs/tao3530_defconfig +++ b/configs/tao3530_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_TAO3530=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/tricorder_defconfig b/configs/tricorder_defconfig index 7ea5e02f5e..3efe8290d9 100644 --- a/configs/tricorder_defconfig +++ b/configs/tricorder_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_TRICORDER=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/tricorder_flash_defconfig b/configs/tricorder_flash_defconfig index f6e1c464aa..8f999ff621 100644 --- a/configs/tricorder_flash_defconfig +++ b/configs/tricorder_flash_defconfig @@ -3,3 +3,6 @@ CONFIG_SYS_EXTRA_OPTIONS="FLASHCARD" +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_TRICORDER=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/configs/twister_defconfig b/configs/twister_defconfig index 902373601a..d21a551f95 100644 --- a/configs/twister_defconfig +++ b/configs/twister_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_OMAP34XX=y +S:CONFIG_TARGET_TWISTER=y +CONFIG_DM=n +CONFIG_DM_SERIAL=n +CONFIG_DM_GPIO=n diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h index 46fc91e5e1..6e1f501b64 100644 --- a/include/configs/nokia_rx51.h +++ b/include/configs/nokia_rx51.h @@ -72,6 +72,7 @@ #define CONFIG_UBI_SIZE (512 << 10) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + CONFIG_UBI_SIZE + \ (128 << 10)) +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* * Hardware drivers diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 35332b5ed8..4ce9d49c18 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -20,11 +20,6 @@ #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC #ifndef CONFIG_SPL_BUILD -#ifndef CONFIG_DM -# define CONFIG_DM -#endif -# define CONFIG_DM_GPIO -# define CONFIG_DM_SERIAL # define CONFIG_OMAP_SERIAL # define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h index 3c634ee680..77211de9a5 100644 --- a/include/configs/ti_omap3_common.h +++ b/include/configs/ti_omap3_common.h @@ -19,10 +19,6 @@ #include #ifndef CONFIG_SPL_BUILD -# define CONFIG_DM -# define CONFIG_CMD_DM -# define CONFIG_DM_GPIO -# define CONFIG_DM_SERIAL # define CONFIG_OMAP_SERIAL # define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif -- cgit From f4aae59fdfc161cbcd3bc628af100d305d739033 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:45 -0700 Subject: dm: sandbox: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- arch/sandbox/Kconfig | 24 ++++++++++++++++++++++++ include/configs/sandbox.h | 11 ----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig index 3057325b47..2098b9c323 100644 --- a/arch/sandbox/Kconfig +++ b/arch/sandbox/Kconfig @@ -10,4 +10,28 @@ config SYS_BOARD config SYS_CONFIG_NAME default "sandbox" +config DM + default y + +config DM_GPIO + default y + +config DM_SERIAL + default y + +config DM_CROS_EC + default y + +config DM_SPI + default y + +config DM_SPI_FLASH + default y + +config DM_I2C + default y + +config DM_TEST + default y + endmenu diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index deff4d648c..bff01708f6 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -23,14 +23,6 @@ #define CONFIG_BOOTSTAGE #define CONFIG_BOOTSTAGE_REPORT -#define CONFIG_CMD_DEMO -#define CONFIG_DM_DEMO -#define CONFIG_DM_DEMO_SIMPLE -#define CONFIG_DM_DEMO_SHAPE -#define CONFIG_DM_GPIO -#define CONFIG_DM_TEST -#define CONFIG_DM_SERIAL -#define CONFIG_DM_CROS_EC #define CONFIG_SYS_STDIO_DEREGISTER @@ -95,8 +87,6 @@ #define CONFIG_CMD_SF_TEST #define CONFIG_CMD_SPI #define CONFIG_SPI_FLASH -#define CONFIG_DM_SPI -#define CONFIG_DM_SPI_FLASH #define CONFIG_SPI_FLASH_ATMEL #define CONFIG_SPI_FLASH_EON #define CONFIG_SPI_FLASH_GIGADEVICE @@ -107,7 +97,6 @@ #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SPI_FLASH_WINBOND -#define CONFIG_DM_I2C #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C_SANDBOX #define CONFIG_I2C_EDID -- cgit From 7b051c5235d6c82cbb396e4419e8d90c7d7635e7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:46 -0700 Subject: dm: sunxi: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass Acked-by: Ian Campbell --- configs/Linksprite_pcDuino3_fdt_defconfig | 2 ++ include/configs/sunxi-common.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig index 3b6dfa6fa6..cfed375fc2 100644 --- a/configs/Linksprite_pcDuino3_fdt_defconfig +++ b/configs/Linksprite_pcDuino3_fdt_defconfig @@ -2,6 +2,8 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI" CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb" CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3" CONFIG_OF_CONTROL=y CONFIG_OF_SEPARATE=y diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 325120da2e..0c5c18cb30 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -28,8 +28,6 @@ #define CONFIG_SYS_TEXT_BASE 0x4a000000 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM) -# define CONFIG_DM_GPIO -# define CONFIG_DM_SERIAL # define CONFIG_DW_SERIAL # define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif -- cgit From 70c45aeb433d1c4c8f970927aba0cd45d701a7ae Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:47 -0700 Subject: dm: mx6: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- configs/cm_fx6_defconfig | 3 +++ include/configs/cm_fx6.h | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index 3c0d64fecb..d2ebf692f3 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -2,3 +2,6 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL,SPL" +S:CONFIG_ARM=y +S:CONFIG_TARGET_CM_FX6=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 1f64495055..4008306944 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -21,13 +21,9 @@ #define CONFIG_MACH_TYPE 4273 #ifndef CONFIG_SPL_BUILD -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO #define CONFIG_CMD_GPIO -#define CONFIG_DM_SERIAL #define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif -- cgit From 0f36f957f4108d2d1d935e3076b7ae91f4e65a7d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 5 Feb 2015 21:41:49 -0700 Subject: dm: socfpga: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- configs/socfpga_socrates_defconfig | 3 +++ include/configs/socfpga_common.h | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index 0f3896d5f0..888bbb6c6f 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -3,3 +3,6 @@ CONFIG_SPL=y +S:CONFIG_TARGET_SOCFPGA_CYCLONE5=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socrates" +CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 6b1f967c44..ee227fef0f 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -190,10 +190,6 @@ unsigned int cm_get_l4_sp_clk_hz(void); * QSPI support */ #ifdef CONFIG_OF_CONTROL /* QSPI is controlled via DT */ -#define CONFIG_CMD_DM -#define CONFIG_DM -#define CONFIG_DM_SPI -#define CONFIG_DM_SPI_FLASH #define CONFIG_CADENCE_QSPI /* Enable multiple SPI NOR flash manufacturers */ #define CONFIG_SPI_FLASH /* SPI flash subsystem */ @@ -210,9 +206,6 @@ unsigned int cm_get_qspi_controller_clk_hz(void); #endif #ifdef CONFIG_OF_CONTROL /* DW SPI is controlled via DT */ -#define CONFIG_CMD_DM -#define CONFIG_DM -#define CONFIG_DM_SPI #define CONFIG_DESIGNWARE_SPI #define CONFIG_CMD_SPI #endif -- cgit From 59088e4a762d5ea2791b6ecd39c81765ba4c4546 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 12 Feb 2015 13:48:04 +0900 Subject: dm: sh: serial: Add support driver model This adds driver model support with this driver. This was tested by Koelsch board and Gose board. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Simon Glass --- drivers/serial/serial_sh.c | 321 ++++++++++++++++++++++++----------- drivers/serial/serial_sh.h | 30 ++-- include/dm/platform_data/serial_sh.h | 37 ++++ 3 files changed, 275 insertions(+), 113 deletions(-) create mode 100644 include/dm/platform_data/serial_sh.h diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 7c1f271376..3641c9f834 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -1,78 +1,21 @@ /* * SuperH SCIF device driver. * Copyright (C) 2013 Renesas Electronics Corporation - * Copyright (C) 2007,2008,2010 Nobuhiro Iwamatsu + * Copyright (C) 2007,2008,2010, 2014 Nobuhiro Iwamatsu * Copyright (C) 2002 - 2008 Paul Mundt * * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #include #include -#include "serial_sh.h" #include #include - -#if defined(CONFIG_CONS_SCIF0) -# define SCIF_BASE SCIF0_BASE -#elif defined(CONFIG_CONS_SCIF1) -# define SCIF_BASE SCIF1_BASE -#elif defined(CONFIG_CONS_SCIF2) -# define SCIF_BASE SCIF2_BASE -#elif defined(CONFIG_CONS_SCIF3) -# define SCIF_BASE SCIF3_BASE -#elif defined(CONFIG_CONS_SCIF4) -# define SCIF_BASE SCIF4_BASE -#elif defined(CONFIG_CONS_SCIF5) -# define SCIF_BASE SCIF5_BASE -#elif defined(CONFIG_CONS_SCIF6) -# define SCIF_BASE SCIF6_BASE -#elif defined(CONFIG_CONS_SCIF7) -# define SCIF_BASE SCIF7_BASE -#else -# error "Default SCIF doesn't set....." -#endif - -#if defined(CONFIG_SCIF_A) - #define SCIF_BASE_PORT PORT_SCIFA -#else - #define SCIF_BASE_PORT PORT_SCIF -#endif - -static struct uart_port sh_sci = { - .membase = (unsigned char*)SCIF_BASE, - .mapbase = SCIF_BASE, - .type = SCIF_BASE_PORT, -}; - -static void sh_serial_setbrg(void) -{ - DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_SCIF_USE_EXT_CLK - unsigned short dl = DL_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ); - sci_out(&sh_sci, DL, dl); - /* Need wait: Clock * 1/dl $B!_(B 1/16 */ - udelay((1000000 * dl * 16 / CONFIG_SYS_CLK_FREQ) * 1000 + 1); -#else - sci_out(&sh_sci, SCBRR, - SCBRR_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ)); -#endif -} - -static int sh_serial_init(void) -{ - sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci)); - sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci)); - sci_out(&sh_sci, SCSMR, 0); - sci_out(&sh_sci, SCSMR, 0); - sci_out(&sh_sci, SCFCR, SCFCR_RFRST|SCFCR_TFRST); - sci_in(&sh_sci, SCFCR); - sci_out(&sh_sci, SCFCR, 0); - - serial_setbrg(); - return 0; -} +#include +#include "serial_sh.h" #if defined(CONFIG_CPU_SH7760) || \ defined(CONFIG_CPU_SH7780) || \ @@ -86,7 +29,7 @@ static int scif_rxfill(struct uart_port *port) static int scif_rxfill(struct uart_port *port) { if ((port->mapbase == 0xffe00000) || - (port->mapbase == 0xffe08000)) { + (port->mapbase == 0xffe08000)) { /* SCIF0/1*/ return sci_in(port, SCRFDR) & 0xff; } else { @@ -109,80 +52,253 @@ static int scif_rxfill(struct uart_port *port) } #endif -static int serial_rx_fifo_level(void) +static void sh_serial_init_generic(struct uart_port *port) { - return scif_rxfill(&sh_sci); + sci_out(port, SCSCR , SCSCR_INIT(port)); + sci_out(port, SCSCR , SCSCR_INIT(port)); + sci_out(port, SCSMR, 0); + sci_out(port, SCSMR, 0); + sci_out(port, SCFCR, SCFCR_RFRST|SCFCR_TFRST); + sci_in(port, SCFCR); + sci_out(port, SCFCR, 0); } -static void handle_error(void) +static void +sh_serial_setbrg_generic(struct uart_port *port, int clk, int baudrate) { - sci_in(&sh_sci, SCxSR); - sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci)); - sci_in(&sh_sci, SCLSR); - sci_out(&sh_sci, SCLSR, 0x00); + if (port->clk_mode == EXT_CLK) { + unsigned short dl = DL_VALUE(baudrate, clk); + sci_out(port, DL, dl); + /* Need wait: Clock * 1/dl $B!_(B 1/16 */ + udelay((1000000 * dl * 16 / clk) * 1000 + 1); + } else { + sci_out(port, SCBRR, SCBRR_VALUE(baudrate, clk)); + } } -static void serial_raw_putc(const char c) +static void handle_error(struct uart_port *port) { - while (1) { - /* Tx fifo is empty */ - if (sci_in(&sh_sci, SCxSR) & SCxSR_TEND(&sh_sci)) - break; - } + sci_in(port, SCxSR); + sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + sci_in(port, SCLSR); + sci_out(port, SCLSR, 0x00); +} + +static int serial_raw_putc(struct uart_port *port, const char c) +{ + /* Tx fifo is empty */ + if (!(sci_in(port, SCxSR) & SCxSR_TEND(port))) + return -EAGAIN; - sci_out(&sh_sci, SCxTDR, c); - sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci)); + sci_out(port, SCxTDR, c); + sci_out(port, SCxSR, sci_in(port, SCxSR) & ~SCxSR_TEND(port)); + + return 0; } -static void sh_serial_putc(const char c) +static int serial_rx_fifo_level(struct uart_port *port) { - if (c == '\n') - serial_raw_putc('\r'); - serial_raw_putc(c); + return scif_rxfill(port); } -static int sh_serial_tstc(void) +static int sh_serial_tstc_generic(struct uart_port *port) { - if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) { - handle_error(); + if (sci_in(port, SCxSR) & SCIF_ERRORS) { + handle_error(port); return 0; } - return serial_rx_fifo_level() ? 1 : 0; + return serial_rx_fifo_level(port) ? 1 : 0; } - -static int serial_getc_check(void) +static int serial_getc_check(struct uart_port *port) { unsigned short status; - status = sci_in(&sh_sci, SCxSR); + status = sci_in(port, SCxSR); if (status & SCIF_ERRORS) - handle_error(); - if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) - handle_error(); - return status & (SCIF_DR | SCxSR_RDxF(&sh_sci)); + handle_error(port); + if (sci_in(port, SCLSR) & SCxSR_ORER(port)) + handle_error(port); + return status & (SCIF_DR | SCxSR_RDxF(port)); } -static int sh_serial_getc(void) +static int sh_serial_getc_generic(struct uart_port *port) { unsigned short status; char ch; - while (!serial_getc_check()) - ; + if (!serial_getc_check(port)) + return -EAGAIN; - ch = sci_in(&sh_sci, SCxRDR); - status = sci_in(&sh_sci, SCxSR); + ch = sci_in(port, SCxRDR); + status = sci_in(port, SCxSR); - sci_out(&sh_sci, SCxSR, SCxSR_RDxF_CLEAR(&sh_sci)); + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); if (status & SCIF_ERRORS) - handle_error(); + handle_error(port); + + if (sci_in(port, SCLSR) & SCxSR_ORER(port)) + handle_error(port); + + return ch; +} + +#ifdef CONFIG_DM_SERIAL + +static int sh_serial_pending(struct udevice *dev, bool input) +{ + struct uart_port *priv = dev_get_priv(dev); + + return sh_serial_tstc_generic(priv); +} + +static int sh_serial_putc(struct udevice *dev, const char ch) +{ + struct uart_port *priv = dev_get_priv(dev); + + return serial_raw_putc(priv, ch); +} + +static int sh_serial_getc(struct udevice *dev) +{ + struct uart_port *priv = dev_get_priv(dev); + + return sh_serial_getc_generic(priv); +} + +static int sh_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct sh_serial_platdata *plat = dev_get_platdata(dev); + struct uart_port *priv = dev_get_priv(dev); + + sh_serial_setbrg_generic(priv, plat->clk, baudrate); + + return 0; +} + +static int sh_serial_probe(struct udevice *dev) +{ + struct sh_serial_platdata *plat = dev_get_platdata(dev); + struct uart_port *priv = dev_get_priv(dev); + + priv->membase = (unsigned char *)plat->base; + priv->mapbase = plat->base; + priv->type = plat->type; + priv->clk_mode = plat->clk_mode; + + sh_serial_init_generic(priv); + + return 0; +} + +static const struct dm_serial_ops sh_serial_ops = { + .putc = sh_serial_putc, + .pending = sh_serial_pending, + .getc = sh_serial_getc, + .setbrg = sh_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_sh) = { + .name = "serial_sh", + .id = UCLASS_SERIAL, + .probe = sh_serial_probe, + .ops = &sh_serial_ops, + .flags = DM_FLAG_PRE_RELOC, + .priv_auto_alloc_size = sizeof(struct uart_port), +}; + +#else /* CONFIG_DM_SERIAL */ + +#if defined(CONFIG_CONS_SCIF0) +# define SCIF_BASE SCIF0_BASE +#elif defined(CONFIG_CONS_SCIF1) +# define SCIF_BASE SCIF1_BASE +#elif defined(CONFIG_CONS_SCIF2) +# define SCIF_BASE SCIF2_BASE +#elif defined(CONFIG_CONS_SCIF3) +# define SCIF_BASE SCIF3_BASE +#elif defined(CONFIG_CONS_SCIF4) +# define SCIF_BASE SCIF4_BASE +#elif defined(CONFIG_CONS_SCIF5) +# define SCIF_BASE SCIF5_BASE +#elif defined(CONFIG_CONS_SCIF6) +# define SCIF_BASE SCIF6_BASE +#elif defined(CONFIG_CONS_SCIF7) +# define SCIF_BASE SCIF7_BASE +#else +# error "Default SCIF doesn't set....." +#endif + +#if defined(CONFIG_SCIF_A) + #define SCIF_BASE_PORT PORT_SCIFA +#else + #define SCIF_BASE_PORT PORT_SCIF +#endif + +static struct uart_port sh_sci = { + .membase = (unsigned char *)SCIF_BASE, + .mapbase = SCIF_BASE, + .type = SCIF_BASE_PORT, +#ifdef CONFIG_SCIF_USE_EXT_CLK + .clk_mode = EXT_CLK, +#endif +}; + +static void sh_serial_setbrg(void) +{ + DECLARE_GLOBAL_DATA_PTR; + struct uart_port *port = &sh_sci; + + sh_serial_setbrg_generic(port, CONFIG_SH_SCIF_CLK_FREQ, gd->baudrate); +} + +static int sh_serial_init(void) +{ + struct uart_port *port = &sh_sci; + + sh_serial_init_generic(port); + serial_setbrg(); + + return 0; +} + +static void sh_serial_putc(const char c) +{ + struct uart_port *port = &sh_sci; + + if (c == '\n') { + while (1) { + if (serial_raw_putc(port, '\r') != -EAGAIN) + break; + } + } + while (1) { + if (serial_raw_putc(port, c) != -EAGAIN) + break; + } +} + +static int sh_serial_tstc(void) +{ + struct uart_port *port = &sh_sci; + + return sh_serial_tstc_generic(port); +} + +static int sh_serial_getc(void) +{ + struct uart_port *port = &sh_sci; + int ch; + + while (1) { + ch = sh_serial_getc_generic(port); + if (ch != -EAGAIN) + break; + } - if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) - handle_error(); return ch; } @@ -206,3 +322,4 @@ __weak struct serial_device *default_serial_console(void) { return &sh_serial_drv; } +#endif /* CONFIG_DM_SERIAL */ diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h index ef88c8f273..528aa7351d 100644 --- a/drivers/serial/serial_sh.h +++ b/drivers/serial/serial_sh.h @@ -2,18 +2,16 @@ * Copy and modify from linux/drivers/serial/sh-sci.h */ +#include + struct uart_port { unsigned long iobase; /* in/out[bwl] */ unsigned char *membase; /* read/write[bwl] */ unsigned long mapbase; /* for ioremap */ - unsigned int type; /* port type */ + enum sh_serial_type type; /* port type */ + enum sh_clk_mode clk_mode; /* clock mode */ }; -#define PORT_SCI 52 -#define PORT_SCIF 53 -#define PORT_SCIFA 83 -#define PORT_SCIFB 93 - #if defined(CONFIG_H83007) || defined(CONFIG_H83068) #include #endif @@ -526,6 +524,7 @@ SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCxTDR, 0x20, 8) SCIF_FNS(SCxRDR, 0x24, 8) SCIF_FNS(SCLSR, 0x00, 0) +SCIF_FNS(DL, 0x00, 0) /* dummy */ #elif defined(CONFIG_ARCH_SH7372) || \ defined(CONFIG_R8A7740) SCIF_FNS(SCSMR, 0x00, 16) @@ -541,6 +540,7 @@ SCIF_FNS(SCRFDR, 0x3c, 16) SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) SCIF_FNS(SCLSR, 0x00, 0) +SCIF_FNS(DL, 0x00, 0) /* dummy */ #elif defined(CONFIG_CPU_SH7723) ||\ defined(CONFIG_CPU_SH7724) SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) @@ -555,6 +555,7 @@ SCIF_FNS(SCFER, 0x10, 16) SCIF_FNS(SCFCR, 0x18, 16) SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCLSR, 0x24, 16) +SCIF_FNS(DL, 0x00, 0) /* dummy */ #else /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ /* name off sz off sz off sz off sz off sz*/ @@ -583,18 +584,21 @@ SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) SCIF_FNS(SCLSR, 0, 0, 0x28, 16) #else + SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) #if defined(CONFIG_CPU_SH7722) SCIF_FNS(SCSPTR, 0, 0, 0, 0) #else SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) #endif +SCIF_FNS(SCLSR, 0, 0, 0x24, 16) +#endif #if defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794) SCIF_FNS(DL, 0, 0, 0x30, 16) SCIF_FNS(CKS, 0, 0, 0x34, 16) -#endif -SCIF_FNS(SCLSR, 0, 0, 0x24, 16) +#else +SCIF_FNS(DL, 0, 0, 0x0, 0) /* dummy */ #endif #endif #define sci_in(port, reg) sci_##reg##_in(port) @@ -725,14 +729,14 @@ static inline int sci_rxd_in(struct uart_port *port) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) #elif defined(CONFIG_CPU_SH7723) ||\ defined(CONFIG_CPU_SH7724) -static inline int scbrr_calc(struct uart_port port, int bps, int clk) +static inline int scbrr_calc(struct uart_port *port, int bps, int clk) { - if (port.type == PORT_SCIF) + if (port->type == PORT_SCIF) return (clk+16*bps)/(32*bps)-1; else return ((clk*2)+16*bps)/(16*bps)-1; } -#define SCBRR_VALUE(bps, clk) scbrr_calc(sh_sci, bps, clk) +#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) #elif defined(__H8300H__) || defined(__H8300S__) #define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1) #elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \ @@ -742,3 +746,7 @@ static inline int scbrr_calc(struct uart_port port, int bps, int clk) #else /* Generic SH */ #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) #endif + +#ifndef DL_VALUE +#define DL_VALUE(bps, clk) 0 +#endif diff --git a/include/dm/platform_data/serial_sh.h b/include/dm/platform_data/serial_sh.h new file mode 100644 index 0000000000..0271ad67b3 --- /dev/null +++ b/include/dm/platform_data/serial_sh.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Nobuhiro Iwamatsu + * Copyright (c) 2014 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __serial_sh_h +#define __serial_sh_h + +enum sh_clk_mode { + INT_CLK, + EXT_CLK, +}; + +enum sh_serial_type { + PORT_SCI, + PORT_SCIF, + PORT_SCIFA, + PORT_SCIFB, +}; + +/* + * Information about SCIF port + * + * @base: Register base address + * @clk: Input clock rate, used for calculating the baud rate divisor + * @clk_mode: Clock mode, set internal (INT) or external (EXT) + * @type: Type of SCIF + */ +struct sh_serial_platdata { + unsigned long base; + unsigned int clk; + enum sh_clk_mode clk_mode; + enum sh_serial_type type; +}; +#endif /* __serial_sh_h */ -- cgit From 757fe635df1c5fc9448db84e458482cf63f0fd21 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 11 Feb 2015 16:32:57 -0700 Subject: dm: at91: Drop use of ATMEL_PIO_PORTS in the header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With driver model the number of PIO ports is defined by platform data, so remove it from the header file. Signed-off-by: Simon Glass Acked-by: Andreas Bießmann --- arch/arm/include/asm/arch-at91/at91_pio.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/arm/include/asm/arch-at91/at91_pio.h b/arch/arm/include/asm/arch-at91/at91_pio.h index 50464ffe8e..301227880a 100644 --- a/arch/arm/include/asm/arch-at91/at91_pio.h +++ b/arch/arm/include/asm/arch-at91/at91_pio.h @@ -114,14 +114,10 @@ typedef union at91_pio { at91_port_t pioa; at91_port_t piob; at91_port_t pioc; - #if (ATMEL_PIO_PORTS > 3) - at91_port_t piod; - #endif - #if (ATMEL_PIO_PORTS > 4) - at91_port_t pioe; - #endif - } ; - at91_port_t port[ATMEL_PIO_PORTS]; + at91_port_t piod; /* not present in all hardware */ + at91_port_t pioe;/* not present in all hardware */ + }; + at91_port_t port[5]; } at91_pio_t; #ifdef CONFIG_AT91_GPIO -- cgit From ad885e45702029362575cec27e4808585c279832 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 11 Feb 2015 16:32:58 -0700 Subject: dm: at91: snapper: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- configs/snapper9260_defconfig | 3 +++ configs/snapper9g20_defconfig | 3 +++ include/configs/snapper9260.h | 4 ---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig index 7055e2a13b..035146c657 100644 --- a/configs/snapper9260_defconfig +++ b/configs/snapper9260_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260" CONFIG_ARM=y CONFIG_TARGET_SNAPPER9260=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig index 2faae15930..66c44ccf78 100644 --- a/configs/snapper9g20_defconfig +++ b/configs/snapper9g20_defconfig @@ -1,3 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20" CONFIG_ARM=y CONFIG_TARGET_SNAPPER9260=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_DM_SERIAL=y diff --git a/include/configs/snapper9260.h b/include/configs/snapper9260.h index 9fa644f7c2..712f9b74ce 100644 --- a/include/configs/snapper9260.h +++ b/include/configs/snapper9260.h @@ -21,10 +21,6 @@ #define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* External Crystal, in Hz */ #define CONFIG_SYS_AT91_SLOW_CLOCK 32768 #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_DM -#define CONFIG_CMD_DM -#define CONFIG_DM_GPIO -#define CONFIG_DM_SERIAL #define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* CPU */ -- cgit From b724bd7d63498449d3960bbd3075ba94d7152890 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 11 Feb 2015 16:32:59 -0700 Subject: dm: Kconfig: Move CONFIG_SYS_MALLOC_F_LEN to Kconfig Move this option to Kconfig and update all boards. Signed-off-by: Simon Glass --- Kconfig | 19 +++++++++++++++++++ arch/arm/cpu/armv7/exynos/Kconfig | 6 ++++++ arch/arm/cpu/armv7/omap3/Kconfig | 6 ++++++ arch/arm/cpu/armv7/tegra-common/Kconfig | 6 ++++++ arch/arm/cpu/armv7/uniphier/Kconfig | 6 ++++++ arch/x86/Kconfig | 6 ++++++ board/ti/am335x/Kconfig | 6 ++++++ configs/Linksprite_pcDuino3_fdt_defconfig | 2 ++ configs/am335x_igep0033_defconfig | 2 ++ configs/cm_fx6_defconfig | 2 ++ configs/cm_t335_defconfig | 2 ++ configs/gwventana_defconfig | 2 ++ configs/mx6dlsabreauto_defconfig | 2 ++ configs/mx6qsabreauto_defconfig | 2 ++ configs/mx6qsabresd_defconfig | 2 ++ configs/mx6sxsabresd_defconfig | 2 ++ configs/nokia_rx51_defconfig | 2 ++ configs/pcm051_rev1_defconfig | 2 ++ configs/pcm051_rev3_defconfig | 2 ++ configs/pengwyn_defconfig | 2 ++ configs/pepper_defconfig | 2 ++ configs/rpi_defconfig | 2 ++ configs/s5p_goni_defconfig | 2 ++ configs/sandbox_defconfig | 2 ++ configs/smdkc100_defconfig | 2 ++ configs/snapper9260_defconfig | 2 ++ configs/snapper9g20_defconfig | 2 ++ configs/stv0991_defconfig | 2 ++ include/configs/cm_fx6.h | 3 --- include/configs/exynos-common.h | 1 - include/configs/gw_ventana.h | 1 - include/configs/mx6sabre_common.h | 1 - include/configs/mx6sxsabresd.h | 1 - include/configs/nokia_rx51.h | 1 - include/configs/novena.h | 1 - include/configs/rpi.h | 1 - include/configs/s5p_goni.h | 1 - include/configs/sandbox.h | 1 - include/configs/smdkc100.h | 3 --- include/configs/snapper9260.h | 1 - include/configs/stv0991.h | 1 - include/configs/sunxi-common.h | 1 - include/configs/tegra-common.h | 1 - include/configs/ti_am335x_common.h | 1 - include/configs/ti_omap3_common.h | 1 - include/configs/uniphier.h | 2 -- include/configs/x86-common.h | 1 - 47 files changed, 97 insertions(+), 24 deletions(-) diff --git a/Kconfig b/Kconfig index 6112a7778e..75bab7f6cc 100644 --- a/Kconfig +++ b/Kconfig @@ -56,6 +56,25 @@ config CC_OPTIMIZE_FOR_SIZE This option is enabled by default for U-Boot. +config SYS_MALLOC_F + bool "Enable malloc() pool before relocation" + default 0x400 + help + Before relocation memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + +config SYS_MALLOC_F_LEN + hex "Size of malloc() pool before relocation" + depends on SYS_MALLOC_F + default 0x400 + help + Before relocation memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + menuconfig EXPERT bool "Configure standard U-Boot features (expert users)" help diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index 17ad567c19..2064efa761 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -80,6 +80,12 @@ config DM_SPI_FLASH config DM_GPIO default y if !SPL_BUILD +config SYS_MALLOC_F + default y if !SPL_BUILD + +config SYS_MALLOC_F_LEN + default 0x400 if !SPL_BUILD + source "board/samsung/smdkv310/Kconfig" source "board/samsung/trats/Kconfig" source "board/samsung/universal_c210/Kconfig" diff --git a/arch/arm/cpu/armv7/omap3/Kconfig b/arch/arm/cpu/armv7/omap3/Kconfig index 2fe323230f..46440981b3 100644 --- a/arch/arm/cpu/armv7/omap3/Kconfig +++ b/arch/arm/cpu/armv7/omap3/Kconfig @@ -102,6 +102,12 @@ config DM_GPIO config DM_SERIAL default y if DM && !SPL_BUILD +config SYS_MALLOC_F + default y if DM && !SPL_BUILD + +config SYS_MALLOC_F_LEN + default 0x400 if DM && !SPL_BUILD + config SYS_SOC default "omap3" diff --git a/arch/arm/cpu/armv7/tegra-common/Kconfig b/arch/arm/cpu/armv7/tegra-common/Kconfig index 93dc7320c9..ee3246929a 100644 --- a/arch/arm/cpu/armv7/tegra-common/Kconfig +++ b/arch/arm/cpu/armv7/tegra-common/Kconfig @@ -17,6 +17,12 @@ config TEGRA124 endchoice +config SYS_MALLOC_F + default y + +config SYS_MALLOC_F_LEN + default 0x1800 + config USE_PRIVATE_LIBGCC default y if SPL_BUILD diff --git a/arch/arm/cpu/armv7/uniphier/Kconfig b/arch/arm/cpu/armv7/uniphier/Kconfig index 5c5a84fe56..1a47ac9029 100644 --- a/arch/arm/cpu/armv7/uniphier/Kconfig +++ b/arch/arm/cpu/armv7/uniphier/Kconfig @@ -48,6 +48,12 @@ config DCC_MICRO_SUPPORT_CARD endchoice +config SYS_MALLOC_F + default y + +config SYS_MALLOC_F_LEN + default 0x2000 + config CMD_PINMON bool "Enable boot mode pins monitor command" default y diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bb3ff4393e..35d24e4aca 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -76,6 +76,12 @@ config DM_GPIO config DM_SERIAL default y +config SYS_MALLOC_F + default y + +config SYS_MALLOC_F_LEN + default 0x800 + config RAMBASE hex default 0x100000 diff --git a/board/ti/am335x/Kconfig b/board/ti/am335x/Kconfig index d6581ac468..a20e0c1ab9 100644 --- a/board/ti/am335x/Kconfig +++ b/board/ti/am335x/Kconfig @@ -47,4 +47,10 @@ config DM_GPIO config DM_SERIAL default y if DM && !SPL_BUILD +config SYS_MALLOC_F + default y if DM && !SPL_BUILD + +config SYS_MALLOC_F_LEN + default 0x400 if DM && !SPL_BUILD + endif diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig index cfed375fc2..1e749cded1 100644 --- a/configs/Linksprite_pcDuino3_fdt_defconfig +++ b/configs/Linksprite_pcDuino3_fdt_defconfig @@ -13,3 +13,5 @@ CONFIG_OF_SEPARATE=y +S:CONFIG_DRAM_CLK=480 +S:CONFIG_DRAM_ZQ=122 +S:CONFIG_DRAM_EMR1=4 +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/am335x_igep0033_defconfig b/configs/am335x_igep0033_defconfig index 23f0a32d63..f3544b5238 100644 --- a/configs/am335x_igep0033_defconfig +++ b/configs/am335x_igep0033_defconfig @@ -1,3 +1,5 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_TARGET_AM335X_IGEP0033=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index d2ebf692f3..631698c95d 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -5,3 +5,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL,SPL" CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/cm_t335_defconfig b/configs/cm_t335_defconfig index 5ff4f9c4a5..5c1d3cf3a5 100644 --- a/configs/cm_t335_defconfig +++ b/configs/cm_t335_defconfig @@ -1,3 +1,5 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_TARGET_CM_T335=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/gwventana_defconfig b/configs/gwventana_defconfig index 4cddbdd655..5b1a4c4e58 100644 --- a/configs/gwventana_defconfig +++ b/configs/gwventana_defconfig @@ -2,3 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL" +S:CONFIG_ARM=y +S:CONFIG_TARGET_GW_VENTANA=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/mx6dlsabreauto_defconfig b/configs/mx6dlsabreauto_defconfig index b649935912..ccdfe31992 100644 --- a/configs/mx6dlsabreauto_defconfig +++ b/configs/mx6dlsabreauto_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,MX6DL" CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/mx6qsabreauto_defconfig b/configs/mx6qsabreauto_defconfig index 7d86700b30..fe3d797851 100644 --- a/configs/mx6qsabreauto_defconfig +++ b/configs/mx6qsabreauto_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/imximage.cfg,MX6Q" CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/mx6qsabresd_defconfig b/configs/mx6qsabresd_defconfig index 67c1b77e05..09b01905e6 100644 --- a/configs/mx6qsabresd_defconfig +++ b/configs/mx6qsabresd_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,MX6Q" CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index f23d48f361..72e0f103ec 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg,MX6SX" CONFIG_ARM=y CONFIG_TARGET_MX6SXSABRESD=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index 20a51e1d2f..1bb7664ed7 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -4,3 +4,5 @@ CONFIG_TARGET_NOKIA_RX51=y CONFIG_DM=n CONFIG_DM_SERIAL=n CONFIG_DM_GPIO=n +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/pcm051_rev1_defconfig b/configs/pcm051_rev1_defconfig index 8b27682997..baa2b231b0 100644 --- a/configs/pcm051_rev1_defconfig +++ b/configs/pcm051_rev1_defconfig @@ -2,3 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="REV1" +S:CONFIG_ARM=y +S:CONFIG_TARGET_PCM051=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/pcm051_rev3_defconfig b/configs/pcm051_rev3_defconfig index 27ad6ff26b..b5c62a6a3b 100644 --- a/configs/pcm051_rev3_defconfig +++ b/configs/pcm051_rev3_defconfig @@ -2,3 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="REV3" +S:CONFIG_ARM=y +S:CONFIG_TARGET_PCM051=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/pengwyn_defconfig b/configs/pengwyn_defconfig index 1b9aa68260..cbdd404c70 100644 --- a/configs/pengwyn_defconfig +++ b/configs/pengwyn_defconfig @@ -1,3 +1,5 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_TARGET_PENGWYN=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/pepper_defconfig b/configs/pepper_defconfig index 22c7bb4a60..14266ef875 100644 --- a/configs/pepper_defconfig +++ b/configs/pepper_defconfig @@ -1,3 +1,5 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_TARGET_PEPPER=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig index 9379cf00d4..98d3199ccd 100644 --- a/configs/rpi_defconfig +++ b/configs/rpi_defconfig @@ -1,2 +1,4 @@ CONFIG_ARM=y CONFIG_TARGET_RPI=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/s5p_goni_defconfig b/configs/s5p_goni_defconfig index 618e590802..33e6fb8848 100644 --- a/configs/s5p_goni_defconfig +++ b/configs/s5p_goni_defconfig @@ -2,3 +2,5 @@ CONFIG_ARM=y CONFIG_ARCH_S5PC1XX=y CONFIG_TARGET_S5P_GONI=y CONFIG_DEFAULT_DEVICE_TREE="s5pc1xx-goni" +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 660063ebf3..0bf5ea34d0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -5,3 +5,5 @@ CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/smdkc100_defconfig b/configs/smdkc100_defconfig index 041030f942..e933a329b6 100644 --- a/configs/smdkc100_defconfig +++ b/configs/smdkc100_defconfig @@ -2,3 +2,5 @@ CONFIG_ARM=y CONFIG_TARGET_SMDKC100=y CONFIG_ARCH_S5PC1XX=y CONFIG_DEFAULT_DEVICE_TREE="s5pc1xx-smdkc100" +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig index 035146c657..97c49f3363 100644 --- a/configs/snapper9260_defconfig +++ b/configs/snapper9260_defconfig @@ -4,3 +4,5 @@ CONFIG_TARGET_SNAPPER9260=y CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig index 66c44ccf78..d5f1d9fa19 100644 --- a/configs/snapper9g20_defconfig +++ b/configs/snapper9g20_defconfig @@ -4,3 +4,5 @@ CONFIG_TARGET_SNAPPER9260=y CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig index a05e9917b6..37b10ba893 100644 --- a/configs/stv0991_defconfig +++ b/configs/stv0991_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="stv0991" CONFIG_ARM=y CONFIG_TARGET_STV0991=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index 4008306944..4207504464 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -21,10 +21,7 @@ #define CONFIG_MACH_TYPE 4273 #ifndef CONFIG_SPL_BUILD - #define CONFIG_CMD_GPIO - -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif /* Display information on boot */ diff --git a/include/configs/exynos-common.h b/include/configs/exynos-common.h index 2c4f35af9f..59676ae61b 100644 --- a/include/configs/exynos-common.h +++ b/include/configs/exynos-common.h @@ -36,7 +36,6 @@ #define CONFIG_ENV_OVERWRITE /* Size of malloc() pool before and after relocation */ -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 << 20)) /* select serial console configuration */ diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index 4f137fc96b..620f9501d2 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -39,7 +39,6 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024) -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* Init Functions */ #define CONFIG_BOARD_EARLY_INIT_F diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h index f0f721e9b7..80e48d141e 100644 --- a/include/configs/mx6sabre_common.h +++ b/include/configs/mx6sabre_common.h @@ -27,7 +27,6 @@ #define CONFIG_DM #define CONFIG_DM_THERMAL -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_IMX6_THERMAL #define CONFIG_SYS_GENERIC_BOARD diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 404b922d39..1005b9e6bc 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -229,7 +229,6 @@ #define CONFIG_DM #define CONFIG_DM_THERMAL -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_IMX6_THERMAL #define CONFIG_CMD_FUSE diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h index 6e1f501b64..46fc91e5e1 100644 --- a/include/configs/nokia_rx51.h +++ b/include/configs/nokia_rx51.h @@ -72,7 +72,6 @@ #define CONFIG_UBI_SIZE (512 << 10) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + CONFIG_UBI_SIZE + \ (128 << 10)) -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* * Hardware drivers diff --git a/include/configs/novena.h b/include/configs/novena.h index ea75d2c2b9..074110c939 100644 --- a/include/configs/novena.h +++ b/include/configs/novena.h @@ -116,7 +116,6 @@ #define CONFIG_SYS_MEMTEST_END 0x20000000 #define CONFIG_SYS_MALLOC_LEN (64 * 1024 * 1024) -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* SPL */ #define CONFIG_SPL_FAT_SUPPORT diff --git a/include/configs/rpi.h b/include/configs/rpi.h index ea19ad8d07..7ad8d08021 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -46,7 +46,6 @@ CONFIG_SYS_SDRAM_SIZE - \ GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_MALLOC_LEN SZ_4M -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_SYS_MEMTEST_START 0x00100000 #define CONFIG_SYS_MEMTEST_END 0x00200000 #define CONFIG_LOADADDR 0x00200000 diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h index 26167a4ece..8fadc68239 100644 --- a/include/configs/s5p_goni.h +++ b/include/configs/s5p_goni.h @@ -40,7 +40,6 @@ #define CONFIG_CMDLINE_EDITING /* Size of malloc() pool before and after relocation */ -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 << 20)) /* diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index bff01708f6..5c116508d0 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -60,7 +60,6 @@ /* * Size of malloc() pool, before and after relocation */ -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_MALLOC_F_ADDR 0x0010000 #define CONFIG_SYS_MALLOC_LEN (32 << 20) /* 32MB */ diff --git a/include/configs/smdkc100.h b/include/configs/smdkc100.h index a7eb33ed43..080fc3a845 100644 --- a/include/configs/smdkc100.h +++ b/include/configs/smdkc100.h @@ -48,9 +48,6 @@ */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) -/* Small malloc pool before relocation */ -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) - /* * select serial console configuration */ diff --git a/include/configs/snapper9260.h b/include/configs/snapper9260.h index 712f9b74ce..6c685965a2 100644 --- a/include/configs/snapper9260.h +++ b/include/configs/snapper9260.h @@ -21,7 +21,6 @@ #define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* External Crystal, in Hz */ #define CONFIG_SYS_AT91_SLOW_CLOCK 32768 #define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) /* CPU */ #define CONFIG_ARCH_CPU_INIT diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h index fd9bd638c6..071b1c2ca7 100644 --- a/include/configs/stv0991.h +++ b/include/configs/stv0991.h @@ -28,7 +28,6 @@ (PHYS_SDRAM_1_SIZE - CONFIG_ENV_SIZE) #define CONFIG_SYS_MAXARGS 16 #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 16 * 1024) -#define CONFIG_SYS_MALLOC_F_LEN 0x2000 #define CONFIG_DM /* serial port (PL011) configuration */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 0c5c18cb30..09889eeb44 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -29,7 +29,6 @@ #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DM) # define CONFIG_DW_SERIAL -# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif /* diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index ef25980252..005fc6aeb3 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -37,7 +37,6 @@ * Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (4 << 20) /* 4MB */ -#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_SYS_NONCACHED_MEMORY (1 << 20) /* 1 MiB */ diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h index 4ce9d49c18..20a55f4aa8 100644 --- a/include/configs/ti_am335x_common.h +++ b/include/configs/ti_am335x_common.h @@ -21,7 +21,6 @@ #ifndef CONFIG_SPL_BUILD # define CONFIG_OMAP_SERIAL -# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif #include diff --git a/include/configs/ti_omap3_common.h b/include/configs/ti_omap3_common.h index 77211de9a5..840e108e05 100644 --- a/include/configs/ti_omap3_common.h +++ b/include/configs/ti_omap3_common.h @@ -20,7 +20,6 @@ #ifndef CONFIG_SPL_BUILD # define CONFIG_OMAP_SERIAL -# define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #endif /* The chip has SDRC controller */ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 6f4ecc9b04..3f738fb642 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -80,8 +80,6 @@ #define CONFIG_SMC911X_BASE CONFIG_SUPPORT_CARD_ETHER_BASE #define CONFIG_SMC911X_32_BIT -#define CONFIG_SYS_MALLOC_F_LEN 0x2000 - /*----------------------------------------------------------------------- * MMU and Cache Setting *----------------------------------------------------------------------*/ diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 277a95c199..994874ca60 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -187,7 +187,6 @@ #define CONFIG_SYS_STACK_SIZE (32 * 1024) #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MALLOC_LEN 0x200000 -#define CONFIG_SYS_MALLOC_F_LEN (2 << 10) /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE -- cgit From be9891c52d5472156949a3137be5f48355fd3f29 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 11 Feb 2015 16:33:00 -0700 Subject: dm: Drop unused driver model config_defaults These are now in Kconfig so we can drop them from the header file. Signed-off-by: Simon Glass --- include/config_defaults.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/config_defaults.h b/include/config_defaults.h index fa99838957..ad08c1d335 100644 --- a/include/config_defaults.h +++ b/include/config_defaults.h @@ -20,16 +20,4 @@ #define CONFIG_ZLIB 1 #define CONFIG_PARTITIONS 1 -#ifndef CONFIG_SPL_BUILD -#ifndef CONFIG_DM_WARN -#define CONFIG_DM_WARN -#endif -#ifndef CONFIG_DM_DEVICE_REMOVE -#define CONFIG_DM_DEVICE_REMOVE -#endif -#ifndef CONFIG_DM_STDIO -#define CONFIG_DM_STDIO -#endif -#endif - #endif -- cgit From c9cac3f8413c1f67d1e1b7a1770e584584107cd2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2015 14:46:32 +0800 Subject: dm: introduce dev_get_addr interface Abstracting dev_get_addr can improve drivers that want to get device's address. Signed-off-by: Peng Fan Acked-by: Igor Grinberg Acked-by: Simon Glass --- drivers/core/device.c | 12 ++++++++++++ include/dm/device.h | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/core/device.c b/drivers/core/device.c index b73d3b8961..73c3e07c28 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -449,3 +449,15 @@ enum uclass_id device_get_uclass_id(struct udevice *dev) { return dev->uclass->uc_drv->id; } + +#ifdef CONFIG_OF_CONTROL +fdt_addr_t dev_get_addr(struct udevice *dev) +{ + return fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); +} +#else +fdt_addr_t dev_get_addr(struct udevice *dev) +{ + return FDT_ADDR_T_NONE; +} +#endif diff --git a/include/dm/device.h b/include/dm/device.h index 81afa8c628..7a48eb88b8 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -12,6 +12,7 @@ #define _DM_DEVICE_H #include +#include #include #include @@ -351,4 +352,13 @@ int device_find_first_child(struct udevice *parent, struct udevice **devp); */ int device_find_next_child(struct udevice **devp); +/** + * dev_get_addr() - Get the reg property of a device + * + * @dev: Pointer to a device + * + * @return addr + */ +fdt_addr_t dev_get_addr(struct udevice *dev); + #endif -- cgit From 637a7693185d00c392df8a9886cb17f462e9a51b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2015 14:46:33 +0800 Subject: dm:gpio:mxc add a bank_index entry in platdata Add a new entry in platdata structure and intialize bank_index in mxc_plat array. This new entry can avoid using `plat - mxc_plat` by using `plat->bank_index`. Signed-off-by: Peng Fan Acked-by: Igor Grinberg Acked-by: Simon Glass --- drivers/gpio/mxc_gpio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 8bb9e39b72..c52dd19ce3 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -23,6 +23,7 @@ enum mxc_gpio_direction { #define GPIO_PER_BANK 32 struct mxc_gpio_plat { + int bank_index; struct gpio_regs *regs; }; @@ -259,19 +260,19 @@ static const struct dm_gpio_ops gpio_mxc_ops = { }; static const struct mxc_gpio_plat mxc_plat[] = { - { (struct gpio_regs *)GPIO1_BASE_ADDR }, - { (struct gpio_regs *)GPIO2_BASE_ADDR }, - { (struct gpio_regs *)GPIO3_BASE_ADDR }, + { 0, (struct gpio_regs *)GPIO1_BASE_ADDR }, + { 1, (struct gpio_regs *)GPIO2_BASE_ADDR }, + { 2, (struct gpio_regs *)GPIO3_BASE_ADDR }, #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \ defined(CONFIG_MX53) || defined(CONFIG_MX6) - { (struct gpio_regs *)GPIO4_BASE_ADDR }, + { 3, (struct gpio_regs *)GPIO4_BASE_ADDR }, #endif #if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) - { (struct gpio_regs *)GPIO5_BASE_ADDR }, - { (struct gpio_regs *)GPIO6_BASE_ADDR }, + { 4, (struct gpio_regs *)GPIO5_BASE_ADDR }, + { 5, (struct gpio_regs *)GPIO6_BASE_ADDR }, #endif #if defined(CONFIG_MX53) || defined(CONFIG_MX6) - { (struct gpio_regs *)GPIO7_BASE_ADDR }, + { 6, (struct gpio_regs *)GPIO7_BASE_ADDR }, #endif }; @@ -283,7 +284,7 @@ static int mxc_gpio_probe(struct udevice *dev) int banknum; char name[18], *str; - banknum = plat - mxc_plat; + banknum = plat->bank_index; sprintf(name, "GPIO%d_", banknum + 1); str = strdup(name); if (!str) -- cgit From 99c0ae16d8b2ebfb7381ba77d4e37e7bda734402 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 10 Feb 2015 14:46:34 +0800 Subject: dm:gpio:mxc add DT support This patch add DT support for mxc gpio driver. There are one place using CONFIG_OF_CONTROL macro. 1. The U_BOOT_DEVICES and mxc_plat array are complied out. To DT, platdata is alloced using calloc, so there is no need to use mxc_plat. The following situations are tested, and all work fine: 1. with DM, without DT 2. with DM and DT 3. without DM Since device tree has not been upstreamed, if want to test this patch. The followings need to be done. + pieces of code does not gpio_request when using gpio_direction_xxx and etc, need to request gpio. + move the gpio settings from board_early_init_f to board_init + define CONFIG_DM ,CONFIG_DM_GPIO and CONFIG_OF_CONTROL + Add device tree file and do related configuration in `make ARCH=arm menuconfig` These will be done in future patches by step. Signed-off-by: Peng Fan Acked-by: Igor Grinberg Acked-by: Simon Glass --- drivers/gpio/mxc_gpio.c | 81 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index c52dd19ce3..815407bb03 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -151,6 +151,9 @@ int gpio_direction_output(unsigned gpio, int value) #endif #ifdef CONFIG_DM_GPIO +#include +DECLARE_GLOBAL_DATA_PTR; + static int mxc_gpio_is_output(struct gpio_regs *regs, int offset) { u32 val; @@ -259,23 +262,6 @@ static const struct dm_gpio_ops gpio_mxc_ops = { .get_function = mxc_gpio_get_function, }; -static const struct mxc_gpio_plat mxc_plat[] = { - { 0, (struct gpio_regs *)GPIO1_BASE_ADDR }, - { 1, (struct gpio_regs *)GPIO2_BASE_ADDR }, - { 2, (struct gpio_regs *)GPIO3_BASE_ADDR }, -#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \ - defined(CONFIG_MX53) || defined(CONFIG_MX6) - { 3, (struct gpio_regs *)GPIO4_BASE_ADDR }, -#endif -#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) - { 4, (struct gpio_regs *)GPIO5_BASE_ADDR }, - { 5, (struct gpio_regs *)GPIO6_BASE_ADDR }, -#endif -#if defined(CONFIG_MX53) || defined(CONFIG_MX6) - { 6, (struct gpio_regs *)GPIO7_BASE_ADDR }, -#endif -}; - static int mxc_gpio_probe(struct udevice *dev) { struct mxc_bank_info *bank = dev_get_priv(dev); @@ -296,12 +282,72 @@ static int mxc_gpio_probe(struct udevice *dev) return 0; } +static int mxc_gpio_bind(struct udevice *dev) +{ + struct mxc_gpio_plat *plat = dev->platdata; + fdt_addr_t addr; + + /* + * If platdata already exsits, directly return. + * Actually only when DT is not supported, platdata + * is statically initialized in U_BOOT_DEVICES.Here + * will return. + */ + if (plat) + return 0; + + addr = dev_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -ENODEV; + + /* + * TODO: + * When every board is converted to driver model and DT is supported, + * this can be done by auto-alloc feature, but not using calloc + * to alloc memory for platdata. + */ + plat = calloc(1, sizeof(*plat)); + if (!plat) + return -ENOMEM; + + plat->regs = (struct gpio_regs *)addr; + plat->bank_index = dev->req_seq; + dev->platdata = plat; + + return 0; +} + +static const struct udevice_id mxc_gpio_ids[] = { + { .compatible = "fsl,imx35-gpio" }, + { } +}; + U_BOOT_DRIVER(gpio_mxc) = { .name = "gpio_mxc", .id = UCLASS_GPIO, .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, .priv_auto_alloc_size = sizeof(struct mxc_bank_info), + .of_match = mxc_gpio_ids, + .bind = mxc_gpio_bind, +}; + +#ifndef CONFIG_OF_CONTROL +static const struct mxc_gpio_plat mxc_plat[] = { + { 0, (struct gpio_regs *)GPIO1_BASE_ADDR }, + { 1, (struct gpio_regs *)GPIO2_BASE_ADDR }, + { 2, (struct gpio_regs *)GPIO3_BASE_ADDR }, +#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \ + defined(CONFIG_MX53) || defined(CONFIG_MX6) + { 3, (struct gpio_regs *)GPIO4_BASE_ADDR }, +#endif +#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) + { 4, (struct gpio_regs *)GPIO5_BASE_ADDR }, + { 5, (struct gpio_regs *)GPIO6_BASE_ADDR }, +#endif +#if defined(CONFIG_MX53) || defined(CONFIG_MX6) + { 6, (struct gpio_regs *)GPIO7_BASE_ADDR }, +#endif }; U_BOOT_DEVICES(mxc_gpios) = { @@ -321,3 +367,4 @@ U_BOOT_DEVICES(mxc_gpios) = { #endif }; #endif +#endif -- cgit From 484fdf5ba058b07be5ca82763aa2b72063540ef3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 2 Feb 2015 16:31:59 +0100 Subject: dm: Add support for all targets which requires MANUAL_RELOC Targets with CONFIG_NEEDS_MANUAL_RELOC do not use REL/RELA relocation (mostly only GOT) where functions aray are not updated. This patch is fixing function pointers for DM core and serial-uclass to ensure that relocated functions are called. Signed-off-by: Michal Simek Acked-by: Simon Glass --- drivers/core/root.c | 64 ++++++++++++++++++++++++++++++++++++++++++ drivers/serial/serial-uclass.c | 16 +++++++++++ 2 files changed, 80 insertions(+) diff --git a/drivers/core/root.c b/drivers/core/root.c index 73e3c7228e..9b5c6bb10c 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -37,6 +37,65 @@ struct udevice *dm_root(void) return gd->dm_root; } +#if defined(CONFIG_NEEDS_MANUAL_RELOC) +void fix_drivers(void) +{ + struct driver *drv = + ll_entry_start(struct driver, driver); + const int n_ents = ll_entry_count(struct driver, driver); + struct driver *entry; + + for (entry = drv; entry != drv + n_ents; entry++) { + if (entry->of_match) + entry->of_match = (const struct udevice_id *) + ((u32)entry->of_match + gd->reloc_off); + if (entry->bind) + entry->bind += gd->reloc_off; + if (entry->probe) + entry->probe += gd->reloc_off; + if (entry->remove) + entry->remove += gd->reloc_off; + if (entry->unbind) + entry->unbind += gd->reloc_off; + if (entry->ofdata_to_platdata) + entry->ofdata_to_platdata += gd->reloc_off; + if (entry->child_pre_probe) + entry->child_pre_probe += gd->reloc_off; + if (entry->child_post_remove) + entry->child_post_remove += gd->reloc_off; + /* OPS are fixed in every uclass post_probe function */ + if (entry->ops) + entry->ops += gd->reloc_off; + } +} + +void fix_uclass(void) +{ + struct uclass_driver *uclass = + ll_entry_start(struct uclass_driver, uclass); + const int n_ents = ll_entry_count(struct uclass_driver, uclass); + struct uclass_driver *entry; + + for (entry = uclass; entry != uclass + n_ents; entry++) { + if (entry->post_bind) + entry->post_bind += gd->reloc_off; + if (entry->pre_unbind) + entry->pre_unbind += gd->reloc_off; + if (entry->post_probe) + entry->post_probe += gd->reloc_off; + if (entry->pre_remove) + entry->pre_remove += gd->reloc_off; + if (entry->init) + entry->init += gd->reloc_off; + if (entry->destroy) + entry->destroy += gd->reloc_off; + /* FIXME maybe also need to fix these ops */ + if (entry->ops) + entry->ops += gd->reloc_off; + } +} +#endif + int dm_init(void) { int ret; @@ -47,6 +106,11 @@ int dm_init(void) } INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + fix_drivers(); + fix_uclass(); +#endif + ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); if (ret) return ret; diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 9131a8f93d..3fc7104359 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -258,6 +258,22 @@ static int serial_post_probe(struct udevice *dev) #endif int ret; +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + if (ops->setbrg) + ops->setbrg += gd->reloc_off; + if (ops->getc) + ops->getc += gd->reloc_off; + if (ops->putc) + ops->putc += gd->reloc_off; + if (ops->pending) + ops->pending += gd->reloc_off; + if (ops->clear) + ops->clear += gd->reloc_off; +#if CONFIG_POST & CONFIG_SYS_POST_UART + if (ops->loop) + ops->loop += gd->reloc_off +#endif +#endif /* Set the baud rate */ if (ops->setbrg) { ret = ops->setbrg(dev, gd->baudrate); -- cgit From 3b7f0e109cd3f3fba387784f3f6debd4127cdefd Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Mon, 12 Jan 2015 19:17:07 +0300 Subject: arm: rmobile: Add SILK board support SILK is an entry level development board based on R-Car E2 SoC (R8A7794) This commit supports the following peripherals: - SCIF, I2C, Ethernet, QSPI, MMC, USB Host Signed-off-by: Vladimir Barinov Reviewed-by: Tom Rini Signed-off-by: Nobuhiro Iwamatsu --- arch/arm/cpu/armv7/rmobile/Kconfig | 6 +- board/renesas/silk/Kconfig | 12 + board/renesas/silk/MAINTAINERS | 6 + board/renesas/silk/Makefile | 10 + board/renesas/silk/qos.c | 951 +++++++++++++++++++++++++++++++++++++ board/renesas/silk/silk.c | 175 +++++++ configs/silk_defconfig | 3 + include/configs/silk.h | 117 +++++ 8 files changed, 1279 insertions(+), 1 deletion(-) create mode 100644 board/renesas/silk/Kconfig create mode 100644 board/renesas/silk/MAINTAINERS create mode 100644 board/renesas/silk/Makefile create mode 100644 board/renesas/silk/qos.c create mode 100644 board/renesas/silk/silk.c create mode 100644 configs/silk_defconfig create mode 100644 include/configs/silk.h diff --git a/arch/arm/cpu/armv7/rmobile/Kconfig b/arch/arm/cpu/armv7/rmobile/Kconfig index 6d94199de8..35866508a3 100644 --- a/arch/arm/cpu/armv7/rmobile/Kconfig +++ b/arch/arm/cpu/armv7/rmobile/Kconfig @@ -21,6 +21,9 @@ config TARGET_KZM9G config TARGET_ALT bool "Alt board" +config TARGET_SILK + bool "Silk board" + endchoice config SYS_SOC @@ -28,7 +31,7 @@ config SYS_SOC config RMOBILE_EXTRAM_BOOT bool "Enable boot from RAM" - depends on TARGET_ALT || TARGET_KOELSCH || TARGET_LAGER + depends on TARGET_ALT || TARGET_KOELSCH || TARGET_LAGER || TARGET_SILK default n source "board/atmark-techno/armadillo-800eva/Kconfig" @@ -37,5 +40,6 @@ source "board/renesas/koelsch/Kconfig" source "board/renesas/lager/Kconfig" source "board/kmc/kzm9g/Kconfig" source "board/renesas/alt/Kconfig" +source "board/renesas/silk/Kconfig" endif diff --git a/board/renesas/silk/Kconfig b/board/renesas/silk/Kconfig new file mode 100644 index 0000000000..07aee0e50f --- /dev/null +++ b/board/renesas/silk/Kconfig @@ -0,0 +1,12 @@ +if TARGET_SILK + +config SYS_BOARD + default "silk" + +config SYS_VENDOR + default "renesas" + +config SYS_CONFIG_NAME + default "silk" + +endif diff --git a/board/renesas/silk/MAINTAINERS b/board/renesas/silk/MAINTAINERS new file mode 100644 index 0000000000..b566ccfbd9 --- /dev/null +++ b/board/renesas/silk/MAINTAINERS @@ -0,0 +1,6 @@ +SILK BOARD +M: Cogent Embedded, Inc. +S: Maintained +F: board/renesas/silk/ +F: include/configs/silk.h +F: configs/silk_defconfig diff --git a/board/renesas/silk/Makefile b/board/renesas/silk/Makefile new file mode 100644 index 0000000000..e6eea6142e --- /dev/null +++ b/board/renesas/silk/Makefile @@ -0,0 +1,10 @@ +# +# board/renesas/silk/Makefile +# +# Copyright (C) 2015 Renesas Electronics Corporation +# Copyright (C) 2015 Cogent Embedded, Inc. +# +# SPDX-License-Identifier: GPL-2.0 +# + +obj-y := silk.o qos.o ../rcar-gen2-common/common.o diff --git a/board/renesas/silk/qos.c b/board/renesas/silk/qos.c new file mode 100644 index 0000000000..4f6e46ce52 --- /dev/null +++ b/board/renesas/silk/qos.c @@ -0,0 +1,951 @@ +/* + * board/renesas/silk/qos.c + * + * Copyright (C) 2015 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + * + */ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_RMOBILE_EXTRAM_BOOT) +/* QoS version 0.11 */ + +enum { + DBSC3_00, DBSC3_01, DBSC3_02, DBSC3_03, DBSC3_04, + DBSC3_05, DBSC3_06, DBSC3_07, DBSC3_08, DBSC3_09, + DBSC3_10, DBSC3_11, DBSC3_12, DBSC3_13, DBSC3_14, + DBSC3_15, + DBSC3_NR, +}; + +static u32 dbsc3_0_r_qos_addr[DBSC3_NR] = { + [DBSC3_00] = DBSC3_0_QOS_R0_BASE, + [DBSC3_01] = DBSC3_0_QOS_R1_BASE, + [DBSC3_02] = DBSC3_0_QOS_R2_BASE, + [DBSC3_03] = DBSC3_0_QOS_R3_BASE, + [DBSC3_04] = DBSC3_0_QOS_R4_BASE, + [DBSC3_05] = DBSC3_0_QOS_R5_BASE, + [DBSC3_06] = DBSC3_0_QOS_R6_BASE, + [DBSC3_07] = DBSC3_0_QOS_R7_BASE, + [DBSC3_08] = DBSC3_0_QOS_R8_BASE, + [DBSC3_09] = DBSC3_0_QOS_R9_BASE, + [DBSC3_10] = DBSC3_0_QOS_R10_BASE, + [DBSC3_11] = DBSC3_0_QOS_R11_BASE, + [DBSC3_12] = DBSC3_0_QOS_R12_BASE, + [DBSC3_13] = DBSC3_0_QOS_R13_BASE, + [DBSC3_14] = DBSC3_0_QOS_R14_BASE, + [DBSC3_15] = DBSC3_0_QOS_R15_BASE, +}; + +static u32 dbsc3_0_w_qos_addr[DBSC3_NR] = { + [DBSC3_00] = DBSC3_0_QOS_W0_BASE, + [DBSC3_01] = DBSC3_0_QOS_W1_BASE, + [DBSC3_02] = DBSC3_0_QOS_W2_BASE, + [DBSC3_03] = DBSC3_0_QOS_W3_BASE, + [DBSC3_04] = DBSC3_0_QOS_W4_BASE, + [DBSC3_05] = DBSC3_0_QOS_W5_BASE, + [DBSC3_06] = DBSC3_0_QOS_W6_BASE, + [DBSC3_07] = DBSC3_0_QOS_W7_BASE, + [DBSC3_08] = DBSC3_0_QOS_W8_BASE, + [DBSC3_09] = DBSC3_0_QOS_W9_BASE, + [DBSC3_10] = DBSC3_0_QOS_W10_BASE, + [DBSC3_11] = DBSC3_0_QOS_W11_BASE, + [DBSC3_12] = DBSC3_0_QOS_W12_BASE, + [DBSC3_13] = DBSC3_0_QOS_W13_BASE, + [DBSC3_14] = DBSC3_0_QOS_W14_BASE, + [DBSC3_15] = DBSC3_0_QOS_W15_BASE, +}; + +void qos_init(void) +{ + int i; + struct rcar_s3c *s3c; + struct rcar_s3c_qos *s3c_qos; + struct rcar_dbsc3_qos *qos_addr; + struct rcar_mxi *mxi; + struct rcar_mxi_qos *mxi_qos; + struct rcar_axi_qos *axi_qos; + + /* DBSC DBADJ2 */ + writel(0x20042004, DBSC3_0_DBADJ2); + + /* S3C -QoS */ + s3c = (struct rcar_s3c *)S3C_BASE; + writel(0x1F0D0B0A, &s3c->s3crorr); + writel(0x1F0D0B09, &s3c->s3cworr); + + /* QoS Control Registers */ + s3c_qos = (struct rcar_s3c_qos *)S3C_QOS_CCI0_BASE; + writel(0x00890089, &s3c_qos->s3cqos0); + writel(0x20960010, &s3c_qos->s3cqos1); + writel(0x20302030, &s3c_qos->s3cqos2); + writel(0x20AA2200, &s3c_qos->s3cqos3); + writel(0x00002032, &s3c_qos->s3cqos4); + writel(0x20960010, &s3c_qos->s3cqos5); + writel(0x20302030, &s3c_qos->s3cqos6); + writel(0x20AA2200, &s3c_qos->s3cqos7); + writel(0x00002032, &s3c_qos->s3cqos8); + + s3c_qos = (struct rcar_s3c_qos *)S3C_QOS_CCI1_BASE; + writel(0x00890089, &s3c_qos->s3cqos0); + writel(0x20960010, &s3c_qos->s3cqos1); + writel(0x20302030, &s3c_qos->s3cqos2); + writel(0x20AA2200, &s3c_qos->s3cqos3); + writel(0x00002032, &s3c_qos->s3cqos4); + writel(0x20960010, &s3c_qos->s3cqos5); + writel(0x20302030, &s3c_qos->s3cqos6); + writel(0x20AA2200, &s3c_qos->s3cqos7); + writel(0x00002032, &s3c_qos->s3cqos8); + + s3c_qos = (struct rcar_s3c_qos *)S3C_QOS_MXI_BASE; + writel(0x80928092, &s3c_qos->s3cqos0); + writel(0x20960020, &s3c_qos->s3cqos1); + writel(0x20302030, &s3c_qos->s3cqos2); + writel(0x20AA20DC, &s3c_qos->s3cqos3); + writel(0x00002032, &s3c_qos->s3cqos4); + writel(0x20960020, &s3c_qos->s3cqos5); + writel(0x20302030, &s3c_qos->s3cqos6); + writel(0x20AA20DC, &s3c_qos->s3cqos7); + writel(0x00002032, &s3c_qos->s3cqos8); + + s3c_qos = (struct rcar_s3c_qos *)S3C_QOS_AXI_BASE; + writel(0x00820082, &s3c_qos->s3cqos0); + writel(0x20960020, &s3c_qos->s3cqos1); + writel(0x20302030, &s3c_qos->s3cqos2); + writel(0x20AA20FA, &s3c_qos->s3cqos3); + writel(0x00002032, &s3c_qos->s3cqos4); + writel(0x20960020, &s3c_qos->s3cqos5); + writel(0x20302030, &s3c_qos->s3cqos6); + writel(0x20AA20FA, &s3c_qos->s3cqos7); + writel(0x00002032, &s3c_qos->s3cqos8); + + /* DBSC -QoS */ + /* DBSC0 - Read */ + for (i = DBSC3_00; i < DBSC3_NR; i++) { + qos_addr = (struct rcar_dbsc3_qos *)dbsc3_0_r_qos_addr[i]; + writel(0x00000002, &qos_addr->dblgcnt); + writel(0x0000207D, &qos_addr->dbtmval0); + writel(0x00002053, &qos_addr->dbtmval1); + writel(0x0000202A, &qos_addr->dbtmval2); + writel(0x00001FBD, &qos_addr->dbtmval3); + writel(0x00000001, &qos_addr->dbrqctr); + writel(0x00002064, &qos_addr->dbthres0); + writel(0x0000203E, &qos_addr->dbthres1); + writel(0x00002019, &qos_addr->dbthres2); + writel(0x00000001, &qos_addr->dblgqon); + } + + /* DBSC0 - Write */ + for (i = DBSC3_00; i < DBSC3_NR; i++) { + qos_addr = (struct rcar_dbsc3_qos *)dbsc3_0_w_qos_addr[i]; + writel(0x00000002, &qos_addr->dblgcnt); + writel(0x0000207D, &qos_addr->dbtmval0); + writel(0x00002053, &qos_addr->dbtmval1); + writel(0x00002043, &qos_addr->dbtmval2); + writel(0x00002030, &qos_addr->dbtmval3); + writel(0x00000001, &qos_addr->dbrqctr); + writel(0x00002064, &qos_addr->dbthres0); + writel(0x0000203E, &qos_addr->dbthres1); + writel(0x00002031, &qos_addr->dbthres2); + writel(0x00000001, &qos_addr->dblgqon); + } + + /* CCI-400 -QoS */ + writel(0x20000800, CCI_400_MAXOT_1); + writel(0x20000800, CCI_400_MAXOT_2); + writel(0x0000000C, CCI_400_QOSCNTL_1); + writel(0x0000000C, CCI_400_QOSCNTL_2); + + /* MXI -QoS */ + /* Transaction Control (MXI) */ + mxi = (struct rcar_mxi *)MXI_BASE; + writel(0x00000013, &mxi->mxrtcr); + writel(0x00000013, &mxi->mxwtcr); + writel(0x00780080, &mxi->mxsaar0); + writel(0x02000800, &mxi->mxsaar1); + + /* QoS Control (MXI) */ + mxi_qos = (struct rcar_mxi_qos *)MXI_QOS_BASE; + writel(0x0000000C, &mxi_qos->vspdu0); + writel(0x0000000E, &mxi_qos->du0); + + /* AXI -QoS */ + /* Transaction Control (MXI) */ + axi_qos = (struct rcar_axi_qos *)SYS_AXI_SYX64TO128_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_AVB_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x000020A6, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_IMUX0_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_IMUX1_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_IMUX2_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_LBS_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x0000214C, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_MMUDS_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_MMUM_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_MMUS0_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_MMUS1_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_RTX_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_SDS0_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x000020A6, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_SDS1_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x000020A6, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_USB20_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_USB22_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_AX2M_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_CC50_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002029, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_CCI_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_CS_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_DDM_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x000020A6, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_ETH_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_MPXM_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_SDM0_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x0000214C, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_SDM1_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x0000214C, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_TRAB_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x000020A6, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_UDM0_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI_UDM1_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + /* QoS Register (RT-AXI) */ + axi_qos = (struct rcar_axi_qos *)RT_AXI_SHX_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)RT_AXI_DBG_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)RT_AXI_RTX64TO128_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)RT_AXI_SY2RT_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + /* QoS Register (MP-AXI) */ + axi_qos = (struct rcar_axi_qos *)MP_AXI_ADSP_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002037, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_ASDS0_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002014, &axi_qos->qosctset0); + writel(0x00000040, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_ASDS1_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002014, &axi_qos->qosctset0); + writel(0x00000040, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_MLP_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00001FF0, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00002001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_MMUMP_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_SPU_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x00002053, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MP_AXI_SPUC_BASE; + writel(0x00000000, &axi_qos->qosconf); + writel(0x0000206E, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + /* QoS Register (SYS-AXI256) */ + axi_qos = (struct rcar_axi_qos *)SYS_AXI256_AXI128TO256_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020EB, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI256_SYX_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020EB, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI256_MPX_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020EB, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)SYS_AXI256_MXI_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020EB, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + /* QoS Register (CCI-AXI) */ + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUS0_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_SYX2_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUDS_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUM_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MXI_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x00002245, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUS1_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)CCI_AXI_MMUMP_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002004, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000000, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + /* QoS Register (Media-AXI) */ + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_MXR_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020DC, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x000020AA, &axi_qos->qosthres0); + writel(0x00002032, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_MXW_BASE; + writel(0x00000002, &axi_qos->qosconf); + writel(0x000020DC, &axi_qos->qosctset0); + writel(0x00002096, &axi_qos->qosctset1); + writel(0x00002030, &axi_qos->qosctset2); + writel(0x00002030, &axi_qos->qosctset3); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x000020AA, &axi_qos->qosthres0); + writel(0x00002032, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_TDMR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_TDMW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSP1CR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSP1CW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSPDU0CR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSPDU0CW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002190, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VIN0W_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00001FF0, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00002001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_FDP0R_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_FDP0W_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_IMSR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_IMSW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSP1R_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSP1W_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_IMRR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_IMRW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSPD0R_BASE; + writel(0x00000003, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VSPD0W_BASE; + writel(0x00000003, &axi_qos->qosconf); + writel(0x000020C8, &axi_qos->qosctset0); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_DU0R_BASE; + writel(0x00000003, &axi_qos->qosconf); + writel(0x00002063, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_DU0W_BASE; + writel(0x00000003, &axi_qos->qosconf); + writel(0x00002063, &axi_qos->qosctset0); + writel(0x00000001, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VCP0CR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002073, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VCP0CW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002073, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VCP0VR_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002073, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VCP0VW_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002073, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00000001, &axi_qos->qosthres0); + writel(0x00000001, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); + + axi_qos = (struct rcar_axi_qos *)MEDIA_AXI_VPC0R_BASE; + writel(0x00000001, &axi_qos->qosconf); + writel(0x00002073, &axi_qos->qosctset0); + writel(0x00000020, &axi_qos->qosreqctr); + writel(0x00002064, &axi_qos->qosthres0); + writel(0x00002004, &axi_qos->qosthres1); + writel(0x00000001, &axi_qos->qosthres2); + writel(0x00000001, &axi_qos->qosqon); +} +#else /* CONFIG_RMOBILE_EXTRAM_BOOT */ +void qos_init(void) +{ +} +#endif /* CONFIG_RMOBILE_EXTRAM_BOOT */ diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c new file mode 100644 index 0000000000..8818211d32 --- /dev/null +++ b/board/renesas/silk/silk.c @@ -0,0 +1,175 @@ +/* + * board/renesas/silk/silk.c + * + * Copyright (C) 2015 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qos.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define CLK2MHZ(clk) (clk / 1000 / 1000) +void s_init(void) +{ + struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE; + struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE; + + /* Watchdog init */ + writel(0xA5A5A500, &rwdt->rwtcsra); + writel(0xA5A5A500, &swdt->swtcsra); + + /* QoS */ + qos_init(); + +#ifndef CONFIG_DCACHE_OFF + /* + * The caches are disabled when ACTLR.SMP is set to 0 + * regardless of the value of the SCTLR.C (cache enable bit) + * on Cortex-A7 MPCore + */ + asm volatile( + "mrc 15, 0, r0, c1, c0, 1\n" /* read ACTLR */ + "orr r0, r0, #(1 << 6)\n" /* set ACTLR.SMP bit */ + "mcr p15, 0, r0, c1, c0, 1\n"); /* write ACTLR */ +#endif +} + +#define TMU0_MSTP125 (1 << 25) +#define SCIF2_MSTP719 (1 << 19) +#define ETHER_MSTP813 (1 << 13) +#define IIC1_MSTP323 (1 << 23) +#define MMC0_MSTP315 (1 << 15) + +int board_early_init_f(void) +{ + /* TMU */ + mstp_clrbits_le32(MSTPSR1, SMSTPCR1, TMU0_MSTP125); + + /* SCIF2 */ + mstp_clrbits_le32(MSTPSR7, SMSTPCR7, SCIF2_MSTP719); + + /* ETHER */ + mstp_clrbits_le32(MSTPSR8, SMSTPCR8, ETHER_MSTP813); + + /* IIC1 / sh-i2c ch1 */ + mstp_clrbits_le32(MSTPSR3, SMSTPCR3, IIC1_MSTP323); + +#ifdef CONFIG_SH_MMCIF + /* MMC */ + mstp_clrbits_le32(MSTPSR3, SMSTPCR3, MMC0_MSTP315); +#endif + return 0; +} + +int board_init(void) +{ + /* adress of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + /* Init PFC controller */ + r8a7794_pinmux_init(); + + /* Ether Enable */ + gpio_request(GPIO_FN_ETH_CRS_DV, NULL); + gpio_request(GPIO_FN_ETH_RX_ER, NULL); + gpio_request(GPIO_FN_ETH_RXD0, NULL); + gpio_request(GPIO_FN_ETH_RXD1, NULL); + gpio_request(GPIO_FN_ETH_LINK, NULL); + gpio_request(GPIO_FN_ETH_REFCLK, NULL); + gpio_request(GPIO_FN_ETH_MDIO, NULL); + gpio_request(GPIO_FN_ETH_TXD1, NULL); + gpio_request(GPIO_FN_ETH_TX_EN, NULL); + gpio_request(GPIO_FN_ETH_MAGIC, NULL); + gpio_request(GPIO_FN_ETH_TXD0, NULL); + gpio_request(GPIO_FN_ETH_MDC, NULL); + gpio_request(GPIO_FN_IRQ8, NULL); + + /* PHY reset */ + gpio_request(GPIO_GP_1_24, NULL); + gpio_direction_output(GPIO_GP_1_24, 0); + mdelay(20); + gpio_set_value(GPIO_GP_1_24, 1); + udelay(1); + + return 0; +} + +#define CXR24 0xEE7003C0 /* MAC address high register */ +#define CXR25 0xEE7003C8 /* MAC address low register */ +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SH_ETHER + int ret = -ENODEV; + u32 val; + unsigned char enetaddr[6]; + + ret = sh_eth_initialize(bis); + if (!eth_getenv_enetaddr("ethaddr", enetaddr)) + return ret; + + /* Set Mac address */ + val = enetaddr[0] << 24 | enetaddr[1] << 16 | + enetaddr[2] << 8 | enetaddr[3]; + writel(val, CXR24); + + val = enetaddr[4] << 8 | enetaddr[5]; + writel(val, CXR25); + + return ret; +#else + return 0; +#endif +} + +int board_mmc_init(bd_t *bis) +{ + int ret = 0; + +#ifdef CONFIG_SH_MMCIF + /* MMC0 */ + gpio_request(GPIO_GP_4_31, NULL); + gpio_set_value(GPIO_GP_4_31, 1); + + ret = mmcif_mmc_init(); +#endif + return ret; +} + +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +const struct rmobile_sysinfo sysinfo = { + CONFIG_RMOBILE_BOARD_STRING +}; + +void reset_cpu(ulong addr) +{ + u8 val; + + i2c_set_bus_num(1); /* PowerIC connected to ch1 */ + i2c_read(CONFIG_SYS_I2C_POWERIC_ADDR, 0x13, 1, &val, 1); + val |= 0x02; + i2c_write(CONFIG_SYS_I2C_POWERIC_ADDR, 0x13, 1, &val, 1); +} diff --git a/configs/silk_defconfig b/configs/silk_defconfig new file mode 100644 index 0000000000..515ee3372b --- /dev/null +++ b/configs/silk_defconfig @@ -0,0 +1,3 @@ +CONFIG_ARM=y +CONFIG_RMOBILE=y +CONFIG_TARGET_SILK=y diff --git a/include/configs/silk.h b/include/configs/silk.h new file mode 100644 index 0000000000..a4235e94d0 --- /dev/null +++ b/include/configs/silk.h @@ -0,0 +1,117 @@ +/* + * include/configs/silk.h + * This file is silk board configuration. + * + * Copyright (C) 2015 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __SILK_H +#define __SILK_H + +#undef DEBUG +#define CONFIG_R8A7794 +#define CONFIG_RMOBILE_BOARD_STRING "Silk" + +#include "rcar-gen2-common.h" + +#if defined(CONFIG_RMOBILE_EXTRAM_BOOT) +#define CONFIG_SYS_TEXT_BASE 0x70000000 +#else +#define CONFIG_SYS_TEXT_BASE 0xE6304000 +#endif + +#if defined(CONFIG_RMOBILE_EXTRAM_BOOT) +#define CONFIG_SYS_INIT_SP_ADDR 0x7003FFFC +#else +#define CONFIG_SYS_INIT_SP_ADDR 0xE633FFFC +#endif +#define STACK_AREA_SIZE 0xC000 +#define LOW_LEVEL_MERAM_STACK \ + (CONFIG_SYS_INIT_SP_ADDR + STACK_AREA_SIZE - 4) + +/* MEMORY */ +#define RCAR_GEN2_SDRAM_BASE 0x40000000 +#define RCAR_GEN2_SDRAM_SIZE (1024u * 1024 * 1024) +#define RCAR_GEN2_UBOOT_SDRAM_SIZE (512 * 1024 * 1024) + +/* SCIF */ +#define CONFIG_SCIF_CONSOLE +#define CONFIG_CONS_SCIF2 +#define CONFIG_SCIF_USE_EXT_CLK + +/* FLASH */ +#define CONFIG_SPI +#define CONFIG_SPI_FLASH_BAR +#define CONFIG_SH_QSPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_SPI_FLASH_QUAD +#define CONFIG_SYS_NO_FLASH + +/* SH Ether */ +#define CONFIG_NET_MULTI +#define CONFIG_SH_ETHER +#define CONFIG_SH_ETHER_USE_PORT 0 +#define CONFIG_SH_ETHER_PHY_ADDR 0x1 +#define CONFIG_SH_ETHER_PHY_MODE PHY_INTERFACE_MODE_RMII +#define CONFIG_SH_ETHER_CACHE_WRITEBACK +#define CONFIG_SH_ETHER_CACHE_INVALIDATE +#define CONFIG_SH_ETHER_ALIGNE_SIZE 64 +#define CONFIG_PHYLIB +#define CONFIG_PHY_MICREL +#define CONFIG_BITBANGMII +#define CONFIG_BITBANGMII_MULTI + +/* Board Clock */ +#define RMOBILE_XTAL_CLK 20000000u +#define CONFIG_SYS_CLK_FREQ RMOBILE_XTAL_CLK +#define CONFIG_SH_TMU_CLK_FREQ (CONFIG_SYS_CLK_FREQ / 2) /* EXT / 2 */ +#define CONFIG_PLL1_CLK_FREQ (CONFIG_SYS_CLK_FREQ * 156 / 2) +#define CONFIG_P_CLK_FREQ (CONFIG_PLL1_CLK_FREQ / 24) +#define CONFIG_SH_SCIF_CLK_FREQ 14745600 /* External Clock */ + +#define CONFIG_SYS_TMU_CLK_DIV 4 + +/* i2c */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_SH +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SYS_I2C_SH_NUM_CONTROLLERS 3 +#define CONFIG_SYS_I2C_SH_SPEED0 400000 +#define CONFIG_SYS_I2C_SH_SPEED1 400000 +#define CONFIG_SYS_I2C_SH_SPEED2 400000 +#define CONFIG_SH_I2C_DATA_HIGH 4 +#define CONFIG_SH_I2C_DATA_LOW 5 +#define CONFIG_SH_I2C_CLOCK 10000000 + +#define CONFIG_SYS_I2C_POWERIC_ADDR 0x58 /* da9063 */ + +/* USB */ +#define CONFIG_USB_STORAGE +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_RMOBILE +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 + +/* MMCIF */ +#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_MMC +#define CONFIG_SH_MMCIF +#define CONFIG_SH_MMCIF_ADDR 0xee200000 +#define CONFIG_SH_MMCIF_CLK 48000000 + +/* Module stop status bits */ +/* INTC-RT */ +#define CONFIG_SMSTP0_ENA 0x00400000 +/* MSIF */ +#define CONFIG_SMSTP2_ENA 0x00002000 +/* INTC-SYS, IRQC */ +#define CONFIG_SMSTP4_ENA 0x00000180 +/* SCIF2 */ +#define CONFIG_SMSTP7_ENA 0x00080000 + +#endif /* __SILK_H */ -- cgit From a973be74c206d6cc04ccee9de6831c1e98d9527b Mon Sep 17 00:00:00 2001 From: Vladimir Barinov Date: Mon, 9 Feb 2015 03:27:47 +0300 Subject: arm: rmobile: Add missed header file for Silk board This file was missed in the commit https://patchwork.ozlabs.org/patch/427801/ Signed-off-by: Vladimir Barinov Signed-off-by: Nobuhiro Iwamatsu --- board/renesas/silk/qos.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 board/renesas/silk/qos.h diff --git a/board/renesas/silk/qos.h b/board/renesas/silk/qos.h new file mode 100644 index 0000000000..75a20bb075 --- /dev/null +++ b/board/renesas/silk/qos.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015 Renesas Electronics Corporation + * Copyright (C) 2015 Cogent Embedded, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __QOS_H__ +#define __QOS_H__ + +void qos_init(void); + +#endif -- cgit From 3eda55a32d3787303934a1575684a8f61c362892 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 23 Jan 2015 09:31:57 +0900 Subject: arm: rmobile: r8a7794: Enable SMP mode of Auxiliary Control Register r8a7794 uses ARM SoC of CA7 base. If we want to use dcache on CA7, we need to enable SMP bit of Auxiliary Control Register. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S b/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S index d47546a11d..a5dbbea9e1 100644 --- a/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S +++ b/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S @@ -40,7 +40,7 @@ do_lowlevel_init: and r1, r1, #0x7F00 lsrs r1, r1, #8 cmp r1, #0x4C /* 0x4C is ID of r8a7794 */ - beq _exit_init_l2_a15 + beq _enable_actlr_smp /* surpress wfe if ca15 */ tst r4, #4 @@ -64,6 +64,16 @@ do_lowlevel_init: orrne r0, r0, #0x20 /* L2CTLR[5] */ #endif mcrne p15, 1, r0, c9, c0, 2 + + b _exit_init_l2_a15 + +_enable_actlr_smp: /* R8A7794 only (CA7) */ +#ifndef CONFIG_DCACHE_OFF + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 +#endif + _exit_init_l2_a15: ldr r3, =(CONFIG_SYS_INIT_SP_ADDR) sub sp, r3, #4 -- cgit From 79bf043e371cfb7bed276e3ce795f066a364f5ff Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 10 Feb 2015 15:26:10 +0900 Subject: ARM: rmobile: silk: Remove initialization of ACTLR.SMP Initialization of ACTLR.SMP is in lowlevel_init. This remove duplicate function. Signed-off-by: Nobuhiro Iwamatsu --- board/renesas/silk/silk.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c index 8818211d32..dfd9a9d3e4 100644 --- a/board/renesas/silk/silk.c +++ b/board/renesas/silk/silk.c @@ -38,18 +38,6 @@ void s_init(void) /* QoS */ qos_init(); - -#ifndef CONFIG_DCACHE_OFF - /* - * The caches are disabled when ACTLR.SMP is set to 0 - * regardless of the value of the SCTLR.C (cache enable bit) - * on Cortex-A7 MPCore - */ - asm volatile( - "mrc 15, 0, r0, c1, c0, 1\n" /* read ACTLR */ - "orr r0, r0, #(1 << 6)\n" /* set ACTLR.SMP bit */ - "mcr p15, 0, r0, c1, c0, 1\n"); /* write ACTLR */ -#endif } #define TMU0_MSTP125 (1 << 25) -- cgit From f13606b77d32344d35f6430eb45cffd47302e244 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 13 Jan 2015 18:35:46 +0300 Subject: arc: introduce U-Boot port for ARCv2 ISA ARC HS and ARC EM are new cores based on ARCv2 ISA which is binary incompatible with ISAv1 (AKA ARCompact). Significant difference between ISAv2 and v1 is implementation of interrupt vector table. In v1 it is implemented in the same way as on many other architectures - as a special location where user may put whether code executed in place (if machine word of space is enough) or jump to a full-scale interrupt handler. In v2 interrupt table is just an array of adresses of real interrupt handlers. That requires a separate section for IVT that is not encoded as code by assembler. This change adds support for following cores: * ARC EM6 (simple 32-bit microcontroller without MMU) * ARC HS36 (advanced 32-bit microcontroller without MMU) * ARC HS38 (advanced 32-bit microcontroller with MMU) As a part of ARC HS38 new version of MMU (v4) was introduced. Also this change adds AXS131 board which is the same DW ARC SDP base board but with ARC HS38 CPU tile. Signed-off-by: Alexey Brodkin --- arch/arc/Kconfig | 59 +++++++++- arch/arc/config.mk | 12 ++ arch/arc/cpu/arcv2/Makefile | 7 ++ arch/arc/cpu/arcv2/start.S | 254 +++++++++++++++++++++++++++++++++++++++++++ arch/arc/include/asm/cache.h | 6 +- configs/axs103_defconfig | 5 + 6 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 arch/arc/cpu/arcv2/Makefile create mode 100644 arch/arc/cpu/arcv2/start.S create mode 100644 configs/axs103_defconfig diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index a8dc4e2336..24f5c02c76 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -8,30 +8,79 @@ config USE_PRIVATE_LIBGCC default y config SYS_CPU - default "arcv1" + default "arcv1" if ISA_ARCOMPACT + default "arcv2" if ISA_ARCV2 + +choice + prompt "ARC Instruction Set" + default ISA_ARCOMPACT + +config ISA_ARCOMPACT + bool "ARCompact ISA" + help + The original ARC ISA of ARC600/700 cores + +config ISA_ARCV2 + bool "ARC ISA v2" + help + ISA for the Next Generation ARC-HS cores + +endchoice choice prompt "CPU selection" - default CPU_ARC770D + default CPU_ARC770D if ISA_ARCOMPACT + default CPU_ARCHS38 if ISA_ARCV2 config CPU_ARC750D bool "ARC 750D" select ARC_MMU_V2 + depends on ISA_ARCOMPACT help Choose this option to build an U-Boot for ARC750D CPU. config CPU_ARC770D bool "ARC 770D" select ARC_MMU_V3 + depends on ISA_ARCOMPACT help Choose this option to build an U-Boot for ARC770D CPU. +config CPU_ARCEM6 + bool "ARC EM6" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS36 + bool "ARC HS36" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS38 + bool "ARC HS38" + select ARC_MMU_V4 + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA with MMU. + endchoice choice prompt "MMU Version" default ARC_MMU_V3 if CPU_ARC770D default ARC_MMU_V2 if CPU_ARC750D + default ARC_MMU_ABSENT if CPU_ARCEM6 + default ARC_MMU_ABSENT if CPU_ARCHS36 + default ARC_MMU_V4 if CPU_ARCHS38 + +config ARC_MMU_ABSENT + bool "No MMU" + help + No MMU config ARC_MMU_V2 bool "MMU v2" @@ -48,6 +97,12 @@ config ARC_MMU_V3 Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) Shared Address Spaces (SASID) +config ARC_MMU_V4 + bool "MMU v4" + depends on CPU_ARCHS38 + help + Introduced as a part of ARC HS38 release. + endchoice config CPU_BIG_ENDIAN diff --git a/arch/arc/config.mk b/arch/arc/config.mk index f1e81b6895..4fcd4076c4 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -38,6 +38,18 @@ ifdef CONFIG_CPU_ARC770D PLATFORM_CPPFLAGS += -marc700 -mlock -mswape endif +ifdef CONFIG_CPU_ARCEM6 +PLATFORM_CPPFLAGS += -marcem +endif + +ifdef CONFIG_CPU_ARCHS34 +PLATFORM_CPPFLAGS += -marchs +endif + +ifdef CONFIG_CPU_ARCHS38 +PLATFORM_CPPFLAGS += -marchs +endif + PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 # Needed for relocation diff --git a/arch/arc/cpu/arcv2/Makefile b/arch/arc/cpu/arcv2/Makefile new file mode 100644 index 0000000000..cc69e5a17e --- /dev/null +++ b/arch/arc/cpu/arcv2/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += start.o diff --git a/arch/arc/cpu/arcv2/start.S b/arch/arc/cpu/arcv2/start.S new file mode 100644 index 0000000000..3ce689675f --- /dev/null +++ b/arch/arc/cpu/arcv2/start.S @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * Note on the LD/ST addressing modes with address register write-back + * + * LD.a same as LD.aw + * + * LD.a reg1, [reg2, x] => Pre Incr + * Eff Addr for load = [reg2 + x] + * + * LD.ab reg1, [reg2, x] => Post Incr + * Eff Addr for load = [reg2] + */ + +.macro PUSH reg + st.a \reg, [%sp, -4] +.endm + +.macro PUSHAX aux + lr %r9, [\aux] + PUSH %r9 +.endm + +.macro SAVE_R1_TO_R24 + PUSH %r1 + PUSH %r2 + PUSH %r3 + PUSH %r4 + PUSH %r5 + PUSH %r6 + PUSH %r7 + PUSH %r8 + PUSH %r9 + PUSH %r10 + PUSH %r11 + PUSH %r12 + PUSH %r13 + PUSH %r14 + PUSH %r15 + PUSH %r16 + PUSH %r17 + PUSH %r18 + PUSH %r19 + PUSH %r20 + PUSH %r21 + PUSH %r22 + PUSH %r23 + PUSH %r24 +.endm + +.macro SAVE_ALL_SYS + /* saving %r0 to reg->r0 in advance since weread %ecr into it */ + st %r0, [%sp, -8] + lr %r0, [%ecr] /* all stack addressing is manual so far */ + st %r0, [%sp] + st %sp, [%sp, -4] + /* now move %sp to reg->r0 position so we can do "push" automatically */ + sub %sp, %sp, 8 + + SAVE_R1_TO_R24 + PUSH %r25 + PUSH %gp + PUSH %fp + PUSH %blink + PUSHAX %eret + PUSHAX %erstatus + PUSH %lp_count + PUSHAX %lp_end + PUSHAX %lp_start + PUSHAX %erbta +.endm + +.macro SAVE_EXCEPTION_SOURCE +#ifdef CONFIG_MMU + /* If MMU exists exception faulting address is loaded in EFA reg */ + lr %r0, [%efa] +#else + /* Otherwise in ERET (exception return) reg */ + lr %r0, [%eret] +#endif +.endm + +.section .ivt, "a",@progbits +.align 4 + /* Critical system events */ +.word _start /* 0 - 0x000 */ +.word memory_error /* 1 - 0x008 */ +.word instruction_error /* 2 - 0x010 */ + + /* Exceptions */ +.word EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ +.word EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ +.word EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ +.word EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ +.word EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ +.word EV_Trap /* 0x128, Trap exception (0x25) */ +.word EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr + +.text +.globl _start +_start: + /* Setup interrupt vector base that matches "__text_start" */ + sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] + + /* Setup stack pointer */ + mov %sp, CONFIG_SYS_INIT_SP_ADDR + mov %fp, %sp + + /* Clear bss */ + mov %r0, __bss_start + mov %r1, __bss_end + +clear_bss: + st.ab 0, [%r0, 4] + brlt %r0, %r1, clear_bss + + /* Zero the one and only argument of "board_init_f" */ + mov_s %r0, 0 + j board_init_f + +memory_error: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_memory_error + +instruction_error: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_instruction_error + +interrupt_handler: + /* Todo - save and restore CPU context when interrupts will be in use */ + bl do_interrupt_handler + rtie + +EV_MachineCheck: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_machine_check_fault + +EV_TLBMissI: + SAVE_ALL_SYS + mov %r0, %sp + j do_itlb_miss + +EV_TLBMissD: + SAVE_ALL_SYS + mov %r0, %sp + j do_dtlb_miss + +EV_TLBProtV: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_tlb_prot_violation + +EV_PrivilegeV: + SAVE_ALL_SYS + mov %r0, %sp + j do_privilege_violation + +EV_Trap: + SAVE_ALL_SYS + mov %r0, %sp + j do_trap + +EV_Extension: + SAVE_ALL_SYS + mov %r0, %sp + j do_extension + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r0 = start_addr_sp + * r1 = new__gd + * r2 = relocaddr + */ +.align 4 +.globl relocate_code +relocate_code: + /* + * r0-r12 might be clobbered by C functions + * so we use r13-r16 for storage here + */ + mov %r13, %r0 /* save addr_sp */ + mov %r14, %r1 /* save addr of gd */ + mov %r15, %r2 /* save addr of destination */ + + mov %r16, %r2 /* %r9 - relocation offset */ + sub %r16, %r16, __image_copy_start + +/* Set up the stack */ +stack_setup: + mov %sp, %r13 + mov %fp, %sp + +/* Check if monitor is loaded right in place for relocation */ + mov %r0, __image_copy_start + cmp %r0, %r15 /* skip relocation if code loaded */ + bz do_board_init_r /* in target location already */ + +/* Copy data (__image_copy_start - __image_copy_end) to new location */ + mov %r1, %r15 + mov %r2, __image_copy_end + sub %r2, %r2, %r0 /* r3 <- amount of bytes to copy */ + asr %r2, %r2, 2 /* r3 <- amount of words to copy */ + mov %lp_count, %r2 + lp copy_end + ld.ab %r2,[%r0,4] + st.ab %r2,[%r1,4] +copy_end: + +/* Fix relocations related issues */ + bl do_elf_reloc_fixups +#ifndef CONFIG_SYS_ICACHE_OFF + bl invalidate_icache_all +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + bl flush_dcache_all +#endif + +/* Update position of intterupt vector table */ + lr %r0, [ARC_AUX_INTR_VEC_BASE] /* Read current position */ + add %r0, %r0, %r16 /* Update address */ + sr %r0, [ARC_AUX_INTR_VEC_BASE] /* Write new position */ + +do_board_init_r: +/* Prepare for exection of "board_init_r" in relocated monitor */ + mov %r2, board_init_r /* old address of "board_init_r()" */ + add %r2, %r2, %r16 /* new address of "board_init_r()" */ + mov %r0, %r14 /* 1-st parameter: gd_t */ + mov %r1, %r15 /* 2-nd parameter: dest_addr */ + j [%r2] diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 2725961221..8a77cd93af 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -17,10 +17,14 @@ #define ARCH_DMA_MINALIGN 128 #endif -#if defined(CONFIG_ARC_MMU_V2) +#if defined(ARC_MMU_ABSENT) +#define CONFIG_ARC_MMU_VER 0 +#elif defined(CONFIG_ARC_MMU_V2) #define CONFIG_ARC_MMU_VER 2 #elif defined(CONFIG_ARC_MMU_V3) #define CONFIG_ARC_MMU_VER 3 +#elif defined(CONFIG_ARC_MMU_V4) +#define CONFIG_ARC_MMU_VER 4 #endif #endif /* __ASM_ARC_CACHE_H */ diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig new file mode 100644 index 0000000000..c63dd4ab2e --- /dev/null +++ b/configs/axs103_defconfig @@ -0,0 +1,5 @@ +CONFIG_SYS_TEXT_BASE=0x81000000 +CONFIG_SYS_CLK_FREQ=50000000 +CONFIG_ARC=y +CONFIG_ISA_ARCV2=y +CONFIG_TARGET_AXS101=y -- cgit From a276172cf32386c211c75638f6bf3c0d59ba03ba Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 8 Jan 2015 16:50:21 +0900 Subject: arm: exynos: fix the div value for set_mmc_clk The most exynos used the "Ratio + 1" as div value. And value at register is "Ratio". So if want to set exact value, it needs to subtract one. Value at register ("Ratio") = div - 1 Signed-off-by: Jaehoon Chung Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index b31c13b14b..3110bb0657 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -1656,6 +1656,10 @@ unsigned long get_mmc_clk(int dev_index) void set_mmc_clk(int dev_index, unsigned int div) { + /* If want to set correct value, it needs to substract one from div.*/ + if (div > 0) + div -= 1; + if (cpu_is_exynos5()) { if (proid_is_exynos5420() || proid_is_exynos5800()) exynos5420_set_mmc_clk(dev_index, div); -- cgit From aa8e00fab5e65a07c2cae52274946a908805ea60 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 15 Jan 2015 11:45:56 +0900 Subject: samsung: board: support eMMC reset using DT Some exynos boards require special handling of nRESET_OUT line for eMMC memory to perform complete reboot e.g. Odroid X2/U3/XU3 boards. This will support eMMC reset using DT from reset_misc of samsung common board file. Signed-off-by: Joonyoung Shim Signed-off-by: Minkyu Kang --- board/samsung/common/board.c | 28 ++++++++++++++++++++++++++ board/samsung/odroid/odroid.c | 8 -------- doc/device-tree-bindings/exynos/emmc-reset.txt | 15 ++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/emmc-reset.txt diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 8b4c8e9a9d..da2245ff9d 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -355,3 +355,31 @@ int misc_init_r(void) return 0; } #endif + +void reset_misc(void) +{ + struct gpio_desc gpio = {}; + int node; + + node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, + "samsung,emmc-reset"); + if (node < 0) + return; + + gpio_request_by_name_nodev(gd->fdt_blob, node, "reset-gpio", 0, &gpio, + GPIOD_IS_OUT); + + if (dm_gpio_is_valid(&gpio)) { + /* + * Reset eMMC + * + * FIXME: Need to optimize delay time. Minimum 1usec pulse is + * required by 'JEDEC Standard No.84-A441' (eMMC) + * document but real delay time is expected to greater + * than 1usec. + */ + dm_gpio_set_value(&gpio, 0); + mdelay(10); + dm_gpio_set_value(&gpio, 1); + } +} diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index e3517f2eb2..306cc0f9d9 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -503,11 +503,3 @@ int board_usb_init(int index, enum usb_init_type init) return s3c_udc_probe(&s5pc210_otg_data); } #endif - -void reset_misc(void) -{ - /* Reset eMMC*/ - gpio_set_value(EXYNOS4X12_GPIO_K12, 0); - mdelay(10); - gpio_set_value(EXYNOS4X12_GPIO_K12, 1); -} diff --git a/doc/device-tree-bindings/exynos/emmc-reset.txt b/doc/device-tree-bindings/exynos/emmc-reset.txt new file mode 100644 index 0000000000..5e7ba26c27 --- /dev/null +++ b/doc/device-tree-bindings/exynos/emmc-reset.txt @@ -0,0 +1,15 @@ +* Samsung eMMC reset + +Some exynos boards require special handling of nRESET_OUT line for eMMC memory +to perform complete reboot. + +Required properties: +- compatible: should be "samsung,emmc-reset" +- reset-gpio: gpio chip for eMMC reset. + +Example: + +emmc-reset { + compatible = "samsung,emmc-reset"; + reset-gpio = <&gpk1 2 0>; +}; -- cgit From 44237f7a89030757e0f4afc01a7b6a300d4aca40 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 15 Jan 2015 11:45:57 +0900 Subject: Odroid: Add eMMC-reset node on DT This needs for special handling of nRESET_OUT line(GPK1-2 gpio) for eMMC memory to perform complete reboot on Odroid X2/U3 boards. Signed-off-by: Joonyoung Shim Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos4412-odroid.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index 00a2917596..582f6e594b 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -85,4 +85,9 @@ reg = <0x125B0000 0x100>; }; }; + + emmc-reset { + compatible = "samsung,emmc-reset"; + reset-gpio = <&gpk1 2 0>; + }; }; -- cgit From de3b251870780c8ed6406e15f3fcaf92a9e3c498 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Thu, 15 Jan 2015 11:45:58 +0900 Subject: Odroid-XU3: Add eMMC-reset node on DT This needs for special handling of nRESET_OUT line(GPD1-0 gpio) for eMMC memory to perform complete reboot on Odroid XU3 board. Signed-off-by: Joonyoung Shim Signed-off-by: Minkyu Kang --- arch/arm/dts/exynos5422-odroidxu3.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/dts/exynos5422-odroidxu3.dts b/arch/arm/dts/exynos5422-odroidxu3.dts index 8f4663733c..d0a8621fda 100644 --- a/arch/arm/dts/exynos5422-odroidxu3.dts +++ b/arch/arm/dts/exynos5422-odroidxu3.dts @@ -46,4 +46,9 @@ mmc@12220000 { fifoth_val = <0x201f0020>; }; + + emmc-reset { + compatible = "samsung,emmc-reset"; + reset-gpio = <&gpd1 0 0>; + }; }; -- cgit From b00f8edb5a1a98636afa121c7c8eacc9045ae19f Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Fri, 23 Jan 2015 17:30:07 +0900 Subject: odroid: fix g2d sclk rate G2D core should be provided 200MHz clock rate. Signed-off-by: Joonyoung Shim Signed-off-by: Minkyu Kang --- board/samsung/odroid/odroid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c index 306cc0f9d9..bff6ac928c 100644 --- a/board/samsung/odroid/odroid.c +++ b/board/samsung/odroid/odroid.c @@ -248,12 +248,12 @@ static void board_clock_init(void) * MOUTc2c = 800 Mhz * MOUTpwi = 108 MHz * - * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 400 (1) + * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 200 (3) * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1) * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1) * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5) */ - set = G2D_ACP_RATIO(1) | C2C_RATIO(1) | PWI_RATIO(5) | + set = G2D_ACP_RATIO(3) | C2C_RATIO(1) | PWI_RATIO(5) | C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1); clrsetbits_le32(&clk->div_dmc1, clr, set); -- cgit From 483e49bfd775adb15102418a72c7fb02ef51fd79 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Wed, 21 Jan 2015 13:51:32 +0900 Subject: EXYNOS5: Add function to enable exynos5420 usbdev phy ctrl Exynos5420 has different registers with other exynos5 SoCs to control usb device phy, so need separated function to enable exynos5420 usb device phy. Signed-off-by: Joonyoung Shim Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/power.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 1520d642c5..1b12051656 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -102,10 +102,34 @@ static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable) } } +static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable) +{ + struct exynos5420_power *power = + (struct exynos5420_power *)samsung_get_base_power(); + + if (enable) { + /* Enabling USBDEV_PHY */ + setbits_le32(&power->usbdev_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + setbits_le32(&power->usbdev1_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } else { + /* Disabling USBDEV_PHY */ + clrbits_le32(&power->usbdev_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + clrbits_le32(&power->usbdev1_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } +} + void set_usbdrd_phy_ctrl(unsigned int enable) { - if (cpu_is_exynos5()) - exynos5_set_usbdrd_phy_ctrl(enable); + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + exynos5420_set_usbdev_phy_ctrl(enable); + else + exynos5_set_usbdrd_phy_ctrl(enable); + } } static void exynos5_dp_phy_control(unsigned int enable) -- cgit From d606ded1dbabba832e7150bc8ebb0719eadb42ef Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 15:59:59 +0530 Subject: Exynos5: Fix compiler warnings due to clock_get_periph_rate Apparently, members of clk_bit_info array do not map correctly to the members of enum periph_id. This mapping got broken after we changed periph_id(s) to reflect interrupt number instead of their position in a sequence. This patch intends to fix above mentioned issue. Signed-off-by: Akshay Saraswat Reviewed-by: Simon Glass Tested-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 80 ++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 3110bb0657..251fc0e9d3 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -20,42 +20,45 @@ * positions of the peripheral clocks of the src and div registers */ struct clk_bit_info { + enum periph_id id; int8_t src_bit; int8_t div_bit; int8_t prediv_bit; }; -/* src_bit div_bit prediv_bit */ +/* periph_id src_bit div_bit prediv_bit */ static struct clk_bit_info clk_bit_info[] = { - {0, 0, -1}, - {4, 4, -1}, - {8, 8, -1}, - {12, 12, -1}, - {0, 0, 8}, - {4, 16, 24}, - {8, 0, 8}, - {12, 16, 24}, - {-1, -1, -1}, - {16, 0, 8}, - {20, 16, 24}, - {24, 0, 8}, - {0, 0, 4}, - {4, 12, 16}, - {-1, -1, -1}, - {-1, -1, -1}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {-1, 24, 0}, - {24, 0, -1}, - {24, 0, -1}, - {24, 0, -1}, - {24, 0, -1}, - {24, 0, -1}, + {PERIPH_ID_UART0, 0, 0, -1}, + {PERIPH_ID_UART1, 4, 4, -1}, + {PERIPH_ID_UART2, 8, 8, -1}, + {PERIPH_ID_UART3, 12, 12, -1}, + {PERIPH_ID_I2C0, -1, 24, 0}, + {PERIPH_ID_I2C1, -1, 24, 0}, + {PERIPH_ID_I2C2, -1, 24, 0}, + {PERIPH_ID_I2C3, -1, 24, 0}, + {PERIPH_ID_I2C4, -1, 24, 0}, + {PERIPH_ID_I2C5, -1, 24, 0}, + {PERIPH_ID_I2C6, -1, 24, 0}, + {PERIPH_ID_I2C7, -1, 24, 0}, + {PERIPH_ID_SPI0, 16, 0, 8}, + {PERIPH_ID_SPI1, 20, 16, 24}, + {PERIPH_ID_SPI2, 24, 0, 8}, + {PERIPH_ID_SDMMC0, 0, 0, 8}, + {PERIPH_ID_SDMMC1, 4, 16, 24}, + {PERIPH_ID_SDMMC2, 8, 0, 8}, + {PERIPH_ID_SDMMC3, 12, 16, 24}, + {PERIPH_ID_I2S0, 0, 0, 4}, + {PERIPH_ID_I2S1, 4, 12, 16}, + {PERIPH_ID_SPI3, 0, 0, 4}, + {PERIPH_ID_SPI4, 4, 12, 16}, + {PERIPH_ID_SDMMC4, 16, 0, 8}, + {PERIPH_ID_PWM0, 24, 0, -1}, + {PERIPH_ID_PWM1, 24, 0, -1}, + {PERIPH_ID_PWM2, 24, 0, -1}, + {PERIPH_ID_PWM3, 24, 0, -1}, + {PERIPH_ID_PWM4, 24, 0, -1}, + + {PERIPH_ID_NONE, -1, -1, -1}, }; /* Epll Clock division values to achive different frequency output */ @@ -260,9 +263,24 @@ static unsigned long exynos5_get_pll_clk(int pllreg) return fout; } +static struct clk_bit_info *get_clk_bit_info(int peripheral) +{ + int i; + + for (i = 0; clk_bit_info[i].id != PERIPH_ID_NONE; i++) { + if (clk_bit_info[i].id == peripheral) + break; + } + + if (clk_bit_info[i].id == PERIPH_ID_NONE) + debug("ERROR: Peripheral ID %d not found\n", peripheral); + + return &clk_bit_info[i]; +} + static unsigned long exynos5_get_periph_rate(int peripheral) { - struct clk_bit_info *bit_info = &clk_bit_info[peripheral]; + struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); unsigned long sclk, sub_clk; unsigned int src, div, sub_div; struct exynos5_clock *clk = -- cgit From 325eb18c7762046b79978f1fe26aa678a7f7a349 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:00 +0530 Subject: Exynos542x: Move exynos5420_get_pll_clk up and rename Moving exynos5420_get_pll_clk function definition up in the code to keep it together with rest of SoC_get_pll_clk functions. This makes code more legible and also removes the need of declaration when called before the position of definition in code. Also, renaming exynos5420_get_pll_clk to exynos542x_get_pll_clk because it is being used for both Exynos 5420 and 5800. Signed-off-by: Akshay Saraswat Reviewed-by: Simon Glass Tested-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 251fc0e9d3..5257a485f8 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -263,6 +263,46 @@ static unsigned long exynos5_get_pll_clk(int pllreg) return fout; } +/* exynos542x: return pll clock frequency */ +static unsigned long exynos542x_get_pll_clk(int pllreg) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned long r, k = 0; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con0); + break; + case MPLL: + r = readl(&clk->mpll_con0); + break; + case EPLL: + r = readl(&clk->epll_con0); + k = readl(&clk->epll_con1); + break; + case VPLL: + r = readl(&clk->vpll_con0); + k = readl(&clk->vpll_con1); + break; + case BPLL: + r = readl(&clk->bpll_con0); + break; + case RPLL: + r = readl(&clk->rpll_con0); + k = readl(&clk->rpll_con1); + break; + case SPLL: + r = readl(&clk->spll_con0); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + return exynos_get_pll_clk(pllreg, r, k); +} + static struct clk_bit_info *get_clk_bit_info(int peripheral) { int i; @@ -382,46 +422,6 @@ unsigned long clock_get_periph_rate(int peripheral) return 0; } -/* exynos5420: return pll clock frequency */ -static unsigned long exynos5420_get_pll_clk(int pllreg) -{ - struct exynos5420_clock *clk = - (struct exynos5420_clock *)samsung_get_base_clock(); - unsigned long r, k = 0; - - switch (pllreg) { - case APLL: - r = readl(&clk->apll_con0); - break; - case MPLL: - r = readl(&clk->mpll_con0); - break; - case EPLL: - r = readl(&clk->epll_con0); - k = readl(&clk->epll_con1); - break; - case VPLL: - r = readl(&clk->vpll_con0); - k = readl(&clk->vpll_con1); - break; - case BPLL: - r = readl(&clk->bpll_con0); - break; - case RPLL: - r = readl(&clk->rpll_con0); - k = readl(&clk->rpll_con1); - break; - case SPLL: - r = readl(&clk->spll_con0); - break; - default: - printf("Unsupported PLL (%d)\n", pllreg); - return 0; - } - - return exynos_get_pll_clk(pllreg, r, k); -} - /* exynos4: return ARM clock frequency */ static unsigned long exynos4_get_arm_clk(void) { @@ -1603,7 +1603,7 @@ unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) { if (proid_is_exynos5420() || proid_is_exynos5800()) - return exynos5420_get_pll_clk(pllreg); + return exynos542x_get_pll_clk(pllreg); return exynos5_get_pll_clk(pllreg); } else { if (proid_is_exynos4412()) -- cgit From ecdfb4e9d2e2bd691e94ee8f96da2e8d7dc45e81 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:01 +0530 Subject: Exynos542x: Add and enable get_periph_rate support We planned to fetch peripheral rate through one generic API per peripheral. These generic peripheral functions are in turn expected to fetch apt values from a function refactored as per SoC versions. This patch adds support for fetching peripheral rates for Exynos5420 and Exynos5800. Signed-off-by: Akshay Saraswat Reviewed-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 153 +++++++++++++++++++++++++++++++-- arch/arm/include/asm/arch-exynos/clk.h | 4 + 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 5257a485f8..59d7dc87bd 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -27,7 +27,7 @@ struct clk_bit_info { }; /* periph_id src_bit div_bit prediv_bit */ -static struct clk_bit_info clk_bit_info[] = { +static struct clk_bit_info exynos5_bit_info[] = { {PERIPH_ID_UART0, 0, 0, -1}, {PERIPH_ID_UART1, 4, 4, -1}, {PERIPH_ID_UART2, 8, 8, -1}, @@ -61,6 +61,41 @@ static struct clk_bit_info clk_bit_info[] = { {PERIPH_ID_NONE, -1, -1, -1}, }; +static struct clk_bit_info exynos542x_bit_info[] = { + {PERIPH_ID_UART0, 4, 8, -1}, + {PERIPH_ID_UART1, 8, 12, -1}, + {PERIPH_ID_UART2, 12, 16, -1}, + {PERIPH_ID_UART3, 16, 20, -1}, + {PERIPH_ID_I2C0, -1, 8, -1}, + {PERIPH_ID_I2C1, -1, 8, -1}, + {PERIPH_ID_I2C2, -1, 8, -1}, + {PERIPH_ID_I2C3, -1, 8, -1}, + {PERIPH_ID_I2C4, -1, 8, -1}, + {PERIPH_ID_I2C5, -1, 8, -1}, + {PERIPH_ID_I2C6, -1, 8, -1}, + {PERIPH_ID_I2C7, -1, 8, -1}, + {PERIPH_ID_SPI0, 20, 20, 8}, + {PERIPH_ID_SPI1, 24, 24, 16}, + {PERIPH_ID_SPI2, 28, 28, 24}, + {PERIPH_ID_SDMMC0, 8, 0, -1}, + {PERIPH_ID_SDMMC1, 12, 10, -1}, + {PERIPH_ID_SDMMC2, 16, 20, -1}, + {PERIPH_ID_I2C8, -1, 8, -1}, + {PERIPH_ID_I2C9, -1, 8, -1}, + {PERIPH_ID_I2S0, 0, 0, 4}, + {PERIPH_ID_I2S1, 4, 12, 16}, + {PERIPH_ID_SPI3, 12, 16, 0}, + {PERIPH_ID_SPI4, 16, 20, 8}, + {PERIPH_ID_PWM0, 24, 28, -1}, + {PERIPH_ID_PWM1, 24, 28, -1}, + {PERIPH_ID_PWM2, 24, 28, -1}, + {PERIPH_ID_PWM3, 24, 28, -1}, + {PERIPH_ID_PWM4, 24, 28, -1}, + {PERIPH_ID_I2C10, -1, 8, -1}, + + {PERIPH_ID_NONE, -1, -1, -1}, +}; + /* Epll Clock division values to achive different frequency output */ static struct set_epll_con_val exynos5_epll_div[] = { { 192000000, 0, 48, 3, 1, 0 }, @@ -306,16 +341,22 @@ static unsigned long exynos542x_get_pll_clk(int pllreg) static struct clk_bit_info *get_clk_bit_info(int peripheral) { int i; + struct clk_bit_info *info; + + if (proid_is_exynos5420() || proid_is_exynos5800()) + info = exynos542x_bit_info; + else + info = exynos5_bit_info; - for (i = 0; clk_bit_info[i].id != PERIPH_ID_NONE; i++) { - if (clk_bit_info[i].id == peripheral) + for (i = 0; info[i].id != PERIPH_ID_NONE; i++) { + if (info[i].id == peripheral) break; } - if (clk_bit_info[i].id == PERIPH_ID_NONE) + if (info[i].id == PERIPH_ID_NONE) debug("ERROR: Peripheral ID %d not found\n", peripheral); - return &clk_bit_info[i]; + return &info[i]; } static unsigned long exynos5_get_periph_rate(int peripheral) @@ -414,12 +455,110 @@ static unsigned long exynos5_get_periph_rate(int peripheral) return sub_clk; } +static unsigned long exynos542x_get_periph_rate(int peripheral) +{ + struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); + unsigned long sclk, sub_clk = 0; + unsigned int src, div, sub_div = 0; + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + case PERIPH_ID_PWM0: + case PERIPH_ID_PWM1: + case PERIPH_ID_PWM2: + case PERIPH_ID_PWM3: + case PERIPH_ID_PWM4: + src = readl(&clk->src_peric0); + div = readl(&clk->div_peric0); + break; + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + case PERIPH_ID_SPI2: + src = readl(&clk->src_peric1); + div = readl(&clk->div_peric1); + sub_div = readl(&clk->div_peric4); + break; + case PERIPH_ID_SPI3: + case PERIPH_ID_SPI4: + src = readl(&clk->src_isp); + div = readl(&clk->div_isp1); + sub_div = readl(&clk->div_isp1); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + src = readl(&clk->src_fsys); + div = readl(&clk->div_fsys1); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + case PERIPH_ID_I2C8: + case PERIPH_ID_I2C9: + case PERIPH_ID_I2C10: + sclk = exynos542x_get_pll_clk(MPLL); + sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) + & 0x7) + 1; + return sclk / sub_div; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + }; + + if (bit_info->src_bit >= 0) + src = (src >> bit_info->src_bit) & 0xf; + + switch (src) { + case EXYNOS542X_SRC_MPLL: + sclk = exynos542x_get_pll_clk(MPLL); + break; + case EXYNOS542X_SRC_SPLL: + sclk = exynos542x_get_pll_clk(SPLL); + break; + case EXYNOS542X_SRC_EPLL: + sclk = exynos542x_get_pll_clk(EPLL); + break; + case EXYNOS542X_SRC_RPLL: + sclk = exynos542x_get_pll_clk(RPLL); + break; + default: + return 0; + } + + /* Ratio clock division for this peripheral */ + if (bit_info->div_bit >= 0) { + div = (div >> bit_info->div_bit) & 0xf; + sub_clk = sclk / (div + 1); + } + + if (bit_info->prediv_bit >= 0) { + sub_div = (sub_div >> bit_info->prediv_bit) & 0xff; + return sub_clk / (sub_div + 1); + } + + return sub_clk; +} + unsigned long clock_get_periph_rate(int peripheral) { - if (cpu_is_exynos5()) + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + return exynos542x_get_periph_rate(peripheral); return exynos5_get_periph_rate(peripheral); - else + } else { return 0; + } } /* exynos4: return ARM clock frequency */ diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h index db24dc0e89..2a17dfc6de 100644 --- a/arch/arm/include/asm/arch-exynos/clk.h +++ b/arch/arm/include/asm/arch-exynos/clk.h @@ -26,6 +26,10 @@ enum pll_src_bit { EXYNOS_SRC_MPLL = 6, EXYNOS_SRC_EPLL, EXYNOS_SRC_VPLL, + EXYNOS542X_SRC_MPLL = 3, + EXYNOS542X_SRC_SPLL, + EXYNOS542X_SRC_EPLL = 6, + EXYNOS542X_SRC_RPLL, }; unsigned long get_pll_clk(int pllreg); -- cgit From 9deff107468ac6d80db962470796e05c667c1077 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:02 +0530 Subject: Exynos5: Fix exynos5_get_periph_rate calculations exynos5_get_periph_rate function reads incorrect div for SDMMC2 & 3. It also reads prediv and does division only for SDMMC0 & 2 when actually various other peripherals need that. Adding changes to fix these mistakes in periph rate calculation. Signed-off-by: Akshay Saraswat Reviewed-by: Simon Glass Tested-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 59d7dc87bd..0153314b45 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -362,8 +362,8 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral) static unsigned long exynos5_get_periph_rate(int peripheral) { struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); - unsigned long sclk, sub_clk; - unsigned int src, div, sub_div; + unsigned long sclk, sub_clk = 0; + unsigned int src, div, sub_div = 0; struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); @@ -402,10 +402,13 @@ static unsigned long exynos5_get_periph_rate(int peripheral) break; case PERIPH_ID_SDMMC0: case PERIPH_ID_SDMMC1: + src = readl(&clk->src_fsys); + div = readl(&clk->div_fsys1); + break; case PERIPH_ID_SDMMC2: case PERIPH_ID_SDMMC3: src = readl(&clk->src_fsys); - div = readl(&clk->div_fsys1); + div = readl(&clk->div_fsys2); break; case PERIPH_ID_I2C0: case PERIPH_ID_I2C1: @@ -426,7 +429,8 @@ static unsigned long exynos5_get_periph_rate(int peripheral) return -1; }; - src = (src >> bit_info->src_bit) & 0xf; + if (bit_info->src_bit >= 0) + src = (src >> bit_info->src_bit) & 0xf; switch (src) { case EXYNOS_SRC_MPLL: @@ -443,11 +447,12 @@ static unsigned long exynos5_get_periph_rate(int peripheral) } /* Ratio clock division for this peripheral */ - sub_div = (div >> bit_info->div_bit) & 0xf; - sub_clk = sclk / (sub_div + 1); + if (bit_info->div_bit >= 0) { + sub_div = (div >> bit_info->div_bit) & 0xf; + sub_clk = sclk / (sub_div + 1); + } - /* Pre-ratio clock division for SDMMC0 and 2 */ - if (peripheral == PERIPH_ID_SDMMC0 || peripheral == PERIPH_ID_SDMMC2) { + if (bit_info->prediv_bit >= 0) { div = (div >> bit_info->prediv_bit) & 0xff; return sub_clk / (div + 1); } -- cgit From d95279685bb9690a6973226a3bd8a3bae65c2ad7 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:03 +0530 Subject: Exynos5: Use clock_get_periph_rate generic API Replacing SoC and peripheral specific function calls with generic clock_get_periph_rate calls to get the peripheral clocks. Also, removing dead code of peripheral and SoC specific function implementations which was used earlier for fetching peripheral clocks. This code is not being used anymore because of the introduction of generic clock_get_periph_rate function. Signed-off-by: Akshay Saraswat Reviewed-by: Simon Glass Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 278 ++++++-------------------------------- 1 file changed, 43 insertions(+), 235 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 0153314b45..4fa1e23122 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -689,27 +689,6 @@ static unsigned long exynos4x12_get_pwm_clk(void) return pclk; } -/* exynos5420: return pwm clock frequency */ -static unsigned long exynos5420_get_pwm_clk(void) -{ - struct exynos5420_clock *clk = - (struct exynos5420_clock *)samsung_get_base_clock(); - unsigned long pclk, sclk; - unsigned int ratio; - - /* - * CLK_DIV_PERIC0 - * PWM_RATIO [31:28] - */ - ratio = readl(&clk->div_peric0); - ratio = (ratio >> 28) & 0xf; - sclk = get_pll_clk(MPLL); - - pclk = sclk / (ratio + 1); - - return pclk; -} - /* exynos4: return uart clock frequency */ static unsigned long exynos4_get_uart_clk(int dev_index) { @@ -802,100 +781,6 @@ static unsigned long exynos4x12_get_uart_clk(int dev_index) return uclk; } -/* exynos5: return uart clock frequency */ -static unsigned long exynos5_get_uart_clk(int dev_index) -{ - struct exynos5_clock *clk = - (struct exynos5_clock *)samsung_get_base_clock(); - unsigned long uclk, sclk; - unsigned int sel; - unsigned int ratio; - - /* - * CLK_SRC_PERIC0 - * UART0_SEL [3:0] - * UART1_SEL [7:4] - * UART2_SEL [8:11] - * UART3_SEL [12:15] - * UART4_SEL [16:19] - * UART5_SEL [23:20] - */ - sel = readl(&clk->src_peric0); - sel = (sel >> (dev_index << 2)) & 0xf; - - if (sel == 0x6) - sclk = get_pll_clk(MPLL); - else if (sel == 0x7) - sclk = get_pll_clk(EPLL); - else if (sel == 0x8) - sclk = get_pll_clk(VPLL); - else - return 0; - - /* - * CLK_DIV_PERIC0 - * UART0_RATIO [3:0] - * UART1_RATIO [7:4] - * UART2_RATIO [8:11] - * UART3_RATIO [12:15] - * UART4_RATIO [16:19] - * UART5_RATIO [23:20] - */ - ratio = readl(&clk->div_peric0); - ratio = (ratio >> (dev_index << 2)) & 0xf; - - uclk = sclk / (ratio + 1); - - return uclk; -} - -/* exynos5420: return uart clock frequency */ -static unsigned long exynos5420_get_uart_clk(int dev_index) -{ - struct exynos5420_clock *clk = - (struct exynos5420_clock *)samsung_get_base_clock(); - unsigned long uclk, sclk; - unsigned int sel; - unsigned int ratio; - - /* - * CLK_SRC_PERIC0 - * UART0_SEL [6:4] - * UART1_SEL [10:8] - * UART2_SEL [14:12] - * UART3_SEL [18:16] - * generalised calculation as follows - * sel = (sel >> ((dev_index * 4) + 4)) & mask; - */ - sel = readl(&clk->src_peric0); - sel = (sel >> ((dev_index * 4) + 4)) & 0x7; - - if (sel == 0x3) - sclk = get_pll_clk(MPLL); - else if (sel == 0x6) - sclk = get_pll_clk(EPLL); - else if (sel == 0x7) - sclk = get_pll_clk(RPLL); - else - return 0; - - /* - * CLK_DIV_PERIC0 - * UART0_RATIO [11:8] - * UART1_RATIO [15:12] - * UART2_RATIO [19:16] - * UART3_RATIO [23:20] - * generalised calculation as follows - * ratio = (ratio >> ((dev_index * 4) + 8)) & mask; - */ - ratio = readl(&clk->div_peric0); - ratio = (ratio >> ((dev_index * 4) + 8)) & 0xf; - - uclk = sclk / (ratio + 1); - - return uclk; -} - static unsigned long exynos4_get_mmc_clk(int dev_index) { struct exynos4_clock *clk = @@ -945,94 +830,6 @@ static unsigned long exynos4_get_mmc_clk(int dev_index) return uclk; } -static unsigned long exynos5_get_mmc_clk(int dev_index) -{ - struct exynos5_clock *clk = - (struct exynos5_clock *)samsung_get_base_clock(); - unsigned long uclk, sclk; - unsigned int sel, ratio, pre_ratio; - int shift = 0; - - sel = readl(&clk->src_fsys); - sel = (sel >> (dev_index << 2)) & 0xf; - - if (sel == 0x6) - sclk = get_pll_clk(MPLL); - else if (sel == 0x7) - sclk = get_pll_clk(EPLL); - else if (sel == 0x8) - sclk = get_pll_clk(VPLL); - else - return 0; - - switch (dev_index) { - case 0: - case 1: - ratio = readl(&clk->div_fsys1); - pre_ratio = readl(&clk->div_fsys1); - break; - case 2: - case 3: - ratio = readl(&clk->div_fsys2); - pre_ratio = readl(&clk->div_fsys2); - break; - default: - return 0; - } - - if (dev_index == 1 || dev_index == 3) - shift = 16; - - ratio = (ratio >> shift) & 0xf; - pre_ratio = (pre_ratio >> (shift + 8)) & 0xff; - uclk = (sclk / (ratio + 1)) / (pre_ratio + 1); - - return uclk; -} - -static unsigned long exynos5420_get_mmc_clk(int dev_index) -{ - struct exynos5420_clock *clk = - (struct exynos5420_clock *)samsung_get_base_clock(); - unsigned long uclk, sclk; - unsigned int sel, ratio; - - /* - * CLK_SRC_FSYS - * MMC0_SEL [10:8] - * MMC1_SEL [14:12] - * MMC2_SEL [18:16] - * generalised calculation as follows - * sel = (sel >> ((dev_index * 4) + 8)) & mask - */ - sel = readl(&clk->src_fsys); - sel = (sel >> ((dev_index * 4) + 8)) & 0x7; - - if (sel == 0x3) - sclk = get_pll_clk(MPLL); - else if (sel == 0x4) - sclk = get_pll_clk(SPLL); - else if (sel == 0x6) - sclk = get_pll_clk(EPLL); - else - return 0; - - /* - * CLK_DIV_FSYS1 - * MMC0_RATIO [9:0] - * MMC1_RATIO [19:10] - * MMC2_RATIO [29:20] - * generalised calculation as follows - * ratio = (ratio >> (dev_index * 10)) & mask - */ - ratio = readl(&clk->div_fsys1); - ratio = (ratio >> (dev_index * 10)) & 0x3ff; - - uclk = (sclk / (ratio + 1)); - - return uclk; -} - /* exynos4: set the mmc clock */ static void exynos4_set_mmc_clk(int dev_index, unsigned int div) { @@ -1411,29 +1208,6 @@ void exynos4_set_mipi_clk(void) clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16); } -/* - * I2C - * - * exynos5: obtaining the I2C clock - */ -static unsigned long exynos5_get_i2c_clk(void) -{ - struct exynos5_clock *clk = - (struct exynos5_clock *)samsung_get_base_clock(); - unsigned long aclk_66, aclk_66_pre, sclk; - unsigned int ratio; - - sclk = get_pll_clk(MPLL); - - ratio = (readl(&clk->div_top1)) >> 24; - ratio &= 0x7; - aclk_66_pre = sclk / (ratio + 1); - ratio = readl(&clk->div_top0); - ratio &= 0x7; - aclk_66 = aclk_66_pre / (ratio + 1); - return aclk_66; -} - int exynos5_set_epll_clk(unsigned long rate) { unsigned int epll_con, epll_con_k; @@ -1770,7 +1544,7 @@ unsigned long get_arm_clk(void) unsigned long get_i2c_clk(void) { if (cpu_is_exynos5()) { - return exynos5_get_i2c_clk(); + return clock_get_periph_rate(PERIPH_ID_I2C0); } else if (cpu_is_exynos4()) { return exynos4_get_i2c_clk(); } else { @@ -1782,8 +1556,6 @@ unsigned long get_i2c_clk(void) unsigned long get_pwm_clk(void) { if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5800()) - return exynos5420_get_pwm_clk(); return clock_get_periph_rate(PERIPH_ID_PWM0); } else { if (proid_is_exynos4412()) @@ -1794,10 +1566,28 @@ unsigned long get_pwm_clk(void) unsigned long get_uart_clk(int dev_index) { + enum periph_id id; + + switch (dev_index) { + case 0: + id = PERIPH_ID_UART0; + break; + case 1: + id = PERIPH_ID_UART1; + break; + case 2: + id = PERIPH_ID_UART2; + break; + case 3: + id = PERIPH_ID_UART3; + break; + default: + debug("%s: invalid UART index %d", __func__, dev_index); + return -1; + } + if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5800()) - return exynos5420_get_uart_clk(dev_index); - return exynos5_get_uart_clk(dev_index); + return clock_get_periph_rate(id); } else { if (proid_is_exynos4412()) return exynos4x12_get_uart_clk(dev_index); @@ -1807,10 +1597,28 @@ unsigned long get_uart_clk(int dev_index) unsigned long get_mmc_clk(int dev_index) { + enum periph_id id; + + switch (dev_index) { + case 0: + id = PERIPH_ID_SDMMC0; + break; + case 1: + id = PERIPH_ID_SDMMC1; + break; + case 2: + id = PERIPH_ID_SDMMC2; + break; + case 3: + id = PERIPH_ID_SDMMC3; + break; + default: + debug("%s: invalid MMC index %d", __func__, dev_index); + return -1; + } + if (cpu_is_exynos5()) { - if (proid_is_exynos5420() || proid_is_exynos5800()) - return exynos5420_get_mmc_clk(dev_index); - return exynos5_get_mmc_clk(dev_index); + return clock_get_periph_rate(id); } else { return exynos4_get_mmc_clk(dev_index); } -- cgit From c5d32170bb98032781be0537ce56159fa52ade97 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:04 +0530 Subject: Exynos: clock: change mask bits as per peripheral We have assumed and kept mask bits for divider and pre-divider as 0xf and 0xff, respectively. But these mask bits change from one peripheral to another, and hence, need to be specified in accordance with the peripherals. Signed-off-by: Akshay Saraswat Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 151 ++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 4fa1e23122..83e5b18d6b 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -21,79 +21,83 @@ */ struct clk_bit_info { enum periph_id id; + int32_t src_mask; + int32_t div_mask; + int32_t prediv_mask; int8_t src_bit; int8_t div_bit; int8_t prediv_bit; }; -/* periph_id src_bit div_bit prediv_bit */ static struct clk_bit_info exynos5_bit_info[] = { - {PERIPH_ID_UART0, 0, 0, -1}, - {PERIPH_ID_UART1, 4, 4, -1}, - {PERIPH_ID_UART2, 8, 8, -1}, - {PERIPH_ID_UART3, 12, 12, -1}, - {PERIPH_ID_I2C0, -1, 24, 0}, - {PERIPH_ID_I2C1, -1, 24, 0}, - {PERIPH_ID_I2C2, -1, 24, 0}, - {PERIPH_ID_I2C3, -1, 24, 0}, - {PERIPH_ID_I2C4, -1, 24, 0}, - {PERIPH_ID_I2C5, -1, 24, 0}, - {PERIPH_ID_I2C6, -1, 24, 0}, - {PERIPH_ID_I2C7, -1, 24, 0}, - {PERIPH_ID_SPI0, 16, 0, 8}, - {PERIPH_ID_SPI1, 20, 16, 24}, - {PERIPH_ID_SPI2, 24, 0, 8}, - {PERIPH_ID_SDMMC0, 0, 0, 8}, - {PERIPH_ID_SDMMC1, 4, 16, 24}, - {PERIPH_ID_SDMMC2, 8, 0, 8}, - {PERIPH_ID_SDMMC3, 12, 16, 24}, - {PERIPH_ID_I2S0, 0, 0, 4}, - {PERIPH_ID_I2S1, 4, 12, 16}, - {PERIPH_ID_SPI3, 0, 0, 4}, - {PERIPH_ID_SPI4, 4, 12, 16}, - {PERIPH_ID_SDMMC4, 16, 0, 8}, - {PERIPH_ID_PWM0, 24, 0, -1}, - {PERIPH_ID_PWM1, 24, 0, -1}, - {PERIPH_ID_PWM2, 24, 0, -1}, - {PERIPH_ID_PWM3, 24, 0, -1}, - {PERIPH_ID_PWM4, 24, 0, -1}, - - {PERIPH_ID_NONE, -1, -1, -1}, + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ + {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1}, + {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1}, + {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1}, + {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1}, + {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8}, + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24}, + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8}, + {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8}, + {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24}, + {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8}, + {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24}, + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8}, + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1}, + + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, }; static struct clk_bit_info exynos542x_bit_info[] = { - {PERIPH_ID_UART0, 4, 8, -1}, - {PERIPH_ID_UART1, 8, 12, -1}, - {PERIPH_ID_UART2, 12, 16, -1}, - {PERIPH_ID_UART3, 16, 20, -1}, - {PERIPH_ID_I2C0, -1, 8, -1}, - {PERIPH_ID_I2C1, -1, 8, -1}, - {PERIPH_ID_I2C2, -1, 8, -1}, - {PERIPH_ID_I2C3, -1, 8, -1}, - {PERIPH_ID_I2C4, -1, 8, -1}, - {PERIPH_ID_I2C5, -1, 8, -1}, - {PERIPH_ID_I2C6, -1, 8, -1}, - {PERIPH_ID_I2C7, -1, 8, -1}, - {PERIPH_ID_SPI0, 20, 20, 8}, - {PERIPH_ID_SPI1, 24, 24, 16}, - {PERIPH_ID_SPI2, 28, 28, 24}, - {PERIPH_ID_SDMMC0, 8, 0, -1}, - {PERIPH_ID_SDMMC1, 12, 10, -1}, - {PERIPH_ID_SDMMC2, 16, 20, -1}, - {PERIPH_ID_I2C8, -1, 8, -1}, - {PERIPH_ID_I2C9, -1, 8, -1}, - {PERIPH_ID_I2S0, 0, 0, 4}, - {PERIPH_ID_I2S1, 4, 12, 16}, - {PERIPH_ID_SPI3, 12, 16, 0}, - {PERIPH_ID_SPI4, 16, 20, 8}, - {PERIPH_ID_PWM0, 24, 28, -1}, - {PERIPH_ID_PWM1, 24, 28, -1}, - {PERIPH_ID_PWM2, 24, 28, -1}, - {PERIPH_ID_PWM3, 24, 28, -1}, - {PERIPH_ID_PWM4, 24, 28, -1}, - {PERIPH_ID_I2C10, -1, 8, -1}, - - {PERIPH_ID_NONE, -1, -1, -1}, + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ + {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1}, + {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1}, + {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1}, + {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1}, + {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8}, + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16}, + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24}, + {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1}, + {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1}, + {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1}, + {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0}, + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8}, + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1}, + + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, }; /* Epll Clock division values to achive different frequency output */ @@ -420,9 +424,9 @@ static unsigned long exynos5_get_periph_rate(int peripheral) case PERIPH_ID_I2C7: sclk = exynos5_get_pll_clk(MPLL); sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) - & 0x7) + 1; + & bit_info->div_mask) + 1; div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) - & 0x7) + 1; + & bit_info->prediv_mask) + 1; return (sclk / sub_div) / div; default: debug("%s: invalid peripheral %d", __func__, peripheral); @@ -430,7 +434,7 @@ static unsigned long exynos5_get_periph_rate(int peripheral) }; if (bit_info->src_bit >= 0) - src = (src >> bit_info->src_bit) & 0xf; + src = (src >> bit_info->src_bit) & bit_info->src_mask; switch (src) { case EXYNOS_SRC_MPLL: @@ -448,12 +452,12 @@ static unsigned long exynos5_get_periph_rate(int peripheral) /* Ratio clock division for this peripheral */ if (bit_info->div_bit >= 0) { - sub_div = (div >> bit_info->div_bit) & 0xf; + sub_div = (div >> bit_info->div_bit) & bit_info->div_mask; sub_clk = sclk / (sub_div + 1); } if (bit_info->prediv_bit >= 0) { - div = (div >> bit_info->prediv_bit) & 0xff; + div = (div >> bit_info->prediv_bit) & bit_info->prediv_mask; return sub_clk / (div + 1); } @@ -514,7 +518,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) case PERIPH_ID_I2C10: sclk = exynos542x_get_pll_clk(MPLL); sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) - & 0x7) + 1; + & bit_info->div_mask) + 1; return sclk / sub_div; default: debug("%s: invalid peripheral %d", __func__, peripheral); @@ -522,7 +526,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) }; if (bit_info->src_bit >= 0) - src = (src >> bit_info->src_bit) & 0xf; + src = (src >> bit_info->src_bit) & bit_info->src_mask; switch (src) { case EXYNOS542X_SRC_MPLL: @@ -543,12 +547,13 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) /* Ratio clock division for this peripheral */ if (bit_info->div_bit >= 0) { - div = (div >> bit_info->div_bit) & 0xf; + div = (div >> bit_info->div_bit) & bit_info->div_mask; sub_clk = sclk / (div + 1); } if (bit_info->prediv_bit >= 0) { - sub_div = (sub_div >> bit_info->prediv_bit) & 0xff; + sub_div = (sub_div >> bit_info->prediv_bit) + & bit_info->prediv_mask; return sub_clk / (sub_div + 1); } -- cgit From 2e82e9252695a612ab0cbf40fa0c7368515f6506 Mon Sep 17 00:00:00 2001 From: Akshay Saraswat Date: Wed, 4 Feb 2015 16:00:05 +0530 Subject: Exynos: Clock: Cleanup soc_get_periph_rate Since we have src, div and pre-div mask bits defined corresponding to peripherals, calculation of clock specific to I2C appears redundant and confusing. Using clk_bit_info struct we can write calculations generic to all peripherals which makes code easy to understand and free from peripheral specific exceptions. Signed-off-by: Akshay Saraswat Signed-off-by: Minkyu Kang --- arch/arm/cpu/armv7/exynos/clock.c | 74 ++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 83e5b18d6b..c6455c2f3c 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -366,8 +366,8 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral) static unsigned long exynos5_get_periph_rate(int peripheral) { struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); - unsigned long sclk, sub_clk = 0; - unsigned int src, div, sub_div = 0; + unsigned long sclk = 0; + unsigned int src = 0, div = 0, sub_div = 0; struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); @@ -389,30 +389,30 @@ static unsigned long exynos5_get_periph_rate(int peripheral) break; case PERIPH_ID_I2S0: src = readl(&clk->src_mau); - div = readl(&clk->div_mau); + div = sub_div = readl(&clk->div_mau); case PERIPH_ID_SPI0: case PERIPH_ID_SPI1: src = readl(&clk->src_peric1); - div = readl(&clk->div_peric1); + div = sub_div = readl(&clk->div_peric1); break; case PERIPH_ID_SPI2: src = readl(&clk->src_peric1); - div = readl(&clk->div_peric2); + div = sub_div = readl(&clk->div_peric2); break; case PERIPH_ID_SPI3: case PERIPH_ID_SPI4: src = readl(&clk->sclk_src_isp); - div = readl(&clk->sclk_div_isp); + div = sub_div = readl(&clk->sclk_div_isp); break; case PERIPH_ID_SDMMC0: case PERIPH_ID_SDMMC1: src = readl(&clk->src_fsys); - div = readl(&clk->div_fsys1); + div = sub_div = readl(&clk->div_fsys1); break; case PERIPH_ID_SDMMC2: case PERIPH_ID_SDMMC3: src = readl(&clk->src_fsys); - div = readl(&clk->div_fsys2); + div = sub_div = readl(&clk->div_fsys2); break; case PERIPH_ID_I2C0: case PERIPH_ID_I2C1: @@ -422,12 +422,10 @@ static unsigned long exynos5_get_periph_rate(int peripheral) case PERIPH_ID_I2C5: case PERIPH_ID_I2C6: case PERIPH_ID_I2C7: - sclk = exynos5_get_pll_clk(MPLL); - sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) - & bit_info->div_mask) + 1; - div = ((readl(&clk->div_top0) >> bit_info->prediv_bit) - & bit_info->prediv_mask) + 1; - return (sclk / sub_div) / div; + src = EXYNOS_SRC_MPLL; + div = readl(&clk->div_top0); + sub_div = readl(&clk->div_top1); + break; default: debug("%s: invalid peripheral %d", __func__, peripheral); return -1; @@ -447,28 +445,28 @@ static unsigned long exynos5_get_periph_rate(int peripheral) sclk = exynos5_get_pll_clk(VPLL); break; default: + debug("%s: EXYNOS_SRC %d not supported\n", __func__, src); return 0; } - /* Ratio clock division for this peripheral */ - if (bit_info->div_bit >= 0) { - sub_div = (div >> bit_info->div_bit) & bit_info->div_mask; - sub_clk = sclk / (sub_div + 1); - } + /* Clock divider ratio for this peripheral */ + if (bit_info->div_bit >= 0) + div = (div >> bit_info->div_bit) & bit_info->div_mask; - if (bit_info->prediv_bit >= 0) { - div = (div >> bit_info->prediv_bit) & bit_info->prediv_mask; - return sub_clk / (div + 1); - } + /* Clock pre-divider ratio for this peripheral */ + if (bit_info->prediv_bit >= 0) + sub_div = (sub_div >> bit_info->prediv_bit) + & bit_info->prediv_mask; - return sub_clk; + /* Calculate and return required clock rate */ + return (sclk / (div + 1)) / (sub_div + 1); } static unsigned long exynos542x_get_periph_rate(int peripheral) { struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); - unsigned long sclk, sub_clk = 0; - unsigned int src, div, sub_div = 0; + unsigned long sclk = 0; + unsigned int src = 0, div = 0, sub_div = 0; struct exynos5420_clock *clk = (struct exynos5420_clock *)samsung_get_base_clock(); @@ -516,10 +514,9 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) case PERIPH_ID_I2C8: case PERIPH_ID_I2C9: case PERIPH_ID_I2C10: - sclk = exynos542x_get_pll_clk(MPLL); - sub_div = ((readl(&clk->div_top1) >> bit_info->div_bit) - & bit_info->div_mask) + 1; - return sclk / sub_div; + src = EXYNOS542X_SRC_MPLL; + div = readl(&clk->div_top1); + break; default: debug("%s: invalid peripheral %d", __func__, peripheral); return -1; @@ -542,22 +539,21 @@ static unsigned long exynos542x_get_periph_rate(int peripheral) sclk = exynos542x_get_pll_clk(RPLL); break; default: + debug("%s: EXYNOS542X_SRC %d not supported", __func__, src); return 0; } - /* Ratio clock division for this peripheral */ - if (bit_info->div_bit >= 0) { + /* Clock divider ratio for this peripheral */ + if (bit_info->div_bit >= 0) div = (div >> bit_info->div_bit) & bit_info->div_mask; - sub_clk = sclk / (div + 1); - } - if (bit_info->prediv_bit >= 0) { + /* Clock pre-divider ratio for this peripheral */ + if (bit_info->prediv_bit >= 0) sub_div = (sub_div >> bit_info->prediv_bit) - & bit_info->prediv_mask; - return sub_clk / (sub_div + 1); - } + & bit_info->prediv_mask; - return sub_clk; + /* Calculate and return required clock rate */ + return (sclk / (div + 1)) / (sub_div + 1); } unsigned long clock_get_periph_rate(int peripheral) -- cgit From 1ae067952d509893bee7c267be954d45ab49f9dc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 9 Feb 2015 13:41:30 -0700 Subject: dm: stv0991: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- configs/stv0991_defconfig | 2 ++ include/configs/stv0991.h | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig index 37b10ba893..1c9ba881a4 100644 --- a/configs/stv0991_defconfig +++ b/configs/stv0991_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_STV0991=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_DM=y +CONFIG_DM_SERIAL=y diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h index 071b1c2ca7..156e0fa8e1 100644 --- a/include/configs/stv0991.h +++ b/include/configs/stv0991.h @@ -29,19 +29,9 @@ #define CONFIG_SYS_MAXARGS 16 #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 16 * 1024) -#define CONFIG_DM /* serial port (PL011) configuration */ #define CONFIG_BAUDRATE 115200 -#ifdef CONFIG_DM -#define CONFIG_DM_SERIAL #define CONFIG_PL01X_SERIAL -#else -#define CONFIG_SYS_SERIAL0 0x80406000 -#define CONFIG_CONS_INDEX 0 -#define CONFIG_PL011_SERIAL -#define CONFIG_PL01x_PORTS {(void *)CONFIG_SYS_SERIAL0} -#define CONFIG_PL011_CLOCK (2700 * 1000) -#endif /* user interface */ #define CONFIG_SYS_PROMPT "STV0991> " -- cgit From b1f6659c420dae9cd06514fbd8342f39b3f326b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 9 Feb 2015 13:41:31 -0700 Subject: dm: mx6: sabre: Move driver model CONFIGs to Kconfig Remove driver model CONFIGs from the board config headers and use Kconfig instead. Signed-off-by: Simon Glass --- configs/mx6dlsabreauto_defconfig | 2 ++ configs/mx6dlsabresd_defconfig | 2 ++ configs/mx6qsabreauto_defconfig | 2 ++ configs/mx6qsabrelite_defconfig | 2 ++ configs/mx6qsabresd_defconfig | 2 ++ configs/mx6sabresd_spl_defconfig | 3 ++- include/configs/mx6sabre_common.h | 2 -- 7 files changed, 12 insertions(+), 3 deletions(-) diff --git a/configs/mx6dlsabreauto_defconfig b/configs/mx6dlsabreauto_defconfig index ccdfe31992..47f3f871ec 100644 --- a/configs/mx6dlsabreauto_defconfig +++ b/configs/mx6dlsabreauto_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6dlsabresd_defconfig b/configs/mx6dlsabresd_defconfig index 7f6cdff384..6adfd55708 100644 --- a/configs/mx6dlsabresd_defconfig +++ b/configs/mx6dlsabresd_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6dlsabresd.cfg,MX6DL" CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6qsabreauto_defconfig b/configs/mx6qsabreauto_defconfig index fe3d797851..ab72942ad5 100644 --- a/configs/mx6qsabreauto_defconfig +++ b/configs/mx6qsabreauto_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_MX6QSABREAUTO=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6qsabrelite_defconfig b/configs/mx6qsabrelite_defconfig index dfa9c2e4db..50b75aee20 100644 --- a/configs/mx6qsabrelite_defconfig +++ b/configs/mx6qsabrelite_defconfig @@ -1,3 +1,5 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024,SABRELITE" CONFIG_ARM=y CONFIG_TARGET_NITROGEN6X=y +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6qsabresd_defconfig b/configs/mx6qsabresd_defconfig index 09b01905e6..112918b1bb 100644 --- a/configs/mx6qsabresd_defconfig +++ b/configs/mx6qsabresd_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_MX6SABRESD=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6sabresd_spl_defconfig b/configs/mx6sabresd_spl_defconfig index 12e784435c..67079ba0cf 100644 --- a/configs/mx6sabresd_spl_defconfig +++ b/configs/mx6sabresd_spl_defconfig @@ -2,4 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6Q" +S:CONFIG_ARM=y +S:CONFIG_TARGET_MX6SABRESD=y - +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h index 80e48d141e..4aa8101524 100644 --- a/include/configs/mx6sabre_common.h +++ b/include/configs/mx6sabre_common.h @@ -25,8 +25,6 @@ #define CONFIG_INITRD_TAG #define CONFIG_REVISION_TAG -#define CONFIG_DM -#define CONFIG_DM_THERMAL #define CONFIG_IMX6_THERMAL #define CONFIG_SYS_GENERIC_BOARD -- cgit From 71edbe5cdaf1516f070cf6c0910910b3240b0bf5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 29 Jan 2015 11:35:16 -0700 Subject: buildman: Fix incorrect arguemnt in GetUpstream() This causes an error when trying to build a local branch which has a local branch as its upstream. Signed-off-by: Simon Glass Reported-by: Masahiro Yamada --- tools/patman/gitutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index c593070d67..4c2c35bf9a 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -129,7 +129,7 @@ def GetUpstream(git_dir, branch): return upstream, msg if remote == '.': - return merge + return merge, None elif remote and merge: leaf = merge.split('/')[-1] return '%s/%s' % (remote, leaf), None -- cgit From 8895b3e16c7a2aab4275d52be19e485605dc5c7b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 29 Jan 2015 11:35:17 -0700 Subject: patman: Read in the git-mailrc alias file We should read this file to obtain a set of aliases. This reduces the need to create them in the ~/.patman file. This feature did exist in some version of patman, and is mentioned in the help but it did not find its way upstream. Reported-by: Graeme Russ Signed-off-by: Simon Glass --- tools/patman/settings.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 122e8fd981..ba2a68ff63 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -235,6 +235,31 @@ def _UpdateDefaults(parser, config): else: print "WARNING: Unknown setting %s" % name +def _ReadAliasFile(fname): + """Read in the U-Boot git alias file if it exists. + + Args: + fname: Filename to read. + """ + if os.path.exists(fname): + bad_line = None + with open(fname) as fd: + linenum = 0 + for line in fd: + linenum += 1 + line = line.strip() + if not line or line.startswith('#'): + continue + words = line.split(' ', 2) + if len(words) < 3 or words[0] != 'alias': + if not bad_line: + bad_line = "%s:%d:Invalid line '%s'" % (fname, linenum, + line) + continue + alias[words[1]] = [s.strip() for s in words[2].split(',')] + if bad_line: + print bad_line + def Setup(parser, project_name, config_fname=''): """Set up the settings module by reading config files. @@ -244,6 +269,8 @@ def Setup(parser, project_name, config_fname=''): for sections named "project_section" as well. config_fname: Config filename to read ('' for default) """ + # First read the git alias file if available + _ReadAliasFile('doc/git-mailrc') config = _ProjectConfigParser(project_name) if config_fname == '': config_fname = '%s/.patman' % os.getenv('HOME') -- cgit From d908898333b22fb2345a7a165ff837fa6b947b0b Mon Sep 17 00:00:00 2001 From: Albert ARIBAUD Date: Sun, 1 Feb 2015 00:12:44 +0100 Subject: buildman: allow multiple toolchains in a single path When buildman scans a toolchain path, it stops at the first toolchain found. However, a single path can contains several toolchains, each with its own prefix. This patch lets buildman scan all toolchains in the path. Signed-off-by: Albert ARIBAUD Acked-by: Simon Glass --- tools/buildman/toolchain.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index d4c5d4a11e..537797ad53 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -197,13 +197,14 @@ class Toolchains: Returns: Filename of C compiler if found, else None """ + fnames = [] for subdir in ['.', 'bin', 'usr/bin']: dirname = os.path.join(path, subdir) if verbose: print " - looking in '%s'" % dirname for fname in glob.glob(dirname + '/*gcc'): if verbose: print " - found '%s'" % fname - return fname - return None + fnames.append(fname) + return fnames def Scan(self, verbose): @@ -219,8 +220,8 @@ class Toolchains: if verbose: print 'Scanning for tool chains' for path in self.paths: if verbose: print " - scanning path '%s'" % path - fname = self.ScanPath(path, verbose) - if fname: + fnames = self.ScanPath(path, verbose) + for fname in fnames: self.Add(fname, True, verbose) def List(self): -- cgit From 88539e4431cd6a596da316f81b644c4df606dbd9 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 6 Feb 2015 15:37:31 -0600 Subject: sandbox: Return '-c command' exit value as sandbox exit code When a command is passed into sandbox using the '-c' argument the command is run directly. This is most helpful when running tests (such as test-dm.sh). Previously the exit code was an unused enum. Change it to be the actual return code from the command so that the script calling sandbox can know if the command succeeded (tests passed). Also remove the now completely unused "exit_state" in sandbox. Signed-off-by: Joe Hershberger Acked-by: Simon Glass --- arch/sandbox/cpu/start.c | 6 ++++-- arch/sandbox/cpu/state.c | 5 ----- arch/sandbox/include/asm/state.h | 15 --------------- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 097f29a290..ec010402d7 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -78,11 +78,13 @@ int sandbox_main_loop_init(void) /* Execute command if required */ if (state->cmd) { + int retval; + cli_init(); - run_command_list(state->cmd, -1, 0); + retval = run_command_list(state->cmd, -1, 0); if (!state->interactive) - os_exit(state->exit_type); + os_exit(retval); } return 0; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index ba73b7e251..033958ce74 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -13,11 +13,6 @@ static struct sandbox_state main_state; static struct sandbox_state *state; /* Pointer to current state record */ -void state_record_exit(enum exit_type_id exit_type) -{ - state->exit_type = exit_type; -} - static int state_ensure_space(int extra_size) { void *blob = state->state_fdt; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 32d55ccc4c..a0c24ba1e0 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -10,13 +10,6 @@ #include #include -/* How we exited U-Boot */ -enum exit_type_id { - STATE_EXIT_NORMAL, - STATE_EXIT_COLD_REBOOT, - STATE_EXIT_POWER_OFF, -}; - /** * Selects the behavior of the serial terminal. * @@ -50,7 +43,6 @@ struct sandbox_state { const char *cmd; /* Command to execute */ bool interactive; /* Enable cmdline after execute */ const char *fdt_fname; /* Filename of FDT binary */ - enum exit_type_id exit_type; /* How we exited U-Boot */ const char *parse_err; /* Error to report from parsing */ int argc; /* Program arguments */ char **argv; /* Command line arguments */ @@ -138,13 +130,6 @@ struct sandbox_state_io { .compat = _compat, \ } -/** - * Record the exit type to be reported by the test program. - * - * @param exit_type Exit type to record - */ -void state_record_exit(enum exit_type_id exit_type); - /** * Gets a pointer to the current state. * -- cgit From e50ab22984ce90ffcc47bc620ed2caac0bcc02f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 10 Feb 2015 18:52:35 -0700 Subject: sandbox: Adjust the order of the NO_SDL check An option is provided to avoid using SDL in U-Boot sandbox (and drop support for the LCD). However the check in the Makefile is too late and warnings are printed even if NO_SDL=y is given. Adjust the order to avoid this warning. Signed-off-by: Simon Glass Acked-by: Jeroen Hofstee --- arch/sandbox/config.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index e38a44bd11..7b84f02a0a 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -5,10 +5,16 @@ PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD PLATFORM_LIBS += -lrt +# Define this to avoid linking with SDL, which requires SDL libraries +# This can solve 'sdl-config: Command not found' errors +ifneq ($(NO_SDL),) +PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL +else ifdef CONFIG_SANDBOX_SDL PLATFORM_LIBS += $(shell sdl-config --libs) PLATFORM_CPPFLAGS += $(shell sdl-config --cflags) endif +endif # Support generic board on sandbox __HAVE_ARCH_GENERIC_BOARD := y @@ -18,9 +24,3 @@ cmd_u-boot__ = $(CC) -o $@ -T u-boot.lds \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map CONFIG_ARCH_DEVICE_TREE := sandbox - -# Define this to avoid linking with SDL, which requires SDL libraries -# This can solve 'sdl-config: Command not found' errors -ifneq ($(NO_SDL),) -PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL -endif -- cgit From 43730ba72c176ffc4d9858249475f458203d9757 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 13 Feb 2015 18:45:57 +0100 Subject: lsxl: add a README file The README describes the recovery method which can be used if the NAS box is not reachable anymore. Addionally, it describes the different boot scripts. Signed-off-by: Michael Walle --- board/buffalo/lsxl/README | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 board/buffalo/lsxl/README diff --git a/board/buffalo/lsxl/README b/board/buffalo/lsxl/README new file mode 100644 index 0000000000..ef5ed42880 --- /dev/null +++ b/board/buffalo/lsxl/README @@ -0,0 +1,139 @@ +Intro +----- +The Buffalo Linkstation Pro/Live, codename LS-XHL and LS-CHLv2, is a single +disk NAS server. The PCBs of the LS-XHL and LS-CHLv2 are almost the same. +The LS-XHL has a faster CPU and more RAM with a wider data bus, therefore +the LS-XHL PCB has two SDRAM chips. Both have a Kirkwood CPU (Marvell +88F6281). The only on-board storage is a 4 Mbit SPI flash which stores the +bootloader and its environment. The linux kernel and the initial ramdisk +are loaded from the hard disk. + + +Rescue Mode +----------- +These linkstations don't have a populated serial port. There is no way to +access an (unmodified) board other than using the netconsole. If you want +to recover from a bad environment setting or an empty environment, you can +do this only with a working network connection. + +Therefore, on entering the resuce mode, a random ethernet address is +generated if no valid address could be loaded from the environment variable +'ethaddr' and a DHCP request is sent. After a successful DHCP response is +received, the network settings are configured and the ncip is unset. Thus +all netconsole packets are broadcasted and you can use the netconsole to +access board from any host within the network segment. To determine the IP +address assigned to the board, you either have to sniff the traffic or +check the logs/leases of your DHCP server. + +The resuce mode is selected by holding the push button for at least one +second, while powering-on the device. The status LED turns solid amber if +the resuce mode is enabled, thus providing a visual feedback. + +Pressing the same button for at least 10 seconds on power-up will erase the +environment and reset the board. In this case the visual indication will +be: +- blinking blue, for about one second +- solid amber, for about nine seconds +- blinking amber, until you release the button + +This ensures, that you still can recover a device with a broken +environment by first erasing the environment and then entering the rescue +mode. + +Once the rescue mode is started, use the ncb binary from the tools/ +directory to access your board. There is a helper script named +'restore_env' to save your changes. It unsets all the network variables +which were set by the rescue mode, saves your changes and then resets the +board. + +The common use case for this is setting a MAC address. Let us assume you +have an empty environment, the board comes up with the amber LED blinking. +Then you enter the rescue mode, connect to the board with the ncb tool and +use the following commands to set your MAC address: + + setenv ethaddr 00:00:00:00:00:00 + run restore_env + +Of course you need to replace the 00:00:00:00:00:00 with your valid MAC +address, which can be found on a sticker on the bottom of your box. + + +Status LED +---------- +blinking blue + Bootloader is running normally. + +blinking amber + No ethaddr set. Use the `Rescue Mode` to set one. + +blinking red + Something bad happend during loading the operating system. + +The default behavior of the linux kernel is to turn on the blue LED. So if +the blinking blue LED changes to solid blue the kernel was loaded +successfully. + + +Power-on Switch +--------------- +The power-on switch is a software switch. If it is not in ON position when +the bootloader starts, the bootloader will disable the HDD and USB power +and stop the fan. Then it loops until the switch is in ON position again, +enables the power and fan again and continue booting. + + +Boot sources +------------ +The environment defines several different boot sources: + +legacy + This is the default boot source. It loads the kernel and ramdisk from the + attached HDD using the original filenames. The load addresses were + modified to support loading larger kernels. But it should behave the same + as the original bootloader. + +hdd + Use this for new-style booting. Loads three files /vmlinuz, /initrd.img + and /dtb from the boot partition. This should work out of the box if you + have debian and the flash-kernel package installed. + +usb + Same as hdd expect, that the files are loaded from an attached USB mass + storage device and the filename for the device tree is kirkwood-lsxhl.dtb + (or kirkwood-lschlv2.dtb). + +net + Same as usb expect, that the file are loaded from the network. + +rescue + Automatically activated if the push button is pressed for at least one + second on power-up. Does a DHCP request and enables the network console. + See `Rescue Mode` for more information. + +You can change the boot source by setting the 'bootsource' variable to the +corresponding value. Please note, that the restore_env script will the the +bootsource back to 'legacy'. + + +Flash map +--------- +00000 - 5ffff u-boot +60000 - 6ffff reserved, may be used to store dtb +70000 - 7ffff u-boot environment + + +Compiling +--------- +make lsxhl_config (or lschlv2_config) +make u-boot.kwb + + +Update your board +----------------- +Just flash the resulting u-boot.kwb to the beginning of the SPI flash. If +you already have a bootloader CLI, you can use the following commands: + + sf probe 0 + bootp ${loadaddr} u-boot.kwb + sf erase 0 +${filelen} + sf write 0 ${fileaddr} ${filesize} -- cgit From 89831112d46fb19127f3de9cec781e5a9c28b281 Mon Sep 17 00:00:00 2001 From: "Egli, Samuel" Date: Fri, 13 Feb 2015 15:47:10 +0100 Subject: mtd, omap: fix case NAND_OMAP_GPMC_PREFETCH not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch c316f577b4b72d1a1aeb559e9b3fad20808f1ffd breaks siemens boards because prefetch mode is not enabled. I assume it breaks other boards as well that don't use prefetch. This patch sets read_buf to nand_read_buf if NAND_OMAP_GPMC_PREFETCH is not defined. Signed-off-by: Samuel Egli CC: Daniel Mack CC: Guido Martínez CC: Tom Rini CC: Heiko Schocher --- drivers/mtd/nand/omap_gpmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index fc64f48144..24123fcfe5 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -989,12 +989,15 @@ int board_nand_init(struct nand_chip *nand) if (err) return err; -#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH /* TODO: Implement for 16-bit bus width */ if (nand->options & NAND_BUSWIDTH_16) nand->read_buf = nand_read_buf16; +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH else nand->read_buf = omap_nand_read_prefetch8; +#else + else + nand->read_buf = nand_read_buf; #endif nand->dev_ready = omap_dev_ready; -- cgit From aa8ac43645243b69faf0e81fab5f0d6fcf4285cf Mon Sep 17 00:00:00 2001 From: Angela Stegmaier Date: Mon, 16 Feb 2015 10:15:55 +0530 Subject: ARM: DRA72x: DDR3: Fix EMIF timings for 666MHz clock DDR3 timing and latency paramenters were not configured correctly for 666MHz. Fixing the timing and latency values according to Data sheet. This fixes the random crashes seen on DRA72-evm. Signed-off-by: Angela Stegmaier Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap5/sdram.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index 7d8cec08c2..e5456ff7cb 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -186,18 +186,18 @@ const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = { }; const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = { - .sdram_config_init = 0x61851AB2, - .sdram_config = 0x61851AB2, + .sdram_config_init = 0x61862B32, + .sdram_config = 0x61862B32, .sdram_config2 = 0x08000000, - .ref_ctrl = 0x00001035, - .sdram_tim1 = 0xCCCF36B3, - .sdram_tim2 = 0x308F7FDA, - .sdram_tim3 = 0x027F88A8, + .ref_ctrl = 0x0000144A, + .sdram_tim1 = 0xD113781C, + .sdram_tim2 = 0x308F7FE3, + .sdram_tim3 = 0x009F86A8, .read_idle_ctrl = 0x00050000, .zq_config = 0x0007190B, .temp_alert_config = 0x00000000, - .emif_ddr_phy_ctlr_1_init = 0x0024400A, - .emif_ddr_phy_ctlr_1 = 0x0024400A, + .emif_ddr_phy_ctlr_1_init = 0x0E24400D, + .emif_ddr_phy_ctlr_1 = 0x0E24400D, .emif_ddr_ext_phy_ctrl_1 = 0x10040100, .emif_ddr_ext_phy_ctrl_2 = 0x00A400A4, .emif_ddr_ext_phy_ctrl_3 = 0x00A900A9, -- cgit From 802bb57a584db2202a47d41ac730fe76ddeb4f33 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Mon, 16 Feb 2015 10:15:56 +0530 Subject: ARM: DRA7: EMIF: Update SDRAM_REF_CTRL register value The value in SDRAM_REF_CTRL controls the delay time between the initial rising edge of DDR_RESETn to rising edge of DDR_CKE (JEDEC specs this as 500us). In order to achieve this, SDRAM_REF_CTRL should be written with a value corresponding to 500us delay before starting DDR initialization sequence, and configure proper value at the end of sequence. Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap-common/emif-common.c | 4 +++- arch/arm/cpu/armv7/omap5/sdram.c | 9 ++++++--- arch/arm/include/asm/emif.h | 1 + board/ti/beagle_x15/board.c | 6 ++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index e601ba1886..c01a98f719 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -252,6 +252,8 @@ static void ddr3_init(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl); + writel(regs->sdram_config_init, &emif->emif_sdram_config); /* * Set SDRAM_CONFIG and PHY control registers to locked frequency * and RL =7. As the default values of the Mode Registers are not @@ -265,7 +267,6 @@ static void ddr3_init(u32 base, const struct emif_regs *regs) writel(regs->sdram_tim2, &emif->emif_sdram_tim_2); writel(regs->sdram_tim3, &emif->emif_sdram_tim_3); - writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl); writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl); /* @@ -274,6 +275,7 @@ static void ddr3_init(u32 base, const struct emif_regs *regs) */ if (is_dra7xx()) { do_ext_phy_settings(base, regs); + writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl); writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config); writel(regs->sdram_config_init, &emif->emif_sdram_config); } else { diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index e5456ff7cb..61e9aefe09 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -141,7 +141,8 @@ const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = { .sdram_config_init = 0x61851ab2, .sdram_config = 0x61851ab2, .sdram_config2 = 0x08000000, - .ref_ctrl = 0x00001035, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, .sdram_tim1 = 0xCCCF36B3, .sdram_tim2 = 0x308F7FDA, .sdram_tim3 = 0x027F88A8, @@ -165,7 +166,8 @@ const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = { .sdram_config_init = 0x61851B32, .sdram_config = 0x61851B32, .sdram_config2 = 0x08000000, - .ref_ctrl = 0x00001035, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, .sdram_tim1 = 0xCCCF36B3, .sdram_tim2 = 0x308F7FDA, .sdram_tim3 = 0x027F88A8, @@ -189,7 +191,8 @@ const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = { .sdram_config_init = 0x61862B32, .sdram_config = 0x61862B32, .sdram_config2 = 0x08000000, - .ref_ctrl = 0x0000144A, + .ref_ctrl = 0x0000493E, + .ref_ctrl_final = 0x0000144A, .sdram_tim1 = 0xD113781C, .sdram_tim2 = 0x308F7FE3, .sdram_tim3 = 0x009F86A8, diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index 342f045f41..7a545ea01a 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -1149,6 +1149,7 @@ struct emif_regs { u32 sdram_config; u32 sdram_config2; u32 ref_ctrl; + u32 ref_ctrl_final; u32 sdram_tim1; u32 sdram_tim2; u32 sdram_tim3; diff --git a/board/ti/beagle_x15/board.c b/board/ti/beagle_x15/board.c index db96e347e7..3a7e04d542 100644 --- a/board/ti/beagle_x15/board.c +++ b/board/ti/beagle_x15/board.c @@ -47,7 +47,8 @@ static const struct emif_regs beagle_x15_emif1_ddr3_532mhz_emif_regs = { .sdram_config_init = 0x61851b32, .sdram_config = 0x61851b32, .sdram_config2 = 0x00000000, - .ref_ctrl = 0x00001035, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, .sdram_tim1 = 0xceef266b, .sdram_tim2 = 0x328f7fda, .sdram_tim3 = 0x027f88a8, @@ -103,7 +104,8 @@ static const struct emif_regs beagle_x15_emif2_ddr3_532mhz_emif_regs = { .sdram_config_init = 0x61851b32, .sdram_config = 0x61851b32, .sdram_config2 = 0x00000000, - .ref_ctrl = 0x00001035, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, .sdram_tim1 = 0xceef266b, .sdram_tim2 = 0x328f7fda, .sdram_tim3 = 0x027f88a8, -- cgit From 1860d101964d6ea77e5411e62e3b42a64dc94865 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Mon, 16 Feb 2015 10:15:57 +0530 Subject: ARM: DRA7-evm: DDR3: Update leveling values Update the software leveling parameters. This fixes the random crash seen on DRA7-evm. Signed-off-by: Lokesh Vutla --- arch/arm/cpu/armv7/omap5/sdram.c | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index 61e9aefe09..5f8daa1ee1 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -152,10 +152,10 @@ const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = { .emif_ddr_phy_ctlr_1_init = 0x0E24400A, .emif_ddr_phy_ctlr_1 = 0x0E24400A, .emif_ddr_ext_phy_ctrl_1 = 0x10040100, - .emif_ddr_ext_phy_ctrl_2 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_3 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_4 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_5 = 0x00BB00BB, + .emif_ddr_ext_phy_ctrl_2 = 0x00910091, + .emif_ddr_ext_phy_ctrl_3 = 0x00950095, + .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, + .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, .emif_rd_wr_lvl_rmp_win = 0x00000000, .emif_rd_wr_lvl_rmp_ctl = 0x00000000, .emif_rd_wr_lvl_ctl = 0x00000000, @@ -177,10 +177,10 @@ const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = { .emif_ddr_phy_ctlr_1_init = 0x0E24400A, .emif_ddr_phy_ctlr_1 = 0x0E24400A, .emif_ddr_ext_phy_ctrl_1 = 0x10040100, - .emif_ddr_ext_phy_ctrl_2 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_3 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_4 = 0x00BB00BB, - .emif_ddr_ext_phy_ctrl_5 = 0x00BB00BB, + .emif_ddr_ext_phy_ctrl_2 = 0x00910091, + .emif_ddr_ext_phy_ctrl_3 = 0x00950095, + .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, + .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, .emif_rd_wr_lvl_rmp_win = 0x00000000, .emif_rd_wr_lvl_rmp_ctl = 0x00000000, .emif_rd_wr_lvl_ctl = 0x00000000, @@ -423,22 +423,22 @@ const u32 ddr3_ext_phy_ctrl_const_base_es2[] = { const u32 dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = { - 0x00BB00BB, - 0x00440044, - 0x00440044, - 0x00440044, - 0x00440044, - 0x00440044, + 0x00980098, + 0x00340034, + 0x00350035, + 0x00340034, + 0x00310031, + 0x00340034, 0x007F007F, 0x007F007F, 0x007F007F, 0x007F007F, 0x007F007F, - 0x00600060, - 0x00600060, - 0x00600060, - 0x00600060, - 0x00600060, + 0x00480048, + 0x004A004A, + 0x00520052, + 0x00550055, + 0x00500050, 0x00000000, 0x00600020, 0x40010080, @@ -452,22 +452,22 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = { const u32 dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = { - 0x00BB00BB, - 0x00440044, - 0x00440044, - 0x00440044, - 0x00440044, - 0x00440044, + 0x00980098, + 0x00330033, + 0x00330033, + 0x002F002F, + 0x00320032, + 0x00310031, 0x007F007F, 0x007F007F, 0x007F007F, 0x007F007F, 0x007F007F, - 0x00600060, - 0x00600060, - 0x00600060, - 0x00600060, - 0x00600060, + 0x00520052, + 0x00520052, + 0x00470047, + 0x00490049, + 0x00500050, 0x00000000, 0x00600020, 0x40010080, -- cgit From bba379d498b4ed408e79f7aec6dc23a3572c37e7 Mon Sep 17 00:00:00 2001 From: Steve Kipisz Date: Wed, 11 Feb 2015 18:54:28 -0500 Subject: clock_am43xx:Set the MAC clock to /5 for OPP100 When EMAC is in the boot order, the boot ROM sets OPP50 and the MAC clock is set to /2. SPL needs to change it to /5 for Ethernet to generate the correct txclk. This patch sets it correctly. Signed-off-by: Steve Kipisz --- arch/arm/cpu/armv7/am33xx/clock_am43xx.c | 3 +++ arch/arm/include/asm/arch-am33xx/cpu.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c index 31188c85bc..529a119514 100644 --- a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c +++ b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c @@ -118,4 +118,7 @@ void enable_basic_clocks(void) /* Select the Master osc clk as Timer2 clock source */ writel(0x1, &cmdpll->clktimer2clk); + + /* For OPP100 the mac clock should be /5. */ + writel(0x4, &cmdpll->clkselmacclk); } diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h index b94b56cba7..523d22eb87 100644 --- a/arch/arm/include/asm/arch-am33xx/cpu.h +++ b/arch/arm/include/asm/arch-am33xx/cpu.h @@ -400,6 +400,8 @@ struct prm_device_inst { struct cm_dpll { unsigned int resv1; unsigned int clktimer2clk; /* offset 0x04 */ + unsigned int resv2[11]; + unsigned int clkselmacclk; /* offset 0x34 */ }; #endif /* CONFIG_AM43XX */ -- cgit From 66c98a0c3807720a32ce49c9ba2a5808555062d7 Mon Sep 17 00:00:00 2001 From: Vitaly Andrianov Date: Wed, 11 Feb 2015 14:07:58 -0500 Subject: keystone2: ddr3: eliminate using global ddr3_size variable KS2 ddr3 initialization uses ddr3_size global variable before u-boot relocation. Even if the variable is not being used after relocation, writing to it corrupts relocation table. This patch removes the global ddr3_size variable and uses local one instead. Signed-off-by: Vitaly Andrianov Tested-by: Nishanth Menon --- arch/arm/cpu/armv7/keystone/ddr3.c | 5 +---- arch/arm/include/asm/arch-keystone/ddr3.h | 5 ++--- board/ti/ks2_evm/board.c | 6 ++++-- board/ti/ks2_evm/ddr3_k2e.c | 14 ++++++-------- board/ti/ks2_evm/ddr3_k2hk.c | 11 ++--------- board/ti/ks2_evm/ddr3_k2l.c | 12 ++---------- 6 files changed, 17 insertions(+), 36 deletions(-) diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c index 923906afb5..dfb27b5ba2 100644 --- a/arch/arm/cpu/armv7/keystone/ddr3.c +++ b/arch/arm/cpu/armv7/keystone/ddr3.c @@ -263,17 +263,14 @@ static void ddr3_map_ecc_cic2_irq(u32 base) } #endif -void ddr3_init_ecc(u32 base) +void ddr3_init_ecc(u32 base, u32 ddr3_size) { - u32 ddr3_size; - if (!ddr3_ecc_support_rmw(base)) { ddr3_disable_ecc(base); return; } ddr3_ecc_init_range(base); - ddr3_size = ddr3_get_size(); ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size); /* mapping DDR3 ECC system interrupt from CIC2 to GIC */ diff --git a/arch/arm/include/asm/arch-keystone/ddr3.h b/arch/arm/include/asm/arch-keystone/ddr3.h index b044d6f18f..a22c237c80 100644 --- a/arch/arm/include/asm/arch-keystone/ddr3.h +++ b/arch/arm/include/asm/arch-keystone/ddr3.h @@ -48,10 +48,9 @@ struct ddr3_emif_config { unsigned int sdrfc; }; -void ddr3_init(void); -int ddr3_get_size(void); +u32 ddr3_init(void); void ddr3_reset_ddrphy(void); -void ddr3_init_ecc(u32 base); +void ddr3_init_ecc(u32 base, u32 ddr3_size); void ddr3_disable_ecc(u32 base); void ddr3_check_ecc_int(u32 base); int ddr3_ecc_support_rmw(u32 base); diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index 04ec675103..8892a2843d 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -35,12 +35,14 @@ static struct aemif_config aemif_configs[] = { int dram_init(void) { - ddr3_init(); + u32 ddr3_size; + + ddr3_size = ddr3_init(); gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, CONFIG_MAX_RAM_BANK_SIZE); aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs); - ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE); + ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size); return 0; } diff --git a/board/ti/ks2_evm/ddr3_k2e.c b/board/ti/ks2_evm/ddr3_k2e.c index 40fd96607d..35ffb42056 100644 --- a/board/ti/ks2_evm/ddr3_k2e.c +++ b/board/ti/ks2_evm/ddr3_k2e.c @@ -11,11 +11,11 @@ #include "ddr3_cfg.h" #include -static int ddr3_size; static struct pll_init_data ddr3_400 = DDR3_PLL_400; -void ddr3_init(void) +u32 ddr3_init(void) { + u32 ddr3_size; char dimm_name[32]; if (~(readl(KS2_PLL_CNTRL_BASE + KS2_RSTCTRL_RSTYPE) & 0x1)) @@ -43,13 +43,11 @@ void ddr3_init(void) printf("DRAM: 4 GiB\n"); ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_4g); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_4g); + } else { + printf("Unknown SO-DIMM. Cannot configure DDR3\n"); + while (1) + ; } -} -/** - * ddr3_get_size - return ddr3 size in GiB - */ -int ddr3_get_size(void) -{ return ddr3_size; } diff --git a/board/ti/ks2_evm/ddr3_k2hk.c b/board/ti/ks2_evm/ddr3_k2hk.c index a1c3d05f8e..b36eb27bfa 100644 --- a/board/ti/ks2_evm/ddr3_k2hk.c +++ b/board/ti/ks2_evm/ddr3_k2hk.c @@ -12,14 +12,13 @@ #include #include -static int ddr3_size; - struct pll_init_data ddr3a_333 = DDR3_PLL_333(A); struct pll_init_data ddr3a_400 = DDR3_PLL_400(A); -void ddr3_init(void) +u32 ddr3_init(void) { char dimm_name[32]; + u32 ddr3_size; ddr3_get_dimm_params(dimm_name); @@ -93,12 +92,6 @@ void ddr3_init(void) /* Apply the workaround for PG 1.0 and 1.1 Silicons */ if (cpu_revision() <= 1) ddr3_err_reset_workaround(); -} -/** - * ddr3_get_size - return ddr3 size in GiB - */ -int ddr3_get_size(void) -{ return ddr3_size; } diff --git a/board/ti/ks2_evm/ddr3_k2l.c b/board/ti/ks2_evm/ddr3_k2l.c index 15a14f2aaf..00fc1943f5 100644 --- a/board/ti/ks2_evm/ddr3_k2l.c +++ b/board/ti/ks2_evm/ddr3_k2l.c @@ -11,28 +11,20 @@ #include "ddr3_cfg.h" #include -static int ddr3_size; static struct pll_init_data ddr3_400 = DDR3_PLL_400; -void ddr3_init(void) +u32 ddr3_init(void) { init_pll(&ddr3_400); /* No SO-DIMM, 2GB discreet DDR */ printf("DRAM: 2 GiB\n"); - ddr3_size = 2; /* Reset DDR3 PHY after PLL enabled */ ddr3_reset_ddrphy(); ddr3_init_ddrphy(KS2_DDR3A_DDRPHYC, &ddr3phy_1600_2g); ddr3_init_ddremif(KS2_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_2g); -} -/** - * ddr3_get_size - return ddr3 size in GiB - */ -int ddr3_get_size(void) -{ - return ddr3_size; + return 2; } -- cgit From 312aca4e6964812007c8218c0b4b0737e9e0f46a Mon Sep 17 00:00:00 2001 From: Vitaly Andrianov Date: Wed, 11 Feb 2015 14:05:41 -0500 Subject: net: keystone_net: move serdes setup to initialization function On Keystone2 devices serdes must be initialized before accessing MDIO bus. This commit moves the keystone2_net_serdes_setup() from keystone2_eth_open to keystone2_emac_initialize to meet that requirement. This also eliminates unnecessary serdes initializatin every time when the keystone2_eth_open is being called. Signed-off-by: Vitaly Andrianov Acked-by: Joe Hershberger Tested-by: Nishanth Menon --- drivers/net/keystone_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c index bedab1d606..35f1a57331 100644 --- a/drivers/net/keystone_net.c +++ b/drivers/net/keystone_net.c @@ -398,8 +398,6 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) sys_has_mdio = (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; - keystone2_net_serdes_setup(); - if (sys_has_mdio) keystone2_mdio_reset(mdio_bus); @@ -556,6 +554,8 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv) return res; } + keystone2_net_serdes_setup(); + /* Create phy device and bind it with driver */ #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, -- cgit From 1fddd7b63c69b8da40b5dc737db0382f473f9644 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Mon, 9 Feb 2015 00:06:10 +0100 Subject: tools/imagetool: remove linker script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a93648d197df48fa46dd55f925ff70468bd81c71 introduced linker generated lists for imagetool which is the base for some host tools (mkimage, dumpimage, et al.). Unfortunately some host tool chains do not support the used type of linker scripts. Therefore this commit broke these host-tools for them, namely FreeBSD and Darwin (OS/X). This commit tries to fix this. In order to have a clean distinction between host and embedded code space we need to introduce our own linker generated list instead of re-using the available linker_lists.h provided functionality. So we copy the implementation used in linux kernel script/mod/file2alias.c which has the very same problem (cause it is a host tool). This code also comes with an abstraction for Mach-O binary format used in Darwin systems. Signed-off-by: Andreas Bießmann Cc: Guilherme Maciel Ferreira --- Makefile | 5 +++++ tools/Makefile | 2 -- tools/imagetool.c | 35 ++++++++++++++++----------------- tools/imagetool.h | 56 ++++++++++++++++++++++++++++++++++++++++++----------- tools/imagetool.lds | 24 ----------------------- 5 files changed, 67 insertions(+), 55 deletions(-) delete mode 100644 tools/imagetool.lds diff --git a/Makefile b/Makefile index 6da42157b5..0538821b5c 100644 --- a/Makefile +++ b/Makefile @@ -281,6 +281,11 @@ os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \ HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc") HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp") HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress") + +# since Lion (10.7) ASLR is on by default, but we use linker generated lists +# in some host tools which is a problem then ... so disable ASLR for these +# tools +HOSTLDFLAGS += $(call os_x_before, 10, 7, "", "-Xlinker -no_pie") endif # Decide whether to build built-in, modular, or both. diff --git a/tools/Makefile b/tools/Makefile index e4b23eb5b8..88770b0611 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -128,8 +128,6 @@ HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage) HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage) HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage) -HOSTLDFLAGS += -T $(srctree)/tools/imagetool.lds - hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl HOSTCFLAGS_mkexynosspl.o := -pedantic diff --git a/tools/imagetool.c b/tools/imagetool.c index 148e4662b7..4b0b73db52 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -12,16 +12,16 @@ struct image_type_params *imagetool_get_type(int type) { - struct image_type_params *curr; - struct image_type_params *start = ll_entry_start( - struct image_type_params, image_type); - struct image_type_params *end = ll_entry_end( - struct image_type_params, image_type); + struct image_type_params **curr; + INIT_SECTION(image_type); + + struct image_type_params **start = __start_image_type; + struct image_type_params **end = __stop_image_type; for (curr = start; curr != end; curr++) { - if (curr->check_image_type) { - if (!curr->check_image_type(type)) - return curr; + if ((*curr)->check_image_type) { + if (!(*curr)->check_image_type(type)) + return *curr; } } return NULL; @@ -34,16 +34,15 @@ int imagetool_verify_print_header( struct image_tool_params *params) { int retval = -1; - struct image_type_params *curr; + struct image_type_params **curr; + INIT_SECTION(image_type); - struct image_type_params *start = ll_entry_start( - struct image_type_params, image_type); - struct image_type_params *end = ll_entry_end( - struct image_type_params, image_type); + struct image_type_params **start = __start_image_type; + struct image_type_params **end = __stop_image_type; for (curr = start; curr != end; curr++) { - if (curr->verify_header) { - retval = curr->verify_header((unsigned char *)ptr, + if ((*curr)->verify_header) { + retval = (*curr)->verify_header((unsigned char *)ptr, sbuf->st_size, params); if (retval == 0) { @@ -51,12 +50,12 @@ int imagetool_verify_print_header( * Print the image information if verify is * successful */ - if (curr->print_header) { - curr->print_header(ptr); + if ((*curr)->print_header) { + (*curr)->print_header(ptr); } else { fprintf(stderr, "%s: print_header undefined for %s\n", - params->cmdname, curr->name); + params->cmdname, (*curr)->name); } break; } diff --git a/tools/imagetool.h b/tools/imagetool.h index f35dec71c7..3e15b4e22b 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -20,15 +20,6 @@ #include #include -/* define __KERNEL__ in order to get the definitions - * required by the linker list. This is probably not - * the best way to do this */ -#ifndef __KERNEL__ -#define __KERNEL__ -#include -#undef __KERNEL__ -#endif /* __KERNEL__ */ - #include "fdt_host.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -194,6 +185,46 @@ int imagetool_save_subimage( void pbl_load_uboot(int fd, struct image_tool_params *mparams); +#define ___cat(a, b) a ## b +#define __cat(a, b) ___cat(a, b) + +/* we need some special handling for this host tool running eventually on + * Darwin. The Mach-O section handling is a bit different than ELF section + * handling. The differnces in detail are: + * a) we have segments which have sections + * b) we need a API call to get the respective section symbols */ +#if defined(__MACH__) +#include + +#define INIT_SECTION(name) do { \ + unsigned long name ## _len; \ + char *__cat(pstart_, name) = getsectdata("__TEXT", \ + #name, &__cat(name, _len)); \ + char *__cat(pstop_, name) = __cat(pstart_, name) + \ + __cat(name, _len); \ + __cat(__start_, name) = (void *)__cat(pstart_, name); \ + __cat(__stop_, name) = (void *)__cat(pstop_, name); \ + } while (0) +#define SECTION(name) __attribute__((section("__TEXT, " #name))) + +struct image_type_params **__start_image_type, **__stop_image_type; +#else +#define INIT_SECTION(name) /* no-op for ELF */ +#define SECTION(name) __attribute__((section(#name))) + +/* We construct a table of pointers in an ELF section (pointers generally + * go unpadded by gcc). ld creates boundary syms for us. */ +extern struct image_type_params *__start_image_type[], *__stop_image_type[]; +#endif /* __MACH__ */ + +#if !defined(__used) +# if __GNUC__ == 3 && __GNUC_MINOR__ < 3 +# define __used __attribute__((__unused__)) +# else +# define __used __attribute__((__used__)) +# endif +#endif + #define U_BOOT_IMAGE_TYPE( \ _id, \ _name, \ @@ -208,7 +239,8 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); _fflag_handle, \ _vrec_header \ ) \ - ll_entry_declare(struct image_type_params, _id, image_type) = { \ + static struct image_type_params __cat(image_type_, _id) = \ + { \ .name = _name, \ .header_size = _header_size, \ .hdr = _header, \ @@ -220,6 +252,8 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); .check_image_type = _check_image_type, \ .fflag_handle = _fflag_handle, \ .vrec_header = _vrec_header \ - } + }; \ + static struct image_type_params *SECTION(image_type) __used \ + __cat(image_type_ptr_, _id) = &__cat(image_type_, _id) #endif /* _IMAGETOOL_H_ */ diff --git a/tools/imagetool.lds b/tools/imagetool.lds deleted file mode 100644 index 7e92b4ac66..0000000000 --- a/tools/imagetool.lds +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2011-2012 The Chromium OS Authors. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -SECTIONS -{ - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - __u_boot_sandbox_option_start = .; - _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } - __u_boot_sandbox_option_end = .; - - __bss_start = .; -} - -INSERT BEFORE .data; -- cgit From 364ac5b5836055c2a49f986769b2d925f230f093 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 7 Feb 2015 09:12:39 +0800 Subject: image: Convert to use fdt_for_each_subnode macro Use fdt_for_each_subnode macro to simplify the code a bit. Signed-off-by: Axel Lin Acked-by: Simon Glass --- common/image-fit.c | 4 +--- common/image-sig.c | 16 ++++------------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/common/image-fit.c b/common/image-fit.c index b47d11024f..778d2a148b 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1010,9 +1010,7 @@ int fit_image_verify(const void *fit, int image_noffset) } /* Process all hash subnodes of the component image node */ - for (noffset = fdt_first_subnode(fit, image_noffset); - noffset >= 0; - noffset = fdt_next_subnode(fit, noffset)) { + fdt_for_each_subnode(fit, noffset, image_noffset) { const char *name = fit_get_name(fit, noffset, NULL); /* diff --git a/common/image-sig.c b/common/image-sig.c index 2c9f0cdf7a..eda5e1353a 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -212,9 +212,7 @@ static int fit_image_verify_sig(const void *fit, int image_noffset, int ret; /* Process all hash subnodes of the component image node */ - for (noffset = fdt_first_subnode(fit, image_noffset); - noffset >= 0; - noffset = fdt_next_subnode(fit, noffset)) { + fdt_for_each_subnode(fit, noffset, image_noffset) { const char *name = fit_get_name(fit, noffset, NULL); if (!strncmp(name, FIT_SIG_NODENAME, @@ -262,9 +260,7 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, return 0; } - for (noffset = fdt_first_subnode(sig_blob, sig_node); - noffset >= 0; - noffset = fdt_next_subnode(sig_blob, noffset)) { + fdt_for_each_subnode(sig_blob, noffset, sig_node) { const char *required; int ret; @@ -397,9 +393,7 @@ static int fit_config_verify_sig(const void *fit, int conf_noffset, int ret; /* Process all hash subnodes of the component conf node */ - for (noffset = fdt_first_subnode(fit, conf_noffset); - noffset >= 0; - noffset = fdt_next_subnode(fit, noffset)) { + fdt_for_each_subnode(fit, noffset, conf_noffset) { const char *name = fit_get_name(fit, noffset, NULL); if (!strncmp(name, FIT_SIG_NODENAME, @@ -444,9 +438,7 @@ int fit_config_verify_required_sigs(const void *fit, int conf_noffset, return 0; } - for (noffset = fdt_first_subnode(sig_blob, sig_node); - noffset >= 0; - noffset = fdt_next_subnode(sig_blob, noffset)) { + fdt_for_each_subnode(sig_blob, noffset, sig_node) { const char *required; int ret; -- cgit From af21f2fb6f7a1178a98f1172bf5df7b7fd8545ee Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 7 Feb 2015 13:38:19 +0100 Subject: config_distro_bootcmd.h: Enable CONFIG_CMD_PART The recent changes to config_distro_bootcmd.h require CONFIG_CMD_PART to be defined, as the default bootcmd now uses the "part" command. This fixes sunxi boards not booting with v2015.04-rc1. Signed-off-by: Hans de Goede Acked-by: Stephen Warren --- include/config_distro_bootcmd.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 49674f4537..07a0b3b234 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -10,6 +10,10 @@ #ifndef _CONFIG_CMD_DISTRO_BOOTCMD_H #define _CONFIG_CMD_DISTRO_BOOTCMD_H +/* We need the part command */ +#define CONFIG_PARTITION_UUIDS +#define CONFIG_CMD_PART + #define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \ "if " #devtypel " dev ${devnum}; then " \ "setenv devtype " #devtypel "; " \ -- cgit From e8f768ab3346feefcf47c9d613d0f55501aa09c6 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Mon, 2 Feb 2015 23:04:08 +0100 Subject: sunxi: Ampe A76 support Signed-off-by: Paul Kocialkowski Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 5 +++++ configs/Ampe_A76_defconfig | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 configs/Ampe_A76_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index faa413cb06..f61144d510 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -46,6 +46,11 @@ S: Maintained F: board/sunxi/dram_a20_olinuxino_l2.c F: configs/A20-OLinuXino-Lime2_defconfig +AMPE A76 BOARD +M: Paul Kocialkowski +S: Maintained +F: configs/Ampe_A76_defconfig + COLOMBUS BOARD M: Maxime Ripard S: Maintained diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig new file mode 100644 index 0000000000..2054fc3c96 --- /dev/null +++ b/configs/Ampe_A76_defconfig @@ -0,0 +1,15 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" +CONFIG_FDTFILE="sun5i-a13-ampe-a76.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="AXP0-0" +CONFIG_VIDEO_LCD_BL_EN="AXP0-1" +CONFIG_VIDEO_LCD_BL_PWM="PB2" ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN5I=y ++S:CONFIG_DRAM_CLK=432 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=4 -- cgit From 8910a7d37a0c0c7b73c8b1e6175966d58979ba5c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 3 Feb 2015 08:45:33 +0100 Subject: sunxi: MAINTAINERS: drop no longer existing felconfig-s from MAINTAINERS Signed-off-by: Hans de Goede --- board/sunxi/MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index f61144d510..9a287d3c30 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -62,9 +62,7 @@ M: Hans de Goede S: Maintained F: include/configs/sun7i.h F: configs/Cubieboard2_defconfig -F: configs/Cubieboard2_FEL_defconfig F: configs/Cubietruck_defconfig -F: configs/Cubietruck_FEL_defconfig GEMEI-G9 TABLET M: Priit Laes -- cgit From 5633a296ebb970d0a6be839fb37eaf8a11aa35f8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 2 Feb 2015 17:13:29 +0100 Subject: sunxi: video: Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer, instead override board_get_usable_ram_top to make sure that u-boot is not relocated into the area where we want to use the framebuffer, and patch the devicetree from sunxi_simplefb_setup() to tell the kernel to not touch the framebuffer. This makes u-boot properly see the framebuffer as dram, and initalize the level 2 cache for it, fixing the very slow cfb scrolling problem. As an added bonus this stops us from reserving the framebuffer when simplefb is not used because an older kernel is booted, or hdp is used and no hdmi cable was plugged in, freeing up the memory for kernel use in these cases. Reported-by: Siarhei Siamashka Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/video/sunxi_display.c | 22 +++++++++++++++++++++- include/configs/sunxi-common.h | 8 +++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index f5f24fc020..cd5963a751 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -1060,6 +1060,11 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor) return NULL; /* never reached */ } +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE; +} + void *video_hw_init(void) { static GraphicDevice *graphic_device = &sunxi_display.graphic_device; @@ -1076,7 +1081,7 @@ void *video_hw_init(void) memset(&sunxi_display, 0, sizeof(struct sunxi_display)); printf("Reserved %dkB of RAM for Framebuffer.\n", - CONFIG_SUNXI_FB_SIZE >> 10); + CONFIG_SUNXI_MAX_FB_SIZE >> 10); gd->fb_base = gd->ram_top; video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, @@ -1194,6 +1199,7 @@ int sunxi_simplefb_setup(void *blob) { static GraphicDevice *graphic_device = &sunxi_display.graphic_device; int offset, ret; + u64 start, size; const char *pipeline = NULL; #ifdef CONFIG_MACH_SUN4I @@ -1237,6 +1243,20 @@ int sunxi_simplefb_setup(void *blob) return 0; /* Keep older kernels working */ } + /* + * Do not report the framebuffer as free RAM to the OS, note we cannot + * use fdt_add_mem_rsv() here, because then it is still seen as RAM, + * and e.g. Linux refuses to iomap RAM on ARM, see: + * linux/arch/arm/mm/ioremap.c around line 301. + */ + start = gd->bd->bi_dram[0].start; + size = gd->bd->bi_dram[0].size - CONFIG_SUNXI_MAX_FB_SIZE; + ret = fdt_fixup_memory_banks(blob, &start, &size, 1); + if (ret) { + eprintf("Cannot setup simplefb: Error reserving memory\n"); + return ret; + } + ret = fdt_setup_simplefb_node(blob, offset, gd->fb_base, graphic_device->winSizeX, graphic_device->winSizeY, graphic_device->winSizeX * graphic_device->gdfBytesPP, diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index cea52dbf7b..33c06146c6 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -210,10 +210,10 @@ #ifdef CONFIG_VIDEO /* - * The amount of RAM that is reserved for the FB. This will not show up as - * RAM to the kernel, but will be reclaimed by a KMS driver in future. + * The amount of RAM to keep free at the top of RAM when relocating u-boot, + * to use as framebuffer. This must be a multiple of 4096. */ -#define CONFIG_SUNXI_FB_SIZE (9 << 20) +#define CONFIG_SUNXI_MAX_FB_SIZE (9 << 20) /* Do we want to initialize a simple FB? */ #define CONFIG_VIDEO_DT_SIMPLEFB @@ -231,8 +231,6 @@ /* stop x86 thinking in cfbconsole from trying to init a pc keyboard */ #define CONFIG_VGA_AS_SINGLE_DEVICE -#define CONFIG_SYS_MEM_TOP_HIDE ((CONFIG_SUNXI_FB_SIZE + 0xFFF) & ~0xFFF) - /* To be able to hook simplefb into dt */ #ifdef CONFIG_VIDEO_DT_SIMPLEFB #define CONFIG_OF_BOARD_SETUP -- cgit From 20779ec3a5d7b3cad4fdc960d9e2e898fab259b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 2 Feb 2015 18:00:53 +0100 Subject: sunxi: video: Dynamically reserve framebuffer memory Only use CONFIG_SUNXI_MAX_FB_SIZE to reserve memory at the top when relocating u-boot, and calculate the actual amount of memory necessary when setting up the video-mode and use only that, freeing up some additional memory for use by the kernel. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/video/sunxi_display.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index cd5963a751..dbda97e746 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -46,6 +46,7 @@ struct sunxi_display { GraphicDevice graphic_device; enum sunxi_monitor monitor; unsigned int depth; + unsigned int fb_size; } sunxi_display; #ifdef CONFIG_VIDEO_HDMI @@ -1080,10 +1081,6 @@ void *video_hw_init(void) memset(&sunxi_display, 0, sizeof(struct sunxi_display)); - printf("Reserved %dkB of RAM for Framebuffer.\n", - CONFIG_SUNXI_MAX_FB_SIZE >> 10); - gd->fb_base = gd->ram_top; - video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &sunxi_display.depth, &options); #ifdef CONFIG_VIDEO_HDMI @@ -1174,6 +1171,17 @@ void *video_hw_init(void) mode->yres, sunxi_get_mon_desc(sunxi_display.monitor)); } + sunxi_display.fb_size = + (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; + if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { + printf("Error need %dkB for fb, but only %dkB is reserved\n", + sunxi_display.fb_size >> 10, + CONFIG_SUNXI_MAX_FB_SIZE >> 10); + return NULL; + } + + gd->fb_base = gd->bd->bi_dram[0].start + + gd->bd->bi_dram[0].size - sunxi_display.fb_size; sunxi_engines_init(); sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE); @@ -1250,7 +1258,7 @@ int sunxi_simplefb_setup(void *blob) * linux/arch/arm/mm/ioremap.c around line 301. */ start = gd->bd->bi_dram[0].start; - size = gd->bd->bi_dram[0].size - CONFIG_SUNXI_MAX_FB_SIZE; + size = gd->bd->bi_dram[0].size - sunxi_display.fb_size; ret = fdt_fixup_memory_banks(blob, &start, &size, 1); if (ret) { eprintf("Cannot setup simplefb: Error reserving memory\n"); -- cgit From 51637afe98ba1745976382f64afc270f7f0b6974 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Feb 2015 12:14:56 +0100 Subject: sunxi: dram: Un-inline dram helper functions Move the dram helper functions to a separate C file, rather then having them as inline helpers in dram.h. This saves 144 bytes in the .text segment for sun6i builds. Signed-off-by: Hans de Goede Reviewed-by: Simon Glass --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/dram_helpers.c | 37 +++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/dram.h | 28 ++----------------------- 3 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/dram_helpers.c diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 48db7442f4..a790a2392f 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -11,6 +11,7 @@ obj-y += timer.o obj-y += board.o obj-y += clock.o obj-y += cpu_info.o +obj-y += dram_helpers.o obj-y += pinmux.o obj-y += usbc.o obj-$(CONFIG_MACH_SUN6I) += prcm.o diff --git a/arch/arm/cpu/armv7/sunxi/dram_helpers.c b/arch/arm/cpu/armv7/sunxi/dram_helpers.c new file mode 100644 index 0000000000..9a94e1b679 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/dram_helpers.c @@ -0,0 +1,37 @@ +/* + * DRAM init helper functions + * + * (C) Copyright 2015 Hans de Goede + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * Wait up to 1s for value to be set in given part of reg. + */ +void mctl_await_completion(u32 *reg, u32 mask, u32 val) +{ + unsigned long tmo = timer_get_us() + 1000000; + + while ((readl(reg) & mask) != val) { + if (timer_get_us() > tmo) + panic("Timeout initialising DRAM\n"); + } +} + +/* + * Test if memory at offset offset matches memory at begin of DRAM + */ +bool mctl_mem_matches(u32 offset) +{ + /* Try to write different values to RAM at two addresses */ + writel(0, CONFIG_SYS_SDRAM_BASE); + writel(0xaa55aa55, CONFIG_SYS_SDRAM_BASE + offset); + /* Check if the same value is actually observed when reading back */ + return readl(CONFIG_SYS_SDRAM_BASE) == + readl(CONFIG_SYS_SDRAM_BASE + offset); +} diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 7ff43e6d3a..aedd1941d5 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -25,31 +25,7 @@ #endif unsigned long sunxi_dram_init(void); - -/* - * Wait up to 1s for value to be set in given part of reg. - */ -static inline void mctl_await_completion(u32 *reg, u32 mask, u32 val) -{ - unsigned long tmo = timer_get_us() + 1000000; - - while ((readl(reg) & mask) != val) { - if (timer_get_us() > tmo) - panic("Timeout initialising DRAM\n"); - } -} - -/* - * Test if memory at offset offset matches memory at begin of DRAM - */ -static inline bool mctl_mem_matches(u32 offset) -{ - /* Try to write different values to RAM at two addresses */ - writel(0, CONFIG_SYS_SDRAM_BASE); - writel(0xaa55aa55, CONFIG_SYS_SDRAM_BASE + offset); - /* Check if the same value is actually observed when reading back */ - return readl(CONFIG_SYS_SDRAM_BASE) == - readl(CONFIG_SYS_SDRAM_BASE + offset); -} +void mctl_await_completion(u32 *reg, u32 mask, u32 val); +bool mctl_mem_matches(u32 offset); #endif /* _SUNXI_DRAM_H */ -- cgit From b1b912ddf3041627e99899cfc09e015a54f9910e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 11 Feb 2015 09:05:18 +0100 Subject: sunxi: otg: Fix peripheral mode Peripheral mode needs us to signal vusb high to the phy for it to work, just like the host mode does. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/usb/musb-new/sunxi.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 778916df00..4646a3d9fe 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -145,16 +145,6 @@ static void USBC_ForceIdToHigh(__iomem void *base) musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_ForceVbusValidDisable(__iomem void *base) -{ - u32 reg_val; - - reg_val = musb_readl(base, USBC_REG_o_ISCR); - reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); - reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); - musb_writel(base, USBC_REG_o_ISCR, reg_val); -} - static void USBC_ForceVbusValidToHigh(__iomem void *base) { u32 reg_val; @@ -248,12 +238,11 @@ static int sunxi_musb_init(struct musb *musb) if (is_host_enabled(musb)) { /* Host mode */ USBC_ForceIdToLow(musb->mregs); - USBC_ForceVbusValidToHigh(musb->mregs); } else { /* Peripheral mode */ USBC_ForceIdToHigh(musb->mregs); - USBC_ForceVbusValidDisable(musb->mregs); } + USBC_ForceVbusValidToHigh(musb->mregs); return 0; } -- cgit From c924e2a8036f43f2f4a8e829ecfc8e9d6e8cce63 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 8 Feb 2015 07:05:27 +0200 Subject: tools: mksunxiboot: Fix problems on big endian systems Now my PS3 can be also used to build u-boot for sunxi devices. Signed-off-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- tools/mksunxiboot.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c index 1f0fbae8e1..0035f6ea26 100644 --- a/tools/mksunxiboot.c +++ b/tools/mksunxiboot.c @@ -43,19 +43,19 @@ int gen_check_sum(struct boot_file_head *head_p) uint32_t i; uint32_t sum; - length = head_p->length; + length = le32_to_cpu(head_p->length); if ((length & 0x3) != 0) /* must 4-byte-aligned */ return -1; buf = (uint32_t *)head_p; - head_p->check_sum = STAMP_VALUE; /* fill stamp */ + head_p->check_sum = cpu_to_le32(STAMP_VALUE); /* fill stamp */ loop = length >> 2; /* calculate the sum */ for (i = 0, sum = 0; i < loop; i++) - sum += buf[i]; + sum += le32_to_cpu(buf[i]); /* write back check sum */ - head_p->check_sum = sum; + head_p->check_sum = cpu_to_le32(sum); return 0; } @@ -125,10 +125,12 @@ int main(int argc, char *argv[]) memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */ img.header.length = ALIGN(file_size + sizeof(struct boot_file_head), BLOCK_SIZE); + img.header.b_instruction = cpu_to_le32(img.header.b_instruction); + img.header.length = cpu_to_le32(img.header.length); gen_check_sum(&img.header); - count = write(fd_out, &img, img.header.length); - if (count != img.header.length) { + count = write(fd_out, &img, le32_to_cpu(img.header.length)); + if (count != le32_to_cpu(img.header.length)) { perror("Writing output"); return EXIT_FAILURE; } -- cgit From e11c6c279d823dc0d2f470c5c2e3c0a9854a640f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 10:47:28 -0700 Subject: arm: Allow lr to be saved by board code The link register value can be required on some boards (e.g. FEL mode on sunxi) so use a branch instruction to jump to save_boot_params() instead of a branch link. This requires a branch back to save_boot_params_ret so adjust the users to deal with this. For exynos just drop the function since it doesn't do anything. Signed-off-by: Simon Glass Acked-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/exynos/spl_boot.c | 1 - arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 2 +- arch/arm/cpu/armv7/omap3/lowlevel_init.S | 2 +- arch/arm/cpu/armv7/start.S | 7 +++++-- arch/arm/include/asm/system.h | 15 +++++++++++++++ board/nokia/rx51/lowlevel_init.S | 3 ++- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index bc237c969f..c7f943eb6a 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -309,4 +309,3 @@ void board_init_r(gd_t *id, ulong dest_addr) while (1) ; } -void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 86c0e42174..e19c7aecec 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -19,7 +19,7 @@ ENTRY(save_boot_params) ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS str r0, [r1] - bx lr + b save_boot_params_ret ENDPROC(save_boot_params) ENTRY(set_pl310_ctrl_reg) diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S index 78577b1d1c..80cb2639f6 100644 --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S @@ -23,7 +23,7 @@ ENTRY(save_boot_params) ldr r5, [r0, #0x4] and r5, r5, #0xff str r5, [r4] - bx lr + b save_boot_params_ret ENDPROC(save_boot_params) #endif diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 70048c10ae..9b49ece2d6 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -31,9 +31,12 @@ *************************************************************************/ .globl reset + .globl save_boot_params_ret reset: - bl save_boot_params + /* Allow the board to save important registers */ + b save_boot_params +save_boot_params_ret: /* * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, * except if in HYP mode already @@ -96,7 +99,7 @@ ENDPROC(c_runtime_cpu_setup) * *************************************************************************/ ENTRY(save_boot_params) - bx lr @ back to my caller + b save_boot_params_ret @ back to my caller ENDPROC(save_boot_params) .weak save_boot_params diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 89f2294689..7820486df0 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -142,6 +142,21 @@ void flush_l3_cache(void); #ifndef __ASSEMBLY__ +/** + * save_boot_params() - Save boot parameters before starting reset sequence + * + * If you provide this function it will be called immediately U-Boot starts, + * both for SPL and U-Boot proper. + * + * All registers are unchanged from U-Boot entry. No registers need be + * preserved. + * + * This is not a normal C function. There is no stack. Return by branching to + * save_boot_params_ret. + * + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3); + */ + #define isb() __asm__ __volatile__ ("" : : : "memory") #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S index e25290966c..9d4ea1b3f9 100644 --- a/board/nokia/rx51/lowlevel_init.S +++ b/board/nokia/rx51/lowlevel_init.S @@ -37,7 +37,8 @@ ih_magic: /* IH_MAGIC in big endian from include/image.h */ .global save_boot_params save_boot_params: - + /* Get return address */ + ldr lr, =save_boot_params_ret /* Copy valid attached kernel to address KERNEL_ADDRESS */ -- cgit From c01c71bc16d2836c3ff81af54529dab0686bca00 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 10:47:29 -0700 Subject: arm: spl: Provide for a board-specific loader Some boards have a special way of loading U-Boot that does not fit with the existing SPL code. For example sunxi uses an 'FEL' mode where U-Boot is loaded over USB. Add a CONFIG option and boot mode for this. Signed-off-by: Simon Glass Acked-by: Siarhei Siamashka Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/include/asm/spl.h | 4 ++++ common/spl/spl.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index 8acd7cd1bd..17b6f544da 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -26,10 +26,14 @@ enum { BOOT_DEVICE_SPI, BOOT_DEVICE_SATA, BOOT_DEVICE_I2C, + BOOT_DEVICE_BOARD, BOOT_DEVICE_NONE }; #endif +/* Board-specific load method */ +void spl_board_load_image(void); + /* Linker symbols. */ extern char __bss_start[], __bss_end[]; diff --git a/common/spl/spl.c b/common/spl/spl.c index daaeb507c4..ded0f30478 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -228,6 +228,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) case BOOT_DEVICE_SATA: spl_sata_load_image(); break; +#endif +#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE + case BOOT_DEVICE_BOARD: + spl_board_load_image(); + break; #endif default: #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) -- cgit From 942cb0b6a29f74507adeb0bce7ff7f23f69faf84 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Feb 2015 10:47:30 -0700 Subject: sunxi: Normalise FEL support Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of creating its own. There are some #ifdefs required in start.S. Future work will hopefully remove these. This series is available at u-boot-dm, branch sunxi-working. Signed-off-by: Simon Glass Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/start.S | 5 +- arch/arm/cpu/armv7/sunxi/Makefile | 4 +- arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++ arch/arm/cpu/armv7/sunxi/config.mk | 2 - arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++ arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 ----------------------------- arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++ board/sunxi/Kconfig | 10 ++++ include/configs/sunxi-common.h | 6 +-- scripts/Makefile.spl | 2 - 10 files changed, 73 insertions(+), 94 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 9b49ece2d6..098a83ab71 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -54,7 +54,8 @@ save_boot_params_ret: * (OMAP4 spl TEXT_BASE is not 32 byte aligned. * Continue to use ROM code vector only in OMAP4 spl) */ -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \ + !defined(CONFIG_SPL_FEL) /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register bic r0, #CR_V @ V = 0 @@ -67,7 +68,9 @@ save_boot_params_ret: /* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT +#ifndef CONFIG_SPL_FEL bl cpu_init_cp15 +#endif bl cpu_init_crit #endif diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index a790a2392f..4bb12ad8bd 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -39,7 +39,5 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o -ifdef CONFIG_SPL_FEL -obj-y += start.o -endif +obj-y += fel_utils.o endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 6e28bcd040..b7492ac1fe 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -27,6 +27,13 @@ #include +struct fel_stash { + uint32_t sp; + uint32_t lr; +}; + +struct fel_stash fel_stash __attribute__((section(".data"))); + static int gpio_init(void) { #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F) @@ -65,6 +72,12 @@ static int gpio_init(void) return 0; } +void spl_board_load_image(void) +{ + debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr); + return_to_fel(fel_stash.sp, fel_stash.lr); +} + void s_init(void) { #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I @@ -95,6 +108,14 @@ void s_init(void) */ u32 spl_boot_device(void) { + /* + * Have we been asked to return to the FEL portion of the boot ROM? + * TODO: We need a more robust test here, or bracket this with + * #ifdef CONFIG_SPL_FEL. + */ + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000) + return BOOT_DEVICE_BOARD; + return BOOT_DEVICE_MMC1; } diff --git a/arch/arm/cpu/armv7/sunxi/config.mk b/arch/arm/cpu/armv7/sunxi/config.mk index 00f5ffc683..76ffec9df6 100644 --- a/arch/arm/cpu/armv7/sunxi/config.mk +++ b/arch/arm/cpu/armv7/sunxi/config.mk @@ -1,8 +1,6 @@ # Build a combined spl + u-boot image ifdef CONFIG_SPL ifndef CONFIG_SPL_BUILD -ifndef CONFIG_SPL_FEL ALL-y += u-boot-sunxi-with-spl.bin endif endif -endif diff --git a/arch/arm/cpu/armv7/sunxi/fel_utils.S b/arch/arm/cpu/armv7/sunxi/fel_utils.S new file mode 100644 index 0000000000..0c1de52df8 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/fel_utils.S @@ -0,0 +1,25 @@ +/* + * Utility functions for FEL mode. + * + * Copyright (c) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +ENTRY(save_boot_params) + ldr r0, =fel_stash + str sp, [r0, #0] + str lr, [r0, #4] + b save_boot_params_ret +ENDPROC(save_boot_params) + +ENTRY(return_to_fel) + mov sp, r0 + mov lr, r1 + bx lr +ENDPROC(return_to_fel) diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds deleted file mode 100644 index 928b7c19e0..0000000000 --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds +++ /dev/null @@ -1,82 +0,0 @@ -/* - * (C) Copyright 2013 - * Henrik Nordstrom - * - * SPDX-License-Identifier: GPL-2.0+ - */ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(s_init) -SECTIONS -{ - . = 0x00002000; - - . = ALIGN(4); - .text : - { - *(.text.s_init) - *(.text*) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { - *(.data*) - } - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); - } - - . = ALIGN(4); - . = .; - - . = ALIGN(4); - .rel.dyn : { - __rel_dyn_start = .; - *(.rel*) - __rel_dyn_end = .; - } - - .dynsym : { - __dynsym_start = .; - *(.dynsym) - } - - . = ALIGN(4); - .note.gnu.build-id : - { - *(.note.gnu.build-id) - } - _end = .; - - . = ALIGN(4096); - .mmutable : { - *(.mmutable) - } - - .bss_start __rel_dyn_start (OVERLAY) : { - KEEP(*(.__bss_start)); - __bss_base = .; - } - - .bss __bss_base (OVERLAY) : { - *(.bss*) - . = ALIGN(4); - __bss_limit = .; - } - - .bss_end __bss_limit (OVERLAY) : { - KEEP(*(.__bss_end)); - } - - /DISCARD/ : { *(.dynstr*) } - /DISCARD/ : { *(.dynamic*) } - /DISCARD/ : { *(.plt*) } - /DISCARD/ : { *(.interp*) } - /DISCARD/ : { *(.gnu*) } - /DISCARD/ : { *(.note*) } -} diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h index c3e636e1d9..60a5bd8c85 100644 --- a/arch/arm/include/asm/arch-sunxi/sys_proto.h +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h @@ -13,4 +13,14 @@ void sdelay(unsigned long); +/* return_to_fel() - Return to BROM from SPL + * + * This returns back into the BROM after U-Boot SPL has performed its initial + * init. It uses the provided lr and sp to do so. + * + * @lr: BROM link register value (return address) + * @sp: BROM stack pointer + */ +void return_to_fel(uint32_t lr, uint32_t sp); + #endif diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4a2158988f..3eab81fd12 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -149,6 +149,16 @@ config SPL_FEL bool "SPL/FEL mode support" depends on SPL default n + help + This enables support for Fast Early Loader (FEL) mode. This + allows U-Boot to be loaded to the board over USB by the on-chip + boot rom. U-Boot should be sent in two parts: SPL first, with + 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000' then U-Boot with + 'fel write 0x4a000000 u-boot.bin; fel exe 0x4a000000'. This option + shrinks the amount of SRAM available to SPL, so only enable it if + you need FEL. Note that enabling this option only allows FEL to be + used; it is still possible to boot U-Boot from boot media. U-Boot + SPL detects when it is being loaded using FEL. config UART0_PORT_F bool "UART0 on MicroSD breakout board" diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 33c06146c6..5ece0202a6 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -18,10 +18,8 @@ */ #define CONFIG_SUNXI /* sunxi family */ #ifdef CONFIG_SPL_BUILD -#ifndef CONFIG_SPL_FEL #define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */ #endif -#endif #include /* get chip and board defs */ @@ -149,10 +147,10 @@ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_BOARD_LOAD_IMAGE + #ifdef CONFIG_SPL_FEL -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds" -#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi" #define CONFIG_SPL_TEXT_BASE 0x2000 #define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */ diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index e4b9881186..cc189adc0c 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -154,10 +154,8 @@ ALL-y += $(obj)/$(BOARD)-spl.bin endif ifdef CONFIG_SUNXI -ifndef CONFIG_SPL_FEL ALL-y += $(obj)/sunxi-spl.bin endif -endif ifeq ($(CONFIG_SYS_SOC),"at91") ALL-y += boot.bin -- cgit From 840fe95c3bcff7692c51b90ebc0d350792597ff0 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Mon, 16 Feb 2015 10:23:59 +0200 Subject: sunxi: Support the FEL boot mode in the regular u-boot build So that the CONFIG_SPL_FEL option is not needed anymore. And the regular SPL binary, generated by the default u-boot build, is now also bootable over USB in the FEL mode. The SPL still can boot from the SD card too. A bunch of system registers need to be saved/restored in order to ensure that the IRQ handler still works in the BROM FEL code after getting control back from the SPL. This is done in the sunxi code instead of abusing ifdefs in 'start.S'. The decision whether to load the main u-boot binary from the SD card or return to the FEL code in the BROM is done at runtime. Signed-off-by: Siarhei Siamashka [hdegoede@redhat.com: Since we now restore various regs before returning to the FEL BROM code we can drop the sunxi specific #ifdefs in start.S] Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/start.S | 5 +---- arch/arm/cpu/armv7/sunxi/board.c | 35 +++++++++++++++++++++++++++++------ arch/arm/cpu/armv7/sunxi/fel_utils.S | 17 +++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 098a83ab71..9b49ece2d6 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -54,8 +54,7 @@ save_boot_params_ret: * (OMAP4 spl TEXT_BASE is not 32 byte aligned. * Continue to use ROM code vector only in OMAP4 spl) */ -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \ - !defined(CONFIG_SPL_FEL) +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register bic r0, #CR_V @ V = 0 @@ -68,9 +67,7 @@ save_boot_params_ret: /* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT -#ifndef CONFIG_SPL_FEL bl cpu_init_cp15 -#endif bl cpu_init_crit #endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index b7492ac1fe..c02c015096 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -30,6 +30,10 @@ struct fel_stash { uint32_t sp; uint32_t lr; + uint32_t cpsr; + uint32_t sctlr; + uint32_t vbar; + uint32_t cr; }; struct fel_stash fel_stash __attribute__((section(".data"))); @@ -108,15 +112,34 @@ void s_init(void) */ u32 spl_boot_device(void) { +#ifdef CONFIG_SPL_FEL /* - * Have we been asked to return to the FEL portion of the boot ROM? - * TODO: We need a more robust test here, or bracket this with - * #ifdef CONFIG_SPL_FEL. + * This is the legacy compile time configuration for a special FEL + * enabled build. It has many restrictions and can only boot over USB. */ - if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000) + return BOOT_DEVICE_BOARD; +#else + /* + * When booting from the SD card, the "eGON.BT0" signature is expected + * to be found in memory at the address 0x0004 (see the "mksunxiboot" + * tool, which generates this header). + * + * When booting in the FEL mode over USB, this signature is patched in + * memory and replaced with something else by the 'fel' tool. This other + * signature is selected in such a way, that it can't be present in a + * valid bootable SD card image (because the BROM would refuse to + * execute the SPL in this case). + * + * This branch is just making a decision at runtime whether to load + * the main u-boot binary from the SD card (if the "eGON.BT0" signature + * is found) or return to the FEL code in the BROM to wait and receive + * the main u-boot binary over USB. + */ + if (readl(4) == 0x4E4F4765 && readl(8) == 0x3054422E) /* eGON.BT0 */ + return BOOT_DEVICE_MMC1; + else return BOOT_DEVICE_BOARD; - - return BOOT_DEVICE_MMC1; +#endif } /* No confirmation data available in SPL yet. Hardcode bootmode */ diff --git a/arch/arm/cpu/armv7/sunxi/fel_utils.S b/arch/arm/cpu/armv7/sunxi/fel_utils.S index 0c1de52df8..bf0033552d 100644 --- a/arch/arm/cpu/armv7/sunxi/fel_utils.S +++ b/arch/arm/cpu/armv7/sunxi/fel_utils.S @@ -15,11 +15,28 @@ ENTRY(save_boot_params) ldr r0, =fel_stash str sp, [r0, #0] str lr, [r0, #4] + mrs lr, cpsr @ Read CPSR + str lr, [r0, #8] + mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR Register + str lr, [r0, #12] + mrc p15, 0, lr, c12, c0, 0 @ Read VBAR + str lr, [r0, #16] + mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control Register + str lr, [r0, #20] b save_boot_params_ret ENDPROC(save_boot_params) ENTRY(return_to_fel) mov sp, r0 mov lr, r1 + ldr r0, =fel_stash + ldr r1, [r0, #20] + mcr p15, 0, r1, c1, c0, 0 @ Write CP15 Control Register + ldr r1, [r0, #16] + mcr p15, 0, r1, c12, c0, 0 @ Write VBAR + ldr r1, [r0, #12] + mcr p15, 0, r1, c1, c0, 0 @ Write CP15 SCTLR Register + ldr r1, [r0, #8] + msr cpsr, r1 @ Write CPSR bx lr ENDPROC(return_to_fel) -- cgit From 6eefd5279c4e80d613420066364ec3c8ba551a56 Mon Sep 17 00:00:00 2001 From: David Feng Date: Mon, 2 Feb 2015 16:53:13 +0800 Subject: PCI: add 64-bit prefetchable memory support PCI specification allow prefetchable memory to be 32-bit or 64-bit. PCI express specification states that all memmory bars for prefetchable memory must be implemented as 64-bit. They all require that 64 bit prefetchble memory are suported especially when u-boot is ported to more and more 64bit processors. Signed-off-by: David Feng Reviewed-by: Bin Meng --- drivers/pci/pci_auto.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index ed92857406..378efbfd9f 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -223,9 +223,12 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_prefetch = hose->pci_prefetch; struct pci_region *pci_io = hose->pci_io; - u16 cmdstat; + u16 cmdstat, prefechable_64; pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE, + &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, @@ -252,12 +255,26 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, /* Set up memory and I/O filter limits, assume 32-bit I/O space */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, (pci_prefetch->bus_lower & 0xfff00000) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + pci_hose_write_config_dword(hose, dev, + PCI_PREF_BASE_UPPER32, + pci_prefetch->bus_lower >> 32); +#else + pci_hose_write_config_dword(hose, dev, + PCI_PREF_BASE_UPPER32, + 0x0); +#endif cmdstat |= PCI_COMMAND_MEMORY; } else { /* We don't support prefetchable memory for now, so disable */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) { + pci_hose_write_config_word(hose, dev, PCI_PREF_BASE_UPPER32, 0x0); + pci_hose_write_config_word(hose, dev, PCI_PREF_LIMIT_UPPER32, 0x0); + } } if (pci_io) { @@ -297,11 +314,28 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, } if (pci_prefetch) { + u16 prefechable_64; + + pci_hose_read_config_word(hose, dev, + PCI_PREF_MEMORY_LIMIT, + &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; + /* Round memory allocator to 1MB boundary */ pciauto_region_align(pci_prefetch, 0x100000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, (pci_prefetch->bus_lower - 1) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + pci_hose_write_config_dword(hose, dev, + PCI_PREF_LIMIT_UPPER32, + (pci_prefetch->bus_lower - 1) >> 32); +#else + pci_hose_write_config_dword(hose, dev, + PCI_PREF_LIMIT_UPPER32, + 0x0); +#endif } if (pci_io) { -- cgit From 30d06bd2fd70c2e940324f88d06aaeb2a7b61efe Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 3 Feb 2015 10:34:10 +0100 Subject: .travis.yml: remove 824x builds remove powerpc 824x build, as this architecture not longer exists. Signed-off-by: Heiko Schocher --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 90f0fd7615..923c9ddc3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -106,9 +106,6 @@ matrix: - env: - TEST_CMD="tools/buildman/buildman mpc512x" INSTALL_TOOLCHAIN="ppc" - - env: - - TEST_CMD="tools/buildman/buildman mpc824x" - INSTALL_TOOLCHAIN="ppc" - env: - TEST_CMD="tools/buildman/buildman mpc8260" INSTALL_TOOLCHAIN="ppc" -- cgit From b9ea0c3a2076c3ef8c150d35aa31f2329ad9efef Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 6 Feb 2015 09:31:36 +0100 Subject: spl, spl_nor: fix compiler warning executing "tools/buildman/buildman mpc5xx" drops this warning: common/spl/spl_nor.c: In function 'spl_nor_load_image': common/spl/spl_nor.c:26:10: warning: assignment discards 'const' qualifier from pointer target type [enabled by default] fix this. Signed-off-by: Heiko Schocher --- common/spl/spl_nor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 2c0e8e00dd..c2fee01ac1 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -17,7 +17,7 @@ void spl_nor_load_image(void) #ifdef CONFIG_SPL_OS_BOOT if (!spl_start_uboot()) { - struct image_header *header; + const struct image_header *header; /* * Load Linux from its location in NOR flash to its defined -- cgit From 16ac90c7ee6fe973ee86fa9b08f876e5c33751bc Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:13 +0100 Subject: KM/IVM: split the IVM reading and parsing in 2 parts This allows to first read the IVM content (earlier in the boot sequence) and define the ethaddr env variable thanks to the ivm_read_eepromi(). Later, the IVM content can be parsed and used to define some hush variables, when the hush subsystem is available thanks to ivm_analyze_eeprom(). To avoid the HW read to happen twice, the buffer passed to ivm_read_eeprom() has to be reused by ivm_analyze_eeprom (and thus allocated before calling ivm_read_eeprom()). Signed-off-by: Valentin Longchamp --- board/keymile/common/common.h | 2 + board/keymile/common/ivm.c | 86 ++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index e075f4687b..7e16d2570b 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -127,6 +127,8 @@ struct bfticu_iomap { int ethernet_present(void); int ivm_read_eeprom(void); +int ivm_simple_read_eeprom(unsigned char *buf, int len); +int ivm_analyze_eeprom(unsigned char *buf, int len); int trigger_fpga_config(void); int wait_for_fpga_config(void); diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c index b6b19ccb8e..9abc09abc6 100644 --- a/board/keymile/common/ivm.c +++ b/board/keymile/common/ivm.c @@ -10,6 +10,8 @@ #include #include "common.h" +#define MAC_STR_SZ 20 + static int ivm_calc_crc(unsigned char *buf, int len) { const unsigned short crc_tab[16] = { @@ -185,45 +187,37 @@ static int ivm_check_crc(unsigned char *buf, int block) return 0; } -static int calculate_mac_offset(unsigned char *valbuf, unsigned char *buf, +/* take care of the possible MAC address offset and the IVM content offset */ +static int process_mac(unsigned char *valbuf, unsigned char *buf, int offset) { + unsigned char mac[6]; unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6]; - if (offset == 0) - return 0; + /* use an intermediate buffer, to not change IVM content + * MAC address is at offset 1 + */ + memcpy(mac, buf+1, 6); - val += offset; - buf[4] = (val >> 16) & 0xff; - buf[5] = (val >> 8) & 0xff; - buf[6] = val & 0xff; - sprintf((char *)valbuf, "%pM", buf + 1); + if (offset) { + val += offset; + mac[3] = (val >> 16) & 0xff; + mac[4] = (val >> 8) & 0xff; + mac[5] = val & 0xff; + } + + sprintf((char *)valbuf, "%pM", mac); return 0; } static int ivm_analyze_block2(unsigned char *buf, int len) { - unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; + unsigned char valbuf[MAC_STR_SZ]; unsigned long count; /* IVM_MAC Adress begins at offset 1 */ sprintf((char *)valbuf, "%pM", buf + 1); ivm_set_value("IVM_MacAddress", (char *)valbuf); - /* if an offset is defined, add it */ - calculate_mac_offset(buf, valbuf, CONFIG_PIGGY_MAC_ADRESS_OFFSET); -#ifdef MACH_TYPE_KM_KIRKWOOD - setenv((char *)"ethaddr", (char *)valbuf); -#else - if (getenv("ethaddr") == NULL) - setenv((char *)"ethaddr", (char *)valbuf); -#endif -#ifdef CONFIG_KMVECT1 -/* KMVECT1 has two ethernet interfaces */ - if (getenv("eth1addr") == NULL) { - calculate_mac_offset(buf, valbuf, 1); - setenv((char *)"eth1addr", (char *)valbuf); - } -#endif /* IVM_MacCount */ count = (buf[10] << 24) + (buf[11] << 16) + @@ -236,7 +230,7 @@ static int ivm_analyze_block2(unsigned char *buf, int len) return 0; } -static int ivm_analyze_eeprom(unsigned char *buf, int len) +int ivm_analyze_eeprom(unsigned char *buf, int len) { unsigned short val; unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; @@ -296,6 +290,48 @@ static int ivm_analyze_eeprom(unsigned char *buf, int len) return 0; } +static int ivm_populate_env(unsigned char *buf, int len) +{ + unsigned char *page2; + unsigned char valbuf[MAC_STR_SZ]; + + /* do we have the page 2 filled ? if not return */ + if (ivm_check_crc(buf, 2)) + return 0; + page2 = &buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN*2]; + + /* if an offset is defined, add it */ + process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET); + if (getenv("ethaddr") == NULL) + setenv((char *)"ethaddr", (char *)valbuf); +#ifdef CONFIG_KMVECT1 +/* KMVECT1 has two ethernet interfaces */ + if (getenv("eth1addr") == NULL) { + process_mac(valbuf, page2, 1); + setenv((char *)"eth1addr", (char *)valbuf); + } +#endif + + return 0; +} + +int ivm_simple_read_eeprom(unsigned char *buf, int len) +{ + int ret; + + i2c_set_bus_num(CONFIG_KM_IVM_BUS); + /* add deblocking here */ + i2c_make_abort(); + + ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, buf, len); + if (ret != 0) { + printf("Error reading EEprom\n"); + return -2; + } + + return ivm_populate_env(buf, len); +} + int ivm_read_eeprom(void) { uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; -- cgit From 0bb95a68fc92bce3cc044ae3c006f6e33431617d Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:14 +0100 Subject: kirkwood/km_arm: read the IVM eeprom earlier This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r. Later, when HUSH is available the content read earlier is analyzed to populate some non env variables. Signed-off-by: Valentin Longchamp --- board/keymile/km_arm/km_arm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index 1c7c108cb5..6eb6712b39 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -102,6 +102,8 @@ static const u32 kwmpp_config[] = { 0 }; +static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + #if defined(CONFIG_KM_MGCOGE3UN) /* * Wait for startup OK from mgcoge3ne @@ -210,6 +212,8 @@ int misc_init_r(void) } #endif + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + initialize_unit_leds(); set_km_env(); set_bootcount_addr(); @@ -419,7 +423,7 @@ void reset_phy(void) #if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif -- cgit From 0fdb6eadff19da604ea8907140421ec07b8bcc19 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:15 +0100 Subject: 85xx/kmp204x: read the IVM eeprom earlier This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r. Later, when HUSH is available the content read earlier is analyzed to populate some non env variables. Signed-off-by: Valentin Longchamp --- board/keymile/kmp204x/kmp204x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index a74f75bad4..0f544fb979 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -26,6 +26,8 @@ DECLARE_GLOBAL_DATA_PTR; +static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + int checkboard(void) { printf("Board: Keymile %s\n", CONFIG_KM_BOARD_NAME); @@ -195,13 +197,14 @@ int misc_init_r(void) } } + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif -- cgit From f32b3d3fcec10dfc6a6848f8cc6a9eab9407aabf Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:16 +0100 Subject: 83xx/km83xx: read the IVM eeprom earlier This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r. Later, when HUSH is available the content read earlier is analyzed to populate some non env variables. Signed-off-by: Valentin Longchamp --- board/keymile/km83xx/km83xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index 1da0dcb9d8..fc68a2f41f 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -28,6 +28,8 @@ #include "../common/common.h" +static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + const qe_iop_conf_t qe_iop_conf_tab[] = { /* port pin dir open_drain assign */ #if defined(CONFIG_MPC8360) @@ -190,6 +192,7 @@ int board_early_init_r(void) int misc_init_r(void) { + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } @@ -370,7 +373,7 @@ int ft_board_setup(void *blob, bd_t *bd) #if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif -- cgit From 2973b098baf6fcb49d9fb7a2ed187e6a65532175 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:17 +0100 Subject: 82xx/km82xx: read the IVM eeprom earlier This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r. Later, when HUSH is available the content read earlier is analyzed to populate some non env variables. Signed-off-by: Valentin Longchamp --- board/keymile/km82xx/km82xx.c | 10 +++++++++- include/configs/km82xx.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/board/keymile/km82xx/km82xx.c b/board/keymile/km82xx/km82xx.c index bf84676b9b..c3a113172c 100644 --- a/board/keymile/km82xx/km82xx.c +++ b/board/keymile/km82xx/km82xx.c @@ -18,6 +18,8 @@ #include #include "../common/common.h" +static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + /* * I/O Port configuration table * @@ -393,9 +395,15 @@ int board_early_init_r(void) return 0; } +int misc_init_r(void) +{ + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + return 0; +} + int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } diff --git a/include/configs/km82xx.h b/include/configs/km82xx.h index 14fd290be1..12f9d424cb 100644 --- a/include/configs/km82xx.h +++ b/include/configs/km82xx.h @@ -34,6 +34,8 @@ #define CONFIG_SYS_TEXT_BASE 0xFE000000 +#define CONFIG_MISC_INIT_R + /* include common defines/options for all Keymile boards */ #include "km/keymile-common.h" #include "km/km-powerpc.h" -- cgit From 60c4ae00be11f07a9b60f95e76538785062f873b Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Tue, 10 Feb 2015 17:10:18 +0100 Subject: KM/IVM: remove ivm_read_eeprom(void) This is not used anymore since the procedure was split into a simple read function and a later alaysis. The ivm_read_eeprom name is now used for the previous ivm_simple_read_eeprom function. Signed-off-by: Valentin Longchamp --- board/keymile/common/common.h | 3 +-- board/keymile/common/ivm.c | 21 +-------------------- board/keymile/km82xx/km82xx.c | 2 +- board/keymile/km83xx/km83xx.c | 2 +- board/keymile/km_arm/km_arm.c | 2 +- board/keymile/kmp204x/kmp204x.c | 2 +- 6 files changed, 6 insertions(+), 26 deletions(-) diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index 7e16d2570b..dcfefc46b3 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -126,8 +126,7 @@ struct bfticu_iomap { #endif int ethernet_present(void); -int ivm_read_eeprom(void); -int ivm_simple_read_eeprom(unsigned char *buf, int len); +int ivm_read_eeprom(unsigned char *buf, int len); int ivm_analyze_eeprom(unsigned char *buf, int len); int trigger_fpga_config(void); diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c index 9abc09abc6..42db54221b 100644 --- a/board/keymile/common/ivm.c +++ b/board/keymile/common/ivm.c @@ -315,7 +315,7 @@ static int ivm_populate_env(unsigned char *buf, int len) return 0; } -int ivm_simple_read_eeprom(unsigned char *buf, int len) +int ivm_read_eeprom(unsigned char *buf, int len) { int ret; @@ -331,22 +331,3 @@ int ivm_simple_read_eeprom(unsigned char *buf, int len) return ivm_populate_env(buf, len); } - -int ivm_read_eeprom(void) -{ - uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; - int ret; - - i2c_set_bus_num(CONFIG_KM_IVM_BUS); - /* add deblocking here */ - i2c_make_abort(); - - ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, i2c_buffer, - CONFIG_SYS_IVM_EEPROM_MAX_LEN); - if (ret != 0) { - printf("Error reading EEprom\n"); - return -2; - } - - return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); -} diff --git a/board/keymile/km82xx/km82xx.c b/board/keymile/km82xx/km82xx.c index c3a113172c..c599b40936 100644 --- a/board/keymile/km82xx/km82xx.c +++ b/board/keymile/km82xx/km82xx.c @@ -397,7 +397,7 @@ int board_early_init_r(void) int misc_init_r(void) { - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index fc68a2f41f..89e9e1e57c 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -192,7 +192,7 @@ int board_early_init_r(void) int misc_init_r(void) { - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index 6eb6712b39..2938861f36 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -212,7 +212,7 @@ int misc_init_r(void) } #endif - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); initialize_unit_leds(); set_km_env(); diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 0f544fb979..eebb47fc21 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -197,7 +197,7 @@ int misc_init_r(void) } } - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } -- cgit From 0ce3f1f90ae6168805f20e473a9ed7fab5fb13a8 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 12 Feb 2015 00:24:20 +0200 Subject: ARM: lpc3250: config: add generic board support The only LPC3250 board works fine with enabled generic board support, add CONFIG_SYS_GENERIC_BOARD right into the arch config header. Signed-off-by: Vladimir Zapolskiy --- arch/arm/include/asm/arch-lpc32xx/config.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-lpc32xx/config.h b/arch/arm/include/asm/arch-lpc32xx/config.h index 8f6426bc1b..564441cbfa 100644 --- a/arch/arm/include/asm/arch-lpc32xx/config.h +++ b/arch/arm/include/asm/arch-lpc32xx/config.h @@ -1,7 +1,7 @@ /* * Common definitions for LPC32XX board configurations * - * Copyright (C) 2011 Vladimir Zapolskiy + * Copyright (C) 2011-2015 Vladimir Zapolskiy * * SPDX-License-Identifier: GPL-2.0+ */ @@ -9,6 +9,8 @@ #ifndef _LPC32XX_CONFIG_H #define _LPC32XX_CONFIG_H +#define CONFIG_SYS_GENERIC_BOARD + /* Basic CPU architecture */ #define CONFIG_ARCH_CPU_INIT -- cgit From de19eddf6c196669222839b3f39a38d0315bdb3e Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 16 Feb 2015 05:59:09 +0100 Subject: add example for file on VFAT filesystem usage For example on a raspberry pi the u-boot environment can be saved in a file on the first VFAT partition. This example illustrates how to use it with fw_printenv/fw_setenv. Signed-off-by: Waldemar Brodkorb --- tools/env/fw_env.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config index c9b9f6a160..6f216f9c64 100644 --- a/tools/env/fw_env.config +++ b/tools/env/fw_env.config @@ -20,3 +20,6 @@ # Block device example #/dev/mmcblk0 0xc0000 0x20000 + +# VFAT example +#/boot/uboot.env 0x0000 0x4000 -- cgit From 5290ab876e18d87bd51e29520494abc6473806ec Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 16 Feb 2015 15:48:49 -0500 Subject: Revert "sunxi: configs/sunxi-common.h: Enable CONFIG_CMD_PART" This reverts commit bd2a4888b123713adec271d6c8040ca9f609aa2f which was an older version of af21f2f which is what we actually want in. Signed-off-by: Tom Rini --- include/configs/sunxi-common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 5e8885277f..1238d821b3 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -79,9 +79,6 @@ #define CONFIG_CMD_MEMORY #define CONFIG_CMD_SETEXPR -#define CONFIG_PARTITION_UUIDS -#define CONFIG_CMD_PART - #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_CMDLINE_TAG #define CONFIG_INITRD_TAG -- cgit From 1e7b357a4ebf9a99a6258a0bbedf4e318a5263e0 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 17 Feb 2015 11:07:19 -0500 Subject: Prepare v2015.04-rc2 Signed-off-by: Tom Rini --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0538821b5c..bd4ababe00 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2015 PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = # *DOCUMENTATION* -- cgit From dbdb5abd070163f59901884c672b49c25b1aeea9 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:39 +0100 Subject: avr32: use dlmalloc for DMA buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann --- arch/avr32/include/asm/dma-mapping.h | 7 ++++- arch/avr32/lib/board.c | 51 ------------------------------------ include/configs/atngw100.h | 1 - include/configs/atngw100mkii.h | 1 - include/configs/atstk1002.h | 1 - include/configs/atstk1006.h | 1 - include/configs/favr-32-ezkit.h | 1 - include/configs/grasshopper.h | 1 - include/configs/hammerhead.h | 1 - include/configs/mimc200.h | 1 - 10 files changed, 6 insertions(+), 60 deletions(-) diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h index dbdd2fee38..1cde8275f4 100644 --- a/arch/avr32/include/asm/dma-mapping.h +++ b/arch/avr32/include/asm/dma-mapping.h @@ -14,7 +14,12 @@ enum dma_data_direction { DMA_TO_DEVICE = 1, DMA_FROM_DEVICE = 2, }; -extern void *dma_alloc_coherent(size_t len, unsigned long *handle); + +static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) +{ + *handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len); + return (void *)*handle; +} static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index bf0997f98d..7d13ac534b 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -45,50 +45,6 @@ int cpu_mmc_init(bd_t *bd) return atmel_mci_init((void *)ATMEL_BASE_MMCI); } -#ifdef CONFIG_SYS_DMA_ALLOC_LEN -#include -#include - -static unsigned long dma_alloc_start; -static unsigned long dma_alloc_end; -static unsigned long dma_alloc_brk; - -static void dma_alloc_init(void) -{ - unsigned long monitor_addr; - - monitor_addr = CONFIG_SYS_MONITOR_BASE + gd->reloc_off; - dma_alloc_end = monitor_addr - CONFIG_SYS_MALLOC_LEN; - dma_alloc_start = dma_alloc_end - CONFIG_SYS_DMA_ALLOC_LEN; - dma_alloc_brk = dma_alloc_start; - - printf("DMA: Using memory from 0x%08lx to 0x%08lx\n", - dma_alloc_start, dma_alloc_end); - - invalidate_dcache_range((unsigned long)cached(dma_alloc_start), - dma_alloc_end); -} - -void *dma_alloc_coherent(size_t len, unsigned long *handle) -{ - unsigned long paddr = dma_alloc_brk; - - if (dma_alloc_brk + len > dma_alloc_end) - return NULL; - - dma_alloc_brk = ((paddr + len + CONFIG_SYS_DCACHE_LINESZ - 1) - & ~(CONFIG_SYS_DCACHE_LINESZ - 1)); - - *handle = paddr; - return uncached(paddr); -} -#else -static inline void dma_alloc_init(void) -{ - -} -#endif - static int init_baudrate(void) { gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); @@ -180,12 +136,6 @@ void board_init_f(ulong board_type) /* Reserve memory for malloc() */ addr -= CONFIG_SYS_MALLOC_LEN; -#ifdef CONFIG_SYS_DMA_ALLOC_LEN - /* Reserve DMA memory (must be cache aligned) */ - addr &= ~(CONFIG_SYS_DCACHE_LINESZ - 1); - addr -= CONFIG_SYS_DMA_ALLOC_LEN; -#endif - #ifdef CONFIG_LCD #ifdef CONFIG_FB_ADDR printf("LCD: Frame buffer allocated at preset 0x%08x\n", @@ -264,7 +214,6 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) /* The malloc area is right below the monitor image in RAM */ mem_malloc_init(CONFIG_SYS_MONITOR_BASE + gd->reloc_off - CONFIG_SYS_MALLOC_LEN, CONFIG_SYS_MALLOC_LEN); - dma_alloc_init(); enable_interrupts(); diff --git a/include/configs/atngw100.h b/include/configs/atngw100.h index 9c81e3199f..540e86ae47 100644 --- a/include/configs/atngw100.h +++ b/include/configs/atngw100.h @@ -143,7 +143,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/atngw100mkii.h b/include/configs/atngw100mkii.h index 7b4f9cf206..35eae76930 100644 --- a/include/configs/atngw100mkii.h +++ b/include/configs/atngw100mkii.h @@ -164,7 +164,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h index 8f3fd0bb00..9e58238f1d 100644 --- a/include/configs/atstk1002.h +++ b/include/configs/atstk1002.h @@ -158,7 +158,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/atstk1006.h b/include/configs/atstk1006.h index bbe0aea861..25090a68fa 100644 --- a/include/configs/atstk1006.h +++ b/include/configs/atstk1006.h @@ -159,7 +159,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/favr-32-ezkit.h b/include/configs/favr-32-ezkit.h index 338d3dc782..75bff4ce28 100644 --- a/include/configs/favr-32-ezkit.h +++ b/include/configs/favr-32-ezkit.h @@ -162,7 +162,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/grasshopper.h b/include/configs/grasshopper.h index 73534addfc..83f0ed2a62 100644 --- a/include/configs/grasshopper.h +++ b/include/configs/grasshopper.h @@ -151,7 +151,6 @@ CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) diff --git a/include/configs/hammerhead.h b/include/configs/hammerhead.h index 4f0603abc1..0bc42f12e0 100644 --- a/include/configs/hammerhead.h +++ b/include/configs/hammerhead.h @@ -137,7 +137,6 @@ #define CONFIG_SYS_MALLOC_LEN (256*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x00400000) diff --git a/include/configs/mimc200.h b/include/configs/mimc200.h index fc7ecfaee4..2fd3addc1a 100644 --- a/include/configs/mimc200.h +++ b/include/configs/mimc200.h @@ -157,7 +157,6 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) #define CONFIG_SYS_MALLOC_LEN (1024*1024) -#define CONFIG_SYS_DMA_ALLOC_LEN (16384) /* Allow 4MB for the kernel run-time image */ #define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) -- cgit From aa0ea2a5538ab7b0f3e8975a27ab8c0a764a69cd Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:40 +0100 Subject: avr32: rename cpu_init() -> arch_cpu_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann Reviewed-by: Simon Glass --- arch/avr32/cpu/cpu.c | 2 +- arch/avr32/include/asm/u-boot.h | 2 ++ arch/avr32/lib/board.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/avr32/cpu/cpu.c b/arch/avr32/cpu/cpu.c index cef630ed45..cd226a6f71 100644 --- a/arch/avr32/cpu/cpu.c +++ b/arch/avr32/cpu/cpu.c @@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; -int cpu_init(void) +int arch_cpu_init(void) { extern void _evba(void); diff --git a/arch/avr32/include/asm/u-boot.h b/arch/avr32/include/asm/u-boot.h index 6aef808749..2387f8af62 100644 --- a/arch/avr32/include/asm/u-boot.h +++ b/arch/avr32/include/asm/u-boot.h @@ -25,4 +25,6 @@ typedef struct bd_info { /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_AVR32 +int arch_cpu_init(void); + #endif /* __ASM_U_BOOT_H__ */ diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 7d13ac534b..95f95266f1 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -98,7 +98,7 @@ void board_init_f(ulong board_type) /* Perform initialization sequence */ board_early_init_f(); - cpu_init(); + arch_cpu_init(); board_postclk_init(); env_init(); init_baudrate(); -- cgit From 26db7903f5102b8cf5570237ccbfc7f2c0dfd7aa Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:41 +0100 Subject: avr32: factor out cpu_mmc_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpu_mmc_init() is required by the init sequence to have a working MMC interface on avr32. This will not be included in the binary if we omit the avr32 board.c when building the generic board. Signed-off-by: Andreas Bießmann --- arch/avr32/cpu/Makefile | 1 + arch/avr32/cpu/mmc.c | 16 ++++++++++++++++ arch/avr32/lib/board.c | 8 -------- 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 arch/avr32/cpu/mmc.c diff --git a/arch/avr32/cpu/Makefile b/arch/avr32/cpu/Makefile index 00cede3fd9..e111db3e75 100644 --- a/arch/avr32/cpu/Makefile +++ b/arch/avr32/cpu/Makefile @@ -16,5 +16,6 @@ obj-y += cache.o obj-y += interrupts.o obj-$(CONFIG_PORTMUX_PIO) += portmux-pio.o obj-$(CONFIG_PORTMUX_GPIO) += portmux-gpio.o +obj-y += mmc.o obj-$(if $(filter at32ap700x,$(SOC)),y) += at32ap700x/ diff --git a/arch/avr32/cpu/mmc.c b/arch/avr32/cpu/mmc.c new file mode 100644 index 0000000000..b7213e4e7a --- /dev/null +++ b/arch/avr32/cpu/mmc.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * Copyright (C) 2015 Andreas Bießmann + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include + +/* provide cpu_mmc_init, to overwrite provide board_mmc_init */ +int cpu_mmc_init(bd_t *bd) +{ + /* This calls the atmel_mci_init in gen_atmel_mci.c */ + return atmel_mci_init((void *)ATMEL_BASE_MMCI); +} diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 95f95266f1..e86530fe77 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -9,7 +9,6 @@ #include #include #include -#include #ifdef CONFIG_BITBANGMII #include @@ -38,13 +37,6 @@ static int __do_nothing(void) int board_postclk_init(void) __attribute__((weak, alias("__do_nothing"))); int board_early_init_r(void) __attribute__((weak, alias("__do_nothing"))); -/* provide cpu_mmc_init, to overwrite provide board_mmc_init */ -int cpu_mmc_init(bd_t *bd) -{ - /* This calls the atmel_mci_init in gen_atmel_mci.c */ - return atmel_mci_init((void *)ATMEL_BASE_MMCI); -} - static int init_baudrate(void) { gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); -- cgit From e9ed41cc5c684b4b08988934544449eb782c14db Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:42 +0100 Subject: avr32: rename mmu.h definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefix mmu.h PAGE_xxx definitions with MMU_ in order to prevent a naming conflict with other definitions. Signed-off-by: Andreas Bießmann --- arch/avr32/cpu/at32ap700x/mmu.c | 8 ++++---- arch/avr32/include/asm/arch-at32ap700x/mmu.h | 6 +++--- board/atmel/atngw100/atngw100.c | 12 ++++++------ board/atmel/atngw100mkii/atngw100mkii.c | 18 +++++++++--------- board/atmel/atstk1000/atstk1000.c | 12 ++++++------ board/earthlcd/favr-32-ezkit/favr-32-ezkit.c | 12 ++++++------ board/in-circuit/grasshopper/grasshopper.c | 12 ++++++------ board/mimc/mimc200/mimc200.c | 18 +++++++++--------- board/miromico/hammerhead/hammerhead.c | 12 ++++++------ 9 files changed, 55 insertions(+), 55 deletions(-) diff --git a/arch/avr32/cpu/at32ap700x/mmu.c b/arch/avr32/cpu/at32ap700x/mmu.c index 0e28b21eef..f5e62f27eb 100644 --- a/arch/avr32/cpu/at32ap700x/mmu.c +++ b/arch/avr32/cpu/at32ap700x/mmu.c @@ -7,7 +7,7 @@ void mmu_init_r(unsigned long dest_addr) uintptr_t vmr_table_addr; /* Round monitor address down to the nearest page boundary */ - dest_addr &= PAGE_ADDR_MASK; + dest_addr &= MMU_PAGE_ADDR_MASK; /* Initialize TLB entry 0 to cover the monitor, and lock it */ sysreg_write(TLBEHI, dest_addr | SYSREG_BIT(TLBEHI_V)); @@ -36,7 +36,7 @@ int mmu_handle_tlb_miss(void) unsigned int fault_pgno; int first, last; - fault_pgno = sysreg_read(TLBEAR) >> PAGE_SHIFT; + fault_pgno = sysreg_read(TLBEAR) >> MMU_PAGE_SHIFT; vmr_table = (const struct mmu_vm_range *)sysreg_read(PTBR); /* Do a binary search through the VM ranges */ @@ -60,8 +60,8 @@ int mmu_handle_tlb_miss(void) /* Got it; let's slam it into the TLB */ uint32_t tlbelo; - tlbelo = vmr->phys & ~PAGE_ADDR_MASK; - tlbelo |= fault_pgno << PAGE_SHIFT; + tlbelo = vmr->phys & ~MMU_PAGE_ADDR_MASK; + tlbelo |= fault_pgno << MMU_PAGE_SHIFT; sysreg_write(TLBELO, tlbelo); __builtin_tlbw(); diff --git a/arch/avr32/include/asm/arch-at32ap700x/mmu.h b/arch/avr32/include/asm/arch-at32ap700x/mmu.h index fcd9a05609..4736312f5d 100644 --- a/arch/avr32/include/asm/arch-at32ap700x/mmu.h +++ b/arch/avr32/include/asm/arch-at32ap700x/mmu.h @@ -13,9 +13,9 @@ #include -#define PAGE_SHIFT 20 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_ADDR_MASK (~(PAGE_SIZE - 1)) +#define MMU_PAGE_SHIFT 20 +#define MMU_PAGE_SIZE (1UL << MMU_PAGE_SHIFT) +#define MMU_PAGE_ADDR_MASK (~(MMU_PAGE_SIZE - 1)) #define MMU_VMR_CACHE_NONE \ (SYSREG_BF(AP, 3) | SYSREG_BF(SZ, 3) | SYSREG_BIT(TLBELO_D)) diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c index 03d767a4a8..ed09c8c7e4 100644 --- a/board/atmel/atngw100/atngw100.c +++ b/board/atmel/atngw100/atngw100.c @@ -18,14 +18,14 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/atmel/atngw100mkii/atngw100mkii.c b/board/atmel/atngw100mkii/atngw100mkii.c index 72d19e430e..912ea10fe4 100644 --- a/board/atmel/atngw100mkii/atngw100mkii.c +++ b/board/atmel/atngw100mkii/atngw100mkii.c @@ -23,21 +23,21 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { /* Atmel AT49BV640D 8 MiB x16 NOR flash on NCS0 */ - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { /* Micron MT29F2G16AAD 256 MiB x16 NAND flash on NCS3 */ - .virt_pgno = EBI_SRAM_CS3_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SRAM_CS3_SIZE >> PAGE_SHIFT, - .phys = (EBI_SRAM_CS3_BASE >> PAGE_SHIFT) + .virt_pgno = EBI_SRAM_CS3_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SRAM_CS3_SIZE >> MMU_PAGE_SHIFT, + .phys = (EBI_SRAM_CS3_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { /* 2x16-bit ISSI IS42S16320B 64 MiB SDRAM (128 MiB total) */ - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c index 4b6b90f683..f3546946c4 100644 --- a/board/atmel/atstk1000/atstk1000.c +++ b/board/atmel/atstk1000/atstk1000.c @@ -17,14 +17,14 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c index a74547bf65..f9fde793f5 100644 --- a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c +++ b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c @@ -17,14 +17,14 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/in-circuit/grasshopper/grasshopper.c b/board/in-circuit/grasshopper/grasshopper.c index 340b713188..2ac54db295 100644 --- a/board/in-circuit/grasshopper/grasshopper.c +++ b/board/in-circuit/grasshopper/grasshopper.c @@ -18,14 +18,14 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/mimc/mimc200/mimc200.c b/board/mimc/mimc200/mimc200.c index 2ad53ec2ab..186ac7df62 100644 --- a/board/mimc/mimc200/mimc200.c +++ b/board/mimc/mimc200/mimc200.c @@ -20,19 +20,19 @@ struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = EBI_SRAM_CS2_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SRAM_CS2_SIZE >> PAGE_SHIFT, - .phys = (EBI_SRAM_CS2_BASE >> PAGE_SHIFT) + .virt_pgno = EBI_SRAM_CS2_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SRAM_CS2_SIZE >> MMU_PAGE_SHIFT, + .phys = (EBI_SRAM_CS2_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; diff --git a/board/miromico/hammerhead/hammerhead.c b/board/miromico/hammerhead/hammerhead.c index d82fee7b90..e9a9e4b3cf 100644 --- a/board/miromico/hammerhead/hammerhead.c +++ b/board/miromico/hammerhead/hammerhead.c @@ -21,14 +21,14 @@ DECLARE_GLOBAL_DATA_PTR; struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { { - .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, - .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_NONE, }, { - .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, - .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, - .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> MMU_PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> MMU_PAGE_SHIFT) | MMU_VMR_CACHE_WRBACK, }, }; -- cgit From 186678600a3aa81f883e4bf4b94ca4d40081d93a Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:43 +0100 Subject: avr32: convert to dram_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann Reviewed-by: Simon Glass --- arch/avr32/include/asm/u-boot.h | 1 + arch/avr32/lib/Makefile | 1 + arch/avr32/lib/board.c | 20 ++++++++++---------- arch/avr32/lib/dram_init.c | 17 +++++++++++++++++ board/atmel/atngw100/atngw100.c | 20 ++------------------ board/atmel/atngw100mkii/atngw100mkii.c | 21 +++------------------ board/atmel/atstk1000/atstk1000.c | 21 +++------------------ board/earthlcd/favr-32-ezkit/favr-32-ezkit.c | 21 +++------------------ board/in-circuit/grasshopper/grasshopper.c | 20 ++------------------ board/mimc/mimc200/mimc200.c | 20 ++------------------ board/miromico/hammerhead/hammerhead.c | 20 ++------------------ 11 files changed, 46 insertions(+), 136 deletions(-) create mode 100644 arch/avr32/lib/dram_init.c diff --git a/arch/avr32/include/asm/u-boot.h b/arch/avr32/include/asm/u-boot.h index 2387f8af62..232350ead8 100644 --- a/arch/avr32/include/asm/u-boot.h +++ b/arch/avr32/include/asm/u-boot.h @@ -26,5 +26,6 @@ typedef struct bd_info { #define IH_ARCH_DEFAULT IH_ARCH_AVR32 int arch_cpu_init(void); +int dram_init(void); #endif /* __ASM_U_BOOT_H__ */ diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile index bb45cbe153..5f2d97bfc7 100644 --- a/arch/avr32/lib/Makefile +++ b/arch/avr32/lib/Makefile @@ -11,3 +11,4 @@ obj-y += memset.o obj-y += board.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += interrupts.o +obj-y += dram_init.o diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index e86530fe77..13b7fede74 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -29,6 +29,12 @@ DECLARE_GLOBAL_DATA_PTR; unsigned long monitor_flash_len; +__weak void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} + /* Weak aliases for optional board functions */ static int __do_nothing(void) { @@ -82,7 +88,6 @@ void board_init_f(ulong board_type) unsigned long monitor_len; unsigned long monitor_addr; unsigned long addr; - long sdram_size; /* Initialize the global data pointer */ memset(&gd_data, 0, sizeof(gd_data)); @@ -97,10 +102,10 @@ void board_init_f(ulong board_type) serial_init(); console_init_f(); display_banner(); - sdram_size = initdram(board_type); + dram_init(); /* If we have no SDRAM, we can't go on */ - if (sdram_size <= 0) + if (gd->ram_size <= 0) panic("No working SDRAM available\n"); /* @@ -114,7 +119,7 @@ void board_init_f(ulong board_type) * - global data struct * - stack */ - addr = CONFIG_SYS_SDRAM_BASE + sdram_size; + addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; monitor_len = (char *)(&__bss_end) - _text; /* @@ -156,12 +161,7 @@ void board_init_f(ulong board_type) *(--new_sp) = 0; *(--new_sp) = 0; - /* - * Initialize the board information struct with the - * information we have. - */ - bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - bd->bi_dram[0].size = sdram_size; + dram_init_banksize(); memcpy(new_gd, gd, sizeof(gd_t)); diff --git a/arch/avr32/lib/dram_init.c b/arch/avr32/lib/dram_init.c new file mode 100644 index 0000000000..5078e77f17 --- /dev/null +++ b/arch/avr32/lib/dram_init.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2015 Andreas Bießmann + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + /* check for the maximum amount of memory possible on AP7000 devices */ + gd->ram_size = get_ram_size( + (void *)CONFIG_SYS_SDRAM_BASE, + (256<<20)); + return 0; +} diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c index ed09c8c7e4..dacd427831 100644 --- a/board/atmel/atngw100/atngw100.c +++ b/board/atmel/atngw100/atngw100.c @@ -52,6 +52,8 @@ int board_early_init_f(void) hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE)); portmux_enable_ebi(16, 23, 0, PORTMUX_DRIVE_HIGH); + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); #if defined(CONFIG_MACB) @@ -68,24 +70,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x01; diff --git a/board/atmel/atngw100mkii/atngw100mkii.c b/board/atmel/atngw100mkii/atngw100mkii.c index 912ea10fe4..8e215d5fcf 100644 --- a/board/atmel/atngw100mkii/atngw100mkii.c +++ b/board/atmel/atngw100mkii/atngw100mkii.c @@ -69,6 +69,9 @@ int board_early_init_f(void) portmux_select_gpio(PORTMUX_PORT_E, 1 << 23, PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH | PORTMUX_DRIVE_MIN); + + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); #if defined(CONFIG_MACB) @@ -85,24 +88,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x01; diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c index f3546946c4..fd4363bece 100644 --- a/board/atmel/atstk1000/atstk1000.c +++ b/board/atmel/atstk1000/atstk1000.c @@ -78,7 +78,10 @@ int board_early_init_f(void) hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE)); portmux_enable_ebi(sdram_config.data_bits, 23, 0, PORTMUX_DRIVE_HIGH); + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); + #if defined(CONFIG_MACB) portmux_enable_macb0(PORTMUX_MACB_MII, PORTMUX_DRIVE_LOW); portmux_enable_macb1(PORTMUX_MACB_MII, PORTMUX_DRIVE_LOW); @@ -90,24 +93,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x10; diff --git a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c index f9fde793f5..f9ac330c33 100644 --- a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c +++ b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c @@ -52,6 +52,9 @@ int board_early_init_f(void) hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE)); portmux_enable_ebi(32, 23, 0, PORTMUX_DRIVE_HIGH); + + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart3(PORTMUX_DRIVE_MIN); #if defined(CONFIG_MACB) portmux_enable_macb0(PORTMUX_MACB_MII, PORTMUX_DRIVE_HIGH); @@ -63,24 +66,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x01; diff --git a/board/in-circuit/grasshopper/grasshopper.c b/board/in-circuit/grasshopper/grasshopper.c index 2ac54db295..91b41162de 100644 --- a/board/in-circuit/grasshopper/grasshopper.c +++ b/board/in-circuit/grasshopper/grasshopper.c @@ -53,6 +53,8 @@ int board_early_init_f(void) hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE)); portmux_enable_ebi(SDRAM_DATA_32BIT, 23, 0, PORTMUX_DRIVE_HIGH); + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart0(PORTMUX_DRIVE_MIN); portmux_enable_usart1(PORTMUX_DRIVE_MIN); #if defined(CONFIG_MACB) @@ -69,24 +71,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x00; diff --git a/board/mimc/mimc200/mimc200.c b/board/mimc/mimc200/mimc200.c index 186ac7df62..f078295508 100644 --- a/board/mimc/mimc200/mimc200.c +++ b/board/mimc/mimc200/mimc200.c @@ -91,6 +91,8 @@ int board_early_init_f(void) /* Enable 26 address bits and NCS2 */ portmux_enable_ebi(16, 26, PORTMUX_EBI_CS(2), PORTMUX_DRIVE_HIGH); + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); /* de-assert "force sys reset" pin */ @@ -151,24 +153,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x01; diff --git a/board/miromico/hammerhead/hammerhead.c b/board/miromico/hammerhead/hammerhead.c index e9a9e4b3cf..a0c7d3b323 100644 --- a/board/miromico/hammerhead/hammerhead.c +++ b/board/miromico/hammerhead/hammerhead.c @@ -63,6 +63,8 @@ int board_early_init_f(void) hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE)); portmux_enable_ebi(32, 23, 0, PORTMUX_DRIVE_HIGH); + sdram_init(uncached(EBI_SDRAM_BASE), &sdram_config); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); #if defined(CONFIG_MACB) @@ -74,24 +76,6 @@ int board_early_init_f(void) return 0; } -phys_size_t initdram(int board_type) -{ - unsigned long expected_size; - unsigned long actual_size; - void *sdram_base; - - sdram_base = uncached(EBI_SDRAM_BASE); - - expected_size = sdram_init(sdram_base, &sdram_config); - actual_size = get_ram_size(sdram_base, expected_size); - - if (expected_size != actual_size) - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - - return actual_size; -} - int board_early_init_r(void) { gd->bd->bi_phy_id[0] = 0x01; -- cgit From 4db896236cdac37db17b215ba3ff2d2701bddb49 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:44 +0100 Subject: avr32: use generic gd->start_addr_sp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before avr32 had an extra storage for stack end to have a nice stack printout on exception. Remove this extra storage and use generic gd->start_addr_sp instead. Signed-off-by: Andreas Bießmann --- arch/avr32/cpu/exception.c | 6 +++--- arch/avr32/include/asm/global_data.h | 1 - arch/avr32/lib/board.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/avr32/cpu/exception.c b/arch/avr32/cpu/exception.c index 5d1bc689f8..d6991f6668 100644 --- a/arch/avr32/cpu/exception.c +++ b/arch/avr32/cpu/exception.c @@ -96,11 +96,11 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) printf("CPU Mode: %s\n", cpu_modes[mode]); /* Avoid exception loops */ - if (regs->sp < (gd->arch.stack_end - CONFIG_STACKSIZE) - || regs->sp >= gd->arch.stack_end) + if (regs->sp < (gd->start_addr_sp - CONFIG_STACKSIZE) || + regs->sp >= gd->start_addr_sp) printf("\nStack pointer seems bogus, won't do stack dump\n"); else - dump_mem("\nStack: ", regs->sp, gd->arch.stack_end); + dump_mem("\nStack: ", regs->sp, gd->start_addr_sp); panic("Unhandled exception\n"); } diff --git a/arch/avr32/include/asm/global_data.h b/arch/avr32/include/asm/global_data.h index d82fb7cc6d..60abd00782 100644 --- a/arch/avr32/include/asm/global_data.h +++ b/arch/avr32/include/asm/global_data.h @@ -8,7 +8,6 @@ /* Architecture-specific global data */ struct arch_global_data { - unsigned long stack_end; /* highest stack address */ unsigned long cpu_hz; /* cpu core clock frequency */ }; diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 13b7fede74..99aa96e23f 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -157,7 +157,7 @@ void board_init_f(ulong board_type) /* And finally, a new, bigger stack. */ new_sp = (unsigned long *)addr; - gd->arch.stack_end = addr; + gd->start_addr_sp = addr; *(--new_sp) = 0; *(--new_sp) = 0; -- cgit From 68145d4c7b3aa83d74c2dc904a39fab17cee1691 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:45 +0100 Subject: common/board_f: factor out reserve_stacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce arch_reserve_stacks() to tailor gd->start_addr_sp and gd->irq_sp to the architecture needs. Signed-off-by: Andreas Bießmann Reviewed-by: Simon Glass --- arch/arm/lib/Makefile | 1 + arch/arm/lib/stack.c | 42 ++++++++++++++++++++++++++++++++++++++++++ arch/powerpc/lib/Makefile | 1 + arch/powerpc/lib/stack.c | 31 +++++++++++++++++++++++++++++++ common/board_f.c | 44 +++++++++----------------------------------- include/common.h | 18 ++++++++++++++++++ 6 files changed, 102 insertions(+), 35 deletions(-) create mode 100644 arch/arm/lib/stack.c create mode 100644 arch/powerpc/lib/stack.c diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d74e4b8415..da8ed72a11 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -35,6 +35,7 @@ endif obj-$(CONFIG_SEMIHOSTING) += semihosting.o obj-y += sections.o +obj-y += stack.o ifdef CONFIG_ARM64 obj-y += gic_64.o obj-y += interrupts_64.o diff --git a/arch/arm/lib/stack.c b/arch/arm/lib/stack.c new file mode 100644 index 0000000000..cf10a53ec6 --- /dev/null +++ b/arch/arm/lib/stack.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 Andreas Bießmann + * + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +DECLARE_GLOBAL_DATA_PTR; + +int arch_reserve_stacks(void) +{ +#ifdef CONFIG_SPL_BUILD + gd->start_addr_sp -= 128; /* leave 32 words for abort-stack */ + gd->irq_sp = gd->start_addr_sp; +#else + /* setup stack pointer for exceptions */ + gd->irq_sp = gd->start_addr_sp; + +# if !defined(CONFIG_ARM64) +# ifdef CONFIG_USE_IRQ + gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); + debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", + CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp); + + /* 8-byte alignment for ARM ABI compliance */ + gd->start_addr_sp &= ~0x07; +# endif + /* leave 3 words for abort-stack, plus 1 for alignment */ + gd->start_addr_sp -= 16; +# endif +#endif + + return 0; +} diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 0f6298269a..05b22bb5f7 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -40,6 +40,7 @@ obj-y += extable.o obj-y += interrupts.o obj-$(CONFIG_CMD_KGDB) += kgdb.o obj-$(CONFIG_CMD_IDE) += ide.o +obj-y += stack.o obj-y += time.o # Don't include the MPC5xxx special memcpy into the diff --git a/arch/powerpc/lib/stack.c b/arch/powerpc/lib/stack.c new file mode 100644 index 0000000000..1985f0348d --- /dev/null +++ b/arch/powerpc/lib/stack.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 Andreas Bießmann + * + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +DECLARE_GLOBAL_DATA_PTR; + +int arch_reserve_stacks(void) +{ + ulong *s; + + /* setup stack pointer for exceptions */ + gd->irq_sp = gd->start_addr_sp; + + /* Clear initial stack frame */ + s = (ulong *)gd->start_addr_sp; + *s = 0; /* Terminate back chain */ + *++s = 0; /* NULL return address */ + + return 0; +} diff --git a/common/board_f.c b/common/board_f.c index 2c10215a17..ef3f036dad 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -573,48 +573,22 @@ static int reserve_fdt(void) return 0; } -static int reserve_stacks(void) +int arch_reserve_stacks(void) { -#ifdef CONFIG_SPL_BUILD -# ifdef CONFIG_ARM - gd->start_addr_sp -= 128; /* leave 32 words for abort-stack */ - gd->irq_sp = gd->start_addr_sp; -# endif -#else -# ifdef CONFIG_PPC - ulong *s; -# endif + return 0; +} - /* setup stack pointer for exceptions */ +static int reserve_stacks(void) +{ + /* make stack pointer 16-byte aligned */ gd->start_addr_sp -= 16; gd->start_addr_sp &= ~0xf; - gd->irq_sp = gd->start_addr_sp; /* - * Handle architecture-specific things here - * TODO(sjg@chromium.org): Perhaps create arch_reserve_stack() - * to handle this and put in arch/xxx/lib/stack.c + * let the architecture specific code tailor gd->start_addr_sp and + * gd->irq_sp */ -# if defined(CONFIG_ARM) && !defined(CONFIG_ARM64) -# ifdef CONFIG_USE_IRQ - gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); - debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", - CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp); - - /* 8-byte alignment for ARM ABI compliance */ - gd->start_addr_sp &= ~0x07; -# endif - /* leave 3 words for abort-stack, plus 1 for alignment */ - gd->start_addr_sp -= 16; -# elif defined(CONFIG_PPC) - /* Clear initial stack frame */ - s = (ulong *) gd->start_addr_sp; - *s = 0; /* Terminate back chain */ - *++s = 0; /* NULL return address */ -# endif /* Architecture specific code */ - - return 0; -#endif + return arch_reserve_stacks(); } static int display_new_sp(void) diff --git a/include/common.h b/include/common.h index 91294547f5..77c55c6f26 100644 --- a/include/common.h +++ b/include/common.h @@ -252,6 +252,24 @@ static inline int print_cpuinfo(void) int update_flash_size(int flash_size); int arch_early_init_r(void); +/** + * Reserve all necessary stacks + * + * This is used in generic board init sequence in common/board_f.c. Each + * architecture could provide this function to tailor the required stacks. + * + * On entry gd->start_addr_sp is pointing to the suggested top of the stack. + * The callee ensures gd->start_add_sp is 16-byte aligned, so architectures + * require only this can leave it untouched. + * + * On exit gd->start_addr_sp and gd->irq_sp should be set to the respective + * positions of the stack. The stack pointer(s) will be set to this later. + * gd->irq_sp is only required, if the architecture needs it. + * + * @return 0 if no error + */ +__weak int arch_reserve_stacks(void); + /** * Show the DRAM size in a board-specific way * -- cgit From c722f0b026249385bbbcec4f5be9bd3abd69342c Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:47 +0100 Subject: common/board_r: allocate bootparams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann Reviewed-by: Simon Glass --- common/board_r.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 907b33cca7..f0b4f9d935 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -459,6 +459,18 @@ static int initr_env(void) return 0; } +#ifdef CONFIG_SYS_BOOTPARAMS_LEN +static int initr_malloc_bootparams(void) +{ + gd->bd->bi_boot_params = (ulong)malloc(CONFIG_SYS_BOOTPARAMS_LEN); + if (!gd->bd->bi_boot_params) { + puts("WARNING: Cannot allocate space for boot parameters\n"); + return -ENOMEM; + } + return 0; +} +#endif + #ifdef CONFIG_SC3 /* TODO: with new initcalls, move this into the driver */ extern void sc3_read_eeprom(void); @@ -775,6 +787,9 @@ init_fnc_t init_sequence_r[] = { initr_dataflash, #endif initr_env, +#ifdef CONFIG_SYS_BOOTPARAMS_LEN + initr_malloc_bootparams, +#endif INIT_FUNC_WATCHDOG_RESET initr_secondary_cpu, #ifdef CONFIG_SC3 -- cgit From a752a8b4c49d67daa4ea9f9ebac3972bb1c2328b Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:48 +0100 Subject: avr32: add generic board support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann --- arch/avr32/config.mk | 3 +++ arch/avr32/cpu/u-boot.lds | 2 ++ arch/avr32/include/asm/config.h | 1 + arch/avr32/include/asm/u-boot.h | 7 +++++++ arch/avr32/lib/Makefile | 2 ++ arch/avr32/lib/interrupts.c | 5 +++++ common/board_f.c | 2 +- common/board_r.c | 13 ++++++++++--- common/cmd_bdinfo.c | 4 ++-- include/asm-generic/u-boot.h | 4 ++++ 10 files changed, 37 insertions(+), 6 deletions(-) diff --git a/arch/avr32/config.mk b/arch/avr32/config.mk index 469185e8b4..8252f598c3 100644 --- a/arch/avr32/config.mk +++ b/arch/avr32/config.mk @@ -9,6 +9,9 @@ ifeq ($(CROSS_COMPILE),) CROSS_COMPILE := avr32-linux- endif +# avr32 has generic board support +__HAVE_ARCH_GENERIC_BOARD := y + CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 PLATFORM_RELFLAGS += -ffixed-r5 -fPIC -mno-init-got -mrelax diff --git a/arch/avr32/cpu/u-boot.lds b/arch/avr32/cpu/u-boot.lds index cb29a22b1e..b0180e3534 100644 --- a/arch/avr32/cpu/u-boot.lds +++ b/arch/avr32/cpu/u-boot.lds @@ -48,9 +48,11 @@ SECTIONS _edata = .; .bss (NOLOAD) : { + __bss_start = .; *(.bss) *(.bss.*) } . = ALIGN(8); __bss_end = .; + __init_end = .; } diff --git a/arch/avr32/include/asm/config.h b/arch/avr32/include/asm/config.h index 63056a4dfa..529fe227a6 100644 --- a/arch/avr32/include/asm/config.h +++ b/arch/avr32/include/asm/config.h @@ -8,5 +8,6 @@ #define _ASM_CONFIG_H_ #define CONFIG_NEEDS_MANUAL_RELOC +#define CONFIG_SYS_GENERIC_GLOBAL_DATA #endif diff --git a/arch/avr32/include/asm/u-boot.h b/arch/avr32/include/asm/u-boot.h index 232350ead8..8b047ec7c8 100644 --- a/arch/avr32/include/asm/u-boot.h +++ b/arch/avr32/include/asm/u-boot.h @@ -6,6 +6,11 @@ #ifndef __ASM_U_BOOT_H__ #define __ASM_U_BOOT_H__ 1 +#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include +#else + typedef struct bd_info { unsigned char bi_phy_id[4]; unsigned long bi_board_number; @@ -22,6 +27,8 @@ typedef struct bd_info { #define bi_memstart bi_dram[0].start #define bi_memsize bi_dram[0].size +#endif + /* For image.h:image_check_target_arch() */ #define IH_ARCH_DEFAULT IH_ARCH_AVR32 diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile index 5f2d97bfc7..6750913630 100644 --- a/arch/avr32/lib/Makefile +++ b/arch/avr32/lib/Makefile @@ -8,7 +8,9 @@ # obj-y += memset.o +ifndef CONFIG_SYS_GENERIC_BOARD obj-y += board.o +endif obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += interrupts.o obj-y += dram_init.o diff --git a/arch/avr32/lib/interrupts.c b/arch/avr32/lib/interrupts.c index bacb2d186a..5f3a49e152 100644 --- a/arch/avr32/lib/interrupts.c +++ b/arch/avr32/lib/interrupts.c @@ -7,6 +7,11 @@ #include +int interrupt_init(void) +{ + return 0; +} + void enable_interrupts(void) { asm volatile("csrf %0" : : "n"(SYSREG_GM_OFFSET)); diff --git a/common/board_f.c b/common/board_f.c index ef3f036dad..4d8b8a626b 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -883,7 +883,7 @@ static init_fnc_t init_sequence_f[] = { #endif announce_dram_init, /* TODO: unify all these dram functions? */ -#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) +#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) dram_init, /* configure available RAM banks */ #endif #if defined(CONFIG_MIPS) || defined(CONFIG_PPC) diff --git a/common/board_r.c b/common/board_r.c index f0b4f9d935..4fcd4f6a70 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -55,6 +55,9 @@ #include #include #include +#ifdef CONFIG_AVR32 +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -498,7 +501,7 @@ static int initr_api(void) #endif /* enable exceptions */ -#ifdef CONFIG_ARM +#if defined(CONFIG_ARM) || defined(CONFIG_AVR32) static int initr_enable_interrupts(void) { enable_interrupts(); @@ -825,10 +828,10 @@ init_fnc_t init_sequence_r[] = { initr_kgdb, #endif interrupt_init, -#if defined(CONFIG_ARM) +#if defined(CONFIG_ARM) || defined(CONFIG_AVR32) initr_enable_interrupts, #endif -#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) +#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) timer_init, /* initialize timer */ #endif #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) @@ -893,6 +896,10 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) int i; #endif +#ifdef CONFIG_AVR32 + mmu_init_r(dest_addr); +#endif + #if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) gd = new_gd; #endif diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index e9eab232f9..aa81da227b 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -345,8 +345,8 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) bd_t *bd = gd->bd; print_num("boot_params", (ulong)bd->bi_boot_params); - print_num("memstart", (ulong)bd->bi_memstart); - print_lnum("memsize", (u64)bd->bi_memsize); + print_num("memstart", (ulong)bd->bi_dram[0].start); + print_lnum("memsize", (u64)bd->bi_dram[0].size); print_num("flashstart", (ulong)bd->bi_flashstart); print_num("flashsize", (ulong)bd->bi_flashsize); print_num("flashoffset", (ulong)bd->bi_flashoffset); diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h index aef39d7884..a63a87a287 100644 --- a/include/asm-generic/u-boot.h +++ b/include/asm-generic/u-boot.h @@ -32,6 +32,10 @@ typedef struct bd_info { unsigned long bi_flashoffset; /* reserved area for startup monitor */ unsigned long bi_sramstart; /* start of SRAM memory */ unsigned long bi_sramsize; /* size of SRAM memory */ +#ifdef CONFIG_AVR32 + unsigned char bi_phy_id[4]; /* PHY address for ATAG_ETHERNET */ + unsigned long bi_board_number;/* ATAG_BOARDINFO */ +#endif #ifdef CONFIG_ARM unsigned long bi_arm_freq; /* arm frequency */ unsigned long bi_dsp_freq; /* dsp core frequency */ -- cgit From 573feec8a43bd1b44134a1a5ce10676b577d0358 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:49 +0100 Subject: grasshopper: enable generic board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann --- include/configs/grasshopper.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/grasshopper.h b/include/configs/grasshopper.h index 83f0ed2a62..54eb9777d7 100644 --- a/include/configs/grasshopper.h +++ b/include/configs/grasshopper.h @@ -62,6 +62,10 @@ #define CONFIG_USART_BASE ATMEL_BASE_USART1 #define CONFIG_USART_ID 1 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_EARLY_INIT_R + /* User serviceable stuff */ #define CONFIG_CMDLINE_TAG #define CONFIG_SETUP_MEMORY_TAGS -- cgit From 5c98d7ffb0b11c9e3909f56ec5ce9dff682f1e30 Mon Sep 17 00:00:00 2001 From: Andreas Bießmann Date: Fri, 6 Feb 2015 23:06:50 +0100 Subject: atstk1002: enable generic board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Bießmann --- include/configs/atstk1002.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h index 9e58238f1d..a9c064a45d 100644 --- a/include/configs/atstk1002.h +++ b/include/configs/atstk1002.h @@ -104,6 +104,10 @@ #define CONFIG_BOOTP_SUBNETMASK #define CONFIG_BOOTP_GATEWAY +/* generic board */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_EARLY_INIT_R /* * Command line configuration. -- cgit From 90fbee3e4051badff770a0ee1b1ca21cb808d634 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 4 Feb 2015 21:56:53 -0600 Subject: cmd_fdt: Actually fix fdt command in sandbox Commit 90bac29a76bc8d649b41a55f2786c0abef9bb2c1 claims to fix this bug that was introduced in commit a92fd6577ea17751ead9b50243e3c562125cf581 but doesn't actually make the change that the commit message describes. Actually fix the bug this time. Signed-off-by: Joe Hershberger Acked-by: Simon Glass --- common/bootm.c | 2 +- common/cmd_fdt.c | 8 ++++---- common/image-fdt.c | 2 +- include/fdt_support.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/bootm.c b/common/bootm.c index e2dc16486b..34f60bbb53 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -233,7 +233,7 @@ static int bootm_find_fdt(int flag, int argc, char * const argv[]) return 1; } - set_working_fdt_addr(images.ft_addr); + set_working_fdt_addr((ulong)images.ft_addr); return 0; } diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index dc59fab828..5878496575 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -38,13 +38,13 @@ static int is_printable_string(const void *data, int len); */ struct fdt_header *working_fdt; -void set_working_fdt_addr(void *addr) +void set_working_fdt_addr(ulong addr) { void *buf; - buf = map_sysmem((ulong)addr, 0); + buf = map_sysmem(addr, 0); working_fdt = buf; - setenv_addr("fdtaddr", addr); + setenv_ulong("fdtaddr", addr); } /* @@ -123,7 +123,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (control) gd->fdt_blob = blob; else - set_working_fdt_addr((void *)blob); + set_working_fdt_addr(addr); if (argc >= 2) { int len; diff --git a/common/image-fdt.c b/common/image-fdt.c index e3f06cdd1a..d9e47283c7 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -190,7 +190,7 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) *of_flat_tree = of_start; *of_size = of_len; - set_working_fdt_addr(*of_flat_tree); + set_working_fdt_addr((ulong)*of_flat_tree); return 0; error: diff --git a/include/fdt_support.h b/include/fdt_support.h index 1f19fe4c96..ae5e8a3ef6 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -100,7 +100,7 @@ void ft_pci_setup(void *blob, bd_t *bd); */ int ft_system_setup(void *blob, bd_t *bd); -void set_working_fdt_addr(void *addr); +void set_working_fdt_addr(ulong addr); int fdt_shrink_to_minimum(void *blob); int fdt_increase_size(void *fdt, int add_len); -- cgit From c71a0164d9b23e624552fb614bcb426a11119b57 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 4 Feb 2015 21:56:54 -0600 Subject: cmd_fdt: Print the control fdt in terms of virtual memory If you want to inspect the control device tree using the fdt command, the "fdt address -c" command previously unhelpfully printed the phys memory address of the device tree. That address could not then be used to set the fdt address for inspection. Changed the resulting print to one that can be copied directly to the 'fdt address ' command. Signed-off-by: Joe Hershberger Acked-by: Simon Glass --- common/cmd_fdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 5878496575..48b3e70415 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -111,7 +111,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (!blob || !fdt_valid(&blob)) return 1; printf("The address of the fdt is %#08lx\n", - control ? (ulong)blob : + control ? (ulong)map_to_sysmem(blob) : getenv_hex("fdtaddr", 0)); return 0; } -- cgit From 9e533cb0462a7d28ec14a816ea627d38ce48dbf3 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 5 Feb 2015 13:50:26 +0900 Subject: cmd_i2c: quit I2C commands immediately on error If the i2c driver returns an error status, error out immediately. Continuing the loop just results in printing error messages again and again. Signed-off-by: Masahiro Yamada Cc: Simon Glass Cc: Heiko Schocher Reviewed-by: Simon Glass --- common/cmd_i2c.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index fe8f77aaec..62b0b4863d 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -518,7 +518,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] ret = i2c_read(chip, addr, alen, linebuf, linebytes); #endif if (ret) - i2c_report_err(ret, I2C_ERR_READ); + return i2c_report_err(ret, I2C_ERR_READ); else { printf("%04x:", addr); cp = linebuf; @@ -616,7 +616,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] ret = i2c_write(chip, addr++, alen, &byte, 1); #endif if (ret) - i2c_report_err(ret, I2C_ERR_WRITE); + return i2c_report_err(ret, I2C_ERR_WRITE); /* * Wait for the write to complete. The write can take * up to 10mSec (we allow a little more time). @@ -798,16 +798,15 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg ret = i2c_read(chip, addr, alen, (uchar *)&data, size); #endif if (ret) - i2c_report_err(ret, I2C_ERR_READ); - else { - data = cpu_to_be32(data); - if (size == 1) - printf(" %02lx", (data >> 24) & 0x000000FF); - else if (size == 2) - printf(" %04lx", (data >> 16) & 0x0000FFFF); - else - printf(" %08lx", data); - } + return i2c_report_err(ret, I2C_ERR_READ); + + data = cpu_to_be32(data); + if (size == 1) + printf(" %02lx", (data >> 24) & 0x000000FF); + else if (size == 2) + printf(" %04lx", (data >> 16) & 0x0000FFFF); + else + printf(" %08lx", data); nbytes = cli_readline(" ? "); if (nbytes == 0) { @@ -848,7 +847,8 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg (uchar *)&data, size); #endif if (ret) - i2c_report_err(ret, I2C_ERR_WRITE); + return i2c_report_err(ret, + I2C_ERR_WRITE); #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif -- cgit From ed16f14689b98c1ec98c9f30b92b8edea9d2d60c Mon Sep 17 00:00:00 2001 From: Lubomir Popov Date: Fri, 30 Jan 2015 19:56:04 +0200 Subject: cmd_i2c: Provide option for bulk 'i2c write' in one transaction I2C chips do exist that require a write of some multi-byte data to occur in a single bus transaction (aka atomic transfer), otherwise either the write does not come into effect at all, or normal operation of internal circuitry cannot be guaranteed. The current implementation of the 'i2c write' command (transfer of multiple bytes from a memory buffer) in fact performs a separate transaction for each byte to be written and thus cannot support such types of I2C slave devices. This patch provides an alternative by allowing 'i2c write' to execute the write transfer of the given number of bytes in a single bus transaction if the '-s' option is specified as a final command argument. Else the current re-addressing method is used. Signed-off-by: Lubomir Popov hs: adapt to CONFIG_DM_I2C --- common/cmd_i2c.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 62b0b4863d..ad38cbf6e1 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -342,9 +342,10 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ int ret; #ifdef CONFIG_DM_I2C struct udevice *dev; + struct dm_i2c_chip *i2c_chip; #endif - if (argc != 5) + if ((argc < 5) || (argc > 6)) return cmd_usage(cmdtp); /* @@ -367,7 +368,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ return cmd_usage(cmdtp); /* - * Length is the number of objects, not number of bytes. + * Length is the number of bytes. */ length = simple_strtoul(argv[4], NULL, 16); @@ -377,22 +378,47 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ ret = i2c_set_chip_offset_len(dev, alen); if (ret) return i2c_report_err(ret, I2C_ERR_WRITE); + i2c_chip = dev_get_parent_platdata(dev); + if (!i2c_chip) + return i2c_report_err(ret, I2C_ERR_WRITE); #endif - while (length-- > 0) { + if (argc == 6 && !strcmp(argv[5], "-s")) { + /* + * Write all bytes in a single I2C transaction. If the target + * device is an EEPROM, it is your responsibility to not cross + * a page boundary. No write delay upon completion, take this + * into account if linking commands. + */ #ifdef CONFIG_DM_I2C - ret = dm_i2c_write(dev, devaddr++, memaddr++, 1); + i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS; + ret = dm_i2c_write(dev, devaddr, memaddr, length); #else - ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); + ret = i2c_write(chip, devaddr, alen, memaddr, length); #endif if (ret) return i2c_report_err(ret, I2C_ERR_WRITE); + } else { + /* + * Repeated addressing - perform separate + * write transactions of one byte each + */ + while (length-- > 0) { +#ifdef CONFIG_DM_I2C + i2c_chip->flags |= DM_I2C_CHIP_WR_ADDRESS; + ret = dm_i2c_write(dev, devaddr++, memaddr++, 1); +#else + ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); +#endif + if (ret) + return i2c_report_err(ret, I2C_ERR_WRITE); /* * No write delay with FRAM devices. */ #if !defined(CONFIG_SYS_I2C_FRAM) - udelay(11000); + udelay(11000); #endif + } } return 0; } @@ -1827,7 +1853,7 @@ static cmd_tbl_t cmd_i2c_sub[] = { U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""), U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""), U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""), - U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""), + U_BOOT_CMD_MKENT(write, 6, 0, do_i2c_write, "", ""), #ifdef CONFIG_DM_I2C U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""), #endif @@ -1894,7 +1920,8 @@ static char i2c_help_text[] = "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" "i2c probe [address] - test for and show device(s) on the I2C bus\n" "i2c read chip address[.0, .1, .2] length memaddress - read to memory\n" - "i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n" + "i2c write memaddress chip address[.0, .1, .2] length [-s] - write memory\n" + " to I2C; the -s option selects bulk write in a single transaction\n" #ifdef CONFIG_DM_I2C "i2c flags chip [flags] - set or get chip flags\n" #endif @@ -1906,7 +1933,7 @@ static char i2c_help_text[] = #endif U_BOOT_CMD( - i2c, 6, 1, do_i2c, + i2c, 7, 1, do_i2c, "I2C sub-system", i2c_help_text ); -- cgit From 6fb9ac15ebac4bcc4864be7958bf9b2b2b7420de Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 13 Feb 2015 12:20:47 -0700 Subject: dm: cros_ec: Convert to Kconfig Since both I2C and SPI are converted to Kconfig, we can convert cros_ec to Kconfig for these buses. LPC will need to wait until driver mode PCI is available. Signed-off-by: Simon Glass --- configs/peach-pi_defconfig | 4 ++++ configs/peach-pit_defconfig | 4 ++++ configs/sandbox_defconfig | 5 ++++ configs/snow_defconfig | 5 ++++ drivers/input/Kconfig | 6 +++++ drivers/misc/Kconfig | 48 ++++++++++++++++++++++++++++++++++++- include/configs/exynos5-dt-common.h | 3 --- include/configs/peach-pi.h | 1 - include/configs/peach-pit.h | 1 - include/configs/sandbox.h | 4 ---- include/configs/snow.h | 2 -- 11 files changed, 71 insertions(+), 12 deletions(-) diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig index 8ada0dbe40..333e335a26 100644 --- a/configs/peach-pi_defconfig +++ b/configs/peach-pi_defconfig @@ -3,3 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_PEACH_PI=y CONFIG_DEFAULT_DEVICE_TREE="exynos5800-peach-pi" +CONFIG_CROS_EC=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig index b944b3bb50..cf84444950 100644 --- a/configs/peach-pit_defconfig +++ b/configs/peach-pit_defconfig @@ -3,3 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_PEACH_PIT=y CONFIG_DEFAULT_DEVICE_TREE="exynos5420-peach-pit" +CONFIG_CROS_EC=y +CONFIG_CROS_EC_SPI=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 0bf5ea34d0..70f5b86b85 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -7,3 +7,8 @@ CONFIG_DM=y CONFIG_DEFAULT_DEVICE_TREE="sandbox" CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_CROS_EC=y +CONFIG_DM_CROS_EC=y +CONFIG_CROS_EC_SANDBOX=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/configs/snow_defconfig b/configs/snow_defconfig index 14ed793f6d..353ddb03a0 100644 --- a/configs/snow_defconfig +++ b/configs/snow_defconfig @@ -3,3 +3,8 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_SNOW=y CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow" +CONFIG_CROS_EC=y +CONFIG_DM_CROS_EC=y +CONFIG_CROS_EC_I2C=y +CONFIG_CROS_EC_KEYB=y +CONFIG_CMD_CROS_EC=y diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e69de29bb2..bb00de7c57 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -0,0 +1,6 @@ +config CROS_EC_KEYB + bool "Enable Chrome OS EC keyboard support" + help + Most ARM Chromebooks use an EC to provide access to the keyboard. + Messages are used to request key scans from the EC and these are + then decoded into keys by this driver. diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 813d1c24b9..0df25c331f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -1,3 +1,49 @@ +config CMD_CROS_EC + bool "Enable crosec command" + depends on CROS_EC + help + Enable command-line access to the Chrome OS EC (Embedded + Controller). This provides the 'crosec' command which has + a number of sub-commands for performing EC tasks such as + updating its flash, accessing a small saved context area + and talking to the I2C bus behind the EC (if there is one). + +config CROS_EC + bool "Enable Chrome OS EC" + help + Enable access to the Chrome OS EC. This is a separate + microcontroller typically available on a SPI bus on Chromebooks. It + provides access to the keyboard, some internal storage and may + control access to the battery and main PMIC depending on the + device. You can use the 'crosec' command to access it. + +config CROS_EC_I2C + bool "Enable Chrome OS EC I2C driver" + depends on CROS_EC + help + Enable I2C access to the Chrome OS EC. This is used on older + ARM Chromebooks such as snow and spring before the standard bus + changed to SPI. The EC will accept commands across the I2C using + a special message protocol, and provide responses. + +config CROS_EC_LPC + bool "Enable Chrome OS EC LPC driver" + depends on CROS_EC + help + Enable I2C access to the Chrome OS EC. This is used on x86 + Chromebooks such as link and falco. The keyboard is provided + through a legacy port interface, so on x86 machines the main + function of the EC is power and thermal management. + +config CROS_EC_SPI + bool "Enable Chrome OS EC SPI driver" + depends on CROS_EC + help + Enable SPI access to the Chrome OS EC. This is used on newer + ARM Chromebooks such as pit, pi and nyan-big. The SPI interface + provides a faster and more robust interface than I2C but the bugs + are less interesting. + config DM_CROS_EC bool "Enable Driver Model for Chrome OS EC" depends on DM @@ -5,5 +51,5 @@ config DM_CROS_EC Enable driver model for the Chrome OS EC interface. This allows the cros_ec SPI driver to operate with CONFIG_DM_SPI but otherwise makes few changes. Since cros_ec also supports - I2C and LPC (which don't support driver model yet), a full + LPC (which doesn't support driver model yet), a full conversion is not yet possible. diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 9cef0b0a38..b1b8e1ace7 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -24,9 +24,6 @@ #define CONFIG_POWER_TPS65090 /* Enable keyboard */ -#define CONFIG_CROS_EC /* CROS_EC protocol */ -#define CONFIG_CROS_EC_KEYB /* CROS_EC keyboard input */ -#define CONFIG_CMD_CROS_EC #define CONFIG_KEYBOARD #endif diff --git a/include/configs/peach-pi.h b/include/configs/peach-pi.h index f724164d89..f04f0613aa 100644 --- a/include/configs/peach-pi.h +++ b/include/configs/peach-pi.h @@ -43,7 +43,6 @@ #endif #define CONFIG_POWER_TPS65090_EC -#define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/peach-pit.h b/include/configs/peach-pit.h index de12a9e1b1..b5efbdcaa6 100644 --- a/include/configs/peach-pit.h +++ b/include/configs/peach-pit.h @@ -43,7 +43,6 @@ #endif #define CONFIG_POWER_TPS65090_EC -#define CONFIG_CROS_EC_SPI /* Support CROS_EC over SPI */ #define CONFIG_USB_XHCI #define CONFIG_USB_XHCI_EXYNOS diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 5c116508d0..febbfb69f6 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -141,9 +141,6 @@ #define CONFIG_BOOTARGS "" -#define CONFIG_CROS_EC -#define CONFIG_CMD_CROS_EC -#define CONFIG_CROS_EC_SANDBOX #define CONFIG_ARCH_EARLY_INIT_R #define CONFIG_BOARD_LATE_INIT @@ -166,7 +163,6 @@ #define LCD_BPP LCD_COLOR16 #define CONFIG_LCD_BMP_RLE8 -#define CONFIG_CROS_EC_KEYB #define CONFIG_KEYBOARD #define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial,cros-ec-keyb\0" \ diff --git a/include/configs/snow.h b/include/configs/snow.h index ce6676eae7..fe802f253c 100644 --- a/include/configs/snow.h +++ b/include/configs/snow.h @@ -20,9 +20,7 @@ #include -#define CONFIG_CROS_EC_I2C /* Support CROS_EC over I2C */ #define CONFIG_POWER_TPS65090_I2C -#define CONFIG_DM_CROS_EC #define CONFIG_BOARD_COMMON #define CONFIG_ARCH_EARLY_INIT_R -- cgit From 4bba9d3f77061ea742d8f697ce72251fb79c8016 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 13 Feb 2015 12:20:48 -0700 Subject: dm: Move CONFIG_I2C_COMPAT to Kconfig Make this option available in Kconfig and clean up the board that uses it. Note there is also an entry in exynos5-common.h but this affects multiple boards and should be dropped as part of the Samsung I2C migration to driver model. Signed-off-by: Simon Glass --- configs/odroid_defconfig | 2 ++ drivers/i2c/Kconfig | 9 +++++++++ include/configs/exynos5-common.h | 2 ++ include/configs/odroid.h | 2 -- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig index a8428373ac..816a3fad3c 100644 --- a/configs/odroid_defconfig +++ b/configs/odroid_defconfig @@ -3,3 +3,5 @@ CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" +CONFIG_DM_I2C=y +CONFIG_DM_I2C_COMPAT=y diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 2cc776c73f..692810d057 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -13,6 +13,15 @@ config DM_I2C enabled together (it is not possible to use driver model for one and not the other). +config DM_I2C_COMPAT + bool "Enable I2C compatibility layer" + depends on DM + help + Enable old-style I2C functions for compatibility with existing code. + This option can be enabled as a temporary measure to avoid needing + to convert all code for a board in a single commit. It should not + be enabled for any board in an official release. + config SYS_I2C_UNIPHIER bool "UniPhier I2C driver" depends on ARCH_UNIPHIER && DM_I2C diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index 0ba39a23dd..3ab8d559bf 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -126,6 +126,8 @@ #define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE) /* I2C */ + +/* TODO(sjg@chromium.org): Move these two options to Kconfig */ #define CONFIG_DM_I2C #define CONFIG_DM_I2C_COMPAT #define CONFIG_CMD_I2C diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 9d5dbdce36..8b47537614 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -177,8 +177,6 @@ /* I2C */ #define CONFIG_CMD_I2C -#define CONFIG_DM_I2C -#define CONFIG_DM_I2C_COMPAT #define CONFIG_SYS_I2C_S3C24X0 #define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 #define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 -- cgit From f11199f0d0495177fe17e651e99955dc7494ab52 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 13 Feb 2015 12:20:49 -0700 Subject: dm: mx6: Adjust mx6sxsabresd to use Kconfig for DM_THERMAL Use Kconfig instead of board config for DM and DM_THERMAL. Signed-off-by: Simon Glass --- configs/mx6sxsabresd_defconfig | 2 ++ configs/mx6sxsabresd_spl_defconfig | 2 ++ include/configs/mx6sxsabresd.h | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index 72e0f103ec..cc823226c1 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -3,3 +3,5 @@ CONFIG_ARM=y CONFIG_TARGET_MX6SXSABRESD=y CONFIG_SYS_MALLOC_F=y CONFIG_SYS_MALLOC_F_LEN=0x400 +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig index 6b36e06a85..901b01bf98 100644 --- a/configs/mx6sxsabresd_spl_defconfig +++ b/configs/mx6sxsabresd_spl_defconfig @@ -2,3 +2,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX" +S:CONFIG_ARM=y +S:CONFIG_TARGET_MX6SXSABRESD=y +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 1005b9e6bc..a2901294a6 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -227,8 +227,6 @@ #define CONFIG_PCIE_IMX_POWER_GPIO IMX_GPIO_NR(2, 1) #endif -#define CONFIG_DM -#define CONFIG_DM_THERMAL #define CONFIG_IMX6_THERMAL #define CONFIG_CMD_FUSE -- cgit From ba25779384671c533a778e53d59fe3f317bfefa8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Feb 2015 18:49:33 +0900 Subject: Documentation: gpio: fix bindings document [ imported from Linux Kernel, commit 74981fb81d83 ] Signed-off-by: Masahiro Yamada Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij Acked-by: Simon Glass --- doc/device-tree-bindings/gpio/gpio.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/device-tree-bindings/gpio/gpio.txt b/doc/device-tree-bindings/gpio/gpio.txt index b9bd1d64cf..f7a158d858 100644 --- a/doc/device-tree-bindings/gpio/gpio.txt +++ b/doc/device-tree-bindings/gpio/gpio.txt @@ -69,7 +69,8 @@ GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller. ---------------------------------- A gpio-specifier should contain a flag indicating the GPIO polarity; active- -high or active-low. If it does, the follow best practices should be followed: +high or active-low. If it does, the following best practices should be +followed: The gpio-specifier's polarity flag should represent the physical level at the GPIO controller that achieves (or represents, for inputs) a logically asserted @@ -147,7 +148,7 @@ contains information structures as follows: numeric-gpio-range ::= named-gpio-range ::= '<0 0>' - gpio-phandle : phandle to pin controller node. + pinctrl-phandle : phandle to pin controller node gpio-base : Base GPIO ID in the GPIO controller pinctrl-base : Base pinctrl pin ID in the pin controller count : The number of GPIOs/pins in this range -- cgit From 2f964aa7b1bf7de50587a1864cf60d187ebefb2c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 18:27:07 -0700 Subject: serial: Support an early UART for debugging This came up in a discussion on the mailing list here: https://patchwork.ozlabs.org/patch/384613/ My concerns at the time were: - it doesn't need to be written in assembler - it doesn't need to be ARM-specific This patch provides a possible alternative. It works by allowing any serial driver to export one init function and provide a putc() function. These can be used to output debug data before the real serial driver is available. This implementation does not depend on driver model, and it is possible for it to operate without a stack on some architectures (e.g. PowerPC, ARM). It provides the same features as the ARM-specific debug.S but with more UART and architecture support. Signed-off-by: Simon Glass --- configs/minnowmax_defconfig | 2 - drivers/serial/Kconfig | 46 +++++++++++++++ include/debug_uart.h | 139 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 include/debug_uart.h diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 7bc9085b32..d12428996d 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -7,7 +7,5 @@ CONFIG_DEFAULT_DEVICE_TREE="minnowmax" CONFIG_VIDEO_X86=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y -CONFIG_DEBUG_UART_NS16550=y -CONFIG_DEBUG_UART=y CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 CONFIG_HAVE_INTEL_ME=y diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index c94353ba6a..6313258eac 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -7,6 +7,52 @@ config DM_SERIAL implements serial_putc() etc. The uclass interface is defined in include/serial.h. +config DEBUG_UART + bool "Enable an early debug UART for debugging" + help + The debug UART is intended for use very early in U-Boot to debug + problems when an ICE or other debug mechanism is not available. + + To use it you should: + - Make sure your UART supports this interface + - Enable CONFIG_DEBUG_UART + - Enable the CONFIG for your UART to tell it to provide this interface + (e.g. CONFIG_DEBUG_UART_NS16550) + - Define the required settings as needed (see below) + - Call debug_uart_init() before use + - Call debug_uart_putc() to output a character + + Depending on your platform it may be possible to use this UART before + a stack is available. + + If your UART does not support this interface you can probably add + support quite easily. Remember that you cannot use driver model and + it is preferred to use no stack. + + You must not use this UART once driver model is working and the + serial drivers are up and running (done in serial_init()). Otherwise + the drivers may conflict and you will get strange output. + +config DEBUG_UART_BASE + hex "Base address of UART" + depends on DEBUG_UART + help + This is the base address of your UART for memory-mapped UARTs. + + A default should be provided by your board, but if not you will need + to use the correct value here. + +config DEBUG_UART_CLOCK + int "UART input clock" + depends on DEBUG_UART + help + The UART input clock determines the speed of the internal UART + circuitry. The baud rate is derived from this by dividing the input + clock down. + + A default should be provided by your board, but if not you will need + to use the correct value here. + config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" depends on ARCH_UNIPHIER && DM_SERIAL diff --git a/include/debug_uart.h b/include/debug_uart.h new file mode 100644 index 0000000000..f56797b72f --- /dev/null +++ b/include/debug_uart.h @@ -0,0 +1,139 @@ +/* + * Early debug UART support + * + * (C) Copyright 2014 Google, Inc + * Writte by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _DEBUG_UART_H +#define _DEBUG_UART_H + +#include + +/* + * The debug UART is intended for use very early in U-Boot to debug problems + * when an ICE or other debug mechanism is not available. + * + * To use it you should: + * - Make sure your UART supports this interface + * - Enable CONFIG_DEBUG_UART + * - Enable the CONFIG for your UART to tell it to provide this interface + * (e.g. CONFIG_DEBUG_UART_NS16550) + * - Define the required settings as needed (see below) + * - Call debug_uart_init() before use + * - Call printch() to output a character + * + * Depending on your platform it may be possible to use this UART before a + * stack is available. + * + * If your UART does not support this interface you can probably add support + * quite easily. Remember that you cannot use driver model and it is preferred + * to use no stack. + * + * You must not use this UART once driver model is working and the serial + * drivers are up and running (done in serial_init()). Otherwise the drivers + * may conflict and you will get strange output. + * + * + * To enable the debug UART in your serial driver: + * + * - #include + * - Define debug_uart_init(), trying to avoid using the stack + * - Define _debug_uart_putc() as static inline (avoiding stack usage) + * - Immediately afterwards, add DEBUG_UART_FUNCS to define the rest of the + * functionality (printch(), etc.) + */ + +/** + * debug_uart_init() - Set up the debug UART ready for use + * + * This sets up the UART with the correct baud rate, etc. + * + * Available CONFIG is: + * + * - CONFIG_DEBUG_UART_BASE: Base address of UART + * - CONFIG_BAUDRATE: Requested baud rate + * - CONFIG_DEBUG_UART_CLOCK: Input clock for UART + */ +void debug_uart_init(void); + +/** + * printch() - Output a character to the debug UART + * + * @ch: Character to output + */ +asmlinkage void printch(int ch); + +/** + * printascii() - Output an ASCII string to the debug UART + * + * @str: String to output + */ +asmlinkage void printascii(const char *str); + +/** + * printhex2() - Output a 2-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex2(uint value); + +/** + * printhex4() - Output a 4-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex4(uint value); + +/** + * printhex8() - Output a 8-digit hex value + * + * @value: Value to output + */ +asmlinkage void printhex8(uint value); + +/* + * Now define some functions - this should be inserted into the serial driver + */ +#define DEBUG_UART_FUNCS \ + asmlinkage void printch(int ch) \ + { \ + _debug_uart_putc(ch); \ + } \ +\ + asmlinkage void printascii(const char *str) \ + { \ + while (*str) \ + _debug_uart_putc(*str++); \ + } \ +\ + static inline void printhex1(uint digit) \ + { \ + digit &= 0xf; \ + _debug_uart_putc(digit > 9 ? digit - 10 + 'a' : digit + '0'); \ + } \ +\ + static inline void printhex(uint value, int digits) \ + { \ + while (digits-- > 0) \ + printhex1(value >> (4 * digits)); \ + } \ +\ + asmlinkage void printhex2(uint value) \ + { \ + printhex(value, 2); \ + } \ +\ + asmlinkage void printhex4(uint value) \ + { \ + printhex(value, 4); \ + } \ +\ + asmlinkage void printhex8(uint value) \ + { \ + printhex(value, 8); \ + } + +#endif -- cgit From 765716744f6743d6c1e6b3c92eea163b4ee59f3c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 18:27:08 -0700 Subject: serial: ns16550: Add access functions that don't need platdata For the debug UART we need to be able to provide any parameters before driver model is set up. Add parameters to the low-level access functions to make this possible. Signed-off-by: Simon Glass --- drivers/serial/ns16550.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 70c946249f..57e6125de2 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -55,17 +55,9 @@ DECLARE_GLOBAL_DATA_PTR; #endif /* CONFIG_SYS_NS16550_IER */ #ifdef CONFIG_DM_SERIAL -static void ns16550_writeb(NS16550_t port, int offset, int value) -{ - struct ns16550_platdata *plat = port->plat; - unsigned char *addr; - offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; - /* - * As far as we know it doesn't make sense to support selection of - * these options at run-time, so use the existing CONFIG options. - */ +static inline void serial_out_shift(unsigned char *addr, int shift, int value) +{ #ifdef CONFIG_SYS_NS16550_PORT_MAPPED outb(value, (ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) @@ -73,19 +65,14 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) out_be32(addr, value); #elif defined(CONFIG_SYS_BIG_ENDIAN) - writeb(value, addr + (1 << plat->reg_shift) - 1); + writeb(value, addr + (1 << shift) - 1); #else writeb(value, addr); #endif } -static int ns16550_readb(NS16550_t port, int offset) +static inline int serial_in_shift(unsigned char *addr, int shift) { - struct ns16550_platdata *plat = port->plat; - unsigned char *addr; - - offset *= 1 << plat->reg_shift; - addr = map_sysmem(plat->base, 0) + offset; #ifdef CONFIG_SYS_NS16550_PORT_MAPPED return inb((ulong)addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN) @@ -93,12 +80,37 @@ static int ns16550_readb(NS16550_t port, int offset) #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) return in_be32(addr); #elif defined(CONFIG_SYS_BIG_ENDIAN) - return readb(addr + (1 << plat->reg_shift) - 1); + return readb(addr + (1 << reg_shift) - 1); #else return readb(addr); #endif } +static void ns16550_writeb(NS16550_t port, int offset, int value) +{ + struct ns16550_platdata *plat = port->plat; + unsigned char *addr; + + offset *= 1 << plat->reg_shift; + addr = map_sysmem(plat->base, 0) + offset; + /* + * As far as we know it doesn't make sense to support selection of + * these options at run-time, so use the existing CONFIG options. + */ + serial_out_shift(addr, plat->reg_shift, value); +} + +static int ns16550_readb(NS16550_t port, int offset) +{ + struct ns16550_platdata *plat = port->plat; + unsigned char *addr; + + offset *= 1 << plat->reg_shift; + addr = map_sysmem(plat->base, 0) + offset; + + return serial_in_shift(addr, plat->reg_shift); +} + /* We can clean these up once everything is moved to driver model */ #define serial_out(value, addr) \ ns16550_writeb(com_port, addr - (unsigned char *)com_port, value) -- cgit From 21d004368fc8a4da07147c58dfe9a4e16d4ab761 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 18:27:09 -0700 Subject: serial: ns16550: Support debug UART Add debug UART functions to permit ns16550 to provide an early debug UART. Try to avoid using the stack so that this can be called from assembler before a stack is set up (at least on ARM and PowerPC). Signed-off-by: Simon Glass --- drivers/serial/Kconfig | 13 +++++++++++++ drivers/serial/ns16550.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6313258eac..1686a1f951 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -33,6 +33,19 @@ config DEBUG_UART serial drivers are up and running (done in serial_init()). Otherwise the drivers may conflict and you will get strange output. +choice + prompt "Select which UART will provide the debug UART" + depends on DEBUG_UART + +config DEBUG_UART_NS16550 + bool "ns16550" + help + Select this to enable a debug UART using the ns16550 driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + +endchoice + config DEBUG_UART_BASE hex "Base address of UART" depends on DEBUG_UART diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 57e6125de2..eb00f1ca8a 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -118,10 +118,15 @@ static int ns16550_readb(NS16550_t port, int offset) ns16550_readb(com_port, addr - (unsigned char *)com_port) #endif -int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) +static inline int calc_divisor(NS16550_t port, int clock, int baudrate) { const unsigned int mode_x_div = 16; + return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); +} + +int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) +{ #ifdef CONFIG_OMAP1510 /* If can't cleanly clock 115200 set div to 1 */ if ((clock == 12000000) && (baudrate == 115200)) { @@ -131,7 +136,7 @@ int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) port->osc_12m_sel = 0; /* clear if previsouly set */ #endif - return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); + return calc_divisor(port, clock, baudrate); } static void NS16550_setbrg(NS16550_t com_port, int baud_divisor) @@ -231,6 +236,47 @@ int NS16550_tstc(NS16550_t com_port) #endif /* CONFIG_NS16550_MIN_FUNCTIONS */ +#ifdef CONFIG_DEBUG_UART_NS16550 + +#include + +void debug_uart_init(void) +{ + struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; + int baud_divisor; + + /* + * We copy the code from above because it is already horribly messy. + * Trying to refactor to nicely remove the duplication doesn't seem + * feasible. The better fix is to move all users of this driver to + * driver model. + */ + baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK, + CONFIG_BAUDRATE); + + serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER); + serial_out_shift(&com_port->mcr, 0, UART_MCRVAL); + serial_out_shift(&com_port->fcr, 0, UART_FCRVAL); + + serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL); + serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff); + serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff); + serial_out_shift(&com_port->lcr, 0, UART_LCRVAL); +} + +static inline void _debug_uart_putc(int ch) +{ + struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; + + while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE)) + ; + serial_out_shift(&com_port->thr, 0, ch); +} + +DEBUG_UART_FUNCS + +#endif + #ifdef CONFIG_DM_SERIAL static int ns16550_serial_putc(struct udevice *dev, const char ch) { -- cgit From 66c03151fc8752c29b7d17003b9c87218640b10b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 18 Feb 2015 22:36:18 +0100 Subject: dm: Protect device_unbind() with CONFIG_DM_DEVICE_REMOVE Since device_unbind() is also defined in device-remove.c, which is compiled in only in case CONFIG_DM_DEVICE_REMOVE is defined, protect the device_unbind() prototype with the same CONFIG_DM_DEVICE_REMOVE check. Signed-off-by: Marek Vasut Cc: Simon Glass Cc: Stefan Roese Cc: Tom Rini Acked-by: Simon Glass --- include/dm/device-internal.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index f0cc794750..e2418fedb9 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -101,7 +101,11 @@ static inline int device_remove(struct udevice *dev) { return 0; } * @dev: Pointer to device to unbind * @return 0 if OK, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int device_unbind(struct udevice *dev); +#else +static inline int device_unbind(struct udevice *dev) { return 0; } +#endif #ifdef CONFIG_DM_DEVICE_REMOVE void device_free(struct udevice *dev); -- cgit From 242e3d893d1311ea38abd25613076a29961d422e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Feb 2015 17:26:41 +0100 Subject: sunxi: video: Add support for LCD reset pin On some boards there is a gpio to reset the LCD panel, add support for this. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 8 ++++++++ drivers/video/sunxi_display.c | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 3eab81fd12..a170c561aa 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -312,6 +312,14 @@ config VIDEO_LCD_POWER Set the power enable pin for the LCD panel. This takes a string in the format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. +config VIDEO_LCD_RESET + string "LCD panel reset pin" + depends on VIDEO + default "" + ---help--- + Set the reset pin for the LCD panel. This takes a string in the format + understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. + config VIDEO_LCD_BL_EN string "LCD panel backlight enable pin" depends on VIDEO diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index dbda97e746..7f01401252 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -592,7 +592,7 @@ static void sunxi_lcdc_enable(void) static void sunxi_lcdc_panel_enable(void) { - int pin; + int pin, reset_pin; /* * Start with backlight disabled to avoid the screen flashing to @@ -610,6 +610,12 @@ static void sunxi_lcdc_panel_enable(void) gpio_direction_output(pin, PWM_OFF); } + reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET); + if (reset_pin != -1) { + gpio_request(reset_pin, "lcd_reset"); + gpio_direction_output(reset_pin, 0); /* Assert reset */ + } + /* Give the backlight some time to turn off and power up the panel. */ mdelay(40); pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER); @@ -617,6 +623,9 @@ static void sunxi_lcdc_panel_enable(void) gpio_request(pin, "lcd_power"); gpio_direction_output(pin, 1); } + + if (reset_pin != -1) + gpio_direction_output(reset_pin, 1); /* De-assert reset */ } static void sunxi_lcdc_backlight_enable(void) -- cgit From 55410089cb979d7a86ee817c0309c4c2348a90df Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Feb 2015 17:23:25 +0100 Subject: sunxi: video: Add support for LCD panels which need to be configured via i2c This commits adds support for configuring a a bitbang i2c controller, which is used on some boards to configure the LCD panel (via i2c). Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 24 ++++++++++++++++++++++++ board/sunxi/board.c | 10 ++++++++++ include/configs/sunxi-common.h | 16 ++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index a170c561aa..bbb4d1b1e5 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -344,6 +344,30 @@ config VIDEO_LCD_BL_PWM_ACTIVE_LOW ---help--- Set this if the backlight pwm output is active low. +config VIDEO_LCD_PANEL_I2C + bool "LCD panel needs to be configured via i2c" + depends on VIDEO + default m + ---help--- + Say y here if the LCD panel needs to be configured via i2c. This + will add a bitbang i2c controller using gpios to talk to the LCD. + +config VIDEO_LCD_PANEL_I2C_SDA + string "LCD panel i2c interface SDA pin" + depends on VIDEO_LCD_PANEL_I2C + default "PG12" + ---help--- + Set the SDA pin for the LCD i2c interface. This takes a string in the + format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. + +config VIDEO_LCD_PANEL_I2C_SCL + string "LCD panel i2c interface SCL pin" + depends on VIDEO_LCD_PANEL_I2C + default "PG10" + ---help--- + Set the SCL pin for the LCD i2c interface. This takes a string in the + format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. + # Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b70e00ce6b..e1891d198e 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -33,6 +33,12 @@ #include #include +#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) +/* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */ +int soft_i2c_gpio_sda; +int soft_i2c_gpio_scl; +#endif + DECLARE_GLOBAL_DATA_PTR; /* add board specific code here */ @@ -152,6 +158,10 @@ void i2c_init_board(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0); sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0); clock_twi_onoff(0, 1); +#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) + soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA); + soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL); +#endif } #ifdef CONFIG_SPL_BUILD diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1238d821b3..f5efebbf28 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -183,6 +183,22 @@ #define CONFIG_SYS_I2C_MVTWSI #define CONFIG_SYS_I2C_SPEED 400000 #define CONFIG_SYS_I2C_SLAVE 0x7f + +#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) +#define CONFIG_SYS_I2C_SOFT +#define CONFIG_SYS_I2C_SOFT_SPEED 50000 +#define CONFIG_SYS_I2C_SOFT_SLAVE 0x00 +#define CONFIG_VIDEO_LCD_I2C_BUS 0 /* The lcd panel soft i2c is bus 0 */ +#define CONFIG_SYS_SPD_BUS_NUM 1 /* And the axp209 i2c bus is bus 1 */ +/* We use pin names in Kconfig and sunxi_name_to_gpio() */ +#define CONFIG_SOFT_I2C_GPIO_SDA soft_i2c_gpio_sda +#define CONFIG_SOFT_I2C_GPIO_SCL soft_i2c_gpio_scl +#ifndef __ASSEMBLY__ +extern int soft_i2c_gpio_sda; +extern int soft_i2c_gpio_scl; +#endif +#endif + #define CONFIG_CMD_I2C /* PMU */ -- cgit From aad2ac24c0871bb897be676aca946f37dd05f187 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Feb 2015 17:49:47 +0100 Subject: sunxi: video: Add support for tl059wv5c0 lcd panels Add support for the 6" 480x800 tl059wv5c0 panel used on e.g. Utoo P66 and Aigo M60/M608/M606 tablets. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 8 ++++++++ drivers/video/sunxi_display.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index bbb4d1b1e5..f5471a14c5 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -406,6 +406,14 @@ config VIDEO_LCD_PANEL_HITACHI_TX18D42VM ---help--- 7.85" 1024x768 Hitachi tx18d42vm LCD panel support +config VIDEO_LCD_TL059WV5C0 + bool "tl059wv5c0 LCD panel" + select VIDEO_LCD_PANEL_I2C + select VIDEO_LCD_IF_PARALLEL + ---help--- + 6" 480x800 tl059wv5c0 panel support, as used on the Utoo P66 and + Aigo M60/M608/M606 tablets. + endchoice diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 7f01401252..4e12150027 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "videomodes.h" #include "hitachi_tx18d42vm_lcd.h" @@ -1030,6 +1031,12 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, mdelay(50); /* Wait for lcd controller power on */ hitachi_tx18d42vm_init(); } + if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) { + unsigned int orig_i2c_bus = i2c_get_bus_num(); + i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS); + i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */ + i2c_set_bus_num(orig_i2c_bus); + } sunxi_composer_mode_set(mode, address); sunxi_lcdc_tcon0_mode_set(mode, false); sunxi_composer_enable(); -- cgit From 4614b891347dde81b59f32e1ea659c8251f0c4ca Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:01 +0900 Subject: ARM: at91: move board select menu and common settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board select menu in arch/arm/Kconfig is still big. To slim down it, this commit moves AT91 boards to arch/arm/mach-at91/Kconfig. Also, consolidate "config SYS_SOC" in each board Kconfig. The Kconfig files under board/ directory were modified with the following command: find board -name Kconfig | xargs sed -i -e ' /config SYS_SOC/ { N /default "at91"/ { N d } } ' Signed-off-by: Masahiro Yamada Acked-by: Andreas Bießmann --- arch/arm/Kconfig | 159 +---------------------- arch/arm/mach-at91/Kconfig | 168 +++++++++++++++++++++++++ board/BuS/eb_cpux9k2/Kconfig | 3 - board/BuS/vl_ma2sc/Kconfig | 3 - board/afeb9260/Kconfig | 3 - board/atmel/at91rm9200ek/Kconfig | 3 - board/atmel/at91sam9260ek/Kconfig | 3 - board/atmel/at91sam9261ek/Kconfig | 3 - board/atmel/at91sam9263ek/Kconfig | 3 - board/atmel/at91sam9m10g45ek/Kconfig | 3 - board/atmel/at91sam9n12ek/Kconfig | 3 - board/atmel/at91sam9rlek/Kconfig | 3 - board/atmel/at91sam9x5ek/Kconfig | 3 - board/atmel/sama5d3_xplained/Kconfig | 3 - board/atmel/sama5d3xek/Kconfig | 3 - board/atmel/sama5d4_xplained/Kconfig | 3 - board/atmel/sama5d4ek/Kconfig | 3 - board/bluewater/snapper9260/Kconfig | 3 - board/calao/sbc35_a9g20/Kconfig | 3 - board/calao/tny_a9260/Kconfig | 3 - board/calao/usb_a9263/Kconfig | 3 - board/egnite/ethernut5/Kconfig | 3 - board/esd/meesc/Kconfig | 3 - board/esd/otc570/Kconfig | 3 - board/eukrea/cpu9260/Kconfig | 3 - board/eukrea/cpuat91/Kconfig | 3 - board/ronetix/pm9261/Kconfig | 3 - board/ronetix/pm9263/Kconfig | 3 - board/ronetix/pm9g45/Kconfig | 3 - board/siemens/corvus/Kconfig | 3 - board/siemens/taurus/Kconfig | 3 - board/taskit/stamp9g20/Kconfig | 3 - configs/afeb9260_defconfig | 1 + configs/at91rm9200ek_defconfig | 1 + configs/at91rm9200ek_ram_defconfig | 1 + configs/at91sam9260ek_dataflash_cs0_defconfig | 1 + configs/at91sam9260ek_dataflash_cs1_defconfig | 1 + configs/at91sam9260ek_nandflash_defconfig | 1 + configs/at91sam9261ek_dataflash_cs0_defconfig | 1 + configs/at91sam9261ek_dataflash_cs3_defconfig | 1 + configs/at91sam9261ek_nandflash_defconfig | 1 + configs/at91sam9263ek_dataflash_cs0_defconfig | 1 + configs/at91sam9263ek_dataflash_defconfig | 1 + configs/at91sam9263ek_nandflash_defconfig | 1 + configs/at91sam9263ek_norflash_boot_defconfig | 1 + configs/at91sam9263ek_norflash_defconfig | 1 + configs/at91sam9g10ek_dataflash_cs0_defconfig | 1 + configs/at91sam9g10ek_dataflash_cs3_defconfig | 1 + configs/at91sam9g10ek_nandflash_defconfig | 1 + configs/at91sam9g20ek_2mmc_defconfig | 1 + configs/at91sam9g20ek_2mmc_nandflash_defconfig | 1 + configs/at91sam9g20ek_dataflash_cs0_defconfig | 1 + configs/at91sam9g20ek_dataflash_cs1_defconfig | 1 + configs/at91sam9g20ek_nandflash_defconfig | 1 + configs/at91sam9m10g45ek_mmc_defconfig | 1 + configs/at91sam9m10g45ek_nandflash_defconfig | 1 + configs/at91sam9n12ek_mmc_defconfig | 1 + configs/at91sam9n12ek_nandflash_defconfig | 1 + configs/at91sam9n12ek_spiflash_defconfig | 1 + configs/at91sam9rlek_dataflash_defconfig | 1 + configs/at91sam9rlek_nandflash_defconfig | 1 + configs/at91sam9x5ek_dataflash_defconfig | 1 + configs/at91sam9x5ek_mmc_defconfig | 1 + configs/at91sam9x5ek_nandflash_defconfig | 1 + configs/at91sam9x5ek_spiflash_defconfig | 1 + configs/at91sam9xeek_dataflash_cs0_defconfig | 1 + configs/at91sam9xeek_dataflash_cs1_defconfig | 1 + configs/at91sam9xeek_nandflash_defconfig | 1 + configs/axm_defconfig | 1 + configs/corvus_defconfig | 1 + configs/cpu9260_128M_defconfig | 1 + configs/cpu9260_defconfig | 1 + configs/cpu9260_nand_128M_defconfig | 1 + configs/cpu9260_nand_defconfig | 1 + configs/cpu9G20_128M_defconfig | 1 + configs/cpu9G20_defconfig | 1 + configs/cpu9G20_nand_128M_defconfig | 1 + configs/cpu9G20_nand_defconfig | 1 + configs/cpuat91_defconfig | 1 + configs/cpuat91_ram_defconfig | 1 + configs/eb_cpux9k2_defconfig | 1 + configs/eb_cpux9k2_ram_defconfig | 1 + configs/ethernut5_defconfig | 1 + configs/meesc_dataflash_defconfig | 1 + configs/meesc_defconfig | 1 + configs/otc570_dataflash_defconfig | 1 + configs/otc570_defconfig | 1 + configs/pm9261_defconfig | 1 + configs/pm9263_defconfig | 1 + configs/pm9g45_defconfig | 1 + configs/portuxg20_defconfig | 1 + configs/sama5d3_xplained_mmc_defconfig | 1 + configs/sama5d3_xplained_nandflash_defconfig | 1 + configs/sama5d3xek_mmc_defconfig | 1 + configs/sama5d3xek_nandflash_defconfig | 1 + configs/sama5d3xek_spiflash_defconfig | 1 + configs/sama5d4_xplained_mmc_defconfig | 1 + configs/sama5d4_xplained_nandflash_defconfig | 1 + configs/sama5d4_xplained_spiflash_defconfig | 1 + configs/sama5d4ek_mmc_defconfig | 1 + configs/sama5d4ek_nandflash_defconfig | 1 + configs/sama5d4ek_spiflash_defconfig | 1 + configs/sbc35_a9g20_eeprom_defconfig | 1 + configs/sbc35_a9g20_nandflash_defconfig | 1 + configs/snapper9260_defconfig | 1 + configs/snapper9g20_defconfig | 1 + configs/stamp9g20_defconfig | 1 + configs/taurus_defconfig | 1 + configs/tny_a9260_eeprom_defconfig | 1 + configs/tny_a9260_nandflash_defconfig | 1 + configs/tny_a9g20_eeprom_defconfig | 1 + configs/tny_a9g20_nandflash_defconfig | 1 + configs/usb_a9263_dataflash_defconfig | 1 + configs/vl_ma2sc_defconfig | 1 + configs/vl_ma2sc_ram_defconfig | 1 + 115 files changed, 255 insertions(+), 245 deletions(-) create mode 100644 arch/arm/mach-at91/Kconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 41f3220580..06c34682c4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -77,17 +77,8 @@ config TARGET_A320EVB bool "Support a320evb" select CPU_ARM920T -config TARGET_AT91RM9200EK - bool "Support at91rm9200ek" - select CPU_ARM920T - -config TARGET_EB_CPUX9K2 - bool "Support eb_cpux9k2" - select CPU_ARM920T - -config TARGET_CPUAT91 - bool "Support cpuat91" - select CPU_ARM920T +config ARCH_AT91 + bool "Atmel AT91" config TARGET_EDB93XX bool "Support edb93xx" @@ -129,100 +120,6 @@ config TARGET_GPLUGD bool "Support gplugd" select CPU_ARM926EJS -config TARGET_AFEB9260 - bool "Support afeb9260" - select CPU_ARM926EJS - -config TARGET_AT91SAM9260EK - bool "Support at91sam9260ek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9261EK - bool "Support at91sam9261ek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9263EK - bool "Support at91sam9263ek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9M10G45EK - bool "Support at91sam9m10g45ek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9N12EK - bool "Support at91sam9n12ek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9RLEK - bool "Support at91sam9rlek" - select CPU_ARM926EJS - -config TARGET_AT91SAM9X5EK - bool "Support at91sam9x5ek" - select CPU_ARM926EJS - -config TARGET_SNAPPER9260 - bool "Support snapper9260" - select CPU_ARM926EJS - -config TARGET_VL_MA2SC - bool "Support vl_ma2sc" - select CPU_ARM926EJS - -config TARGET_SBC35_A9G20 - bool "Support sbc35_a9g20" - select CPU_ARM926EJS - -config TARGET_TNY_A9260 - bool "Support tny_a9260" - select CPU_ARM926EJS - -config TARGET_USB_A9263 - bool "Support usb_a9263" - select CPU_ARM926EJS - -config TARGET_ETHERNUT5 - bool "Support ethernut5" - select CPU_ARM926EJS - -config TARGET_MEESC - bool "Support meesc" - select CPU_ARM926EJS - -config TARGET_OTC570 - bool "Support otc570" - select CPU_ARM926EJS - -config TARGET_CPU9260 - bool "Support cpu9260" - select CPU_ARM926EJS - -config TARGET_PM9261 - bool "Support pm9261" - select CPU_ARM926EJS - -config TARGET_PM9263 - bool "Support pm9263" - select CPU_ARM926EJS - -config TARGET_PM9G45 - bool "Support pm9g45" - select CPU_ARM926EJS - -config TARGET_CORVUS - select SUPPORT_SPL - bool "Support corvus" - select CPU_ARM926EJS - -config TARGET_TAURUS - select SUPPORT_SPL - bool "Support taurus" - select CPU_ARM926EJS - -config TARGET_STAMP9G20 - bool "Support stamp9g20" - select CPU_ARM926EJS - config ARCH_DAVINCI bool "TI DaVinci" select CPU_ARM926EJS @@ -514,26 +411,6 @@ config TARGET_TI816X_EVM select CPU_V7 select SUPPORT_SPL -config TARGET_SAMA5D3_XPLAINED - bool "Support sama5d3_xplained" - select CPU_V7 - select SUPPORT_SPL - -config TARGET_SAMA5D3XEK - bool "Support sama5d3xek" - select CPU_V7 - select SUPPORT_SPL - -config TARGET_SAMA5D4_XPLAINED - bool "Support sama5d4_xplained" - select CPU_V7 - select SUPPORT_SPL - -config TARGET_SAMA5D4EK - bool "Support sama5d4ek" - select CPU_V7 - select SUPPORT_SPL - config TARGET_BCM28155_AP bool "Support bcm28155_ap" select CPU_V7 @@ -837,6 +714,8 @@ config ARCH_UNIPHIER endchoice +source "arch/arm/mach-at91/Kconfig" + source "arch/arm/cpu/arm926ejs/davinci/Kconfig" source "arch/arm/cpu/arm1176/bcm2835/Kconfig" @@ -876,44 +755,25 @@ source "arch/arm/cpu/armv7/Kconfig" source "board/aristainetos/Kconfig" source "board/BuR/kwb/Kconfig" source "board/BuR/tseries/Kconfig" -source "board/BuS/eb_cpux9k2/Kconfig" -source "board/BuS/vl_ma2sc/Kconfig" source "board/CarMediaLab/flea3/Kconfig" source "board/Marvell/aspenite/Kconfig" source "board/Marvell/db-mv784mp-gp/Kconfig" source "board/Marvell/dkb/Kconfig" source "board/Marvell/gplugd/Kconfig" -source "board/afeb9260/Kconfig" source "board/altera/socfpga/Kconfig" source "board/armadeus/apf27/Kconfig" source "board/armltd/integrator/Kconfig" source "board/armltd/vexpress/Kconfig" source "board/armltd/vexpress64/Kconfig" -source "board/atmel/at91rm9200ek/Kconfig" -source "board/atmel/at91sam9260ek/Kconfig" -source "board/atmel/at91sam9261ek/Kconfig" -source "board/atmel/at91sam9263ek/Kconfig" -source "board/atmel/at91sam9m10g45ek/Kconfig" -source "board/atmel/at91sam9n12ek/Kconfig" -source "board/atmel/at91sam9rlek/Kconfig" -source "board/atmel/at91sam9x5ek/Kconfig" -source "board/atmel/sama5d3_xplained/Kconfig" -source "board/atmel/sama5d3xek/Kconfig" -source "board/atmel/sama5d4_xplained/Kconfig" -source "board/atmel/sama5d4ek/Kconfig" source "board/bachmann/ot1200/Kconfig" source "board/balloon3/Kconfig" source "board/barco/platinum/Kconfig" source "board/barco/titanium/Kconfig" source "board/bluegiga/apx4devkit/Kconfig" -source "board/bluewater/snapper9260/Kconfig" source "board/boundary/nitrogen6x/Kconfig" source "board/broadcom/bcm28155_ap/Kconfig" source "board/broadcom/bcmcygnus/Kconfig" source "board/broadcom/bcmnsp/Kconfig" -source "board/calao/sbc35_a9g20/Kconfig" -source "board/calao/tny_a9260/Kconfig" -source "board/calao/usb_a9263/Kconfig" source "board/cirrus/edb93xx/Kconfig" source "board/cm4008/Kconfig" source "board/cm41xx/Kconfig" @@ -924,13 +784,8 @@ source "board/creative/xfi3/Kconfig" source "board/davedenx/qong/Kconfig" source "board/denx/m28evk/Kconfig" source "board/denx/m53evk/Kconfig" -source "board/egnite/ethernut5/Kconfig" source "board/embest/mx6boards/Kconfig" -source "board/esd/meesc/Kconfig" -source "board/esd/otc570/Kconfig" source "board/esg/ima3-mx53/Kconfig" -source "board/eukrea/cpu9260/Kconfig" -source "board/eukrea/cpuat91/Kconfig" source "board/faraday/a320evb/Kconfig" source "board/freescale/ls2085a/Kconfig" source "board/freescale/ls1021aqds/Kconfig" @@ -975,18 +830,13 @@ source "board/phytec/pcm051/Kconfig" source "board/ppcag/bg0900/Kconfig" source "board/pxa255_idp/Kconfig" source "board/raspberrypi/rpi/Kconfig" -source "board/ronetix/pm9261/Kconfig" -source "board/ronetix/pm9263/Kconfig" -source "board/ronetix/pm9g45/Kconfig" source "board/samsung/smdk2410/Kconfig" source "board/sandisk/sansa_fuze_plus/Kconfig" source "board/scb9328/Kconfig" source "board/schulercontrol/sc_sps_1/Kconfig" -source "board/siemens/corvus/Kconfig" source "board/siemens/draco/Kconfig" source "board/siemens/pxm2/Kconfig" source "board/siemens/rut/Kconfig" -source "board/siemens/taurus/Kconfig" source "board/silica/pengwyn/Kconfig" source "board/solidrun/hummingboard/Kconfig" source "board/spear/spear300/Kconfig" @@ -1000,7 +850,6 @@ source "board/st/stv0991/Kconfig" source "board/sunxi/Kconfig" source "board/syteco/jadecpu/Kconfig" source "board/syteco/zmx25/Kconfig" -source "board/taskit/stamp9g20/Kconfig" source "board/tbs/tbs2910/Kconfig" source "board/ti/am335x/Kconfig" source "board/ti/am43xx/Kconfig" diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig new file mode 100644 index 0000000000..30945c101b --- /dev/null +++ b/arch/arm/mach-at91/Kconfig @@ -0,0 +1,168 @@ +if ARCH_AT91 + +choice + prompt "Atmel AT91 board select" + +config TARGET_AT91RM9200EK + bool "Atmel AT91RM9200 evaluation kit" + select CPU_ARM920T + +config TARGET_EB_CPUX9K2 + bool "Support eb_cpux9k2" + select CPU_ARM920T + +config TARGET_CPUAT91 + bool "Support cpuat91" + select CPU_ARM920T + +config TARGET_AT91SAM9260EK + bool "Atmel at91sam9260 reference board" + select CPU_ARM926EJS + +config TARGET_ETHERNUT5 + bool "Ethernut5 board" + select CPU_ARM926EJS + +config TARGET_TNY_A9260 + bool "Caloa TNY A9260 board" + select CPU_ARM926EJS + +config TARGET_SNAPPER9260 + bool "Support snapper9260" + select CPU_ARM926EJS + +config TARGET_AFEB9260 + bool "Support afeb9260" + select CPU_ARM926EJS + +config TARGET_AT91SAM9261EK + bool "Atmel at91sam9261 reference board" + select CPU_ARM926EJS + +config TARGET_PM9261 + bool "Ronetix pm9261 board" + select CPU_ARM926EJS + +config TARGET_AT91SAM9263EK + bool "Atmel at91sam9263 reference board" + select CPU_ARM926EJS + +config TARGET_USB_A9263 + bool "Caloa USB A9260 board" + select CPU_ARM926EJS + +config TARGET_PM9263 + bool "Ronetix pm9263 board" + select CPU_ARM926EJS + +config TARGET_SBC35_A9G20 + bool "Support sbc35_a9g20" + select CPU_ARM926EJS + +config TARGET_STAMP9G20 + bool "Support stamp9g20" + select CPU_ARM926EJS + +config TARGET_AT91SAM9M10G45EK + bool "Atmel AT91SAM9M10G45-EK board" + select CPU_ARM926EJS + +config TARGET_PM9G45 + bool "Ronetix pm9g45 board" + select CPU_ARM926EJS + +config TARGET_AT91SAM9N12EK + bool "Atmel AT91SAM9N12-EK board" + select CPU_ARM926EJS + +config TARGET_AT91SAM9RLEK + bool "Atmel at91sam9rl reference board" + select CPU_ARM926EJS + +config TARGET_AT91SAM9X5EK + bool "Atmel AT91SAM9X5-EK board" + select CPU_ARM926EJS + +config TARGET_SAMA5D3_XPLAINED + bool "SAMA5D3 Xplained board" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_SAMA5D3XEK + bool "SAMA5D3X-EK board" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_SAMA5D4_XPLAINED + bool "SAMA5D4 Xplained board" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_SAMA5D4EK + bool "SAMA5D4 Evaluation Kit" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_VL_MA2SC + bool "Support vl_ma2sc" + select CPU_ARM926EJS + +config TARGET_MEESC + bool "Support meesc" + select CPU_ARM926EJS + +config TARGET_OTC570 + bool "Support otc570" + select CPU_ARM926EJS + +config TARGET_CPU9260 + bool "Support cpu9260" + select CPU_ARM926EJS + +config TARGET_CORVUS + bool "Support corvus" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_TAURUS + bool "Support taurus" + select CPU_ARM926EJS + select SUPPORT_SPL + +endchoice + +config SYS_SOC + default "at91" + +source "board/atmel/at91rm9200ek/Kconfig" +source "board/atmel/at91sam9260ek/Kconfig" +source "board/atmel/at91sam9261ek/Kconfig" +source "board/atmel/at91sam9263ek/Kconfig" +source "board/atmel/at91sam9m10g45ek/Kconfig" +source "board/atmel/at91sam9n12ek/Kconfig" +source "board/atmel/at91sam9rlek/Kconfig" +source "board/atmel/at91sam9x5ek/Kconfig" +source "board/atmel/sama5d3_xplained/Kconfig" +source "board/atmel/sama5d3xek/Kconfig" +source "board/atmel/sama5d4_xplained/Kconfig" +source "board/atmel/sama5d4ek/Kconfig" +source "board/BuS/eb_cpux9k2/Kconfig" +source "board/eukrea/cpuat91/Kconfig" +source "board/afeb9260/Kconfig" +source "board/bluewater/snapper9260/Kconfig" +source "board/BuS/vl_ma2sc/Kconfig" +source "board/calao/sbc35_a9g20/Kconfig" +source "board/calao/tny_a9260/Kconfig" +source "board/calao/usb_a9263/Kconfig" +source "board/egnite/ethernut5/Kconfig" +source "board/esd/meesc/Kconfig" +source "board/esd/otc570/Kconfig" +source "board/eukrea/cpu9260/Kconfig" +source "board/ronetix/pm9261/Kconfig" +source "board/ronetix/pm9263/Kconfig" +source "board/ronetix/pm9g45/Kconfig" +source "board/siemens/corvus/Kconfig" +source "board/siemens/taurus/Kconfig" +source "board/taskit/stamp9g20/Kconfig" + +endif diff --git a/board/BuS/eb_cpux9k2/Kconfig b/board/BuS/eb_cpux9k2/Kconfig index 230e64d8fc..e2a787a1a8 100644 --- a/board/BuS/eb_cpux9k2/Kconfig +++ b/board/BuS/eb_cpux9k2/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "BuS" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "eb_cpux9k2" diff --git a/board/BuS/vl_ma2sc/Kconfig b/board/BuS/vl_ma2sc/Kconfig index 2f43519089..848177f4c4 100644 --- a/board/BuS/vl_ma2sc/Kconfig +++ b/board/BuS/vl_ma2sc/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "BuS" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "vl_ma2sc" diff --git a/board/afeb9260/Kconfig b/board/afeb9260/Kconfig index 6a5a93139d..fb64c9cec7 100644 --- a/board/afeb9260/Kconfig +++ b/board/afeb9260/Kconfig @@ -3,9 +3,6 @@ if TARGET_AFEB9260 config SYS_BOARD default "afeb9260" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "afeb9260" diff --git a/board/atmel/at91rm9200ek/Kconfig b/board/atmel/at91rm9200ek/Kconfig index bad4a37da0..952351dcdb 100644 --- a/board/atmel/at91rm9200ek/Kconfig +++ b/board/atmel/at91rm9200ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91rm9200ek" diff --git a/board/atmel/at91sam9260ek/Kconfig b/board/atmel/at91sam9260ek/Kconfig index fe00ed5e60..3844f086b4 100644 --- a/board/atmel/at91sam9260ek/Kconfig +++ b/board/atmel/at91sam9260ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9260ek" diff --git a/board/atmel/at91sam9261ek/Kconfig b/board/atmel/at91sam9261ek/Kconfig index d839c1a632..2971b3cf9f 100644 --- a/board/atmel/at91sam9261ek/Kconfig +++ b/board/atmel/at91sam9261ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9261ek" diff --git a/board/atmel/at91sam9263ek/Kconfig b/board/atmel/at91sam9263ek/Kconfig index 311c504da2..3f0873fe51 100644 --- a/board/atmel/at91sam9263ek/Kconfig +++ b/board/atmel/at91sam9263ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9263ek" diff --git a/board/atmel/at91sam9m10g45ek/Kconfig b/board/atmel/at91sam9m10g45ek/Kconfig index 1bc086a483..211c411ef6 100644 --- a/board/atmel/at91sam9m10g45ek/Kconfig +++ b/board/atmel/at91sam9m10g45ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9m10g45ek" diff --git a/board/atmel/at91sam9n12ek/Kconfig b/board/atmel/at91sam9n12ek/Kconfig index cf1d1a3670..816003a5de 100644 --- a/board/atmel/at91sam9n12ek/Kconfig +++ b/board/atmel/at91sam9n12ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9n12ek" diff --git a/board/atmel/at91sam9rlek/Kconfig b/board/atmel/at91sam9rlek/Kconfig index 438d300421..81a839ac03 100644 --- a/board/atmel/at91sam9rlek/Kconfig +++ b/board/atmel/at91sam9rlek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9rlek" diff --git a/board/atmel/at91sam9x5ek/Kconfig b/board/atmel/at91sam9x5ek/Kconfig index 5c5ec61577..3f92754fb9 100644 --- a/board/atmel/at91sam9x5ek/Kconfig +++ b/board/atmel/at91sam9x5ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "at91sam9x5ek" diff --git a/board/atmel/sama5d3_xplained/Kconfig b/board/atmel/sama5d3_xplained/Kconfig index 0ba8a7bf93..2df751a264 100644 --- a/board/atmel/sama5d3_xplained/Kconfig +++ b/board/atmel/sama5d3_xplained/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "sama5d3_xplained" diff --git a/board/atmel/sama5d3xek/Kconfig b/board/atmel/sama5d3xek/Kconfig index 2a9ed23ecf..abd1ad81fc 100644 --- a/board/atmel/sama5d3xek/Kconfig +++ b/board/atmel/sama5d3xek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "sama5d3xek" diff --git a/board/atmel/sama5d4_xplained/Kconfig b/board/atmel/sama5d4_xplained/Kconfig index f320a68d30..2cb03cb178 100644 --- a/board/atmel/sama5d4_xplained/Kconfig +++ b/board/atmel/sama5d4_xplained/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "sama5d4_xplained" diff --git a/board/atmel/sama5d4ek/Kconfig b/board/atmel/sama5d4ek/Kconfig index 7dc569c411..1a634032ac 100644 --- a/board/atmel/sama5d4ek/Kconfig +++ b/board/atmel/sama5d4ek/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "atmel" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "sama5d4ek" diff --git a/board/bluewater/snapper9260/Kconfig b/board/bluewater/snapper9260/Kconfig index c896c46895..b8e9cbc585 100644 --- a/board/bluewater/snapper9260/Kconfig +++ b/board/bluewater/snapper9260/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "bluewater" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "snapper9260" diff --git a/board/calao/sbc35_a9g20/Kconfig b/board/calao/sbc35_a9g20/Kconfig index fb5a1a3f42..37ecfb5f7d 100644 --- a/board/calao/sbc35_a9g20/Kconfig +++ b/board/calao/sbc35_a9g20/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "calao" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "sbc35_a9g20" diff --git a/board/calao/tny_a9260/Kconfig b/board/calao/tny_a9260/Kconfig index b1de8f8ba8..2b663298f3 100644 --- a/board/calao/tny_a9260/Kconfig +++ b/board/calao/tny_a9260/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "calao" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "tny_a9260" diff --git a/board/calao/usb_a9263/Kconfig b/board/calao/usb_a9263/Kconfig index 7a159dc3ba..19e446ded5 100644 --- a/board/calao/usb_a9263/Kconfig +++ b/board/calao/usb_a9263/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "calao" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "usb_a9263" diff --git a/board/egnite/ethernut5/Kconfig b/board/egnite/ethernut5/Kconfig index c42c734f1f..5a6c1c5de1 100644 --- a/board/egnite/ethernut5/Kconfig +++ b/board/egnite/ethernut5/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "egnite" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "ethernut5" diff --git a/board/esd/meesc/Kconfig b/board/esd/meesc/Kconfig index 5041041dd2..150348ac34 100644 --- a/board/esd/meesc/Kconfig +++ b/board/esd/meesc/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "esd" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "meesc" diff --git a/board/esd/otc570/Kconfig b/board/esd/otc570/Kconfig index 55a2f70f40..4966f5f755 100644 --- a/board/esd/otc570/Kconfig +++ b/board/esd/otc570/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "esd" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "otc570" diff --git a/board/eukrea/cpu9260/Kconfig b/board/eukrea/cpu9260/Kconfig index 9bd077b1ff..90d2124557 100644 --- a/board/eukrea/cpu9260/Kconfig +++ b/board/eukrea/cpu9260/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "eukrea" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "cpu9260" diff --git a/board/eukrea/cpuat91/Kconfig b/board/eukrea/cpuat91/Kconfig index b69e4c3f82..27b005cdf4 100644 --- a/board/eukrea/cpuat91/Kconfig +++ b/board/eukrea/cpuat91/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "eukrea" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "cpuat91" diff --git a/board/ronetix/pm9261/Kconfig b/board/ronetix/pm9261/Kconfig index a4934c582e..8c54198102 100644 --- a/board/ronetix/pm9261/Kconfig +++ b/board/ronetix/pm9261/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "ronetix" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "pm9261" diff --git a/board/ronetix/pm9263/Kconfig b/board/ronetix/pm9263/Kconfig index 339a6ea169..5b47d34845 100644 --- a/board/ronetix/pm9263/Kconfig +++ b/board/ronetix/pm9263/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "ronetix" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "pm9263" diff --git a/board/ronetix/pm9g45/Kconfig b/board/ronetix/pm9g45/Kconfig index 65fc5c4838..ad5309f816 100644 --- a/board/ronetix/pm9g45/Kconfig +++ b/board/ronetix/pm9g45/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "ronetix" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "pm9g45" diff --git a/board/siemens/corvus/Kconfig b/board/siemens/corvus/Kconfig index 7b505aac36..69fe0f0723 100644 --- a/board/siemens/corvus/Kconfig +++ b/board/siemens/corvus/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "siemens" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "corvus" diff --git a/board/siemens/taurus/Kconfig b/board/siemens/taurus/Kconfig index c07d244bc3..cf71e4ce56 100644 --- a/board/siemens/taurus/Kconfig +++ b/board/siemens/taurus/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "siemens" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "taurus" diff --git a/board/taskit/stamp9g20/Kconfig b/board/taskit/stamp9g20/Kconfig index 3139f9af86..1121dacfc7 100644 --- a/board/taskit/stamp9g20/Kconfig +++ b/board/taskit/stamp9g20/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "taskit" -config SYS_SOC - default "at91" - config SYS_CONFIG_NAME default "stamp9g20" diff --git a/configs/afeb9260_defconfig b/configs/afeb9260_defconfig index 2616d2d027..694d24d888 100644 --- a/configs/afeb9260_defconfig +++ b/configs/afeb9260_defconfig @@ -1,2 +1,3 @@ CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AFEB9260=y diff --git a/configs/at91rm9200ek_defconfig b/configs/at91rm9200ek_defconfig index 95b5c2797b..e1fd2ec225 100644 --- a/configs/at91rm9200ek_defconfig +++ b/configs/at91rm9200ek_defconfig @@ -1,2 +1,3 @@ CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91RM9200EK=y diff --git a/configs/at91rm9200ek_ram_defconfig b/configs/at91rm9200ek_ram_defconfig index 5039ebc9b9..64f5e54325 100644 --- a/configs/at91rm9200ek_ram_defconfig +++ b/configs/at91rm9200ek_ram_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91RM9200EK=y diff --git a/configs/at91sam9260ek_dataflash_cs0_defconfig b/configs/at91sam9260ek_dataflash_cs0_defconfig index 7f929c8376..46ce31ba49 100644 --- a/configs/at91sam9260ek_dataflash_cs0_defconfig +++ b/configs/at91sam9260ek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260,SYS_USE_DATAFLASH_CS0" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9260ek_dataflash_cs1_defconfig b/configs/at91sam9260ek_dataflash_cs1_defconfig index e2c32bf7c7..9fd40dfd3f 100644 --- a/configs/at91sam9260ek_dataflash_cs1_defconfig +++ b/configs/at91sam9260ek_dataflash_cs1_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260,SYS_USE_DATAFLASH_CS1" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9260ek_nandflash_defconfig b/configs/at91sam9260ek_nandflash_defconfig index 1168cace31..98adab2b10 100644 --- a/configs/at91sam9260ek_nandflash_defconfig +++ b/configs/at91sam9260ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9261ek_dataflash_cs0_defconfig b/configs/at91sam9261ek_dataflash_cs0_defconfig index 486eeb295f..9c311a3a82 100644 --- a/configs/at91sam9261ek_dataflash_cs0_defconfig +++ b/configs/at91sam9261ek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9261,SYS_USE_DATAFLASH_CS0" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9261ek_dataflash_cs3_defconfig b/configs/at91sam9261ek_dataflash_cs3_defconfig index 5f42a90ca5..3711fe4893 100644 --- a/configs/at91sam9261ek_dataflash_cs3_defconfig +++ b/configs/at91sam9261ek_dataflash_cs3_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9261,SYS_USE_DATAFLASH_CS3" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9261ek_nandflash_defconfig b/configs/at91sam9261ek_nandflash_defconfig index 4d7aa9064e..503f760f11 100644 --- a/configs/at91sam9261ek_nandflash_defconfig +++ b/configs/at91sam9261ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9261,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9263ek_dataflash_cs0_defconfig b/configs/at91sam9263ek_dataflash_cs0_defconfig index 4dce54e5c6..15925b6574 100644 --- a/configs/at91sam9263ek_dataflash_cs0_defconfig +++ b/configs/at91sam9263ek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9263EK=y diff --git a/configs/at91sam9263ek_dataflash_defconfig b/configs/at91sam9263ek_dataflash_defconfig index 4dce54e5c6..15925b6574 100644 --- a/configs/at91sam9263ek_dataflash_defconfig +++ b/configs/at91sam9263ek_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9263EK=y diff --git a/configs/at91sam9263ek_nandflash_defconfig b/configs/at91sam9263ek_nandflash_defconfig index 6f60daa9c7..457fb1ab33 100644 --- a/configs/at91sam9263ek_nandflash_defconfig +++ b/configs/at91sam9263ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9263EK=y diff --git a/configs/at91sam9263ek_norflash_boot_defconfig b/configs/at91sam9263ek_norflash_boot_defconfig index 944c14dde0..e49b17732b 100644 --- a/configs/at91sam9263ek_norflash_boot_defconfig +++ b/configs/at91sam9263ek_norflash_boot_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_BOOT_NORFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9263EK=y diff --git a/configs/at91sam9263ek_norflash_defconfig b/configs/at91sam9263ek_norflash_defconfig index b54ef7f0ba..fcd176480a 100644 --- a/configs/at91sam9263ek_norflash_defconfig +++ b/configs/at91sam9263ek_norflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_NORFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9263EK=y diff --git a/configs/at91sam9g10ek_dataflash_cs0_defconfig b/configs/at91sam9g10ek_dataflash_cs0_defconfig index 132102db3c..833412261b 100644 --- a/configs/at91sam9g10ek_dataflash_cs0_defconfig +++ b/configs/at91sam9g10ek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G10,SYS_USE_DATAFLASH_CS0" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9g10ek_dataflash_cs3_defconfig b/configs/at91sam9g10ek_dataflash_cs3_defconfig index 3dd3f9a817..25626ce2a6 100644 --- a/configs/at91sam9g10ek_dataflash_cs3_defconfig +++ b/configs/at91sam9g10ek_dataflash_cs3_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G10,SYS_USE_DATAFLASH_CS3" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9g10ek_nandflash_defconfig b/configs/at91sam9g10ek_nandflash_defconfig index a2bd6df384..7ae07940f4 100644 --- a/configs/at91sam9g10ek_nandflash_defconfig +++ b/configs/at91sam9g10ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G10,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9261EK=y diff --git a/configs/at91sam9g20ek_2mmc_defconfig b/configs/at91sam9g20ek_2mmc_defconfig index 4eef04f179..e277557351 100644 --- a/configs/at91sam9g20ek_2mmc_defconfig +++ b/configs/at91sam9g20ek_2mmc_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,AT91SAM9G20EK_2MMC,SYS_USE_MMC" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9g20ek_2mmc_nandflash_defconfig b/configs/at91sam9g20ek_2mmc_nandflash_defconfig index 1a4c505849..29219fb902 100644 --- a/configs/at91sam9g20ek_2mmc_nandflash_defconfig +++ b/configs/at91sam9g20ek_2mmc_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,AT91SAM9G20EK_2MMC,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9g20ek_dataflash_cs0_defconfig b/configs/at91sam9g20ek_dataflash_cs0_defconfig index cf35782ebb..4587f49640 100644 --- a/configs/at91sam9g20ek_dataflash_cs0_defconfig +++ b/configs/at91sam9g20ek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_DATAFLASH_CS0" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9g20ek_dataflash_cs1_defconfig b/configs/at91sam9g20ek_dataflash_cs1_defconfig index 1377ad91f4..c9fcc6eac3 100644 --- a/configs/at91sam9g20ek_dataflash_cs1_defconfig +++ b/configs/at91sam9g20ek_dataflash_cs1_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_DATAFLASH_CS1" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9g20ek_nandflash_defconfig b/configs/at91sam9g20ek_nandflash_defconfig index cfe91273c6..1d60e0abd5 100644 --- a/configs/at91sam9g20ek_nandflash_defconfig +++ b/configs/at91sam9g20ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9m10g45ek_mmc_defconfig b/configs/at91sam9m10g45ek_mmc_defconfig index 1681bc8b71..6949d3a007 100644 --- a/configs/at91sam9m10g45ek_mmc_defconfig +++ b/configs/at91sam9m10g45ek_mmc_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,SYS_USE_MMC" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9M10G45EK=y diff --git a/configs/at91sam9m10g45ek_nandflash_defconfig b/configs/at91sam9m10g45ek_nandflash_defconfig index 61ae56e452..30967e39c4 100644 --- a/configs/at91sam9m10g45ek_nandflash_defconfig +++ b/configs/at91sam9m10g45ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9M10G45EK=y diff --git a/configs/at91sam9n12ek_mmc_defconfig b/configs/at91sam9n12ek_mmc_defconfig index 71d16588f3..4fc417a4a4 100644 --- a/configs/at91sam9n12ek_mmc_defconfig +++ b/configs/at91sam9n12ek_mmc_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9N12,SYS_USE_MMC" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9N12EK=y diff --git a/configs/at91sam9n12ek_nandflash_defconfig b/configs/at91sam9n12ek_nandflash_defconfig index 6f677b1744..f908246d3d 100644 --- a/configs/at91sam9n12ek_nandflash_defconfig +++ b/configs/at91sam9n12ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9N12,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9N12EK=y diff --git a/configs/at91sam9n12ek_spiflash_defconfig b/configs/at91sam9n12ek_spiflash_defconfig index 7e898f0c43..d106b5a28e 100644 --- a/configs/at91sam9n12ek_spiflash_defconfig +++ b/configs/at91sam9n12ek_spiflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9N12,SYS_USE_SPIFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9N12EK=y diff --git a/configs/at91sam9rlek_dataflash_defconfig b/configs/at91sam9rlek_dataflash_defconfig index 90516e0c45..ee632d1ea9 100644 --- a/configs/at91sam9rlek_dataflash_defconfig +++ b/configs/at91sam9rlek_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9RL,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9RLEK=y diff --git a/configs/at91sam9rlek_nandflash_defconfig b/configs/at91sam9rlek_nandflash_defconfig index 0e2edfd0e0..6465f577cd 100644 --- a/configs/at91sam9rlek_nandflash_defconfig +++ b/configs/at91sam9rlek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9RL,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9RLEK=y diff --git a/configs/at91sam9x5ek_dataflash_defconfig b/configs/at91sam9x5ek_dataflash_defconfig index d00eed5876..15b5fa9f0c 100644 --- a/configs/at91sam9x5ek_dataflash_defconfig +++ b/configs/at91sam9x5ek_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9X5,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9X5EK=y diff --git a/configs/at91sam9x5ek_mmc_defconfig b/configs/at91sam9x5ek_mmc_defconfig index 64f7af9bab..c8096c22f4 100644 --- a/configs/at91sam9x5ek_mmc_defconfig +++ b/configs/at91sam9x5ek_mmc_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9X5,SYS_USE_MMC" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9X5EK=y diff --git a/configs/at91sam9x5ek_nandflash_defconfig b/configs/at91sam9x5ek_nandflash_defconfig index 47cd1e013b..c2ebb00a97 100644 --- a/configs/at91sam9x5ek_nandflash_defconfig +++ b/configs/at91sam9x5ek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9X5,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9X5EK=y diff --git a/configs/at91sam9x5ek_spiflash_defconfig b/configs/at91sam9x5ek_spiflash_defconfig index 1b7391e096..76f68a6039 100644 --- a/configs/at91sam9x5ek_spiflash_defconfig +++ b/configs/at91sam9x5ek_spiflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9X5,SYS_USE_SPIFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9X5EK=y diff --git a/configs/at91sam9xeek_dataflash_cs0_defconfig b/configs/at91sam9xeek_dataflash_cs0_defconfig index ccbccd43c8..1449791b06 100644 --- a/configs/at91sam9xeek_dataflash_cs0_defconfig +++ b/configs/at91sam9xeek_dataflash_cs0_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9XE,SYS_USE_DATAFLASH_CS0" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9xeek_dataflash_cs1_defconfig b/configs/at91sam9xeek_dataflash_cs1_defconfig index e8f4cc32c9..b465064446 100644 --- a/configs/at91sam9xeek_dataflash_cs1_defconfig +++ b/configs/at91sam9xeek_dataflash_cs1_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9XE,SYS_USE_DATAFLASH_CS1" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/at91sam9xeek_nandflash_defconfig b/configs/at91sam9xeek_nandflash_defconfig index 49c5d78778..7e73d48c3c 100644 --- a/configs/at91sam9xeek_nandflash_defconfig +++ b/configs/at91sam9xeek_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9XE,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_AT91SAM9260EK=y diff --git a/configs/axm_defconfig b/configs/axm_defconfig index 076ad0fe8d..abb64b6def 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,MACH_TYPE=2068,BOARD_AXM" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_TAURUS=y diff --git a/configs/corvus_defconfig b/configs/corvus_defconfig index 5d60847523..82be323a79 100644 --- a/configs/corvus_defconfig +++ b/configs/corvus_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_CORVUS=y diff --git a/configs/cpu9260_128M_defconfig b/configs/cpu9260_128M_defconfig index 86fc6bd7c5..6fe59ddcbb 100644 --- a/configs/cpu9260_128M_defconfig +++ b/configs/cpu9260_128M_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9260,CPU9260_128M" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9260_defconfig b/configs/cpu9260_defconfig index 10299e3bde..63e7c73c75 100644 --- a/configs/cpu9260_defconfig +++ b/configs/cpu9260_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9260" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9260_nand_128M_defconfig b/configs/cpu9260_nand_128M_defconfig index e582a15ce4..11c5bce975 100644 --- a/configs/cpu9260_nand_128M_defconfig +++ b/configs/cpu9260_nand_128M_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9260,CPU9260_128M,NANDBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9260_nand_defconfig b/configs/cpu9260_nand_defconfig index 40988cdf2a..d4d6ec9dbd 100644 --- a/configs/cpu9260_nand_defconfig +++ b/configs/cpu9260_nand_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9260,NANDBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9G20_128M_defconfig b/configs/cpu9G20_128M_defconfig index 4c28d252f9..8d33f082ce 100644 --- a/configs/cpu9G20_128M_defconfig +++ b/configs/cpu9G20_128M_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9G20,CPU9G20_128M" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9G20_defconfig b/configs/cpu9G20_defconfig index 468b2c8c9b..fcfebb86d7 100644 --- a/configs/cpu9G20_defconfig +++ b/configs/cpu9G20_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9G20" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9G20_nand_128M_defconfig b/configs/cpu9G20_nand_128M_defconfig index a74df9d124..315042d4e7 100644 --- a/configs/cpu9G20_nand_128M_defconfig +++ b/configs/cpu9G20_nand_128M_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9G20,CPU9G20_128M,NANDBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpu9G20_nand_defconfig b/configs/cpu9G20_nand_defconfig index 11cc276838..c405c5077b 100644 --- a/configs/cpu9G20_nand_defconfig +++ b/configs/cpu9G20_nand_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CPU9G20,NANDBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPU9260=y diff --git a/configs/cpuat91_defconfig b/configs/cpuat91_defconfig index d25bd3ae78..5a1ef3a3eb 100644 --- a/configs/cpuat91_defconfig +++ b/configs/cpuat91_defconfig @@ -1,2 +1,3 @@ CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPUAT91=y diff --git a/configs/cpuat91_ram_defconfig b/configs/cpuat91_ram_defconfig index f5b722dd4c..275919251a 100644 --- a/configs/cpuat91_ram_defconfig +++ b/configs/cpuat91_ram_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_CPUAT91=y diff --git a/configs/eb_cpux9k2_defconfig b/configs/eb_cpux9k2_defconfig index 5f0ab44f45..257fee5901 100644 --- a/configs/eb_cpux9k2_defconfig +++ b/configs/eb_cpux9k2_defconfig @@ -1,2 +1,3 @@ CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_EB_CPUX9K2=y diff --git a/configs/eb_cpux9k2_ram_defconfig b/configs/eb_cpux9k2_ram_defconfig index c6e8b71773..4393ccce26 100644 --- a/configs/eb_cpux9k2_ram_defconfig +++ b/configs/eb_cpux9k2_ram_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_EB_CPUX9K2=y diff --git a/configs/ethernut5_defconfig b/configs/ethernut5_defconfig index 5be495cfa3..9a3d40a80f 100644 --- a/configs/ethernut5_defconfig +++ b/configs/ethernut5_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9XE" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_ETHERNUT5=y diff --git a/configs/meesc_dataflash_defconfig b/configs/meesc_dataflash_defconfig index fa737ef206..0430d58ba2 100644 --- a/configs/meesc_dataflash_defconfig +++ b/configs/meesc_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_MEESC=y diff --git a/configs/meesc_defconfig b/configs/meesc_defconfig index f58efbbe6c..b8a48f8e2b 100644 --- a/configs/meesc_defconfig +++ b/configs/meesc_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_MEESC=y diff --git a/configs/otc570_dataflash_defconfig b/configs/otc570_dataflash_defconfig index 992d6b649c..7aac6d8fcf 100644 --- a/configs/otc570_dataflash_defconfig +++ b/configs/otc570_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_OTC570=y diff --git a/configs/otc570_defconfig b/configs/otc570_defconfig index 65295cb734..5204245798 100644 --- a/configs/otc570_defconfig +++ b/configs/otc570_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_OTC570=y diff --git a/configs/pm9261_defconfig b/configs/pm9261_defconfig index b8a02483c1..0c7efc70ae 100644 --- a/configs/pm9261_defconfig +++ b/configs/pm9261_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9261" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_PM9261=y diff --git a/configs/pm9263_defconfig b/configs/pm9263_defconfig index 3a5029a665..6e88046cc7 100644 --- a/configs/pm9263_defconfig +++ b/configs/pm9263_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_PM9263=y diff --git a/configs/pm9g45_defconfig b/configs/pm9g45_defconfig index 89297e0dbe..112ad5f784 100644 --- a/configs/pm9g45_defconfig +++ b/configs/pm9g45_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G45" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_PM9G45=y diff --git a/configs/portuxg20_defconfig b/configs/portuxg20_defconfig index b1634e9a68..9f3a8e18a5 100644 --- a/configs/portuxg20_defconfig +++ b/configs/portuxg20_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,PORTUXG20" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_STAMP9G20=y diff --git a/configs/sama5d3_xplained_mmc_defconfig b/configs/sama5d3_xplained_mmc_defconfig index a7d791f85c..1d95487b4c 100644 --- a/configs/sama5d3_xplained_mmc_defconfig +++ b/configs/sama5d3_xplained_mmc_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_MMC" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D3_XPLAINED=y diff --git a/configs/sama5d3_xplained_nandflash_defconfig b/configs/sama5d3_xplained_nandflash_defconfig index b97286081e..91dd104cdb 100644 --- a/configs/sama5d3_xplained_nandflash_defconfig +++ b/configs/sama5d3_xplained_nandflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D3_XPLAINED=y diff --git a/configs/sama5d3xek_mmc_defconfig b/configs/sama5d3xek_mmc_defconfig index 3f8d997af5..c03106ca08 100644 --- a/configs/sama5d3xek_mmc_defconfig +++ b/configs/sama5d3xek_mmc_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_MMC" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D3XEK=y diff --git a/configs/sama5d3xek_nandflash_defconfig b/configs/sama5d3xek_nandflash_defconfig index 7a924172fe..54bf79c963 100644 --- a/configs/sama5d3xek_nandflash_defconfig +++ b/configs/sama5d3xek_nandflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D3XEK=y diff --git a/configs/sama5d3xek_spiflash_defconfig b/configs/sama5d3xek_spiflash_defconfig index c83a7ab1fb..07bff18fb4 100644 --- a/configs/sama5d3xek_spiflash_defconfig +++ b/configs/sama5d3xek_spiflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D3,SYS_USE_SERIALFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D3XEK=y diff --git a/configs/sama5d4_xplained_mmc_defconfig b/configs/sama5d4_xplained_mmc_defconfig index 73df28ccff..da5f811f77 100644 --- a/configs/sama5d4_xplained_mmc_defconfig +++ b/configs/sama5d4_xplained_mmc_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_MMC" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/configs/sama5d4_xplained_nandflash_defconfig b/configs/sama5d4_xplained_nandflash_defconfig index 046fe0682e..ea06200509 100644 --- a/configs/sama5d4_xplained_nandflash_defconfig +++ b/configs/sama5d4_xplained_nandflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/configs/sama5d4_xplained_spiflash_defconfig b/configs/sama5d4_xplained_spiflash_defconfig index 755dd8b55f..0408fa4b87 100644 --- a/configs/sama5d4_xplained_spiflash_defconfig +++ b/configs/sama5d4_xplained_spiflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_SERIALFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4_XPLAINED=y diff --git a/configs/sama5d4ek_mmc_defconfig b/configs/sama5d4ek_mmc_defconfig index aafb4c2247..1f66d373c6 100644 --- a/configs/sama5d4ek_mmc_defconfig +++ b/configs/sama5d4ek_mmc_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_MMC" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/configs/sama5d4ek_nandflash_defconfig b/configs/sama5d4ek_nandflash_defconfig index d430fa768f..c623d9b21c 100644 --- a/configs/sama5d4ek_nandflash_defconfig +++ b/configs/sama5d4ek_nandflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_NANDFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/configs/sama5d4ek_spiflash_defconfig b/configs/sama5d4ek_spiflash_defconfig index 796fa4b15a..3b4e124a5c 100644 --- a/configs/sama5d4ek_spiflash_defconfig +++ b/configs/sama5d4ek_spiflash_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="SAMA5D4,SYS_USE_SERIALFLASH" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_SAMA5D4EK=y diff --git a/configs/sbc35_a9g20_eeprom_defconfig b/configs/sbc35_a9g20_eeprom_defconfig index aa9cd3e4a0..cd0909c881 100644 --- a/configs/sbc35_a9g20_eeprom_defconfig +++ b/configs/sbc35_a9g20_eeprom_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_EEPROM" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_SBC35_A9G20=y diff --git a/configs/sbc35_a9g20_nandflash_defconfig b/configs/sbc35_a9g20_nandflash_defconfig index fba9f311c6..017346f38c 100644 --- a/configs/sbc35_a9g20_nandflash_defconfig +++ b/configs/sbc35_a9g20_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_SBC35_A9G20=y diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig index 97c49f3363..3a475053ba 100644 --- a/configs/snapper9260_defconfig +++ b/configs/snapper9260_defconfig @@ -1,5 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_SNAPPER9260=y CONFIG_DM=y CONFIG_DM_GPIO=y diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig index d5f1d9fa19..1f0244b251 100644 --- a/configs/snapper9g20_defconfig +++ b/configs/snapper9g20_defconfig @@ -1,5 +1,6 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_SNAPPER9260=y CONFIG_DM=y CONFIG_DM_GPIO=y diff --git a/configs/stamp9g20_defconfig b/configs/stamp9g20_defconfig index 8c0f874c88..03bf492fcd 100644 --- a/configs/stamp9g20_defconfig +++ b/configs/stamp9g20_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_STAMP9G20=y diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig index 438e25d84f..fac3316421 100644 --- a/configs/taurus_defconfig +++ b/configs/taurus_defconfig @@ -1,4 +1,5 @@ CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,MACH_TYPE=2067,BOARD_TAURUS" +S:CONFIG_ARM=y ++S:CONFIG_ARCH_AT91=y +S:CONFIG_TARGET_TAURUS=y diff --git a/configs/tny_a9260_eeprom_defconfig b/configs/tny_a9260_eeprom_defconfig index a662669d96..28a1d5e517 100644 --- a/configs/tny_a9260_eeprom_defconfig +++ b/configs/tny_a9260_eeprom_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260,SYS_USE_EEPROM" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_TNY_A9260=y diff --git a/configs/tny_a9260_nandflash_defconfig b/configs/tny_a9260_nandflash_defconfig index 41fd9c1192..14710c0b29 100644 --- a/configs/tny_a9260_nandflash_defconfig +++ b/configs/tny_a9260_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_TNY_A9260=y diff --git a/configs/tny_a9g20_eeprom_defconfig b/configs/tny_a9g20_eeprom_defconfig index a2eb60ef71..f4023cc55a 100644 --- a/configs/tny_a9g20_eeprom_defconfig +++ b/configs/tny_a9g20_eeprom_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_EEPROM" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_TNY_A9260=y diff --git a/configs/tny_a9g20_nandflash_defconfig b/configs/tny_a9g20_nandflash_defconfig index 60ebfa2512..2452e1ec31 100644 --- a/configs/tny_a9g20_nandflash_defconfig +++ b/configs/tny_a9g20_nandflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,SYS_USE_NANDFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_TNY_A9260=y diff --git a/configs/usb_a9263_dataflash_defconfig b/configs/usb_a9263_dataflash_defconfig index 8c0ac11ed9..ae2b9a14e7 100644 --- a/configs/usb_a9263_dataflash_defconfig +++ b/configs/usb_a9263_dataflash_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9263,SYS_USE_DATAFLASH" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_USB_A9263=y diff --git a/configs/vl_ma2sc_defconfig b/configs/vl_ma2sc_defconfig index 39cd7258e5..e6478a7dc1 100644 --- a/configs/vl_ma2sc_defconfig +++ b/configs/vl_ma2sc_defconfig @@ -1,2 +1,3 @@ CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_VL_MA2SC=y diff --git a/configs/vl_ma2sc_ram_defconfig b/configs/vl_ma2sc_ram_defconfig index 70a07abe65..fdb262d4c8 100644 --- a/configs/vl_ma2sc_ram_defconfig +++ b/configs/vl_ma2sc_ram_defconfig @@ -1,3 +1,4 @@ CONFIG_SYS_EXTRA_OPTIONS="RAMLOAD" CONFIG_ARM=y +CONFIG_ARCH_AT91=y CONFIG_TARGET_VL_MA2SC=y -- cgit From 01f14456306c84f9bcd3945a10c98ae50e30542a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:02 +0900 Subject: ARM: prepare for moving SoC sources into mach-* In U-boot, the directory structure, arch/$(ARCH)/cpu/$(CPU)/$(SOC)/ has been adopted except that $(CPU) is missing from some architectures and $(SOC) is missing from some CPUs. This structure did not fit very well in some cases. [1] AT91 AT91 SoC family have been developed across some ARM processor generations. Generally speaking, some IPs are often re-used in the same SoC family (same SoC vendor) even when the main processor is updated. As a result, a SoC-common directory is needed in the upper level. Currently, AT91 source files are placed as follows: arch/arm/cpu/arm920t/at91/* arch/arm/cpu/arm926ejs/at91/* arch/arm/cpu/armv7/at91/* arch/arm/cpu/at91-common/* Once directories are split, the motivation for refactorings across CPU directories is lost. Some files in arm920t/at91/ and arm926ejs/at91/ are so similar that they could be merged. [2] Tegra Tegra is a little bit special case where different CPUs are used for SPL and the main U-boot. To obey the arch/$(ARCH)/cpu/$(CPU)/$(SOC) structure, the source files must be placed across the CPUs, again SoC-common directory is necessary in the upper level. Moreover, there are several families in Tegra: Tegra20, Tegra30, Tegra114, Tegra124. Here again, the tegra-common directory is needed to contain commonly-used files. Tegra directories have been sprinkled in the directory structure. arch/arm/cpu/arm720t/tegra20 arch/arm/cpu/arm720t/tegra30 arch/arm/cpu/arm720t/tegra114 arch/arm/cpu/arm720t/tegra124 arch/arm/cpu/arm720t/tegra-common arch/arm/cpu/armv7/tegra20 arch/arm/cpu/armv7/tegra30 arch/arm/cpu/armv7/tegra114 arch/arm/cpu/armv7/tegra124 arch/arm/cpu/armv7/tegra-common arch/arm/cpu/tegra20-common arch/arm/cpu/tegra30-common arch/arm/cpu/tegra114-common arch/arm/cpu/tegra124-common arch/arm/cpu/tegra-common As you see, splitting SoC code by the CPU is not going well, especially for ARM. Why don't we collect SoC-specific files into a single place? A good example we can follow is Linux's arch/arm/mach-* structure. This item was discussed in the following thread: http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/188548/ Looks like I got some positive responses and we are almost ready to start this movement. This commit prepares arch/arm/Makefile for describing machdirs in it. After this commit, we can move SoC directory to arch/arm/mach-$(SOC) in simple steps although some cases such as AT91 and Tegra need more fixes. What we generally have to do is: [1] Move files arch/arm/cpu/$(CPU)/$(SOC)/* to arch/arm/mach-$(SOC)/* [2] Add machine entry into arch/arm/Makefile [3] Remove "obj-y += $(SOC)" from arch/arm/cpu/$(CPU)/Makefile [4] Fix the Kconfig file path in arch/arm/Kconfig [5] Modify MAINTAINERS if necessary Signed-off-by: Masahiro Yamada --- arch/arm/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ebb7dc34ac..5da2c231e9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -2,6 +2,13 @@ # SPDX-License-Identifier: GPL-2.0+ # +# Machine directory name. This list is sorted alphanumerically +# by CONFIG_* macro name. + +machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) + +libs-y += $(machdirs) + head-y := arch/arm/cpu/$(CPU)/start.o ifeq ($(CONFIG_SPL_BUILD),y) @@ -27,3 +34,6 @@ endif ifneq (,$(filter $(SOC), armada-xp kirkwood)) libs-y += arch/arm/mvebu-common/ endif + +# deprecated +-include $(machdirs)/config.mk -- cgit From 620118403e1521b4c883848a84d2fb68e3fa1aa0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:03 +0900 Subject: ARM: at91: collect SoC sources into mach-at91 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit moves source files as follows: arch/arm/cpu/arm920t/at91/* -> arch/arm/mach-at91/arm920t/* arch/arm/cpu/arm926ejs/at91/* -> arch/arm/mach-at91/arm926ejs/* arch/arm/cpu/armv7/at91/* -> arch/arm/mach-at91/armv7/* arch/arm/cpu/at91-common/* -> arch/arm/mach-at91/* Signed-off-by: Masahiro Yamada Acked-by: Andreas Bießmann --- MAINTAINERS | 3 +- arch/arm/Makefile | 1 + arch/arm/cpu/Makefile | 1 - arch/arm/cpu/arm920t/Makefile | 1 - arch/arm/cpu/arm920t/at91/Makefile | 13 -- arch/arm/cpu/arm920t/at91/at91rm9200_devices.c | 67 ------ arch/arm/cpu/arm920t/at91/clock.c | 157 ------------- arch/arm/cpu/arm920t/at91/cpu.c | 26 --- arch/arm/cpu/arm920t/at91/lowlevel_init.S | 152 ------------ arch/arm/cpu/arm920t/at91/reset.c | 41 ---- arch/arm/cpu/arm920t/at91/timer.c | 127 ----------- arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/at91/Makefile | 28 --- arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c | 245 -------------------- arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c | 140 ------------ arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c | 218 ------------------ .../cpu/arm926ejs/at91/at91sam9m10g45_devices.c | 184 --------------- arch/arm/cpu/arm926ejs/at91/at91sam9n12_devices.c | 161 ------------- arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c | 103 --------- arch/arm/cpu/arm926ejs/at91/at91sam9x5_devices.c | 244 -------------------- arch/arm/cpu/arm926ejs/at91/clock.c | 249 -------------------- arch/arm/cpu/arm926ejs/at91/config.mk | 2 - arch/arm/cpu/arm926ejs/at91/cpu.c | 57 ----- arch/arm/cpu/arm926ejs/at91/eflash.c | 254 --------------------- arch/arm/cpu/arm926ejs/at91/led.c | 48 ---- arch/arm/cpu/arm926ejs/at91/lowlevel_init.S | 246 -------------------- arch/arm/cpu/arm926ejs/at91/reset.c | 29 --- arch/arm/cpu/arm926ejs/at91/timer.c | 120 ---------- arch/arm/cpu/armv7/Makefile | 1 - arch/arm/cpu/armv7/at91/Makefile | 16 -- arch/arm/cpu/armv7/at91/clock.c | 175 -------------- arch/arm/cpu/armv7/at91/config.mk | 8 - arch/arm/cpu/armv7/at91/cpu.c | 76 ------ arch/arm/cpu/armv7/at91/reset.c | 31 --- arch/arm/cpu/armv7/at91/sama5d3_devices.c | 218 ------------------ arch/arm/cpu/armv7/at91/sama5d4_devices.c | 93 -------- arch/arm/cpu/armv7/at91/timer.c | 124 ---------- arch/arm/cpu/at91-common/Makefile | 18 -- arch/arm/cpu/at91-common/mpddrc.c | 133 ----------- arch/arm/cpu/at91-common/phy.c | 57 ----- arch/arm/cpu/at91-common/sdram.c | 77 ------- arch/arm/cpu/at91-common/spl.c | 50 ---- arch/arm/cpu/at91-common/spl_at91.c | 124 ---------- arch/arm/cpu/at91-common/spl_atmel.c | 96 -------- arch/arm/cpu/at91-common/u-boot-spl.lds | 55 ----- arch/arm/mach-at91/Makefile | 12 + arch/arm/mach-at91/arm920t/Makefile | 13 ++ arch/arm/mach-at91/arm920t/at91rm9200_devices.c | 67 ++++++ arch/arm/mach-at91/arm920t/clock.c | 157 +++++++++++++ arch/arm/mach-at91/arm920t/cpu.c | 26 +++ arch/arm/mach-at91/arm920t/lowlevel_init.S | 152 ++++++++++++ arch/arm/mach-at91/arm920t/reset.c | 41 ++++ arch/arm/mach-at91/arm920t/timer.c | 127 +++++++++++ arch/arm/mach-at91/arm926ejs/Makefile | 28 +++ arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c | 245 ++++++++++++++++++++ arch/arm/mach-at91/arm926ejs/at91sam9261_devices.c | 140 ++++++++++++ arch/arm/mach-at91/arm926ejs/at91sam9263_devices.c | 218 ++++++++++++++++++ .../mach-at91/arm926ejs/at91sam9m10g45_devices.c | 184 +++++++++++++++ arch/arm/mach-at91/arm926ejs/at91sam9n12_devices.c | 161 +++++++++++++ arch/arm/mach-at91/arm926ejs/at91sam9rl_devices.c | 103 +++++++++ arch/arm/mach-at91/arm926ejs/at91sam9x5_devices.c | 244 ++++++++++++++++++++ arch/arm/mach-at91/arm926ejs/clock.c | 249 ++++++++++++++++++++ arch/arm/mach-at91/arm926ejs/cpu.c | 57 +++++ arch/arm/mach-at91/arm926ejs/eflash.c | 254 +++++++++++++++++++++ arch/arm/mach-at91/arm926ejs/led.c | 48 ++++ arch/arm/mach-at91/arm926ejs/lowlevel_init.S | 246 ++++++++++++++++++++ arch/arm/mach-at91/arm926ejs/reset.c | 29 +++ arch/arm/mach-at91/arm926ejs/timer.c | 120 ++++++++++ arch/arm/mach-at91/armv7/Makefile | 16 ++ arch/arm/mach-at91/armv7/clock.c | 175 ++++++++++++++ arch/arm/mach-at91/armv7/cpu.c | 76 ++++++ arch/arm/mach-at91/armv7/reset.c | 31 +++ arch/arm/mach-at91/armv7/sama5d3_devices.c | 218 ++++++++++++++++++ arch/arm/mach-at91/armv7/sama5d4_devices.c | 93 ++++++++ arch/arm/mach-at91/armv7/timer.c | 124 ++++++++++ arch/arm/mach-at91/config.mk | 9 + arch/arm/mach-at91/mpddrc.c | 133 +++++++++++ arch/arm/mach-at91/phy.c | 57 +++++ arch/arm/mach-at91/sdram.c | 77 +++++++ arch/arm/mach-at91/spl.c | 50 ++++ arch/arm/mach-at91/spl_at91.c | 124 ++++++++++ arch/arm/mach-at91/spl_atmel.c | 96 ++++++++ arch/arm/mach-at91/u-boot-spl.lds | 55 +++++ include/configs/sama5d3_xplained.h | 2 +- include/configs/sama5d3xek.h | 2 +- 85 files changed, 4259 insertions(+), 4270 deletions(-) delete mode 100644 arch/arm/cpu/arm920t/at91/Makefile delete mode 100644 arch/arm/cpu/arm920t/at91/at91rm9200_devices.c delete mode 100644 arch/arm/cpu/arm920t/at91/clock.c delete mode 100644 arch/arm/cpu/arm920t/at91/cpu.c delete mode 100644 arch/arm/cpu/arm920t/at91/lowlevel_init.S delete mode 100644 arch/arm/cpu/arm920t/at91/reset.c delete mode 100644 arch/arm/cpu/arm920t/at91/timer.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9n12_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/at91sam9x5_devices.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/clock.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/config.mk delete mode 100644 arch/arm/cpu/arm926ejs/at91/cpu.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/eflash.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/led.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/lowlevel_init.S delete mode 100644 arch/arm/cpu/arm926ejs/at91/reset.c delete mode 100644 arch/arm/cpu/arm926ejs/at91/timer.c delete mode 100644 arch/arm/cpu/armv7/at91/Makefile delete mode 100644 arch/arm/cpu/armv7/at91/clock.c delete mode 100644 arch/arm/cpu/armv7/at91/config.mk delete mode 100644 arch/arm/cpu/armv7/at91/cpu.c delete mode 100644 arch/arm/cpu/armv7/at91/reset.c delete mode 100644 arch/arm/cpu/armv7/at91/sama5d3_devices.c delete mode 100644 arch/arm/cpu/armv7/at91/sama5d4_devices.c delete mode 100644 arch/arm/cpu/armv7/at91/timer.c delete mode 100644 arch/arm/cpu/at91-common/Makefile delete mode 100644 arch/arm/cpu/at91-common/mpddrc.c delete mode 100644 arch/arm/cpu/at91-common/phy.c delete mode 100644 arch/arm/cpu/at91-common/sdram.c delete mode 100644 arch/arm/cpu/at91-common/spl.c delete mode 100644 arch/arm/cpu/at91-common/spl_at91.c delete mode 100644 arch/arm/cpu/at91-common/spl_atmel.c delete mode 100644 arch/arm/cpu/at91-common/u-boot-spl.lds create mode 100644 arch/arm/mach-at91/Makefile create mode 100644 arch/arm/mach-at91/arm920t/Makefile create mode 100644 arch/arm/mach-at91/arm920t/at91rm9200_devices.c create mode 100644 arch/arm/mach-at91/arm920t/clock.c create mode 100644 arch/arm/mach-at91/arm920t/cpu.c create mode 100644 arch/arm/mach-at91/arm920t/lowlevel_init.S create mode 100644 arch/arm/mach-at91/arm920t/reset.c create mode 100644 arch/arm/mach-at91/arm920t/timer.c create mode 100644 arch/arm/mach-at91/arm926ejs/Makefile create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9261_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9263_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9n12_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9rl_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/at91sam9x5_devices.c create mode 100644 arch/arm/mach-at91/arm926ejs/clock.c create mode 100644 arch/arm/mach-at91/arm926ejs/cpu.c create mode 100644 arch/arm/mach-at91/arm926ejs/eflash.c create mode 100644 arch/arm/mach-at91/arm926ejs/led.c create mode 100644 arch/arm/mach-at91/arm926ejs/lowlevel_init.S create mode 100644 arch/arm/mach-at91/arm926ejs/reset.c create mode 100644 arch/arm/mach-at91/arm926ejs/timer.c create mode 100644 arch/arm/mach-at91/armv7/Makefile create mode 100644 arch/arm/mach-at91/armv7/clock.c create mode 100644 arch/arm/mach-at91/armv7/cpu.c create mode 100644 arch/arm/mach-at91/armv7/reset.c create mode 100644 arch/arm/mach-at91/armv7/sama5d3_devices.c create mode 100644 arch/arm/mach-at91/armv7/sama5d4_devices.c create mode 100644 arch/arm/mach-at91/armv7/timer.c create mode 100644 arch/arm/mach-at91/config.mk create mode 100644 arch/arm/mach-at91/mpddrc.c create mode 100644 arch/arm/mach-at91/phy.c create mode 100644 arch/arm/mach-at91/sdram.c create mode 100644 arch/arm/mach-at91/spl.c create mode 100644 arch/arm/mach-at91/spl_at91.c create mode 100644 arch/arm/mach-at91/spl_atmel.c create mode 100644 arch/arm/mach-at91/u-boot-spl.lds diff --git a/MAINTAINERS b/MAINTAINERS index 74a56ecf4f..a558bd4fcb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -76,8 +76,7 @@ ARM ATMEL AT91 M: Andreas Bießmann S: Maintained T: git git://git.denx.de/u-boot-atmel.git -F: arch/arm/cpu/armv7/at91/ -F: arch/arm/cpu/at91-common/ +F: arch/arm/mach-at91/ F: arch/arm/include/asm/arch-at91/ ARM FREESCALE IMX diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 5da2c231e9..f4e9af6598 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -4,6 +4,7 @@ # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_AT91) += at91 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 35d8d387bd..ba4f3900f7 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_AT91FAMILY) += at91-common/ obj-$(CONFIG_TEGRA20) += tegra20-common/ obj-$(CONFIG_TEGRA30) += tegra30-common/ obj-$(CONFIG_TEGRA114) += tegra114-common/ diff --git a/arch/arm/cpu/arm920t/Makefile b/arch/arm/cpu/arm920t/Makefile index a72e5de99e..a16838b479 100644 --- a/arch/arm/cpu/arm920t/Makefile +++ b/arch/arm/cpu/arm920t/Makefile @@ -11,7 +11,6 @@ obj-y += cpu.o obj-$(CONFIG_USE_IRQ) += interrupts.o obj-$(if $(filter a320,$(SOC)),y) += a320/ -obj-$(CONFIG_AT91FAMILY) += at91/ obj-$(CONFIG_EP93XX) += ep93xx/ obj-$(CONFIG_IMX) += imx/ obj-$(CONFIG_KS8695) += ks8695/ diff --git a/arch/arm/cpu/arm920t/at91/Makefile b/arch/arm/cpu/arm920t/at91/Makefile deleted file mode 100644 index 561b4b4cbb..0000000000 --- a/arch/arm/cpu/arm920t/at91/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += lowlevel_init.o -obj-y += reset.o -obj-y += timer.o -obj-y += clock.o -obj-y += cpu.o -obj-y += at91rm9200_devices.o diff --git a/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c b/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c deleted file mode 100644 index fc54327c0d..0000000000 --- a/arch/arm/cpu/arm920t/at91/at91rm9200_devices.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * [partely copied from arch/arm/cpu/arm926ejs/at91/arm9260_devices.c] - * - * (C) Copyright 2011 - * Andreas Bießmann - * - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 17, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 18, PUP); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 20, PUP); /* RXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 21, 1); /* TXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 22, PUP); /* RXD2 */ - at91_set_a_periph(AT91_PIO_PORTA, 23, 1); /* TXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTA, 30, PUP); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 31, 1); /* DTXD */ - /* writing SYS to PCER has no effect on AT91RM9200 */ -} diff --git a/arch/arm/cpu/arm920t/at91/clock.c b/arch/arm/cpu/arm920t/at91/clock.c deleted file mode 100644 index 2813bf7821..0000000000 --- a/arch/arm/cpu/arm920t/at91/clock.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] - * - * Copyright (C) 2011 Andreas Bießmann - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include - -#if !defined(CONFIG_AT91FAMILY) -# error You need to define CONFIG_AT91FAMILY in your board config! -#endif - -DECLARE_GLOBAL_DATA_PTR; - -static unsigned long at91_css_to_rate(unsigned long css) -{ - switch (css) { - case AT91_PMC_MCKR_CSS_SLOW: - return CONFIG_SYS_AT91_SLOW_CLOCK; - case AT91_PMC_MCKR_CSS_MAIN: - return gd->arch.main_clk_rate_hz; - case AT91_PMC_MCKR_CSS_PLLA: - return gd->arch.plla_rate_hz; - case AT91_PMC_MCKR_CSS_PLLB: - return gd->arch.pllb_rate_hz; - } - - return 0; -} - -#ifdef CONFIG_USB_ATMEL -static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) -{ - unsigned i, div = 0, mul = 0, diff = 1 << 30; - unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; - - /* PLL output max 240 MHz (or 180 MHz per errata) */ - if (out_freq > 240000000) - goto fail; - - for (i = 1; i < 256; i++) { - int diff1; - unsigned input, mul1; - - /* - * PLL input between 1MHz and 32MHz per spec, but lower - * frequences seem necessary in some cases so allow 100K. - * Warning: some newer products need 2MHz min. - */ - input = main_freq / i; - if (input < 100000) - continue; - if (input > 32000000) - continue; - - mul1 = out_freq / input; - if (mul1 > 2048) - continue; - if (mul1 < 2) - goto fail; - - diff1 = out_freq - input * mul1; - if (diff1 < 0) - diff1 = -diff1; - if (diff > diff1) { - diff = diff1; - div = i; - mul = mul1; - if (diff == 0) - break; - } - } - if (i == 256 && diff > (out_freq >> 5)) - goto fail; - return ret | ((mul - 1) << 16) | div; -fail: - return 0; -} -#endif - -static u32 at91_pll_rate(u32 freq, u32 reg) -{ - unsigned mul, div; - - div = reg & 0xff; - mul = (reg >> 16) & 0x7ff; - if (div && mul) { - freq /= div; - freq *= mul + 1; - } else - freq = 0; - - return freq; -} - -int at91_clock_init(unsigned long main_clock) -{ - unsigned freq, mckr; - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK - unsigned tmp; - /* - * When the bootloader initialized the main oscillator correctly, - * there's no problem using the cycle counter. But if it didn't, - * or when using oscillator bypass mode, we must be told the speed - * of the main clock. - */ - if (!main_clock) { - do { - tmp = readl(&pmc->mcfr); - } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); - tmp &= AT91_PMC_MCFR_MAINF_MASK; - main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); - } -#endif - gd->arch.main_clk_rate_hz = main_clock; - - /* report if PLLA is more than mildly overclocked */ - gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); - -#ifdef CONFIG_USB_ATMEL - /* - * USB clock init: choose 48 MHz PLLB value, - * disable 48MHz clock during usb peripheral suspend. - * - * REVISIT: assumes MCK doesn't derive from PLLB! - */ - gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | - AT91_PMC_PLLBR_USBDIV_2; - gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, - gd->arch.at91_pllb_usb_init); -#endif - - /* - * MCK and CPU derive from one of those primary clocks. - * For now, assume this parentage won't change. - */ - mckr = readl(&pmc->mckr); - gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = gd->arch.mck_rate_hz; - - freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ - /* mdiv */ - gd->arch.mck_rate_hz = freq / - (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); - gd->arch.cpu_clk_rate_hz = freq; - - return 0; -} diff --git a/arch/arm/cpu/arm920t/at91/cpu.c b/arch/arm/cpu/arm920t/at91/cpu.c deleted file mode 100644 index b0f411b1c3..0000000000 --- a/arch/arm/cpu/arm920t/at91/cpu.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * [origin: arch/arm/cpu/arm926ejs/at91/cpu.c] - * - * (C) Copyright 2011 - * Andreas Bießmann, andreas.devel@googlemail.com - * (C) Copyright 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * (C) Copyright 2009 - * Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK -#define CONFIG_SYS_AT91_MAIN_CLOCK 0 -#endif - -int arch_cpu_init(void) -{ - return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); -} diff --git a/arch/arm/cpu/arm920t/at91/lowlevel_init.S b/arch/arm/cpu/arm920t/at91/lowlevel_init.S deleted file mode 100644 index d2934a3525..0000000000 --- a/arch/arm/cpu/arm920t/at91/lowlevel_init.S +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Modified for the at91rm9200dk board by - * (C) Copyright 2004 - * Gary Jennejohn, DENX Software Engineering, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#ifndef CONFIG_SKIP_LOWLEVEL_INIT - -#include -#include -#include -#include - -#define ARM920T_CONTROL 0xC0000000 /* @ set bit 31 (iA) and 30 (nF) */ - -_MTEXT_BASE: -#undef START_FROM_MEM -#ifdef START_FROM_MEM - .word CONFIG_SYS_TEXT_BASE-PHYS_FLASH_1 -#else - .word CONFIG_SYS_TEXT_BASE -#endif - -.globl lowlevel_init -lowlevel_init: - ldr r1, =AT91_ASM_PMC_MOR - /* Main oscillator Enable register */ -#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR - ldr r0, =0x0000FF01 /* Enable main oscillator */ -#else - ldr r0, =0x0000FF00 /* Disable main oscillator */ -#endif - str r0, [r1] /*AT91C_CKGR_MOR] */ - /* Add loop to compensate Main Oscillator startup time */ - ldr r0, =0x00000010 -LoopOsc: - subs r0, r0, #1 - bhi LoopOsc - - /* memory control configuration */ - /* this isn't very elegant, but what the heck */ - ldr r0, =SMRDATA - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - ldr r2, =SMRDATAE - sub r2, r2, r1 -pllloop: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne pllloop - /* delay - this is all done by guess */ - ldr r0, =0x00010000 - /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ -lock: - subs r0, r0, #1 - bhi lock - ldr r0, =SMRDATA1 - ldr r1, _MTEXT_BASE - sub r0, r0, r1 - ldr r2, =SMRDATA1E - sub r2, r2, r1 -sdinit: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne sdinit - - /* switch from FastBus to Asynchronous clock mode */ - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #ARM920T_CONTROL - mcr p15, 0, r0, c1, c0, 0 - - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word AT91_ASM_MC_EBI_CFG - .word CONFIG_SYS_EBI_CFGR_VAL - .word AT91_ASM_MC_SMC_CSR0 - .word CONFIG_SYS_SMC_CSR0_VAL - .word AT91_ASM_PMC_PLLAR - .word CONFIG_SYS_PLLAR_VAL - .word AT91_ASM_PMC_PLLBR - .word CONFIG_SYS_PLLBR_VAL - .word AT91_ASM_PMC_MCKR - .word CONFIG_SYS_MCKR_VAL -SMRDATAE: - /* here there's a delay */ -SMRDATA1: - .word AT91_ASM_PIOC_ASR - .word CONFIG_SYS_PIOC_ASR_VAL - .word AT91_ASM_PIOC_BSR - .word CONFIG_SYS_PIOC_BSR_VAL - .word AT91_ASM_PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL - .word AT91_ASM_MC_EBI_CSA - .word CONFIG_SYS_EBI_CSA_VAL - .word AT91_ASM_MC_SDRAMC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word CONFIG_SYS_SDRAM1 - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word AT91_ASM_MC_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL -SMRDATA1E: - /* SMRDATA1 is 176 bytes long */ -#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/arch/arm/cpu/arm920t/at91/reset.c b/arch/arm/cpu/arm920t/at91/reset.c deleted file mode 100644 index d47777a367..0000000000 --- a/arch/arm/cpu/arm920t/at91/reset.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -void __attribute__((weak)) board_reset(void) -{ - /* true empty function for defining weak symbol */ -} - -void reset_cpu(ulong ignored) -{ - at91_st_t *st = (at91_st_t *) ATMEL_BASE_ST; - - board_reset(); - - /* Reset the cpu by setting up the watchdog timer */ - writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2), - &st->wdmr); - writel(AT91_ST_CR_WDRST, &st->cr); - /* and let it timeout */ - while (1) - ; - /* Never reached */ -} diff --git a/arch/arm/cpu/arm920t/at91/timer.c b/arch/arm/cpu/arm920t/at91/timer.c deleted file mode 100644 index 6aa2994723..0000000000 --- a/arch/arm/cpu/arm920t/at91/timer.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* the number of clocks per CONFIG_SYS_HZ */ -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) - -int timer_init(void) -{ - at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - /* enables TC1.0 clock */ - writel(1 << ATMEL_ID_TC0, &pmc->pcer); /* enable clock */ - - writel(0, &tc->bcr); - writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | - AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); - - writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); - /* set to MCLK/2 and restart the timer - when the value in TC_RC is reached */ - writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); - - writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */ - writel(TIMER_LOAD_VAL, &tc->tc[0].rc); - - writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); - gd->arch.lastinc = 0; - gd->arch.tbl = 0; - - return 0; -} - -/* - * timer without interrupts - */ -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void __udelay(unsigned long usec) -{ - udelay_masked(usec); -} - -ulong get_timer_raw(void) -{ - at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; - u32 now; - - now = readl(&tc->tc[0].cv) & 0x0000ffff; - - if (now >= gd->arch.lastinc) { - /* normal mode */ - gd->arch.tbl += now - gd->arch.lastinc; - } else { - /* we have an overflow ... */ - gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc; - } - gd->arch.lastinc = now; - - return gd->arch.tbl; -} - -ulong get_timer_masked(void) -{ - return get_timer_raw()/TIMER_LOAD_VAL; -} - -void udelay_masked(unsigned long usec) -{ - u32 tmo; - u32 endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= 1000; - - endtime = get_timer_raw() + tmo; - - do { - u32 now = get_timer_raw(); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index adcea9f683..f41357aaeb 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -15,7 +15,6 @@ endif endif obj-$(CONFIG_ARMADA100) += armada100/ -obj-$(CONFIG_AT91FAMILY) += at91/ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_KIRKWOOD) += kirkwood/ obj-$(if $(filter lpc32xx,$(SOC)),y) += lpc32xx/ diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile deleted file mode 100644 index ddc323f641..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o -obj-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o -obj-$(CONFIG_AT91SAM9XE) += at91sam9260_devices.o -obj-$(CONFIG_AT91SAM9261) += at91sam9261_devices.o -obj-$(CONFIG_AT91SAM9G10) += at91sam9261_devices.o -obj-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o -obj-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o -obj-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o -obj-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o -obj-$(CONFIG_AT91SAM9N12) += at91sam9n12_devices.o -obj-$(CONFIG_AT91SAM9X5) += at91sam9x5_devices.o -obj-$(CONFIG_AT91_EFLASH) += eflash.o -obj-$(CONFIG_AT91_LED) += led.o -obj-y += clock.o -obj-y += cpu.o -obj-y += reset.o -obj-y += timer.o - -ifndef CONFIG_SKIP_LOWLEVEL_INIT -obj-y += lowlevel_init.o -endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c deleted file mode 100644 index efb53d673f..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 7, PUP); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTB, 9, PUP); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTC, 11, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTC, 16, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTC, 17, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTC, 11, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTC, 16, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTC, 17, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTC, 5, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTC, 4, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTC, 3, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTC, 5, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTC, 4, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTC, 3, 1); - } -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - /* Enable EMAC clock */ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - writel(1 << ATMEL_ID_EMAC0, &pmc->pcer); - - at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTA, 25, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 26, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ERXCK */ -#if defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AFEB9260) - /* - * use PA10, PA11 for ETX2, ETX3. - * PA23 and PA24 are for TWI EEPROM - */ - at91_set_b_periph(AT91_PIO_PORTA, 10, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 11, 0); /* ETX3 */ -#else - at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 24, 0); /* ETX3 */ -#if defined(CONFIG_AT91SAM9G20) - /* 9G20 BOOT ROM initializes those pins to multi-drive, undo that */ - at91_set_pio_multi_drive(AT91_PIO_PORTA, 23, 0); - at91_set_pio_multi_drive(AT91_PIO_PORTA, 24, 0); -#endif -#endif - at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* ETXER */ -#endif -} -#endif - -#if defined(CONFIG_GENERIC_ATMEL_MCI) -void at91_mci_hw_init(void) -{ - /* Enable mci clock */ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - writel(1 << ATMEL_ID_MCI, &pmc->pcer); - - at91_set_a_periph(AT91_PIO_PORTA, 8, 1); /* MCCK */ -#if defined(CONFIG_ATMEL_MCI_PORTB) - at91_set_b_periph(AT91_PIO_PORTA, 1, 1); /* MCCDB */ - at91_set_b_periph(AT91_PIO_PORTA, 0, 1); /* MCDB0 */ - at91_set_b_periph(AT91_PIO_PORTA, 5, 1); /* MCDB1 */ - at91_set_b_periph(AT91_PIO_PORTA, 4, 1); /* MCDB2 */ - at91_set_b_periph(AT91_PIO_PORTA, 3, 1); /* MCDB3 */ -#else - at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* MCCDA */ - at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* MCDA0 */ - at91_set_a_periph(AT91_PIO_PORTA, 9, 1); /* MCDA1 */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* MCDA2 */ - at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* MCDA3 */ -#endif -} -#endif - -void at91_sdram_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTC, 16, 0); - at91_set_a_periph(AT91_PIO_PORTC, 17, 0); - at91_set_a_periph(AT91_PIO_PORTC, 18, 0); - at91_set_a_periph(AT91_PIO_PORTC, 19, 0); - at91_set_a_periph(AT91_PIO_PORTC, 20, 0); - at91_set_a_periph(AT91_PIO_PORTC, 21, 0); - at91_set_a_periph(AT91_PIO_PORTC, 22, 0); - at91_set_a_periph(AT91_PIO_PORTC, 23, 0); - at91_set_a_periph(AT91_PIO_PORTC, 24, 0); - at91_set_a_periph(AT91_PIO_PORTC, 25, 0); - at91_set_a_periph(AT91_PIO_PORTC, 26, 0); - at91_set_a_periph(AT91_PIO_PORTC, 27, 0); - at91_set_a_periph(AT91_PIO_PORTC, 28, 0); - at91_set_a_periph(AT91_PIO_PORTC, 29, 0); - at91_set_a_periph(AT91_PIO_PORTC, 30, 0); - at91_set_a_periph(AT91_PIO_PORTC, 31, 0); -} - -/* Platform data for the GPIOs */ -static const struct at91_port_platdata at91sam9260_plat[] = { - { ATMEL_BASE_PIOA, "PA" }, - { ATMEL_BASE_PIOB, "PB" }, - { ATMEL_BASE_PIOC, "PC" }, -}; - -U_BOOT_DEVICES(at91sam9260_gpios) = { - { "gpio_at91", &at91sam9260_plat[0] }, - { "gpio_at91", &at91sam9260_plat[1] }, - { "gpio_at91", &at91sam9260_plat[2] }, -}; diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c deleted file mode 100644 index a445c7507e..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9261_devices.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTC, 8, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTC, 12, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTC, 14, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTA, 6, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTA, 6, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 30, PUP); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 31, PUP); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 29, PUP); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 28, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 24, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTA, 25, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTA, 26, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 28, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 24, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 25, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTA, 26, 1); - } -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c deleted file mode 100644 index 6b51d5f355..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9263_devices.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2009-2011 - * Daniel Gorsulowski - * esd electronic system design gmbh - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 26, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 27, PUP); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTD, 1, PUP); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 3, PUP); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTC, 30, PUP); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_b_periph(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTB, 11, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 5, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTA, 3, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTA, 4, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 11, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 12, PUP); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 13, PUP); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_a_periph(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 15, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 16, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 1); - } -} -#endif - -#if defined(CONFIG_GENERIC_ATMEL_MCI) -void at91_mci_hw_init(void) -{ - /* Enable mci clock */ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - writel(1 << ATMEL_ID_MCI1, &pmc->pcer); - - at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCI1_CK */ - -#if defined(CONFIG_ATMEL_MCI_PORTB) - at91_set_a_periph(AT91_PIO_PORTA, 21, PUP); /* MCI1_CDB */ - at91_set_a_periph(AT91_PIO_PORTA, 22, PUP); /* MCI1_DB0 */ - at91_set_a_periph(AT91_PIO_PORTA, 23, PUP); /* MCI1_DB1 */ - at91_set_a_periph(AT91_PIO_PORTA, 24, PUP); /* MCI1_DB2 */ - at91_set_a_periph(AT91_PIO_PORTA, 25, PUP); /* MCI1_DB3 */ -#else - at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCI1_CDA */ - at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCI1_DA0 */ - at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCI1_DA1 */ - at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCI1_DA2 */ - at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCI1_DA3 */ -#endif -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTE, 21, 0); /* ETXCK_EREFCK */ - at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTE, 25, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTE, 26, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTE, 27, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTE, 28, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTE, 23, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTE, 24, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTE, 30, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTE, 29, 0); /* EMDC */ - -#ifndef CONFIG_RMII - at91_set_a_periph(AT91_PIO_PORTE, 22, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ -#endif -} -#endif - -#ifdef CONFIG_USB_OHCI_NEW -void at91_uhp_hw_init(void) -{ - /* Enable VBus on UHP ports */ - at91_set_pio_output(AT91_PIO_PORTA, 21, 0); - at91_set_pio_output(AT91_PIO_PORTA, 24, 0); -} -#endif - -#ifdef CONFIG_AT91_CAN -void at91_can_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* CAN_TX */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 1); /* CAN_RX */ - - /* Enable clock */ - writel(1 << ATMEL_ID_CAN, &pmc->pcer); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c deleted file mode 100644 index 0e6c0da1bd..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9m10g45_devices.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 19, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTB, 18, PUP); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTD, 6, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTD, 7, PUP); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 1); /* DTXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_b_periph(AT91_PIO_PORTB, 19, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 27, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 3, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 18, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTB, 19, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 27, 1); - } -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* SPI1_MISO */ - at91_set_a_periph(AT91_PIO_PORTB, 15, PUP); /* SPI1_MOSI */ - at91_set_a_periph(AT91_PIO_PORTB, 16, PUP); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTD, 28, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTD, 18, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_a_periph(AT91_PIO_PORTD, 19, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTB, 17, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTD, 28, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 18, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 19, 1); - } - -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* EMDC */ -#ifndef CONFIG_RMII - at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECRS */ - at91_set_b_periph(AT91_PIO_PORTA, 30, 0); /* ECOL */ - at91_set_b_periph(AT91_PIO_PORTA, 8, 0); /* ERX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 9, 0); /* ERX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ERXCK */ - at91_set_b_periph(AT91_PIO_PORTA, 6, 0); /* ETX2 */ - at91_set_b_periph(AT91_PIO_PORTA, 7, 0); /* ETX3 */ - at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ETXER */ -#endif -} -#endif - -#ifdef CONFIG_GENERIC_ATMEL_MCI -void at91_mci_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* MCI0 CLK */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* MCI0 CDA */ - at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* MCI0 DA0 */ - at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* MCI0 DA1 */ - at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* MCI0 DA2 */ - at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* MCI0 DA3 */ - - /* Enable clock */ - writel(1 << ATMEL_ID_MCI0, &pmc->pcer); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9n12_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9n12_devices.c deleted file mode 100644 index 39f17a1e11..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9n12_devices.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * (C) Copyright 2013 Atmel Corporation - * Josh Wu - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -unsigned int has_lcdc() -{ - return 1; -} - -void at91_serial0_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 0, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 5, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_serial3_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_b_periph(AT91_PIO_PORTC, 22, 1); /* TXD3 */ - at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* RXD3 */ - writel(1 << ATMEL_ID_USART3, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ - at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#ifdef CONFIG_ATMEL_SPI -void at91_spi0_hw_init(unsigned long cs_mask) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) - at91_set_pio_output(AT91_PIO_PORTA, 14, 1); - if (cs_mask & (1 << 1)) - at91_set_pio_output(AT91_PIO_PORTA, 7, 1); - if (cs_mask & (1 << 2)) - at91_set_pio_output(AT91_PIO_PORTA, 1, 1); - if (cs_mask & (1 << 3)) - at91_set_pio_output(AT91_PIO_PORTB, 3, 1); -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_b_periph(AT91_PIO_PORTA, 21, 0); /* SPI1_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* SPI1_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) - at91_set_pio_output(AT91_PIO_PORTA, 8, 1); - if (cs_mask & (1 << 1)) - at91_set_pio_output(AT91_PIO_PORTA, 0, 1); - if (cs_mask & (1 << 2)) - at91_set_pio_output(AT91_PIO_PORTA, 31, 1); - if (cs_mask & (1 << 3)) - at91_set_pio_output(AT91_PIO_PORTA, 30, 1); -} -#endif - -void at91_mci_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* MCCK */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* MCCDA */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* MCDA0 */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* MCDA1 */ - at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* MCDA2 */ - at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* MCDA3 */ - - writel(1 << ATMEL_ID_HSMCI0, &pmc->pcer); -} - -#ifdef CONFIG_LCD -void at91_lcd_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTC, 24, 0); /* LCDDPWR */ - at91_set_a_periph(AT91_PIO_PORTC, 26, 0); /* LCDVSYNC */ - at91_set_a_periph(AT91_PIO_PORTC, 27, 0); /* LCDHSYNC */ - at91_set_a_periph(AT91_PIO_PORTC, 28, 0); /* LCDDOTCK */ - at91_set_a_periph(AT91_PIO_PORTC, 29, 0); /* LCDDEN */ - at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* LCDDOTCK */ - - at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* LCDD0 */ - at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* LCDD1 */ - at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* LCDD2 */ - at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* LCDD3 */ - at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* LCDD4 */ - at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* LCDD5 */ - at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* LCDD6 */ - at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* LCDD7 */ - at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* LCDD8 */ - at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* LCDD9 */ - at91_set_a_periph(AT91_PIO_PORTC, 10, 0); /* LCDD10 */ - at91_set_a_periph(AT91_PIO_PORTC, 11, 0); /* LCDD11 */ - at91_set_a_periph(AT91_PIO_PORTC, 12, 0); /* LCDD12 */ - at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* LCDD13 */ - at91_set_a_periph(AT91_PIO_PORTC, 14, 0); /* LCDD14 */ - at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* LCDD15 */ - at91_set_a_periph(AT91_PIO_PORTC, 16, 0); /* LCDD16 */ - at91_set_a_periph(AT91_PIO_PORTC, 17, 0); /* LCDD17 */ - at91_set_a_periph(AT91_PIO_PORTC, 18, 0); /* LCDD18 */ - at91_set_a_periph(AT91_PIO_PORTC, 19, 0); /* LCDD19 */ - at91_set_a_periph(AT91_PIO_PORTC, 20, 0); /* LCDD20 */ - at91_set_a_periph(AT91_PIO_PORTC, 21, 0); /* LCDD21 */ - at91_set_a_periph(AT91_PIO_PORTC, 22, 0); /* LCDD22 */ - at91_set_a_periph(AT91_PIO_PORTC, 23, 0); /* LCDD23 */ - - writel(1 << ATMEL_ID_LCDC, &pmc->pcer); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c deleted file mode 100644 index 0ec32c3ab9..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9rl_devices.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -/* - * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all - * peripheral pins. Good to have if hardware is soldered optionally - * or in case of SPI no slave is selected. Avoid lines to float - * needlessly. Use a short local PUP define. - * - * Due to errata "TXD floats when CTS is inactive" pullups are always - * on for TXD pins. - */ -#ifdef CONFIG_AT91_GPIO_PULLUP -# define PUP CONFIG_AT91_GPIO_PULLUP -#else -# define PUP 0 -#endif - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* RXD0 */ - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTA, 12, PUP); /* RXD1 */ - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* TXD2 */ - at91_set_a_periph(AT91_PIO_PORTA, 14, PUP); /* RXD2 */ - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 21, PUP); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* DTXD */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 25, PUP); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 26, PUP); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 27, PUP); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI, &pmc->pcer); - - if (cs_mask & (1 << 0)) { - at91_set_a_periph(AT91_PIO_PORTA, 28, 1); - } - if (cs_mask & (1 << 1)) { - at91_set_b_periph(AT91_PIO_PORTB, 7, 1); - } - if (cs_mask & (1 << 2)) { - at91_set_a_periph(AT91_PIO_PORTD, 8, 1); - } - if (cs_mask & (1 << 3)) { - at91_set_b_periph(AT91_PIO_PORTD, 9, 1); - } - if (cs_mask & (1 << 4)) { - at91_set_pio_output(AT91_PIO_PORTA, 28, 1); - } - if (cs_mask & (1 << 5)) { - at91_set_pio_output(AT91_PIO_PORTB, 7, 1); - } - if (cs_mask & (1 << 6)) { - at91_set_pio_output(AT91_PIO_PORTD, 8, 1); - } - if (cs_mask & (1 << 7)) { - at91_set_pio_output(AT91_PIO_PORTD, 9, 1); - } -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9x5_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9x5_devices.c deleted file mode 100644 index 6d94572237..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/at91sam9x5_devices.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2012 Atmel Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -unsigned int get_chip_id(void) -{ - /* The 0x40 is the offset of cidr in DBGU */ - return readl(ATMEL_BASE_DBGU + 0x40) & ~ARCH_ID_VERSION_MASK; -} - -unsigned int get_extension_chip_id(void) -{ - /* The 0x44 is the offset of exid in DBGU */ - return readl(ATMEL_BASE_DBGU + 0x44); -} - -unsigned int has_emac1() -{ - return cpu_is_at91sam9x25(); -} - -unsigned int has_emac0() -{ - return !(cpu_is_at91sam9g15()); -} - -unsigned int has_lcdc() -{ - return cpu_is_at91sam9g15() || cpu_is_at91sam9g35() - || cpu_is_at91sam9x35(); -} - -char *get_cpu_name() -{ - unsigned int extension_id = get_extension_chip_id(); - - if (cpu_is_at91sam9x5()) { - switch (extension_id) { - case ARCH_EXID_AT91SAM9G15: - return "AT91SAM9G15"; - case ARCH_EXID_AT91SAM9G25: - return "AT91SAM9G25"; - case ARCH_EXID_AT91SAM9G35: - return "AT91SAM9G35"; - case ARCH_EXID_AT91SAM9X25: - return "AT91SAM9X25"; - case ARCH_EXID_AT91SAM9X35: - return "AT91SAM9X35"; - default: - return "Unknown CPU type"; - } - } else { - return "Unknown CPU type"; - } -} - -void at91_seriald_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ - - writel(1 << ATMEL_ID_SYS, &pmc->pcer); -} - -void at91_serial0_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 0, 1); /* TXD */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* RXD */ - - writel(1 << ATMEL_ID_USART0, &pmc->pcer); -} - -void at91_serial1_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 5, 1); /* TXD */ - at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* RXD */ - - writel(1 << ATMEL_ID_USART1, &pmc->pcer); -} - -void at91_serial2_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* TXD */ - at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* RXD */ - - writel(1 << ATMEL_ID_USART2, &pmc->pcer); -} - -void at91_mci_hw_init(void) -{ - /* Initialize the MCI0 */ - at91_set_a_periph(AT91_PIO_PORTA, 17, 1); /* MCCK */ - at91_set_a_periph(AT91_PIO_PORTA, 16, 1); /* MCCDA */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 1); /* MCDA0 */ - at91_set_a_periph(AT91_PIO_PORTA, 18, 1); /* MCDA1 */ - at91_set_a_periph(AT91_PIO_PORTA, 19, 1); /* MCDA2 */ - at91_set_a_periph(AT91_PIO_PORTA, 20, 1); /* MCDA3 */ - - /* Enable clock for MCI0 */ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - writel(1 << ATMEL_ID_HSMCI0, &pmc->pcer); -} - -#ifdef CONFIG_ATMEL_SPI -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* SPI0_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI0, &pmc->pcer); - - if (cs_mask & (1 << 0)) - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); - if (cs_mask & (1 << 1)) - at91_set_b_periph(AT91_PIO_PORTA, 7, 0); - if (cs_mask & (1 << 2)) - at91_set_b_periph(AT91_PIO_PORTA, 1, 0); - if (cs_mask & (1 << 3)) - at91_set_b_periph(AT91_PIO_PORTB, 3, 0); - if (cs_mask & (1 << 4)) - at91_set_pio_output(AT91_PIO_PORTA, 14, 0); - if (cs_mask & (1 << 5)) - at91_set_pio_output(AT91_PIO_PORTA, 7, 0); - if (cs_mask & (1 << 6)) - at91_set_pio_output(AT91_PIO_PORTA, 1, 0); - if (cs_mask & (1 << 7)) - at91_set_pio_output(AT91_PIO_PORTB, 3, 0); -} - -void at91_spi1_hw_init(unsigned long cs_mask) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - at91_set_b_periph(AT91_PIO_PORTA, 21, 0); /* SPI1_MISO */ - at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* SPI1_MOSI */ - at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* SPI1_SPCK */ - - /* Enable clock */ - writel(1 << ATMEL_ID_SPI1, &pmc->pcer); - - if (cs_mask & (1 << 0)) - at91_set_b_periph(AT91_PIO_PORTA, 8, 0); - if (cs_mask & (1 << 1)) - at91_set_b_periph(AT91_PIO_PORTA, 0, 0); - if (cs_mask & (1 << 2)) - at91_set_b_periph(AT91_PIO_PORTA, 31, 0); - if (cs_mask & (1 << 3)) - at91_set_b_periph(AT91_PIO_PORTA, 30, 0); - if (cs_mask & (1 << 4)) - at91_set_pio_output(AT91_PIO_PORTA, 8, 0); - if (cs_mask & (1 << 5)) - at91_set_pio_output(AT91_PIO_PORTA, 0, 0); - if (cs_mask & (1 << 6)) - at91_set_pio_output(AT91_PIO_PORTA, 31, 0); - if (cs_mask & (1 << 7)) - at91_set_pio_output(AT91_PIO_PORTA, 30, 0); -} -#endif - -#if defined(CONFIG_USB_OHCI_NEW) || defined(CONFIG_USB_EHCI) -void at91_uhp_hw_init(void) -{ - /* Enable VBus on UHP ports */ - at91_set_pio_output(AT91_PIO_PORTD, 18, 0); /* port A */ - at91_set_pio_output(AT91_PIO_PORTD, 19, 0); /* port B */ -#if defined(CONFIG_USB_OHCI_NEW) - /* port C is OHCI only */ - at91_set_pio_output(AT91_PIO_PORTD, 20, 0); /* port C */ -#endif -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - if (has_emac0()) { - /* Enable EMAC0 clock */ - writel(1 << ATMEL_ID_EMAC0, &pmc->pcer); - /* EMAC0 pins setup */ - at91_set_a_periph(AT91_PIO_PORTB, 4, 0); /* ETXCK */ - at91_set_a_periph(AT91_PIO_PORTB, 3, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 10, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTB, 6, 0); /* EMDC */ - } - - if (has_emac1()) { - /* Enable EMAC1 clock */ - writel(1 << ATMEL_ID_EMAC1, &pmc->pcer); - /* EMAC1 pins setup */ - at91_set_b_periph(AT91_PIO_PORTC, 29, 0); /* ETXCK */ - at91_set_b_periph(AT91_PIO_PORTC, 28, 0); /* ECRSDV */ - at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ERXO */ - at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ERX1 */ - at91_set_b_periph(AT91_PIO_PORTC, 16, 0); /* ERXER */ - at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ETXEN */ - at91_set_b_periph(AT91_PIO_PORTC, 18, 0); /* ETX0 */ - at91_set_b_periph(AT91_PIO_PORTC, 19, 0); /* ETX1 */ - at91_set_b_periph(AT91_PIO_PORTC, 31, 0); /* EMDIO */ - at91_set_b_periph(AT91_PIO_PORTC, 30, 0); /* EMDC */ - } - -#ifndef CONFIG_RMII - /* Only emac0 support MII */ - if (has_emac0()) { - at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* ECRS */ - at91_set_a_periph(AT91_PIO_PORTB, 17, 0); /* ECOL */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* ERX2 */ - at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* ERX3 */ - at91_set_a_periph(AT91_PIO_PORTB, 15, 0); /* ERXCK */ - at91_set_a_periph(AT91_PIO_PORTB, 11, 0); /* ETX2 */ - at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* ETX3 */ - at91_set_a_periph(AT91_PIO_PORTB, 8, 0); /* ETXER */ - } -#endif -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/clock.c b/arch/arm/cpu/arm926ejs/at91/clock.c deleted file mode 100644 index f363982d03..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/clock.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] - * - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -#if !defined(CONFIG_AT91FAMILY) -# error You need to define CONFIG_AT91FAMILY in your board config! -#endif - -DECLARE_GLOBAL_DATA_PTR; - -static unsigned long at91_css_to_rate(unsigned long css) -{ - switch (css) { - case AT91_PMC_MCKR_CSS_SLOW: - return CONFIG_SYS_AT91_SLOW_CLOCK; - case AT91_PMC_MCKR_CSS_MAIN: - return gd->arch.main_clk_rate_hz; - case AT91_PMC_MCKR_CSS_PLLA: - return gd->arch.plla_rate_hz; - case AT91_PMC_MCKR_CSS_PLLB: - return gd->arch.pllb_rate_hz; - } - - return 0; -} - -#ifdef CONFIG_USB_ATMEL -static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) -{ - unsigned i, div = 0, mul = 0, diff = 1 << 30; - unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; - - /* PLL output max 240 MHz (or 180 MHz per errata) */ - if (out_freq > 240000000) - goto fail; - - for (i = 1; i < 256; i++) { - int diff1; - unsigned input, mul1; - - /* - * PLL input between 1MHz and 32MHz per spec, but lower - * frequences seem necessary in some cases so allow 100K. - * Warning: some newer products need 2MHz min. - */ - input = main_freq / i; -#if defined(CONFIG_AT91SAM9G20) - if (input < 2000000) - continue; -#endif - if (input < 100000) - continue; - if (input > 32000000) - continue; - - mul1 = out_freq / input; -#if defined(CONFIG_AT91SAM9G20) - if (mul > 63) - continue; -#endif - if (mul1 > 2048) - continue; - if (mul1 < 2) - goto fail; - - diff1 = out_freq - input * mul1; - if (diff1 < 0) - diff1 = -diff1; - if (diff > diff1) { - diff = diff1; - div = i; - mul = mul1; - if (diff == 0) - break; - } - } - if (i == 256 && diff > (out_freq >> 5)) - goto fail; - return ret | ((mul - 1) << 16) | div; -fail: - return 0; -} -#endif - -static u32 at91_pll_rate(u32 freq, u32 reg) -{ - unsigned mul, div; - - div = reg & 0xff; - mul = (reg >> 16) & 0x7ff; - if (div && mul) { - freq /= div; - freq *= mul + 1; - } else - freq = 0; - - return freq; -} - -int at91_clock_init(unsigned long main_clock) -{ - unsigned freq, mckr; - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK - unsigned tmp; - /* - * When the bootloader initialized the main oscillator correctly, - * there's no problem using the cycle counter. But if it didn't, - * or when using oscillator bypass mode, we must be told the speed - * of the main clock. - */ - if (!main_clock) { - do { - tmp = readl(&pmc->mcfr); - } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); - tmp &= AT91_PMC_MCFR_MAINF_MASK; - main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); - } -#endif - gd->arch.main_clk_rate_hz = main_clock; - - /* report if PLLA is more than mildly overclocked */ - gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); - -#ifdef CONFIG_USB_ATMEL - /* - * USB clock init: choose 48 MHz PLLB value, - * disable 48MHz clock during usb peripheral suspend. - * - * REVISIT: assumes MCK doesn't derive from PLLB! - */ - gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | - AT91_PMC_PLLBR_USBDIV_2; - gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, - gd->arch.at91_pllb_usb_init); -#endif - - /* - * MCK and CPU derive from one of those primary clocks. - * For now, assume this parentage won't change. - */ - mckr = readl(&pmc->mckr); -#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ - || defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) - /* plla divisor by 2 */ - gd->arch.plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); -#endif - gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = gd->arch.mck_rate_hz; - - freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ -#if defined(CONFIG_AT91SAM9G20) - /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ - gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? - freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; - if (mckr & AT91_PMC_MCKR_MDIV_MASK) - freq /= 2; /* processor clock division */ -#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ - || defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) - /* mdiv <==> divisor - * 0 <==> 1 - * 1 <==> 2 - * 2 <==> 4 - * 3 <==> 3 - */ - gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == - (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) - ? freq / 3 - : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); -#else - gd->arch.mck_rate_hz = freq / - (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); -#endif - gd->arch.cpu_clk_rate_hz = freq; - - return 0; -} - -#if !defined(AT91_PLL_LOCK_TIMEOUT) -#define AT91_PLL_LOCK_TIMEOUT 1000000 -#endif - -void at91_plla_init(u32 pllar) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - int timeout = AT91_PLL_LOCK_TIMEOUT; - - writel(pllar, &pmc->pllar); - while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) { - timeout--; - if (timeout == 0) - break; - } -} -void at91_pllb_init(u32 pllbr) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - int timeout = AT91_PLL_LOCK_TIMEOUT; - - writel(pllbr, &pmc->pllbr); - while (!(readl(&pmc->sr) & (AT91_PMC_LOCKB | AT91_PMC_MCKRDY))) { - timeout--; - if (timeout == 0) - break; - } -} - -void at91_mck_init(u32 mckr) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - int timeout = AT91_PLL_LOCK_TIMEOUT; - u32 tmp; - - tmp = readl(&pmc->mckr); - tmp &= ~(AT91_PMC_MCKR_PRES_MASK | - AT91_PMC_MCKR_MDIV_MASK | - AT91_PMC_MCKR_PLLADIV_MASK | - AT91_PMC_MCKR_CSS_MASK); - tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK | - AT91_PMC_MCKR_MDIV_MASK | - AT91_PMC_MCKR_PLLADIV_MASK | - AT91_PMC_MCKR_CSS_MASK); - writel(tmp, &pmc->mckr); - - while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) { - timeout--; - if (timeout == 0) - break; - } -} - -void at91_periph_clk_enable(int id) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - writel(1 << id, &pmc->pcer); -} diff --git a/arch/arm/cpu/arm926ejs/at91/config.mk b/arch/arm/cpu/arm926ejs/at91/config.mk deleted file mode 100644 index 370630d4de..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/config.mk +++ /dev/null @@ -1,2 +0,0 @@ -PF_CPPFLAGS_TUNE := $(call cc-option,-mtune=arm926ejs,) -PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_TUNE) diff --git a/arch/arm/cpu/arm926ejs/at91/cpu.c b/arch/arm/cpu/arm926ejs/at91/cpu.c deleted file mode 100644 index da1d35907e..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/cpu.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * (C) Copyright 2009 - * Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK -#define CONFIG_SYS_AT91_MAIN_CLOCK 0 -#endif - -int arch_cpu_init(void) -{ - return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); -} - -void arch_preboot_os(void) -{ - ulong cpiv; - at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; - - cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir)); - - /* - * Disable PITC - * Add 0x1000 to current counter to stop it faster - * without waiting for wrapping back to 0 - */ - writel(cpiv + 0x1000, &pit->mr); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - char buf[32]; - - printf("CPU: %s\n", ATMEL_CPU_NAME); - printf("Crystal frequency: %8s MHz\n", - strmhz(buf, get_main_clk_rate())); - printf("CPU clock : %8s MHz\n", - strmhz(buf, get_cpu_clk_rate())); - printf("Master clock : %8s MHz\n", - strmhz(buf, get_mck_clk_rate())); - - return 0; -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c deleted file mode 100644 index 3f39264289..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/eflash.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * (C) Copyright 2010 - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * this driver supports the enhanced embedded flash in the Atmel - * AT91SAM9XE devices with the following geometry: - * - * AT91SAM9XE128: 1 plane of 8 regions of 32 pages (total 256 pages) - * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total 512 pages) - * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages) - * (the exact geometry is read from the flash at runtime, so any - * future devices should already be covered) - * - * Regions can be write/erase protected. - * Whole (!) pages can be individually written with erase on the fly. - * Writing partial pages will corrupt the rest of the page. - * - * The flash is presented to u-boot with each region being a sector, - * having the following effects: - * Each sector can be hardware protected (protect on/off). - * Each page in a sector can be rewritten anytime. - * Since pages are erased when written, the "erase" does nothing. - * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected - * by u-Boot commands. - * - * Note: Redundant environment will not work in this flash since - * it does use partial page writes. Make sure the environment spans - * whole pages! - */ - -/* - * optional TODOs (nice to have features): - * - * make the driver coexist with other NOR flash drivers - * (use an index into flash_info[], requires work - * in those other drivers, too) - * Make the erase command fill the sectors with 0xff - * (if the flashes grow larger in the future and - * someone puts a jffs2 into them) - * do a read-modify-write for partially programmed pages - */ -#include -#include -#include -#include -#include -#include - -/* checks to detect configuration errors */ -#if CONFIG_SYS_MAX_FLASH_BANKS!=1 -#error eflash: this driver can only handle 1 bank -#endif - -/* global structure */ -flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; -static u32 pagesize; - -unsigned long flash_init (void) -{ - at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; - at91_dbu_t *dbu = (at91_dbu_t *) ATMEL_BASE_DBGU; - u32 id, size, nplanes, planesize, nlocks; - u32 addr, i, tmp=0; - - debug("eflash: init\n"); - - flash_info[0].flash_id = FLASH_UNKNOWN; - - /* check if its an AT91ARM9XE SoC */ - if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) { - puts("eflash: not an AT91SAM9XE\n"); - return 0; - } - - /* now query the eflash for its structure */ - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr); - while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) - ; - id = readl(&eefc->frr); /* word 0 */ - size = readl(&eefc->frr); /* word 1 */ - pagesize = readl(&eefc->frr); /* word 2 */ - nplanes = readl(&eefc->frr); /* word 3 */ - planesize = readl(&eefc->frr); /* word 4 */ - debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n", - id, size, pagesize, nplanes, planesize); - for (i=1; ifrr); /* words 5..4+nplanes-1 */ - }; - nlocks = readl(&eefc->frr); /* word 4+nplanes */ - debug("nlocks=%u\n", nlocks); - /* since we are going to use the lock regions as sectors, check count */ - if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) { - printf("eflash: number of lock regions(%u) "\ - "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n", - nlocks); - nlocks = CONFIG_SYS_MAX_FLASH_SECT; - } - flash_info[0].size = size; - flash_info[0].sector_count = nlocks; - flash_info[0].flash_id = id; - - addr = ATMEL_BASE_FLASH; - for (i=0; ifrr); /* words 4+nplanes+1.. */ - flash_info[0].start[i] = addr; - flash_info[0].protect[i] = 0; - addr += tmp; - }; - - /* now read the protection information for all regions */ - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); - while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) - ; - for (i=0; ifrr); - flash_info[0].protect[i] = (tmp >> (i%32)) & 1; -#if defined(CONFIG_EFLASH_PROTSECTORS) - if (i < CONFIG_EFLASH_PROTSECTORS) - flash_info[0].protect[i] = 1; -#endif - } - - return size; -} - -void flash_print_info (flash_info_t *info) -{ - int i; - - puts("AT91SAM9XE embedded flash\n Size: "); - print_size(info->size, " in "); - printf("%d Sectors\n", info->sector_count); - - printf(" Sector Start Addresses:"); - for (i=0; isector_count; ++i) { - if ((i % 5) == 0) - printf("\n "); - printf(" %08lX%s", - info->start[i], - info->protect[i] ? " (RO)" : " " - ); - } - printf ("\n"); - return; -} - -int flash_real_protect (flash_info_t *info, long sector, int prot) -{ - at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; - u32 pagenum = (info->start[sector]-ATMEL_BASE_FLASH)/pagesize; - u32 i, tmp=0; - - debug("protect sector=%ld prot=%d\n", sector, prot); - -#if defined(CONFIG_EFLASH_PROTSECTORS) - if (sector < CONFIG_EFLASH_PROTSECTORS) { - if (!prot) { - printf("eflash: sector %lu cannot be unprotected\n", - sector); - } - return 1; /* return anyway, caller does not care for result */ - } -#endif - if (prot) { - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB | - (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); - } else { - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB | - (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); - } - while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) - ; - /* now re-read the protection information for all regions */ - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); - while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) - ; - for (i=0; isector_count; i++) { - if (i%32 == 0) - tmp = readl(&eefc->frr); - info->protect[i] = (tmp >> (i%32)) & 1; - } - return 0; -} - -static u32 erase_write_page (u32 pagenum) -{ - at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; - - debug("erase+write page=%u\n", pagenum); - - /* give erase and write page command */ - writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP | - (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); - while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) - ; - /* return status */ - return readl(&eefc->fsr) - & (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE); -} - -int flash_erase (flash_info_t *info, int s_first, int s_last) -{ - debug("erase first=%d last=%d\n", s_first, s_last); - puts("this flash does not need and support erasing!\n"); - return 0; -} - -/* - * Copy memory to flash, returns: - * 0 - OK - * 1 - write timeout - */ - -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) -{ - u32 pagenum; - u32 *src32, *dst32; - u32 i; - - debug("write src=%08lx addr=%08lx cnt=%lx\n", - (ulong)src, addr, cnt); - - /* REQUIRE addr to be on a page start, abort if not */ - if (addr % pagesize) { - printf ("eflash: start %08lx is not on page start\n"\ - " write aborted\n", addr); - return 1; - } - - /* now start copying data */ - pagenum = (addr-ATMEL_BASE_FLASH)/pagesize; - src32 = (u32 *) src; - dst32 = (u32 *) addr; - while (cnt > 0) { - i = pagesize / 4; - /* fill page buffer */ - while (i--) - *dst32++ = *src32++; - /* write page */ - if (erase_write_page(pagenum)) - return 1; - pagenum++; - if (cnt > pagesize) - cnt -= pagesize; - else - cnt = 0; - } - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/at91/led.c b/arch/arm/cpu/arm926ejs/at91/led.c deleted file mode 100644 index b8d5c785df..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/led.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -#ifdef CONFIG_RED_LED -void red_led_on(void) -{ - gpio_set_value(CONFIG_RED_LED, 1); -} - -void red_led_off(void) -{ - gpio_set_value(CONFIG_RED_LED, 0); -} -#endif - -#ifdef CONFIG_GREEN_LED -void green_led_on(void) -{ - gpio_set_value(CONFIG_GREEN_LED, 0); -} - -void green_led_off(void) -{ - gpio_set_value(CONFIG_GREEN_LED, 1); -} -#endif - -#ifdef CONFIG_YELLOW_LED -void yellow_led_on(void) -{ - gpio_set_value(CONFIG_YELLOW_LED, 0); -} - -void yellow_led_off(void) -{ - gpio_set_value(CONFIG_YELLOW_LED, 1); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S b/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S deleted file mode 100644 index a9ec81a75c..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/lowlevel_init.S +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Memory Setup stuff - taken from blob memsetup.S - * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at) - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_ATMEL_LEGACY -#include -#endif -#ifndef CONFIG_SYS_MATRIX_EBICSA_VAL -#define CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_EBI0CSA_VAL -#endif - -.globl lowlevel_init -.type lowlevel_init,function -lowlevel_init: - -POS1: - adr r5, POS1 /* r5 = POS1 run time */ - ldr r0, =POS1 /* r0 = POS1 compile */ - sub r5, r5, r0 /* r0 = CONFIG_SYS_TEXT_BASE-1 */ - - /* memory control configuration 1 */ - ldr r0, =SMRDATA - ldr r2, =SMRDATA1 - add r0, r0, r5 - add r2, r2, r5 -0: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 0b - -/* ---------------------------------------------------------------------------- - * PMC Init Step 1. - * ---------------------------------------------------------------------------- - * - Check if the PLL is already initialized - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MCKR) - ldr r0, [r1] - and r0, r0, #3 - cmp r0, #0 - bne PLL_setup_end - -/* --------------------------------------------------------------------------- - * - Enable the Main Oscillator - * --------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MOR) - ldr r2, =(AT91_ASM_PMC_SR) - /* Main oscillator Enable register PMC_MOR: */ - ldr r0, =CONFIG_SYS_MOR_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Main Oscillator is enabled */ - mov r4, #AT91_PMC_IXR_MOSCS -MOSCS_Loop: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MOSCS - bne MOSCS_Loop - -/* ---------------------------------------------------------------------------- - * PMC Init Step 2. - * ---------------------------------------------------------------------------- - * Setup PLLA - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_PLLAR) - ldr r0, =CONFIG_SYS_PLLAR_VAL - str r0, [r1] - - /* Reading the PMC Status register to detect when the PLLA is locked */ - mov r4, #AT91_PMC_IXR_LOCKA -MOSCS_Loop1: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_LOCKA - bne MOSCS_Loop1 - -/* ---------------------------------------------------------------------------- - * PMC Init Step 3. - * ---------------------------------------------------------------------------- - * - Switch on the Main Oscillator - * ---------------------------------------------------------------------------- - */ - ldr r1, =(AT91_ASM_PMC_MCKR) - - /* -Master Clock Controller register PMC_MCKR */ - ldr r0, =CONFIG_SYS_MCKR1_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Master clock is ready */ - mov r4, #AT91_PMC_IXR_MCKRDY -MCKRDY_Loop: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MCKRDY - bne MCKRDY_Loop - - ldr r0, =CONFIG_SYS_MCKR2_VAL - str r0, [r1] - - /* Reading the PMC Status to detect when the Master clock is ready */ - mov r4, #AT91_PMC_IXR_MCKRDY -MCKRDY_Loop1: - ldr r3, [r2] - and r3, r4, r3 - cmp r3, #AT91_PMC_IXR_MCKRDY - bne MCKRDY_Loop1 -PLL_setup_end: - -/* ---------------------------------------------------------------------------- - * - memory control configuration 2 - * ---------------------------------------------------------------------------- - */ - ldr r0, =(AT91_ASM_SDRAMC_TR) - ldr r1, [r0] - cmp r1, #0 - bne SDRAM_setup_end - - ldr r0, =SMRDATA1 - ldr r2, =SMRDATA2 - add r0, r0, r5 - add r2, r2, r5 -2: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 2b - -SDRAM_setup_end: - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word AT91_ASM_WDT_MR - .word CONFIG_SYS_WDTC_WDMR_VAL - /* configure PIOx as EBI0 D[16-31] */ -#if defined(CONFIG_AT91SAM9263) - .word AT91_ASM_PIOD_PDR - .word CONFIG_SYS_PIOD_PDR_VAL1 - .word AT91_ASM_PIOD_PUDR - .word CONFIG_SYS_PIOD_PPUDR_VAL - .word AT91_ASM_PIOD_ASR - .word CONFIG_SYS_PIOD_PPUDR_VAL -#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \ - || defined(CONFIG_AT91SAM9G20) - .word AT91_ASM_PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL1 - .word AT91_ASM_PIOC_PUDR - .word CONFIG_SYS_PIOC_PPUDR_VAL -#endif - .word AT91_ASM_MATRIX_CSA0 - .word CONFIG_SYS_MATRIX_EBICSA_VAL - - /* flash */ - .word AT91_ASM_SMC_MODE0 - .word CONFIG_SYS_SMC0_MODE0_VAL - - .word AT91_ASM_SMC_CYCLE0 - .word CONFIG_SYS_SMC0_CYCLE0_VAL - - .word AT91_ASM_SMC_PULSE0 - .word CONFIG_SYS_SMC0_PULSE0_VAL - - .word AT91_ASM_SMC_SETUP0 - .word CONFIG_SYS_SMC0_SETUP0_VAL - -SMRDATA1: - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word AT91_ASM_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL1 - .word AT91_ASM_SDRAMC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word AT91_ASM_SDRAMC_MDR - .word CONFIG_SYS_SDRC_MDR_VAL - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL1 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL2 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL3 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL4 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL5 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL6 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL7 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL8 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL9 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL4 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL10 - .word AT91_ASM_SDRAMC_MR - .word CONFIG_SYS_SDRC_MR_VAL5 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL11 - .word AT91_ASM_SDRAMC_TR - .word CONFIG_SYS_SDRC_TR_VAL2 - .word CONFIG_SYS_SDRAM_BASE - .word CONFIG_SYS_SDRAM_VAL12 - /* User reset enable*/ - .word AT91_ASM_RSTC_MR - .word CONFIG_SYS_RSTC_RMR_VAL -#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP - /* MATRIX_MCFG - REMAP all masters */ - .word AT91_ASM_MATRIX_MCFG - .word 0x1FF -#endif -SMRDATA2: - .word 0 diff --git a/arch/arm/cpu/arm926ejs/at91/reset.c b/arch/arm/cpu/arm926ejs/at91/reset.c deleted file mode 100644 index e67f47bd04..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/reset.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* Reset the cpu by telling the reset controller to do so */ -void reset_cpu(ulong ignored) -{ - at91_rstc_t *rstc = (at91_rstc_t *) ATMEL_BASE_RSTC; - - writel(AT91_RSTC_KEY - | AT91_RSTC_CR_PROCRST /* Processor Reset */ - | AT91_RSTC_CR_PERRST /* Peripheral Reset */ -#ifdef CONFIG_AT91RESET_EXTRST - | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */ -#endif - , &rstc->cr); - /* never reached */ - while (1) - ; -} diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c deleted file mode 100644 index b0b7fb93fb..0000000000 --- a/arch/arm/cpu/arm926ejs/at91/timer.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(CONFIG_AT91FAMILY) -# error You need to define CONFIG_AT91FAMILY in your board config! -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/* - * We're using the AT91CAP9/SAM9 PITC in 32 bit mode, by - * setting the 20 bit counter period to its maximum (0xfffff). - * (See the relevant data sheets to understand that this really works) - * - * We do also mimic the typical powerpc way of incrementing - * two 32 bit registers called tbl and tbu. - * - * Those registers increment at 1/16 the main clock rate. - */ - -#define TIMER_LOAD_VAL 0xfffff - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, gd->arch.timer_rate_hz); - - return tick; -} - -static inline unsigned long long usec_to_tick(unsigned long long usec) -{ - usec *= gd->arch.timer_rate_hz; - do_div(usec, 1000000); - - return usec; -} - -/* - * Use the PITC in full 32 bit incrementing mode - */ -int timer_init(void) -{ - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; - - /* Enable PITC Clock */ - writel(1 << ATMEL_ID_SYS, &pmc->pcer); - - /* Enable PITC */ - writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); - - gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16; - gd->arch.tbu = gd->arch.tbl = 0; - - return 0; -} - -/* - * Get the current 64 bit timer tick count - */ -unsigned long long get_ticks(void) -{ - at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; - - ulong now = readl(&pit->piir); - - /* increment tbu if tbl has rolled over */ - if (now < gd->arch.tbl) - gd->arch.tbu++; - gd->arch.tbl = now; - return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; -} - -void __udelay(unsigned long usec) -{ - unsigned long long start; - ulong tmo; - - start = get_ticks(); /* get current timestamp */ - tmo = usec_to_tick(usec); /* convert usecs to ticks */ - while ((get_ticks() - start) < tmo) - ; /* loop till time has passed */ -} - -/* - * get_timer(base) can be used to check for timeouts or - * to measure elasped time relative to an event: - * - * ulong start_time = get_timer(0) sets start_time to the current - * time value. - * get_timer(start_time) returns the time elapsed since then. - * - * The time is used in CONFIG_SYS_HZ units! - */ -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -/* - * Return the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return gd->arch.timer_rate_hz; -} diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 409e6f5651..6dbca26ceb 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -40,7 +40,6 @@ endif obj-$(if $(filter am33xx,$(SOC)),y) += am33xx/ obj-$(if $(filter armada-xp,$(SOC)),y) += armada-xp/ -obj-$(CONFIG_AT91FAMILY) += at91/ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ diff --git a/arch/arm/cpu/armv7/at91/Makefile b/arch/arm/cpu/armv7/at91/Makefile deleted file mode 100644 index f4f35a4bc1..0000000000 --- a/arch/arm/cpu/armv7/at91/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2013 -# Bo Shen -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o -obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o -obj-y += clock.o -obj-y += cpu.o -obj-y += reset.o -obj-y += timer.o diff --git a/arch/arm/cpu/armv7/at91/clock.c b/arch/arm/cpu/armv7/at91/clock.c deleted file mode 100644 index 0bf453eff5..0000000000 --- a/arch/arm/cpu/armv7/at91/clock.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] - * - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * Copyright (C) 2013 Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -#if !defined(CONFIG_AT91FAMILY) -# error You need to define CONFIG_AT91FAMILY in your board config! -#endif - -DECLARE_GLOBAL_DATA_PTR; - -static unsigned long at91_css_to_rate(unsigned long css) -{ - switch (css) { - case AT91_PMC_MCKR_CSS_SLOW: - return CONFIG_SYS_AT91_SLOW_CLOCK; - case AT91_PMC_MCKR_CSS_MAIN: - return gd->arch.main_clk_rate_hz; - case AT91_PMC_MCKR_CSS_PLLA: - return gd->arch.plla_rate_hz; - } - - return 0; -} - -static u32 at91_pll_rate(u32 freq, u32 reg) -{ - unsigned mul, div; - - div = reg & 0xff; - mul = (reg >> 18) & 0x7f; - if (div && mul) { - freq /= div; - freq *= mul + 1; - } else { - freq = 0; - } - - return freq; -} - -int at91_clock_init(unsigned long main_clock) -{ - unsigned freq, mckr; - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK - unsigned tmp; - /* - * When the bootloader initialized the main oscillator correctly, - * there's no problem using the cycle counter. But if it didn't, - * or when using oscillator bypass mode, we must be told the speed - * of the main clock. - */ - if (!main_clock) { - do { - tmp = readl(&pmc->mcfr); - } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); - tmp &= AT91_PMC_MCFR_MAINF_MASK; - main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); - } -#endif - gd->arch.main_clk_rate_hz = main_clock; - - /* report if PLLA is more than mildly overclocked */ - gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); - - /* - * MCK and CPU derive from one of those primary clocks. - * For now, assume this parentage won't change. - */ - mckr = readl(&pmc->mckr); - - /* plla divisor by 2 */ - if (mckr & (1 << 12)) - gd->arch.plla_rate_hz >>= 1; - - gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); - freq = gd->arch.mck_rate_hz; - - /* prescale */ - freq >>= mckr & AT91_PMC_MCKR_PRES_MASK; - - switch (mckr & AT91_PMC_MCKR_MDIV_MASK) { - case AT91_PMC_MCKR_MDIV_2: - gd->arch.mck_rate_hz = freq / 2; - break; - case AT91_PMC_MCKR_MDIV_3: - gd->arch.mck_rate_hz = freq / 3; - break; - case AT91_PMC_MCKR_MDIV_4: - gd->arch.mck_rate_hz = freq / 4; - break; - default: - break; - } - - gd->arch.cpu_clk_rate_hz = freq; - - return 0; -} - -void at91_plla_init(u32 pllar) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - writel(pllar, &pmc->pllar); - while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) - ; -} - -void at91_mck_init(u32 mckr) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - u32 tmp; - - tmp = readl(&pmc->mckr); - tmp &= ~(AT91_PMC_MCKR_CSS_MASK | - AT91_PMC_MCKR_PRES_MASK | - AT91_PMC_MCKR_MDIV_MASK | - AT91_PMC_MCKR_PLLADIV_2); -#ifdef CPU_HAS_H32MXDIV - tmp &= ~AT91_PMC_MCKR_H32MXDIV; -#endif - - tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK | - AT91_PMC_MCKR_PRES_MASK | - AT91_PMC_MCKR_MDIV_MASK | - AT91_PMC_MCKR_PLLADIV_2); -#ifdef CPU_HAS_H32MXDIV - tmp |= mckr & AT91_PMC_MCKR_H32MXDIV; -#endif - - writel(tmp, &pmc->mckr); - - while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) - ; -} - -void at91_periph_clk_enable(int id) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - u32 regval; - - if (id > AT91_PMC_PCR_PID_MASK) - return; - - regval = AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD_WRITE | id; - - writel(regval, &pmc->pcr); -} - -void at91_periph_clk_disable(int id) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - u32 regval; - - if (id > AT91_PMC_PCR_PID_MASK) - return; - - regval = AT91_PMC_PCR_CMD_WRITE | id; - - writel(regval, &pmc->pcr); -} diff --git a/arch/arm/cpu/armv7/at91/config.mk b/arch/arm/cpu/armv7/at91/config.mk deleted file mode 100644 index db6030880f..0000000000 --- a/arch/arm/cpu/armv7/at91/config.mk +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (C) 2014, Andreas Bießmann -# -# SPDX-License-Identifier: GPL-2.0+ -# -ifndef CONFIG_SPL_BUILD -ALL-y += u-boot.img -endif diff --git a/arch/arm/cpu/armv7/at91/cpu.c b/arch/arm/cpu/armv7/at91/cpu.c deleted file mode 100644 index 8d86f97e3d..0000000000 --- a/arch/arm/cpu/armv7/at91/cpu.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * (C) Copyright 2009 - * Jean-Christophe PLAGNIOL-VILLARD - * (C) Copyright 2013 - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_SYS_AT91_MAIN_CLOCK -#define CONFIG_SYS_AT91_MAIN_CLOCK 0 -#endif - -int arch_cpu_init(void) -{ - return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); -} - -void arch_preboot_os(void) -{ - ulong cpiv; - at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; - - cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir)); - - /* - * Disable PITC - * Add 0x1000 to current counter to stop it faster - * without waiting for wrapping back to 0 - */ - writel(cpiv + 0x1000, &pit->mr); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - char buf[32]; - - printf("CPU: %s\n", get_cpu_name()); - printf("Crystal frequency: %8s MHz\n", - strmhz(buf, get_main_clk_rate())); - printf("CPU clock : %8s MHz\n", - strmhz(buf, get_cpu_clk_rate())); - printf("Master clock : %8s MHz\n", - strmhz(buf, get_mck_clk_rate())); - - return 0; -} -#endif - -void enable_caches(void) -{ - icache_enable(); - dcache_enable(); -} - -unsigned int get_chip_id(void) -{ - return readl(ATMEL_BASE_DBGU + AT91_DBU_CIDR) & ~AT91_DBU_CIDR_MASK; -} - -unsigned int get_extension_chip_id(void) -{ - return readl(ATMEL_BASE_DBGU + AT91_DBU_EXID); -} diff --git a/arch/arm/cpu/armv7/at91/reset.c b/arch/arm/cpu/armv7/at91/reset.c deleted file mode 100644 index b30e79b60a..0000000000 --- a/arch/arm/cpu/armv7/at91/reset.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2013 - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* Reset the cpu by telling the reset controller to do so */ -void reset_cpu(ulong ignored) -{ - at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; - - writel(AT91_RSTC_KEY - | AT91_RSTC_CR_PROCRST /* Processor Reset */ - | AT91_RSTC_CR_PERRST /* Peripheral Reset */ -#ifdef CONFIG_AT91RESET_EXTRST - | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */ -#endif - , &rstc->cr); - /* never reached */ - do { } while (1); -} diff --git a/arch/arm/cpu/armv7/at91/sama5d3_devices.c b/arch/arm/cpu/armv7/at91/sama5d3_devices.c deleted file mode 100644 index 78ecfc882a..0000000000 --- a/arch/arm/cpu/armv7/at91/sama5d3_devices.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2012-2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -unsigned int has_emac() -{ - return cpu_is_sama5d31() || cpu_is_sama5d35() || cpu_is_sama5d36(); -} - -unsigned int has_gmac() -{ - return !cpu_is_sama5d31(); -} - -unsigned int has_lcdc() -{ - return !cpu_is_sama5d35(); -} - -char *get_cpu_name() -{ - unsigned int extension_id = get_extension_chip_id(); - - if (cpu_is_sama5d3()) - switch (extension_id) { - case ARCH_EXID_SAMA5D31: - return "SAMA5D31"; - case ARCH_EXID_SAMA5D33: - return "SAMA5D33"; - case ARCH_EXID_SAMA5D34: - return "SAMA5D34"; - case ARCH_EXID_SAMA5D35: - return "SAMA5D35"; - case ARCH_EXID_SAMA5D36: - return "SAMA5D36"; - default: - return "Unknown CPU type"; - } - else - return "Unknown CPU type"; -} - -void at91_serial0_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTD, 18, 1); /* TXD0 */ - at91_set_a_periph(AT91_PIO_PORTD, 17, 0); /* RXD0 */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_USART0); -} - -void at91_serial1_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTB, 29, 1); /* TXD1 */ - at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* RXD1 */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_USART1); -} - -void at91_serial2_hw_init(void) -{ - at91_set_b_periph(AT91_PIO_PORTE, 26, 1); /* TXD2 */ - at91_set_b_periph(AT91_PIO_PORTE, 25, 0); /* RXD2 */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_USART2); -} - -void at91_seriald_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTB, 31, 1); /* DTXD */ - at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_DBGU); -} - -#if defined(CONFIG_ATMEL_SPI) -void at91_spi0_hw_init(unsigned long cs_mask) -{ - at91_set_a_periph(AT91_PIO_PORTD, 10, 0); /* SPI0_MISO */ - at91_set_a_periph(AT91_PIO_PORTD, 11, 0); /* SPI0_MOSI */ - at91_set_a_periph(AT91_PIO_PORTD, 12, 0); /* SPI0_SPCK */ - - if (cs_mask & (1 << 0)) - at91_set_pio_output(AT91_PIO_PORTD, 13, 1); - if (cs_mask & (1 << 1)) - at91_set_pio_output(AT91_PIO_PORTD, 14, 1); - if (cs_mask & (1 << 2)) - at91_set_pio_output(AT91_PIO_PORTD, 15, 1); - if (cs_mask & (1 << 3)) - at91_set_pio_output(AT91_PIO_PORTD, 16, 1); - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_SPI0); -} -#endif - -#ifdef CONFIG_GENERIC_ATMEL_MCI -void at91_mci_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTD, 0, 0); /* MCI0 CMD */ - at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* MCI0 DA0 */ - at91_set_a_periph(AT91_PIO_PORTD, 2, 0); /* MCI0 DA1 */ - at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* MCI0 DA2 */ - at91_set_a_periph(AT91_PIO_PORTD, 4, 0); /* MCI0 DA3 */ -#ifdef CONFIG_ATMEL_MCI_8BIT - at91_set_a_periph(AT91_PIO_PORTD, 5, 0); /* MCI0 DA4 */ - at91_set_a_periph(AT91_PIO_PORTD, 6, 0); /* MCI0 DA5 */ - at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* MCI0 DA6 */ - at91_set_a_periph(AT91_PIO_PORTD, 8, 0); /* MCI0 DA7 */ -#endif - at91_set_a_periph(AT91_PIO_PORTD, 9, 0); /* MCI0 CLK */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_MCI0); -} -#endif - -#ifdef CONFIG_MACB -void at91_macb_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* ETXCK_EREFCK */ - at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* ERXDV */ - at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* ERX0 */ - at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* ERX1 */ - at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* ERXER */ - at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* ETXEN */ - at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* ETX0 */ - at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* ETX1 */ - at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* EMDIO */ - at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* EMDC */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_EMAC); -} - -void at91_gmac_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* GTX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* GTX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* GTX2 */ - at91_set_a_periph(AT91_PIO_PORTB, 3, 0); /* GTX3 */ - at91_set_a_periph(AT91_PIO_PORTB, 4, 0); /* GRX0 */ - at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* GRX1 */ - at91_set_a_periph(AT91_PIO_PORTB, 6, 0); /* GRX2 */ - at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* GRX3 */ - at91_set_a_periph(AT91_PIO_PORTB, 8, 0); /* GTXCK */ - at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* GTXEN */ - - at91_set_a_periph(AT91_PIO_PORTB, 11, 0); /* GRXCK */ - at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* GRXER */ - - at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* GMDC */ - at91_set_a_periph(AT91_PIO_PORTB, 17, 0); /* GMDIO */ - at91_set_a_periph(AT91_PIO_PORTB, 18, 0); /* G125CK */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_GMAC); -} -#endif - -#ifdef CONFIG_LCD -void at91_lcd_hw_init(void) -{ - at91_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */ - at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */ - at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */ - at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */ - at91_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */ - at91_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */ - - /* The lower 16-bit of LCD only available on Port A */ - at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */ - at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */ - at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */ - at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */ - at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */ - at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */ - at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */ - at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */ - at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD8 */ - at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD9 */ - at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */ - at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */ - at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */ - at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */ - at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */ - at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */ - - /* Enable clock */ - at91_periph_clk_enable(ATMEL_ID_LCDC); -} -#endif - -#ifdef CONFIG_USB_GADGET_ATMEL_USBA -void at91_udp_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - /* Enable UPLL clock */ - writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr); - /* Enable UDPHS clock */ - at91_periph_clk_enable(ATMEL_ID_UDPHS); -} -#endif diff --git a/arch/arm/cpu/armv7/at91/sama5d4_devices.c b/arch/arm/cpu/armv7/at91/sama5d4_devices.c deleted file mode 100644 index ef39cb7e08..0000000000 --- a/arch/arm/cpu/armv7/at91/sama5d4_devices.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2014 Atmel - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -char *get_cpu_name() -{ - unsigned int extension_id = get_extension_chip_id(); - - if (cpu_is_sama5d4()) - switch (extension_id) { - case ARCH_EXID_SAMA5D41: - return "SAMA5D41"; - case ARCH_EXID_SAMA5D42: - return "SAMA5D42"; - case ARCH_EXID_SAMA5D43: - return "SAMA5D43"; - case ARCH_EXID_SAMA5D44: - return "SAMA5D44"; - default: - return "Unknown CPU type"; - } - else - return "Unknown CPU type"; -} - -#ifdef CONFIG_USB_GADGET_ATMEL_USBA -void at91_udp_hw_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - /* Enable UPLL clock */ - writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr); - /* Enable UDPHS clock */ - at91_periph_clk_enable(ATMEL_ID_UDPHS); -} -#endif - -#ifdef CONFIG_SPL_BUILD -void matrix_init(void) -{ - struct atmel_matrix *h64mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX0; - struct atmel_matrix *h32mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX1; - int i; - - /* Disable the write protect */ - writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); - writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); - - /* DDR port 1 ~ poart 7, slave number is: 4 ~ 10 */ - for (i = 4; i <= 10; i++) { - writel(0x000f0f0f, &h64mx->ssr[i]); - writel(0x0000ffff, &h64mx->sassr[i]); - writel(0x0000000f, &h64mx->srtsr[i]); - } - - /* CS3 */ - writel(0x00c0c0c0, &h32mx->ssr[3]); - writel(0xff000000, &h32mx->sassr[3]); - writel(0xff000000, &h32mx->srtsr[3]); - - /* NFC SRAM */ - writel(0x00010101, &h32mx->ssr[4]); - writel(0x00000001, &h32mx->sassr[4]); - writel(0x00000001, &h32mx->srtsr[4]); - - /* Enable the write protect */ - writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); - writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); -} - -void redirect_int_from_saic_to_aic(void) -{ - struct atmel_sfr *sfr = (struct atmel_sfr *)ATMEL_BASE_SFR; - u32 key32; - - if (!(readl(&sfr->aicredir) & ATMEL_SFR_AICREDIR_NSAIC)) { - key32 = readl(&sfr->sn1) ^ ATMEL_SFR_AICREDIR_KEY; - writel((key32 | ATMEL_SFR_AICREDIR_NSAIC), &sfr->aicredir); - } -} -#endif diff --git a/arch/arm/cpu/armv7/at91/timer.c b/arch/arm/cpu/armv7/at91/timer.c deleted file mode 100644 index 19bf80ba7e..0000000000 --- a/arch/arm/cpu/armv7/at91/timer.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2013 - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(CONFIG_AT91FAMILY) -# error You need to define CONFIG_AT91FAMILY in your board config! -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/* - * We're using the SAMA5D3x PITC in 32 bit mode, by - * setting the 20 bit counter period to its maximum (0xfffff). - * (See the relevant data sheets to understand that this really works) - * - * We do also mimic the typical powerpc way of incrementing - * two 32 bit registers called tbl and tbu. - * - * Those registers increment at 1/16 the main clock rate. - */ - -#define TIMER_LOAD_VAL 0xfffff - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, gd->arch.timer_rate_hz); - - return tick; -} - -static inline unsigned long long usec_to_tick(unsigned long long usec) -{ - usec *= gd->arch.timer_rate_hz; - do_div(usec, 1000000); - - return usec; -} - -/* - * Use the PITC in full 32 bit incrementing mode - */ -int timer_init(void) -{ - at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; - - /* Enable PITC Clock */ - at91_periph_clk_enable(ATMEL_ID_PIT); - - /* Enable PITC */ - writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); - - gd->arch.timer_rate_hz = get_pit_clk_rate() / 16; - - gd->arch.tbu = 0; - gd->arch.tbl = 0; - - return 0; -} - -/* - * Get the current 64 bit timer tick count - */ -unsigned long long get_ticks(void) -{ - at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; - - ulong now = readl(&pit->piir); - - /* increment tbu if tbl has rolled over */ - if (now < gd->arch.tbl) - gd->arch.tbu++; - gd->arch.tbl = now; - return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; -} - -void __udelay(unsigned long usec) -{ - unsigned long long start; - ulong tmo; - - start = get_ticks(); /* get current timestamp */ - tmo = usec_to_tick(usec); /* convert usecs to ticks */ - while ((get_ticks() - start) < tmo) - ; /* loop till time has passed */ -} - -/* - * get_timer(base) can be used to check for timeouts or - * to measure elasped time relative to an event: - * - * ulong start_time = get_timer(0) sets start_time to the current - * time value. - * get_timer(start_time) returns the time elapsed since then. - * - * The time is used in CONFIG_SYS_HZ units! - */ -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -/* - * Return the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return gd->arch.timer_rate_hz; -} diff --git a/arch/arm/cpu/at91-common/Makefile b/arch/arm/cpu/at91-common/Makefile deleted file mode 100644 index 03614d4140..0000000000 --- a/arch/arm/cpu/at91-common/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2013 Atmel Corporation -# Bo Shen -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o -ifneq ($(CONFIG_SPL_BUILD),) -obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o -obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o -obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o -obj-$(CONFIG_SAMA5D4) += mpddrc.o spl_atmel.o -obj-y += spl.o -endif diff --git a/arch/arm/cpu/at91-common/mpddrc.c b/arch/arm/cpu/at91-common/mpddrc.c deleted file mode 100644 index beec13db8c..0000000000 --- a/arch/arm/cpu/at91-common/mpddrc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -static inline void atmel_mpddr_op(int mode, u32 ram_address) -{ - struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; - - writel(mode, &mpddr->mr); - writel(0, ram_address); -} - -static int ddr2_decodtype_is_seq(u32 cr) -{ -#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) - if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED) - return 0; -#endif - return 1; -} - -int ddr2_init(const unsigned int ram_address, - const struct atmel_mpddr *mpddr_value) -{ - struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; - u32 ba_off, cr; - - /* Compute bank offset according to NC in configuration register */ - ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; - if (ddr2_decodtype_is_seq(mpddr_value->cr)) - ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; - - ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; - - /* Program the memory device type into the memory device register */ - writel(mpddr_value->md, &mpddr->md); - - /* Program the configuration register */ - writel(mpddr_value->cr, &mpddr->cr); - - /* Program the timing register */ - writel(mpddr_value->tpr0, &mpddr->tpr0); - writel(mpddr_value->tpr1, &mpddr->tpr1); - writel(mpddr_value->tpr2, &mpddr->tpr2); - - /* Issue a NOP command */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); - - /* A 200 us is provided to precede any signal toggle */ - udelay(200); - - /* Issue a NOP command */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); - - /* Issue an all banks precharge command */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); - - /* Issue an extended mode register set(EMRS2) to choose operation */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, - ram_address + (0x2 << ba_off)); - - /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, - ram_address + (0x3 << ba_off)); - - /* - * Issue an extended mode register set(EMRS1) to enable DLL and - * program D.I.C (output driver impedance control) - */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, - ram_address + (0x1 << ba_off)); - - /* Enable DLL reset */ - cr = readl(&mpddr->cr); - writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr); - - /* A mode register set(MRS) cycle is issued to reset DLL */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); - - /* Issue an all banks precharge command */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); - - /* Two auto-refresh (CBR) cycles are provided */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); - - /* Disable DLL reset */ - cr = readl(&mpddr->cr); - writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr); - - /* A mode register set (MRS) cycle is issued to disable DLL reset */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); - - /* Set OCD calibration in default state */ - cr = readl(&mpddr->cr); - writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr); - - /* - * An extended mode register set (EMRS1) cycle is issued - * to OCD default value - */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, - ram_address + (0x1 << ba_off)); - - /* OCD calibration mode exit */ - cr = readl(&mpddr->cr); - writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr); - - /* - * An extended mode register set (EMRS1) cycle is issued - * to enable OCD exit - */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, - ram_address + (0x1 << ba_off)); - - /* A nornal mode command is provided */ - atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address); - - /* Perform a write access to any DDR2-SDRAM address */ - writel(0, ram_address); - - /* Write the refresh rate */ - writel(mpddr_value->rtr, &mpddr->rtr); - - return 0; -} diff --git a/arch/arm/cpu/at91-common/phy.c b/arch/arm/cpu/at91-common/phy.c deleted file mode 100644 index 2cba7169e4..0000000000 --- a/arch/arm/cpu/at91-common/phy.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * (C) Copyright 2012 - * Markus Hubig - * IMKO GmbH - * - * Copyright (C) 2013 DENX Software Engineering, hs@denx.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -void at91_phy_reset(void) -{ - unsigned long erstl; - unsigned long start = get_timer(0); - unsigned long const timeout = 1000; /* 1000ms */ - at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; - - erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK; - - /* - * Need to reset PHY -> 500ms reset - * Reset PHY by pulling the NRST line for 500ms to low. To do so - * disable user reset for low level on NRST pin and poll the NRST - * level in reset status register. - */ - writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) | - AT91_RSTC_MR_URSTEN, &rstc->mr); - - writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr); - - /* Wait for end of hardware reset */ - while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) { - /* avoid shutdown by watchdog */ - WATCHDOG_RESET(); - mdelay(10); - - /* timeout for not getting stuck in an endless loop */ - if (get_timer(start) >= timeout) { - puts("*** ERROR: Timeout waiting for PHY reset!\n"); - break; - } - }; - - /* Restore NRST value */ - writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr); -} diff --git a/arch/arm/cpu/at91-common/sdram.c b/arch/arm/cpu/at91-common/sdram.c deleted file mode 100644 index 5758b066e4..0000000000 --- a/arch/arm/cpu/at91-common/sdram.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (C) Copyright 2014 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * Based on: - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -int sdramc_initialize(unsigned int sdram_address, const struct sdramc_reg *p) -{ - struct sdramc_reg *reg = (struct sdramc_reg *)ATMEL_BASE_SDRAMC; - unsigned int i; - - /* SDRAM feature must be in the configuration register */ - writel(p->cr, ®->cr); - - /* The SDRAM memory type must be set in the Memory Device Register */ - writel(p->mdr, ®->mdr); - - /* - * The minimum pause of 200 us is provided to precede any single - * toggle - */ - for (i = 0; i < 1000; i++) - ; - - /* A NOP command is issued to the SDRAM devices */ - writel(AT91_SDRAMC_MODE_NOP, ®->mr); - writel(0x00000000, sdram_address); - - /* An All Banks Precharge command is issued to the SDRAM devices */ - writel(AT91_SDRAMC_MODE_PRECHARGE, ®->mr); - writel(0x00000000, sdram_address); - - for (i = 0; i < 10000; i++) - ; - - /* Eight auto-refresh cycles are provided */ - for (i = 0; i < 8; i++) { - writel(AT91_SDRAMC_MODE_REFRESH, ®->mr); - writel(0x00000001 + i, sdram_address + 4 + 4 * i); - } - - /* - * A Mode Register set (MRS) cyscle is issued to program the - * SDRAM parameters(TCSR, PASR, DS) - */ - writel(AT91_SDRAMC_MODE_LMR, ®->mr); - writel(0xcafedede, sdram_address + 0x24); - - /* - * The application must go into Normal Mode, setting Mode - * to 0 in the Mode Register and perform a write access at - * any location in the SDRAM. - */ - writel(AT91_SDRAMC_MODE_NORMAL, ®->mr); - writel(0x00000000, sdram_address); /* Perform Normal mode */ - - /* - * Write the refresh rate into the count field in the SDRAMC - * Refresh Timer Rgister. - */ - writel(p->tr, ®->tr); - - return 0; -} diff --git a/arch/arm/cpu/at91-common/spl.c b/arch/arm/cpu/at91-common/spl.c deleted file mode 100644 index aaa5eec2e6..0000000000 --- a/arch/arm/cpu/at91-common/spl.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_AT91SAM9_WATCHDOG) -void at91_disable_wdt(void) { } -#else -void at91_disable_wdt(void) -{ - struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; - - writel(AT91_WDT_MR_WDDIS, &wdt->mr); -} -#endif - -u32 spl_boot_device(void) -{ -#ifdef CONFIG_SYS_USE_MMC - return BOOT_DEVICE_MMC1; -#elif CONFIG_SYS_USE_NANDFLASH - return BOOT_DEVICE_NAND; -#elif CONFIG_SYS_USE_SERIALFLASH - return BOOT_DEVICE_SPI; -#endif - return BOOT_DEVICE_NONE; -} - -u32 spl_boot_mode(void) -{ - switch (spl_boot_device()) { -#ifdef CONFIG_SYS_USE_MMC - case BOOT_DEVICE_MMC1: - return MMCSD_MODE_FS; - break; -#endif - case BOOT_DEVICE_NONE: - default: - hang(); - } -} diff --git a/arch/arm/cpu/at91-common/spl_at91.c b/arch/arm/cpu/at91-common/spl_at91.c deleted file mode 100644 index 89f588be45..0000000000 --- a/arch/arm/cpu/at91-common/spl_at91.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2014 DENX Software Engineering - * Heiko Schocher - * - * Based on: - * Copyright (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static void enable_ext_reset(void) -{ - struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC; - - writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr); -} - -void lowlevel_clock_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) { - /* Enable Main Oscillator */ - writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor); - - /* Wait until Main Oscillator is stable */ - while (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) - ; - } - - /* After stabilization, switch to Main Oscillator */ - if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) { - unsigned long tmp; - - tmp = readl(&pmc->mckr); - tmp &= ~AT91_PMC_CSS; - tmp |= AT91_PMC_CSS_MAIN; - writel(tmp, &pmc->mckr); - while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) - ; - - tmp &= ~AT91_PMC_PRES; - tmp |= AT91_PMC_PRES_1; - writel(tmp, &pmc->mckr); - while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) - ; - } - - return; -} - -void __weak matrix_init(void) -{ -} - -void __weak at91_spl_board_init(void) -{ -} - -void spl_board_init(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - lowlevel_clock_init(); - at91_disable_wdt(); - - /* - * At this stage the main oscillator is supposed to be enabled - * PCK = MCK = MOSC - */ - writel(0x00, &pmc->pllicpr); - - /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ - at91_plla_init(CONFIG_SYS_AT91_PLLA); - - /* PCK = PLLA = 2 * MCK */ - at91_mck_init(CONFIG_SYS_MCKR); - - /* Switch MCK on PLLA output */ - at91_mck_init(CONFIG_SYS_MCKR_CSS); - -#if defined(CONFIG_SYS_AT91_PLLB) - /* Configure PLLB */ - at91_pllb_init(CONFIG_SYS_AT91_PLLB); -#endif - - /* Enable External Reset */ - enable_ext_reset(); - - /* Initialize matrix */ - matrix_init(); - - gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK; - /* - * init timer long enough for using in spl. - */ - timer_init(); - - /* enable clocks for all PIOs */ - at91_periph_clk_enable(ATMEL_ID_PIOA); - at91_periph_clk_enable(ATMEL_ID_PIOB); - at91_periph_clk_enable(ATMEL_ID_PIOC); - /* init console */ - at91_seriald_hw_init(); - preloader_console_init(); - - mem_init(); - - at91_spl_board_init(); -} diff --git a/arch/arm/cpu/at91-common/spl_atmel.c b/arch/arm/cpu/at91-common/spl_atmel.c deleted file mode 100644 index 9cc1111234..0000000000 --- a/arch/arm/cpu/at91-common/spl_atmel.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static void switch_to_main_crystal_osc(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - u32 tmp; - - tmp = readl(&pmc->mor); - tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff); - tmp &= ~AT91_PMC_MOR_KEY(0xff); - tmp |= AT91_PMC_MOR_MOSCEN; - tmp |= AT91_PMC_MOR_OSCOUNT(8); - tmp |= AT91_PMC_MOR_KEY(0x37); - writel(tmp, &pmc->mor); - while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS)) - ; - - tmp = readl(&pmc->mor); - tmp &= ~AT91_PMC_MOR_OSCBYPASS; - tmp &= ~AT91_PMC_MOR_KEY(0xff); - tmp |= AT91_PMC_MOR_KEY(0x37); - writel(tmp, &pmc->mor); - - tmp = readl(&pmc->mor); - tmp |= AT91_PMC_MOR_MOSCSEL; - tmp &= ~AT91_PMC_MOR_KEY(0xff); - tmp |= AT91_PMC_MOR_KEY(0x37); - writel(tmp, &pmc->mor); - - while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS)) - ; - - /* Wait until MAINRDY field is set to make sure main clock is stable */ - while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY)) - ; - -#ifndef CONFIG_SAMA5D4 - tmp = readl(&pmc->mor); - tmp &= ~AT91_PMC_MOR_MOSCRCEN; - tmp &= ~AT91_PMC_MOR_KEY(0xff); - tmp |= AT91_PMC_MOR_KEY(0x37); - writel(tmp, &pmc->mor); -#endif -} - -__weak void matrix_init(void) -{ - /* This only be used for sama5d4 soc now */ -} - -__weak void redirect_int_from_saic_to_aic(void) -{ - /* This only be used for sama5d4 soc now */ -} - -void s_init(void) -{ - switch_to_main_crystal_osc(); - - /* disable watchdog */ - at91_disable_wdt(); - - /* PMC configuration */ - at91_pmc_init(); - - at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); - - matrix_init(); - - redirect_int_from_saic_to_aic(); - - timer_init(); - - board_early_init_f(); - - preloader_console_init(); - - mem_init(); -} diff --git a/arch/arm/cpu/at91-common/u-boot-spl.lds b/arch/arm/cpu/at91-common/u-boot-spl.lds deleted file mode 100644 index eccca43a42..0000000000 --- a/arch/arm/cpu/at91-common/u-boot-spl.lds +++ /dev/null @@ -1,55 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2010 - * Texas Instruments, - * Aneesh V - * - * (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \ - LENGTH = CONFIG_SPL_MAX_SIZE } -MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ - LENGTH = CONFIG_SPL_BSS_MAX_SIZE } - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - .text : - { - __start = .; - *(.vectors) - arch/arm/cpu/armv7/start.o (.text*) - *(.text*) - } >.sram - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram - - . = ALIGN(4); - .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram - - . = ALIGN(4); - __image_copy_end = .; - - .end : - { - *(.__end) - } >.sram - - .bss : - { - . = ALIGN(4); - __bss_start = .; - *(.bss*) - . = ALIGN(4); - __bss_end = .; - } >.sdram -} diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile new file mode 100644 index 0000000000..e596ba6ce8 --- /dev/null +++ b/arch/arm/mach-at91/Makefile @@ -0,0 +1,12 @@ +obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o +ifneq ($(CONFIG_SPL_BUILD),) +obj-$(CONFIG_AT91SAM9G20) += sdram.o spl_at91.o +obj-$(CONFIG_AT91SAM9M10G45) += mpddrc.o spl_at91.o +obj-$(CONFIG_SAMA5D3) += mpddrc.o spl_atmel.o +obj-$(CONFIG_SAMA5D4) += mpddrc.o spl_atmel.o +obj-y += spl.o +endif + +obj-$(CONFIG_CPU_ARM920T) += arm920t/ +obj-$(CONFIG_CPU_ARM926EJS) += arm926ejs/ +obj-$(CONFIG_CPU_V7) += armv7/ diff --git a/arch/arm/mach-at91/arm920t/Makefile b/arch/arm/mach-at91/arm920t/Makefile new file mode 100644 index 0000000000..561b4b4cbb --- /dev/null +++ b/arch/arm/mach-at91/arm920t/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += lowlevel_init.o +obj-y += reset.o +obj-y += timer.o +obj-y += clock.o +obj-y += cpu.o +obj-y += at91rm9200_devices.o diff --git a/arch/arm/mach-at91/arm920t/at91rm9200_devices.c b/arch/arm/mach-at91/arm920t/at91rm9200_devices.c new file mode 100644 index 0000000000..fc54327c0d --- /dev/null +++ b/arch/arm/mach-at91/arm920t/at91rm9200_devices.c @@ -0,0 +1,67 @@ +/* + * [partely copied from arch/arm/cpu/arm926ejs/at91/arm9260_devices.c] + * + * (C) Copyright 2011 + * Andreas Bießmann + * + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 17, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 18, PUP); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 20, PUP); /* RXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 21, 1); /* TXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 22, PUP); /* RXD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 23, 1); /* TXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 30, PUP); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 31, 1); /* DTXD */ + /* writing SYS to PCER has no effect on AT91RM9200 */ +} diff --git a/arch/arm/mach-at91/arm920t/clock.c b/arch/arm/mach-at91/arm920t/clock.c new file mode 100644 index 0000000000..2813bf7821 --- /dev/null +++ b/arch/arm/mach-at91/arm920t/clock.c @@ -0,0 +1,157 @@ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2011 Andreas Bießmann + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static unsigned long at91_css_to_rate(unsigned long css) +{ + switch (css) { + case AT91_PMC_MCKR_CSS_SLOW: + return CONFIG_SYS_AT91_SLOW_CLOCK; + case AT91_PMC_MCKR_CSS_MAIN: + return gd->arch.main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return gd->arch.plla_rate_hz; + case AT91_PMC_MCKR_CSS_PLLB: + return gd->arch.pllb_rate_hz; + } + + return 0; +} + +#ifdef CONFIG_USB_ATMEL +static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) +{ + unsigned i, div = 0, mul = 0, diff = 1 << 30; + unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + + /* PLL output max 240 MHz (or 180 MHz per errata) */ + if (out_freq > 240000000) + goto fail; + + for (i = 1; i < 256; i++) { + int diff1; + unsigned input, mul1; + + /* + * PLL input between 1MHz and 32MHz per spec, but lower + * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. + */ + input = main_freq / i; + if (input < 100000) + continue; + if (input > 32000000) + continue; + + mul1 = out_freq / input; + if (mul1 > 2048) + continue; + if (mul1 < 2) + goto fail; + + diff1 = out_freq - input * mul1; + if (diff1 < 0) + diff1 = -diff1; + if (diff > diff1) { + diff = diff1; + div = i; + mul = mul1; + if (diff == 0) + break; + } + } + if (i == 256 && diff > (out_freq >> 5)) + goto fail; + return ret | ((mul - 1) << 16) | div; +fail: + return 0; +} +#endif + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 16) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK + unsigned tmp; + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(&pmc->mcfr); + } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); + tmp &= AT91_PMC_MCFR_MAINF_MASK; + main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); + } +#endif + gd->arch.main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + +#ifdef CONFIG_USB_ATMEL + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + AT91_PMC_PLLBR_USBDIV_2; + gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, + gd->arch.at91_pllb_usb_init); +#endif + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(&pmc->mckr); + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; + + freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ + /* mdiv */ + gd->arch.mck_rate_hz = freq / + (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); + gd->arch.cpu_clk_rate_hz = freq; + + return 0; +} diff --git a/arch/arm/mach-at91/arm920t/cpu.c b/arch/arm/mach-at91/arm920t/cpu.c new file mode 100644 index 0000000000..b0f411b1c3 --- /dev/null +++ b/arch/arm/mach-at91/arm920t/cpu.c @@ -0,0 +1,26 @@ +/* + * [origin: arch/arm/cpu/arm926ejs/at91/cpu.c] + * + * (C) Copyright 2011 + * Andreas Bießmann, andreas.devel@googlemail.com + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +int arch_cpu_init(void) +{ + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} diff --git a/arch/arm/mach-at91/arm920t/lowlevel_init.S b/arch/arm/mach-at91/arm920t/lowlevel_init.S new file mode 100644 index 0000000000..d2934a3525 --- /dev/null +++ b/arch/arm/mach-at91/arm920t/lowlevel_init.S @@ -0,0 +1,152 @@ +/* + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the at91rm9200dk board by + * (C) Copyright 2004 + * Gary Jennejohn, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +#include +#include +#include +#include + +#define ARM920T_CONTROL 0xC0000000 /* @ set bit 31 (iA) and 30 (nF) */ + +_MTEXT_BASE: +#undef START_FROM_MEM +#ifdef START_FROM_MEM + .word CONFIG_SYS_TEXT_BASE-PHYS_FLASH_1 +#else + .word CONFIG_SYS_TEXT_BASE +#endif + +.globl lowlevel_init +lowlevel_init: + ldr r1, =AT91_ASM_PMC_MOR + /* Main oscillator Enable register */ +#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR + ldr r0, =0x0000FF01 /* Enable main oscillator */ +#else + ldr r0, =0x0000FF00 /* Disable main oscillator */ +#endif + str r0, [r1] /*AT91C_CKGR_MOR] */ + /* Add loop to compensate Main Oscillator startup time */ + ldr r0, =0x00000010 +LoopOsc: + subs r0, r0, #1 + bhi LoopOsc + + /* memory control configuration */ + /* this isn't very elegant, but what the heck */ + ldr r0, =SMRDATA + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + ldr r2, =SMRDATAE + sub r2, r2, r1 +pllloop: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne pllloop + /* delay - this is all done by guess */ + ldr r0, =0x00010000 + /* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */ +lock: + subs r0, r0, #1 + bhi lock + ldr r0, =SMRDATA1 + ldr r1, _MTEXT_BASE + sub r0, r0, r1 + ldr r2, =SMRDATA1E + sub r2, r2, r1 +sdinit: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne sdinit + + /* switch from FastBus to Asynchronous clock mode */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #ARM920T_CONTROL + mcr p15, 0, r0, c1, c0, 0 + + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91_ASM_MC_EBI_CFG + .word CONFIG_SYS_EBI_CFGR_VAL + .word AT91_ASM_MC_SMC_CSR0 + .word CONFIG_SYS_SMC_CSR0_VAL + .word AT91_ASM_PMC_PLLAR + .word CONFIG_SYS_PLLAR_VAL + .word AT91_ASM_PMC_PLLBR + .word CONFIG_SYS_PLLBR_VAL + .word AT91_ASM_PMC_MCKR + .word CONFIG_SYS_MCKR_VAL +SMRDATAE: + /* here there's a delay */ +SMRDATA1: + .word AT91_ASM_PIOC_ASR + .word CONFIG_SYS_PIOC_ASR_VAL + .word AT91_ASM_PIOC_BSR + .word CONFIG_SYS_PIOC_BSR_VAL + .word AT91_ASM_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL + .word AT91_ASM_MC_EBI_CSA + .word CONFIG_SYS_EBI_CSA_VAL + .word AT91_ASM_MC_SDRAMC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM1 + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word AT91_ASM_MC_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL +SMRDATA1E: + /* SMRDATA1 is 176 bytes long */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/arch/arm/mach-at91/arm920t/reset.c b/arch/arm/mach-at91/arm920t/reset.c new file mode 100644 index 0000000000..d47777a367 --- /dev/null +++ b/arch/arm/mach-at91/arm920t/reset.c @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +void __attribute__((weak)) board_reset(void) +{ + /* true empty function for defining weak symbol */ +} + +void reset_cpu(ulong ignored) +{ + at91_st_t *st = (at91_st_t *) ATMEL_BASE_ST; + + board_reset(); + + /* Reset the cpu by setting up the watchdog timer */ + writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2), + &st->wdmr); + writel(AT91_ST_CR_WDRST, &st->cr); + /* and let it timeout */ + while (1) + ; + /* Never reached */ +} diff --git a/arch/arm/mach-at91/arm920t/timer.c b/arch/arm/mach-at91/arm920t/timer.c new file mode 100644 index 0000000000..6aa2994723 --- /dev/null +++ b/arch/arm/mach-at91/arm920t/timer.c @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* the number of clocks per CONFIG_SYS_HZ */ +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) + +int timer_init(void) +{ + at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + /* enables TC1.0 clock */ + writel(1 << ATMEL_ID_TC0, &pmc->pcer); /* enable clock */ + + writel(0, &tc->bcr); + writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | + AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); + + writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); + /* set to MCLK/2 and restart the timer + when the value in TC_RC is reached */ + writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); + + writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */ + writel(TIMER_LOAD_VAL, &tc->tc[0].rc); + + writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); + gd->arch.lastinc = 0; + gd->arch.tbl = 0; + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void __udelay(unsigned long usec) +{ + udelay_masked(usec); +} + +ulong get_timer_raw(void) +{ + at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; + u32 now; + + now = readl(&tc->tc[0].cv) & 0x0000ffff; + + if (now >= gd->arch.lastinc) { + /* normal mode */ + gd->arch.tbl += now - gd->arch.lastinc; + } else { + /* we have an overflow ... */ + gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc; + } + gd->arch.lastinc = now; + + return gd->arch.tbl; +} + +ulong get_timer_masked(void) +{ + return get_timer_raw()/TIMER_LOAD_VAL; +} + +void udelay_masked(unsigned long usec) +{ + u32 tmo; + u32 endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= 1000; + + endtime = get_timer_raw() + tmo; + + do { + u32 now = get_timer_raw(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/mach-at91/arm926ejs/Makefile b/arch/arm/mach-at91/arm926ejs/Makefile new file mode 100644 index 0000000000..ddc323f641 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/Makefile @@ -0,0 +1,28 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o +obj-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o +obj-$(CONFIG_AT91SAM9XE) += at91sam9260_devices.o +obj-$(CONFIG_AT91SAM9261) += at91sam9261_devices.o +obj-$(CONFIG_AT91SAM9G10) += at91sam9261_devices.o +obj-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o +obj-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o +obj-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o +obj-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o +obj-$(CONFIG_AT91SAM9N12) += at91sam9n12_devices.o +obj-$(CONFIG_AT91SAM9X5) += at91sam9x5_devices.o +obj-$(CONFIG_AT91_EFLASH) += eflash.o +obj-$(CONFIG_AT91_LED) += led.o +obj-y += clock.o +obj-y += cpu.o +obj-y += reset.o +obj-y += timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y += lowlevel_init.o +endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c new file mode 100644 index 0000000000..efb53d673f --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9260_devices.c @@ -0,0 +1,245 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 7, PUP); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTB, 9, PUP); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTC, 11, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTC, 16, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTC, 17, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTC, 11, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTC, 16, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTC, 17, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTC, 5, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTC, 4, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTC, 3, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTC, 5, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTC, 4, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTC, 3, 1); + } +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + /* Enable EMAC clock */ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + writel(1 << ATMEL_ID_EMAC0, &pmc->pcer); + + at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* EMDC */ + +#ifndef CONFIG_RMII + at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTA, 25, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 26, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ERXCK */ +#if defined(CONFIG_AT91SAM9260EK) || defined(CONFIG_AFEB9260) + /* + * use PA10, PA11 for ETX2, ETX3. + * PA23 and PA24 are for TWI EEPROM + */ + at91_set_b_periph(AT91_PIO_PORTA, 10, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 11, 0); /* ETX3 */ +#else + at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 24, 0); /* ETX3 */ +#if defined(CONFIG_AT91SAM9G20) + /* 9G20 BOOT ROM initializes those pins to multi-drive, undo that */ + at91_set_pio_multi_drive(AT91_PIO_PORTA, 23, 0); + at91_set_pio_multi_drive(AT91_PIO_PORTA, 24, 0); +#endif +#endif + at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* ETXER */ +#endif +} +#endif + +#if defined(CONFIG_GENERIC_ATMEL_MCI) +void at91_mci_hw_init(void) +{ + /* Enable mci clock */ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + writel(1 << ATMEL_ID_MCI, &pmc->pcer); + + at91_set_a_periph(AT91_PIO_PORTA, 8, 1); /* MCCK */ +#if defined(CONFIG_ATMEL_MCI_PORTB) + at91_set_b_periph(AT91_PIO_PORTA, 1, 1); /* MCCDB */ + at91_set_b_periph(AT91_PIO_PORTA, 0, 1); /* MCDB0 */ + at91_set_b_periph(AT91_PIO_PORTA, 5, 1); /* MCDB1 */ + at91_set_b_periph(AT91_PIO_PORTA, 4, 1); /* MCDB2 */ + at91_set_b_periph(AT91_PIO_PORTA, 3, 1); /* MCDB3 */ +#else + at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* MCCDA */ + at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* MCDA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 9, 1); /* MCDA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* MCDA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* MCDA3 */ +#endif +} +#endif + +void at91_sdram_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTC, 16, 0); + at91_set_a_periph(AT91_PIO_PORTC, 17, 0); + at91_set_a_periph(AT91_PIO_PORTC, 18, 0); + at91_set_a_periph(AT91_PIO_PORTC, 19, 0); + at91_set_a_periph(AT91_PIO_PORTC, 20, 0); + at91_set_a_periph(AT91_PIO_PORTC, 21, 0); + at91_set_a_periph(AT91_PIO_PORTC, 22, 0); + at91_set_a_periph(AT91_PIO_PORTC, 23, 0); + at91_set_a_periph(AT91_PIO_PORTC, 24, 0); + at91_set_a_periph(AT91_PIO_PORTC, 25, 0); + at91_set_a_periph(AT91_PIO_PORTC, 26, 0); + at91_set_a_periph(AT91_PIO_PORTC, 27, 0); + at91_set_a_periph(AT91_PIO_PORTC, 28, 0); + at91_set_a_periph(AT91_PIO_PORTC, 29, 0); + at91_set_a_periph(AT91_PIO_PORTC, 30, 0); + at91_set_a_periph(AT91_PIO_PORTC, 31, 0); +} + +/* Platform data for the GPIOs */ +static const struct at91_port_platdata at91sam9260_plat[] = { + { ATMEL_BASE_PIOA, "PA" }, + { ATMEL_BASE_PIOB, "PB" }, + { ATMEL_BASE_PIOC, "PC" }, +}; + +U_BOOT_DEVICES(at91sam9260_gpios) = { + { "gpio_at91", &at91sam9260_plat[0] }, + { "gpio_at91", &at91sam9260_plat[1] }, + { "gpio_at91", &at91sam9260_plat[2] }, +}; diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9261_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9261_devices.c new file mode 100644 index 0000000000..a445c7507e --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9261_devices.c @@ -0,0 +1,140 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTC, 8, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTC, 12, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTC, 14, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_a_periph(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTA, 6, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTA, 6, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 30, PUP); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 31, PUP); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 29, PUP); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 28, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTA, 24, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTA, 25, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTA, 26, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 28, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 24, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 25, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTA, 26, 1); + } +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9263_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9263_devices.c new file mode 100644 index 0000000000..6b51d5f355 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9263_devices.c @@ -0,0 +1,218 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2009-2011 + * Daniel Gorsulowski + * esd electronic system design gmbh + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 26, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 27, PUP); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTD, 1, PUP); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTD, 3, PUP); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTC, 30, PUP); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ + at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ + at91_set_b_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_b_periph(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTB, 11, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 5, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTA, 3, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTA, 4, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTB, 11, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 12, PUP); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 13, PUP); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_a_periph(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTB, 18, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 15, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 16, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTB, 18, 1); + } +} +#endif + +#if defined(CONFIG_GENERIC_ATMEL_MCI) +void at91_mci_hw_init(void) +{ + /* Enable mci clock */ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + writel(1 << ATMEL_ID_MCI1, &pmc->pcer); + + at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCI1_CK */ + +#if defined(CONFIG_ATMEL_MCI_PORTB) + at91_set_a_periph(AT91_PIO_PORTA, 21, PUP); /* MCI1_CDB */ + at91_set_a_periph(AT91_PIO_PORTA, 22, PUP); /* MCI1_DB0 */ + at91_set_a_periph(AT91_PIO_PORTA, 23, PUP); /* MCI1_DB1 */ + at91_set_a_periph(AT91_PIO_PORTA, 24, PUP); /* MCI1_DB2 */ + at91_set_a_periph(AT91_PIO_PORTA, 25, PUP); /* MCI1_DB3 */ +#else + at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCI1_CDA */ + at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCI1_DA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCI1_DA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCI1_DA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCI1_DA3 */ +#endif +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTE, 21, 0); /* ETXCK_EREFCK */ + at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTE, 25, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTE, 26, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTE, 27, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTE, 28, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTE, 23, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTE, 24, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTE, 30, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTE, 29, 0); /* EMDC */ + +#ifndef CONFIG_RMII + at91_set_a_periph(AT91_PIO_PORTE, 22, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */ + at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */ + at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */ +#endif +} +#endif + +#ifdef CONFIG_USB_OHCI_NEW +void at91_uhp_hw_init(void) +{ + /* Enable VBus on UHP ports */ + at91_set_pio_output(AT91_PIO_PORTA, 21, 0); + at91_set_pio_output(AT91_PIO_PORTA, 24, 0); +} +#endif + +#ifdef CONFIG_AT91_CAN +void at91_can_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* CAN_TX */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 1); /* CAN_RX */ + + /* Enable clock */ + writel(1 << ATMEL_ID_CAN, &pmc->pcer); +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c new file mode 100644 index 0000000000..0e6c0da1bd --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9m10g45_devices.c @@ -0,0 +1,184 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 19, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTB, 18, PUP); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTD, 6, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTD, 7, PUP); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 1); /* DTXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTB, 18, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_b_periph(AT91_PIO_PORTB, 19, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTD, 27, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 3, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 18, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTB, 19, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 27, 1); + } +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* SPI1_MISO */ + at91_set_a_periph(AT91_PIO_PORTB, 15, PUP); /* SPI1_MOSI */ + at91_set_a_periph(AT91_PIO_PORTB, 16, PUP); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTD, 28, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTD, 18, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_a_periph(AT91_PIO_PORTD, 19, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTB, 17, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTD, 28, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTD, 18, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 19, 1); + } + +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* EMDC */ +#ifndef CONFIG_RMII + at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECRS */ + at91_set_b_periph(AT91_PIO_PORTA, 30, 0); /* ECOL */ + at91_set_b_periph(AT91_PIO_PORTA, 8, 0); /* ERX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 9, 0); /* ERX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ERXCK */ + at91_set_b_periph(AT91_PIO_PORTA, 6, 0); /* ETX2 */ + at91_set_b_periph(AT91_PIO_PORTA, 7, 0); /* ETX3 */ + at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ETXER */ +#endif +} +#endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +void at91_mci_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* MCI0 CLK */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* MCI0 CDA */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* MCI0 DA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* MCI0 DA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* MCI0 DA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* MCI0 DA3 */ + + /* Enable clock */ + writel(1 << ATMEL_ID_MCI0, &pmc->pcer); +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9n12_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9n12_devices.c new file mode 100644 index 0000000000..39f17a1e11 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9n12_devices.c @@ -0,0 +1,161 @@ +/* + * (C) Copyright 2013 Atmel Corporation + * Josh Wu + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +unsigned int has_lcdc() +{ + return 1; +} + +void at91_serial0_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 5, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_serial3_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_b_periph(AT91_PIO_PORTC, 22, 1); /* TXD3 */ + at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* RXD3 */ + writel(1 << ATMEL_ID_USART3, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#ifdef CONFIG_ATMEL_SPI +void at91_spi0_hw_init(unsigned long cs_mask) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) + at91_set_pio_output(AT91_PIO_PORTA, 14, 1); + if (cs_mask & (1 << 1)) + at91_set_pio_output(AT91_PIO_PORTA, 7, 1); + if (cs_mask & (1 << 2)) + at91_set_pio_output(AT91_PIO_PORTA, 1, 1); + if (cs_mask & (1 << 3)) + at91_set_pio_output(AT91_PIO_PORTB, 3, 1); +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_b_periph(AT91_PIO_PORTA, 21, 0); /* SPI1_MISO */ + at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* SPI1_MOSI */ + at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) + at91_set_pio_output(AT91_PIO_PORTA, 8, 1); + if (cs_mask & (1 << 1)) + at91_set_pio_output(AT91_PIO_PORTA, 0, 1); + if (cs_mask & (1 << 2)) + at91_set_pio_output(AT91_PIO_PORTA, 31, 1); + if (cs_mask & (1 << 3)) + at91_set_pio_output(AT91_PIO_PORTA, 30, 1); +} +#endif + +void at91_mci_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* MCCK */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* MCCDA */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* MCDA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* MCDA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* MCDA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* MCDA3 */ + + writel(1 << ATMEL_ID_HSMCI0, &pmc->pcer); +} + +#ifdef CONFIG_LCD +void at91_lcd_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTC, 24, 0); /* LCDDPWR */ + at91_set_a_periph(AT91_PIO_PORTC, 26, 0); /* LCDVSYNC */ + at91_set_a_periph(AT91_PIO_PORTC, 27, 0); /* LCDHSYNC */ + at91_set_a_periph(AT91_PIO_PORTC, 28, 0); /* LCDDOTCK */ + at91_set_a_periph(AT91_PIO_PORTC, 29, 0); /* LCDDEN */ + at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* LCDDOTCK */ + + at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* LCDD0 */ + at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* LCDD1 */ + at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* LCDD2 */ + at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* LCDD3 */ + at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* LCDD4 */ + at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* LCDD5 */ + at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* LCDD6 */ + at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* LCDD7 */ + at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* LCDD8 */ + at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* LCDD9 */ + at91_set_a_periph(AT91_PIO_PORTC, 10, 0); /* LCDD10 */ + at91_set_a_periph(AT91_PIO_PORTC, 11, 0); /* LCDD11 */ + at91_set_a_periph(AT91_PIO_PORTC, 12, 0); /* LCDD12 */ + at91_set_a_periph(AT91_PIO_PORTC, 13, 0); /* LCDD13 */ + at91_set_a_periph(AT91_PIO_PORTC, 14, 0); /* LCDD14 */ + at91_set_a_periph(AT91_PIO_PORTC, 15, 0); /* LCDD15 */ + at91_set_a_periph(AT91_PIO_PORTC, 16, 0); /* LCDD16 */ + at91_set_a_periph(AT91_PIO_PORTC, 17, 0); /* LCDD17 */ + at91_set_a_periph(AT91_PIO_PORTC, 18, 0); /* LCDD18 */ + at91_set_a_periph(AT91_PIO_PORTC, 19, 0); /* LCDD19 */ + at91_set_a_periph(AT91_PIO_PORTC, 20, 0); /* LCDD20 */ + at91_set_a_periph(AT91_PIO_PORTC, 21, 0); /* LCDD21 */ + at91_set_a_periph(AT91_PIO_PORTC, 22, 0); /* LCDD22 */ + at91_set_a_periph(AT91_PIO_PORTC, 23, 0); /* LCDD23 */ + + writel(1 << ATMEL_ID_LCDC, &pmc->pcer); +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9rl_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9rl_devices.c new file mode 100644 index 0000000000..0ec32c3ab9 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9rl_devices.c @@ -0,0 +1,103 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* + * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all + * peripheral pins. Good to have if hardware is soldered optionally + * or in case of SPI no slave is selected. Avoid lines to float + * needlessly. Use a short local PUP define. + * + * Due to errata "TXD floats when CTS is inactive" pullups are always + * on for TXD pins. + */ +#ifdef CONFIG_AT91_GPIO_PULLUP +# define PUP CONFIG_AT91_GPIO_PULLUP +#else +# define PUP 0 +#endif + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* RXD0 */ + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTA, 12, PUP); /* RXD1 */ + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* TXD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 14, PUP); /* RXD2 */ + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 21, PUP); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* DTXD */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +#if defined(CONFIG_HAS_DATAFLASH) || defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 25, PUP); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 26, PUP); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 27, PUP); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI, &pmc->pcer); + + if (cs_mask & (1 << 0)) { + at91_set_a_periph(AT91_PIO_PORTA, 28, 1); + } + if (cs_mask & (1 << 1)) { + at91_set_b_periph(AT91_PIO_PORTB, 7, 1); + } + if (cs_mask & (1 << 2)) { + at91_set_a_periph(AT91_PIO_PORTD, 8, 1); + } + if (cs_mask & (1 << 3)) { + at91_set_b_periph(AT91_PIO_PORTD, 9, 1); + } + if (cs_mask & (1 << 4)) { + at91_set_pio_output(AT91_PIO_PORTA, 28, 1); + } + if (cs_mask & (1 << 5)) { + at91_set_pio_output(AT91_PIO_PORTB, 7, 1); + } + if (cs_mask & (1 << 6)) { + at91_set_pio_output(AT91_PIO_PORTD, 8, 1); + } + if (cs_mask & (1 << 7)) { + at91_set_pio_output(AT91_PIO_PORTD, 9, 1); + } +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/at91sam9x5_devices.c b/arch/arm/mach-at91/arm926ejs/at91sam9x5_devices.c new file mode 100644 index 0000000000..6d94572237 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/at91sam9x5_devices.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2012 Atmel Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +unsigned int get_chip_id(void) +{ + /* The 0x40 is the offset of cidr in DBGU */ + return readl(ATMEL_BASE_DBGU + 0x40) & ~ARCH_ID_VERSION_MASK; +} + +unsigned int get_extension_chip_id(void) +{ + /* The 0x44 is the offset of exid in DBGU */ + return readl(ATMEL_BASE_DBGU + 0x44); +} + +unsigned int has_emac1() +{ + return cpu_is_at91sam9x25(); +} + +unsigned int has_emac0() +{ + return !(cpu_is_at91sam9g15()); +} + +unsigned int has_lcdc() +{ + return cpu_is_at91sam9g15() || cpu_is_at91sam9g35() + || cpu_is_at91sam9x35(); +} + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_at91sam9x5()) { + switch (extension_id) { + case ARCH_EXID_AT91SAM9G15: + return "AT91SAM9G15"; + case ARCH_EXID_AT91SAM9G25: + return "AT91SAM9G25"; + case ARCH_EXID_AT91SAM9G35: + return "AT91SAM9G35"; + case ARCH_EXID_AT91SAM9X25: + return "AT91SAM9X25"; + case ARCH_EXID_AT91SAM9X35: + return "AT91SAM9X35"; + default: + return "Unknown CPU type"; + } + } else { + return "Unknown CPU type"; + } +} + +void at91_seriald_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* DRXD */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* DTXD */ + + writel(1 << ATMEL_ID_SYS, &pmc->pcer); +} + +void at91_serial0_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 0, 1); /* TXD */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* RXD */ + + writel(1 << ATMEL_ID_USART0, &pmc->pcer); +} + +void at91_serial1_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 5, 1); /* TXD */ + at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* RXD */ + + writel(1 << ATMEL_ID_USART1, &pmc->pcer); +} + +void at91_serial2_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* TXD */ + at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* RXD */ + + writel(1 << ATMEL_ID_USART2, &pmc->pcer); +} + +void at91_mci_hw_init(void) +{ + /* Initialize the MCI0 */ + at91_set_a_periph(AT91_PIO_PORTA, 17, 1); /* MCCK */ + at91_set_a_periph(AT91_PIO_PORTA, 16, 1); /* MCCDA */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 1); /* MCDA0 */ + at91_set_a_periph(AT91_PIO_PORTA, 18, 1); /* MCDA1 */ + at91_set_a_periph(AT91_PIO_PORTA, 19, 1); /* MCDA2 */ + at91_set_a_periph(AT91_PIO_PORTA, 20, 1); /* MCDA3 */ + + /* Enable clock for MCI0 */ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + writel(1 << ATMEL_ID_HSMCI0, &pmc->pcer); +} + +#ifdef CONFIG_ATMEL_SPI +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* SPI0_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI0, &pmc->pcer); + + if (cs_mask & (1 << 0)) + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); + if (cs_mask & (1 << 1)) + at91_set_b_periph(AT91_PIO_PORTA, 7, 0); + if (cs_mask & (1 << 2)) + at91_set_b_periph(AT91_PIO_PORTA, 1, 0); + if (cs_mask & (1 << 3)) + at91_set_b_periph(AT91_PIO_PORTB, 3, 0); + if (cs_mask & (1 << 4)) + at91_set_pio_output(AT91_PIO_PORTA, 14, 0); + if (cs_mask & (1 << 5)) + at91_set_pio_output(AT91_PIO_PORTA, 7, 0); + if (cs_mask & (1 << 6)) + at91_set_pio_output(AT91_PIO_PORTA, 1, 0); + if (cs_mask & (1 << 7)) + at91_set_pio_output(AT91_PIO_PORTB, 3, 0); +} + +void at91_spi1_hw_init(unsigned long cs_mask) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + at91_set_b_periph(AT91_PIO_PORTA, 21, 0); /* SPI1_MISO */ + at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* SPI1_MOSI */ + at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* SPI1_SPCK */ + + /* Enable clock */ + writel(1 << ATMEL_ID_SPI1, &pmc->pcer); + + if (cs_mask & (1 << 0)) + at91_set_b_periph(AT91_PIO_PORTA, 8, 0); + if (cs_mask & (1 << 1)) + at91_set_b_periph(AT91_PIO_PORTA, 0, 0); + if (cs_mask & (1 << 2)) + at91_set_b_periph(AT91_PIO_PORTA, 31, 0); + if (cs_mask & (1 << 3)) + at91_set_b_periph(AT91_PIO_PORTA, 30, 0); + if (cs_mask & (1 << 4)) + at91_set_pio_output(AT91_PIO_PORTA, 8, 0); + if (cs_mask & (1 << 5)) + at91_set_pio_output(AT91_PIO_PORTA, 0, 0); + if (cs_mask & (1 << 6)) + at91_set_pio_output(AT91_PIO_PORTA, 31, 0); + if (cs_mask & (1 << 7)) + at91_set_pio_output(AT91_PIO_PORTA, 30, 0); +} +#endif + +#if defined(CONFIG_USB_OHCI_NEW) || defined(CONFIG_USB_EHCI) +void at91_uhp_hw_init(void) +{ + /* Enable VBus on UHP ports */ + at91_set_pio_output(AT91_PIO_PORTD, 18, 0); /* port A */ + at91_set_pio_output(AT91_PIO_PORTD, 19, 0); /* port B */ +#if defined(CONFIG_USB_OHCI_NEW) + /* port C is OHCI only */ + at91_set_pio_output(AT91_PIO_PORTD, 20, 0); /* port C */ +#endif +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + + if (has_emac0()) { + /* Enable EMAC0 clock */ + writel(1 << ATMEL_ID_EMAC0, &pmc->pcer); + /* EMAC0 pins setup */ + at91_set_a_periph(AT91_PIO_PORTB, 4, 0); /* ETXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 3, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 10, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTB, 6, 0); /* EMDC */ + } + + if (has_emac1()) { + /* Enable EMAC1 clock */ + writel(1 << ATMEL_ID_EMAC1, &pmc->pcer); + /* EMAC1 pins setup */ + at91_set_b_periph(AT91_PIO_PORTC, 29, 0); /* ETXCK */ + at91_set_b_periph(AT91_PIO_PORTC, 28, 0); /* ECRSDV */ + at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ERXO */ + at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ERX1 */ + at91_set_b_periph(AT91_PIO_PORTC, 16, 0); /* ERXER */ + at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ETXEN */ + at91_set_b_periph(AT91_PIO_PORTC, 18, 0); /* ETX0 */ + at91_set_b_periph(AT91_PIO_PORTC, 19, 0); /* ETX1 */ + at91_set_b_periph(AT91_PIO_PORTC, 31, 0); /* EMDIO */ + at91_set_b_periph(AT91_PIO_PORTC, 30, 0); /* EMDC */ + } + +#ifndef CONFIG_RMII + /* Only emac0 support MII */ + if (has_emac0()) { + at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* ECRS */ + at91_set_a_periph(AT91_PIO_PORTB, 17, 0); /* ECOL */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* ERX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* ERX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 15, 0); /* ERXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 11, 0); /* ETX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* ETX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 8, 0); /* ETXER */ + } +#endif +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/clock.c b/arch/arm/mach-at91/arm926ejs/clock.c new file mode 100644 index 0000000000..f363982d03 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/clock.c @@ -0,0 +1,249 @@ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static unsigned long at91_css_to_rate(unsigned long css) +{ + switch (css) { + case AT91_PMC_MCKR_CSS_SLOW: + return CONFIG_SYS_AT91_SLOW_CLOCK; + case AT91_PMC_MCKR_CSS_MAIN: + return gd->arch.main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return gd->arch.plla_rate_hz; + case AT91_PMC_MCKR_CSS_PLLB: + return gd->arch.pllb_rate_hz; + } + + return 0; +} + +#ifdef CONFIG_USB_ATMEL +static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq) +{ + unsigned i, div = 0, mul = 0, diff = 1 << 30; + unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + + /* PLL output max 240 MHz (or 180 MHz per errata) */ + if (out_freq > 240000000) + goto fail; + + for (i = 1; i < 256; i++) { + int diff1; + unsigned input, mul1; + + /* + * PLL input between 1MHz and 32MHz per spec, but lower + * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. + */ + input = main_freq / i; +#if defined(CONFIG_AT91SAM9G20) + if (input < 2000000) + continue; +#endif + if (input < 100000) + continue; + if (input > 32000000) + continue; + + mul1 = out_freq / input; +#if defined(CONFIG_AT91SAM9G20) + if (mul > 63) + continue; +#endif + if (mul1 > 2048) + continue; + if (mul1 < 2) + goto fail; + + diff1 = out_freq - input * mul1; + if (diff1 < 0) + diff1 = -diff1; + if (diff > diff1) { + diff = diff1; + div = i; + mul = mul1; + if (diff == 0) + break; + } + } + if (i == 256 && diff > (out_freq >> 5)) + goto fail; + return ret | ((mul - 1) << 16) | div; +fail: + return 0; +} +#endif + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 16) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK + unsigned tmp; + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(&pmc->mcfr); + } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); + tmp &= AT91_PMC_MCFR_MAINF_MASK; + main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); + } +#endif + gd->arch.main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + +#ifdef CONFIG_USB_ATMEL + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | + AT91_PMC_PLLBR_USBDIV_2; + gd->arch.pllb_rate_hz = at91_pll_rate(main_clock, + gd->arch.at91_pllb_usb_init); +#endif + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(&pmc->mckr); +#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ + || defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) + /* plla divisor by 2 */ + gd->arch.plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12)); +#endif + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; + + freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */ +#if defined(CONFIG_AT91SAM9G20) + /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ + gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ? + freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq; + if (mckr & AT91_PMC_MCKR_MDIV_MASK) + freq /= 2; /* processor clock division */ +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \ + || defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) + /* mdiv <==> divisor + * 0 <==> 1 + * 1 <==> 2 + * 2 <==> 4 + * 3 <==> 3 + */ + gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) == + (AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4) + ? freq / 3 + : freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +#else + gd->arch.mck_rate_hz = freq / + (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8)); +#endif + gd->arch.cpu_clk_rate_hz = freq; + + return 0; +} + +#if !defined(AT91_PLL_LOCK_TIMEOUT) +#define AT91_PLL_LOCK_TIMEOUT 1000000 +#endif + +void at91_plla_init(u32 pllar) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + int timeout = AT91_PLL_LOCK_TIMEOUT; + + writel(pllar, &pmc->pllar); + while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) { + timeout--; + if (timeout == 0) + break; + } +} +void at91_pllb_init(u32 pllbr) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + int timeout = AT91_PLL_LOCK_TIMEOUT; + + writel(pllbr, &pmc->pllbr); + while (!(readl(&pmc->sr) & (AT91_PMC_LOCKB | AT91_PMC_MCKRDY))) { + timeout--; + if (timeout == 0) + break; + } +} + +void at91_mck_init(u32 mckr) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + int timeout = AT91_PLL_LOCK_TIMEOUT; + u32 tmp; + + tmp = readl(&pmc->mckr); + tmp &= ~(AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_MASK | + AT91_PMC_MCKR_CSS_MASK); + tmp |= mckr & (AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_MASK | + AT91_PMC_MCKR_CSS_MASK); + writel(tmp, &pmc->mckr); + + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) { + timeout--; + if (timeout == 0) + break; + } +} + +void at91_periph_clk_enable(int id) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + writel(1 << id, &pmc->pcer); +} diff --git a/arch/arm/mach-at91/arm926ejs/cpu.c b/arch/arm/mach-at91/arm926ejs/cpu.c new file mode 100644 index 0000000000..da1d35907e --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/cpu.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +int arch_cpu_init(void) +{ + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} + +void arch_preboot_os(void) +{ + ulong cpiv; + at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; + + cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir)); + + /* + * Disable PITC + * Add 0x1000 to current counter to stop it faster + * without waiting for wrapping back to 0 + */ + writel(cpiv + 0x1000, &pit->mr); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU: %s\n", ATMEL_CPU_NAME); + printf("Crystal frequency: %8s MHz\n", + strmhz(buf, get_main_clk_rate())); + printf("CPU clock : %8s MHz\n", + strmhz(buf, get_cpu_clk_rate())); + printf("Master clock : %8s MHz\n", + strmhz(buf, get_mck_clk_rate())); + + return 0; +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/eflash.c b/arch/arm/mach-at91/arm926ejs/eflash.c new file mode 100644 index 0000000000..3f39264289 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/eflash.c @@ -0,0 +1,254 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * this driver supports the enhanced embedded flash in the Atmel + * AT91SAM9XE devices with the following geometry: + * + * AT91SAM9XE128: 1 plane of 8 regions of 32 pages (total 256 pages) + * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total 512 pages) + * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages) + * (the exact geometry is read from the flash at runtime, so any + * future devices should already be covered) + * + * Regions can be write/erase protected. + * Whole (!) pages can be individually written with erase on the fly. + * Writing partial pages will corrupt the rest of the page. + * + * The flash is presented to u-boot with each region being a sector, + * having the following effects: + * Each sector can be hardware protected (protect on/off). + * Each page in a sector can be rewritten anytime. + * Since pages are erased when written, the "erase" does nothing. + * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected + * by u-Boot commands. + * + * Note: Redundant environment will not work in this flash since + * it does use partial page writes. Make sure the environment spans + * whole pages! + */ + +/* + * optional TODOs (nice to have features): + * + * make the driver coexist with other NOR flash drivers + * (use an index into flash_info[], requires work + * in those other drivers, too) + * Make the erase command fill the sectors with 0xff + * (if the flashes grow larger in the future and + * someone puts a jffs2 into them) + * do a read-modify-write for partially programmed pages + */ +#include +#include +#include +#include +#include +#include + +/* checks to detect configuration errors */ +#if CONFIG_SYS_MAX_FLASH_BANKS!=1 +#error eflash: this driver can only handle 1 bank +#endif + +/* global structure */ +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; +static u32 pagesize; + +unsigned long flash_init (void) +{ + at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; + at91_dbu_t *dbu = (at91_dbu_t *) ATMEL_BASE_DBGU; + u32 id, size, nplanes, planesize, nlocks; + u32 addr, i, tmp=0; + + debug("eflash: init\n"); + + flash_info[0].flash_id = FLASH_UNKNOWN; + + /* check if its an AT91ARM9XE SoC */ + if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) { + puts("eflash: not an AT91SAM9XE\n"); + return 0; + } + + /* now query the eflash for its structure */ + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr); + while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) + ; + id = readl(&eefc->frr); /* word 0 */ + size = readl(&eefc->frr); /* word 1 */ + pagesize = readl(&eefc->frr); /* word 2 */ + nplanes = readl(&eefc->frr); /* word 3 */ + planesize = readl(&eefc->frr); /* word 4 */ + debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n", + id, size, pagesize, nplanes, planesize); + for (i=1; ifrr); /* words 5..4+nplanes-1 */ + }; + nlocks = readl(&eefc->frr); /* word 4+nplanes */ + debug("nlocks=%u\n", nlocks); + /* since we are going to use the lock regions as sectors, check count */ + if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) { + printf("eflash: number of lock regions(%u) "\ + "> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n", + nlocks); + nlocks = CONFIG_SYS_MAX_FLASH_SECT; + } + flash_info[0].size = size; + flash_info[0].sector_count = nlocks; + flash_info[0].flash_id = id; + + addr = ATMEL_BASE_FLASH; + for (i=0; ifrr); /* words 4+nplanes+1.. */ + flash_info[0].start[i] = addr; + flash_info[0].protect[i] = 0; + addr += tmp; + }; + + /* now read the protection information for all regions */ + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); + while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) + ; + for (i=0; ifrr); + flash_info[0].protect[i] = (tmp >> (i%32)) & 1; +#if defined(CONFIG_EFLASH_PROTSECTORS) + if (i < CONFIG_EFLASH_PROTSECTORS) + flash_info[0].protect[i] = 1; +#endif + } + + return size; +} + +void flash_print_info (flash_info_t *info) +{ + int i; + + puts("AT91SAM9XE embedded flash\n Size: "); + print_size(info->size, " in "); + printf("%d Sectors\n", info->sector_count); + + printf(" Sector Start Addresses:"); + for (i=0; isector_count; ++i) { + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +int flash_real_protect (flash_info_t *info, long sector, int prot) +{ + at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; + u32 pagenum = (info->start[sector]-ATMEL_BASE_FLASH)/pagesize; + u32 i, tmp=0; + + debug("protect sector=%ld prot=%d\n", sector, prot); + +#if defined(CONFIG_EFLASH_PROTSECTORS) + if (sector < CONFIG_EFLASH_PROTSECTORS) { + if (!prot) { + printf("eflash: sector %lu cannot be unprotected\n", + sector); + } + return 1; /* return anyway, caller does not care for result */ + } +#endif + if (prot) { + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB | + (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); + } else { + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB | + (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); + } + while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) + ; + /* now re-read the protection information for all regions */ + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr); + while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) + ; + for (i=0; isector_count; i++) { + if (i%32 == 0) + tmp = readl(&eefc->frr); + info->protect[i] = (tmp >> (i%32)) & 1; + } + return 0; +} + +static u32 erase_write_page (u32 pagenum) +{ + at91_eefc_t *eefc = (at91_eefc_t *) ATMEL_BASE_EEFC; + + debug("erase+write page=%u\n", pagenum); + + /* give erase and write page command */ + writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP | + (pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr); + while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0) + ; + /* return status */ + return readl(&eefc->fsr) + & (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE); +} + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + debug("erase first=%d last=%d\n", s_first, s_last); + puts("this flash does not need and support erasing!\n"); + return 0; +} + +/* + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + u32 pagenum; + u32 *src32, *dst32; + u32 i; + + debug("write src=%08lx addr=%08lx cnt=%lx\n", + (ulong)src, addr, cnt); + + /* REQUIRE addr to be on a page start, abort if not */ + if (addr % pagesize) { + printf ("eflash: start %08lx is not on page start\n"\ + " write aborted\n", addr); + return 1; + } + + /* now start copying data */ + pagenum = (addr-ATMEL_BASE_FLASH)/pagesize; + src32 = (u32 *) src; + dst32 = (u32 *) addr; + while (cnt > 0) { + i = pagesize / 4; + /* fill page buffer */ + while (i--) + *dst32++ = *src32++; + /* write page */ + if (erase_write_page(pagenum)) + return 1; + pagenum++; + if (cnt > pagesize) + cnt -= pagesize; + else + cnt = 0; + } + return 0; +} diff --git a/arch/arm/mach-at91/arm926ejs/led.c b/arch/arm/mach-at91/arm926ejs/led.c new file mode 100644 index 0000000000..b8d5c785df --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/led.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +#ifdef CONFIG_RED_LED +void red_led_on(void) +{ + gpio_set_value(CONFIG_RED_LED, 1); +} + +void red_led_off(void) +{ + gpio_set_value(CONFIG_RED_LED, 0); +} +#endif + +#ifdef CONFIG_GREEN_LED +void green_led_on(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 0); +} + +void green_led_off(void) +{ + gpio_set_value(CONFIG_GREEN_LED, 1); +} +#endif + +#ifdef CONFIG_YELLOW_LED +void yellow_led_on(void) +{ + gpio_set_value(CONFIG_YELLOW_LED, 0); +} + +void yellow_led_off(void) +{ + gpio_set_value(CONFIG_YELLOW_LED, 1); +} +#endif diff --git a/arch/arm/mach-at91/arm926ejs/lowlevel_init.S b/arch/arm/mach-at91/arm926ejs/lowlevel_init.S new file mode 100644 index 0000000000..a9ec81a75c --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/lowlevel_init.S @@ -0,0 +1,246 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Copyright (C) 2008 Ronetix Ilko Iliev (www.ronetix.at) + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ATMEL_LEGACY +#include +#endif +#ifndef CONFIG_SYS_MATRIX_EBICSA_VAL +#define CONFIG_SYS_MATRIX_EBICSA_VAL CONFIG_SYS_MATRIX_EBI0CSA_VAL +#endif + +.globl lowlevel_init +.type lowlevel_init,function +lowlevel_init: + +POS1: + adr r5, POS1 /* r5 = POS1 run time */ + ldr r0, =POS1 /* r0 = POS1 compile */ + sub r5, r5, r0 /* r0 = CONFIG_SYS_TEXT_BASE-1 */ + + /* memory control configuration 1 */ + ldr r0, =SMRDATA + ldr r2, =SMRDATA1 + add r0, r0, r5 + add r2, r2, r5 +0: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 0b + +/* ---------------------------------------------------------------------------- + * PMC Init Step 1. + * ---------------------------------------------------------------------------- + * - Check if the PLL is already initialized + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + ldr r0, [r1] + and r0, r0, #3 + cmp r0, #0 + bne PLL_setup_end + +/* --------------------------------------------------------------------------- + * - Enable the Main Oscillator + * --------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MOR) + ldr r2, =(AT91_ASM_PMC_SR) + /* Main oscillator Enable register PMC_MOR: */ + ldr r0, =CONFIG_SYS_MOR_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Main Oscillator is enabled */ + mov r4, #AT91_PMC_IXR_MOSCS +MOSCS_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MOSCS + bne MOSCS_Loop + +/* ---------------------------------------------------------------------------- + * PMC Init Step 2. + * ---------------------------------------------------------------------------- + * Setup PLLA + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_PLLAR) + ldr r0, =CONFIG_SYS_PLLAR_VAL + str r0, [r1] + + /* Reading the PMC Status register to detect when the PLLA is locked */ + mov r4, #AT91_PMC_IXR_LOCKA +MOSCS_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_LOCKA + bne MOSCS_Loop1 + +/* ---------------------------------------------------------------------------- + * PMC Init Step 3. + * ---------------------------------------------------------------------------- + * - Switch on the Main Oscillator + * ---------------------------------------------------------------------------- + */ + ldr r1, =(AT91_ASM_PMC_MCKR) + + /* -Master Clock Controller register PMC_MCKR */ + ldr r0, =CONFIG_SYS_MCKR1_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop + + ldr r0, =CONFIG_SYS_MCKR2_VAL + str r0, [r1] + + /* Reading the PMC Status to detect when the Master clock is ready */ + mov r4, #AT91_PMC_IXR_MCKRDY +MCKRDY_Loop1: + ldr r3, [r2] + and r3, r4, r3 + cmp r3, #AT91_PMC_IXR_MCKRDY + bne MCKRDY_Loop1 +PLL_setup_end: + +/* ---------------------------------------------------------------------------- + * - memory control configuration 2 + * ---------------------------------------------------------------------------- + */ + ldr r0, =(AT91_ASM_SDRAMC_TR) + ldr r1, [r0] + cmp r1, #0 + bne SDRAM_setup_end + + ldr r0, =SMRDATA1 + ldr r2, =SMRDATA2 + add r0, r0, r5 + add r2, r2, r5 +2: + /* the address */ + ldr r1, [r0], #4 + /* the value */ + ldr r3, [r0], #4 + str r3, [r1] + cmp r2, r0 + bne 2b + +SDRAM_setup_end: + /* everything is fine now */ + mov pc, lr + + .ltorg + +SMRDATA: + .word AT91_ASM_WDT_MR + .word CONFIG_SYS_WDTC_WDMR_VAL + /* configure PIOx as EBI0 D[16-31] */ +#if defined(CONFIG_AT91SAM9263) + .word AT91_ASM_PIOD_PDR + .word CONFIG_SYS_PIOD_PDR_VAL1 + .word AT91_ASM_PIOD_PUDR + .word CONFIG_SYS_PIOD_PPUDR_VAL + .word AT91_ASM_PIOD_ASR + .word CONFIG_SYS_PIOD_PPUDR_VAL +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \ + || defined(CONFIG_AT91SAM9G20) + .word AT91_ASM_PIOC_PDR + .word CONFIG_SYS_PIOC_PDR_VAL1 + .word AT91_ASM_PIOC_PUDR + .word CONFIG_SYS_PIOC_PPUDR_VAL +#endif + .word AT91_ASM_MATRIX_CSA0 + .word CONFIG_SYS_MATRIX_EBICSA_VAL + + /* flash */ + .word AT91_ASM_SMC_MODE0 + .word CONFIG_SYS_SMC0_MODE0_VAL + + .word AT91_ASM_SMC_CYCLE0 + .word CONFIG_SYS_SMC0_CYCLE0_VAL + + .word AT91_ASM_SMC_PULSE0 + .word CONFIG_SYS_SMC0_PULSE0_VAL + + .word AT91_ASM_SMC_SETUP0 + .word CONFIG_SYS_SMC0_SETUP0_VAL + +SMRDATA1: + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL1 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL1 + .word AT91_ASM_SDRAMC_CR + .word CONFIG_SYS_SDRC_CR_VAL + .word AT91_ASM_SDRAMC_MDR + .word CONFIG_SYS_SDRC_MDR_VAL + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL1 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL3 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL4 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL5 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL6 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL7 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL8 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL9 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL4 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL10 + .word AT91_ASM_SDRAMC_MR + .word CONFIG_SYS_SDRC_MR_VAL5 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL11 + .word AT91_ASM_SDRAMC_TR + .word CONFIG_SYS_SDRC_TR_VAL2 + .word CONFIG_SYS_SDRAM_BASE + .word CONFIG_SYS_SDRAM_VAL12 + /* User reset enable*/ + .word AT91_ASM_RSTC_MR + .word CONFIG_SYS_RSTC_RMR_VAL +#ifdef CONFIG_SYS_MATRIX_MCFG_REMAP + /* MATRIX_MCFG - REMAP all masters */ + .word AT91_ASM_MATRIX_MCFG + .word 0x1FF +#endif +SMRDATA2: + .word 0 diff --git a/arch/arm/mach-at91/arm926ejs/reset.c b/arch/arm/mach-at91/arm926ejs/reset.c new file mode 100644 index 0000000000..e67f47bd04 --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/reset.c @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* Reset the cpu by telling the reset controller to do so */ +void reset_cpu(ulong ignored) +{ + at91_rstc_t *rstc = (at91_rstc_t *) ATMEL_BASE_RSTC; + + writel(AT91_RSTC_KEY + | AT91_RSTC_CR_PROCRST /* Processor Reset */ + | AT91_RSTC_CR_PERRST /* Peripheral Reset */ +#ifdef CONFIG_AT91RESET_EXTRST + | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */ +#endif + , &rstc->cr); + /* never reached */ + while (1) + ; +} diff --git a/arch/arm/mach-at91/arm926ejs/timer.c b/arch/arm/mach-at91/arm926ejs/timer.c new file mode 100644 index 0000000000..b0b7fb93fb --- /dev/null +++ b/arch/arm/mach-at91/arm926ejs/timer.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* + * We're using the AT91CAP9/SAM9 PITC in 32 bit mode, by + * setting the 20 bit counter period to its maximum (0xfffff). + * (See the relevant data sheets to understand that this really works) + * + * We do also mimic the typical powerpc way of incrementing + * two 32 bit registers called tbl and tbu. + * + * Those registers increment at 1/16 the main clock rate. + */ + +#define TIMER_LOAD_VAL 0xfffff + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, gd->arch.timer_rate_hz); + + return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ + usec *= gd->arch.timer_rate_hz; + do_div(usec, 1000000); + + return usec; +} + +/* + * Use the PITC in full 32 bit incrementing mode + */ +int timer_init(void) +{ + at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; + at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; + + /* Enable PITC Clock */ + writel(1 << ATMEL_ID_SYS, &pmc->pcer); + + /* Enable PITC */ + writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); + + gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16; + gd->arch.tbu = gd->arch.tbl = 0; + + return 0; +} + +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) +{ + at91_pit_t *pit = (at91_pit_t *) ATMEL_BASE_PIT; + + ulong now = readl(&pit->piir); + + /* increment tbu if tbl has rolled over */ + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + +void __udelay(unsigned long usec) +{ + unsigned long long start; + ulong tmo; + + start = get_ticks(); /* get current timestamp */ + tmo = usec_to_tick(usec); /* convert usecs to ticks */ + while ((get_ticks() - start) < tmo) + ; /* loop till time has passed */ +} + +/* + * get_timer(base) can be used to check for timeouts or + * to measure elasped time relative to an event: + * + * ulong start_time = get_timer(0) sets start_time to the current + * time value. + * get_timer(start_time) returns the time elapsed since then. + * + * The time is used in CONFIG_SYS_HZ units! + */ +ulong get_timer(ulong base) +{ + return tick_to_time(get_ticks()) - base; +} + +/* + * Return the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +} diff --git a/arch/arm/mach-at91/armv7/Makefile b/arch/arm/mach-at91/armv7/Makefile new file mode 100644 index 0000000000..f4f35a4bc1 --- /dev/null +++ b/arch/arm/mach-at91/armv7/Makefile @@ -0,0 +1,16 @@ +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2013 +# Bo Shen +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SAMA5D3) += sama5d3_devices.o +obj-$(CONFIG_SAMA5D4) += sama5d4_devices.o +obj-y += clock.o +obj-y += cpu.o +obj-y += reset.o +obj-y += timer.o diff --git a/arch/arm/mach-at91/armv7/clock.c b/arch/arm/mach-at91/armv7/clock.c new file mode 100644 index 0000000000..0bf453eff5 --- /dev/null +++ b/arch/arm/mach-at91/armv7/clock.c @@ -0,0 +1,175 @@ +/* + * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c] + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2013 Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static unsigned long at91_css_to_rate(unsigned long css) +{ + switch (css) { + case AT91_PMC_MCKR_CSS_SLOW: + return CONFIG_SYS_AT91_SLOW_CLOCK; + case AT91_PMC_MCKR_CSS_MAIN: + return gd->arch.main_clk_rate_hz; + case AT91_PMC_MCKR_CSS_PLLA: + return gd->arch.plla_rate_hz; + } + + return 0; +} + +static u32 at91_pll_rate(u32 freq, u32 reg) +{ + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 18) & 0x7f; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else { + freq = 0; + } + + return freq; +} + +int at91_clock_init(unsigned long main_clock) +{ + unsigned freq, mckr; + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK + unsigned tmp; + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = readl(&pmc->mcfr); + } while (!(tmp & AT91_PMC_MCFR_MAINRDY)); + tmp &= AT91_PMC_MCFR_MAINF_MASK; + main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16); + } +#endif + gd->arch.main_clk_rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar)); + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = readl(&pmc->mckr); + + /* plla divisor by 2 */ + if (mckr & (1 << 12)) + gd->arch.plla_rate_hz >>= 1; + + gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK); + freq = gd->arch.mck_rate_hz; + + /* prescale */ + freq >>= mckr & AT91_PMC_MCKR_PRES_MASK; + + switch (mckr & AT91_PMC_MCKR_MDIV_MASK) { + case AT91_PMC_MCKR_MDIV_2: + gd->arch.mck_rate_hz = freq / 2; + break; + case AT91_PMC_MCKR_MDIV_3: + gd->arch.mck_rate_hz = freq / 3; + break; + case AT91_PMC_MCKR_MDIV_4: + gd->arch.mck_rate_hz = freq / 4; + break; + default: + break; + } + + gd->arch.cpu_clk_rate_hz = freq; + + return 0; +} + +void at91_plla_init(u32 pllar) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + writel(pllar, &pmc->pllar); + while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY))) + ; +} + +void at91_mck_init(u32 mckr) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = readl(&pmc->mckr); + tmp &= ~(AT91_PMC_MCKR_CSS_MASK | + AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp &= ~AT91_PMC_MCKR_H32MXDIV; +#endif + + tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK | + AT91_PMC_MCKR_PRES_MASK | + AT91_PMC_MCKR_MDIV_MASK | + AT91_PMC_MCKR_PLLADIV_2); +#ifdef CPU_HAS_H32MXDIV + tmp |= mckr & AT91_PMC_MCKR_H32MXDIV; +#endif + + writel(tmp, &pmc->mckr); + + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + ; +} + +void at91_periph_clk_enable(int id) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 regval; + + if (id > AT91_PMC_PCR_PID_MASK) + return; + + regval = AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD_WRITE | id; + + writel(regval, &pmc->pcr); +} + +void at91_periph_clk_disable(int id) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 regval; + + if (id > AT91_PMC_PCR_PID_MASK) + return; + + regval = AT91_PMC_PCR_CMD_WRITE | id; + + writel(regval, &pmc->pcr); +} diff --git a/arch/arm/mach-at91/armv7/cpu.c b/arch/arm/mach-at91/armv7/cpu.c new file mode 100644 index 0000000000..8d86f97e3d --- /dev/null +++ b/arch/arm/mach-at91/armv7/cpu.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD + * (C) Copyright 2013 + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_AT91_MAIN_CLOCK +#define CONFIG_SYS_AT91_MAIN_CLOCK 0 +#endif + +int arch_cpu_init(void) +{ + return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); +} + +void arch_preboot_os(void) +{ + ulong cpiv; + at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; + + cpiv = AT91_PIT_MR_PIV_MASK(readl(&pit->piir)); + + /* + * Disable PITC + * Add 0x1000 to current counter to stop it faster + * without waiting for wrapping back to 0 + */ + writel(cpiv + 0x1000, &pit->mr); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU: %s\n", get_cpu_name()); + printf("Crystal frequency: %8s MHz\n", + strmhz(buf, get_main_clk_rate())); + printf("CPU clock : %8s MHz\n", + strmhz(buf, get_cpu_clk_rate())); + printf("Master clock : %8s MHz\n", + strmhz(buf, get_mck_clk_rate())); + + return 0; +} +#endif + +void enable_caches(void) +{ + icache_enable(); + dcache_enable(); +} + +unsigned int get_chip_id(void) +{ + return readl(ATMEL_BASE_DBGU + AT91_DBU_CIDR) & ~AT91_DBU_CIDR_MASK; +} + +unsigned int get_extension_chip_id(void) +{ + return readl(ATMEL_BASE_DBGU + AT91_DBU_EXID); +} diff --git a/arch/arm/mach-at91/armv7/reset.c b/arch/arm/mach-at91/armv7/reset.c new file mode 100644 index 0000000000..b30e79b60a --- /dev/null +++ b/arch/arm/mach-at91/armv7/reset.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2013 + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* Reset the cpu by telling the reset controller to do so */ +void reset_cpu(ulong ignored) +{ + at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; + + writel(AT91_RSTC_KEY + | AT91_RSTC_CR_PROCRST /* Processor Reset */ + | AT91_RSTC_CR_PERRST /* Peripheral Reset */ +#ifdef CONFIG_AT91RESET_EXTRST + | AT91_RSTC_CR_EXTRST /* External Reset (assert nRST pin) */ +#endif + , &rstc->cr); + /* never reached */ + do { } while (1); +} diff --git a/arch/arm/mach-at91/armv7/sama5d3_devices.c b/arch/arm/mach-at91/armv7/sama5d3_devices.c new file mode 100644 index 0000000000..78ecfc882a --- /dev/null +++ b/arch/arm/mach-at91/armv7/sama5d3_devices.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2012-2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +unsigned int has_emac() +{ + return cpu_is_sama5d31() || cpu_is_sama5d35() || cpu_is_sama5d36(); +} + +unsigned int has_gmac() +{ + return !cpu_is_sama5d31(); +} + +unsigned int has_lcdc() +{ + return !cpu_is_sama5d35(); +} + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_sama5d3()) + switch (extension_id) { + case ARCH_EXID_SAMA5D31: + return "SAMA5D31"; + case ARCH_EXID_SAMA5D33: + return "SAMA5D33"; + case ARCH_EXID_SAMA5D34: + return "SAMA5D34"; + case ARCH_EXID_SAMA5D35: + return "SAMA5D35"; + case ARCH_EXID_SAMA5D36: + return "SAMA5D36"; + default: + return "Unknown CPU type"; + } + else + return "Unknown CPU type"; +} + +void at91_serial0_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTD, 18, 1); /* TXD0 */ + at91_set_a_periph(AT91_PIO_PORTD, 17, 0); /* RXD0 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART0); +} + +void at91_serial1_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 29, 1); /* TXD1 */ + at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* RXD1 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART1); +} + +void at91_serial2_hw_init(void) +{ + at91_set_b_periph(AT91_PIO_PORTE, 26, 1); /* TXD2 */ + at91_set_b_periph(AT91_PIO_PORTE, 25, 0); /* RXD2 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_USART2); +} + +void at91_seriald_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 31, 1); /* DTXD */ + at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* DRXD */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_DBGU); +} + +#if defined(CONFIG_ATMEL_SPI) +void at91_spi0_hw_init(unsigned long cs_mask) +{ + at91_set_a_periph(AT91_PIO_PORTD, 10, 0); /* SPI0_MISO */ + at91_set_a_periph(AT91_PIO_PORTD, 11, 0); /* SPI0_MOSI */ + at91_set_a_periph(AT91_PIO_PORTD, 12, 0); /* SPI0_SPCK */ + + if (cs_mask & (1 << 0)) + at91_set_pio_output(AT91_PIO_PORTD, 13, 1); + if (cs_mask & (1 << 1)) + at91_set_pio_output(AT91_PIO_PORTD, 14, 1); + if (cs_mask & (1 << 2)) + at91_set_pio_output(AT91_PIO_PORTD, 15, 1); + if (cs_mask & (1 << 3)) + at91_set_pio_output(AT91_PIO_PORTD, 16, 1); + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_SPI0); +} +#endif + +#ifdef CONFIG_GENERIC_ATMEL_MCI +void at91_mci_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTD, 0, 0); /* MCI0 CMD */ + at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* MCI0 DA0 */ + at91_set_a_periph(AT91_PIO_PORTD, 2, 0); /* MCI0 DA1 */ + at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* MCI0 DA2 */ + at91_set_a_periph(AT91_PIO_PORTD, 4, 0); /* MCI0 DA3 */ +#ifdef CONFIG_ATMEL_MCI_8BIT + at91_set_a_periph(AT91_PIO_PORTD, 5, 0); /* MCI0 DA4 */ + at91_set_a_periph(AT91_PIO_PORTD, 6, 0); /* MCI0 DA5 */ + at91_set_a_periph(AT91_PIO_PORTD, 7, 0); /* MCI0 DA6 */ + at91_set_a_periph(AT91_PIO_PORTD, 8, 0); /* MCI0 DA7 */ +#endif + at91_set_a_periph(AT91_PIO_PORTD, 9, 0); /* MCI0 CLK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_MCI0); +} +#endif + +#ifdef CONFIG_MACB +void at91_macb_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTC, 7, 0); /* ETXCK_EREFCK */ + at91_set_a_periph(AT91_PIO_PORTC, 5, 0); /* ERXDV */ + at91_set_a_periph(AT91_PIO_PORTC, 2, 0); /* ERX0 */ + at91_set_a_periph(AT91_PIO_PORTC, 3, 0); /* ERX1 */ + at91_set_a_periph(AT91_PIO_PORTC, 6, 0); /* ERXER */ + at91_set_a_periph(AT91_PIO_PORTC, 4, 0); /* ETXEN */ + at91_set_a_periph(AT91_PIO_PORTC, 0, 0); /* ETX0 */ + at91_set_a_periph(AT91_PIO_PORTC, 1, 0); /* ETX1 */ + at91_set_a_periph(AT91_PIO_PORTC, 9, 0); /* EMDIO */ + at91_set_a_periph(AT91_PIO_PORTC, 8, 0); /* EMDC */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_EMAC); +} + +void at91_gmac_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTB, 0, 0); /* GTX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 1, 0); /* GTX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 2, 0); /* GTX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 3, 0); /* GTX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 4, 0); /* GRX0 */ + at91_set_a_periph(AT91_PIO_PORTB, 5, 0); /* GRX1 */ + at91_set_a_periph(AT91_PIO_PORTB, 6, 0); /* GRX2 */ + at91_set_a_periph(AT91_PIO_PORTB, 7, 0); /* GRX3 */ + at91_set_a_periph(AT91_PIO_PORTB, 8, 0); /* GTXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 9, 0); /* GTXEN */ + + at91_set_a_periph(AT91_PIO_PORTB, 11, 0); /* GRXCK */ + at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* GRXER */ + + at91_set_a_periph(AT91_PIO_PORTB, 16, 0); /* GMDC */ + at91_set_a_periph(AT91_PIO_PORTB, 17, 0); /* GMDIO */ + at91_set_a_periph(AT91_PIO_PORTB, 18, 0); /* G125CK */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_GMAC); +} +#endif + +#ifdef CONFIG_LCD +void at91_lcd_hw_init(void) +{ + at91_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */ + at91_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */ + at91_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */ + at91_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */ + at91_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */ + at91_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */ + + /* The lower 16-bit of LCD only available on Port A */ + at91_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */ + at91_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */ + at91_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */ + at91_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */ + at91_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */ + at91_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */ + at91_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */ + at91_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */ + at91_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD8 */ + at91_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD9 */ + at91_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */ + at91_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */ + at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */ + at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */ + at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */ + at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */ + + /* Enable clock */ + at91_periph_clk_enable(ATMEL_ID_LCDC); +} +#endif + +#ifdef CONFIG_USB_GADGET_ATMEL_USBA +void at91_udp_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + /* Enable UPLL clock */ + writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr); + /* Enable UDPHS clock */ + at91_periph_clk_enable(ATMEL_ID_UDPHS); +} +#endif diff --git a/arch/arm/mach-at91/armv7/sama5d4_devices.c b/arch/arm/mach-at91/armv7/sama5d4_devices.c new file mode 100644 index 0000000000..ef39cb7e08 --- /dev/null +++ b/arch/arm/mach-at91/armv7/sama5d4_devices.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *get_cpu_name() +{ + unsigned int extension_id = get_extension_chip_id(); + + if (cpu_is_sama5d4()) + switch (extension_id) { + case ARCH_EXID_SAMA5D41: + return "SAMA5D41"; + case ARCH_EXID_SAMA5D42: + return "SAMA5D42"; + case ARCH_EXID_SAMA5D43: + return "SAMA5D43"; + case ARCH_EXID_SAMA5D44: + return "SAMA5D44"; + default: + return "Unknown CPU type"; + } + else + return "Unknown CPU type"; +} + +#ifdef CONFIG_USB_GADGET_ATMEL_USBA +void at91_udp_hw_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + /* Enable UPLL clock */ + writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr); + /* Enable UDPHS clock */ + at91_periph_clk_enable(ATMEL_ID_UDPHS); +} +#endif + +#ifdef CONFIG_SPL_BUILD +void matrix_init(void) +{ + struct atmel_matrix *h64mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX0; + struct atmel_matrix *h32mx = (struct atmel_matrix *)ATMEL_BASE_MATRIX1; + int i; + + /* Disable the write protect */ + writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); + writel(ATMEL_MATRIX_WPMR_WPKEY & ~ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); + + /* DDR port 1 ~ poart 7, slave number is: 4 ~ 10 */ + for (i = 4; i <= 10; i++) { + writel(0x000f0f0f, &h64mx->ssr[i]); + writel(0x0000ffff, &h64mx->sassr[i]); + writel(0x0000000f, &h64mx->srtsr[i]); + } + + /* CS3 */ + writel(0x00c0c0c0, &h32mx->ssr[3]); + writel(0xff000000, &h32mx->sassr[3]); + writel(0xff000000, &h32mx->srtsr[3]); + + /* NFC SRAM */ + writel(0x00010101, &h32mx->ssr[4]); + writel(0x00000001, &h32mx->sassr[4]); + writel(0x00000001, &h32mx->srtsr[4]); + + /* Enable the write protect */ + writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h64mx->wpmr); + writel(ATMEL_MATRIX_WPMR_WPKEY | ATMEL_MATRIX_WPMR_WPEN, &h32mx->wpmr); +} + +void redirect_int_from_saic_to_aic(void) +{ + struct atmel_sfr *sfr = (struct atmel_sfr *)ATMEL_BASE_SFR; + u32 key32; + + if (!(readl(&sfr->aicredir) & ATMEL_SFR_AICREDIR_NSAIC)) { + key32 = readl(&sfr->sn1) ^ ATMEL_SFR_AICREDIR_KEY; + writel((key32 | ATMEL_SFR_AICREDIR_NSAIC), &sfr->aicredir); + } +} +#endif diff --git a/arch/arm/mach-at91/armv7/timer.c b/arch/arm/mach-at91/armv7/timer.c new file mode 100644 index 0000000000..19bf80ba7e --- /dev/null +++ b/arch/arm/mach-at91/armv7/timer.c @@ -0,0 +1,124 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2013 + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_AT91FAMILY) +# error You need to define CONFIG_AT91FAMILY in your board config! +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* + * We're using the SAMA5D3x PITC in 32 bit mode, by + * setting the 20 bit counter period to its maximum (0xfffff). + * (See the relevant data sheets to understand that this really works) + * + * We do also mimic the typical powerpc way of incrementing + * two 32 bit registers called tbl and tbu. + * + * Those registers increment at 1/16 the main clock rate. + */ + +#define TIMER_LOAD_VAL 0xfffff + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, gd->arch.timer_rate_hz); + + return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ + usec *= gd->arch.timer_rate_hz; + do_div(usec, 1000000); + + return usec; +} + +/* + * Use the PITC in full 32 bit incrementing mode + */ +int timer_init(void) +{ + at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; + + /* Enable PITC Clock */ + at91_periph_clk_enable(ATMEL_ID_PIT); + + /* Enable PITC */ + writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr); + + gd->arch.timer_rate_hz = get_pit_clk_rate() / 16; + + gd->arch.tbu = 0; + gd->arch.tbl = 0; + + return 0; +} + +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) +{ + at91_pit_t *pit = (at91_pit_t *)ATMEL_BASE_PIT; + + ulong now = readl(&pit->piir); + + /* increment tbu if tbl has rolled over */ + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + +void __udelay(unsigned long usec) +{ + unsigned long long start; + ulong tmo; + + start = get_ticks(); /* get current timestamp */ + tmo = usec_to_tick(usec); /* convert usecs to ticks */ + while ((get_ticks() - start) < tmo) + ; /* loop till time has passed */ +} + +/* + * get_timer(base) can be used to check for timeouts or + * to measure elasped time relative to an event: + * + * ulong start_time = get_timer(0) sets start_time to the current + * time value. + * get_timer(start_time) returns the time elapsed since then. + * + * The time is used in CONFIG_SYS_HZ units! + */ +ulong get_timer(ulong base) +{ + return tick_to_time(get_ticks()) - base; +} + +/* + * Return the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +} diff --git a/arch/arm/mach-at91/config.mk b/arch/arm/mach-at91/config.mk new file mode 100644 index 0000000000..7168abbd58 --- /dev/null +++ b/arch/arm/mach-at91/config.mk @@ -0,0 +1,9 @@ +ifeq ($(CONFIG_CPU_ARM926EJS),y) +PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) +endif + +ifeq ($(CONFIG_CPU_V7),y) +ifndef CONFIG_SPL_BUILD +ALL-y += u-boot.img +endif +endif diff --git a/arch/arm/mach-at91/mpddrc.c b/arch/arm/mach-at91/mpddrc.c new file mode 100644 index 0000000000..beec13db8c --- /dev/null +++ b/arch/arm/mach-at91/mpddrc.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +static inline void atmel_mpddr_op(int mode, u32 ram_address) +{ + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; + + writel(mode, &mpddr->mr); + writel(0, ram_address); +} + +static int ddr2_decodtype_is_seq(u32 cr) +{ +#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) + if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED) + return 0; +#endif + return 1; +} + +int ddr2_init(const unsigned int ram_address, + const struct atmel_mpddr *mpddr_value) +{ + struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC; + u32 ba_off, cr; + + /* Compute bank offset according to NC in configuration register */ + ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; + if (ddr2_decodtype_is_seq(mpddr_value->cr)) + ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; + + ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; + + /* Program the memory device type into the memory device register */ + writel(mpddr_value->md, &mpddr->md); + + /* Program the configuration register */ + writel(mpddr_value->cr, &mpddr->cr); + + /* Program the timing register */ + writel(mpddr_value->tpr0, &mpddr->tpr0); + writel(mpddr_value->tpr1, &mpddr->tpr1); + writel(mpddr_value->tpr2, &mpddr->tpr2); + + /* Issue a NOP command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); + + /* A 200 us is provided to precede any signal toggle */ + udelay(200); + + /* Issue a NOP command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); + + /* Issue an extended mode register set(EMRS2) to choose operation */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x2 << ba_off)); + + /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x3 << ba_off)); + + /* + * Issue an extended mode register set(EMRS1) to enable DLL and + * program D.I.C (output driver impedance control) + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* Enable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr); + + /* A mode register set(MRS) cycle is issued to reset DLL */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); + + /* Issue an all banks precharge command */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); + + /* Two auto-refresh (CBR) cycles are provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); + + /* Disable DLL reset */ + cr = readl(&mpddr->cr); + writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr); + + /* A mode register set (MRS) cycle is issued to disable DLL reset */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); + + /* Set OCD calibration in default state */ + cr = readl(&mpddr->cr); + writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr); + + /* + * An extended mode register set (EMRS1) cycle is issued + * to OCD default value + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* OCD calibration mode exit */ + cr = readl(&mpddr->cr); + writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr); + + /* + * An extended mode register set (EMRS1) cycle is issued + * to enable OCD exit + */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, + ram_address + (0x1 << ba_off)); + + /* A nornal mode command is provided */ + atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address); + + /* Perform a write access to any DDR2-SDRAM address */ + writel(0, ram_address); + + /* Write the refresh rate */ + writel(mpddr_value->rtr, &mpddr->rtr); + + return 0; +} diff --git a/arch/arm/mach-at91/phy.c b/arch/arm/mach-at91/phy.c new file mode 100644 index 0000000000..2cba7169e4 --- /dev/null +++ b/arch/arm/mach-at91/phy.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * (C) Copyright 2012 + * Markus Hubig + * IMKO GmbH + * + * Copyright (C) 2013 DENX Software Engineering, hs@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +void at91_phy_reset(void) +{ + unsigned long erstl; + unsigned long start = get_timer(0); + unsigned long const timeout = 1000; /* 1000ms */ + at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC; + + erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK; + + /* + * Need to reset PHY -> 500ms reset + * Reset PHY by pulling the NRST line for 500ms to low. To do so + * disable user reset for low level on NRST pin and poll the NRST + * level in reset status register. + */ + writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) | + AT91_RSTC_MR_URSTEN, &rstc->mr); + + writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr); + + /* Wait for end of hardware reset */ + while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) { + /* avoid shutdown by watchdog */ + WATCHDOG_RESET(); + mdelay(10); + + /* timeout for not getting stuck in an endless loop */ + if (get_timer(start) >= timeout) { + puts("*** ERROR: Timeout waiting for PHY reset!\n"); + break; + } + }; + + /* Restore NRST value */ + writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr); +} diff --git a/arch/arm/mach-at91/sdram.c b/arch/arm/mach-at91/sdram.c new file mode 100644 index 0000000000..5758b066e4 --- /dev/null +++ b/arch/arm/mach-at91/sdram.c @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2014 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * Based on: + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +int sdramc_initialize(unsigned int sdram_address, const struct sdramc_reg *p) +{ + struct sdramc_reg *reg = (struct sdramc_reg *)ATMEL_BASE_SDRAMC; + unsigned int i; + + /* SDRAM feature must be in the configuration register */ + writel(p->cr, ®->cr); + + /* The SDRAM memory type must be set in the Memory Device Register */ + writel(p->mdr, ®->mdr); + + /* + * The minimum pause of 200 us is provided to precede any single + * toggle + */ + for (i = 0; i < 1000; i++) + ; + + /* A NOP command is issued to the SDRAM devices */ + writel(AT91_SDRAMC_MODE_NOP, ®->mr); + writel(0x00000000, sdram_address); + + /* An All Banks Precharge command is issued to the SDRAM devices */ + writel(AT91_SDRAMC_MODE_PRECHARGE, ®->mr); + writel(0x00000000, sdram_address); + + for (i = 0; i < 10000; i++) + ; + + /* Eight auto-refresh cycles are provided */ + for (i = 0; i < 8; i++) { + writel(AT91_SDRAMC_MODE_REFRESH, ®->mr); + writel(0x00000001 + i, sdram_address + 4 + 4 * i); + } + + /* + * A Mode Register set (MRS) cyscle is issued to program the + * SDRAM parameters(TCSR, PASR, DS) + */ + writel(AT91_SDRAMC_MODE_LMR, ®->mr); + writel(0xcafedede, sdram_address + 0x24); + + /* + * The application must go into Normal Mode, setting Mode + * to 0 in the Mode Register and perform a write access at + * any location in the SDRAM. + */ + writel(AT91_SDRAMC_MODE_NORMAL, ®->mr); + writel(0x00000000, sdram_address); /* Perform Normal mode */ + + /* + * Write the refresh rate into the count field in the SDRAMC + * Refresh Timer Rgister. + */ + writel(p->tr, ®->tr); + + return 0; +} diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c new file mode 100644 index 0000000000..aaa5eec2e6 --- /dev/null +++ b/arch/arm/mach-at91/spl.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_AT91SAM9_WATCHDOG) +void at91_disable_wdt(void) { } +#else +void at91_disable_wdt(void) +{ + struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; + + writel(AT91_WDT_MR_WDDIS, &wdt->mr); +} +#endif + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SYS_USE_MMC + return BOOT_DEVICE_MMC1; +#elif CONFIG_SYS_USE_NANDFLASH + return BOOT_DEVICE_NAND; +#elif CONFIG_SYS_USE_SERIALFLASH + return BOOT_DEVICE_SPI; +#endif + return BOOT_DEVICE_NONE; +} + +u32 spl_boot_mode(void) +{ + switch (spl_boot_device()) { +#ifdef CONFIG_SYS_USE_MMC + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_FS; + break; +#endif + case BOOT_DEVICE_NONE: + default: + hang(); + } +} diff --git a/arch/arm/mach-at91/spl_at91.c b/arch/arm/mach-at91/spl_at91.c new file mode 100644 index 0000000000..89f588be45 --- /dev/null +++ b/arch/arm/mach-at91/spl_at91.c @@ -0,0 +1,124 @@ +/* + * (C) Copyright 2014 DENX Software Engineering + * Heiko Schocher + * + * Based on: + * Copyright (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static void enable_ext_reset(void) +{ + struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC; + + writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN, &rstc->mr); +} + +void lowlevel_clock_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) { + /* Enable Main Oscillator */ + writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor); + + /* Wait until Main Oscillator is stable */ + while (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) + ; + } + + /* After stabilization, switch to Main Oscillator */ + if ((readl(&pmc->mckr) & AT91_PMC_CSS) == AT91_PMC_CSS_SLOW) { + unsigned long tmp; + + tmp = readl(&pmc->mckr); + tmp &= ~AT91_PMC_CSS; + tmp |= AT91_PMC_CSS_MAIN; + writel(tmp, &pmc->mckr); + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + ; + + tmp &= ~AT91_PMC_PRES; + tmp |= AT91_PMC_PRES_1; + writel(tmp, &pmc->mckr); + while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY)) + ; + } + + return; +} + +void __weak matrix_init(void) +{ +} + +void __weak at91_spl_board_init(void) +{ +} + +void spl_board_init(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + lowlevel_clock_init(); + at91_disable_wdt(); + + /* + * At this stage the main oscillator is supposed to be enabled + * PCK = MCK = MOSC + */ + writel(0x00, &pmc->pllicpr); + + /* Configure PLLA = MOSC * (PLL_MULA + 1) / PLL_DIVA */ + at91_plla_init(CONFIG_SYS_AT91_PLLA); + + /* PCK = PLLA = 2 * MCK */ + at91_mck_init(CONFIG_SYS_MCKR); + + /* Switch MCK on PLLA output */ + at91_mck_init(CONFIG_SYS_MCKR_CSS); + +#if defined(CONFIG_SYS_AT91_PLLB) + /* Configure PLLB */ + at91_pllb_init(CONFIG_SYS_AT91_PLLB); +#endif + + /* Enable External Reset */ + enable_ext_reset(); + + /* Initialize matrix */ + matrix_init(); + + gd->arch.mck_rate_hz = CONFIG_SYS_MASTER_CLOCK; + /* + * init timer long enough for using in spl. + */ + timer_init(); + + /* enable clocks for all PIOs */ + at91_periph_clk_enable(ATMEL_ID_PIOA); + at91_periph_clk_enable(ATMEL_ID_PIOB); + at91_periph_clk_enable(ATMEL_ID_PIOC); + /* init console */ + at91_seriald_hw_init(); + preloader_console_init(); + + mem_init(); + + at91_spl_board_init(); +} diff --git a/arch/arm/mach-at91/spl_atmel.c b/arch/arm/mach-at91/spl_atmel.c new file mode 100644 index 0000000000..9cc1111234 --- /dev/null +++ b/arch/arm/mach-at91/spl_atmel.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static void switch_to_main_crystal_osc(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + u32 tmp; + + tmp = readl(&pmc->mor); + tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff); + tmp &= ~AT91_PMC_MOR_KEY(0xff); + tmp |= AT91_PMC_MOR_MOSCEN; + tmp |= AT91_PMC_MOR_OSCOUNT(8); + tmp |= AT91_PMC_MOR_KEY(0x37); + writel(tmp, &pmc->mor); + while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS)) + ; + + tmp = readl(&pmc->mor); + tmp &= ~AT91_PMC_MOR_OSCBYPASS; + tmp &= ~AT91_PMC_MOR_KEY(0xff); + tmp |= AT91_PMC_MOR_KEY(0x37); + writel(tmp, &pmc->mor); + + tmp = readl(&pmc->mor); + tmp |= AT91_PMC_MOR_MOSCSEL; + tmp &= ~AT91_PMC_MOR_KEY(0xff); + tmp |= AT91_PMC_MOR_KEY(0x37); + writel(tmp, &pmc->mor); + + while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCSELS)) + ; + + /* Wait until MAINRDY field is set to make sure main clock is stable */ + while (!(readl(&pmc->mcfr) & AT91_PMC_MAINRDY)) + ; + +#ifndef CONFIG_SAMA5D4 + tmp = readl(&pmc->mor); + tmp &= ~AT91_PMC_MOR_MOSCRCEN; + tmp &= ~AT91_PMC_MOR_KEY(0xff); + tmp |= AT91_PMC_MOR_KEY(0x37); + writel(tmp, &pmc->mor); +#endif +} + +__weak void matrix_init(void) +{ + /* This only be used for sama5d4 soc now */ +} + +__weak void redirect_int_from_saic_to_aic(void) +{ + /* This only be used for sama5d4 soc now */ +} + +void s_init(void) +{ + switch_to_main_crystal_osc(); + + /* disable watchdog */ + at91_disable_wdt(); + + /* PMC configuration */ + at91_pmc_init(); + + at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); + + matrix_init(); + + redirect_int_from_saic_to_aic(); + + timer_init(); + + board_early_init_f(); + + preloader_console_init(); + + mem_init(); +} diff --git a/arch/arm/mach-at91/u-boot-spl.lds b/arch/arm/mach-at91/u-boot-spl.lds new file mode 100644 index 0000000000..eccca43a42 --- /dev/null +++ b/arch/arm/mach-at91/u-boot-spl.lds @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2010 + * Texas Instruments, + * Aneesh V + * + * (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } >.sram + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +} diff --git a/include/configs/sama5d3_xplained.h b/include/configs/sama5d3_xplained.h index 5a0ab284ab..5dab61d56d 100644 --- a/include/configs/sama5d3_xplained.h +++ b/include/configs/sama5d3_xplained.h @@ -227,7 +227,7 @@ #define CONFIG_SYS_MONITOR_LEN (512 << 10) #ifdef CONFIG_SYS_USE_MMC -#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#define CONFIG_SPL_LDSCRIPT arch/arm/mach-at91/u-boot-spl.lds #define CONFIG_SPL_MMC_SUPPORT #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h index cccc1edbb8..bd288beaeb 100644 --- a/include/configs/sama5d3xek.h +++ b/include/configs/sama5d3xek.h @@ -274,7 +274,7 @@ #define CONFIG_SYS_MONITOR_LEN (512 << 10) #ifdef CONFIG_SYS_USE_MMC -#define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds +#define CONFIG_SPL_LDSCRIPT arch/arm/mach-at91/u-boot-spl.lds #define CONFIG_SPL_MMC_SUPPORT #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x400 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x200 -- cgit From 09f455dca74973ef5e42311162c8dff7e83d44a2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:04 +0900 Subject: ARM: tegra: collect SoC sources into mach-tegra This commit moves files as follows: arch/arm/cpu/arm720t/tegra20/* -> arch/arm/mach-tegra/tegra20/* arch/arm/cpu/arm720t/tegra30/* -> arch/arm/mach-tegra/tegra30/* arch/arm/cpu/arm720t/tegra114/* -> arch/arm/mach-tegra/tegra114/* arch/arm/cpu/arm720t/tegra124* -> arch/arm/mach-tegra/tegra124/* arch/arm/cpu/arm720t/tegra-common/* -> arch/arm/mach-tegra/* arch/arm/cpu/armv7/tegra20/* -> arch/arm/mach-tegra/tegra20/* arch/arm/cpu/armv7/tegra30/* -> arch/arm/mach-tegra/tegra30/* arch/arm/cpu/armv7/tegra114/* -> arch/arm/mach-tegra/tegra114/* arch/arm/cpu/armv7/tegra124/* -> arch/arm/mach-tegra/tegra124/* arch/arm/cpu/armv7/tegra-common/* -> arch/arm/mach-tegra/* arch/arm/cpu/tegra20-common/* -> arch/arm/mach-tegra/tegra20/* arch/arm/cpu/tegra30-common/* -> arch/arm/mach-tegra/tegra30/* arch/arm/cpu/tegra114-common/* -> arch/arm/mach-tegra/tegra114/* arch/arm/cpu/tegra124-common/* -> arch/arm/mach-tegra/tegra124/* arch/arm/cpu/tegra-common/* -> arch/arm/mach-tegra/* Signed-off-by: Masahiro Yamada Tested-by: Simon Glass [ on nyan-big ] Cc: Stephen Warren Cc: Tom Warren --- MAINTAINERS | 4 +- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 2 + arch/arm/cpu/Makefile | 6 +- arch/arm/cpu/arm720t/Makefile | 6 - arch/arm/cpu/arm720t/tegra-common/Makefile | 11 - arch/arm/cpu/arm720t/tegra-common/cpu.c | 384 ---------- arch/arm/cpu/arm720t/tegra-common/cpu.h | 74 -- arch/arm/cpu/arm720t/tegra-common/spl.c | 49 -- arch/arm/cpu/arm720t/tegra114/Makefile | 21 - arch/arm/cpu/arm720t/tegra114/cpu.c | 310 -------- arch/arm/cpu/arm720t/tegra124/Makefile | 8 - arch/arm/cpu/arm720t/tegra124/cpu.c | 265 ------- arch/arm/cpu/arm720t/tegra20/Makefile | 10 - arch/arm/cpu/arm720t/tegra20/cpu.c | 70 -- arch/arm/cpu/arm720t/tegra30/Makefile | 20 - arch/arm/cpu/arm720t/tegra30/cpu.c | 183 ----- arch/arm/cpu/armv7/Makefile | 2 - arch/arm/cpu/armv7/tegra-common/Kconfig | 52 -- arch/arm/cpu/armv7/tegra-common/Makefile | 10 - arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c | 51 -- arch/arm/cpu/armv7/tegra114/Kconfig | 16 - arch/arm/cpu/armv7/tegra124/Kconfig | 30 - arch/arm/cpu/armv7/tegra20/Kconfig | 52 -- arch/arm/cpu/armv7/tegra20/Makefile | 11 - arch/arm/cpu/armv7/tegra20/display.c | 394 ----------- arch/arm/cpu/armv7/tegra20/pwm.c | 86 --- arch/arm/cpu/armv7/tegra30/Kconfig | 32 - arch/arm/cpu/tegra-common/Makefile | 19 - arch/arm/cpu/tegra-common/ap.c | 169 ----- arch/arm/cpu/tegra-common/board.c | 159 ----- arch/arm/cpu/tegra-common/cache.c | 46 -- arch/arm/cpu/tegra-common/clock.c | 669 ------------------ arch/arm/cpu/tegra-common/lowlevel_init.S | 26 - arch/arm/cpu/tegra-common/pinmux-common.c | 527 -------------- arch/arm/cpu/tegra-common/powergate.c | 102 --- arch/arm/cpu/tegra-common/sys_info.c | 31 - arch/arm/cpu/tegra-common/vpr.c | 35 - arch/arm/cpu/tegra-common/xusb-padctl.c | 39 -- arch/arm/cpu/tegra114-common/Makefile | 20 - arch/arm/cpu/tegra114-common/clock.c | 669 ------------------ arch/arm/cpu/tegra114-common/funcmux.c | 67 -- arch/arm/cpu/tegra114-common/pinmux.c | 293 -------- arch/arm/cpu/tegra124-common/Makefile | 11 - arch/arm/cpu/tegra124-common/clock.c | 935 ------------------------- arch/arm/cpu/tegra124-common/funcmux.c | 71 -- arch/arm/cpu/tegra124-common/pinmux.c | 306 -------- arch/arm/cpu/tegra124-common/xusb-padctl.c | 716 ------------------- arch/arm/cpu/tegra20-common/Makefile | 17 - arch/arm/cpu/tegra20-common/clock.c | 687 ------------------ arch/arm/cpu/tegra20-common/crypto.c | 137 ---- arch/arm/cpu/tegra20-common/crypto.h | 20 - arch/arm/cpu/tegra20-common/emc.c | 270 ------- arch/arm/cpu/tegra20-common/funcmux.c | 296 -------- arch/arm/cpu/tegra20-common/pinmux.c | 425 ----------- arch/arm/cpu/tegra20-common/pmu.c | 65 -- arch/arm/cpu/tegra20-common/warmboot.c | 372 ---------- arch/arm/cpu/tegra20-common/warmboot_avp.c | 236 ------- arch/arm/cpu/tegra20-common/warmboot_avp.h | 65 -- arch/arm/cpu/tegra30-common/Makefile | 20 - arch/arm/cpu/tegra30-common/clock.c | 744 -------------------- arch/arm/cpu/tegra30-common/funcmux.c | 61 -- arch/arm/cpu/tegra30-common/pinmux.c | 276 -------- arch/arm/mach-tegra/Kconfig | 52 ++ arch/arm/mach-tegra/Makefile | 31 + arch/arm/mach-tegra/ap.c | 169 +++++ arch/arm/mach-tegra/board.c | 159 +++++ arch/arm/mach-tegra/cache.c | 46 ++ arch/arm/mach-tegra/clock.c | 669 ++++++++++++++++++ arch/arm/mach-tegra/cmd_enterrcm.c | 51 ++ arch/arm/mach-tegra/cpu.c | 384 ++++++++++ arch/arm/mach-tegra/cpu.h | 74 ++ arch/arm/mach-tegra/lowlevel_init.S | 26 + arch/arm/mach-tegra/pinmux-common.c | 527 ++++++++++++++ arch/arm/mach-tegra/powergate.c | 102 +++ arch/arm/mach-tegra/spl.c | 49 ++ arch/arm/mach-tegra/sys_info.c | 31 + arch/arm/mach-tegra/tegra114/Kconfig | 16 + arch/arm/mach-tegra/tegra114/Makefile | 19 + arch/arm/mach-tegra/tegra114/clock.c | 669 ++++++++++++++++++ arch/arm/mach-tegra/tegra114/cpu.c | 310 ++++++++ arch/arm/mach-tegra/tegra114/funcmux.c | 67 ++ arch/arm/mach-tegra/tegra114/pinmux.c | 293 ++++++++ arch/arm/mach-tegra/tegra124/Kconfig | 30 + arch/arm/mach-tegra/tegra124/Makefile | 13 + arch/arm/mach-tegra/tegra124/clock.c | 935 +++++++++++++++++++++++++ arch/arm/mach-tegra/tegra124/cpu.c | 265 +++++++ arch/arm/mach-tegra/tegra124/funcmux.c | 71 ++ arch/arm/mach-tegra/tegra124/pinmux.c | 306 ++++++++ arch/arm/mach-tegra/tegra124/xusb-padctl.c | 716 +++++++++++++++++++ arch/arm/mach-tegra/tegra20/Kconfig | 52 ++ arch/arm/mach-tegra/tegra20/Makefile | 21 + arch/arm/mach-tegra/tegra20/clock.c | 687 ++++++++++++++++++ arch/arm/mach-tegra/tegra20/cpu.c | 70 ++ arch/arm/mach-tegra/tegra20/crypto.c | 137 ++++ arch/arm/mach-tegra/tegra20/crypto.h | 20 + arch/arm/mach-tegra/tegra20/display.c | 394 +++++++++++ arch/arm/mach-tegra/tegra20/emc.c | 270 +++++++ arch/arm/mach-tegra/tegra20/funcmux.c | 296 ++++++++ arch/arm/mach-tegra/tegra20/pinmux.c | 425 +++++++++++ arch/arm/mach-tegra/tegra20/pmu.c | 65 ++ arch/arm/mach-tegra/tegra20/pwm.c | 86 +++ arch/arm/mach-tegra/tegra20/warmboot.c | 372 ++++++++++ arch/arm/mach-tegra/tegra20/warmboot_avp.c | 236 +++++++ arch/arm/mach-tegra/tegra20/warmboot_avp.h | 65 ++ arch/arm/mach-tegra/tegra30/Kconfig | 32 + arch/arm/mach-tegra/tegra30/Makefile | 19 + arch/arm/mach-tegra/tegra30/clock.c | 744 ++++++++++++++++++++ arch/arm/mach-tegra/tegra30/cpu.c | 183 +++++ arch/arm/mach-tegra/tegra30/funcmux.c | 61 ++ arch/arm/mach-tegra/tegra30/pinmux.c | 276 ++++++++ arch/arm/mach-tegra/vpr.c | 35 + arch/arm/mach-tegra/xusb-padctl.c | 39 ++ 113 files changed, 10670 insertions(+), 10757 deletions(-) delete mode 100644 arch/arm/cpu/arm720t/tegra-common/Makefile delete mode 100644 arch/arm/cpu/arm720t/tegra-common/cpu.c delete mode 100644 arch/arm/cpu/arm720t/tegra-common/cpu.h delete mode 100644 arch/arm/cpu/arm720t/tegra-common/spl.c delete mode 100644 arch/arm/cpu/arm720t/tegra114/Makefile delete mode 100644 arch/arm/cpu/arm720t/tegra114/cpu.c delete mode 100644 arch/arm/cpu/arm720t/tegra124/Makefile delete mode 100644 arch/arm/cpu/arm720t/tegra124/cpu.c delete mode 100644 arch/arm/cpu/arm720t/tegra20/Makefile delete mode 100644 arch/arm/cpu/arm720t/tegra20/cpu.c delete mode 100644 arch/arm/cpu/arm720t/tegra30/Makefile delete mode 100644 arch/arm/cpu/arm720t/tegra30/cpu.c delete mode 100644 arch/arm/cpu/armv7/tegra-common/Kconfig delete mode 100644 arch/arm/cpu/armv7/tegra-common/Makefile delete mode 100644 arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c delete mode 100644 arch/arm/cpu/armv7/tegra114/Kconfig delete mode 100644 arch/arm/cpu/armv7/tegra124/Kconfig delete mode 100644 arch/arm/cpu/armv7/tegra20/Kconfig delete mode 100644 arch/arm/cpu/armv7/tegra20/Makefile delete mode 100644 arch/arm/cpu/armv7/tegra20/display.c delete mode 100644 arch/arm/cpu/armv7/tegra20/pwm.c delete mode 100644 arch/arm/cpu/armv7/tegra30/Kconfig delete mode 100644 arch/arm/cpu/tegra-common/Makefile delete mode 100644 arch/arm/cpu/tegra-common/ap.c delete mode 100644 arch/arm/cpu/tegra-common/board.c delete mode 100644 arch/arm/cpu/tegra-common/cache.c delete mode 100644 arch/arm/cpu/tegra-common/clock.c delete mode 100644 arch/arm/cpu/tegra-common/lowlevel_init.S delete mode 100644 arch/arm/cpu/tegra-common/pinmux-common.c delete mode 100644 arch/arm/cpu/tegra-common/powergate.c delete mode 100644 arch/arm/cpu/tegra-common/sys_info.c delete mode 100644 arch/arm/cpu/tegra-common/vpr.c delete mode 100644 arch/arm/cpu/tegra-common/xusb-padctl.c delete mode 100644 arch/arm/cpu/tegra114-common/Makefile delete mode 100644 arch/arm/cpu/tegra114-common/clock.c delete mode 100644 arch/arm/cpu/tegra114-common/funcmux.c delete mode 100644 arch/arm/cpu/tegra114-common/pinmux.c delete mode 100644 arch/arm/cpu/tegra124-common/Makefile delete mode 100644 arch/arm/cpu/tegra124-common/clock.c delete mode 100644 arch/arm/cpu/tegra124-common/funcmux.c delete mode 100644 arch/arm/cpu/tegra124-common/pinmux.c delete mode 100644 arch/arm/cpu/tegra124-common/xusb-padctl.c delete mode 100644 arch/arm/cpu/tegra20-common/Makefile delete mode 100644 arch/arm/cpu/tegra20-common/clock.c delete mode 100644 arch/arm/cpu/tegra20-common/crypto.c delete mode 100644 arch/arm/cpu/tegra20-common/crypto.h delete mode 100644 arch/arm/cpu/tegra20-common/emc.c delete mode 100644 arch/arm/cpu/tegra20-common/funcmux.c delete mode 100644 arch/arm/cpu/tegra20-common/pinmux.c delete mode 100644 arch/arm/cpu/tegra20-common/pmu.c delete mode 100644 arch/arm/cpu/tegra20-common/warmboot.c delete mode 100644 arch/arm/cpu/tegra20-common/warmboot_avp.c delete mode 100644 arch/arm/cpu/tegra20-common/warmboot_avp.h delete mode 100644 arch/arm/cpu/tegra30-common/Makefile delete mode 100644 arch/arm/cpu/tegra30-common/clock.c delete mode 100644 arch/arm/cpu/tegra30-common/funcmux.c delete mode 100644 arch/arm/cpu/tegra30-common/pinmux.c create mode 100644 arch/arm/mach-tegra/Kconfig create mode 100644 arch/arm/mach-tegra/Makefile create mode 100644 arch/arm/mach-tegra/ap.c create mode 100644 arch/arm/mach-tegra/board.c create mode 100644 arch/arm/mach-tegra/cache.c create mode 100644 arch/arm/mach-tegra/clock.c create mode 100644 arch/arm/mach-tegra/cmd_enterrcm.c create mode 100644 arch/arm/mach-tegra/cpu.c create mode 100644 arch/arm/mach-tegra/cpu.h create mode 100644 arch/arm/mach-tegra/lowlevel_init.S create mode 100644 arch/arm/mach-tegra/pinmux-common.c create mode 100644 arch/arm/mach-tegra/powergate.c create mode 100644 arch/arm/mach-tegra/spl.c create mode 100644 arch/arm/mach-tegra/sys_info.c create mode 100644 arch/arm/mach-tegra/tegra114/Kconfig create mode 100644 arch/arm/mach-tegra/tegra114/Makefile create mode 100644 arch/arm/mach-tegra/tegra114/clock.c create mode 100644 arch/arm/mach-tegra/tegra114/cpu.c create mode 100644 arch/arm/mach-tegra/tegra114/funcmux.c create mode 100644 arch/arm/mach-tegra/tegra114/pinmux.c create mode 100644 arch/arm/mach-tegra/tegra124/Kconfig create mode 100644 arch/arm/mach-tegra/tegra124/Makefile create mode 100644 arch/arm/mach-tegra/tegra124/clock.c create mode 100644 arch/arm/mach-tegra/tegra124/cpu.c create mode 100644 arch/arm/mach-tegra/tegra124/funcmux.c create mode 100644 arch/arm/mach-tegra/tegra124/pinmux.c create mode 100644 arch/arm/mach-tegra/tegra124/xusb-padctl.c create mode 100644 arch/arm/mach-tegra/tegra20/Kconfig create mode 100644 arch/arm/mach-tegra/tegra20/Makefile create mode 100644 arch/arm/mach-tegra/tegra20/clock.c create mode 100644 arch/arm/mach-tegra/tegra20/cpu.c create mode 100644 arch/arm/mach-tegra/tegra20/crypto.c create mode 100644 arch/arm/mach-tegra/tegra20/crypto.h create mode 100644 arch/arm/mach-tegra/tegra20/display.c create mode 100644 arch/arm/mach-tegra/tegra20/emc.c create mode 100644 arch/arm/mach-tegra/tegra20/funcmux.c create mode 100644 arch/arm/mach-tegra/tegra20/pinmux.c create mode 100644 arch/arm/mach-tegra/tegra20/pmu.c create mode 100644 arch/arm/mach-tegra/tegra20/pwm.c create mode 100644 arch/arm/mach-tegra/tegra20/warmboot.c create mode 100644 arch/arm/mach-tegra/tegra20/warmboot_avp.c create mode 100644 arch/arm/mach-tegra/tegra20/warmboot_avp.h create mode 100644 arch/arm/mach-tegra/tegra30/Kconfig create mode 100644 arch/arm/mach-tegra/tegra30/Makefile create mode 100644 arch/arm/mach-tegra/tegra30/clock.c create mode 100644 arch/arm/mach-tegra/tegra30/cpu.c create mode 100644 arch/arm/mach-tegra/tegra30/funcmux.c create mode 100644 arch/arm/mach-tegra/tegra30/pinmux.c create mode 100644 arch/arm/mach-tegra/vpr.c create mode 100644 arch/arm/mach-tegra/xusb-padctl.c diff --git a/MAINTAINERS b/MAINTAINERS index a558bd4fcb..63085fc16d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -146,9 +146,7 @@ ARM TEGRA M: Tom Warren S: Maintained T: git git://git.denx.de/u-boot-tegra.git -F: arch/arm/cpu/arm720t/tegra*/ -F: arch/arm/cpu/armv7/tegra*/ -F: arch/arm/cpu/tegra*/ +F: arch/arm/mach-tegra/ F: arch/arm/include/asm/arch-tegra*/ ARM TI diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 06c34682c4..adecafcad1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -742,7 +742,7 @@ source "arch/arm/cpu/armv7/rmobile/Kconfig" source "arch/arm/cpu/armv7/s5pc1xx/Kconfig" -source "arch/arm/cpu/armv7/tegra-common/Kconfig" +source "arch/arm/mach-tegra/Kconfig" source "arch/arm/cpu/armv7/uniphier/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index f4e9af6598..f1ae929154 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -5,6 +5,8 @@ # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) += at91 +# TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA +machine-$(CONFIG_TEGRA) += tegra machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index ba4f3900f7..6bea3d3a2d 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,5 +1 @@ -obj-$(CONFIG_TEGRA20) += tegra20-common/ -obj-$(CONFIG_TEGRA30) += tegra30-common/ -obj-$(CONFIG_TEGRA114) += tegra114-common/ -obj-$(CONFIG_TEGRA124) += tegra124-common/ -obj-$(CONFIG_TEGRA) += tegra-common/ +obj- += dummy.o diff --git a/arch/arm/cpu/arm720t/Makefile b/arch/arm/cpu/arm720t/Makefile index 9f61ea2516..243a123378 100644 --- a/arch/arm/cpu/arm720t/Makefile +++ b/arch/arm/cpu/arm720t/Makefile @@ -7,9 +7,3 @@ extra-y = start.o obj-y = interrupts.o cpu.o - -obj-$(CONFIG_TEGRA) += tegra-common/ -obj-$(CONFIG_TEGRA20) += tegra20/ -obj-$(CONFIG_TEGRA30) += tegra30/ -obj-$(CONFIG_TEGRA114) += tegra114/ -obj-$(CONFIG_TEGRA124) += tegra124/ diff --git a/arch/arm/cpu/arm720t/tegra-common/Makefile b/arch/arm/cpu/arm720t/tegra-common/Makefile deleted file mode 100644 index a9c2b675ae..0000000000 --- a/arch/arm/cpu/arm720t/tegra-common/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_SPL_BUILD) += spl.o -obj-y += cpu.o diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.c b/arch/arm/cpu/arm720t/tegra-common/cpu.c deleted file mode 100644 index c6f3b029a1..0000000000 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cpu.h" - -int get_num_cpus(void) -{ - struct apb_misc_gp_ctlr *gp; - uint rev; - - gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; - - switch (rev) { - case CHIPID_TEGRA20: - return 2; - break; - case CHIPID_TEGRA30: - case CHIPID_TEGRA114: - default: - return 4; - break; - } -} - -/* - * Timing tables for each SOC for all four oscillator options. - */ -struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { - /* - * T20: 1 GHz - * - * Register Field Bits Width - * ------------------------------ - * PLLX_BASE p 22:20 3 - * PLLX_BASE n 17: 8 10 - * PLLX_BASE m 4: 0 5 - * PLLX_MISC cpcon 11: 8 4 - */ - { - { .n = 1000, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ - { .n = 625, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ - { .n = 1000, .m = 12, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ - { .n = 1000, .m = 26, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ - }, - /* - * T25: 1.2 GHz - * - * Register Field Bits Width - * ------------------------------ - * PLLX_BASE p 22:20 3 - * PLLX_BASE n 17: 8 10 - * PLLX_BASE m 4: 0 5 - * PLLX_MISC cpcon 11: 8 4 - */ - { - { .n = 923, .m = 10, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ - { .n = 750, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ - { .n = 600, .m = 6, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ - { .n = 600, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ - }, - /* - * T30: 600 MHz - * - * Register Field Bits Width - * ------------------------------ - * PLLX_BASE p 22:20 3 - * PLLX_BASE n 17: 8 10 - * PLLX_BASE m 4: 0 5 - * PLLX_MISC cpcon 11: 8 4 - */ - { - { .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 13.0 MHz */ - { .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ - { .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 12.0 MHz */ - { .n = 600, .m = 26, .p = 0, .cpcon = 8 }, /* OSC: 26.0 MHz */ - }, - /* - * T114: 700 MHz - * - * Register Field Bits Width - * ------------------------------ - * PLLX_BASE p 23:20 4 - * PLLX_BASE n 15: 8 8 - * PLLX_BASE m 7: 0 8 - */ - { - { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ - { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ - { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ - { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ - }, - - /* - * T124: 700 MHz - * - * Register Field Bits Width - * ------------------------------ - * PLLX_BASE p 23:20 4 - * PLLX_BASE n 15: 8 8 - * PLLX_BASE m 7: 0 8 - */ - { - { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ - { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ - { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ - { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ - }, -}; - -static inline void pllx_set_iddq(void) -{ -#if defined(CONFIG_TEGRA124) - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - /* Disable IDDQ */ - reg = readl(&clkrst->crc_pllx_misc3); - reg &= ~PLLX_IDDQ_MASK; - writel(reg, &clkrst->crc_pllx_misc3); - udelay(2); - debug("%s: IDDQ: PLLX IDDQ = 0x%08X\n", __func__, - readl(&clkrst->crc_pllx_misc3)); -#endif -} - -int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, - u32 divp, u32 cpcon) -{ - int chip = tegra_get_chip(); - u32 reg; - - /* If PLLX is already enabled, just return */ - if (readl(&pll->pll_base) & PLL_ENABLE_MASK) { - debug("pllx_set_rate: PLLX already enabled, returning\n"); - return 0; - } - - debug(" pllx_set_rate entry\n"); - - pllx_set_iddq(); - - /* Set BYPASS, m, n and p to PLLX_BASE */ - reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT); - reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT)); - writel(reg, &pll->pll_base); - - /* Set cpcon to PLLX_MISC */ - if (chip == CHIPID_TEGRA20 || chip == CHIPID_TEGRA30) - reg = (cpcon << PLL_CPCON_SHIFT); - else - reg = 0; - - /* Set dccon to PLLX_MISC if freq > 600MHz */ - if (divn > 600) - reg |= (1 << PLL_DCCON_SHIFT); - writel(reg, &pll->pll_misc); - - /* Disable BYPASS */ - reg = readl(&pll->pll_base); - reg &= ~PLL_BYPASS_MASK; - writel(reg, &pll->pll_base); - debug("pllx_set_rate: base = 0x%08X\n", reg); - - /* Set lock_enable to PLLX_MISC */ - reg = readl(&pll->pll_misc); - reg |= PLL_LOCK_ENABLE_MASK; - writel(reg, &pll->pll_misc); - debug("pllx_set_rate: misc = 0x%08X\n", reg); - - /* Enable PLLX last, once it's all configured */ - reg = readl(&pll->pll_base); - reg |= PLL_ENABLE_MASK; - writel(reg, &pll->pll_base); - debug("pllx_set_rate: base final = 0x%08X\n", reg); - - return 0; -} - -void init_pllx(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX]; - int soc_type, sku_info, chip_sku; - enum clock_osc_freq osc; - struct clk_pll_table *sel; - - debug("init_pllx entry\n"); - - /* get SOC (chip) type */ - soc_type = tegra_get_chip(); - debug(" init_pllx: SoC = 0x%02X\n", soc_type); - - /* get SKU info */ - sku_info = tegra_get_sku_info(); - debug(" init_pllx: SKU info byte = 0x%02X\n", sku_info); - - /* get chip SKU, combo of the above info */ - chip_sku = tegra_get_chip_sku(); - debug(" init_pllx: Chip SKU = %d\n", chip_sku); - - /* get osc freq */ - osc = clock_get_osc_freq(); - debug(" init_pllx: osc = %d\n", osc); - - /* set pllx */ - sel = &tegra_pll_x_table[chip_sku][osc]; - pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); -} - -void enable_cpu_clock(int enable) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 clk; - - /* - * NOTE: - * Regardless of whether the request is to enable or disable the CPU - * clock, every processor in the CPU complex except the master (CPU 0) - * will have it's clock stopped because the AVP only talks to the - * master. - */ - - if (enable) { - /* Initialize PLLX */ - init_pllx(); - - /* Wait until all clocks are stable */ - udelay(PLL_STABILIZATION_DELAY); - - writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); - } - - /* - * Read the register containing the individual CPU clock enables and - * always stop the clocks to CPUs > 0. - */ - clk = readl(&clkrst->crc_clk_cpu_cmplx); - clk |= 1 << CPU1_CLK_STP_SHIFT; - if (get_num_cpus() == 4) - clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT); - - /* Stop/Unstop the CPU clock */ - clk &= ~CPU0_CLK_STP_MASK; - clk |= !enable << CPU0_CLK_STP_SHIFT; - writel(clk, &clkrst->crc_clk_cpu_cmplx); - - clock_enable(PERIPH_ID_CPU); -} - -static int is_cpu_powered(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; -} - -static void remove_cpu_io_clamps(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - /* Remove the clamps on the CPU I/O signals */ - reg = readl(&pmc->pmc_remove_clamping); - reg |= CPU_CLMP; - writel(reg, &pmc->pmc_remove_clamping); - - /* Give I/O signals time to stabilize */ - udelay(IO_STABILIZATION_DELAY); -} - -void powerup_cpu(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - int timeout = IO_STABILIZATION_DELAY; - - if (!is_cpu_powered()) { - /* Toggle the CPU power state (OFF -> ON) */ - reg = readl(&pmc->pmc_pwrgate_toggle); - reg &= PARTID_CP; - reg |= START_CP; - writel(reg, &pmc->pmc_pwrgate_toggle); - - /* Wait for the power to come up */ - while (!is_cpu_powered()) { - if (timeout-- == 0) - printf("CPU failed to power up!\n"); - else - udelay(10); - } - - /* - * Remove the I/O clamps from CPU power partition. - * Recommended only on a Warm boot, if the CPU partition gets - * power gated. Shouldn't cause any harm when called after a - * cold boot according to HW, probably just redundant. - */ - remove_cpu_io_clamps(); - } -} - -void reset_A9_cpu(int reset) -{ - /* - * NOTE: Regardless of whether the request is to hold the CPU in reset - * or take it out of reset, every processor in the CPU complex - * except the master (CPU 0) will be held in reset because the - * AVP only talks to the master. The AVP does not know that there - * are multiple processors in the CPU complex. - */ - int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; - int num_cpus = get_num_cpus(); - int cpu; - - debug("reset_a9_cpu entry\n"); - /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ - for (cpu = 1; cpu < num_cpus; cpu++) - reset_cmplx_set_enable(cpu, mask, 1); - reset_cmplx_set_enable(0, mask, reset); - - /* Enable/Disable master CPU reset */ - reset_set_enable(PERIPH_ID_CPU, reset); -} - -void clock_enable_coresight(int enable) -{ - u32 rst, src = 2; - - debug("clock_enable_coresight entry\n"); - clock_set_enable(PERIPH_ID_CORESIGHT, enable); - reset_set_enable(PERIPH_ID_CORESIGHT, !enable); - - if (enable) { - /* - * Put CoreSight on PLLP_OUT0 and divide it down as per - * PLLP base frequency based on SoC type (T20/T30+). - * Clock divider request would setup CSITE clock as 144MHz - * for PLLP base 216MHz and 204MHz for PLLP base 408MHz - */ - src = CLK_DIVIDER(NVBL_PLLP_KHZ, CSITE_KHZ); - clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); - - /* Unlock the CPU CoreSight interfaces */ - rst = CORESIGHT_UNLOCK; - writel(rst, CSITE_CPU_DBG0_LAR); - writel(rst, CSITE_CPU_DBG1_LAR); - if (get_num_cpus() == 4) { - writel(rst, CSITE_CPU_DBG2_LAR); - writel(rst, CSITE_CPU_DBG3_LAR); - } - } -} - -void halt_avp(void) -{ - for (;;) { - writel(HALT_COP_EVENT_JTAG | (FLOW_MODE_STOP << 29), - FLOW_CTLR_HALT_COP_EVENTS); - } -} diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h deleted file mode 100644 index b4ca44fce1..0000000000 --- a/arch/arm/cpu/arm720t/tegra-common/cpu.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2010-2014 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include - -/* Stabilization delays, in usec */ -#define PLL_STABILIZATION_DELAY (300) -#define IO_STABILIZATION_DELAY (1000) - -#if defined(CONFIG_TEGRA20) -#define NVBL_PLLP_KHZ 216000 -#define CSITE_KHZ 144000 -#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) || \ - defined(CONFIG_TEGRA124) -#define NVBL_PLLP_KHZ 408000 -#define CSITE_KHZ 204000 -#else -#error "Unknown Tegra chip!" -#endif - -#define PLLX_ENABLED (1 << 30) -#define CCLK_BURST_POLICY 0x20008888 -#define SUPER_CCLK_DIVIDER 0x80000000 - -/* Calculate clock fractional divider value from ref and target frequencies */ -#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) - -/* Calculate clock frequency value from reference and clock divider value */ -#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) - -/* AVP/CPU ID */ -#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ -#define PG_UP_TAG_0 0x0 - -#define CORESIGHT_UNLOCK 0xC5ACCE55; - -#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) -#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) -#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) -#define CSITE_CPU_DBG2_LAR (NV_PA_CSITE_BASE + 0x14FB0) -#define CSITE_CPU_DBG3_LAR (NV_PA_CSITE_BASE + 0x16FB0) - -#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) -#define FLOW_MODE_STOP 2 -#define HALT_COP_EVENT_JTAG (1 << 28) -#define HALT_COP_EVENT_IRQ_1 (1 << 11) -#define HALT_COP_EVENT_FIQ_1 (1 << 9) - -#define FLOW_MODE_NONE 0 - -#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) - -struct clk_pll_table { - u16 n; - u16 m; - u8 p; - u8 cpcon; -}; - -void clock_enable_coresight(int enable); -void enable_cpu_clock(int enable); -void halt_avp(void) __attribute__ ((noreturn)); -void init_pllx(void); -void powerup_cpu(void); -void reset_A9_cpu(int reset); -void start_cpu(u32 reset_vector); -int tegra_get_chip(void); -int tegra_get_sku_info(void); -int tegra_get_chip_sku(void); -void adjust_pllp_out_freqs(void); -void pmic_enable_cpu_vdd(void); diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c deleted file mode 100644 index e0f9d5b6b4..0000000000 --- a/arch/arm/cpu/arm720t/tegra-common/spl.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * (C) Copyright 2012 - * NVIDIA Inc, - * - * Allen Martin - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "cpu.h" - -void spl_board_init(void) -{ - struct apb_misc_pp_ctlr *apb_misc = - (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; - - /* enable JTAG */ - writel(0xC0, &apb_misc->cfg_ctl); - - board_init_uart_f(); - - /* Initialize periph GPIOs */ - gpio_early_init_uart(); - - clock_early_init(); - preloader_console_init(); -} - -u32 spl_boot_device(void) -{ - return BOOT_DEVICE_RAM; -} - -void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) -{ - debug("image entry point: 0x%X\n", spl_image->entry_point); - - start_cpu((u32)spl_image->entry_point); - halt_avp(); -} diff --git a/arch/arm/cpu/arm720t/tegra114/Makefile b/arch/arm/cpu/arm720t/tegra114/Makefile deleted file mode 100644 index ea3e55ea62..0000000000 --- a/arch/arm/cpu/arm720t/tegra114/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -#obj-y += cpu.o t11x.o -obj-y += cpu.o diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c b/arch/arm/cpu/arm720t/tegra114/cpu.c deleted file mode 100644 index 5ed3bb9d9a..0000000000 --- a/arch/arm/cpu/arm720t/tegra114/cpu.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "../tegra-common/cpu.h" - -/* Tegra114-specific CPU init code */ -static void enable_cpu_power_rail(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - debug("enable_cpu_power_rail entry\n"); - - /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ - pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); - pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SDA_PZ7); - - /* - * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), - * set it for 25ms (102MHz * .025) - */ - reg = 0x26E8F0; - writel(reg, &pmc->pmc_cpupwrgood_timer); - - /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ - clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); - setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); - - /* - * Set CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0_CAR2PMC_CPU_ACK_WIDTH - * to 408 to satisfy the requirement of having at least 16 CPU clock - * cycles before clamp removal. - */ - - clrbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 0xFFF); - setbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 408); -} - -static void enable_cpu_clocks(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - debug("enable_cpu_clocks entry\n"); - - /* Wait for PLL-X to lock */ - do { - reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - } while ((reg & PLL_LOCK_MASK) == 0); - - /* Wait until all clocks are stable */ - udelay(PLL_STABILIZATION_DELAY); - - writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); - - /* Always enable the main CPU complex clocks */ - clock_enable(PERIPH_ID_CPU); - clock_enable(PERIPH_ID_CPULP); - clock_enable(PERIPH_ID_CPUG); -} - -static void remove_cpu_resets(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - debug("remove_cpu_resets entry\n"); - /* Take the slow non-CPU partition out of reset */ - reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); - writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr); - - /* Take the fast non-CPU partition out of reset */ - reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); - writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpug_cmplx_clr); - - /* Clear the SW-controlled reset of the slow cluster */ - reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); - reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); - writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); - - /* Clear the SW-controlled reset of the fast cluster */ - reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); - reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); - reg |= (CLR_CPURESET1+CLR_DBGRESET1+CLR_CORERESET1+CLR_CXRESET1); - reg |= (CLR_CPURESET2+CLR_DBGRESET2+CLR_CORERESET2+CLR_CXRESET2); - reg |= (CLR_CPURESET3+CLR_DBGRESET3+CLR_CORERESET3+CLR_CXRESET3); - writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); -} - -/** - * The T114 requires some special clock initialization, including setting up - * the DVC I2C, turning on MSELECT and selecting the G CPU cluster - */ -void t114_init_clocks(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - u32 val; - - debug("t114_init_clocks entry\n"); - - /* Set active CPU cluster to G */ - clrbits_le32(&flow->cluster_control, 1); - - writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); - - debug("Setting up PLLX\n"); - init_pllx(); - - val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); - writel(val, &clkrst->crc_clk_sys_rate); - - /* Enable clocks to required peripherals. TBD - minimize this list */ - debug("Enabling clocks\n"); - - clock_set_enable(PERIPH_ID_CACHE2, 1); - clock_set_enable(PERIPH_ID_GPIO, 1); - clock_set_enable(PERIPH_ID_TMR, 1); - clock_set_enable(PERIPH_ID_RTC, 1); - clock_set_enable(PERIPH_ID_CPU, 1); - clock_set_enable(PERIPH_ID_EMC, 1); - clock_set_enable(PERIPH_ID_I2C5, 1); - clock_set_enable(PERIPH_ID_FUSE, 1); - clock_set_enable(PERIPH_ID_PMC, 1); - clock_set_enable(PERIPH_ID_APBDMA, 1); - clock_set_enable(PERIPH_ID_MEM, 1); - clock_set_enable(PERIPH_ID_IRAMA, 1); - clock_set_enable(PERIPH_ID_IRAMB, 1); - clock_set_enable(PERIPH_ID_IRAMC, 1); - clock_set_enable(PERIPH_ID_IRAMD, 1); - clock_set_enable(PERIPH_ID_CORESIGHT, 1); - clock_set_enable(PERIPH_ID_MSELECT, 1); - clock_set_enable(PERIPH_ID_EMC1, 1); - clock_set_enable(PERIPH_ID_MC1, 1); - clock_set_enable(PERIPH_ID_DVFS, 1); - - /* - * Set MSELECT clock source as PLLP (00), and ask for a clock - * divider that would set the MSELECT clock at 102MHz for a - * PLLP base of 408MHz. - */ - clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, - CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); - - /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ - clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); - - /* Give clocks time to stabilize */ - udelay(1000); - - /* Take required peripherals out of reset */ - debug("Taking periphs out of reset\n"); - reset_set_enable(PERIPH_ID_CACHE2, 0); - reset_set_enable(PERIPH_ID_GPIO, 0); - reset_set_enable(PERIPH_ID_TMR, 0); - reset_set_enable(PERIPH_ID_COP, 0); - reset_set_enable(PERIPH_ID_EMC, 0); - reset_set_enable(PERIPH_ID_I2C5, 0); - reset_set_enable(PERIPH_ID_FUSE, 0); - reset_set_enable(PERIPH_ID_APBDMA, 0); - reset_set_enable(PERIPH_ID_MEM, 0); - reset_set_enable(PERIPH_ID_CORESIGHT, 0); - reset_set_enable(PERIPH_ID_MSELECT, 0); - reset_set_enable(PERIPH_ID_EMC1, 0); - reset_set_enable(PERIPH_ID_MC1, 0); - reset_set_enable(PERIPH_ID_DVFS, 0); - - debug("t114_init_clocks exit\n"); -} - -static bool is_partition_powered(u32 partid) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - /* Get power gate status */ - reg = readl(&pmc->pmc_pwrgate_status); - return !!(reg & (1 << partid)); -} - -static bool is_clamp_enabled(u32 partid) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - /* Get clamp status. */ - reg = readl(&pmc->pmc_clamp_status); - return !!(reg & (1 << partid)); -} - -static void power_partition(u32 partid) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - debug("%s: part ID = %08X\n", __func__, partid); - /* Is the partition already on? */ - if (!is_partition_powered(partid)) { - /* No, toggle the partition power state (OFF -> ON) */ - debug("power_partition, toggling state\n"); - writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); - - /* Wait for the power to come up */ - while (!is_partition_powered(partid)) - ; - - /* Wait for the clamp status to be cleared */ - while (is_clamp_enabled(partid)) - ; - - /* Give I/O signals time to stabilize */ - udelay(IO_STABILIZATION_DELAY); - } -} - -void powerup_cpus(void) -{ - debug("powerup_cpus entry\n"); - - /* We boot to the fast cluster */ - debug("powerup_cpus entry: G cluster\n"); - /* Power up the fast cluster rail partition */ - power_partition(CRAIL); - - /* Power up the fast cluster non-CPU partition */ - power_partition(C0NC); - - /* Power up the fast cluster CPU0 partition */ - power_partition(CE0); -} - -void start_cpu(u32 reset_vector) -{ - u32 imme, inst; - - debug("start_cpu entry, reset_vector = %x\n", reset_vector); - - t114_init_clocks(); - - /* Enable VDD_CPU */ - enable_cpu_power_rail(); - - /* Get the CPU(s) running */ - enable_cpu_clocks(); - - /* Enable CoreSight */ - clock_enable_coresight(1); - - /* Take CPU(s) out of reset */ - remove_cpu_resets(); - - /* Set the entry point for CPU execution from reset */ - - /* - * A01P with patched boot ROM; vector hard-coded to 0x4003fffc. - * See nvbug 1193357 for details. - */ - - /* mov r0, #lsb(reset_vector) */ - imme = reset_vector & 0xffff; - inst = imme & 0xfff; - inst |= ((imme >> 12) << 16); - inst |= 0xe3000000; - writel(inst, 0x4003fff0); - - /* movt r0, #msb(reset_vector) */ - imme = (reset_vector >> 16) & 0xffff; - inst = imme & 0xfff; - inst |= ((imme >> 12) << 16); - inst |= 0xe3400000; - writel(inst, 0x4003fff4); - - /* bx r0 */ - writel(0xe12fff10, 0x4003fff8); - - /* b -12 */ - imme = (u32)-20; - inst = (imme >> 2) & 0xffffff; - inst |= 0xea000000; - writel(inst, 0x4003fffc); - - /* Write to orignal location for compatibility */ - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* If the CPU(s) don't already have power, power 'em up */ - powerup_cpus(); -} diff --git a/arch/arm/cpu/arm720t/tegra124/Makefile b/arch/arm/cpu/arm720t/tegra124/Makefile deleted file mode 100644 index 61abf45d3d..0000000000 --- a/arch/arm/cpu/arm720t/tegra124/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2013-2014 -# NVIDIA Corporation -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += cpu.o diff --git a/arch/arm/cpu/arm720t/tegra124/cpu.c b/arch/arm/cpu/arm720t/tegra124/cpu.c deleted file mode 100644 index 6ff6aeb546..0000000000 --- a/arch/arm/cpu/arm720t/tegra124/cpu.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * (C) Copyright 2013 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../tegra-common/cpu.h" - -/* Tegra124-specific CPU init code */ - -static void enable_cpu_power_rail(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - debug("enable_cpu_power_rail entry\n"); - - /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ - pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); - pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SDA_PZ7); - - pmic_enable_cpu_vdd(); - - /* - * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), - * set it for 5ms as per SysEng (102MHz*5ms = 510000 (7C830h). - */ - writel(0x7C830, &pmc->pmc_cpupwrgood_timer); - - /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ - clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); - setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); -} - -static void enable_cpu_clocks(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - debug("enable_cpu_clocks entry\n"); - - /* Wait for PLL-X to lock */ - do { - reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - debug("%s: PLLX base = 0x%08X\n", __func__, reg); - } while ((reg & PLL_LOCK_MASK) == 0); - - debug("%s: PLLX locked, delay for stable clocks\n", __func__); - /* Wait until all clocks are stable */ - udelay(PLL_STABILIZATION_DELAY); - - debug("%s: Setting CCLK_BURST and DIVIDER\n", __func__); - writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); - - debug("%s: Enabling clock to all CPUs\n", __func__); - /* Enable the clock to all CPUs */ - reg = CLR_CPU3_CLK_STP | CLR_CPU2_CLK_STP | CLR_CPU1_CLK_STP | - CLR_CPU0_CLK_STP; - writel(reg, &clkrst->crc_clk_cpu_cmplx_clr); - - debug("%s: Enabling main CPU complex clocks\n", __func__); - /* Always enable the main CPU complex clocks */ - clock_enable(PERIPH_ID_CPU); - clock_enable(PERIPH_ID_CPULP); - clock_enable(PERIPH_ID_CPUG); - - debug("%s: Done\n", __func__); -} - -static void remove_cpu_resets(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - debug("remove_cpu_resets entry\n"); - - /* Take the slow and fast partitions out of reset */ - reg = CLR_NONCPURESET; - writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); - writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); - - /* Clear the SW-controlled reset of the slow cluster */ - reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | - CLR_L2RESET | CLR_PRESETDBG; - writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); - - /* Clear the SW-controlled reset of the fast cluster */ - reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | - CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 | - CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 | - CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3 | - CLR_L2RESET | CLR_PRESETDBG; - writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); -} - -/** - * The Tegra124 requires some special clock initialization, including setting up - * the DVC I2C, turning on MSELECT and selecting the G CPU cluster - */ -void tegra124_init_clocks(void) -{ - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 val; - - debug("tegra124_init_clocks entry\n"); - - /* Set active CPU cluster to G */ - clrbits_le32(&flow->cluster_control, 1); - - /* Change the oscillator drive strength */ - val = readl(&clkrst->crc_osc_ctrl); - val &= ~OSC_XOFS_MASK; - val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); - writel(val, &clkrst->crc_osc_ctrl); - - /* Update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot */ - val = readl(&pmc->pmc_osc_edpd_over); - val &= ~PMC_XOFS_MASK; - val |= (OSC_DRIVE_STRENGTH << PMC_XOFS_SHIFT); - writel(val, &pmc->pmc_osc_edpd_over); - - /* Set HOLD_CKE_LOW_EN to 1 */ - setbits_le32(&pmc->pmc_cntrl2, HOLD_CKE_LOW_EN); - - debug("Setting up PLLX\n"); - init_pllx(); - - val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); - writel(val, &clkrst->crc_clk_sys_rate); - - /* Enable clocks to required peripherals. TBD - minimize this list */ - debug("Enabling clocks\n"); - - clock_set_enable(PERIPH_ID_CACHE2, 1); - clock_set_enable(PERIPH_ID_GPIO, 1); - clock_set_enable(PERIPH_ID_TMR, 1); - clock_set_enable(PERIPH_ID_CPU, 1); - clock_set_enable(PERIPH_ID_EMC, 1); - clock_set_enable(PERIPH_ID_I2C5, 1); - clock_set_enable(PERIPH_ID_APBDMA, 1); - clock_set_enable(PERIPH_ID_MEM, 1); - clock_set_enable(PERIPH_ID_CORESIGHT, 1); - clock_set_enable(PERIPH_ID_MSELECT, 1); - clock_set_enable(PERIPH_ID_DVFS, 1); - - /* - * Set MSELECT clock source as PLLP (00), and ask for a clock - * divider that would set the MSELECT clock at 102MHz for a - * PLLP base of 408MHz. - */ - clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, - CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); - - /* Give clock time to stabilize */ - udelay(IO_STABILIZATION_DELAY); - - /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ - clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); - - /* Give clock time to stabilize */ - udelay(IO_STABILIZATION_DELAY); - - /* Take required peripherals out of reset */ - debug("Taking periphs out of reset\n"); - reset_set_enable(PERIPH_ID_CACHE2, 0); - reset_set_enable(PERIPH_ID_GPIO, 0); - reset_set_enable(PERIPH_ID_TMR, 0); - reset_set_enable(PERIPH_ID_COP, 0); - reset_set_enable(PERIPH_ID_EMC, 0); - reset_set_enable(PERIPH_ID_I2C5, 0); - reset_set_enable(PERIPH_ID_APBDMA, 0); - reset_set_enable(PERIPH_ID_MEM, 0); - reset_set_enable(PERIPH_ID_CORESIGHT, 0); - reset_set_enable(PERIPH_ID_MSELECT, 0); - reset_set_enable(PERIPH_ID_DVFS, 0); - - debug("tegra124_init_clocks exit\n"); -} - -static bool is_partition_powered(u32 partid) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - /* Get power gate status */ - reg = readl(&pmc->pmc_pwrgate_status); - return !!(reg & (1 << partid)); -} - -static void power_partition(u32 partid) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - debug("%s: part ID = %08X\n", __func__, partid); - /* Is the partition already on? */ - if (!is_partition_powered(partid)) { - /* No, toggle the partition power state (OFF -> ON) */ - debug("power_partition, toggling state\n"); - writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); - - /* Wait for the power to come up */ - while (!is_partition_powered(partid)) - ; - - /* Give I/O signals time to stabilize */ - udelay(IO_STABILIZATION_DELAY); - } -} - -void powerup_cpus(void) -{ - debug("powerup_cpus entry\n"); - - /* We boot to the fast cluster */ - debug("powerup_cpus entry: G cluster\n"); - - /* Power up the fast cluster rail partition */ - debug("powerup_cpus: CRAIL\n"); - power_partition(CRAIL); - - /* Power up the fast cluster non-CPU partition */ - debug("powerup_cpus: C0NC\n"); - power_partition(C0NC); - - /* Power up the fast cluster CPU0 partition */ - debug("powerup_cpus: CE0\n"); - power_partition(CE0); - - debug("powerup_cpus: done\n"); -} - -void start_cpu(u32 reset_vector) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - debug("start_cpu entry, reset_vector = %x\n", reset_vector); - - tegra124_init_clocks(); - - /* Set power-gating timer multiplier */ - writel((MULT_8 << TIMER_MULT_SHIFT) | (MULT_8 << TIMER_MULT_CPU_SHIFT), - &pmc->pmc_pwrgate_timer_mult); - - enable_cpu_power_rail(); - enable_cpu_clocks(); - clock_enable_coresight(1); - remove_cpu_resets(); - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - powerup_cpus(); - debug("start_cpu exit, should continue @ reset_vector\n"); -} diff --git a/arch/arm/cpu/arm720t/tegra20/Makefile b/arch/arm/cpu/arm720t/tegra20/Makefile deleted file mode 100644 index 12243fa9be..0000000000 --- a/arch/arm/cpu/arm720t/tegra20/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += cpu.o diff --git a/arch/arm/cpu/arm720t/tegra20/cpu.c b/arch/arm/cpu/arm720t/tegra20/cpu.c deleted file mode 100644 index 253389955f..0000000000 --- a/arch/arm/cpu/arm720t/tegra20/cpu.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include "../tegra-common/cpu.h" - -static void enable_cpu_power_rail(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - reg = readl(&pmc->pmc_cntrl); - reg |= CPUPWRREQ_OE; - writel(reg, &pmc->pmc_cntrl); - - /* - * The TI PMU65861C needs a 3.75ms delay between enabling - * the power rail and enabling the CPU clock. This delay - * between SM1EN and SM1 is for switching time + the ramp - * up of the voltage to the CPU (VDD_CPU from PMU). - */ - udelay(3750); -} - -void start_cpu(u32 reset_vector) -{ - /* Enable VDD_CPU */ - enable_cpu_power_rail(); - - /* Hold the CPUs in reset */ - reset_A9_cpu(1); - - /* Disable the CPU clock */ - enable_cpu_clock(0); - - /* Enable CoreSight */ - clock_enable_coresight(1); - - /* - * Set the entry point for CPU execution from reset, - * if it's a non-zero value. - */ - if (reset_vector) - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Enable the CPU clock */ - enable_cpu_clock(1); - - /* If the CPU doesn't already have power, power it up */ - powerup_cpu(); - - /* Take the CPU out of reset */ - reset_A9_cpu(0); -} diff --git a/arch/arm/cpu/arm720t/tegra30/Makefile b/arch/arm/cpu/arm720t/tegra30/Makefile deleted file mode 100644 index 6ff4c55213..0000000000 --- a/arch/arm/cpu/arm720t/tegra30/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -obj-y += cpu.o diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c deleted file mode 100644 index 9003902e3f..0000000000 --- a/arch/arm/cpu/arm720t/tegra30/cpu.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "../tegra-common/cpu.h" - -/* Tegra30-specific CPU init code */ -void tegra_i2c_ll_write_addr(uint addr, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; - - writel(addr, ®->cmd_addr0); - writel(config, ®->cnfg); -} - -void tegra_i2c_ll_write_data(uint data, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; - - writel(data, ®->cmd_data1); - writel(config, ®->cnfg); -} - -#define TPS62366A_I2C_ADDR 0xC0 -#define TPS62366A_SET1_REG 0x01 -#define TPS62366A_SET1_DATA (0x4600 | TPS62366A_SET1_REG) - -#define TPS62361B_I2C_ADDR 0xC0 -#define TPS62361B_SET3_REG 0x03 -#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG) - -#define TPS65911_I2C_ADDR 0x5A -#define TPS65911_VDDCTRL_OP_REG 0x28 -#define TPS65911_VDDCTRL_SR_REG 0x27 -#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) -#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) -#define I2C_SEND_2_BYTES 0x0A02 - -static void enable_cpu_power_rail(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 reg; - - debug("enable_cpu_power_rail entry\n"); - reg = readl(&pmc->pmc_cntrl); - reg |= CPUPWRREQ_OE; - writel(reg, &pmc->pmc_cntrl); - - /* Set VDD_CORE to 1.200V. */ -#ifdef CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1 - tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES); -#endif -#ifdef CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3 - tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES); -#endif - udelay(1000); - - /* - * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. - * First set VDD to 1.0125V, then enable the VDD regulator. - */ - tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); - udelay(1000); - tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); - udelay(10 * 1000); -} - -/** - * The T30 requires some special clock initialization, including setting up - * the dvc i2c, turning on mselect and selecting the G CPU cluster - */ -void t30_init_clocks(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - u32 val; - - debug("t30_init_clocks entry\n"); - /* Set active CPU cluster to G */ - clrbits_le32(flow->cluster_control, 1 << 0); - - writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); - - val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | - (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | - (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | - (0 << CLK_SYS_RATE_APB_RATE_SHIFT); - writel(val, &clkrst->crc_clk_sys_rate); - - /* Put i2c, mselect in reset and enable clocks */ - reset_set_enable(PERIPH_ID_DVC_I2C, 1); - clock_set_enable(PERIPH_ID_DVC_I2C, 1); - reset_set_enable(PERIPH_ID_MSELECT, 1); - clock_set_enable(PERIPH_ID_MSELECT, 1); - - /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */ - clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2); - - /* - * Our high-level clock routines are not available prior to - * relocation. We use the low-level functions which require a - * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) - */ - clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); - - /* - * Give clocks time to stabilize, then take i2c and mselect out of - * reset - */ - udelay(1000); - reset_set_enable(PERIPH_ID_DVC_I2C, 0); - reset_set_enable(PERIPH_ID_MSELECT, 0); -} - -static void set_cpu_running(int run) -{ - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - - debug("set_cpu_running entry, run = %d\n", run); - writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events); -} - -void start_cpu(u32 reset_vector) -{ - debug("start_cpu entry, reset_vector = %x\n", reset_vector); - t30_init_clocks(); - - /* Enable VDD_CPU */ - enable_cpu_power_rail(); - - set_cpu_running(0); - - /* Hold the CPUs in reset */ - reset_A9_cpu(1); - - /* Disable the CPU clock */ - enable_cpu_clock(0); - - /* Enable CoreSight */ - clock_enable_coresight(1); - - /* - * Set the entry point for CPU execution from reset, - * if it's a non-zero value. - */ - if (reset_vector) - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Enable the CPU clock */ - enable_cpu_clock(1); - - /* If the CPU doesn't already have power, power it up */ - powerup_cpu(); - - /* Take the CPU out of reset */ - reset_A9_cpu(0); - - set_cpu_running(1); -} diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 6dbca26ceb..91e69233c3 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_IPROC) += iproc-common/ obj-$(CONFIG_KONA) += kona-common/ obj-$(CONFIG_OMAP_COMMON) += omap-common/ obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o -obj-$(CONFIG_TEGRA) += tegra-common/ ifneq (,$(filter s5pc1xx exynos,$(SOC))) obj-y += s5p-common/ @@ -57,7 +56,6 @@ obj-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx/ obj-$(CONFIG_SOCFPGA) += socfpga/ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ -obj-$(CONFIG_TEGRA20) += tegra20/ obj-$(CONFIG_U8500) += u8500/ obj-$(CONFIG_ARCH_UNIPHIER) += uniphier/ obj-$(CONFIG_VF610) += vf610/ diff --git a/arch/arm/cpu/armv7/tegra-common/Kconfig b/arch/arm/cpu/armv7/tegra-common/Kconfig deleted file mode 100644 index ee3246929a..0000000000 --- a/arch/arm/cpu/armv7/tegra-common/Kconfig +++ /dev/null @@ -1,52 +0,0 @@ -if TEGRA - -choice - prompt "Tegra SoC select" - -config TEGRA20 - bool "Tegra20 family" - -config TEGRA30 - bool "Tegra30 family" - -config TEGRA114 - bool "Tegra114 family" - -config TEGRA124 - bool "Tegra124 family" - -endchoice - -config SYS_MALLOC_F - default y - -config SYS_MALLOC_F_LEN - default 0x1800 - -config USE_PRIVATE_LIBGCC - default y if SPL_BUILD - -config DM - default y if !SPL_BUILD - -config DM_SERIAL - default y if !SPL_BUILD - -config DM_SPI - default y if !SPL_BUILD - -config DM_SPI_FLASH - default y if !SPL_BUILD - -config DM_I2C - default y if !SPL_BUILD - -config DM_GPIO - default y if !SPL_BUILD - -source "arch/arm/cpu/armv7/tegra20/Kconfig" -source "arch/arm/cpu/armv7/tegra30/Kconfig" -source "arch/arm/cpu/armv7/tegra114/Kconfig" -source "arch/arm/cpu/armv7/tegra124/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/tegra-common/Makefile b/arch/arm/cpu/armv7/tegra-common/Makefile deleted file mode 100644 index 463c260f18..0000000000 --- a/arch/arm/cpu/armv7/tegra-common/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o diff --git a/arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c b/arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c deleted file mode 100644 index a94ec93e7b..0000000000 --- a/arch/arm/cpu/armv7/tegra-common/cmd_enterrcm.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - * - * Derived from code (arch/arm/lib/reset.c) that is: - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * (C) Copyright 2004 Texas Insturments - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -static int do_enterrcm(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - - puts("Entering RCM...\n"); - udelay(50000); - - pmc->pmc_scratch0 = 2; - disable_interrupts(); - reset_cpu(0); - - return 0; -} - -U_BOOT_CMD( - enterrcm, 1, 0, do_enterrcm, - "reset Tegra and enter USB Recovery Mode", - "" -); diff --git a/arch/arm/cpu/armv7/tegra114/Kconfig b/arch/arm/cpu/armv7/tegra114/Kconfig deleted file mode 100644 index 31012bc770..0000000000 --- a/arch/arm/cpu/armv7/tegra114/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -if TEGRA114 - -choice - prompt "Tegra114 board select" - -config TARGET_DALMORE - bool "NVIDIA Tegra114 Dalmore evaluation board" - -endchoice - -config SYS_SOC - default "tegra114" - -source "board/nvidia/dalmore/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/tegra124/Kconfig b/arch/arm/cpu/armv7/tegra124/Kconfig deleted file mode 100644 index 88f627c932..0000000000 --- a/arch/arm/cpu/armv7/tegra124/Kconfig +++ /dev/null @@ -1,30 +0,0 @@ -if TEGRA124 - -choice - prompt "Tegra124 board select" - -config TARGET_JETSON_TK1 - bool "NVIDIA Tegra124 Jetson TK1 board" - -config TARGET_NYAN_BIG - bool "Google/NVIDIA Nyan-big Chrombook" - help - Nyan Big is a Tegra124 clamshell board that is very similar - to venice2, but it has a different panel, the sdcard CD and WP - sense are flipped, and it has a different revision of the AS3722 - PMIC. The retail name is the Acer Chromebook 13 CB5-311-T7NN - (13.3-inch HD, NVIDIA Tegra K1, 2GB). - -config TARGET_VENICE2 - bool "NVIDIA Tegra124 Venice2" - -endchoice - -config SYS_SOC - default "tegra124" - -source "board/nvidia/jetson-tk1/Kconfig" -source "board/nvidia/nyan-big/Kconfig" -source "board/nvidia/venice2/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/tegra20/Kconfig b/arch/arm/cpu/armv7/tegra20/Kconfig deleted file mode 100644 index a354e2ad1f..0000000000 --- a/arch/arm/cpu/armv7/tegra20/Kconfig +++ /dev/null @@ -1,52 +0,0 @@ -if TEGRA20 - -choice - prompt "Tegra20 board select" - -config TARGET_HARMONY - bool "NVIDIA Tegra20 Harmony evaluation board" - -config TARGET_MEDCOM_WIDE - bool "Avionic Design Medcom-Wide board" - -config TARGET_PAZ00 - bool "Paz00 board" - -config TARGET_PLUTUX - bool "Avionic Design Plutux board" - -config TARGET_SEABOARD - bool "NVIDIA Seaboard" - -config TARGET_TEC - bool "Avionic Design Tamonten Evaluation Carrier" - -config TARGET_TRIMSLICE - bool "Compulab TrimSlice board" - -config TARGET_VENTANA - bool "NVIDIA Tegra20 Ventana evaluation board" - -config TARGET_WHISTLER - bool "NVIDIA Tegra20 Whistler evaluation board" - -config TARGET_COLIBRI_T20_IRIS - bool "Toradex Colibri T20 board" - -endchoice - -config SYS_SOC - default "tegra20" - -source "board/nvidia/harmony/Kconfig" -source "board/avionic-design/medcom-wide/Kconfig" -source "board/compal/paz00/Kconfig" -source "board/avionic-design/plutux/Kconfig" -source "board/nvidia/seaboard/Kconfig" -source "board/avionic-design/tec/Kconfig" -source "board/compulab/trimslice/Kconfig" -source "board/nvidia/ventana/Kconfig" -source "board/nvidia/whistler/Kconfig" -source "board/toradex/colibri_t20_iris/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/tegra20/Makefile b/arch/arm/cpu/armv7/tegra20/Makefile deleted file mode 100644 index 9b4295c72d..0000000000 --- a/arch/arm/cpu/armv7/tegra20/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_PWM_TEGRA) += pwm.o -obj-$(CONFIG_VIDEO_TEGRA) += display.o diff --git a/arch/arm/cpu/armv7/tegra20/display.c b/arch/arm/cpu/armv7/tegra20/display.c deleted file mode 100644 index 61efed6464..0000000000 --- a/arch/arm/cpu/armv7/tegra20/display.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * (C) Copyright 2010 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct fdt_disp_config config; - -static void update_window(struct dc_ctlr *dc, struct disp_ctl_win *win) -{ - unsigned h_dda, v_dda; - unsigned long val; - - val = readl(&dc->cmd.disp_win_header); - val |= WINDOW_A_SELECT; - writel(val, &dc->cmd.disp_win_header); - - writel(win->fmt, &dc->win.color_depth); - - clrsetbits_le32(&dc->win.byte_swap, BYTE_SWAP_MASK, - BYTE_SWAP_NOSWAP << BYTE_SWAP_SHIFT); - - val = win->out_x << H_POSITION_SHIFT; - val |= win->out_y << V_POSITION_SHIFT; - writel(val, &dc->win.pos); - - val = win->out_w << H_SIZE_SHIFT; - val |= win->out_h << V_SIZE_SHIFT; - writel(val, &dc->win.size); - - val = (win->w * win->bpp / 8) << H_PRESCALED_SIZE_SHIFT; - val |= win->h << V_PRESCALED_SIZE_SHIFT; - writel(val, &dc->win.prescaled_size); - - writel(0, &dc->win.h_initial_dda); - writel(0, &dc->win.v_initial_dda); - - h_dda = (win->w * 0x1000) / max(win->out_w - 1, 1U); - v_dda = (win->h * 0x1000) / max(win->out_h - 1, 1U); - - val = h_dda << H_DDA_INC_SHIFT; - val |= v_dda << V_DDA_INC_SHIFT; - writel(val, &dc->win.dda_increment); - - writel(win->stride, &dc->win.line_stride); - writel(0, &dc->win.buf_stride); - - val = WIN_ENABLE; - if (win->bpp < 24) - val |= COLOR_EXPAND; - writel(val, &dc->win.win_opt); - - writel((unsigned long)win->phys_addr, &dc->winbuf.start_addr); - writel(win->x, &dc->winbuf.addr_h_offset); - writel(win->y, &dc->winbuf.addr_v_offset); - - writel(0xff00, &dc->win.blend_nokey); - writel(0xff00, &dc->win.blend_1win); - - val = GENERAL_ACT_REQ | WIN_A_ACT_REQ; - val |= GENERAL_UPDATE | WIN_A_UPDATE; - writel(val, &dc->cmd.state_ctrl); -} - -static void write_pair(struct fdt_disp_config *config, int item, u32 *reg) -{ - writel(config->horiz_timing[item] | - (config->vert_timing[item] << 16), reg); -} - -static int update_display_mode(struct dc_disp_reg *disp, - struct fdt_disp_config *config) -{ - unsigned long val; - unsigned long rate; - unsigned long div; - - writel(0x0, &disp->disp_timing_opt); - write_pair(config, FDT_LCD_TIMING_REF_TO_SYNC, &disp->ref_to_sync); - write_pair(config, FDT_LCD_TIMING_SYNC_WIDTH, &disp->sync_width); - write_pair(config, FDT_LCD_TIMING_BACK_PORCH, &disp->back_porch); - write_pair(config, FDT_LCD_TIMING_FRONT_PORCH, &disp->front_porch); - - writel(config->width | (config->height << 16), &disp->disp_active); - - val = DE_SELECT_ACTIVE << DE_SELECT_SHIFT; - val |= DE_CONTROL_NORMAL << DE_CONTROL_SHIFT; - writel(val, &disp->data_enable_opt); - - val = DATA_FORMAT_DF1P1C << DATA_FORMAT_SHIFT; - val |= DATA_ALIGNMENT_MSB << DATA_ALIGNMENT_SHIFT; - val |= DATA_ORDER_RED_BLUE << DATA_ORDER_SHIFT; - writel(val, &disp->disp_interface_ctrl); - - /* - * The pixel clock divider is in 7.1 format (where the bottom bit - * represents 0.5). Here we calculate the divider needed to get from - * the display clock (typically 600MHz) to the pixel clock. We round - * up or down as requried. - */ - rate = clock_get_periph_rate(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL); - div = ((rate * 2 + config->pixel_clock / 2) / config->pixel_clock) - 2; - debug("Display clock %lu, divider %lu\n", rate, div); - - writel(0x00010001, &disp->shift_clk_opt); - - val = PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT; - val |= div << SHIFT_CLK_DIVIDER_SHIFT; - writel(val, &disp->disp_clk_ctrl); - - return 0; -} - -/* Start up the display and turn on power to PWMs */ -static void basic_init(struct dc_cmd_reg *cmd) -{ - u32 val; - - writel(0x00000100, &cmd->gen_incr_syncpt_ctrl); - writel(0x0000011a, &cmd->cont_syncpt_vsync); - writel(0x00000000, &cmd->int_type); - writel(0x00000000, &cmd->int_polarity); - writel(0x00000000, &cmd->int_mask); - writel(0x00000000, &cmd->int_enb); - - val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE; - val |= PW3_ENABLE | PW4_ENABLE | PM0_ENABLE; - val |= PM1_ENABLE; - writel(val, &cmd->disp_pow_ctrl); - - val = readl(&cmd->disp_cmd); - val |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT; - writel(val, &cmd->disp_cmd); -} - -static void basic_init_timer(struct dc_disp_reg *disp) -{ - writel(0x00000020, &disp->mem_high_pri); - writel(0x00000001, &disp->mem_high_pri_timer); -} - -static const u32 rgb_enb_tab[PIN_REG_COUNT] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -static const u32 rgb_polarity_tab[PIN_REG_COUNT] = { - 0x00000000, - 0x01000000, - 0x00000000, - 0x00000000, -}; - -static const u32 rgb_data_tab[PIN_REG_COUNT] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -static const u32 rgb_sel_tab[PIN_OUTPUT_SEL_COUNT] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00210222, - 0x00002200, - 0x00020000, -}; - -static void rgb_enable(struct dc_com_reg *com) -{ - int i; - - for (i = 0; i < PIN_REG_COUNT; i++) { - writel(rgb_enb_tab[i], &com->pin_output_enb[i]); - writel(rgb_polarity_tab[i], &com->pin_output_polarity[i]); - writel(rgb_data_tab[i], &com->pin_output_data[i]); - } - - for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++) - writel(rgb_sel_tab[i], &com->pin_output_sel[i]); -} - -static int setup_window(struct disp_ctl_win *win, - struct fdt_disp_config *config) -{ - win->x = 0; - win->y = 0; - win->w = config->width; - win->h = config->height; - win->out_x = 0; - win->out_y = 0; - win->out_w = config->width; - win->out_h = config->height; - win->phys_addr = config->frame_buffer; - win->stride = config->width * (1 << config->log2_bpp) / 8; - debug("%s: depth = %d\n", __func__, config->log2_bpp); - switch (config->log2_bpp) { - case 5: - case 24: - win->fmt = COLOR_DEPTH_R8G8B8A8; - win->bpp = 32; - break; - case 4: - win->fmt = COLOR_DEPTH_B5G6R5; - win->bpp = 16; - break; - - default: - debug("Unsupported LCD bit depth"); - return -1; - } - - return 0; -} - -struct fdt_disp_config *tegra_display_get_config(void) -{ - return config.valid ? &config : NULL; -} - -static void debug_timing(const char *name, unsigned int timing[]) -{ -#ifdef DEBUG - int i; - - debug("%s timing: ", name); - for (i = 0; i < FDT_LCD_TIMING_COUNT; i++) - debug("%d ", timing[i]); - debug("\n"); -#endif -} - -/** - * Decode panel information from the fdt, according to a standard binding - * - * @param blob fdt blob - * @param node offset of fdt node to read from - * @param config structure to store fdt config into - * @return 0 if ok, -ve on error - */ -static int tegra_decode_panel(const void *blob, int node, - struct fdt_disp_config *config) -{ - int front, back, ref; - - config->width = fdtdec_get_int(blob, node, "xres", -1); - config->height = fdtdec_get_int(blob, node, "yres", -1); - config->pixel_clock = fdtdec_get_int(blob, node, "clock", 0); - if (!config->pixel_clock || config->width == -1 || - config->height == -1) { - debug("%s: Pixel parameters missing\n", __func__); - return -FDT_ERR_NOTFOUND; - } - - back = fdtdec_get_int(blob, node, "left-margin", -1); - front = fdtdec_get_int(blob, node, "right-margin", -1); - ref = fdtdec_get_int(blob, node, "hsync-len", -1); - if ((back | front | ref) == -1) { - debug("%s: Horizontal parameters missing\n", __func__); - return -FDT_ERR_NOTFOUND; - } - - /* Use a ref-to-sync of 1 always, and take this from the front porch */ - config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; - config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; - config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back; - config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - - config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC]; - debug_timing("horiz", config->horiz_timing); - - back = fdtdec_get_int(blob, node, "upper-margin", -1); - front = fdtdec_get_int(blob, node, "lower-margin", -1); - ref = fdtdec_get_int(blob, node, "vsync-len", -1); - if ((back | front | ref) == -1) { - debug("%s: Vertical parameters missing\n", __func__); - return -FDT_ERR_NOTFOUND; - } - - config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; - config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; - config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back; - config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - - config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC]; - debug_timing("vert", config->vert_timing); - - return 0; -} - -/** - * Decode the display controller information from the fdt. - * - * @param blob fdt blob - * @param config structure to store fdt config into - * @return 0 if ok, -ve on error - */ -static int tegra_display_decode_config(const void *blob, - struct fdt_disp_config *config) -{ - int node, rgb; - int bpp, bit; - - /* TODO: Support multiple controllers */ - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC); - if (node < 0) { - debug("%s: Cannot find display controller node in fdt\n", - __func__); - return node; - } - config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg"); - if (!config->disp) { - debug("%s: No display controller address\n", __func__); - return -1; - } - - rgb = fdt_subnode_offset(blob, node, "rgb"); - - config->panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel"); - if (config->panel_node < 0) { - debug("%s: Cannot find panel information\n", __func__); - return -1; - } - - if (tegra_decode_panel(blob, config->panel_node, config)) { - debug("%s: Failed to decode panel information\n", __func__); - return -1; - } - - bpp = fdtdec_get_int(blob, config->panel_node, "nvidia,bits-per-pixel", - -1); - bit = ffs(bpp) - 1; - if (bpp == (1 << bit)) - config->log2_bpp = bit; - else - config->log2_bpp = bpp; - if (bpp == -1) { - debug("%s: Pixel bpp parameters missing\n", __func__); - return -FDT_ERR_NOTFOUND; - } - config->bpp = bpp; - - config->valid = 1; /* we have a valid configuration */ - - return 0; -} - -int tegra_display_probe(const void *blob, void *default_lcd_base) -{ - struct disp_ctl_win window; - struct dc_ctlr *dc; - - if (tegra_display_decode_config(blob, &config)) - return -1; - - config.frame_buffer = (u32)default_lcd_base; - - dc = (struct dc_ctlr *)config.disp; - - /* - * A header file for clock constants was NAKed upstream. - * TODO: Put this into the FDT and fdt_lcd struct when we have clock - * support there - */ - clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, - 144 * 1000000); - clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL, - 600 * 1000000); - basic_init(&dc->cmd); - basic_init_timer(&dc->disp); - rgb_enable(&dc->com); - - if (config.pixel_clock) - update_display_mode(&dc->disp, &config); - - if (setup_window(&window, &config)) - return -1; - - update_window(dc, &window); - - return 0; -} diff --git a/arch/arm/cpu/armv7/tegra20/pwm.c b/arch/arm/cpu/armv7/tegra20/pwm.c deleted file mode 100644 index 5b886363f8..0000000000 --- a/arch/arm/cpu/armv7/tegra20/pwm.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Tegra2 pulse width frequency modulator definitions - * - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -struct pwm_info { - struct pwm_ctlr *pwm; /* Registers for our pwm controller */ - int pwm_node; /* PWM device tree node */ -} local; - -void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider) -{ - u32 reg; - - assert(channel < PWM_NUM_CHANNELS); - - /* TODO: Can we use clock_adjust_periph_pll_div() here? */ - clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, rate); - - reg = PWM_ENABLE_MASK; - reg |= pulse_width << PWM_WIDTH_SHIFT; - reg |= freq_divider << PWM_DIVIDER_SHIFT; - writel(reg, &local.pwm[channel].control); - debug("%s: channel=%d, rate=%d\n", __func__, channel, rate); -} - -int pwm_request(const void *blob, int node, const char *prop_name) -{ - int pwm_node; - u32 data[3]; - - if (fdtdec_get_int_array(blob, node, prop_name, data, - ARRAY_SIZE(data))) { - debug("%s: Cannot decode PWM property '%s'\n", __func__, - prop_name); - return -1; - } - - pwm_node = fdt_node_offset_by_phandle(blob, data[0]); - if (pwm_node != local.pwm_node) { - debug("%s: PWM property '%s' phandle %d not recognised" - "- expecting %d\n", __func__, prop_name, data[0], - local.pwm_node); - return -1; - } - if (data[1] >= PWM_NUM_CHANNELS) { - debug("%s: PWM property '%s': invalid channel %u\n", __func__, - prop_name, data[1]); - return -1; - } - - /* - * TODO: We could maintain a list of requests, but it might not be - * worth it for U-Boot. - */ - return data[1]; -} - -int pwm_init(const void *blob) -{ - local.pwm_node = fdtdec_next_compatible(blob, 0, - COMPAT_NVIDIA_TEGRA20_PWM); - if (local.pwm_node < 0) { - debug("%s: Cannot find device tree node\n", __func__); - return -1; - } - - local.pwm = (struct pwm_ctlr *)fdtdec_get_addr(blob, local.pwm_node, - "reg"); - if (local.pwm == (struct pwm_ctlr *)FDT_ADDR_T_NONE) { - debug("%s: Cannot find pwm reg address\n", __func__); - return -1; - } - debug("Tegra PWM at %p, node %d\n", local.pwm, local.pwm_node); - - return 0; -} diff --git a/arch/arm/cpu/armv7/tegra30/Kconfig b/arch/arm/cpu/armv7/tegra30/Kconfig deleted file mode 100644 index 3abdc7ba17..0000000000 --- a/arch/arm/cpu/armv7/tegra30/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -if TEGRA30 - -choice - prompt "Tegra30 board select" - -config TARGET_APALIS_T30 - bool "Toradex Apalis T30 board" - -config TARGET_BEAVER - bool "NVIDIA Tegra30 Beaver evaluation board" - -config TARGET_CARDHU - bool "NVIDIA Tegra30 Cardhu evaluation board" - -config TARGET_COLIBRI_T30 - bool "Toradex Colibri T30 board" - -config TARGET_TEC_NG - bool "Avionic Design TEC-NG board" - -endchoice - -config SYS_SOC - default "tegra30" - -source "board/toradex/apalis_t30/Kconfig" -source "board/nvidia/beaver/Kconfig" -source "board/nvidia/cardhu/Kconfig" -source "board/toradex/colibri_t30/Kconfig" -source "board/avionic-design/tec-ng/Kconfig" - -endif diff --git a/arch/arm/cpu/tegra-common/Makefile b/arch/arm/cpu/tegra-common/Makefile deleted file mode 100644 index a78869ee23..0000000000 --- a/arch/arm/cpu/tegra-common/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += ap.o -obj-y += board.o -obj-y += cache.o -obj-y += clock.o -obj-y += lowlevel_init.o -obj-y += pinmux-common.o -obj-y += powergate.o -obj-y += xusb-padctl.o -obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o -obj-$(CONFIG_TEGRA124) += vpr.o diff --git a/arch/arm/cpu/tegra-common/ap.c b/arch/arm/cpu/tegra-common/ap.c deleted file mode 100644 index a17dfd1e22..0000000000 --- a/arch/arm/cpu/tegra-common/ap.c +++ /dev/null @@ -1,169 +0,0 @@ -/* -* (C) Copyright 2010-2014 -* NVIDIA Corporation -* - * SPDX-License-Identifier: GPL-2.0+ -*/ - -/* Tegra AP (Application Processor) code */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int tegra_get_chip(void) -{ - int rev; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - - /* - * This is undocumented, Chip ID is bits 15:8 of the register - * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for - * Tegra30, 0x35 for T114, and 0x40 for Tegra124. - */ - rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; - debug("%s: CHIPID is 0x%02X\n", __func__, rev); - - return rev; -} - -int tegra_get_sku_info(void) -{ - int sku_id; - struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; - - sku_id = readl(&fuse->sku_info) & 0xff; - debug("%s: SKU info byte is 0x%02X\n", __func__, sku_id); - - return sku_id; -} - -int tegra_get_chip_sku(void) -{ - uint sku_id, chip_id; - - chip_id = tegra_get_chip(); - sku_id = tegra_get_sku_info(); - - switch (chip_id) { - case CHIPID_TEGRA20: - switch (sku_id) { - case SKU_ID_T20_7: - case SKU_ID_T20: - return TEGRA_SOC_T20; - case SKU_ID_T25SE: - case SKU_ID_AP25: - case SKU_ID_T25: - case SKU_ID_AP25E: - case SKU_ID_T25E: - return TEGRA_SOC_T25; - } - break; - case CHIPID_TEGRA30: - switch (sku_id) { - case SKU_ID_T33: - case SKU_ID_T30: - case SKU_ID_TM30MQS_P_A3: - default: - return TEGRA_SOC_T30; - } - break; - case CHIPID_TEGRA114: - switch (sku_id) { - case SKU_ID_T114_ENG: - case SKU_ID_T114_1: - default: - return TEGRA_SOC_T114; - } - break; - case CHIPID_TEGRA124: - switch (sku_id) { - case SKU_ID_T124_ENG: - default: - return TEGRA_SOC_T124; - } - break; - } - - /* unknown chip/sku id */ - printf("%s: ERROR: UNKNOWN CHIP/SKU ID COMBO (0x%02X/0x%02X)\n", - __func__, chip_id, sku_id); - return TEGRA_SOC_UNKNOWN; -} - -static void enable_scu(void) -{ - struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; - u32 reg; - - /* Only enable the SCU on T20/T25 */ - if (tegra_get_chip() != CHIPID_TEGRA20) - return; - - /* If SCU already setup/enabled, return */ - if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) - return; - - /* Invalidate all ways for all processors */ - writel(0xFFFF, &scu->scu_inv_all); - - /* Enable SCU - bit 0 */ - reg = readl(&scu->scu_ctrl); - reg |= SCU_CTRL_ENABLE; - writel(reg, &scu->scu_ctrl); -} - -static u32 get_odmdata(void) -{ - /* - * ODMDATA is stored in the BCT in IRAM by the BootROM. - * The BCT start and size are stored in the BIT in IRAM. - * Read the data @ bct_start + (bct_size - 12). This works - * on BCTs for currently supported SoCs, which are locked down. - * If this changes in new chips, we can revisit this algorithm. - */ - - u32 bct_start, odmdata; - - bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); - odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); - - return odmdata; -} - -static void init_pmc_scratch(void) -{ - struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - u32 odmdata; - int i; - - /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ - for (i = 0; i < 23; i++) - writel(0, &pmc->pmc_scratch1+i); - - /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ - odmdata = get_odmdata(); - writel(odmdata, &pmc->pmc_scratch20); -} - -void s_init(void) -{ - /* Init PMC scratch memory */ - init_pmc_scratch(); - - enable_scu(); - - /* init the cache */ - config_cache(); - - /* init vpr */ - config_vpr(); -} diff --git a/arch/arm/cpu/tegra-common/board.c b/arch/arm/cpu/tegra-common/board.c deleted file mode 100644 index b6a84a5774..0000000000 --- a/arch/arm/cpu/tegra-common/board.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * (C) Copyright 2010-2014 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -enum { - /* UARTs which we can enable */ - UARTA = 1 << 0, - UARTB = 1 << 1, - UARTC = 1 << 2, - UARTD = 1 << 3, - UARTE = 1 << 4, - UART_COUNT = 5, -}; - -/* Read the RAM size directly from the memory controller */ -unsigned int query_sdram_size(void) -{ - struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; - u32 size_mb; - - size_mb = readl(&mc->mc_emem_cfg); -#if defined(CONFIG_TEGRA20) - debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", size_mb); - size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024); -#else - debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", size_mb); - size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024 * 1024); -#endif - -#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) - /* External memory limited to 2047 MB due to IROM/HI-VEC */ - if (size_mb == SZ_2G) size_mb -= SZ_1M; -#endif - - return size_mb; -} - -int dram_init(void) -{ - /* We do not initialise DRAM here. We just query the size */ - gd->ram_size = query_sdram_size(); - return 0; -} - -#ifdef CONFIG_DISPLAY_BOARDINFO -int checkboard(void) -{ - printf("Board: %s\n", sysinfo.board_string); - return 0; -} -#endif /* CONFIG_DISPLAY_BOARDINFO */ - -static int uart_configs[] = { -#if defined(CONFIG_TEGRA20) - #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) - FUNCMUX_UART1_UAA_UAB, - #elif defined(CONFIG_TEGRA_UARTA_GPU) - FUNCMUX_UART1_GPU, - #elif defined(CONFIG_TEGRA_UARTA_SDIO1) - FUNCMUX_UART1_SDIO1, - #else - FUNCMUX_UART1_IRRX_IRTX, -#endif - FUNCMUX_UART2_UAD, - -1, - FUNCMUX_UART4_GMC, - -1, -#elif defined(CONFIG_TEGRA30) - FUNCMUX_UART1_ULPI, /* UARTA */ - -1, - -1, - -1, - -1, -#elif defined(CONFIG_TEGRA114) - -1, - -1, - -1, - FUNCMUX_UART4_GMI, /* UARTD */ - -1, -#else /* Tegra124 */ - FUNCMUX_UART1_KBC, /* UARTA */ - -1, - -1, - FUNCMUX_UART4_GPIO, /* UARTD */ - -1, -#endif -}; - -/** - * Set up the specified uarts - * - * @param uarts_ids Mask containing UARTs to init (UARTx) - */ -static void setup_uarts(int uart_ids) -{ - static enum periph_id id_for_uart[] = { - PERIPH_ID_UART1, - PERIPH_ID_UART2, - PERIPH_ID_UART3, - PERIPH_ID_UART4, - PERIPH_ID_UART5, - }; - size_t i; - - for (i = 0; i < UART_COUNT; i++) { - if (uart_ids & (1 << i)) { - enum periph_id id = id_for_uart[i]; - - funcmux_select(id, uart_configs[i]); - clock_ll_start_uart(id); - } - } -} - -void board_init_uart_f(void) -{ - int uart_ids = 0; /* bit mask of which UART ids to enable */ - -#ifdef CONFIG_TEGRA_ENABLE_UARTA - uart_ids |= UARTA; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTB - uart_ids |= UARTB; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTC - uart_ids |= UARTC; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTD - uart_ids |= UARTD; -#endif -#ifdef CONFIG_TEGRA_ENABLE_UARTE - uart_ids |= UARTE; -#endif - setup_uarts(uart_ids); -} - -#ifndef CONFIG_SYS_DCACHE_OFF -void enable_caches(void) -{ - /* Enable D-cache. I-cache is already enabled in start.S */ - dcache_enable(); -} -#endif diff --git a/arch/arm/cpu/tegra-common/cache.c b/arch/arm/cpu/tegra-common/cache.c deleted file mode 100644 index 94f5bce90e..0000000000 --- a/arch/arm/cpu/tegra-common/cache.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra cache routines */ - -#include -#include -#include -#include - -void config_cache(void) -{ - u32 reg = 0; - - /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ - asm volatile( - "mrc p15, 0, r0, c1, c0, 1\n" - "orr r0, r0, #0x41\n" - "mcr p15, 0, r0, c1, c0, 1\n"); - - /* Currently, only Tegra114+ needs this L2 cache change to boot Linux */ - if (tegra_get_chip() < CHIPID_TEGRA114) - return; - - /* - * Systems with an architectural L2 cache must not use the PL310. - * Config L2CTLR here for a data RAM latency of 3 cycles. - */ - asm("mrc p15, 1, %0, c9, c0, 2" : : "r" (reg)); - reg &= ~7; - reg |= 2; - asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg)); -} diff --git a/arch/arm/cpu/tegra-common/clock.c b/arch/arm/cpu/tegra-common/clock.c deleted file mode 100644 index 11c7435505..0000000000 --- a/arch/arm/cpu/tegra-common/clock.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra SoC common clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This is our record of the current clock rate of each clock. We don't - * fill all of these in since we are only really interested in clocks which - * we use as parents. - */ -static unsigned pll_rate[CLOCK_ID_COUNT]; - -/* - * The oscillator frequency is fixed to one of four set values. Based on this - * the other clocks are set up appropriately. - */ -static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { - 13000000, - 19200000, - 12000000, - 26000000, -}; - -/* return 1 if a peripheral ID is in range */ -#define clock_type_id_isvalid(id) ((id) >= 0 && \ - (id) < CLOCK_TYPE_COUNT) - -char pllp_valid = 1; /* PLLP is set up correctly */ - -/* return 1 if a periphc_internal_id is in range */ -#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ - (id) < PERIPHC_COUNT) - -/* number of clock outputs of a PLL */ -static const u8 pll_num_clkouts[] = { - 1, /* PLLC */ - 1, /* PLLM */ - 4, /* PLLP */ - 1, /* PLLA */ - 0, /* PLLU */ - 0, /* PLLD */ -}; - -int clock_get_osc_bypass(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; -} - -/* Returns a pointer to the registers of the given pll */ -static struct clk_pll *get_pll(enum clock_id clkid) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - - assert(clock_id_is_pll(clkid)); - return &clkrst->crc_pll[clkid]; -} - -int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, - u32 *divp, u32 *cpcon, u32 *lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - assert(clkid != CLOCK_ID_USB); - - /* Safety check, adds to code size but is small */ - if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) - return -1; - data = readl(&pll->pll_base); - *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; - *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - data = readl(&pll->pll_misc); - *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; - *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; - - return 0; -} - -unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, - u32 divp, u32 cpcon, u32 lfcon) -{ - struct clk_pll *pll = get_pll(clkid); - u32 data; - - /* - * We cheat by treating all PLL (except PLLU) in the same fashion. - * This works only because: - * - same fields are always mapped at same offsets, except DCCON - * - DCCON is always 0, doesn't conflict - * - M,N, P of PLLP values are ignored for PLLP - */ - data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); - writel(data, &pll->pll_misc); - - data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | - (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); - - if (clkid == CLOCK_ID_USB) - data |= divp << PLLU_VCO_FREQ_SHIFT; - else - data |= divp << PLL_DIVP_SHIFT; - writel(data, &pll->pll_base); - - /* calculate the stable time */ - return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; -} - -void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, - unsigned divisor) -{ - u32 *reg = get_periph_source_reg(periph_id); - u32 value; - - value = readl(reg); - - value &= ~OUT_CLK_SOURCE_31_30_MASK; - value |= source << OUT_CLK_SOURCE_31_30_SHIFT; - - value &= ~OUT_CLK_DIVISOR_MASK; - value |= divisor << OUT_CLK_DIVISOR_SHIFT; - - writel(value, reg); -} - -void clock_ll_set_source(enum periph_id periph_id, unsigned source) -{ - u32 *reg = get_periph_source_reg(periph_id); - - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_30_MASK, - source << OUT_CLK_SOURCE_31_30_SHIFT); -} - -/** - * Given the parent's rate and the required rate for the children, this works - * out the peripheral clock divider to use, in 7.1 binary format. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @return divider which should be used - */ -static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate) -{ - u64 divider = parent_rate * 2; - unsigned max_divider = 1 << divider_bits; - - divider += rate - 1; - do_div(divider, rate); - - if ((s64)divider - 2 < 0) - return 0; - - if ((s64)divider - 2 >= max_divider) - return -1; - - return divider - 2; -} - -int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) -{ - struct clk_pll *pll = get_pll(clkid); - int data = 0, div = 0, offset = 0; - - if (!clock_id_is_pll(clkid)) - return -1; - - if (pllout + 1 > pll_num_clkouts[clkid]) - return -1; - - div = clk_get_divider(8, pll_rate[clkid], rate); - - if (div < 0) - return -1; - - /* out2 and out4 are in the high part of the register */ - if (pllout == PLL_OUT2 || pllout == PLL_OUT4) - offset = 16; - - data = (div << PLL_OUT_RATIO_SHIFT) | - PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; - clrsetbits_le32(&pll->pll_out[pllout >> 1], - PLL_OUT_RATIO_MASK << offset, data << offset); - - return 0; -} - -/** - * Given the parent's rate and the divider in 7.1 format, this works out the - * resulting peripheral clock rate. - * - * @param parent_rate clock rate of parent clock in Hz - * @param divider which should be used in 7.1 format - * @return effective clock rate of peripheral - */ -static unsigned long get_rate_from_divider(unsigned long parent_rate, - int divider) -{ - u64 rate; - - rate = (u64)parent_rate * 2; - do_div(rate, divider + 2); - return rate; -} - -unsigned long clock_get_periph_rate(enum periph_id periph_id, - enum clock_id parent) -{ - u32 *reg = get_periph_source_reg(periph_id); - - return get_rate_from_divider(pll_rate[parent], - (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); -} - -/** - * Find the best available 7.1 format divisor given a parent clock rate and - * required child clock rate. This function assumes that a second-stage - * divisor is available which can divide by powers of 2 from 1 to 256. - * - * @param divider_bits number of divider bits (8 or 16) - * @param parent_rate clock rate of parent clock in Hz - * @param rate required clock rate for this clock - * @param extra_div value for the second-stage divisor (not set if this - * function returns -1. - * @return divider which should be used, or -1 if nothing is valid - * - */ -static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, - unsigned long rate, int *extra_div) -{ - int shift; - int best_divider = -1; - int best_error = rate; - - /* try dividers from 1 to 256 and find closest match */ - for (shift = 0; shift <= 8 && best_error > 0; shift++) { - unsigned divided_parent = parent_rate >> shift; - int divider = clk_get_divider(divider_bits, divided_parent, - rate); - unsigned effective_rate = get_rate_from_divider(divided_parent, - divider); - int error = rate - effective_rate; - - /* Given a valid divider, look for the lowest error */ - if (divider != -1 && error < best_error) { - best_error = error; - *extra_div = 1 << shift; - best_divider = divider; - } - } - - /* return what we found - *extra_div will already be set */ - return best_divider; -} - -/** - * Adjust peripheral PLL to use the given divider and source. - * - * @param periph_id peripheral to adjust - * @param source Source number (0-3 or 0-7) - * @param mux_bits Number of mux bits (2 or 4) - * @param divider Required divider in 7.1 or 15.1 format - * @return 0 if ok, -1 on error (requesting a parent clock which is not valid - * for this peripheral) - */ -static int adjust_periph_pll(enum periph_id periph_id, int source, - int mux_bits, unsigned divider) -{ - u32 *reg = get_periph_source_reg(periph_id); - - clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, - divider << OUT_CLK_DIVISOR_SHIFT); - udelay(1); - - /* work out the source clock and set it */ - if (source < 0) - return -1; - - switch (mux_bits) { - case MASK_BITS_31_30: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_30_MASK, - source << OUT_CLK_SOURCE_31_30_SHIFT); - break; - - case MASK_BITS_31_29: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_29_MASK, - source << OUT_CLK_SOURCE_31_29_SHIFT); - break; - - case MASK_BITS_31_28: - clrsetbits_le32(reg, OUT_CLK_SOURCE_31_28_MASK, - source << OUT_CLK_SOURCE_31_28_SHIFT); - break; - - default: - return -1; - } - - udelay(2); - return 0; -} - -unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, - enum clock_id parent, unsigned rate, int *extra_div) -{ - unsigned effective_rate; - int mux_bits, divider_bits, source; - int divider; - int xdiv = 0; - - /* work out the source clock and set it */ - source = get_periph_clock_source(periph_id, parent, &mux_bits, - ÷r_bits); - - divider = find_best_divider(divider_bits, pll_rate[parent], - rate, &xdiv); - if (extra_div) - *extra_div = xdiv; - - assert(divider >= 0); - if (adjust_periph_pll(periph_id, source, mux_bits, divider)) - return -1U; - debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, - get_periph_source_reg(periph_id), - readl(get_periph_source_reg(periph_id))); - - /* Check what we ended up with. This shouldn't matter though */ - effective_rate = clock_get_periph_rate(periph_id, parent); - if (extra_div) - effective_rate /= *extra_div; - if (rate != effective_rate) - debug("Requested clock rate %u not honored (got %u)\n", - rate, effective_rate); - return effective_rate; -} - -unsigned clock_start_periph_pll(enum periph_id periph_id, - enum clock_id parent, unsigned rate) -{ - unsigned effective_rate; - - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - - effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, - NULL); - - reset_set_enable(periph_id, 0); - return effective_rate; -} - -void clock_enable(enum periph_id clkid) -{ - clock_set_enable(clkid, 1); -} - -void clock_disable(enum periph_id clkid) -{ - clock_set_enable(clkid, 0); -} - -void reset_periph(enum periph_id periph_id, int us_delay) -{ - /* Put peripheral into reset */ - reset_set_enable(periph_id, 1); - udelay(us_delay); - - /* Remove reset */ - reset_set_enable(periph_id, 0); - - udelay(us_delay); -} - -void reset_cmplx_set_enable(int cpu, int which, int reset) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 mask; - - /* Form the mask, which depends on the cpu chosen (2 or 4) */ - assert(cpu >= 0 && cpu < MAX_NUM_CPU); - mask = which << cpu; - - /* either enable or disable those reset for that CPU */ - if (reset) - writel(mask, &clkrst->crc_cpu_cmplx_set); - else - writel(mask, &clkrst->crc_cpu_cmplx_clr); -} - -unsigned clock_get_rate(enum clock_id clkid) -{ - struct clk_pll *pll; - u32 base; - u32 divm; - u64 parent_rate; - u64 rate; - - parent_rate = osc_freq[clock_get_osc_freq()]; - if (clkid == CLOCK_ID_OSC) - return parent_rate; - - pll = get_pll(clkid); - base = readl(&pll->pll_base); - - /* Oh for bf_unpack()... */ - rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); - divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; - if (clkid == CLOCK_ID_USB) - divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; - else - divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; - do_div(rate, divm); - return rate; -} - -/** - * Set the output frequency you want for each PLL clock. - * PLL output frequencies are programmed by setting their N, M and P values. - * The governing equations are: - * VCO = (Fi / m) * n, Fo = VCO / (2^p) - * where Fo is the output frequency from the PLL. - * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) - * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 - * Please see Tegra TRM section 5.3 to get the detail for PLL Programming - * - * @param n PLL feedback divider(DIVN) - * @param m PLL input divider(DIVN) - * @param p post divider(DIVP) - * @param cpcon base PLL charge pump(CPCON) - * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot - * be overriden), 1 if PLL is already correct - */ -int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) -{ - u32 base_reg; - u32 misc_reg; - struct clk_pll *pll; - - pll = get_pll(clkid); - - base_reg = readl(&pll->pll_base); - - /* Set BYPASS, m, n and p to PLL_BASE */ - base_reg &= ~PLL_DIVM_MASK; - base_reg |= m << PLL_DIVM_SHIFT; - - base_reg &= ~PLL_DIVN_MASK; - base_reg |= n << PLL_DIVN_SHIFT; - - base_reg &= ~PLL_DIVP_MASK; - base_reg |= p << PLL_DIVP_SHIFT; - - if (clkid == CLOCK_ID_PERIPH) { - /* - * If the PLL is already set up, check that it is correct - * and record this info for clock_verify() to check. - */ - if (base_reg & PLL_BASE_OVRRIDE_MASK) { - base_reg |= PLL_ENABLE_MASK; - if (base_reg != readl(&pll->pll_base)) - pllp_valid = 0; - return pllp_valid ? 1 : -1; - } - base_reg |= PLL_BASE_OVRRIDE_MASK; - } - - base_reg |= PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - /* Set cpcon to PLL_MISC */ - misc_reg = readl(&pll->pll_misc); - misc_reg &= ~PLL_CPCON_MASK; - misc_reg |= cpcon << PLL_CPCON_SHIFT; - writel(misc_reg, &pll->pll_misc); - - /* Enable PLL */ - base_reg |= PLL_ENABLE_MASK; - writel(base_reg, &pll->pll_base); - - /* Disable BYPASS */ - base_reg &= ~PLL_BYPASS_MASK; - writel(base_reg, &pll->pll_base); - - return 0; -} - -void clock_ll_start_uart(enum periph_id periph_id) -{ - /* Assert UART reset and enable clock */ - reset_set_enable(periph_id, 1); - clock_enable(periph_id); - clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ - - /* wait for 2us */ - udelay(2); - - /* De-assert reset to UART */ - reset_set_enable(periph_id, 0); -} - -#ifdef CONFIG_OF_CONTROL -int clock_decode_periph_id(const void *blob, int node) -{ - enum periph_id id; - u32 cell[2]; - int err; - - err = fdtdec_get_int_array(blob, node, "clocks", cell, - ARRAY_SIZE(cell)); - if (err) - return -1; - id = clk_id_to_periph_id(cell[1]); - assert(clock_periph_id_isvalid(id)); - return id; -} -#endif /* CONFIG_OF_CONTROL */ - -int clock_verify(void) -{ - struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); - u32 reg = readl(&pll->pll_base); - - if (!pllp_valid) { - printf("Warning: PLLP %x is not correct\n", reg); - return -1; - } - debug("PLLP %x is correct\n", reg); - return 0; -} - -void clock_init(void) -{ - pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); - pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); - pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); - pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); - pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; - pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU); - debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); - debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); - debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); - debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]); - debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]); - - /* Do any special system timer/TSC setup */ - arch_timer_init(); -} - -static void set_avp_clock_source(u32 src) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 val; - - val = (src << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | - (src << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | - (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); - writel(val, &clkrst->crc_sclk_brst_pol); - udelay(3); -} - -/* - * This function is useful on Tegra30, and any later SoCs that have compatible - * PLLP configuration registers. - */ -void tegra30_set_up_pllp(void) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - /* - * Based on the Tegra TRM, the system clock (which is the AVP clock) can - * run up to 275MHz. On power on, the default sytem clock source is set - * to PLLP_OUT0. This function sets PLLP's (hence PLLP_OUT0's) rate to - * 408MHz which is beyond system clock's upper limit. - * - * The fix is to set the system clock to CLK_M before initializing PLLP, - * and then switch back to PLLP_OUT4, which has an appropriate divider - * configured, after PLLP has been configured - */ - set_avp_clock_source(SCLK_SOURCE_CLKM); - - /* - * PLLP output frequency set to 408Mhz - * PLLC output frequency set to 228Mhz - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); - break; - - case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); - break; - case CLOCK_OSC_FREQ_19_2: - default: - /* - * These are not supported. It is too early to print a - * message and the UART likely won't work anyway due to the - * oscillator being wrong. - */ - break; - } - - /* Set PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ - - /* OUT1, 2 */ - /* Assert RSTN before enable */ - reg = PLLP_OUT2_RSTN_EN | PLLP_OUT1_RSTN_EN; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); - /* Set divisor and reenable */ - reg = (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) - | PLLP_OUT2_OVR | PLLP_OUT2_CLKEN | PLLP_OUT2_RSTN_DIS - | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) - | PLLP_OUT1_OVR | PLLP_OUT1_CLKEN | PLLP_OUT1_RSTN_DIS; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); - - /* OUT3, 4 */ - /* Assert RSTN before enable */ - reg = PLLP_OUT4_RSTN_EN | PLLP_OUT3_RSTN_EN; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); - /* Set divisor and reenable */ - reg = (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) - | PLLP_OUT4_OVR | PLLP_OUT4_CLKEN | PLLP_OUT4_RSTN_DIS - | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) - | PLLP_OUT3_OVR | PLLP_OUT3_CLKEN | PLLP_OUT3_RSTN_DIS; - writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); - - set_avp_clock_source(SCLK_SOURCE_PLLP_OUT4); -} diff --git a/arch/arm/cpu/tegra-common/lowlevel_init.S b/arch/arm/cpu/tegra-common/lowlevel_init.S deleted file mode 100644 index a211bb3b1a..0000000000 --- a/arch/arm/cpu/tegra-common/lowlevel_init.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SoC-specific setup info - * - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - - .align 5 -ENTRY(reset_cpu) - ldr r1, rstctl @ get addr for global reset - @ reg - ldr r3, [r1] - orr r3, r3, #0x10 - str r3, [r1] @ force reset - mov r0, r0 -_loop_forever: - b _loop_forever -rstctl: - .word PRM_RSTCTRL -ENDPROC(reset_cpu) diff --git a/arch/arm/cpu/tegra-common/pinmux-common.c b/arch/arm/cpu/tegra-common/pinmux-common.c deleted file mode 100644 index 6e3ab0c14c..0000000000 --- a/arch/arm/cpu/tegra-common/pinmux-common.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -/* return 1 if a pingrp is in range */ -#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT)) - -/* return 1 if a pmux_func is in range */ -#define pmux_func_isvalid(func) \ - (((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) - -/* return 1 if a pin_pupd_is in range */ -#define pmux_pin_pupd_isvalid(pupd) \ - (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP)) - -/* return 1 if a pin_tristate_is in range */ -#define pmux_pin_tristate_isvalid(tristate) \ - (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE)) - -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC -/* return 1 if a pin_io_is in range */ -#define pmux_pin_io_isvalid(io) \ - (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT)) - -/* return 1 if a pin_lock is in range */ -#define pmux_pin_lock_isvalid(lock) \ - (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE)) - -/* return 1 if a pin_od is in range */ -#define pmux_pin_od_isvalid(od) \ - (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE)) - -/* return 1 if a pin_ioreset_is in range */ -#define pmux_pin_ioreset_isvalid(ioreset) \ - (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \ - ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) - -#ifdef TEGRA_PMX_HAS_RCV_SEL -/* return 1 if a pin_rcv_sel_is in range */ -#define pmux_pin_rcv_sel_isvalid(rcv_sel) \ - (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \ - ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH)) -#endif /* TEGRA_PMX_HAS_RCV_SEL */ -#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ - -#define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset)) - -#if defined(CONFIG_TEGRA20) - -#define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4)) -#define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2) - -#define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4)) -#define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2) - -#define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4)) -#define TRI_SHIFT(grp) ((grp) % 32) - -#else - -#define REG(pin) _R(0x3000 + ((pin) * 4)) - -#define MUX_REG(pin) REG(pin) -#define MUX_SHIFT(pin) 0 - -#define PULL_REG(pin) REG(pin) -#define PULL_SHIFT(pin) 2 - -#define TRI_REG(pin) REG(pin) -#define TRI_SHIFT(pin) 4 - -#endif /* CONFIG_TEGRA20 */ - -#define DRV_REG(group) _R(0x868 + ((group) * 4)) - -#define IO_SHIFT 5 -#define OD_SHIFT 6 -#define LOCK_SHIFT 7 -#define IO_RESET_SHIFT 8 -#define RCV_SEL_SHIFT 9 - -#if !defined(CONFIG_TEGRA20) && !defined(CONFIG_TEGRA30) -/* This register/field only exists on Tegra114 and later */ -#define APB_MISC_PP_PINMUX_GLOBAL_0 0x40 -#define CLAMP_INPUTS_WHEN_TRISTATED 1 - -void pinmux_set_tristate_input_clamping(void) -{ - u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); - u32 val; - - val = readl(reg); - val |= CLAMP_INPUTS_WHEN_TRISTATED; - writel(val, reg); -} -#endif - -void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) -{ - u32 *reg = MUX_REG(pin); - int i, mux = -1; - u32 val; - - if (func == PMUX_FUNC_DEFAULT) - return; - - /* Error check on pin and func */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_func_isvalid(func)); - - if (func >= PMUX_FUNC_RSVD1) { - mux = (func - PMUX_FUNC_RSVD1) & 3; - } else { - /* Search for the appropriate function */ - for (i = 0; i < 4; i++) { - if (tegra_soc_pingroups[pin].funcs[i] == func) { - mux = i; - break; - } - } - } - assert(mux != -1); - - val = readl(reg); - val &= ~(3 << MUX_SHIFT(pin)); - val |= (mux << MUX_SHIFT(pin)); - writel(val, reg); -} - -void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) -{ - u32 *reg = PULL_REG(pin); - u32 val; - - /* Error check on pin and pupd */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_pupd_isvalid(pupd)); - - val = readl(reg); - val &= ~(3 << PULL_SHIFT(pin)); - val |= (pupd << PULL_SHIFT(pin)); - writel(val, reg); -} - -static void pinmux_set_tristate(enum pmux_pingrp pin, int tri) -{ - u32 *reg = TRI_REG(pin); - u32 val; - - /* Error check on pin */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_tristate_isvalid(tri)); - - val = readl(reg); - if (tri == PMUX_TRI_TRISTATE) - val |= (1 << TRI_SHIFT(pin)); - else - val &= ~(1 << TRI_SHIFT(pin)); - writel(val, reg); -} - -void pinmux_tristate_enable(enum pmux_pingrp pin) -{ - pinmux_set_tristate(pin, PMUX_TRI_TRISTATE); -} - -void pinmux_tristate_disable(enum pmux_pingrp pin) -{ - pinmux_set_tristate(pin, PMUX_TRI_NORMAL); -} - -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC -void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) -{ - u32 *reg = REG(pin); - u32 val; - - if (io == PMUX_PIN_NONE) - return; - - /* Error check on pin and io */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_io_isvalid(io)); - - val = readl(reg); - if (io == PMUX_PIN_INPUT) - val |= (io & 1) << IO_SHIFT; - else - val &= ~(1 << IO_SHIFT); - writel(val, reg); -} - -static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) -{ - u32 *reg = REG(pin); - u32 val; - - if (lock == PMUX_PIN_LOCK_DEFAULT) - return; - - /* Error check on pin and lock */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_lock_isvalid(lock)); - - val = readl(reg); - if (lock == PMUX_PIN_LOCK_ENABLE) { - val |= (1 << LOCK_SHIFT); - } else { - if (val & (1 << LOCK_SHIFT)) - printf("%s: Cannot clear LOCK bit!\n", __func__); - val &= ~(1 << LOCK_SHIFT); - } - writel(val, reg); - - return; -} - -static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) -{ - u32 *reg = REG(pin); - u32 val; - - if (od == PMUX_PIN_OD_DEFAULT) - return; - - /* Error check on pin and od */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_od_isvalid(od)); - - val = readl(reg); - if (od == PMUX_PIN_OD_ENABLE) - val |= (1 << OD_SHIFT); - else - val &= ~(1 << OD_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_ioreset(enum pmux_pingrp pin, - enum pmux_pin_ioreset ioreset) -{ - u32 *reg = REG(pin); - u32 val; - - if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) - return; - - /* Error check on pin and ioreset */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_ioreset_isvalid(ioreset)); - - val = readl(reg); - if (ioreset == PMUX_PIN_IO_RESET_ENABLE) - val |= (1 << IO_RESET_SHIFT); - else - val &= ~(1 << IO_RESET_SHIFT); - writel(val, reg); - - return; -} - -#ifdef TEGRA_PMX_HAS_RCV_SEL -static void pinmux_set_rcv_sel(enum pmux_pingrp pin, - enum pmux_pin_rcv_sel rcv_sel) -{ - u32 *reg = REG(pin); - u32 val; - - if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT) - return; - - /* Error check on pin and rcv_sel */ - assert(pmux_pingrp_isvalid(pin)); - assert(pmux_pin_rcv_sel_isvalid(rcv_sel)); - - val = readl(reg); - if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH) - val |= (1 << RCV_SEL_SHIFT); - else - val &= ~(1 << RCV_SEL_SHIFT); - writel(val, reg); - - return; -} -#endif /* TEGRA_PMX_HAS_RCV_SEL */ -#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ - -static void pinmux_config_pingrp(const struct pmux_pingrp_config *config) -{ - enum pmux_pingrp pin = config->pingrp; - - pinmux_set_func(pin, config->func); - pinmux_set_pullupdown(pin, config->pull); - pinmux_set_tristate(pin, config->tristate); -#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC - pinmux_set_io(pin, config->io); - pinmux_set_lock(pin, config->lock); - pinmux_set_od(pin, config->od); - pinmux_set_ioreset(pin, config->ioreset); -#ifdef TEGRA_PMX_HAS_RCV_SEL - pinmux_set_rcv_sel(pin, config->rcv_sel); -#endif -#endif -} - -void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config, - int len) -{ - int i; - - for (i = 0; i < len; i++) - pinmux_config_pingrp(&config[i]); -} - -#ifdef TEGRA_PMX_HAS_DRVGRPS - -#define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT)) - -#define pmux_slw_isvalid(slw) \ - (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX)) - -#define pmux_drv_isvalid(drv) \ - (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX)) - -#define pmux_lpmd_isvalid(lpm) \ - (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X)) - -#define pmux_schmt_isvalid(schmt) \ - (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE)) - -#define pmux_hsm_isvalid(hsm) \ - (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE)) - -#define HSM_SHIFT 2 -#define SCHMT_SHIFT 3 -#define LPMD_SHIFT 4 -#define LPMD_MASK (3 << LPMD_SHIFT) -#define DRVDN_SHIFT 12 -#define DRVDN_MASK (0x7F << DRVDN_SHIFT) -#define DRVUP_SHIFT 20 -#define DRVUP_MASK (0x7F << DRVUP_SHIFT) -#define SLWR_SHIFT 28 -#define SLWR_MASK (3 << SLWR_SHIFT) -#define SLWF_SHIFT 30 -#define SLWF_MASK (3 << SLWF_SHIFT) - -static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (slwf == PMUX_SLWF_NONE) - return; - - /* Error check on pad and slwf */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_slw_isvalid(slwf)); - - val = readl(reg); - val &= ~SLWF_MASK; - val |= (slwf << SLWF_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (slwr == PMUX_SLWR_NONE) - return; - - /* Error check on pad and slwr */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_slw_isvalid(slwr)); - - val = readl(reg); - val &= ~SLWR_MASK; - val |= (slwr << SLWR_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (drvup == PMUX_DRVUP_NONE) - return; - - /* Error check on pad and drvup */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_drv_isvalid(drvup)); - - val = readl(reg); - val &= ~DRVUP_MASK; - val |= (drvup << DRVUP_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (drvdn == PMUX_DRVDN_NONE) - return; - - /* Error check on pad and drvdn */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_drv_isvalid(drvdn)); - - val = readl(reg); - val &= ~DRVDN_MASK; - val |= (drvdn << DRVDN_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (lpmd == PMUX_LPMD_NONE) - return; - - /* Error check pad and lpmd value */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_lpmd_isvalid(lpmd)); - - val = readl(reg); - val &= ~LPMD_MASK; - val |= (lpmd << LPMD_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (schmt == PMUX_SCHMT_NONE) - return; - - /* Error check pad */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_schmt_isvalid(schmt)); - - val = readl(reg); - if (schmt == PMUX_SCHMT_ENABLE) - val |= (1 << SCHMT_SHIFT); - else - val &= ~(1 << SCHMT_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm) -{ - u32 *reg = DRV_REG(grp); - u32 val; - - /* NONE means unspecified/do not change/use POR value */ - if (hsm == PMUX_HSM_NONE) - return; - - /* Error check pad */ - assert(pmux_drvgrp_isvalid(grp)); - assert(pmux_hsm_isvalid(hsm)); - - val = readl(reg); - if (hsm == PMUX_HSM_ENABLE) - val |= (1 << HSM_SHIFT); - else - val &= ~(1 << HSM_SHIFT); - writel(val, reg); - - return; -} - -static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config) -{ - enum pmux_drvgrp grp = config->drvgrp; - - pinmux_set_drvup_slwf(grp, config->slwf); - pinmux_set_drvdn_slwr(grp, config->slwr); - pinmux_set_drvup(grp, config->drvup); - pinmux_set_drvdn(grp, config->drvdn); - pinmux_set_lpmd(grp, config->lpmd); - pinmux_set_schmt(grp, config->schmt); - pinmux_set_hsm(grp, config->hsm); -} - -void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config, - int len) -{ - int i; - - for (i = 0; i < len; i++) - pinmux_config_drvgrp(&config[i]); -} -#endif /* TEGRA_PMX_HAS_DRVGRPS */ diff --git a/arch/arm/cpu/tegra-common/powergate.c b/arch/arm/cpu/tegra-common/powergate.c deleted file mode 100644 index 439cff36b9..0000000000 --- a/arch/arm/cpu/tegra-common/powergate.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include -#include - -#include -#include - -#include -#include - -#define PWRGATE_TOGGLE 0x30 -#define PWRGATE_TOGGLE_START (1 << 8) - -#define REMOVE_CLAMPING 0x34 - -#define PWRGATE_STATUS 0x38 - -static int tegra_powergate_set(enum tegra_powergate id, bool state) -{ - u32 value, mask = state ? (1 << id) : 0, old_mask; - unsigned long start, timeout = 25; - - value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); - old_mask = value & (1 << id); - - if (mask == old_mask) - return 0; - - writel(PWRGATE_TOGGLE_START | id, NV_PA_PMC_BASE + PWRGATE_TOGGLE); - - start = get_timer(0); - - while (get_timer(start) < timeout) { - value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); - if ((value & (1 << id)) == mask) - return 0; - } - - return -ETIMEDOUT; -} - -static int tegra_powergate_power_on(enum tegra_powergate id) -{ - return tegra_powergate_set(id, true); -} - -int tegra_powergate_power_off(enum tegra_powergate id) -{ - return tegra_powergate_set(id, false); -} - -static int tegra_powergate_remove_clamping(enum tegra_powergate id) -{ - unsigned long value; - - /* - * The REMOVE_CLAMPING register has the bits for the PCIE and VDEC - * partitions reversed. This was originally introduced on Tegra20 but - * has since been carried forward for backwards-compatibility. - */ - if (id == TEGRA_POWERGATE_VDEC) - value = 1 << TEGRA_POWERGATE_PCIE; - else if (id == TEGRA_POWERGATE_PCIE) - value = 1 << TEGRA_POWERGATE_VDEC; - else - value = 1 << id; - - writel(value, NV_PA_PMC_BASE + REMOVE_CLAMPING); - - return 0; -} - -int tegra_powergate_sequence_power_up(enum tegra_powergate id, - enum periph_id periph) -{ - int err; - - reset_set_enable(periph, 1); - - err = tegra_powergate_power_on(id); - if (err < 0) - return err; - - clock_enable(periph); - - udelay(10); - - err = tegra_powergate_remove_clamping(id); - if (err < 0) - return err; - - udelay(10); - - reset_set_enable(periph, 0); - - return 0; -} diff --git a/arch/arm/cpu/tegra-common/sys_info.c b/arch/arm/cpu/tegra-common/sys_info.c deleted file mode 100644 index 5933c35ddd..0000000000 --- a/arch/arm/cpu/tegra-common/sys_info.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * (C) Copyright 2010,2011 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -static void upstring(char *s) -{ - while (*s) { - *s = toupper(*s); - s++; - } -} - -/* Print CPU information */ -int print_cpuinfo(void) -{ - char soc_name[10]; - - strncpy(soc_name, CONFIG_SYS_SOC, 10); - upstring(soc_name); - puts(soc_name); - puts("\n"); - - /* TBD: Add printf of major/minor rev info, stepping, etc. */ - return 0; -} diff --git a/arch/arm/cpu/tegra-common/vpr.c b/arch/arm/cpu/tegra-common/vpr.c deleted file mode 100644 index f695811c9b..0000000000 --- a/arch/arm/cpu/tegra-common/vpr.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra vpr routines */ - -#include -#include -#include -#include - -/* Configures VPR. Right now, all we do is turn it off. */ -void config_vpr(void) -{ - struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; - - /* Turn VPR off */ - writel(0, &mc->mc_video_protect_size_mb); - writel(TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED, - &mc->mc_video_protect_reg_ctrl); - /* read back to ensure the write went through */ - readl(&mc->mc_video_protect_reg_ctrl); -} diff --git a/arch/arm/cpu/tegra-common/xusb-padctl.c b/arch/arm/cpu/tegra-common/xusb-padctl.c deleted file mode 100644 index 65f8d2ea96..0000000000 --- a/arch/arm/cpu/tegra-common/xusb-padctl.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include -#include - -#include - -struct tegra_xusb_phy * __weak tegra_xusb_phy_get(unsigned int type) -{ - return NULL; -} - -int __weak tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -int __weak tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) -{ - return -ENOSYS; -} - -void __weak tegra_xusb_padctl_init(const void *fdt) -{ -} diff --git a/arch/arm/cpu/tegra114-common/Makefile b/arch/arm/cpu/tegra114-common/Makefile deleted file mode 100644 index d959b575ce..0000000000 --- a/arch/arm/cpu/tegra114-common/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -obj-y += clock.o funcmux.o pinmux.o diff --git a/arch/arm/cpu/tegra114-common/clock.c b/arch/arm/cpu/tegra114-common/clock.c deleted file mode 100644 index d5194e11b5..0000000000 --- a/arch/arm/cpu/tegra114-common/clock.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra114 Clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Clock types that we can use as a source. The Tegra114 has muxes for the - * peripheral clocks, and in most cases there are four options for the clock - * source. This gives us a clock 'type' and exploits what commonality exists - * in the device. - * - * Letters are obvious, except for T which means CLK_M, and S which means the - * clock derived from 32KHz. Beware that CLK_M (also called OSC in the - * datasheet) and PLL_M are different things. The former is the basic - * clock supplied to the SOC from an external oscillator. The latter is the - * memory clock PLL. - * - * See definitions in clock_id in the header file. - */ -enum clock_type_id { - CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ - CLOCK_TYPE_MCPA, /* and so on */ - CLOCK_TYPE_MCPT, - CLOCK_TYPE_PCM, - CLOCK_TYPE_PCMT, - CLOCK_TYPE_PCMT16, - CLOCK_TYPE_PDCT, - CLOCK_TYPE_ACPT, - CLOCK_TYPE_ASPTE, - CLOCK_TYPE_PMDACD2T, - CLOCK_TYPE_PCST, - - CLOCK_TYPE_COUNT, - CLOCK_TYPE_NONE = -1, /* invalid clock type */ -}; - -enum { - CLOCK_MAX_MUX = 8 /* number of source options for each clock */ -}; - -/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. - * - * Note: - * The extra column in each clock source array is used to store the mask - * bits in its register for the source. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), - CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), - CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_28} -}; - -/* - * Clock type for each peripheral clock source. We put the name in each - * record just so it is easy to match things up - */ -#define TYPE(name, type) type -static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { - /* 0x00 */ - TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), - TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), - - /* 0x08 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_I2C5, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), - - /* 0x10 */ - TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), - - /* 0x18 */ - TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ - TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), - - /* 0x20 */ - TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), - - /* 0x28 */ - TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), - - /* 0x30 */ - TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - - /* 0x38h */ /* Jumps to reg offset 0x3B0h */ - TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ - TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), - - /* 0x40 */ - TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ - TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), - - /* 0x48 */ - TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ - TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - - /* 0x50 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ - TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), -}; - -/* - * This array translates a periph_id to a periphc_internal_id - * - * Not present/matched up: - * uint vi_sensor; _VI_SENSOR_0, 0x1A8 - * SPDIF - which is both 0x08 and 0x0c - * - */ -#define NONE(name) (-1) -#define OFFSET(name, value) PERIPHC_ ## name -static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { - /* Low word: 31:0 */ - NONE(CPU), - NONE(COP), - NONE(TRIGSYS), - NONE(RESERVED3), - NONE(RTC), - NONE(TMR), - PERIPHC_UART1, - PERIPHC_UART2, /* and vfir 0x68 */ - - /* 8 */ - NONE(GPIO), - PERIPHC_SDMMC2, - NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ - PERIPHC_I2S1, - PERIPHC_I2C1, - PERIPHC_NDFLASH, - PERIPHC_SDMMC1, - PERIPHC_SDMMC4, - - /* 16 */ - NONE(RESERVED16), - PERIPHC_PWM, - PERIPHC_I2S2, - PERIPHC_EPP, - PERIPHC_VI, - PERIPHC_G2D, - NONE(USBD), - NONE(ISP), - - /* 24 */ - PERIPHC_G3D, - NONE(RESERVED25), - PERIPHC_DISP2, - PERIPHC_DISP1, - PERIPHC_HOST1X, - NONE(VCP), - PERIPHC_I2S0, - NONE(CACHE2), - - /* Middle word: 63:32 */ - NONE(MEM), - NONE(AHBDMA), - NONE(APBDMA), - NONE(RESERVED35), - NONE(RESERVED36), - NONE(STAT_MON), - NONE(RESERVED38), - NONE(RESERVED39), - - /* 40 */ - NONE(KFUSE), - NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ - PERIPHC_NOR, - NONE(RESERVED43), - PERIPHC_SBC2, - NONE(RESERVED45), - PERIPHC_SBC3, - PERIPHC_I2C5, - - /* 48 */ - NONE(DSI), - PERIPHC_TVO, /* also CVE 0x40 */ - PERIPHC_MIPI, - PERIPHC_HDMI, - NONE(CSI), - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_UART3, - - /* 56 */ - NONE(RESERVED56), - PERIPHC_EMC, - NONE(USB2), - NONE(USB3), - PERIPHC_MPE, - PERIPHC_VDE, - NONE(BSEA), - NONE(BSEV), - - /* Upper word 95:64 */ - PERIPHC_SPEEDO, - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_I2C3, - PERIPHC_SBC4, - PERIPHC_SDMMC3, - NONE(PCIE), - PERIPHC_OWR, - - /* 72 */ - NONE(AFI), - PERIPHC_CSITE, - NONE(PCIEXCLK), - NONE(AVPUCQ), - NONE(RESERVED76), - NONE(RESERVED77), - NONE(RESERVED78), - NONE(DTV), - - /* 80 */ - PERIPHC_NANDSPEED, - PERIPHC_I2CSLOW, - NONE(DSIB), - NONE(RESERVED83), - NONE(IRAMA), - NONE(IRAMB), - NONE(IRAMC), - NONE(IRAMD), - - /* 88 */ - NONE(CRAM2), - NONE(RESERVED89), - NONE(MDOUBLER), - NONE(RESERVED91), - NONE(SUSOUT), - NONE(RESERVED93), - NONE(RESERVED94), - NONE(RESERVED95), - - /* V word: 31:0 */ - NONE(CPUG), - NONE(CPULP), - PERIPHC_G3D2, - PERIPHC_MSELECT, - PERIPHC_TSENSOR, - PERIPHC_I2S3, - PERIPHC_I2S4, - PERIPHC_I2C4, - - /* 08 */ - PERIPHC_SBC5, - PERIPHC_SBC6, - PERIPHC_AUDIO, - NONE(APBIF), - PERIPHC_DAM0, - PERIPHC_DAM1, - PERIPHC_DAM2, - PERIPHC_HDA2CODEC2X, - - /* 16 */ - NONE(ATOMICS), - NONE(RESERVED17), - NONE(RESERVED18), - NONE(RESERVED19), - NONE(RESERVED20), - NONE(RESERVED21), - NONE(RESERVED22), - PERIPHC_ACTMON, - - /* 24 */ - NONE(RESERVED24), - NONE(RESERVED25), - NONE(RESERVED26), - NONE(RESERVED27), - PERIPHC_SATA, - PERIPHC_HDA, - NONE(RESERVED30), - NONE(RESERVED31), - - /* W word: 31:0 */ - NONE(HDA2HDMICODEC), - NONE(RESERVED1_SATACOLD), - NONE(RESERVED2_PCIERX0), - NONE(RESERVED3_PCIERX1), - NONE(RESERVED4_PCIERX2), - NONE(RESERVED5_PCIERX3), - NONE(RESERVED6_PCIERX4), - NONE(RESERVED7_PCIERX5), - - /* 40 */ - NONE(CEC), - NONE(PCIE2_IOBIST), - NONE(EMC_IOBIST), - NONE(HDMI_IOBIST), - NONE(SATA_IOBIST), - NONE(MIPI_IOBIST), - NONE(EMC1_IOBIST), - NONE(XUSB), - - /* 48 */ - NONE(CILAB), - NONE(CILCD), - NONE(CILE), - NONE(DSIA_LP), - NONE(DSIB_LP), - NONE(RESERVED21_ENTROPY), - NONE(RESERVED22_W), - NONE(RESERVED23_W), - - /* 56 */ - NONE(RESERVED24_W), - NONE(AMX0), - NONE(ADX0), - NONE(DVFS), - NONE(XUSB_SS), - NONE(EMC_DLL), - NONE(MC1), - NONE(EMC1), -}; - -/* - * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that T30/T114 support 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. - */ -enum clock_osc_freq clock_get_osc_freq(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ -} - -/* Returns a pointer to the clock source register for a peripheral */ -u32 *get_periph_source_reg(enum periph_id periph_id) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - enum periphc_internal_id internal_id; - - /* Coresight is a special case */ - if (periph_id == PERIPH_ID_CSI) - return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; - - assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); - internal_id = periph_id_to_internal_id[periph_id]; - assert(internal_id != -1); - if (internal_id >= PERIPHC_VW_FIRST) { - internal_id -= PERIPHC_VW_FIRST; - return &clkrst->crc_clk_src_vw[internal_id]; - } else - return &clkrst->crc_clk_src[internal_id]; -} - -/** - * Given a peripheral ID and the required source clock, this returns which - * value should be programmed into the source mux for that peripheral. - * - * There is special code here to handle the one source type with 5 sources. - * - * @param periph_id peripheral to start - * @param source PLL id of required parent clock - * @param mux_bits Set to number of bits in mux register: 2 or 4 - * @param divider_bits Set to number of divider bits (8 or 16) - * @return mux value (0-4, or -1 if not found) - */ -int get_periph_clock_source(enum periph_id periph_id, - enum clock_id parent, int *mux_bits, int *divider_bits) -{ - enum clock_type_id type; - enum periphc_internal_id internal_id; - int mux; - - assert(clock_periph_id_isvalid(periph_id)); - - internal_id = periph_id_to_internal_id[periph_id]; - assert(periphc_internal_id_isvalid(internal_id)); - - type = clock_periph_type[internal_id]; - assert(clock_type_id_isvalid(type)); - - *mux_bits = clock_source[type][CLOCK_MAX_MUX]; - - if (type == CLOCK_TYPE_PCMT16) - *divider_bits = 16; - else - *divider_bits = 8; - - for (mux = 0; mux < CLOCK_MAX_MUX; mux++) - if (clock_source[type][mux] == parent) - return mux; - - /* if we get here, either us or the caller has made a mistake */ - printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, - parent); - return -1; -} - -void clock_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk; - u32 reg; - - /* Enable/disable the clock to this peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) - clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; - else - clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; - reg = readl(clk); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, clk); -} - -void reset_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset; - u32 reg; - - /* Enable/disable reset to the peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if (periph_id < PERIPH_ID_VW_FIRST) - reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; - else - reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; - reg = readl(reset); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, reset); -} - -#ifdef CONFIG_OF_CONTROL -/* - * Convert a device tree clock ID to our peripheral ID. They are mostly - * the same but we are very cautious so we check that a valid clock ID is - * provided. - * - * @param clk_id Clock ID according to tegra114 device tree binding - * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid - */ -enum periph_id clk_id_to_periph_id(int clk_id) -{ - if (clk_id > PERIPH_ID_COUNT) - return PERIPH_ID_NONE; - - switch (clk_id) { - case PERIPH_ID_RESERVED3: - case PERIPH_ID_RESERVED16: - case PERIPH_ID_RESERVED24: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED43: - case PERIPH_ID_RESERVED45: - case PERIPH_ID_RESERVED56: - case PERIPH_ID_RESERVED76: - case PERIPH_ID_RESERVED77: - case PERIPH_ID_RESERVED78: - case PERIPH_ID_RESERVED83: - case PERIPH_ID_RESERVED89: - case PERIPH_ID_RESERVED91: - case PERIPH_ID_RESERVED93: - case PERIPH_ID_RESERVED94: - case PERIPH_ID_RESERVED95: - return PERIPH_ID_NONE; - default: - return clk_id; - } -} -#endif /* CONFIG_OF_CONTROL */ - -void clock_early_init(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - - tegra30_set_up_pllp(); - - /* - * PLLC output frequency set to 600Mhz - * PLLD output frequency set to 925Mhz - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); - break; - - case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); - break; - case CLOCK_OSC_FREQ_19_2: - default: - /* - * These are not supported. It is too early to print a - * message and the UART likely won't work anyway due to the - * oscillator being wrong. - */ - break; - } - - /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ - writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); - - /* PLLC_MISC: Set LOCK_ENABLE */ - writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); - udelay(2); - - /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ - writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); - udelay(2); -} - -void arch_timer_init(void) -{ - struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; - u32 freq, val; - - freq = clock_get_rate(CLOCK_ID_OSC); - debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq); - - /* ARM CNTFRQ */ - asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); - - /* Only T114 has the System Counter regs */ - debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); - writel(freq, &sysctr->cntfid0); - - val = readl(&sysctr->cntcr); - val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; - writel(val, &sysctr->cntcr); - debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); -} diff --git a/arch/arm/cpu/tegra114-common/funcmux.c b/arch/arm/cpu/tegra114-common/funcmux.c deleted file mode 100644 index 52441c71e6..0000000000 --- a/arch/arm/cpu/tegra114-common/funcmux.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra114 high-level function multiplexing */ - -#include -#include -#include -#include - -int funcmux_select(enum periph_id id, int config) -{ - int bad_config = config != FUNCMUX_DEFAULT; - - switch (id) { - case PERIPH_ID_UART4: - switch (config) { - case FUNCMUX_UART4_GMI: - pinmux_set_func(PMUX_PINGRP_GMI_A16_PJ7, - PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_GMI_A17_PB0, - PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_GMI_A18_PB1, - PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_GMI_A19_PK7, - PMUX_FUNC_UARTD); - - pinmux_set_io(PMUX_PINGRP_GMI_A16_PJ7, PMUX_PIN_OUTPUT); - pinmux_set_io(PMUX_PINGRP_GMI_A17_PB0, PMUX_PIN_INPUT); - pinmux_set_io(PMUX_PINGRP_GMI_A18_PB1, PMUX_PIN_INPUT); - pinmux_set_io(PMUX_PINGRP_GMI_A19_PK7, PMUX_PIN_OUTPUT); - - pinmux_tristate_disable(PMUX_PINGRP_GMI_A16_PJ7); - pinmux_tristate_disable(PMUX_PINGRP_GMI_A17_PB0); - pinmux_tristate_disable(PMUX_PINGRP_GMI_A18_PB1); - pinmux_tristate_disable(PMUX_PINGRP_GMI_A19_PK7); - break; - } - break; - - /* Add other periph IDs here as needed */ - - default: - debug("%s: invalid periph_id %d", __func__, id); - return -1; - } - - if (bad_config) { - debug("%s: invalid config %d for periph_id %d", __func__, - config, id); - return -1; - } - return 0; -} diff --git a/arch/arm/cpu/tegra114-common/pinmux.c b/arch/arm/cpu/tegra114-common/pinmux.c deleted file mode 100644 index 3e5acb93ce..0000000000 --- a/arch/arm/cpu/tegra114-common/pinmux.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define PIN(pin, f0, f1, f2, f3) \ - { \ - .funcs = { \ - PMUX_FUNC_##f0, \ - PMUX_FUNC_##f1, \ - PMUX_FUNC_##f2, \ - PMUX_FUNC_##f3, \ - }, \ - } - -#define PIN_RESERVED {} - -static const struct pmux_pingrp_desc tegra114_pingroups[] = { - /* pin, f0, f1, f2, f3 */ - /* Offset 0x3000 */ - PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_CLK_PY0, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_DIR_PY1, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_NXT_PY2, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_STP_PY3, SPI1, SPI5, UARTD, ULPI), - PIN(DAP3_FS_PP0, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(DAP3_DIN_PP1, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(DAP3_DOUT_PP2, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(DAP3_SCLK_PP3, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(PV0, USB, RSVD2, RSVD3, RSVD4), - PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(SDMMC1_CLK_PZ0, SDMMC1, CLK12, RSVD3, RSVD4), - PIN(SDMMC1_CMD_PZ1, SDMMC1, SPDIF, SPI4, UARTA), - PIN(SDMMC1_DAT3_PY4, SDMMC1, SPDIF, SPI4, UARTA), - PIN(SDMMC1_DAT2_PY5, SDMMC1, PWM0, SPI4, UARTA), - PIN(SDMMC1_DAT1_PY6, SDMMC1, PWM1, SPI4, UARTA), - PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, SPI4, UARTA), - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3068 */ - PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), - PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3110 */ - PIN(HDMI_INT_PN7, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), - PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3164 */ - PIN(UART2_RXD_PC3, IRDA, SPDIF, UARTA, SPI4), - PIN(UART2_TXD_PC2, IRDA, SPDIF, UARTA, SPI4), - PIN(UART2_RTS_N_PJ6, UARTA, UARTB, RSVD3, SPI4), - PIN(UART2_CTS_N_PJ5, UARTA, UARTB, RSVD3, SPI4), - PIN(UART3_TXD_PW6, UARTC, RSVD2, RSVD3, SPI4), - PIN(UART3_RXD_PW7, UARTC, RSVD2, RSVD3, SPI4), - PIN(UART3_CTS_N_PA1, UARTC, SDMMC1, DTV, SPI4), - PIN(UART3_RTS_N_PC0, UARTC, PWM0, DTV, DISPLAYA), - PIN(PU0, OWR, UARTA, RSVD3, RSVD4), - PIN(PU1, RSVD1, UARTA, RSVD3, RSVD4), - PIN(PU2, RSVD1, UARTA, RSVD3, RSVD4), - PIN(PU3, PWM0, UARTA, DISPLAYA, DISPLAYB), - PIN(PU4, PWM1, UARTA, DISPLAYA, DISPLAYB), - PIN(PU5, PWM2, UARTA, DISPLAYA, DISPLAYB), - PIN(PU6, PWM3, UARTA, USB, DISPLAYB), - PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), - PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), - PIN(DAP4_FS_PP4, I2S3, RSVD2, DTV, RSVD4), - PIN(DAP4_DIN_PP5, I2S3, RSVD2, RSVD3, RSVD4), - PIN(DAP4_DOUT_PP6, I2S3, RSVD2, DTV, RSVD4), - PIN(DAP4_SCLK_PP7, I2S3, RSVD2, RSVD3, RSVD4), - PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), - PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), - PIN(GMI_WP_N_PC7, RSVD1, NAND, GMI, GMI_ALT), - PIN(GMI_IORDY_PI5, SDMMC2, RSVD2, GMI, TRACE), - PIN(GMI_WAIT_PI7, SPI4, NAND, GMI, DTV), - PIN(GMI_ADV_N_PK0, RSVD1, NAND, GMI, TRACE), - PIN(GMI_CLK_PK1, SDMMC2, NAND, GMI, TRACE), - PIN(GMI_CS0_N_PJ0, RSVD1, NAND, GMI, USB), - PIN(GMI_CS1_N_PJ2, RSVD1, NAND, GMI, SOC), - PIN(GMI_CS2_N_PK3, SDMMC2, NAND, GMI, TRACE), - PIN(GMI_CS3_N_PK4, SDMMC2, NAND, GMI, GMI_ALT), - PIN(GMI_CS4_N_PK2, USB, NAND, GMI, TRACE), - PIN(GMI_CS6_N_PI3, NAND, NAND_ALT, GMI, SPI4), - PIN(GMI_CS7_N_PI6, NAND, NAND_ALT, GMI, SDMMC2), - PIN(GMI_AD0_PG0, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD1_PG1, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD2_PG2, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD3_PG3, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD4_PG4, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD5_PG5, RSVD1, NAND, GMI, SPI4), - PIN(GMI_AD6_PG6, RSVD1, NAND, GMI, SPI4), - PIN(GMI_AD7_PG7, RSVD1, NAND, GMI, SPI4), - PIN(GMI_AD8_PH0, PWM0, NAND, GMI, DTV), - PIN(GMI_AD9_PH1, PWM1, NAND, GMI, CLDVFS), - PIN(GMI_AD10_PH2, PWM2, NAND, GMI, CLDVFS), - PIN(GMI_AD11_PH3, PWM3, NAND, GMI, USB), - PIN(GMI_AD12_PH4, SDMMC2, NAND, GMI, RSVD4), - PIN(GMI_AD13_PH5, SDMMC2, NAND, GMI, RSVD4), - PIN(GMI_AD14_PH6, SDMMC2, NAND, GMI, DTV), - PIN(GMI_AD15_PH7, SDMMC2, NAND, GMI, DTV), - PIN(GMI_A16_PJ7, UARTD, TRACE, GMI, GMI_ALT), - PIN(GMI_A17_PB0, UARTD, RSVD2, GMI, TRACE), - PIN(GMI_A18_PB1, UARTD, RSVD2, GMI, TRACE), - PIN(GMI_A19_PK7, UARTD, SPI4, GMI, TRACE), - PIN(GMI_WR_N_PI0, RSVD1, NAND, GMI, SPI4), - PIN(GMI_OE_N_PI1, RSVD1, NAND, GMI, SOC), - PIN(GMI_DQS_P_PJ3, SDMMC2, NAND, GMI, TRACE), - PIN(GMI_RST_N_PI4, NAND, NAND_ALT, GMI, RSVD4), - PIN(GEN2_I2C_SCL_PT5, I2C2, RSVD2, GMI, RSVD4), - PIN(GEN2_I2C_SDA_PT6, I2C2, RSVD2, GMI, RSVD4), - PIN(SDMMC4_CLK_PCC4, SDMMC4, RSVD2, GMI, RSVD4), - PIN(SDMMC4_CMD_PT7, SDMMC4, RSVD2, GMI, RSVD4), - PIN(SDMMC4_DAT0_PAA0, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT1_PAA1, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT2_PAA2, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT3_PAA3, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT4_PAA4, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT5_PAA5, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT6_PAA6, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT7_PAA7, SDMMC4, RSVD2, GMI, RSVD4), - PIN_RESERVED, - /* Offset 0x3284 */ - PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, RSVD4), - PIN(PCC1, I2S4, RSVD2, RSVD3, RSVD4), - PIN(PBB0, I2S4, VI, VI_ALT1, VI_ALT3), - PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, RSVD4), - PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, RSVD4), - PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, RSVD4), - PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, RSVD4), - PIN(PBB5, VGP5, DISPLAYA, DISPLAYB, RSVD4), - PIN(PBB6, VGP6, DISPLAYA, DISPLAYB, RSVD4), - PIN(PBB7, I2S4, RSVD2, RSVD3, RSVD4), - PIN(PCC2, I2S4, RSVD2, RSVD3, RSVD4), - PIN(JTAG_RTCK, RTCK, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW0_PR0, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW1_PR1, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW2_PR2, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW3_PR3, KBC, DISPLAYA, RSVD3, DISPLAYB), - PIN(KB_ROW4_PR4, KBC, DISPLAYA, SPI2, DISPLAYB), - PIN(KB_ROW5_PR5, KBC, DISPLAYA, SPI2, DISPLAYB), - PIN(KB_ROW6_PR6, KBC, DISPLAYA, DISPLAYA_ALT, DISPLAYB), - PIN(KB_ROW7_PR7, KBC, RSVD2, CLDVFS, UARTA), - PIN(KB_ROW8_PS0, KBC, RSVD2, CLDVFS, UARTA), - PIN(KB_ROW9_PS1, KBC, RSVD2, RSVD3, UARTA), - PIN(KB_ROW10_PS2, KBC, RSVD2, RSVD3, UARTA), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x32fc */ - PIN(KB_COL0_PQ0, KBC, USB, SPI2, EMC_DLL), - PIN(KB_COL1_PQ1, KBC, RSVD2, SPI2, EMC_DLL), - PIN(KB_COL2_PQ2, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_COL3_PQ3, KBC, DISPLAYA, PWM2, UARTA), - PIN(KB_COL4_PQ4, KBC, OWR, SDMMC3, UARTA), - PIN(KB_COL5_PQ5, KBC, RSVD2, SDMMC1, RSVD4), - PIN(KB_COL6_PQ6, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_COL7_PQ7, KBC, RSVD2, SPI2, RSVD4), - PIN(CLK_32K_OUT_PA0, BLINK, SOC, RSVD3, RSVD4), - PIN(SYS_CLK_REQ_PZ5, SYSCLK, RSVD2, RSVD3, RSVD4), - PIN(CORE_PWR_REQ, PWRON, RSVD2, RSVD3, RSVD4), - PIN(CPU_PWR_REQ, CPU, RSVD2, RSVD3, RSVD4), - PIN(PWR_INT_N, PMI, RSVD2, RSVD3, RSVD4), - PIN(CLK_32K_IN, CLK, RSVD2, RSVD3, RSVD4), - PIN(OWR, OWR, RSVD2, RSVD3, RSVD4), - PIN(DAP1_FS_PN0, I2S0, HDA, GMI, RSVD4), - PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, RSVD4), - PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, RSVD4), - PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, RSVD4), - PIN(CLK1_REQ_PEE2, DAP, DAP1, RSVD3, RSVD4), - PIN(CLK1_OUT_PW4, EXTPERIPH1, DAP2, RSVD3, RSVD4), - PIN(SPDIF_IN_PK6, SPDIF, USB, RSVD3, RSVD4), - PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, RSVD3, RSVD4), - PIN(DAP2_FS_PA2, I2S1, HDA, RSVD3, RSVD4), - PIN(DAP2_DIN_PA4, I2S1, HDA, RSVD3, RSVD4), - PIN(DAP2_DOUT_PA5, I2S1, HDA, RSVD3, RSVD4), - PIN(DAP2_SCLK_PA3, I2S1, HDA, RSVD3, RSVD4), - PIN(DVFS_PWM_PX0, SPI6, CLDVFS, RSVD3, RSVD4), - PIN(GPIO_X1_AUD_PX1, SPI6, RSVD2, RSVD3, RSVD4), - PIN(GPIO_X3_AUD_PX3, SPI6, SPI1, RSVD3, RSVD4), - PIN(DVFS_CLK_PX2, SPI6, CLDVFS, RSVD3, RSVD4), - PIN(GPIO_X4_AUD_PX4, RSVD1, SPI1, SPI2, DAP2), - PIN(GPIO_X5_AUD_PX5, RSVD1, SPI1, SPI2, RSVD4), - PIN(GPIO_X6_AUD_PX6, SPI6, SPI1, SPI2, RSVD4), - PIN(GPIO_X7_AUD_PX7, RSVD1, SPI1, SPI2, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3390 */ - PIN(SDMMC3_CLK_PA6, SDMMC3, RSVD2, RSVD3, SPI3), - PIN(SDMMC3_CMD_PA7, SDMMC3, PWM3, UARTA, SPI3), - PIN(SDMMC3_DAT0_PB7, SDMMC3, RSVD2, RSVD3, SPI3), - PIN(SDMMC3_DAT1_PB6, SDMMC3, PWM2, UARTA, SPI3), - PIN(SDMMC3_DAT2_PB5, SDMMC3, PWM1, DISPLAYA, SPI3), - PIN(SDMMC3_DAT3_PB4, SDMMC3, PWM0, DISPLAYB, SPI3), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x33e0 */ - PIN(HDMI_CEC_PEE3, CEC, SDMMC3, RSVD3, SOC), - PIN(SDMMC1_WP_N_PV3, SDMMC1, CLK12, SPI4, UARTA), - PIN(SDMMC3_CD_N_PV2, SDMMC3, OWR, RSVD3, RSVD4), - PIN(GPIO_W2_AUD_PW2, SPI6, RSVD2, SPI2, I2C1), - PIN(GPIO_W3_AUD_PW3, SPI6, SPI1, SPI2, I2C1), - PIN(USB_VBUS_EN0_PN4, USB, RSVD2, RSVD3, RSVD4), - PIN(USB_VBUS_EN1_PN5, USB, RSVD2, RSVD3, RSVD4), - PIN(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, RSVD2, RSVD3, RSVD4), - PIN(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, RSVD2, RSVD3, RSVD4), - PIN(GMI_CLK_LB, SDMMC2, NAND, GMI, RSVD4), - PIN(RESET_OUT_N, RSVD1, RSVD2, RSVD3, RESET_OUT_N), -}; -const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra114_pingroups; diff --git a/arch/arm/cpu/tegra124-common/Makefile b/arch/arm/cpu/tegra124-common/Makefile deleted file mode 100644 index 7b59fb1216..0000000000 --- a/arch/arm/cpu/tegra124-common/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2013-2014 -# NVIDIA Corporation -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += clock.o -obj-y += funcmux.o -obj-y += pinmux.o -obj-y += xusb-padctl.o diff --git a/arch/arm/cpu/tegra124-common/clock.c b/arch/arm/cpu/tegra124-common/clock.c deleted file mode 100644 index fc8bd194dd..0000000000 --- a/arch/arm/cpu/tegra124-common/clock.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * (C) Copyright 2013 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Tegra124 Clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Clock types that we can use as a source. The Tegra124 has muxes for the - * peripheral clocks, and in most cases there are four options for the clock - * source. This gives us a clock 'type' and exploits what commonality exists - * in the device. - * - * Letters are obvious, except for T which means CLK_M, and S which means the - * clock derived from 32KHz. Beware that CLK_M (also called OSC in the - * datasheet) and PLL_M are different things. The former is the basic - * clock supplied to the SOC from an external oscillator. The latter is the - * memory clock PLL. - * - * See definitions in clock_id in the header file. - */ -enum clock_type_id { - CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ - CLOCK_TYPE_MCPA, /* and so on */ - CLOCK_TYPE_MCPT, - CLOCK_TYPE_PCM, - CLOCK_TYPE_PCMT, - CLOCK_TYPE_PDCT, - CLOCK_TYPE_ACPT, - CLOCK_TYPE_ASPTE, - CLOCK_TYPE_PMDACD2T, - CLOCK_TYPE_PCST, - - CLOCK_TYPE_PC2CC3M, - CLOCK_TYPE_PC2CC3S_T, - CLOCK_TYPE_PC2CC3M_T, - CLOCK_TYPE_PC2CC3M_T16, /* PC2CC3M_T, but w/16-bit divisor (I2C) */ - CLOCK_TYPE_MC2CC3P_A, - CLOCK_TYPE_M, - CLOCK_TYPE_MCPTM2C2C3, - CLOCK_TYPE_PC2CC3T_S, - CLOCK_TYPE_AC2CC3P_TS2, - - CLOCK_TYPE_COUNT, - CLOCK_TYPE_NONE = -1, /* invalid clock type */ -}; - -enum { - CLOCK_MAX_MUX = 8 /* number of source options for each clock */ -}; - -/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. - * - * Note: - * The extra column in each clock source array is used to store the mask - * bits in its register for the source. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), - CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), - CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_28}, - - /* Additional clock types on Tegra114+ */ - /* CLOCK_TYPE_PC2CC3M */ - { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_PC2CC3S_T */ - { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(SFROM32KHZ), CLK(NONE), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_PC2CC3M_T */ - { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_PC2CC3M_T, w/16-bit divisor (I2C) */ - { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_MC2CC3P_A */ - { CLK(MEMORY), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(PERIPH), CLK(NONE), CLK(AUDIO), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_M */ - { CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - /* CLOCK_TYPE_MCPTM2C2C3 */ - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(MEMORY2), CLK(CGENERAL2), CLK(CGENERAL3), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_PC2CC3T_S */ - { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(OSC), CLK(NONE), CLK(SFROM32KHZ), CLK(NONE), - MASK_BITS_31_29}, - /* CLOCK_TYPE_AC2CC3P_TS2 */ - { CLK(AUDIO), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), - CLK(PERIPH), CLK(NONE), CLK(OSC), CLK(SRC2), - MASK_BITS_31_29}, -}; - -/* - * Clock type for each peripheral clock source. We put the name in each - * record just so it is easy to match things up - */ -#define TYPE(name, type) type -static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { - /* 0x00 */ - TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PC2CC3M), - TYPE(PERIPHC_PWM, CLOCK_TYPE_PC2CC3S_T), - TYPE(PERIPHC_05h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC2, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_SBC3, CLOCK_TYPE_PC2CC3M_T), - - /* 0x08 */ - TYPE(PERIPHC_08h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PC2CC3M_T16), - TYPE(PERIPHC_I2C5, CLOCK_TYPE_PC2CC3M_T16), - TYPE(PERIPHC_0bh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_0ch, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC1, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), - - /* 0x10 */ - TYPE(PERIPHC_10h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_11h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MC2CC3P_A), - TYPE(PERIPHC_13h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_16h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_17h, CLOCK_TYPE_NONE), - - /* 0x18 */ - TYPE(PERIPHC_18h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_VFIR, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_1Bh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_1Ch, CLOCK_TYPE_NONE), - TYPE(PERIPHC_HSI, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_UART1, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_UART2, CLOCK_TYPE_PC2CC3M_T), - - /* 0x20 */ - TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MC2CC3P_A), - TYPE(PERIPHC_21h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_22h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_24h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_25h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2C2, CLOCK_TYPE_PC2CC3M_T16), - TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPTM2C2C3), - - /* 0x28 */ - TYPE(PERIPHC_UART3, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_29h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI_SENSOR, CLOCK_TYPE_MC2CC3P_A), - TYPE(PERIPHC_2bh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_2ch, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC4, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_I2C3, CLOCK_TYPE_PC2CC3M_T16), - TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PC2CC3M_T), - - /* 0x30 */ - TYPE(PERIPHC_UART4, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_UART5, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_VDE, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_OWR, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_NOR, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_CSITE, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_DTV, CLOCK_TYPE_NONE), - - /* 0x38 */ - TYPE(PERIPHC_38h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_39h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_3ah, CLOCK_TYPE_NONE), - TYPE(PERIPHC_3bh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_MSENC, CLOCK_TYPE_MC2CC3P_A), - TYPE(PERIPHC_TSEC, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_3eh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_OSC, CLOCK_TYPE_NONE), - - /* 0x40 */ - TYPE(PERIPHC_40h, CLOCK_TYPE_NONE), /* start with 0x3b0 */ - TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PC2CC3T_S), - TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2C4, CLOCK_TYPE_PC2CC3M_T16), - TYPE(PERIPHC_SBC5, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_SBC6, CLOCK_TYPE_PC2CC3M_T), - - /* 0x48 */ - TYPE(PERIPHC_AUDIO, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_49h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DAM0, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_DAM1, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_DAM2, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PC2CC3S_T), - TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), - - /* 0x50 */ - TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_52h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PC2CC3S_T), - TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), - TYPE(PERIPHC_55h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_56h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_57h, CLOCK_TYPE_NONE), - - /* 0x58 */ - TYPE(PERIPHC_58h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_59h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_5ah, CLOCK_TYPE_NONE), - TYPE(PERIPHC_5bh, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_HDA, CLOCK_TYPE_PC2CC3M_T), - TYPE(PERIPHC_5fh, CLOCK_TYPE_NONE), - - /* 0x60 */ - TYPE(PERIPHC_XUSB_CORE_HOST, CLOCK_TYPE_NONE), - TYPE(PERIPHC_XUSB_FALCON, CLOCK_TYPE_NONE), - TYPE(PERIPHC_XUSB_FS, CLOCK_TYPE_NONE), - TYPE(PERIPHC_XUSB_CORE_DEV, CLOCK_TYPE_NONE), - TYPE(PERIPHC_XUSB_SS, CLOCK_TYPE_NONE), - TYPE(PERIPHC_CILAB, CLOCK_TYPE_NONE), - TYPE(PERIPHC_CILCD, CLOCK_TYPE_NONE), - TYPE(PERIPHC_CILE, CLOCK_TYPE_NONE), - - /* 0x68 */ - TYPE(PERIPHC_DSIA_LP, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DSIB_LP, CLOCK_TYPE_NONE), - TYPE(PERIPHC_ENTROPY, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DVFS_REF, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DVFS_SOC, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TRACECLKIN, CLOCK_TYPE_NONE), - TYPE(PERIPHC_ADX0, CLOCK_TYPE_NONE), - TYPE(PERIPHC_AMX0, CLOCK_TYPE_NONE), - - /* 0x70 */ - TYPE(PERIPHC_EMC_LATENCY, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SOC_THERM, CLOCK_TYPE_NONE), - TYPE(PERIPHC_72h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_73h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_74h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_75h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI_SENSOR2, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2C6, CLOCK_TYPE_PC2CC3M_T16), - - /* 0x78 */ - TYPE(PERIPHC_78h, CLOCK_TYPE_NONE), - TYPE(PERIPHC_EMC_DLL, CLOCK_TYPE_MCPTM2C2C3), - TYPE(PERIPHC_HDMI_AUDIO, CLOCK_TYPE_NONE), - TYPE(PERIPHC_CLK72MHZ, CLOCK_TYPE_NONE), - TYPE(PERIPHC_ADX1, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_AMX1, CLOCK_TYPE_AC2CC3P_TS2), - TYPE(PERIPHC_VIC, CLOCK_TYPE_NONE), - TYPE(PERIPHC_7Fh, CLOCK_TYPE_NONE), -}; - -/* - * This array translates a periph_id to a periphc_internal_id - * - * Not present/matched up: - * uint vi_sensor; _VI_SENSOR_0, 0x1A8 - * SPDIF - which is both 0x08 and 0x0c - * - */ -#define NONE(name) (-1) -#define OFFSET(name, value) PERIPHC_ ## name -static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { - /* Low word: 31:0 */ - NONE(CPU), - NONE(COP), - NONE(TRIGSYS), - NONE(ISPB), - NONE(RESERVED4), - NONE(TMR), - PERIPHC_UART1, - PERIPHC_UART2, /* and vfir 0x68 */ - - /* 8 */ - NONE(GPIO), - PERIPHC_SDMMC2, - PERIPHC_SPDIF_IN, - PERIPHC_I2S1, - PERIPHC_I2C1, - NONE(RESERVED13), - PERIPHC_SDMMC1, - PERIPHC_SDMMC4, - - /* 16 */ - NONE(TCW), - PERIPHC_PWM, - PERIPHC_I2S2, - NONE(RESERVED19), - PERIPHC_VI, - NONE(RESERVED21), - NONE(USBD), - NONE(ISP), - - /* 24 */ - NONE(RESERVED24), - NONE(RESERVED25), - PERIPHC_DISP2, - PERIPHC_DISP1, - PERIPHC_HOST1X, - NONE(VCP), - PERIPHC_I2S0, - NONE(CACHE2), - - /* Middle word: 63:32 */ - NONE(MEM), - NONE(AHBDMA), - NONE(APBDMA), - NONE(RESERVED35), - NONE(RESERVED36), - NONE(STAT_MON), - NONE(RESERVED38), - NONE(FUSE), - - /* 40 */ - NONE(KFUSE), - PERIPHC_SBC1, /* SBCx = SPIx */ - PERIPHC_NOR, - NONE(RESERVED43), - PERIPHC_SBC2, - NONE(XIO), - PERIPHC_SBC3, - PERIPHC_I2C5, - - /* 48 */ - NONE(DSI), - NONE(RESERVED49), - PERIPHC_HSI, - PERIPHC_HDMI, - NONE(CSI), - NONE(RESERVED53), - PERIPHC_I2C2, - PERIPHC_UART3, - - /* 56 */ - NONE(MIPI_CAL), - PERIPHC_EMC, - NONE(USB2), - NONE(USB3), - NONE(RESERVED60), - PERIPHC_VDE, - NONE(BSEA), - NONE(BSEV), - - /* Upper word 95:64 */ - NONE(RESERVED64), - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_I2C3, - PERIPHC_SBC4, - PERIPHC_SDMMC3, - NONE(PCIE), - PERIPHC_OWR, - - /* 72 */ - NONE(AFI), - PERIPHC_CSITE, - NONE(PCIEXCLK), - NONE(AVPUCQ), - NONE(LA), - NONE(TRACECLKIN), - NONE(SOC_THERM), - NONE(DTV), - - /* 80 */ - NONE(RESERVED80), - PERIPHC_I2CSLOW, - NONE(DSIB), - PERIPHC_TSEC, - NONE(RESERVED84), - NONE(RESERVED85), - NONE(RESERVED86), - NONE(EMUCIF), - - /* 88 */ - NONE(RESERVED88), - NONE(XUSB_HOST), - NONE(RESERVED90), - PERIPHC_MSENC, - NONE(RESERVED92), - NONE(RESERVED93), - NONE(RESERVED94), - NONE(XUSB_DEV), - - /* V word: 31:0 */ - NONE(CPUG), - NONE(CPULP), - NONE(V_RESERVED2), - PERIPHC_MSELECT, - NONE(V_RESERVED4), - PERIPHC_I2S3, - PERIPHC_I2S4, - PERIPHC_I2C4, - - /* 104 */ - PERIPHC_SBC5, - PERIPHC_SBC6, - PERIPHC_AUDIO, - NONE(APBIF), - PERIPHC_DAM0, - PERIPHC_DAM1, - PERIPHC_DAM2, - PERIPHC_HDA2CODEC2X, - - /* 112 */ - NONE(ATOMICS), - NONE(V_RESERVED17), - NONE(V_RESERVED18), - NONE(V_RESERVED19), - NONE(V_RESERVED20), - NONE(V_RESERVED21), - NONE(V_RESERVED22), - PERIPHC_ACTMON, - - /* 120 */ - NONE(EXTPERIPH1), - NONE(EXTPERIPH2), - NONE(EXTPERIPH3), - NONE(OOB), - PERIPHC_SATA, - PERIPHC_HDA, - NONE(TZRAM), - NONE(SE), - - /* W word: 31:0 */ - NONE(HDA2HDMICODEC), - NONE(SATACOLD), - NONE(W_RESERVED2), - NONE(W_RESERVED3), - NONE(W_RESERVED4), - NONE(W_RESERVED5), - NONE(W_RESERVED6), - NONE(W_RESERVED7), - - /* 136 */ - NONE(CEC), - NONE(W_RESERVED9), - NONE(W_RESERVED10), - NONE(W_RESERVED11), - NONE(W_RESERVED12), - NONE(W_RESERVED13), - NONE(XUSB_PADCTL), - NONE(W_RESERVED15), - - /* 144 */ - NONE(W_RESERVED16), - NONE(W_RESERVED17), - NONE(W_RESERVED18), - NONE(W_RESERVED19), - NONE(W_RESERVED20), - NONE(ENTROPY), - NONE(DDS), - NONE(W_RESERVED23), - - /* 152 */ - NONE(DP2), - NONE(AMX0), - NONE(ADX0), - NONE(DVFS), - NONE(XUSB_SS), - NONE(W_RESERVED29), - NONE(W_RESERVED30), - NONE(W_RESERVED31), - - /* X word: 31:0 */ - NONE(SPARE), - NONE(X_RESERVED1), - NONE(X_RESERVED2), - NONE(X_RESERVED3), - NONE(CAM_MCLK), - NONE(CAM_MCLK2), - PERIPHC_I2C6, - NONE(X_RESERVED7), - - /* 168 */ - NONE(X_RESERVED8), - NONE(X_RESERVED9), - NONE(X_RESERVED10), - NONE(VIM2_CLK), - NONE(X_RESERVED12), - NONE(X_RESERVED13), - NONE(EMC_DLL), - NONE(X_RESERVED15), - - /* 176 */ - NONE(HDMI_AUDIO), - NONE(CLK72MHZ), - NONE(VIC), - NONE(X_RESERVED19), - NONE(ADX1), - NONE(DPAUX), - NONE(SOR0), - NONE(X_RESERVED23), - - /* 184 */ - NONE(GPU), - NONE(AMX1), - NONE(X_RESERVED26), - NONE(X_RESERVED27), - NONE(X_RESERVED28), - NONE(X_RESERVED29), - NONE(X_RESERVED30), - NONE(X_RESERVED31), -}; - -/* - * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that Tegra30+ support 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. - */ -enum clock_osc_freq clock_get_osc_freq(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ -} - -/* Returns a pointer to the clock source register for a peripheral */ -u32 *get_periph_source_reg(enum periph_id periph_id) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - enum periphc_internal_id internal_id; - - /* Coresight is a special case */ - if (periph_id == PERIPH_ID_CSI) - return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; - - assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); - internal_id = periph_id_to_internal_id[periph_id]; - assert(internal_id != -1); - if (internal_id >= PERIPHC_VW_FIRST) { - internal_id -= PERIPHC_VW_FIRST; - return &clkrst->crc_clk_src_vw[internal_id]; - } else { - return &clkrst->crc_clk_src[internal_id]; - } -} - -/** - * Given a peripheral ID and the required source clock, this returns which - * value should be programmed into the source mux for that peripheral. - * - * There is special code here to handle the one source type with 5 sources. - * - * @param periph_id peripheral to start - * @param source PLL id of required parent clock - * @param mux_bits Set to number of bits in mux register: 2 or 4 - * @param divider_bits Set to number of divider bits (8 or 16) - * @return mux value (0-4, or -1 if not found) - */ -int get_periph_clock_source(enum periph_id periph_id, - enum clock_id parent, int *mux_bits, int *divider_bits) -{ - enum clock_type_id type; - enum periphc_internal_id internal_id; - int mux; - - assert(clock_periph_id_isvalid(periph_id)); - - internal_id = periph_id_to_internal_id[periph_id]; - assert(periphc_internal_id_isvalid(internal_id)); - - type = clock_periph_type[internal_id]; - assert(clock_type_id_isvalid(type)); - - *mux_bits = clock_source[type][CLOCK_MAX_MUX]; - - if (type == CLOCK_TYPE_PC2CC3M_T16) - *divider_bits = 16; - else - *divider_bits = 8; - - for (mux = 0; mux < CLOCK_MAX_MUX; mux++) - if (clock_source[type][mux] == parent) - return mux; - - /* if we get here, either us or the caller has made a mistake */ - printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, - parent); - return -1; -} - -void clock_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk; - u32 reg; - - /* Enable/disable the clock to this peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) - clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; - else - clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; - reg = readl(clk); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, clk); -} - -void reset_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset; - u32 reg; - - /* Enable/disable reset to the peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if (periph_id < PERIPH_ID_VW_FIRST) - reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; - else - reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; - reg = readl(reset); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, reset); -} - -#ifdef CONFIG_OF_CONTROL -/* - * Convert a device tree clock ID to our peripheral ID. They are mostly - * the same but we are very cautious so we check that a valid clock ID is - * provided. - * - * @param clk_id Clock ID according to tegra124 device tree binding - * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid - */ -enum periph_id clk_id_to_periph_id(int clk_id) -{ - if (clk_id > PERIPH_ID_COUNT) - return PERIPH_ID_NONE; - - switch (clk_id) { - case PERIPH_ID_RESERVED4: - case PERIPH_ID_RESERVED25: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED36: - case PERIPH_ID_RESERVED38: - case PERIPH_ID_RESERVED43: - case PERIPH_ID_RESERVED49: - case PERIPH_ID_RESERVED53: - case PERIPH_ID_RESERVED64: - case PERIPH_ID_RESERVED84: - case PERIPH_ID_RESERVED85: - case PERIPH_ID_RESERVED86: - case PERIPH_ID_RESERVED88: - case PERIPH_ID_RESERVED90: - case PERIPH_ID_RESERVED92: - case PERIPH_ID_RESERVED93: - case PERIPH_ID_RESERVED94: - case PERIPH_ID_V_RESERVED2: - case PERIPH_ID_V_RESERVED4: - case PERIPH_ID_V_RESERVED17: - case PERIPH_ID_V_RESERVED18: - case PERIPH_ID_V_RESERVED19: - case PERIPH_ID_V_RESERVED20: - case PERIPH_ID_V_RESERVED21: - case PERIPH_ID_V_RESERVED22: - case PERIPH_ID_W_RESERVED2: - case PERIPH_ID_W_RESERVED3: - case PERIPH_ID_W_RESERVED4: - case PERIPH_ID_W_RESERVED5: - case PERIPH_ID_W_RESERVED6: - case PERIPH_ID_W_RESERVED7: - case PERIPH_ID_W_RESERVED9: - case PERIPH_ID_W_RESERVED10: - case PERIPH_ID_W_RESERVED11: - case PERIPH_ID_W_RESERVED12: - case PERIPH_ID_W_RESERVED13: - case PERIPH_ID_W_RESERVED15: - case PERIPH_ID_W_RESERVED16: - case PERIPH_ID_W_RESERVED17: - case PERIPH_ID_W_RESERVED18: - case PERIPH_ID_W_RESERVED19: - case PERIPH_ID_W_RESERVED20: - case PERIPH_ID_W_RESERVED23: - case PERIPH_ID_W_RESERVED29: - case PERIPH_ID_W_RESERVED30: - case PERIPH_ID_W_RESERVED31: - return PERIPH_ID_NONE; - default: - return clk_id; - } -} -#endif /* CONFIG_OF_CONTROL */ - -void clock_early_init(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - - tegra30_set_up_pllp(); - - /* - * PLLC output frequency set to 600Mhz - * PLLD output frequency set to 925Mhz - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); - break; - - case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ - clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); - clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); - break; - case CLOCK_OSC_FREQ_19_2: - default: - /* - * These are not supported. It is too early to print a - * message and the UART likely won't work anyway due to the - * oscillator being wrong. - */ - break; - } - - /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ - writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); - - /* PLLC_MISC: Set LOCK_ENABLE */ - writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); - udelay(2); - - /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ - writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); - udelay(2); -} - -void arch_timer_init(void) -{ - struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; - u32 freq, val; - - freq = clock_get_rate(CLOCK_ID_OSC); - debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq); - - /* ARM CNTFRQ */ - asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); - - /* Only Tegra114+ has the System Counter regs */ - debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); - writel(freq, &sysctr->cntfid0); - - val = readl(&sysctr->cntcr); - val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; - writel(val, &sysctr->cntcr); - debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); -} - -#define PLLE_SS_CNTL 0x68 -#define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24) -#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) -#define PLLE_SS_CNTL_SSCINVERT (1 << 15) -#define PLLE_SS_CNTL_SSCCENTER (1 << 14) -#define PLLE_SS_CNTL_SSCBYP (1 << 12) -#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) -#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) -#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) - -#define PLLE_BASE 0x0e8 -#define PLLE_BASE_ENABLE (1 << 30) -#define PLLE_BASE_LOCK_OVERRIDE (1 << 29) -#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) -#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) -#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) - -#define PLLE_MISC 0x0ec -#define PLLE_MISC_IDDQ_SWCTL (1 << 14) -#define PLLE_MISC_IDDQ_OVERRIDE (1 << 13) -#define PLLE_MISC_LOCK_ENABLE (1 << 9) -#define PLLE_MISC_PTS (1 << 8) -#define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4) -#define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2) - -#define PLLE_AUX 0x48c -#define PLLE_AUX_SEQ_ENABLE (1 << 24) -#define PLLE_AUX_ENABLE_SWCTL (1 << 4) - -int tegra_plle_enable(void) -{ - unsigned int m = 1, n = 200, cpcon = 13; - u32 value; - - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_LOCK_OVERRIDE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX); - value |= PLLE_AUX_ENABLE_SWCTL; - value &= ~PLLE_AUX_SEQ_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); - - udelay(1); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value |= PLLE_MISC_IDDQ_SWCTL; - value &= ~PLLE_MISC_IDDQ_OVERRIDE; - value |= PLLE_MISC_LOCK_ENABLE; - value |= PLLE_MISC_PTS; - value |= PLLE_MISC_VREG_BG_CTRL(3); - value |= PLLE_MISC_VREG_CTRL(2); - writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); - - udelay(5); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | - PLLE_SS_CNTL_BYPASS_SS; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_PLDIV_CML(0xf); - value &= ~PLLE_BASE_NDIV(0xff); - value &= ~PLLE_BASE_MDIV(0xff); - value |= PLLE_BASE_PLDIV_CML(cpcon); - value |= PLLE_BASE_NDIV(n); - value |= PLLE_BASE_MDIV(m); - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - udelay(1); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value |= PLLE_BASE_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - /* wait for lock */ - udelay(300); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCINVERT; - value &= ~PLLE_SS_CNTL_SSCCENTER; - - value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f); - value &= ~PLLE_SS_CNTL_SSCINC(0xff); - value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); - - value |= PLLE_SS_CNTL_SSCINCINTR(0x20); - value |= PLLE_SS_CNTL_SSCINC(0x01); - value |= PLLE_SS_CNTL_SSCMAX(0x25); - - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCBYP; - value &= ~PLLE_SS_CNTL_BYPASS_SS; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - udelay(1); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_INTERP_RESET; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - udelay(1); - - return 0; -} diff --git a/arch/arm/cpu/tegra124-common/funcmux.c b/arch/arm/cpu/tegra124-common/funcmux.c deleted file mode 100644 index cced787e6b..0000000000 --- a/arch/arm/cpu/tegra124-common/funcmux.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (C) Copyright 2013 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Tegra124 high-level function multiplexing */ - -#include -#include -#include -#include - -int funcmux_select(enum periph_id id, int config) -{ - int bad_config = config != FUNCMUX_DEFAULT; - - switch (id) { - case PERIPH_ID_UART4: - switch (config) { - case FUNCMUX_UART4_GPIO: /* TXD,RXD,CTS,RTS */ - pinmux_set_func(PMUX_PINGRP_PJ7, PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_PB0, PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_PB1, PMUX_FUNC_UARTD); - pinmux_set_func(PMUX_PINGRP_PK7, PMUX_FUNC_UARTD); - - pinmux_set_io(PMUX_PINGRP_PJ7, PMUX_PIN_OUTPUT); - pinmux_set_io(PMUX_PINGRP_PB0, PMUX_PIN_INPUT); - pinmux_set_io(PMUX_PINGRP_PB1, PMUX_PIN_INPUT); - pinmux_set_io(PMUX_PINGRP_PK7, PMUX_PIN_OUTPUT); - - pinmux_tristate_disable(PMUX_PINGRP_PJ7); - pinmux_tristate_disable(PMUX_PINGRP_PB0); - pinmux_tristate_disable(PMUX_PINGRP_PB1); - pinmux_tristate_disable(PMUX_PINGRP_PK7); - break; - } - break; - - case PERIPH_ID_UART1: - switch (config) { - case FUNCMUX_UART1_KBC: - pinmux_set_func(PMUX_PINGRP_KB_ROW9_PS1, - PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_KB_ROW10_PS2, - PMUX_FUNC_UARTA); - - pinmux_set_io(PMUX_PINGRP_KB_ROW9_PS1, PMUX_PIN_OUTPUT); - pinmux_set_io(PMUX_PINGRP_KB_ROW10_PS2, PMUX_PIN_INPUT); - - pinmux_tristate_disable(PMUX_PINGRP_KB_ROW9_PS1); - pinmux_tristate_disable(PMUX_PINGRP_KB_ROW10_PS2); - break; - } - break; - - /* Add other periph IDs here as needed */ - - default: - debug("%s: invalid periph_id %d", __func__, id); - return -1; - } - - if (bad_config) { - debug("%s: invalid config %d for periph_id %d", __func__, - config, id); - return -1; - } - return 0; -} diff --git a/arch/arm/cpu/tegra124-common/pinmux.c b/arch/arm/cpu/tegra124-common/pinmux.c deleted file mode 100644 index c6685eaae1..0000000000 --- a/arch/arm/cpu/tegra124-common/pinmux.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define PIN(pin, f0, f1, f2, f3) \ - { \ - .funcs = { \ - PMUX_FUNC_##f0, \ - PMUX_FUNC_##f1, \ - PMUX_FUNC_##f2, \ - PMUX_FUNC_##f3, \ - }, \ - } - -#define PIN_RESERVED {} - -static const struct pmux_pingrp_desc tegra124_pingroups[] = { - /* pin, f0, f1, f2, f3 */ - /* Offset 0x3000 */ - PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_CLK_PY0, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_DIR_PY1, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_NXT_PY2, SPI1, SPI5, UARTD, ULPI), - PIN(ULPI_STP_PY3, SPI1, SPI5, UARTD, ULPI), - PIN(DAP3_FS_PP0, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(DAP3_DIN_PP1, I2S2, SPI5, DISPLAYA, DISPLAYB), - PIN(DAP3_DOUT_PP2, I2S2, SPI5, DISPLAYA, RSVD4), - PIN(DAP3_SCLK_PP3, I2S2, SPI5, RSVD3, DISPLAYB), - PIN(PV0, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(SDMMC1_CLK_PZ0, SDMMC1, CLK12, RSVD3, RSVD4), - PIN(SDMMC1_CMD_PZ1, SDMMC1, SPDIF, SPI4, UARTA), - PIN(SDMMC1_DAT3_PY4, SDMMC1, SPDIF, SPI4, UARTA), - PIN(SDMMC1_DAT2_PY5, SDMMC1, PWM0, SPI4, UARTA), - PIN(SDMMC1_DAT1_PY6, SDMMC1, PWM1, SPI4, UARTA), - PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, SPI4, UARTA), - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3068 */ - PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), - PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3110 */ - PIN(HDMI_INT_PN7, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), - PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3164 */ - PIN(UART2_RXD_PC3, IRDA, SPDIF, UARTA, SPI4), - PIN(UART2_TXD_PC2, IRDA, SPDIF, UARTA, SPI4), - PIN(UART2_RTS_N_PJ6, UARTA, UARTB, GMI, SPI4), - PIN(UART2_CTS_N_PJ5, UARTA, UARTB, GMI, SPI4), - PIN(UART3_TXD_PW6, UARTC, RSVD2, GMI, SPI4), - PIN(UART3_RXD_PW7, UARTC, RSVD2, GMI, SPI4), - PIN(UART3_CTS_N_PA1, UARTC, SDMMC1, DTV, GMI), - PIN(UART3_RTS_N_PC0, UARTC, PWM0, DTV, GMI), - PIN(PU0, OWR, UARTA, GMI, RSVD4), - PIN(PU1, RSVD1, UARTA, GMI, RSVD4), - PIN(PU2, RSVD1, UARTA, GMI, RSVD4), - PIN(PU3, PWM0, UARTA, GMI, DISPLAYB), - PIN(PU4, PWM1, UARTA, GMI, DISPLAYB), - PIN(PU5, PWM2, UARTA, GMI, DISPLAYB), - PIN(PU6, PWM3, UARTA, RSVD3, GMI), - PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), - PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), - PIN(DAP4_FS_PP4, I2S3, GMI, DTV, RSVD4), - PIN(DAP4_DIN_PP5, I2S3, GMI, RSVD3, RSVD4), - PIN(DAP4_DOUT_PP6, I2S3, GMI, DTV, RSVD4), - PIN(DAP4_SCLK_PP7, I2S3, GMI, RSVD3, RSVD4), - PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), - PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), - PIN(PC7, RSVD1, RSVD2, GMI, GMI_ALT), - PIN(PI5, SDMMC2, RSVD2, GMI, RSVD4), - PIN(PI7, RSVD1, TRACE, GMI, DTV), - PIN(PK0, RSVD1, SDMMC3, GMI, SOC), - PIN(PK1, SDMMC2, TRACE, GMI, RSVD4), - PIN(PJ0, RSVD1, RSVD2, GMI, USB), - PIN(PJ2, RSVD1, RSVD2, GMI, SOC), - PIN(PK3, SDMMC2, TRACE, GMI, CCLA), - PIN(PK4, SDMMC2, RSVD2, GMI, GMI_ALT), - PIN(PK2, RSVD1, RSVD2, GMI, RSVD4), - PIN(PI3, RSVD1, RSVD2, GMI, SPI4), - PIN(PI6, RSVD1, RSVD2, GMI, SDMMC2), - PIN(PG0, RSVD1, RSVD2, GMI, RSVD4), - PIN(PG1, RSVD1, RSVD2, GMI, RSVD4), - PIN(PG2, RSVD1, TRACE, GMI, RSVD4), - PIN(PG3, RSVD1, TRACE, GMI, RSVD4), - PIN(PG4, RSVD1, TMDS, GMI, SPI4), - PIN(PG5, RSVD1, RSVD2, GMI, SPI4), - PIN(PG6, RSVD1, RSVD2, GMI, SPI4), - PIN(PG7, RSVD1, RSVD2, GMI, SPI4), - PIN(PH0, PWM0, TRACE, GMI, DTV), - PIN(PH1, PWM1, TMDS, GMI, DISPLAYA), - PIN(PH2, PWM2, TMDS, GMI, CLDVFS), - PIN(PH3, PWM3, SPI4, GMI, CLDVFS), - PIN(PH4, SDMMC2, RSVD2, GMI, RSVD4), - PIN(PH5, SDMMC2, RSVD2, GMI, RSVD4), - PIN(PH6, SDMMC2, TRACE, GMI, DTV), - PIN(PH7, SDMMC2, TRACE, GMI, DTV), - PIN(PJ7, UARTD, RSVD2, GMI, GMI_ALT), - PIN(PB0, UARTD, RSVD2, GMI, RSVD4), - PIN(PB1, UARTD, RSVD2, GMI, RSVD4), - PIN(PK7, UARTD, RSVD2, GMI, RSVD4), - PIN(PI0, RSVD1, RSVD2, GMI, RSVD4), - PIN(PI1, RSVD1, RSVD2, GMI, RSVD4), - PIN(PI2, SDMMC2, TRACE, GMI, RSVD4), - PIN(PI4, SPI4, TRACE, GMI, DISPLAYA), - PIN(GEN2_I2C_SCL_PT5, I2C2, RSVD2, GMI, RSVD4), - PIN(GEN2_I2C_SDA_PT6, I2C2, RSVD2, GMI, RSVD4), - PIN(SDMMC4_CLK_PCC4, SDMMC4, RSVD2, GMI, RSVD4), - PIN(SDMMC4_CMD_PT7, SDMMC4, RSVD2, GMI, RSVD4), - PIN(SDMMC4_DAT0_PAA0, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT1_PAA1, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT2_PAA2, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT3_PAA3, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT4_PAA4, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT5_PAA5, SDMMC4, SPI3, RSVD3, RSVD4), - PIN(SDMMC4_DAT6_PAA6, SDMMC4, SPI3, GMI, RSVD4), - PIN(SDMMC4_DAT7_PAA7, SDMMC4, RSVD2, GMI, RSVD4), - PIN_RESERVED, - /* Offset 0x3284 */ - PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, SDMMC2), - PIN(PCC1, I2S4, RSVD2, RSVD3, SDMMC2), - PIN(PBB0, VGP6, VIMCLK2, SDMMC2, VIMCLK2_ALT), - PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, SDMMC2), - PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, SDMMC2), - PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, SDMMC2), - PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, SDMMC2), - PIN(PBB5, VGP5, DISPLAYA, RSVD3, SDMMC2), - PIN(PBB6, I2S4, RSVD2, DISPLAYB, SDMMC2), - PIN(PBB7, I2S4, RSVD2, RSVD3, SDMMC2), - PIN(PCC2, I2S4, RSVD2, SDMMC3, SDMMC2), - PIN(JTAG_RTCK, RTCK, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW0_PR0, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW1_PR1, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW2_PR2, KBC, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW3_PR3, KBC, DISPLAYA, SYS, DISPLAYB), - PIN(KB_ROW4_PR4, KBC, DISPLAYA, RSVD3, DISPLAYB), - PIN(KB_ROW5_PR5, KBC, DISPLAYA, RSVD3, DISPLAYB), - PIN(KB_ROW6_PR6, KBC, DISPLAYA, DISPLAYA_ALT, DISPLAYB), - PIN(KB_ROW7_PR7, KBC, RSVD2, CLDVFS, UARTA), - PIN(KB_ROW8_PS0, KBC, RSVD2, CLDVFS, UARTA), - PIN(KB_ROW9_PS1, KBC, RSVD2, RSVD3, UARTA), - PIN(KB_ROW10_PS2, KBC, RSVD2, RSVD3, UARTA), - PIN(KB_ROW11_PS3, KBC, RSVD2, RSVD3, IRDA), - PIN(KB_ROW12_PS4, KBC, RSVD2, RSVD3, IRDA), - PIN(KB_ROW13_PS5, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_ROW14_PS6, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_ROW15_PS7, KBC, SOC, RSVD3, RSVD4), - PIN(KB_COL0_PQ0, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_COL1_PQ1, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_COL2_PQ2, KBC, RSVD2, SPI2, RSVD4), - PIN(KB_COL3_PQ3, KBC, DISPLAYA, PWM2, UARTA), - PIN(KB_COL4_PQ4, KBC, OWR, SDMMC3, UARTA), - PIN(KB_COL5_PQ5, KBC, RSVD2, SDMMC3, RSVD4), - PIN(KB_COL6_PQ6, KBC, RSVD2, SPI2, UARTD), - PIN(KB_COL7_PQ7, KBC, RSVD2, SPI2, UARTD), - PIN(CLK_32K_OUT_PA0, BLINK, SOC, RSVD3, RSVD4), - PIN_RESERVED, - /* Offset 0x3324 */ - PIN(CORE_PWR_REQ, PWRON, RSVD2, RSVD3, RSVD4), - PIN(CPU_PWR_REQ, CPU, RSVD2, RSVD3, RSVD4), - PIN(PWR_INT_N, PMI, RSVD2, RSVD3, RSVD4), - PIN(CLK_32K_IN, CLK, RSVD2, RSVD3, RSVD4), - PIN(OWR, OWR, RSVD2, RSVD3, RSVD4), - PIN(DAP1_FS_PN0, I2S0, HDA, GMI, RSVD4), - PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, RSVD4), - PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, SATA), - PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, RSVD4), - PIN(DAP_MCLK1_REQ_PEE2, DAP, DAP1, SATA, RSVD4), - PIN(DAP_MCLK1_PW4, EXTPERIPH1, DAP2, RSVD3, RSVD4), - PIN(SPDIF_IN_PK6, SPDIF, RSVD2, RSVD3, I2C3), - PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, RSVD3, I2C3), - PIN(DAP2_FS_PA2, I2S1, HDA, GMI, RSVD4), - PIN(DAP2_DIN_PA4, I2S1, HDA, GMI, RSVD4), - PIN(DAP2_DOUT_PA5, I2S1, HDA, GMI, RSVD4), - PIN(DAP2_SCLK_PA3, I2S1, HDA, GMI, RSVD4), - PIN(DVFS_PWM_PX0, SPI6, CLDVFS, GMI, RSVD4), - PIN(GPIO_X1_AUD_PX1, SPI6, RSVD2, GMI, RSVD4), - PIN(GPIO_X3_AUD_PX3, SPI6, SPI1, GMI, RSVD4), - PIN(DVFS_CLK_PX2, SPI6, CLDVFS, GMI, RSVD4), - PIN(GPIO_X4_AUD_PX4, GMI, SPI1, SPI2, DAP2), - PIN(GPIO_X5_AUD_PX5, GMI, SPI1, SPI2, RSVD4), - PIN(GPIO_X6_AUD_PX6, SPI6, SPI1, SPI2, GMI), - PIN(GPIO_X7_AUD_PX7, RSVD1, SPI1, SPI2, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3390 */ - PIN(SDMMC3_CLK_PA6, SDMMC3, RSVD2, RSVD3, SPI3), - PIN(SDMMC3_CMD_PA7, SDMMC3, PWM3, UARTA, SPI3), - PIN(SDMMC3_DAT0_PB7, SDMMC3, RSVD2, RSVD3, SPI3), - PIN(SDMMC3_DAT1_PB6, SDMMC3, PWM2, UARTA, SPI3), - PIN(SDMMC3_DAT2_PB5, SDMMC3, PWM1, DISPLAYA, SPI3), - PIN(SDMMC3_DAT3_PB4, SDMMC3, PWM0, DISPLAYB, SPI3), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x33bc */ - PIN(PEX_L0_RST_N_PDD1, PE0, RSVD2, RSVD3, RSVD4), - PIN(PEX_L0_CLKREQ_N_PDD2, PE0, RSVD2, RSVD3, RSVD4), - PIN(PEX_WAKE_N_PDD3, PE, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - /* Offset 0x33cc */ - PIN(PEX_L1_RST_N_PDD5, PE1, RSVD2, RSVD3, RSVD4), - PIN(PEX_L1_CLKREQ_N_PDD6, PE1, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x33e0 */ - PIN(HDMI_CEC_PEE3, CEC, RSVD2, RSVD3, RSVD4), - PIN(SDMMC1_WP_N_PV3, SDMMC1, CLK12, SPI4, UARTA), - PIN(SDMMC3_CD_N_PV2, SDMMC3, OWR, RSVD3, RSVD4), - PIN(GPIO_W2_AUD_PW2, SPI6, RSVD2, SPI2, I2C1), - PIN(GPIO_W3_AUD_PW3, SPI6, SPI1, SPI2, I2C1), - PIN(USB_VBUS_EN0_PN4, USB, RSVD2, RSVD3, RSVD4), - PIN(USB_VBUS_EN1_PN5, USB, RSVD2, RSVD3, RSVD4), - PIN(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, RSVD2, RSVD3, RSVD4), - PIN(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, RSVD2, RSVD3, RSVD4), - PIN(GMI_CLK_LB, SDMMC2, RSVD2, GMI, RSVD4), - PIN(RESET_OUT_N, RSVD1, RSVD2, RSVD3, RESET_OUT_N), - PIN(KB_ROW16_PT0, KBC, RSVD2, RSVD3, UARTC), - PIN(KB_ROW17_PT1, KBC, RSVD2, RSVD3, UARTC), - PIN(USB_VBUS_EN2_PFF1, USB, RSVD2, RSVD3, RSVD4), - PIN(PFF2, SATA, RSVD2, RSVD3, RSVD4), - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - PIN_RESERVED, - /* Offset 0x3430 */ - PIN(DP_HPD_PFF0, DP, RSVD2, RSVD3, RSVD4), -}; -const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra124_pingroups; diff --git a/arch/arm/cpu/tegra124-common/xusb-padctl.c b/arch/arm/cpu/tegra124-common/xusb-padctl.c deleted file mode 100644 index 43af883f2c..0000000000 --- a/arch/arm/cpu/tegra124-common/xusb-padctl.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt - -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#define XUSB_PADCTL_ELPG_PROGRAM 0x01c -#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) -#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) -#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) - -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) - -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) -#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) - -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) -#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) - -#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 -#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) -#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) - -enum tegra124_function { - TEGRA124_FUNC_SNPS, - TEGRA124_FUNC_XUSB, - TEGRA124_FUNC_UART, - TEGRA124_FUNC_PCIE, - TEGRA124_FUNC_USB3, - TEGRA124_FUNC_SATA, - TEGRA124_FUNC_RSVD, -}; - -static const char *const tegra124_functions[] = { - "snps", - "xusb", - "uart", - "pcie", - "usb3", - "sata", - "rsvd", -}; - -static const unsigned int tegra124_otg_functions[] = { - TEGRA124_FUNC_SNPS, - TEGRA124_FUNC_XUSB, - TEGRA124_FUNC_UART, - TEGRA124_FUNC_RSVD, -}; - -static const unsigned int tegra124_usb_functions[] = { - TEGRA124_FUNC_SNPS, - TEGRA124_FUNC_XUSB, -}; - -static const unsigned int tegra124_pci_functions[] = { - TEGRA124_FUNC_PCIE, - TEGRA124_FUNC_USB3, - TEGRA124_FUNC_SATA, - TEGRA124_FUNC_RSVD, -}; - -struct tegra_xusb_padctl_lane { - const char *name; - - unsigned int offset; - unsigned int shift; - unsigned int mask; - unsigned int iddq; - - const unsigned int *funcs; - unsigned int num_funcs; -}; - -#define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ - { \ - .name = _name, \ - .offset = _offset, \ - .shift = _shift, \ - .mask = _mask, \ - .iddq = _iddq, \ - .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ - .funcs = tegra124_##_funcs##_functions, \ - } - -static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { - TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), - TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), - TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), - TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), - TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), - TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), - TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), - TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), - TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), - TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), - TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), - TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), -}; - -struct tegra_xusb_phy_ops { - int (*prepare)(struct tegra_xusb_phy *phy); - int (*enable)(struct tegra_xusb_phy *phy); - int (*disable)(struct tegra_xusb_phy *phy); - int (*unprepare)(struct tegra_xusb_phy *phy); -}; - -struct tegra_xusb_phy { - const struct tegra_xusb_phy_ops *ops; - - struct tegra_xusb_padctl *padctl; -}; - -struct tegra_xusb_padctl_pin { - const struct tegra_xusb_padctl_lane *lane; - - unsigned int func; - int iddq; -}; - -#define MAX_GROUPS 3 -#define MAX_PINS 6 - -struct tegra_xusb_padctl_group { - const char *name; - - const char *pins[MAX_PINS]; - unsigned int num_pins; - - const char *func; - int iddq; -}; - -struct tegra_xusb_padctl_config { - const char *name; - - struct tegra_xusb_padctl_group groups[MAX_GROUPS]; - unsigned int num_groups; -}; - -struct tegra_xusb_padctl { - struct fdt_resource regs; - - unsigned int enable; - - struct tegra_xusb_phy phys[2]; - - const struct tegra_xusb_padctl_lane *lanes; - unsigned int num_lanes; - - const char *const *functions; - unsigned int num_functions; - - struct tegra_xusb_padctl_config config; -}; - -static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, - unsigned long offset) -{ - return readl(padctl->regs.start + offset); -} - -static inline void padctl_writel(struct tegra_xusb_padctl *padctl, - u32 value, unsigned long offset) -{ - writel(value, padctl->regs.start + offset); -} - -static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) -{ - u32 value; - - if (padctl->enable++ > 0) - return 0; - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - udelay(100); - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - udelay(100); - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - return 0; -} - -static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) -{ - u32 value; - - if (padctl->enable == 0) { - error("tegra-xusb-padctl: unbalanced enable/disable"); - return 0; - } - - if (--padctl->enable > 0) - return 0; - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - udelay(100); - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - udelay(100); - - value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); - value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; - padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - - return 0; -} - -static int phy_prepare(struct tegra_xusb_phy *phy) -{ - return tegra_xusb_padctl_enable(phy->padctl); -} - -static int phy_unprepare(struct tegra_xusb_phy *phy) -{ - return tegra_xusb_padctl_disable(phy->padctl); -} - -static int pcie_phy_enable(struct tegra_xusb_phy *phy) -{ - struct tegra_xusb_padctl *padctl = phy->padctl; - int err = -ETIMEDOUT; - unsigned long start; - u32 value; - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); - value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | - XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | - XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - - start = get_timer(0); - - while (get_timer(start) < 50) { - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { - err = 0; - break; - } - } - - return err; -} - -static int pcie_phy_disable(struct tegra_xusb_phy *phy) -{ - struct tegra_xusb_padctl *padctl = phy->padctl; - u32 value; - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); - - return 0; -} - -static int sata_phy_enable(struct tegra_xusb_phy *phy) -{ - struct tegra_xusb_padctl *padctl = phy->padctl; - int err = -ETIMEDOUT; - unsigned long start; - u32 value; - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; - value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; - value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - start = get_timer(0); - - while (get_timer(start) < 50) { - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { - err = 0; - break; - } - } - - return err; -} - -static int sata_phy_disable(struct tegra_xusb_phy *phy) -{ - struct tegra_xusb_padctl *padctl = phy->padctl; - u32 value; - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; - value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); - - value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); - value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; - value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; - padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); - - return 0; -} - -static const struct tegra_xusb_phy_ops pcie_phy_ops = { - .prepare = phy_prepare, - .enable = pcie_phy_enable, - .disable = pcie_phy_disable, - .unprepare = phy_unprepare, -}; - -static const struct tegra_xusb_phy_ops sata_phy_ops = { - .prepare = phy_prepare, - .enable = sata_phy_enable, - .disable = sata_phy_disable, - .unprepare = phy_unprepare, -}; - -static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) { - .phys = { - [0] = { - .ops = &pcie_phy_ops, - }, - [1] = { - .ops = &sata_phy_ops, - }, - }, -}; - -static const struct tegra_xusb_padctl_lane * -tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name) -{ - unsigned int i; - - for (i = 0; i < padctl->num_lanes; i++) - if (strcmp(name, padctl->lanes[i].name) == 0) - return &padctl->lanes[i]; - - return NULL; -} - -static int -tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_group *group, - const void *fdt, int node) -{ - unsigned int i; - int len, err; - - group->name = fdt_get_name(fdt, node, &len); - - len = fdt_count_strings(fdt, node, "nvidia,lanes"); - if (len < 0) { - error("tegra-xusb-padctl: failed to parse \"nvidia,lanes\" property"); - return -EINVAL; - } - - group->num_pins = len; - - for (i = 0; i < group->num_pins; i++) { - err = fdt_get_string_index(fdt, node, "nvidia,lanes", i, - &group->pins[i]); - if (err < 0) { - error("tegra-xusb-padctl: failed to read string from \"nvidia,lanes\" property"); - return -EINVAL; - } - } - - group->num_pins = len; - - err = fdt_get_string(fdt, node, "nvidia,function", &group->func); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse \"nvidia,func\" property"); - return -EINVAL; - } - - group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); - - return 0; -} - -static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl, - const char *name) -{ - unsigned int i; - - for (i = 0; i < padctl->num_functions; i++) - if (strcmp(name, padctl->functions[i]) == 0) - return i; - - return -ENOENT; -} - -static int -tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl, - const struct tegra_xusb_padctl_lane *lane, - const char *name) -{ - unsigned int i; - int func; - - func = tegra_xusb_padctl_find_function(padctl, name); - if (func < 0) - return func; - - for (i = 0; i < lane->num_funcs; i++) - if (lane->funcs[i] == func) - return i; - - return -ENOENT; -} - -static int -tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl, - const struct tegra_xusb_padctl_group *group) -{ - unsigned int i; - - for (i = 0; i < group->num_pins; i++) { - const struct tegra_xusb_padctl_lane *lane; - unsigned int func; - u32 value; - - lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]); - if (!lane) { - error("tegra-xusb-padctl: no lane for pin %s", - group->pins[i]); - continue; - } - - func = tegra_xusb_padctl_lane_find_function(padctl, lane, - group->func); - if (func < 0) { - error("tegra-xusb-padctl: function %s invalid for lane %s: %d", - group->func, lane->name, func); - continue; - } - - value = padctl_readl(padctl, lane->offset); - - /* set pin function */ - value &= ~(lane->mask << lane->shift); - value |= func << lane->shift; - - /* - * Set IDDQ if supported on the lane and specified in the - * configuration. - */ - if (lane->iddq > 0 && group->iddq >= 0) { - if (group->iddq != 0) - value &= ~(1 << lane->iddq); - else - value |= 1 << lane->iddq; - } - - padctl_writel(padctl, value, lane->offset); - } - - return 0; -} - -static int -tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_config *config) -{ - unsigned int i; - - for (i = 0; i < config->num_groups; i++) { - const struct tegra_xusb_padctl_group *group; - int err; - - group = &config->groups[i]; - - err = tegra_xusb_padctl_group_apply(padctl, group); - if (err < 0) { - error("tegra-xusb-padctl: failed to apply group %s: %d", - group->name, err); - continue; - } - } - - return 0; -} - -static int -tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, - struct tegra_xusb_padctl_config *config, - const void *fdt, int node) -{ - int subnode; - - config->name = fdt_get_name(fdt, node, NULL); - - fdt_for_each_subnode(fdt, subnode, node) { - struct tegra_xusb_padctl_group *group; - int err; - - group = &config->groups[config->num_groups]; - - err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt, - subnode); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse group %s", - group->name); - return err; - } - - config->num_groups++; - } - - return 0; -} - -static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, - const void *fdt, int node) -{ - int subnode, err; - - err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); - if (err < 0) { - error("tegra-xusb-padctl: registers not found"); - return err; - } - - fdt_for_each_subnode(fdt, subnode, node) { - struct tegra_xusb_padctl_config *config = &padctl->config; - - err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt, - subnode); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse entry %s: %d", - config->name, err); - continue; - } - } - - return 0; -} - -static int process_nodes(const void *fdt, int nodes[], unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; i++) { - enum fdt_compat_id id; - int err; - - if (!fdtdec_get_is_enabled(fdt, nodes[i])) - continue; - - id = fdtdec_lookup(fdt, nodes[i]); - switch (id) { - case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: - break; - - default: - error("tegra-xusb-padctl: unsupported compatible: %s", - fdtdec_get_compatible(id)); - continue; - } - - padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); - padctl->lanes = tegra124_lanes; - - padctl->num_functions = ARRAY_SIZE(tegra124_functions); - padctl->functions = tegra124_functions; - - err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); - if (err < 0) { - error("tegra-xusb-padctl: failed to parse DT: %d", - err); - continue; - } - - /* deassert XUSB padctl reset */ - reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); - - err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); - if (err < 0) { - error("tegra-xusb-padctl: failed to apply pinmux: %d", - err); - continue; - } - - /* only a single instance is supported */ - break; - } - - return 0; -} - -struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type) -{ - struct tegra_xusb_phy *phy = NULL; - - switch (type) { - case TEGRA_XUSB_PADCTL_PCIE: - phy = &padctl->phys[0]; - phy->padctl = padctl; - break; - - case TEGRA_XUSB_PADCTL_SATA: - phy = &padctl->phys[1]; - phy->padctl = padctl; - break; - } - - return phy; -} - -int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->prepare) - return phy->ops->prepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->enable) - return phy->ops->enable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->disable) - return phy->ops->disable(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) -{ - if (phy && phy->ops && phy->ops->unprepare) - return phy->ops->unprepare(phy); - - return phy ? -ENOSYS : -EINVAL; -} - -void tegra_xusb_padctl_init(const void *fdt) -{ - int count, nodes[1]; - - count = fdtdec_find_aliases_for_id(fdt, "padctl", - COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, - nodes, ARRAY_SIZE(nodes)); - if (process_nodes(fdt, nodes, count)) - return; -} diff --git a/arch/arm/cpu/tegra20-common/Makefile b/arch/arm/cpu/tegra20-common/Makefile deleted file mode 100644 index 0e4b3fc1dd..0000000000 --- a/arch/arm/cpu/tegra20-common/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# (C) Copyright 2010,2011 Nvidia Corporation. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -# The AVP is ARMv4T architecture so we must use special compiler -# flags for any startup files it might use. -CFLAGS_warmboot_avp.o += -march=armv4t - -obj-y += clock.o funcmux.o pinmux.o -obj-$(CONFIG_TEGRA_LP0) += warmboot.o crypto.o warmboot_avp.o -obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o -obj-$(CONFIG_TEGRA_PMU) += pmu.o diff --git a/arch/arm/cpu/tegra20-common/clock.c b/arch/arm/cpu/tegra20-common/clock.c deleted file mode 100644 index 7b9e10cd93..0000000000 --- a/arch/arm/cpu/tegra20-common/clock.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Tegra20 Clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Clock types that we can use as a source. The Tegra20 has muxes for the - * peripheral clocks, and in most cases there are four options for the clock - * source. This gives us a clock 'type' and exploits what commonality exists - * in the device. - * - * Letters are obvious, except for T which means CLK_M, and S which means the - * clock derived from 32KHz. Beware that CLK_M (also called OSC in the - * datasheet) and PLL_M are different things. The former is the basic - * clock supplied to the SOC from an external oscillator. The latter is the - * memory clock PLL. - * - * See definitions in clock_id in the header file. - */ -enum clock_type_id { - CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ - CLOCK_TYPE_MCPA, /* and so on */ - CLOCK_TYPE_MCPT, - CLOCK_TYPE_PCM, - CLOCK_TYPE_PCMT, - CLOCK_TYPE_PCMT16, /* CLOCK_TYPE_PCMT with 16-bit divider */ - CLOCK_TYPE_PCXTS, - CLOCK_TYPE_PDCT, - - CLOCK_TYPE_COUNT, - CLOCK_TYPE_NONE = -1, /* invalid clock type */ -}; - -enum { - CLOCK_MAX_MUX = 4 /* number of source options for each clock */ -}; - -/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS - * is special as it has 5 sources. Since it also has a different number of - * bits in its register for the source, we just handle it with a special - * case in the code. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, - { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, -}; - -/* - * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is - * not in the header file since it is for purely internal use - we want - * callers to use the PERIPH_ID for all access to peripheral clocks to avoid - * confusion bewteen PERIPH_ID_... and PERIPHC_... - * - * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be - * confusing. - * - * Note to SOC vendors: perhaps define a unified numbering for peripherals and - * use it for reset, clock enable, clock source/divider and even pinmuxing - * if you can. - */ -enum periphc_internal_id { - /* 0x00 */ - PERIPHC_I2S1, - PERIPHC_I2S2, - PERIPHC_SPDIF_OUT, - PERIPHC_SPDIF_IN, - PERIPHC_PWM, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_SPI3, - - /* 0x08 */ - PERIPHC_XIO, - PERIPHC_I2C1, - PERIPHC_DVC_I2C, - PERIPHC_TWC, - PERIPHC_0c, - PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ - PERIPHC_DISP1, - PERIPHC_DISP2, - - /* 0x10 */ - PERIPHC_CVE, - PERIPHC_IDE0, - PERIPHC_VI, - PERIPHC_1c, - PERIPHC_SDMMC1, - PERIPHC_SDMMC2, - PERIPHC_G3D, - PERIPHC_G2D, - - /* 0x18 */ - PERIPHC_NDFLASH, - PERIPHC_SDMMC4, - PERIPHC_VFIR, - PERIPHC_EPP, - PERIPHC_MPE, - PERIPHC_MIPI, - PERIPHC_UART1, - PERIPHC_UART2, - - /* 0x20 */ - PERIPHC_HOST1X, - PERIPHC_21, - PERIPHC_TVO, - PERIPHC_HDMI, - PERIPHC_24, - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_EMC, - - /* 0x28 */ - PERIPHC_UART3, - PERIPHC_29, - PERIPHC_VI_SENSOR, - PERIPHC_2b, - PERIPHC_2c, - PERIPHC_SPI4, - PERIPHC_I2C3, - PERIPHC_SDMMC3, - - /* 0x30 */ - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_VDE, - PERIPHC_OWR, - PERIPHC_NOR, - PERIPHC_CSITE, - - PERIPHC_COUNT, - - PERIPHC_NONE = -1, -}; - -/* - * Clock type for each peripheral clock source. We put the name in each - * record just so it is easy to match things up - */ -#define TYPE(name, type) type -static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { - /* 0x00 */ - TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), - TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), - - /* 0x08 */ - TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), - - /* 0x10 */ - TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), - - /* 0x18 */ - TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), - - /* 0x20 */ - TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), - - /* 0x28 */ - TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), - - /* 0x30 */ - TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), -}; - -/* - * This array translates a periph_id to a periphc_internal_id - * - * Not present/matched up: - * uint vi_sensor; _VI_SENSOR_0, 0x1A8 - * SPDIF - which is both 0x08 and 0x0c - * - */ -#define NONE(name) (-1) -#define OFFSET(name, value) PERIPHC_ ## name -static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { - /* Low word: 31:0 */ - NONE(CPU), - NONE(RESERVED1), - NONE(RESERVED2), - NONE(AC97), - NONE(RTC), - NONE(TMR), - PERIPHC_UART1, - PERIPHC_UART2, /* and vfir 0x68 */ - - /* 0x08 */ - NONE(GPIO), - PERIPHC_SDMMC2, - NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ - PERIPHC_I2S1, - PERIPHC_I2C1, - PERIPHC_NDFLASH, - PERIPHC_SDMMC1, - PERIPHC_SDMMC4, - - /* 0x10 */ - PERIPHC_TWC, - PERIPHC_PWM, - PERIPHC_I2S2, - PERIPHC_EPP, - PERIPHC_VI, - PERIPHC_G2D, - NONE(USBD), - NONE(ISP), - - /* 0x18 */ - PERIPHC_G3D, - PERIPHC_IDE0, - PERIPHC_DISP2, - PERIPHC_DISP1, - PERIPHC_HOST1X, - NONE(VCP), - NONE(RESERVED30), - NONE(CACHE2), - - /* Middle word: 63:32 */ - NONE(MEM), - NONE(AHBDMA), - NONE(APBDMA), - NONE(RESERVED35), - NONE(KBC), - NONE(STAT_MON), - NONE(PMC), - NONE(FUSE), - - /* 0x28 */ - NONE(KFUSE), - NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ - PERIPHC_NOR, - PERIPHC_SPI1, - PERIPHC_SPI2, - PERIPHC_XIO, - PERIPHC_SPI3, - PERIPHC_DVC_I2C, - - /* 0x30 */ - NONE(DSI), - PERIPHC_TVO, /* also CVE 0x40 */ - PERIPHC_MIPI, - PERIPHC_HDMI, - PERIPHC_CSITE, - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_UART3, - - /* 0x38 */ - NONE(RESERVED56), - PERIPHC_EMC, - NONE(USB2), - NONE(USB3), - PERIPHC_MPE, - PERIPHC_VDE, - NONE(BSEA), - NONE(BSEV), - - /* Upper word 95:64 */ - NONE(SPEEDO), - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_I2C3, - PERIPHC_SPI4, - PERIPHC_SDMMC3, - NONE(PCIE), - PERIPHC_OWR, - - /* 0x48 */ - NONE(AFI), - NONE(CORESIGHT), - NONE(PCIEXCLK), - NONE(AVPUCQ), - NONE(RESERVED76), - NONE(RESERVED77), - NONE(RESERVED78), - NONE(RESERVED79), - - /* 0x50 */ - NONE(RESERVED80), - NONE(RESERVED81), - NONE(RESERVED82), - NONE(RESERVED83), - NONE(IRAMA), - NONE(IRAMB), - NONE(IRAMC), - NONE(IRAMD), - - /* 0x58 */ - NONE(CRAM2), -}; - -/* - * Get the oscillator frequency, from the corresponding hardware configuration - * field. T20 has 4 frequencies that it supports. - */ -enum clock_osc_freq clock_get_osc_freq(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; -} - -/* Returns a pointer to the clock source register for a peripheral */ -u32 *get_periph_source_reg(enum periph_id periph_id) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - enum periphc_internal_id internal_id; - - assert(clock_periph_id_isvalid(periph_id)); - internal_id = periph_id_to_internal_id[periph_id]; - assert(internal_id != -1); - return &clkrst->crc_clk_src[internal_id]; -} - -/** - * Given a peripheral ID and the required source clock, this returns which - * value should be programmed into the source mux for that peripheral. - * - * There is special code here to handle the one source type with 5 sources. - * - * @param periph_id peripheral to start - * @param source PLL id of required parent clock - * @param mux_bits Set to number of bits in mux register: 2 or 4 - * @param divider_bits Set to number of divider bits (8 or 16) - * @return mux value (0-4, or -1 if not found) - */ -int get_periph_clock_source(enum periph_id periph_id, - enum clock_id parent, int *mux_bits, int *divider_bits) -{ - enum clock_type_id type; - enum periphc_internal_id internal_id; - int mux; - - assert(clock_periph_id_isvalid(periph_id)); - - internal_id = periph_id_to_internal_id[periph_id]; - assert(periphc_internal_id_isvalid(internal_id)); - - type = clock_periph_type[internal_id]; - assert(clock_type_id_isvalid(type)); - - /* - * Special cases here for the clock with a 4-bit source mux and I2C - * with its 16-bit divisor - */ - if (type == CLOCK_TYPE_PCXTS) - *mux_bits = MASK_BITS_31_28; - else - *mux_bits = MASK_BITS_31_30; - if (type == CLOCK_TYPE_PCMT16) - *divider_bits = 16; - else - *divider_bits = 8; - - for (mux = 0; mux < CLOCK_MAX_MUX; mux++) - if (clock_source[type][mux] == parent) - return mux; - - /* - * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS - * which is not in our table. If not, then they are asking for a - * source which this peripheral can't access through its mux. - */ - assert(type == CLOCK_TYPE_PCXTS); - assert(parent == CLOCK_ID_SFROM32KHZ); - if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) - return 4; /* mux value for this clock */ - - /* if we get here, either us or the caller has made a mistake */ - printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, - parent); - return -1; -} - -void clock_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; - u32 reg; - - /* Enable/disable the clock to this peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - reg = readl(clk); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, clk); -} - -void reset_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; - u32 reg; - - /* Enable/disable reset to the peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - reg = readl(reset); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, reset); -} - -#ifdef CONFIG_OF_CONTROL -/* - * Convert a device tree clock ID to our peripheral ID. They are mostly - * the same but we are very cautious so we check that a valid clock ID is - * provided. - * - * @param clk_id Clock ID according to tegra20 device tree binding - * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid - */ -enum periph_id clk_id_to_periph_id(int clk_id) -{ - if (clk_id > PERIPH_ID_COUNT) - return PERIPH_ID_NONE; - - switch (clk_id) { - case PERIPH_ID_RESERVED1: - case PERIPH_ID_RESERVED2: - case PERIPH_ID_RESERVED30: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED56: - case PERIPH_ID_PCIEXCLK: - case PERIPH_ID_RESERVED76: - case PERIPH_ID_RESERVED77: - case PERIPH_ID_RESERVED78: - case PERIPH_ID_RESERVED79: - case PERIPH_ID_RESERVED80: - case PERIPH_ID_RESERVED81: - case PERIPH_ID_RESERVED82: - case PERIPH_ID_RESERVED83: - case PERIPH_ID_RESERVED91: - return PERIPH_ID_NONE; - default: - return clk_id; - } -} -#endif /* CONFIG_OF_CONTROL */ - -void clock_early_init(void) -{ - /* - * PLLP output frequency set to 216MHz - * PLLC output frequency set to 600Mhz - * - * TODO: Can we calculate these values instead of hard-coding? - */ - switch (clock_get_osc_freq()) { - case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); - break; - - case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); - break; - - case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ - clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8); - clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); - break; - case CLOCK_OSC_FREQ_19_2: - default: - /* - * These are not supported. It is too early to print a - * message and the UART likely won't work anyway due to the - * oscillator being wrong. - */ - break; - } -} - -void arch_timer_init(void) -{ -} - -#define PMC_SATA_PWRGT 0x1ac -#define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) -#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) - -#define PLLE_SS_CNTL 0x68 -#define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) -#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) -#define PLLE_SS_CNTL_SSCBYP (1 << 12) -#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) -#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) -#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) - -#define PLLE_BASE 0x0e8 -#define PLLE_BASE_ENABLE_CML (1 << 31) -#define PLLE_BASE_ENABLE (1 << 30) -#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) -#define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) -#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) -#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) - -#define PLLE_MISC 0x0ec -#define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) -#define PLLE_MISC_PLL_READY (1 << 15) -#define PLLE_MISC_LOCK (1 << 11) -#define PLLE_MISC_LOCK_ENABLE (1 << 9) -#define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) - -static int tegra_plle_train(void) -{ - unsigned int timeout = 2000; - unsigned long value; - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - do { - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if (value & PLLE_MISC_PLL_READY) - break; - - udelay(100); - } while (--timeout); - - if (timeout == 0) { - error("timeout waiting for PLLE to become ready"); - return -ETIMEDOUT; - } - - return 0; -} - -int tegra_plle_enable(void) -{ - unsigned int timeout = 1000; - u32 value; - int err; - - /* disable PLLE clock */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_ENABLE_CML; - value &= ~PLLE_BASE_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - /* clear lock enable and setup field */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value &= ~PLLE_MISC_LOCK_ENABLE; - value &= ~PLLE_MISC_SETUP_BASE(0xffff); - value &= ~PLLE_MISC_SETUP_EXT(0x3); - writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if ((value & PLLE_MISC_PLL_READY) == 0) { - err = tegra_plle_train(); - if (err < 0) { - error("failed to train PLLE: %d", err); - return err; - } - } - - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value |= PLLE_MISC_SETUP_BASE(0x7); - value |= PLLE_MISC_LOCK_ENABLE; - value |= PLLE_MISC_SETUP_EXT(0); - writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | - PLLE_SS_CNTL_BYPASS_SS; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - do { - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if (value & PLLE_MISC_LOCK) - break; - - udelay(2); - } while (--timeout); - - if (timeout == 0) { - error("timeout waiting for PLLE to lock"); - return -ETIMEDOUT; - } - - udelay(50); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); - value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); - - value &= ~PLLE_SS_CNTL_SSCINC(0xff); - value |= PLLE_SS_CNTL_SSCINC(0x01); - - value &= ~PLLE_SS_CNTL_SSCBYP; - value &= ~PLLE_SS_CNTL_INTERP_RESET; - value &= ~PLLE_SS_CNTL_BYPASS_SS; - - value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); - value |= PLLE_SS_CNTL_SSCMAX(0x24); - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - return 0; -} diff --git a/arch/arm/cpu/tegra20-common/crypto.c b/arch/arm/cpu/tegra20-common/crypto.c deleted file mode 100644 index ec95d7ceb1..0000000000 --- a/arch/arm/cpu/tegra20-common/crypto.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010 - 2011 NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include "crypto.h" -#include "aes.h" - -static u8 zero_key[16]; - -#define AES_CMAC_CONST_RB 0x87 /* from RFC 4493, Figure 2.2 */ - -enum security_op { - SECURITY_SIGN = 1 << 0, /* Sign the data */ - SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */ -}; - -/** - * Shift a vector left by one bit - * - * \param in Input vector - * \param out Output vector - * \param size Length of vector in bytes - */ -static void left_shift_vector(u8 *in, u8 *out, int size) -{ - int carry = 0; - int i; - - for (i = size - 1; i >= 0; i--) { - out[i] = (in[i] << 1) | carry; - carry = in[i] >> 7; /* get most significant bit */ - } -} - -/** - * Sign a block of data, putting the result into dst. - * - * \param key Input AES key, length AES_KEY_LENGTH - * \param key_schedule Expanded key to use - * \param src Source data of length 'num_aes_blocks' blocks - * \param dst Destination buffer, length AES_KEY_LENGTH - * \param num_aes_blocks Number of AES blocks to encrypt - */ -static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, - u32 num_aes_blocks) -{ - u8 tmp_data[AES_KEY_LENGTH]; - u8 left[AES_KEY_LENGTH]; - u8 k1[AES_KEY_LENGTH]; - u8 *cbc_chain_data; - unsigned i; - - cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ - - /* compute K1 constant needed by AES-CMAC calculation */ - for (i = 0; i < AES_KEY_LENGTH; i++) - tmp_data[i] = 0; - - aes_cbc_encrypt_blocks(key_schedule, tmp_data, left, 1); - - left_shift_vector(left, k1, sizeof(left)); - - if ((left[0] >> 7) != 0) /* get MSB of L */ - k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB; - - /* compute the AES-CMAC value */ - for (i = 0; i < num_aes_blocks; i++) { - /* Apply the chain data */ - aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data); - - /* for the final block, XOR K1 into the IV */ - if (i == num_aes_blocks - 1) - aes_apply_cbc_chain_data(tmp_data, k1, tmp_data); - - /* encrypt the AES block */ - aes_encrypt(tmp_data, key_schedule, dst); - - debug("sign_obj: block %d of %d\n", i, num_aes_blocks); - - /* Update pointers for next loop. */ - cbc_chain_data = dst; - src += AES_KEY_LENGTH; - } -} - -/** - * Encrypt and sign a block of data (depending on security mode). - * - * \param key Input AES key, length AES_KEY_LENGTH - * \param oper Security operations mask to perform (enum security_op) - * \param src Source data - * \param length Size of source data - * \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes - */ -static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, - u32 length, u8 *sig_dst) -{ - u32 num_aes_blocks; - u8 key_schedule[AES_EXPAND_KEY_LENGTH]; - - debug("encrypt_and_sign: length = %d\n", length); - - /* - * The only need for a key is for signing/checksum purposes, so - * if not encrypting, expand a key of 0s. - */ - aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule); - - num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH; - - if (oper & SECURITY_ENCRYPT) { - /* Perform this in place, resulting in src being encrypted. */ - debug("encrypt_and_sign: begin encryption\n"); - aes_cbc_encrypt_blocks(key_schedule, src, src, num_aes_blocks); - debug("encrypt_and_sign: end encryption\n"); - } - - if (oper & SECURITY_SIGN) { - /* encrypt the data, overwriting the result in signature. */ - debug("encrypt_and_sign: begin signing\n"); - sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); - debug("encrypt_and_sign: end signing\n"); - } - - return 0; -} - -int sign_data_block(u8 *source, unsigned length, u8 *signature) -{ - return encrypt_and_sign(zero_key, SECURITY_SIGN, source, - length, signature); -} diff --git a/arch/arm/cpu/tegra20-common/crypto.h b/arch/arm/cpu/tegra20-common/crypto.h deleted file mode 100644 index f59b92768a..0000000000 --- a/arch/arm/cpu/tegra20-common/crypto.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010 - 2011 NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _CRYPTO_H_ -#define _CRYPTO_H_ - -/** - * Sign a block of data - * - * \param source Source data - * \param length Size of source data - * \param signature Destination address for signature, AES_KEY_LENGTH bytes - */ -int sign_data_block(u8 *source, unsigned length, u8 *signature); - -#endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/cpu/tegra20-common/emc.c b/arch/arm/cpu/tegra20-common/emc.c deleted file mode 100644 index ed2462ab0f..0000000000 --- a/arch/arm/cpu/tegra20-common/emc.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The EMC registers have shadow registers. When the EMC clock is updated - * in the clock controller, the shadow registers are copied to the active - * registers, allowing glitchless memory bus frequency changes. - * This function updates the shadow registers for a new clock frequency, - * and relies on the clock lock on the emc clock to avoid races between - * multiple frequency changes - */ - -/* - * This table defines the ordering of the registers provided to - * tegra_set_mmc() - * TODO: Convert to fdt version once available - */ -static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { - 0x2c, /* RC */ - 0x30, /* RFC */ - 0x34, /* RAS */ - 0x38, /* RP */ - 0x3c, /* R2W */ - 0x40, /* W2R */ - 0x44, /* R2P */ - 0x48, /* W2P */ - 0x4c, /* RD_RCD */ - 0x50, /* WR_RCD */ - 0x54, /* RRD */ - 0x58, /* REXT */ - 0x5c, /* WDV */ - 0x60, /* QUSE */ - 0x64, /* QRST */ - 0x68, /* QSAFE */ - 0x6c, /* RDV */ - 0x70, /* REFRESH */ - 0x74, /* BURST_REFRESH_NUM */ - 0x78, /* PDEX2WR */ - 0x7c, /* PDEX2RD */ - 0x80, /* PCHG2PDEN */ - 0x84, /* ACT2PDEN */ - 0x88, /* AR2PDEN */ - 0x8c, /* RW2PDEN */ - 0x90, /* TXSR */ - 0x94, /* TCKE */ - 0x98, /* TFAW */ - 0x9c, /* TRPAB */ - 0xa0, /* TCLKSTABLE */ - 0xa4, /* TCLKSTOP */ - 0xa8, /* TREFBW */ - 0xac, /* QUSE_EXTRA */ - 0x114, /* FBIO_CFG6 */ - 0xb0, /* ODT_WRITE */ - 0xb4, /* ODT_READ */ - 0x104, /* FBIO_CFG5 */ - 0x2bc, /* CFG_DIG_DLL */ - 0x2c0, /* DLL_XFORM_DQS */ - 0x2c4, /* DLL_XFORM_QUSE */ - 0x2e0, /* ZCAL_REF_CNT */ - 0x2e4, /* ZCAL_WAIT_CNT */ - 0x2a8, /* AUTO_CAL_INTERVAL */ - 0x2d0, /* CFG_CLKTRIM_0 */ - 0x2d4, /* CFG_CLKTRIM_1 */ - 0x2d8, /* CFG_CLKTRIM_2 */ -}; - -struct emc_ctlr *emc_get_controller(const void *blob) -{ - fdt_addr_t addr; - int node; - - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); - if (node > 0) { - addr = fdtdec_get_addr(blob, node, "reg"); - if (addr != FDT_ADDR_T_NONE) - return (struct emc_ctlr *)addr; - } - return NULL; -} - -/* Error codes we use */ -enum { - ERR_NO_EMC_NODE = -10, - ERR_NO_EMC_REG, - ERR_NO_FREQ, - ERR_FREQ_NOT_FOUND, - ERR_BAD_REGS, - ERR_NO_RAM_CODE, - ERR_RAM_CODE_NOT_FOUND, -}; - -/** - * Find EMC tables for the given ram code. - * - * The tegra EMC binding has two options, one using the ram code and one not. - * We detect which is in use by looking for the nvidia,use-ram-code property. - * If this is not present, then the EMC tables are directly below 'node', - * otherwise we select the correct emc-tables subnode based on the 'ram_code' - * value. - * - * @param blob Device tree blob - * @param node EMC node (nvidia,tegra20-emc compatible string) - * @param ram_code RAM code to select (0-3, or -1 if unknown) - * @return 0 if ok, otherwise a -ve ERR_ code (see enum above) - */ -static int find_emc_tables(const void *blob, int node, int ram_code) -{ - int need_ram_code; - int depth; - int offset; - - /* If we are using RAM codes, scan through the tables for our code */ - need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code"); - if (!need_ram_code) - return node; - if (ram_code == -1) { - debug("%s: RAM code required but not supplied\n", __func__); - return ERR_NO_RAM_CODE; - } - - offset = node; - depth = 0; - do { - /* - * Sadly there is no compatible string so we cannot use - * fdtdec_next_compatible_subnode(). - */ - offset = fdt_next_node(blob, offset, &depth); - if (depth <= 0) - break; - - /* Make sure this is a direct subnode */ - if (depth != 1) - continue; - if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL))) - continue; - - if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1) - == ram_code) - return offset; - } while (1); - - debug("%s: Could not find tables for RAM code %d\n", __func__, - ram_code); - return ERR_RAM_CODE_NOT_FOUND; -} - -/** - * Decode the EMC node of the device tree, returning a pointer to the emc - * controller and the table to be used for the given rate. - * - * @param blob Device tree blob - * @param rate Clock speed of memory controller in Hz (=2x memory bus rate) - * @param emcp Returns address of EMC controller registers - * @param tablep Returns pointer to table to program into EMC. There are - * TEGRA_EMC_NUM_REGS entries, destined for offsets as per the - * emc_reg_addr array. - * @return 0 if ok, otherwise a -ve error code which will allow someone to - * figure out roughly what went wrong by looking at this code. - */ -static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp, - const u32 **tablep) -{ - struct apb_misc_pp_ctlr *pp = - (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; - int ram_code; - int depth; - int node; - - ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK) - >> RAM_CODE_SHIFT; - /* - * The EMC clock rate is twice the bus rate, and the bus rate is - * measured in kHz - */ - rate = rate / 2 / 1000; - - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); - if (node < 0) { - debug("%s: No EMC node found in FDT\n", __func__); - return ERR_NO_EMC_NODE; - } - *emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg"); - if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) { - debug("%s: No EMC node reg property\n", __func__); - return ERR_NO_EMC_REG; - } - - /* Work out the parent node which contains our EMC tables */ - node = find_emc_tables(blob, node, ram_code & 3); - if (node < 0) - return node; - - depth = 0; - for (;;) { - int node_rate; - - node = fdtdec_next_compatible_subnode(blob, node, - COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth); - if (node < 0) - break; - node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1); - if (node_rate == -1) { - debug("%s: Missing clock-frequency\n", __func__); - return ERR_NO_FREQ; /* we expect this property */ - } - - if (node_rate == rate) - break; - } - if (node < 0) { - debug("%s: No node found for clock frequency %d\n", __func__, - rate); - return ERR_FREQ_NOT_FOUND; - } - - *tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers", - TEGRA_EMC_NUM_REGS); - if (!*tablep) { - debug("%s: node '%s' array missing / wrong size\n", __func__, - fdt_get_name(blob, node, NULL)); - return ERR_BAD_REGS; - } - - /* All seems well */ - return 0; -} - -int tegra_set_emc(const void *blob, unsigned rate) -{ - struct emc_ctlr *emc; - const u32 *table = NULL; - int err, i; - - err = decode_emc(blob, rate, &emc, &table); - if (err) { - debug("Warning: no valid EMC (%d), memory timings unset\n", - err); - return err; - } - - debug("%s: Table found, setting EMC values as follows:\n", __func__); - for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) { - u32 value = fdt32_to_cpu(table[i]); - u32 addr = (uintptr_t)emc + emc_reg_addr[i]; - - debug(" %#x: %#x\n", addr, value); - writel(value, addr); - } - - /* trigger emc with new settings */ - clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY, - clock_get_rate(CLOCK_ID_MEMORY), NULL); - debug("EMC clock set to %lu\n", - clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY)); - - return 0; -} diff --git a/arch/arm/cpu/tegra20-common/funcmux.c b/arch/arm/cpu/tegra20-common/funcmux.c deleted file mode 100644 index 0df4a0738d..0000000000 --- a/arch/arm/cpu/tegra20-common/funcmux.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Tegra20 high-level function multiplexing */ -#include -#include -#include -#include - -/* - * The PINMUX macro is used to set up pinmux tables. - */ -#define PINMUX(grp, mux, pupd, tri) \ - {PMUX_PINGRP_##grp, PMUX_FUNC_##mux, PMUX_PULL_##pupd, PMUX_TRI_##tri} - -static const struct pmux_pingrp_config disp1_default[] = { - PINMUX(LDI, DISPA, NORMAL, NORMAL), - PINMUX(LHP0, DISPA, NORMAL, NORMAL), - PINMUX(LHP1, DISPA, NORMAL, NORMAL), - PINMUX(LHP2, DISPA, NORMAL, NORMAL), - PINMUX(LHS, DISPA, NORMAL, NORMAL), - PINMUX(LM0, RSVD4, NORMAL, NORMAL), - PINMUX(LPP, DISPA, NORMAL, NORMAL), - PINMUX(LPW0, DISPA, NORMAL, NORMAL), - PINMUX(LPW2, DISPA, NORMAL, NORMAL), - PINMUX(LSC0, DISPA, NORMAL, NORMAL), - PINMUX(LSPI, DISPA, NORMAL, NORMAL), - PINMUX(LVP1, DISPA, NORMAL, NORMAL), - PINMUX(LVS, DISPA, NORMAL, NORMAL), - PINMUX(SLXD, SPDIF, NORMAL, NORMAL), -}; - - -int funcmux_select(enum periph_id id, int config) -{ - int bad_config = config != FUNCMUX_DEFAULT; - - switch (id) { - case PERIPH_ID_UART1: - switch (config) { - case FUNCMUX_UART1_IRRX_IRTX: - pinmux_set_func(PMUX_PINGRP_IRRX, PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_IRTX, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PMUX_PINGRP_IRRX); - pinmux_tristate_disable(PMUX_PINGRP_IRTX); - break; - case FUNCMUX_UART1_UAA_UAB: - pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PMUX_PINGRP_UAA); - pinmux_tristate_disable(PMUX_PINGRP_UAB); - bad_config = 0; - break; - case FUNCMUX_UART1_GPU: - pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PMUX_PINGRP_GPU); - bad_config = 0; - break; - case FUNCMUX_UART1_SDIO1: - pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PMUX_PINGRP_SDIO1); - bad_config = 0; - break; - } - if (!bad_config) { - /* - * Tegra appears to boot with function UARTA pre- - * selected on mux group SDB. If two mux groups are - * both set to the same function, it's unclear which - * group's pins drive the RX signals into the HW. - * For UARTA, SDB certainly overrides group IRTX in - * practice. To solve this, configure some alternative - * function on SDB to avoid the conflict. Also, tri- - * state the group to avoid driving any signal onto it - * until we know what's connected. - */ - pinmux_tristate_enable(PMUX_PINGRP_SDB); - pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); - } - break; - - case PERIPH_ID_UART2: - if (config == FUNCMUX_UART2_UAD) { - pinmux_set_func(PMUX_PINGRP_UAD, PMUX_FUNC_UARTB); - pinmux_tristate_disable(PMUX_PINGRP_UAD); - } - break; - - case PERIPH_ID_UART4: - if (config == FUNCMUX_UART4_GMC) { - pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_UARTD); - pinmux_tristate_disable(PMUX_PINGRP_GMC); - } - break; - - case PERIPH_ID_DVC_I2C: - /* there is only one selection, pinmux_config is ignored */ - if (config == FUNCMUX_DVC_I2CP) { - pinmux_set_func(PMUX_PINGRP_I2CP, PMUX_FUNC_I2C); - pinmux_tristate_disable(PMUX_PINGRP_I2CP); - } - break; - - case PERIPH_ID_I2C1: - /* support pinmux_config of 0 for now, */ - if (config == FUNCMUX_I2C1_RM) { - pinmux_set_func(PMUX_PINGRP_RM, PMUX_FUNC_I2C); - pinmux_tristate_disable(PMUX_PINGRP_RM); - } - break; - case PERIPH_ID_I2C2: /* I2C2 */ - switch (config) { - case FUNCMUX_I2C2_DDC: /* DDC pin group, select I2C2 */ - pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_I2C2); - /* PTA to HDMI */ - pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_HDMI); - pinmux_tristate_disable(PMUX_PINGRP_DDC); - break; - case FUNCMUX_I2C2_PTA: /* PTA pin group, select I2C2 */ - pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_I2C2); - /* set DDC_SEL to RSVDx (RSVD2 works for now) */ - pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_RSVD2); - pinmux_tristate_disable(PMUX_PINGRP_PTA); - bad_config = 0; - break; - } - break; - case PERIPH_ID_I2C3: /* I2C3 */ - /* support pinmux_config of 0 for now */ - if (config == FUNCMUX_I2C3_DTF) { - pinmux_set_func(PMUX_PINGRP_DTF, PMUX_FUNC_I2C3); - pinmux_tristate_disable(PMUX_PINGRP_DTF); - } - break; - - case PERIPH_ID_SDMMC1: - if (config == FUNCMUX_SDMMC1_SDIO1_4BIT) { - pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_SDIO1); - pinmux_tristate_disable(PMUX_PINGRP_SDIO1); - } - break; - - case PERIPH_ID_SDMMC2: - if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { - pinmux_set_func(PMUX_PINGRP_DTA, PMUX_FUNC_SDIO2); - pinmux_set_func(PMUX_PINGRP_DTD, PMUX_FUNC_SDIO2); - - pinmux_tristate_disable(PMUX_PINGRP_DTA); - pinmux_tristate_disable(PMUX_PINGRP_DTD); - } - break; - - case PERIPH_ID_SDMMC3: - switch (config) { - case FUNCMUX_SDMMC3_SDB_SLXA_8BIT: - pinmux_set_func(PMUX_PINGRP_SLXA, PMUX_FUNC_SDIO3); - pinmux_set_func(PMUX_PINGRP_SLXC, PMUX_FUNC_SDIO3); - pinmux_set_func(PMUX_PINGRP_SLXD, PMUX_FUNC_SDIO3); - pinmux_set_func(PMUX_PINGRP_SLXK, PMUX_FUNC_SDIO3); - - pinmux_tristate_disable(PMUX_PINGRP_SLXA); - pinmux_tristate_disable(PMUX_PINGRP_SLXC); - pinmux_tristate_disable(PMUX_PINGRP_SLXD); - pinmux_tristate_disable(PMUX_PINGRP_SLXK); - /* fall through */ - - case FUNCMUX_SDMMC3_SDB_4BIT: - pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); - pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_SDIO3); - pinmux_set_func(PMUX_PINGRP_SDD, PMUX_FUNC_SDIO3); - - pinmux_tristate_disable(PMUX_PINGRP_SDB); - pinmux_tristate_disable(PMUX_PINGRP_SDC); - pinmux_tristate_disable(PMUX_PINGRP_SDD); - bad_config = 0; - break; - } - break; - - case PERIPH_ID_SDMMC4: - switch (config) { - case FUNCMUX_SDMMC4_ATC_ATD_8BIT: - pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_SDIO4); - pinmux_set_func(PMUX_PINGRP_ATD, PMUX_FUNC_SDIO4); - - pinmux_tristate_disable(PMUX_PINGRP_ATC); - pinmux_tristate_disable(PMUX_PINGRP_ATD); - break; - - case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT: - pinmux_set_func(PMUX_PINGRP_GME, PMUX_FUNC_SDIO4); - pinmux_tristate_disable(PMUX_PINGRP_GME); - /* fall through */ - - case FUNCMUX_SDMMC4_ATB_GMA_4_BIT: - pinmux_set_func(PMUX_PINGRP_ATB, PMUX_FUNC_SDIO4); - pinmux_set_func(PMUX_PINGRP_GMA, PMUX_FUNC_SDIO4); - - pinmux_tristate_disable(PMUX_PINGRP_ATB); - pinmux_tristate_disable(PMUX_PINGRP_GMA); - bad_config = 0; - break; - } - break; - - case PERIPH_ID_KBC: - if (config == FUNCMUX_DEFAULT) { - enum pmux_pingrp grp[] = {PMUX_PINGRP_KBCA, - PMUX_PINGRP_KBCB, PMUX_PINGRP_KBCC, - PMUX_PINGRP_KBCD, PMUX_PINGRP_KBCE, - PMUX_PINGRP_KBCF}; - int i; - - for (i = 0; i < ARRAY_SIZE(grp); i++) { - pinmux_tristate_disable(grp[i]); - pinmux_set_func(grp[i], PMUX_FUNC_KBC); - pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); - } - } - break; - - case PERIPH_ID_USB2: - if (config == FUNCMUX_USB2_ULPI) { - pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_ULPI); - pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_ULPI); - pinmux_set_func(PMUX_PINGRP_UDA, PMUX_FUNC_ULPI); - - pinmux_tristate_disable(PMUX_PINGRP_UAA); - pinmux_tristate_disable(PMUX_PINGRP_UAB); - pinmux_tristate_disable(PMUX_PINGRP_UDA); - } - break; - - case PERIPH_ID_SPI1: - if (config == FUNCMUX_SPI1_GMC_GMD) { - pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH); - pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH); - - pinmux_tristate_disable(PMUX_PINGRP_GMC); - pinmux_tristate_disable(PMUX_PINGRP_GMD); - } - break; - - case PERIPH_ID_NDFLASH: - switch (config) { - case FUNCMUX_NDFLASH_ATC: - pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_NAND); - pinmux_tristate_disable(PMUX_PINGRP_ATC); - break; - case FUNCMUX_NDFLASH_KBC_8_BIT: - pinmux_set_func(PMUX_PINGRP_KBCA, PMUX_FUNC_NAND); - pinmux_set_func(PMUX_PINGRP_KBCC, PMUX_FUNC_NAND); - pinmux_set_func(PMUX_PINGRP_KBCD, PMUX_FUNC_NAND); - pinmux_set_func(PMUX_PINGRP_KBCE, PMUX_FUNC_NAND); - pinmux_set_func(PMUX_PINGRP_KBCF, PMUX_FUNC_NAND); - - pinmux_tristate_disable(PMUX_PINGRP_KBCA); - pinmux_tristate_disable(PMUX_PINGRP_KBCC); - pinmux_tristate_disable(PMUX_PINGRP_KBCD); - pinmux_tristate_disable(PMUX_PINGRP_KBCE); - pinmux_tristate_disable(PMUX_PINGRP_KBCF); - - bad_config = 0; - break; - } - break; - case PERIPH_ID_DISP1: - if (config == FUNCMUX_DEFAULT) { - int i; - - for (i = PMUX_PINGRP_LD0; i <= PMUX_PINGRP_LD17; i++) { - pinmux_set_func(i, PMUX_FUNC_DISPA); - pinmux_tristate_disable(i); - pinmux_set_pullupdown(i, PMUX_PULL_NORMAL); - } - pinmux_config_pingrp_table(disp1_default, - ARRAY_SIZE(disp1_default)); - } - break; - - default: - debug("%s: invalid periph_id %d", __func__, id); - return -1; - } - - if (bad_config) { - debug("%s: invalid config %d for periph_id %d", __func__, - config, id); - return -1; - } - - return 0; -} diff --git a/arch/arm/cpu/tegra20-common/pinmux.c b/arch/arm/cpu/tegra20-common/pinmux.c deleted file mode 100644 index e484f991bf..0000000000 --- a/arch/arm/cpu/tegra20-common/pinmux.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Tegra20 pin multiplexing functions */ - -#include -#include -#include - -/* - * This defines the order of the pin mux control bits in the registers. For - * some reason there is no correspendence between the tristate, pin mux and - * pullup/pulldown registers. - */ -enum pmux_ctlid { - /* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */ - MUXCTL_UAA, - MUXCTL_UAB, - MUXCTL_UAC, - MUXCTL_UAD, - MUXCTL_UDA, - MUXCTL_RESERVED5, - MUXCTL_ATE, - MUXCTL_RM, - - MUXCTL_ATB, - MUXCTL_RESERVED9, - MUXCTL_ATD, - MUXCTL_ATC, - MUXCTL_ATA, - MUXCTL_KBCF, - MUXCTL_KBCE, - MUXCTL_SDMMC1, - - /* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */ - MUXCTL_GMA, - MUXCTL_GMC, - MUXCTL_HDINT, - MUXCTL_SLXA, - MUXCTL_OWC, - MUXCTL_SLXC, - MUXCTL_SLXD, - MUXCTL_SLXK, - - MUXCTL_UCA, - MUXCTL_UCB, - MUXCTL_DTA, - MUXCTL_DTB, - MUXCTL_RESERVED28, - MUXCTL_DTC, - MUXCTL_DTD, - MUXCTL_DTE, - - /* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */ - MUXCTL_DDC, - MUXCTL_CDEV1, - MUXCTL_CDEV2, - MUXCTL_CSUS, - MUXCTL_I2CP, - MUXCTL_KBCA, - MUXCTL_KBCB, - MUXCTL_KBCC, - - MUXCTL_IRTX, - MUXCTL_IRRX, - MUXCTL_DAP1, - MUXCTL_DAP2, - MUXCTL_DAP3, - MUXCTL_DAP4, - MUXCTL_GMB, - MUXCTL_GMD, - - /* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */ - MUXCTL_GME, - MUXCTL_GPV, - MUXCTL_GPU, - MUXCTL_SPDO, - MUXCTL_SPDI, - MUXCTL_SDB, - MUXCTL_SDC, - MUXCTL_SDD, - - MUXCTL_SPIH, - MUXCTL_SPIG, - MUXCTL_SPIF, - MUXCTL_SPIE, - MUXCTL_SPID, - MUXCTL_SPIC, - MUXCTL_SPIB, - MUXCTL_SPIA, - - /* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */ - MUXCTL_LPW0, - MUXCTL_LPW1, - MUXCTL_LPW2, - MUXCTL_LSDI, - MUXCTL_LSDA, - MUXCTL_LSPI, - MUXCTL_LCSN, - MUXCTL_LDC, - - MUXCTL_LSCK, - MUXCTL_LSC0, - MUXCTL_LSC1, - MUXCTL_LHS, - MUXCTL_LVS, - MUXCTL_LM0, - MUXCTL_LM1, - MUXCTL_LVP0, - - /* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */ - MUXCTL_LD0, - MUXCTL_LD1, - MUXCTL_LD2, - MUXCTL_LD3, - MUXCTL_LD4, - MUXCTL_LD5, - MUXCTL_LD6, - MUXCTL_LD7, - - MUXCTL_LD8, - MUXCTL_LD9, - MUXCTL_LD10, - MUXCTL_LD11, - MUXCTL_LD12, - MUXCTL_LD13, - MUXCTL_LD14, - MUXCTL_LD15, - - /* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */ - MUXCTL_LD16, - MUXCTL_LD17, - MUXCTL_LHP1, - MUXCTL_LHP2, - MUXCTL_LVP1, - MUXCTL_LHP0, - MUXCTL_RESERVED102, - MUXCTL_LPP, - - MUXCTL_LDI, - MUXCTL_PMC, - MUXCTL_CRTP, - MUXCTL_PTA, - MUXCTL_RESERVED108, - MUXCTL_KBCD, - MUXCTL_GPU7, - MUXCTL_DTF, - - MUXCTL_NONE = -1, -}; - -/* - * And this defines the order of the pullup/pulldown controls which are again - * in a different order - */ -enum pmux_pullid { - /* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */ - PUCTL_ATA, - PUCTL_ATB, - PUCTL_ATC, - PUCTL_ATD, - PUCTL_ATE, - PUCTL_DAP1, - PUCTL_DAP2, - PUCTL_DAP3, - - PUCTL_DAP4, - PUCTL_DTA, - PUCTL_DTB, - PUCTL_DTC, - PUCTL_DTD, - PUCTL_DTE, - PUCTL_DTF, - PUCTL_GPV, - - /* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */ - PUCTL_RM, - PUCTL_I2CP, - PUCTL_PTA, - PUCTL_GPU7, - PUCTL_KBCA, - PUCTL_KBCB, - PUCTL_KBCC, - PUCTL_KBCD, - - PUCTL_SPDI, - PUCTL_SPDO, - PUCTL_GPSLXAU, - PUCTL_CRTP, - PUCTL_SLXC, - PUCTL_SLXD, - PUCTL_SLXK, - - /* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */ - PUCTL_CDEV1, - PUCTL_CDEV2, - PUCTL_SPIA, - PUCTL_SPIB, - PUCTL_SPIC, - PUCTL_SPID, - PUCTL_SPIE, - PUCTL_SPIF, - - PUCTL_SPIG, - PUCTL_SPIH, - PUCTL_IRTX, - PUCTL_IRRX, - PUCTL_GME, - PUCTL_RESERVED45, - PUCTL_XM2D, - PUCTL_XM2C, - - /* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */ - PUCTL_UAA, - PUCTL_UAB, - PUCTL_UAC, - PUCTL_UAD, - PUCTL_UCA, - PUCTL_UCB, - PUCTL_LD17, - PUCTL_LD19_18, - - PUCTL_LD21_20, - PUCTL_LD23_22, - PUCTL_LS, - PUCTL_LC, - PUCTL_CSUS, - PUCTL_DDRC, - PUCTL_SDC, - PUCTL_SDD, - - /* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */ - PUCTL_KBCF, - PUCTL_KBCE, - PUCTL_PMCA, - PUCTL_PMCB, - PUCTL_PMCC, - PUCTL_PMCD, - PUCTL_PMCE, - PUCTL_CK32, - - PUCTL_UDA, - PUCTL_SDMMC1, - PUCTL_GMA, - PUCTL_GMB, - PUCTL_GMC, - PUCTL_GMD, - PUCTL_DDC, - PUCTL_OWC, - - PUCTL_NONE = -1 -}; - -/* Convenient macro for defining pin group properties */ -#define PINALL(pingrp, f0, f1, f2, f3, mux, pupd) \ - { \ - .funcs = { \ - PMUX_FUNC_ ## f0, \ - PMUX_FUNC_ ## f1, \ - PMUX_FUNC_ ## f2, \ - PMUX_FUNC_ ## f3, \ - }, \ - .ctl_id = mux, \ - .pull_id = pupd \ - } - -/* A normal pin group where the mux name and pull-up name match */ -#define PIN(pingrp, f0, f1, f2, f3) \ - PINALL(pingrp, f0, f1, f2, f3, MUXCTL_##pingrp, PUCTL_##pingrp) - -/* A pin group where the pull-up name doesn't have a 1-1 mapping */ -#define PINP(pingrp, f0, f1, f2, f3, pupd) \ - PINALL(pingrp, f0, f1, f2, f3, MUXCTL_##pingrp, PUCTL_##pupd) - -/* A pin group number which is not used */ -#define PIN_RESERVED \ - PIN(NONE, RSVD1, RSVD2, RSVD3, RSVD4) - -#define DRVGRP(drvgrp) \ - PINALL(drvgrp, RSVD1, RSVD2, RSVD3, RSVD4, MUXCTL_NONE, PUCTL_NONE) - -static const struct pmux_pingrp_desc tegra20_pingroups[] = { - PIN(ATA, IDE, NAND, GMI, RSVD4), - PIN(ATB, IDE, NAND, GMI, SDIO4), - PIN(ATC, IDE, NAND, GMI, SDIO4), - PIN(ATD, IDE, NAND, GMI, SDIO4), - PIN(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC), - PIN(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4), - PIN(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK), - PIN(DAP1, DAP1, RSVD2, GMI, SDIO2), - - PIN(DAP2, DAP2, TWC, RSVD3, GMI), - PIN(DAP3, DAP3, RSVD2, RSVD3, RSVD4), - PIN(DAP4, DAP4, RSVD2, GMI, RSVD4), - PIN(DTA, RSVD1, SDIO2, VI, RSVD4), - PIN(DTB, RSVD1, RSVD2, VI, SPI1), - PIN(DTC, RSVD1, RSVD2, VI, RSVD4), - PIN(DTD, RSVD1, SDIO2, VI, RSVD4), - PIN(DTE, RSVD1, RSVD2, VI, SPI1), - - PINP(GPU, PWM, UARTA, GMI, RSVD4, GPSLXAU), - PIN(GPV, PCIE, RSVD2, RSVD3, RSVD4), - PIN(I2CP, I2C, RSVD2, RSVD3, RSVD4), - PIN(IRTX, UARTA, UARTB, GMI, SPI4), - PIN(IRRX, UARTA, UARTB, GMI, SPI4), - PIN(KBCB, KBC, NAND, SDIO2, MIO), - PIN(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL), - PINP(PMC, PWR_ON, PWR_INTR, RSVD3, RSVD4, NONE), - - PIN(PTA, I2C2, HDMI, GMI, RSVD4), - PIN(RM, I2C, RSVD2, RSVD3, RSVD4), - PIN(KBCE, KBC, NAND, OWR, RSVD4), - PIN(KBCF, KBC, NAND, TRACE, MIO), - PIN(GMA, UARTE, SPI3, GMI, SDIO4), - PIN(GMC, UARTD, SPI4, GMI, SFLASH), - PIN(SDMMC1, SDIO1, RSVD2, UARTE, UARTA), - PIN(OWC, OWR, RSVD2, RSVD3, RSVD4), - - PIN(GME, RSVD1, DAP5, GMI, SDIO4), - PIN(SDC, PWM, TWC, SDIO3, SPI3), - PIN(SDD, UARTA, PWM, SDIO3, SPI3), - PIN_RESERVED, - PINP(SLXA, PCIE, SPI4, SDIO3, SPI2, CRTP), - PIN(SLXC, SPDIF, SPI4, SDIO3, SPI2), - PIN(SLXD, SPDIF, SPI4, SDIO3, SPI2), - PIN(SLXK, PCIE, SPI4, SDIO3, SPI2), - - PIN(SPDI, SPDIF, RSVD2, I2C, SDIO2), - PIN(SPDO, SPDIF, RSVD2, I2C, SDIO2), - PIN(SPIA, SPI1, SPI2, SPI3, GMI), - PIN(SPIB, SPI1, SPI2, SPI3, GMI), - PIN(SPIC, SPI1, SPI2, SPI3, GMI), - PIN(SPID, SPI2, SPI1, SPI2_ALT, GMI), - PIN(SPIE, SPI2, SPI1, SPI2_ALT, GMI), - PIN(SPIF, SPI3, SPI1, SPI2, RSVD4), - - PIN(SPIG, SPI3, SPI2, SPI2_ALT, I2C), - PIN(SPIH, SPI3, SPI2, SPI2_ALT, I2C), - PIN(UAA, SPI3, MIPI_HS, UARTA, ULPI), - PIN(UAB, SPI2, MIPI_HS, UARTA, ULPI), - PIN(UAC, OWR, RSVD2, RSVD3, RSVD4), - PIN(UAD, UARTB, SPDIF, UARTA, SPI4), - PIN(UCA, UARTC, RSVD2, GMI, RSVD4), - PIN(UCB, UARTC, PWM, GMI, RSVD4), - - PIN_RESERVED, - PIN(ATE, IDE, NAND, GMI, RSVD4), - PIN(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL), - PIN_RESERVED, - PIN_RESERVED, - PIN(GMB, IDE, NAND, GMI, GMI_INT), - PIN(GMD, RSVD1, NAND, GMI, SFLASH), - PIN(DDC, I2C2, RSVD2, RSVD3, RSVD4), - - /* 64 */ - PINP(LD0, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD1, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD2, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD3, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD4, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD5, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD6, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD7, DISPA, DISPB, XIO, RSVD4, LD17), - - PINP(LD8, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD9, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD10, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD11, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD12, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD13, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD14, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD15, DISPA, DISPB, XIO, RSVD4, LD17), - - PINP(LD16, DISPA, DISPB, XIO, RSVD4, LD17), - PINP(LD17, DISPA, DISPB, RSVD3, RSVD4, LD17), - PINP(LHP0, DISPA, DISPB, RSVD3, RSVD4, LD21_20), - PINP(LHP1, DISPA, DISPB, RSVD3, RSVD4, LD19_18), - PINP(LHP2, DISPA, DISPB, RSVD3, RSVD4, LD19_18), - PINP(LVP0, DISPA, DISPB, RSVD3, RSVD4, LC), - PINP(LVP1, DISPA, DISPB, RSVD3, RSVD4, LD21_20), - PINP(HDINT, HDMI, RSVD2, RSVD3, RSVD4, LC), - - PINP(LM0, DISPA, DISPB, SPI3, RSVD4, LC), - PINP(LM1, DISPA, DISPB, RSVD3, CRT, LC), - PINP(LVS, DISPA, DISPB, XIO, RSVD4, LC), - PINP(LSC0, DISPA, DISPB, XIO, RSVD4, LC), - PINP(LSC1, DISPA, DISPB, SPI3, HDMI, LS), - PINP(LSCK, DISPA, DISPB, SPI3, HDMI, LS), - PINP(LDC, DISPA, DISPB, RSVD3, RSVD4, LS), - PINP(LCSN, DISPA, DISPB, SPI3, RSVD4, LS), - - /* 96 */ - PINP(LSPI, DISPA, DISPB, XIO, HDMI, LC), - PINP(LSDA, DISPA, DISPB, SPI3, HDMI, LS), - PINP(LSDI, DISPA, DISPB, SPI3, RSVD4, LS), - PINP(LPW0, DISPA, DISPB, SPI3, HDMI, LS), - PINP(LPW1, DISPA, DISPB, RSVD3, RSVD4, LS), - PINP(LPW2, DISPA, DISPB, SPI3, HDMI, LS), - PINP(LDI, DISPA, DISPB, RSVD3, RSVD4, LD23_22), - PINP(LHS, DISPA, DISPB, XIO, RSVD4, LC), - - PINP(LPP, DISPA, DISPB, RSVD3, RSVD4, LD23_22), - PIN_RESERVED, - PIN(KBCD, KBC, NAND, SDIO2, MIO), - PIN(GPU7, RTCK, RSVD2, RSVD3, RSVD4), - PIN(DTF, I2C3, RSVD2, VI, RSVD4), - PIN(UDA, SPI1, RSVD2, UARTD, ULPI), - PIN(CRTP, CRT, RSVD2, RSVD3, RSVD4), - PINP(SDB, UARTA, PWM, SDIO3, SPI2, NONE), - - /* these pin groups only have pullup and pull down control */ - DRVGRP(CK32), - DRVGRP(DDRC), - DRVGRP(PMCA), - DRVGRP(PMCB), - DRVGRP(PMCC), - DRVGRP(PMCD), - DRVGRP(PMCE), - DRVGRP(XM2C), - DRVGRP(XM2D), -}; -const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra20_pingroups; diff --git a/arch/arm/cpu/tegra20-common/pmu.c b/arch/arm/cpu/tegra20-common/pmu.c deleted file mode 100644 index a774246a27..0000000000 --- a/arch/arm/cpu/tegra20-common/pmu.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010,2011 NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define VDD_CORE_NOMINAL_T25 0x17 /* 1.3v */ -#define VDD_CPU_NOMINAL_T25 0x10 /* 1.125v */ - -#define VDD_CORE_NOMINAL_T20 0x16 /* 1.275v */ -#define VDD_CPU_NOMINAL_T20 0x0f /* 1.1v */ - -#define VDD_RELATION 0x02 /* 50mv */ -#define VDD_TRANSITION_STEP 0x06 /* 150mv */ -#define VDD_TRANSITION_RATE 0x06 /* 3.52mv/us */ - -#define PMI_I2C_ADDRESS 0x34 /* chip requires this address */ - -int pmu_set_nominal(void) -{ - struct udevice *bus, *dev; - int core, cpu; - int ret; - - /* by default, the table has been filled with T25 settings */ - switch (tegra_get_chip_sku()) { - case TEGRA_SOC_T20: - core = VDD_CORE_NOMINAL_T20; - cpu = VDD_CPU_NOMINAL_T20; - break; - case TEGRA_SOC_T25: - core = VDD_CORE_NOMINAL_T25; - cpu = VDD_CPU_NOMINAL_T25; - break; - default: - debug("%s: Unknown SKU id\n", __func__); - return -1; - } - - ret = tegra_i2c_get_dvc_bus(&bus); - if (ret) { - debug("%s: Cannot find DVC I2C bus\n", __func__); - return ret; - } - ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, 1, &dev); - if (ret) { - debug("%s: Cannot find DVC I2C chip\n", __func__); - return ret; - } - - tps6586x_init(dev); - tps6586x_set_pwm_mode(TPS6586X_PWM_SM1); - return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP, - VDD_TRANSITION_RATE, VDD_RELATION); -} diff --git a/arch/arm/cpu/tegra20-common/warmboot.c b/arch/arm/cpu/tegra20-common/warmboot.c deleted file mode 100644 index 5fdc4bbb50..0000000000 --- a/arch/arm/cpu/tegra20-common/warmboot.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * (C) Copyright 2010 - 2011 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_TEGRA_CLOCK_SCALING -#error "You must enable CONFIG_TEGRA_CLOCK_SCALING to use CONFIG_TEGRA_LP0" -#endif - -/* - * This is the place in SRAM where the SDRAM parameters are stored. There - * are 4 blocks, one for each RAM code - */ -#define SDRAM_PARAMS_BASE (NV_PA_BASE_SRAM + 0x188) - -/* TODO: If we later add support for the Misc GP controller, refactor this */ -union xm2cfga_reg { - struct { - u32 reserved0:2; - u32 hsm_en:1; - u32 reserved1:2; - u32 preemp_en:1; - u32 vref_en:1; - u32 reserved2:5; - u32 cal_drvdn:5; - u32 reserved3:3; - u32 cal_drvup:5; - u32 reserved4:3; - u32 cal_drvdn_slwr:2; - u32 cal_drvup_slwf:2; - }; - u32 word; -}; - -union xm2cfgd_reg { - struct { - u32 reserved0:2; - u32 hsm_en:1; - u32 schmt_en:1; - u32 lpmd:2; - u32 vref_en:1; - u32 reserved1:5; - u32 cal_drvdn:5; - u32 reserved2:3; - u32 cal_drvup:5; - u32 reserved3:3; - u32 cal_drvdn_slwr:2; - u32 cal_drvup_slwf:2; - }; - u32 word; -}; - -/* - * TODO: This register is not documented in the TRM yet. We could move this - * into the EMC and give it a proper interface, but not while it is - * undocumented. - */ -union fbio_spare_reg { - struct { - u32 reserved:24; - u32 cfg_wb0:8; - }; - u32 word; -}; - -/* We pack the resume information into these unions for later */ -union scratch2_reg { - struct { - u32 pllm_base_divm:5; - u32 pllm_base_divn:10; - u32 pllm_base_divp:3; - u32 pllm_misc_lfcon:4; - u32 pllm_misc_cpcon:4; - u32 gp_xm2cfga_padctrl_preemp:1; - u32 gp_xm2cfgd_padctrl_schmt:1; - u32 osc_ctrl_xobp:1; - u32 memory_type:3; - }; - u32 word; -}; - -union scratch4_reg { - struct { - u32 emc_clock_divider:8; - u32 pllm_stable_time:8; - u32 pllx_stable_time:8; - u32 emc_fbio_spare_cfg_wb0:8; - }; - u32 word; -}; - -union scratch24_reg { - struct { - u32 emc_auto_cal_wait:8; - u32 emc_pin_program_wait:8; - u32 warmboot_wait:8; - u32 reserved:8; - }; - u32 word; -}; - -int warmboot_save_sdram_params(void) -{ - u32 ram_code; - struct sdram_params sdram; - struct apb_misc_pp_ctlr *apb_misc = - (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - struct emc_ctlr *emc = emc_get_controller(gd->fdt_blob); - union scratch2_reg scratch2; - union scratch4_reg scratch4; - union scratch24_reg scratch24; - union xm2cfga_reg xm2cfga; - union xm2cfgd_reg xm2cfgd; - union fbio_spare_reg fbio_spare; - - /* get ram code that is used as index to array sdram_params in BCT */ - ram_code = (readl(&apb_misc->strapping_opt_a) >> - STRAP_OPT_A_RAM_CODE_SHIFT) & 3; - memcpy(&sdram, - (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code), - sizeof(sdram)); - - xm2cfga.word = readl(&gp->xm2cfga); - xm2cfgd.word = readl(&gp->xm2cfgd); - - scratch2.word = 0; - scratch2.osc_ctrl_xobp = clock_get_osc_bypass(); - - /* Get the memory PLL settings */ - { - u32 divm, divn, divp, cpcon, lfcon; - - if (clock_ll_read_pll(CLOCK_ID_MEMORY, &divm, &divn, &divp, - &cpcon, &lfcon)) - return -1; - scratch2.pllm_base_divm = divm; - scratch2.pllm_base_divn = divn; - scratch2.pllm_base_divp = divp; - scratch2.pllm_misc_cpcon = cpcon; - scratch2.pllm_misc_lfcon = lfcon; - } - - scratch2.gp_xm2cfga_padctrl_preemp = xm2cfga.preemp_en; - scratch2.gp_xm2cfgd_padctrl_schmt = xm2cfgd.schmt_en; - scratch2.memory_type = sdram.memory_type; - writel(scratch2.word, &pmc->pmc_scratch2); - - /* collect data from various sources for pmc_scratch4 */ - fbio_spare.word = readl(&emc->fbio_spare); - scratch4.word = 0; - scratch4.emc_fbio_spare_cfg_wb0 = fbio_spare.cfg_wb0; - scratch4.emc_clock_divider = sdram.emc_clock_divider; - scratch4.pllm_stable_time = -1; - scratch4.pllx_stable_time = -1; - writel(scratch4.word, &pmc->pmc_scratch4); - - /* collect various data from sdram for pmc_scratch24 */ - scratch24.word = 0; - scratch24.emc_pin_program_wait = sdram.emc_pin_program_wait; - scratch24.emc_auto_cal_wait = sdram.emc_auto_cal_wait; - scratch24.warmboot_wait = sdram.warm_boot_wait; - writel(scratch24.word, &pmc->pmc_scratch24); - - return 0; -} - -static u32 get_major_version(void) -{ - u32 major_id; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - - major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >> - HIDREV_MAJORPREV_SHIFT; - return major_id; -} - -static int is_production_mode_fuse_set(struct fuse_regs *fuse) -{ - return readl(&fuse->production_mode); -} - -static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse) -{ - return readl(&fuse->security_mode); -} - -static int is_failure_analysis_mode(struct fuse_regs *fuse) -{ - return readl(&fuse->fa); -} - -static int ap20_is_odm_production_mode(void) -{ - struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; - - if (!is_failure_analysis_mode(fuse) && - is_odm_production_mode_fuse_set(fuse)) - return 1; - else - return 0; -} - -static int ap20_is_production_mode(void) -{ - struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; - - if (get_major_version() == 0) - return 1; - - if (!is_failure_analysis_mode(fuse) && - is_production_mode_fuse_set(fuse) && - !is_odm_production_mode_fuse_set(fuse)) - return 1; - else - return 0; -} - -static enum fuse_operating_mode fuse_get_operation_mode(void) -{ - u32 chip_id; - struct apb_misc_gp_ctlr *gp = - (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; - - chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> - HIDREV_CHIPID_SHIFT; - if (chip_id == CHIPID_TEGRA20) { - if (ap20_is_odm_production_mode()) { - printf("!! odm_production_mode is not supported !!\n"); - return MODE_UNDEFINED; - } else - if (ap20_is_production_mode()) - return MODE_PRODUCTION; - else - return MODE_UNDEFINED; - } - return MODE_UNDEFINED; -} - -static void determine_crypto_options(int *is_encrypted, int *is_signed, - int *use_zero_key) -{ - switch (fuse_get_operation_mode()) { - case MODE_PRODUCTION: - *is_encrypted = 0; - *is_signed = 1; - *use_zero_key = 1; - break; - case MODE_UNDEFINED: - default: - *is_encrypted = 0; - *is_signed = 0; - *use_zero_key = 0; - break; - } -} - -static int sign_wb_code(u32 start, u32 length, int use_zero_key) -{ - int err; - u8 *source; /* Pointer to source */ - u8 *hash; - - /* Calculate AES block parameters. */ - source = (u8 *)(start + offsetof(struct wb_header, random_aes_block)); - length -= offsetof(struct wb_header, random_aes_block); - hash = (u8 *)(start + offsetof(struct wb_header, hash)); - err = sign_data_block(source, length, hash); - - return err; -} - -int warmboot_prepare_code(u32 seg_address, u32 seg_length) -{ - int err = 0; - u32 length; /* length of the signed/encrypt code */ - struct wb_header *dst_header; /* Pointer to dest WB header */ - int is_encrypted; /* Segment is encrypted */ - int is_signed; /* Segment is signed */ - int use_zero_key; /* Use key of all zeros */ - - /* Determine crypto options. */ - determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key); - - /* Get the actual code limits. */ - length = roundup(((u32)wb_end - (u32)wb_start), 16); - - /* - * The region specified by seg_address must be in SDRAM and must be - * nonzero in length. - */ - if (seg_length == 0 || seg_address < NV_PA_SDRAM_BASE || - seg_address + seg_length >= NV_PA_SDRAM_BASE + gd->ram_size) { - err = -EFAULT; - goto fail; - } - - /* Things must be 16-byte aligned. */ - if ((seg_length & 0xF) || (seg_address & 0xF)) { - err = -EINVAL; - goto fail; - } - - /* Will the code fit? (destination includes wb_header + wb code) */ - if (seg_length < (length + sizeof(struct wb_header))) { - err = -EINVAL; - goto fail; - } - - dst_header = (struct wb_header *)seg_address; - memset((char *)dst_header, 0, sizeof(struct wb_header)); - - /* Populate the random_aes_block as requested. */ - { - u32 *aes_block = (u32 *)&(dst_header->random_aes_block); - u32 *end = (u32 *)(((u32)aes_block) + - sizeof(dst_header->random_aes_block)); - - do { - *aes_block++ = 0; - } while (aes_block < end); - } - - /* Populate the header. */ - dst_header->length_insecure = length + sizeof(struct wb_header); - dst_header->length_secure = length + sizeof(struct wb_header); - dst_header->destination = NV_WB_RUN_ADDRESS; - dst_header->entry_point = NV_WB_RUN_ADDRESS; - dst_header->code_length = length; - - if (is_encrypted) { - printf("!!!! Encryption is not supported !!!!\n"); - dst_header->length_insecure = 0; - err = -EACCES; - goto fail; - } else - /* copy the wb code directly following dst_header. */ - memcpy((char *)(dst_header+1), (char *)wb_start, length); - - if (is_signed) - err = sign_wb_code(seg_address, dst_header->length_insecure, - use_zero_key); - -fail: - if (err) - printf("Warning: warmboot code copy failed (error=%d)\n", err); - - return err; -} diff --git a/arch/arm/cpu/tegra20-common/warmboot_avp.c b/arch/arm/cpu/tegra20-common/warmboot_avp.c deleted file mode 100644 index 27ce5f480f..0000000000 --- a/arch/arm/cpu/tegra20-common/warmboot_avp.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * (C) Copyright 2010 - 2011 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "warmboot_avp.h" - -#define DEBUG_RESET_CORESIGHT - -void wb_start(void) -{ - struct apb_misc_pp_ctlr *apb_misc = - (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; - struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; - struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - union osc_ctrl_reg osc_ctrl; - union pllx_base_reg pllx_base; - union pllx_misc_reg pllx_misc; - union scratch3_reg scratch3; - u32 reg; - - /* enable JTAG & TBE */ - writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &apb_misc->cfg_ctl); - - /* Are we running where we're supposed to be? */ - asm volatile ( - "adr %0, wb_start;" /* reg: wb_start address */ - : "=r"(reg) /* output */ - /* no input, no clobber list */ - ); - - if (reg != NV_WB_RUN_ADDRESS) - goto do_reset; - - /* Are we running with AVP? */ - if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP) - goto do_reset; - -#ifdef DEBUG_RESET_CORESIGHT - /* Assert CoreSight reset */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); - reg |= SWR_CSITE_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); -#endif - - /* TODO: Set the drive strength - maybe make this a board parameter? */ - osc_ctrl.word = readl(&clkrst->crc_osc_ctrl); - osc_ctrl.xofs = 4; - osc_ctrl.xoe = 1; - writel(osc_ctrl.word, &clkrst->crc_osc_ctrl); - - /* Power up the CPU complex if necessary */ - if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) { - reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START; - writel(reg, &pmc->pmc_pwrgate_toggle); - while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) - ; - } - - /* Remove the I/O clamps from the CPU power partition. */ - reg = readl(&pmc->pmc_remove_clamping); - reg |= CPU_CLMP; - writel(reg, &pmc->pmc_remove_clamping); - - reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP; - writel(reg, &flow->halt_cop_events); - - /* Assert CPU complex reset */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); - reg |= CPU_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - - /* Hold both CPUs in reset */ - reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 | - CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1; - writel(reg, &clkrst->crc_cpu_cmplx_set); - - /* Halt CPU1 at the flow controller for uni-processor configurations */ - writel(EVENT_MODE_STOP, &flow->halt_cpu1_events); - - /* - * Set the CPU reset vector. SCRATCH41 contains the physical - * address of the CPU-side restoration code. - */ - reg = readl(&pmc->pmc_scratch41); - writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Select CPU complex clock source */ - writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - - /* Start the CPU0 clock and stop the CPU1 clock */ - reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN | - CPU_CMPLX_CPU1_CLK_STP_STOP; - writel(reg, &clkrst->crc_clk_cpu_cmplx); - - /* Enable the CPU complex clock */ - reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]); - reg |= CLK_ENB_CPU; - writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]); - - /* Make sure the resets were held for at least 2 microseconds */ - reg = readl(TIMER_USEC_CNTR); - while (readl(TIMER_USEC_CNTR) <= (reg + 2)) - ; - -#ifdef DEBUG_RESET_CORESIGHT - /* - * De-assert CoreSight reset. - * NOTE: We're leaving the CoreSight clock on the oscillator for - * now. It will be restored to its original clock source - * when the CPU-side restoration code runs. - */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); - reg &= ~SWR_CSITE_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); -#endif - - /* Unlock the CPU CoreSight interfaces */ - reg = 0xC5ACCE55; - writel(reg, CSITE_CPU_DBG0_LAR); - writel(reg, CSITE_CPU_DBG1_LAR); - - /* - * Sample the microsecond timestamp again. This is the time we must - * use when returning from LP0 for PLL stabilization delays. - */ - reg = readl(TIMER_USEC_CNTR); - writel(reg, &pmc->pmc_scratch1); - - pllx_base.word = 0; - pllx_misc.word = 0; - scratch3.word = readl(&pmc->pmc_scratch3); - - /* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */ - reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1; - - /* - * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and - * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz. - * - * reg is used to calculate the pllx freq, which is used to determine if - * to set dccon or not. - */ - if (reg > 26) - reg = 19; - - /* PLLX_BASE.PLLX_DIVM */ - if (scratch3.pllx_base_divm == reg) - reg = 0; - else - reg = 1; - - /* PLLX_BASE.PLLX_DIVN */ - pllx_base.divn = scratch3.pllx_base_divn; - reg = scratch3.pllx_base_divn << reg; - - /* PLLX_BASE.PLLX_DIVP */ - pllx_base.divp = scratch3.pllx_base_divp; - reg = reg >> scratch3.pllx_base_divp; - - pllx_base.bypass = 1; - - /* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */ - if (reg > 600) - pllx_misc.dccon = 1; - - /* PLLX_MISC_LFCON */ - pllx_misc.lfcon = scratch3.pllx_misc_lfcon; - - /* PLLX_MISC_CPCON */ - pllx_misc.cpcon = scratch3.pllx_misc_cpcon; - - writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc); - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - - pllx_base.enable = 1; - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - pllx_base.bypass = 0; - writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); - - writel(0, flow->halt_cpu_events); - - reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0; - writel(reg, &clkrst->crc_cpu_cmplx_clr); - - reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE | - PLLM_OUT1_RATIO_VAL_8; - writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out[0]); - - reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 | - SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 | - SCLK_SYS_STATE_IDLE; - writel(reg, &clkrst->crc_sclk_brst_pol); - - /* avp_resume: no return after the write */ - reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); - reg &= ~CPU_RST; - writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - - /* avp_halt: */ -avp_halt: - reg = EVENT_MODE_STOP | EVENT_JTAG; - writel(reg, flow->halt_cop_events); - goto avp_halt; - -do_reset: - /* - * Execution comes here if something goes wrong. The chip is reset and - * a cold boot is performed. - */ - writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]); - goto do_reset; -} - -/* - * wb_end() is a dummy function, and must be directly following wb_start(), - * and is used to calculate the size of wb_start(). - */ -void wb_end(void) -{ -} diff --git a/arch/arm/cpu/tegra20-common/warmboot_avp.h b/arch/arm/cpu/tegra20-common/warmboot_avp.h deleted file mode 100644 index 7b86acb156..0000000000 --- a/arch/arm/cpu/tegra20-common/warmboot_avp.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) Copyright 2010, 2011 - * NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _WARMBOOT_AVP_H_ -#define _WARMBOOT_AVP_H_ - -#define TEGRA_DEV_L 0 -#define TEGRA_DEV_H 1 -#define TEGRA_DEV_U 2 - -#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) -#define SIMPLE_PLLE (CLOCK_ID_EPCI - CLOCK_ID_FIRST_SIMPLE) - -#define TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0) -#define TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4) - -#define USEC_CFG_DIVISOR_MASK 0xffff - -#define CONFIG_CTL_TBE (1 << 7) -#define CONFIG_CTL_JTAG (1 << 6) - -#define CPU_RST (1 << 0) -#define CLK_ENB_CPU (1 << 0) -#define SWR_TRIG_SYS_RST (1 << 2) -#define SWR_CSITE_RST (1 << 9) - -#define PWRGATE_STATUS_CPU (1 << 0) -#define PWRGATE_TOGGLE_PARTID_CPU (0 << 0) -#define PWRGATE_TOGGLE_START (1 << 8) - -#define CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 (3 << 0) -#define CPU_CMPLX_CPU0_CLK_STP_STOP (1 << 8) -#define CPU_CMPLX_CPU0_CLK_STP_RUN (0 << 8) -#define CPU_CMPLX_CPU1_CLK_STP_STOP (1 << 9) -#define CPU_CMPLX_CPU1_CLK_STP_RUN (0 << 9) - -#define CPU_CMPLX_CPURESET0 (1 << 0) -#define CPU_CMPLX_CPURESET1 (1 << 1) -#define CPU_CMPLX_DERESET0 (1 << 4) -#define CPU_CMPLX_DERESET1 (1 << 5) -#define CPU_CMPLX_DBGRESET0 (1 << 12) -#define CPU_CMPLX_DBGRESET1 (1 << 13) - -#define PLLM_OUT1_RSTN_RESET_DISABLE (1 << 0) -#define PLLM_OUT1_CLKEN_ENABLE (1 << 1) -#define PLLM_OUT1_RATIO_VAL_8 (8 << 8) - -#define SCLK_SYS_STATE_IDLE (1 << 28) -#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 (7 << 12) -#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 (7 << 8) -#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1 (7 << 4) -#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 (7 << 0) - -#define EVENT_ZERO_VAL_20 (20 << 0) -#define EVENT_MSEC (1 << 24) -#define EVENT_JTAG (1 << 28) -#define EVENT_MODE_STOP (2 << 29) - -#define CCLK_PLLP_BURST_POLICY 0x20004444 - -#endif diff --git a/arch/arm/cpu/tegra30-common/Makefile b/arch/arm/cpu/tegra30-common/Makefile deleted file mode 100644 index d2d616e8a4..0000000000 --- a/arch/arm/cpu/tegra30-common/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. -# -# (C) Copyright 2000-2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms and conditions of the GNU General Public License, -# version 2, as published by the Free Software Foundation. -# -# This program is distributed in the hope 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. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -obj-y += clock.o funcmux.o pinmux.o diff --git a/arch/arm/cpu/tegra30-common/clock.c b/arch/arm/cpu/tegra30-common/clock.c deleted file mode 100644 index 0eb0f0ade3..0000000000 --- a/arch/arm/cpu/tegra30-common/clock.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra30 Clock control functions */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Clock types that we can use as a source. The Tegra30 has muxes for the - * peripheral clocks, and in most cases there are four options for the clock - * source. This gives us a clock 'type' and exploits what commonality exists - * in the device. - * - * Letters are obvious, except for T which means CLK_M, and S which means the - * clock derived from 32KHz. Beware that CLK_M (also called OSC in the - * datasheet) and PLL_M are different things. The former is the basic - * clock supplied to the SOC from an external oscillator. The latter is the - * memory clock PLL. - * - * See definitions in clock_id in the header file. - */ -enum clock_type_id { - CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ - CLOCK_TYPE_MCPA, /* and so on */ - CLOCK_TYPE_MCPT, - CLOCK_TYPE_PCM, - CLOCK_TYPE_PCMT, - CLOCK_TYPE_PCMT16, - CLOCK_TYPE_PDCT, - CLOCK_TYPE_ACPT, - CLOCK_TYPE_ASPTE, - CLOCK_TYPE_PMDACD2T, - CLOCK_TYPE_PCST, - - CLOCK_TYPE_COUNT, - CLOCK_TYPE_NONE = -1, /* invalid clock type */ -}; - -enum { - CLOCK_MAX_MUX = 8 /* number of source options for each clock */ -}; - -/* - * Clock source mux for each clock type. This just converts our enum into - * a list of mux sources for use by the code. - * - * Note: - * The extra column in each clock source array is used to store the mask - * bits in its register for the source. - */ -#define CLK(x) CLOCK_ID_ ## x -static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { - { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_30}, - { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), - CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), - CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), - MASK_BITS_31_29}, - { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), - CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), - MASK_BITS_31_28} -}; - -/* - * Clock type for each peripheral clock source. We put the name in each - * record just so it is easy to match things up - */ -#define TYPE(name, type) type -static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { - /* 0x00 */ - TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), - TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), - - /* 0x08 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), - - /* 0x10 */ - TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), - - /* 0x18 */ - TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ - TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), - - /* 0x20 */ - TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), - TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), - - /* 0x28 */ - TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), - - /* 0x30 */ - TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - - /* 0x38h */ /* Jumps to reg offset 0x3B0h - new for T30 */ - TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), - TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ - TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), - TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), - TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), - - /* 0x40 */ - TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), - TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ - TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), - - /* 0x48 */ - TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), - TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ - TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - - /* 0x50 */ - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), - TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ - TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), - TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), -}; - -/* - * This array translates a periph_id to a periphc_internal_id - * - * Not present/matched up: - * uint vi_sensor; _VI_SENSOR_0, 0x1A8 - * SPDIF - which is both 0x08 and 0x0c - * - */ -#define NONE(name) (-1) -#define OFFSET(name, value) PERIPHC_ ## name -static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { - /* Low word: 31:0 */ - NONE(CPU), - NONE(COP), - NONE(TRIGSYS), - NONE(RESERVED3), - NONE(RESERVED4), - NONE(TMR), - PERIPHC_UART1, - PERIPHC_UART2, /* and vfir 0x68 */ - - /* 8 */ - NONE(GPIO), - PERIPHC_SDMMC2, - NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ - PERIPHC_I2S1, - PERIPHC_I2C1, - PERIPHC_NDFLASH, - PERIPHC_SDMMC1, - PERIPHC_SDMMC4, - - /* 16 */ - NONE(RESERVED16), - PERIPHC_PWM, - PERIPHC_I2S2, - PERIPHC_EPP, - PERIPHC_VI, - PERIPHC_G2D, - NONE(USBD), - NONE(ISP), - - /* 24 */ - PERIPHC_G3D, - NONE(RESERVED25), - PERIPHC_DISP2, - PERIPHC_DISP1, - PERIPHC_HOST1X, - NONE(VCP), - PERIPHC_I2S0, - NONE(CACHE2), - - /* Middle word: 63:32 */ - NONE(MEM), - NONE(AHBDMA), - NONE(APBDMA), - NONE(RESERVED35), - NONE(RESERVED36), - NONE(STAT_MON), - NONE(RESERVED38), - NONE(RESERVED39), - - /* 40 */ - NONE(KFUSE), - PERIPHC_SBC1, - PERIPHC_NOR, - NONE(RESERVED43), - PERIPHC_SBC2, - NONE(RESERVED45), - PERIPHC_SBC3, - PERIPHC_DVC_I2C, - - /* 48 */ - NONE(DSI), - PERIPHC_TVO, /* also CVE 0x40 */ - PERIPHC_MIPI, - PERIPHC_HDMI, - NONE(CSI), - PERIPHC_TVDAC, - PERIPHC_I2C2, - PERIPHC_UART3, - - /* 56 */ - NONE(RESERVED56), - PERIPHC_EMC, - NONE(USB2), - NONE(USB3), - PERIPHC_MPE, - PERIPHC_VDE, - NONE(BSEA), - NONE(BSEV), - - /* Upper word 95:64 */ - PERIPHC_SPEEDO, - PERIPHC_UART4, - PERIPHC_UART5, - PERIPHC_I2C3, - PERIPHC_SBC4, - PERIPHC_SDMMC3, - NONE(PCIE), - PERIPHC_OWR, - - /* 72 */ - NONE(AFI), - PERIPHC_CSITE, - NONE(PCIEXCLK), - NONE(AVPUCQ), - NONE(RESERVED76), - NONE(RESERVED77), - NONE(RESERVED78), - NONE(DTV), - - /* 80 */ - PERIPHC_NANDSPEED, - PERIPHC_I2CSLOW, - NONE(DSIB), - NONE(RESERVED83), - NONE(IRAMA), - NONE(IRAMB), - NONE(IRAMC), - NONE(IRAMD), - - /* 88 */ - NONE(CRAM2), - NONE(RESERVED89), - NONE(MDOUBLER), - NONE(RESERVED91), - NONE(SUSOUT), - NONE(RESERVED93), - NONE(RESERVED94), - NONE(RESERVED95), - - /* V word: 31:0 */ - NONE(CPUG), - NONE(CPULP), - PERIPHC_G3D2, - PERIPHC_MSELECT, - PERIPHC_TSENSOR, - PERIPHC_I2S3, - PERIPHC_I2S4, - PERIPHC_I2C4, - - /* 08 */ - PERIPHC_SBC5, - PERIPHC_SBC6, - PERIPHC_AUDIO, - NONE(APBIF), - PERIPHC_DAM0, - PERIPHC_DAM1, - PERIPHC_DAM2, - PERIPHC_HDA2CODEC2X, - - /* 16 */ - NONE(ATOMICS), - NONE(RESERVED17), - NONE(RESERVED18), - NONE(RESERVED19), - NONE(RESERVED20), - NONE(RESERVED21), - NONE(RESERVED22), - PERIPHC_ACTMON, - - /* 24 */ - NONE(RESERVED24), - NONE(RESERVED25), - NONE(RESERVED26), - NONE(RESERVED27), - PERIPHC_SATA, - PERIPHC_HDA, - NONE(RESERVED30), - NONE(RESERVED31), - - /* W word: 31:0 */ - NONE(HDA2HDMICODEC), - NONE(SATACOLD), - NONE(RESERVED0_PCIERX0), - NONE(RESERVED1_PCIERX1), - NONE(RESERVED2_PCIERX2), - NONE(RESERVED3_PCIERX3), - NONE(RESERVED4_PCIERX4), - NONE(RESERVED5_PCIERX5), - - /* 40 */ - NONE(CEC), - NONE(RESERVED6_PCIE2), - NONE(RESERVED7_EMC), - NONE(RESERVED8_HDMI), - NONE(RESERVED9_SATA), - NONE(RESERVED10_MIPI), - NONE(EX_RESERVED46), - NONE(EX_RESERVED47), -}; - -/* - * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that T30 supports 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. - */ -enum clock_osc_freq clock_get_osc_freq(void) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 reg; - - reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ -} - -/* Returns a pointer to the clock source register for a peripheral */ -u32 *get_periph_source_reg(enum periph_id periph_id) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - enum periphc_internal_id internal_id; - - /* Coresight is a special case */ - if (periph_id == PERIPH_ID_CSI) - return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; - - assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); - internal_id = periph_id_to_internal_id[periph_id]; - assert(internal_id != -1); - if (internal_id >= PERIPHC_VW_FIRST) { - internal_id -= PERIPHC_VW_FIRST; - return &clkrst->crc_clk_src_vw[internal_id]; - } else - return &clkrst->crc_clk_src[internal_id]; -} - -/** - * Given a peripheral ID and the required source clock, this returns which - * value should be programmed into the source mux for that peripheral. - * - * There is special code here to handle the one source type with 5 sources. - * - * @param periph_id peripheral to start - * @param source PLL id of required parent clock - * @param mux_bits Set to number of bits in mux register: 2 or 4 - * @param divider_bits Set to number of divider bits (8 or 16) - * @return mux value (0-4, or -1 if not found) - */ -int get_periph_clock_source(enum periph_id periph_id, - enum clock_id parent, int *mux_bits, int *divider_bits) -{ - enum clock_type_id type; - enum periphc_internal_id internal_id; - int mux; - - assert(clock_periph_id_isvalid(periph_id)); - - internal_id = periph_id_to_internal_id[periph_id]; - assert(periphc_internal_id_isvalid(internal_id)); - - type = clock_periph_type[internal_id]; - assert(clock_type_id_isvalid(type)); - - *mux_bits = clock_source[type][CLOCK_MAX_MUX]; - - if (type == CLOCK_TYPE_PCMT16) - *divider_bits = 16; - else - *divider_bits = 8; - - for (mux = 0; mux < CLOCK_MAX_MUX; mux++) - if (clock_source[type][mux] == parent) - return mux; - - /* if we get here, either us or the caller has made a mistake */ - printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, - parent); - return -1; -} - -void clock_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *clk; - u32 reg; - - /* Enable/disable the clock to this peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) - clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; - else - clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; - reg = readl(clk); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, clk); -} - -void reset_set_enable(enum periph_id periph_id, int enable) -{ - struct clk_rst_ctlr *clkrst = - (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 *reset; - u32 reg; - - /* Enable/disable reset to the peripheral */ - assert(clock_periph_id_isvalid(periph_id)); - if (periph_id < PERIPH_ID_VW_FIRST) - reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; - else - reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; - reg = readl(reset); - if (enable) - reg |= PERIPH_MASK(periph_id); - else - reg &= ~PERIPH_MASK(periph_id); - writel(reg, reset); -} - -#ifdef CONFIG_OF_CONTROL -/* - * Convert a device tree clock ID to our peripheral ID. They are mostly - * the same but we are very cautious so we check that a valid clock ID is - * provided. - * - * @param clk_id Clock ID according to tegra30 device tree binding - * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid - */ -enum periph_id clk_id_to_periph_id(int clk_id) -{ - if (clk_id > PERIPH_ID_COUNT) - return PERIPH_ID_NONE; - - switch (clk_id) { - case PERIPH_ID_RESERVED3: - case PERIPH_ID_RESERVED4: - case PERIPH_ID_RESERVED16: - case PERIPH_ID_RESERVED24: - case PERIPH_ID_RESERVED35: - case PERIPH_ID_RESERVED43: - case PERIPH_ID_RESERVED45: - case PERIPH_ID_RESERVED56: - case PERIPH_ID_PCIEXCLK: - case PERIPH_ID_RESERVED76: - case PERIPH_ID_RESERVED77: - case PERIPH_ID_RESERVED78: - case PERIPH_ID_RESERVED83: - case PERIPH_ID_RESERVED89: - case PERIPH_ID_RESERVED91: - case PERIPH_ID_RESERVED93: - case PERIPH_ID_RESERVED94: - case PERIPH_ID_RESERVED95: - return PERIPH_ID_NONE; - default: - return clk_id; - } -} -#endif /* CONFIG_OF_CONTROL */ - -void clock_early_init(void) -{ - tegra30_set_up_pllp(); -} - -void arch_timer_init(void) -{ -} - -#define PMC_SATA_PWRGT 0x1ac -#define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) -#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) - -#define PLLE_SS_CNTL 0x68 -#define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) -#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) -#define PLLE_SS_CNTL_SSCBYP (1 << 12) -#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) -#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) -#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) - -#define PLLE_BASE 0x0e8 -#define PLLE_BASE_ENABLE_CML (1 << 31) -#define PLLE_BASE_ENABLE (1 << 30) -#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) -#define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) -#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) -#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) - -#define PLLE_MISC 0x0ec -#define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) -#define PLLE_MISC_PLL_READY (1 << 15) -#define PLLE_MISC_LOCK (1 << 11) -#define PLLE_MISC_LOCK_ENABLE (1 << 9) -#define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) - -static int tegra_plle_train(void) -{ - unsigned int timeout = 2000; - unsigned long value; - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); - value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; - writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); - - do { - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if (value & PLLE_MISC_PLL_READY) - break; - - udelay(100); - } while (--timeout); - - if (timeout == 0) { - error("timeout waiting for PLLE to become ready"); - return -ETIMEDOUT; - } - - return 0; -} - -int tegra_plle_enable(void) -{ - unsigned int cpcon = 11, p = 18, n = 150, m = 1, timeout = 1000; - u32 value; - int err; - - /* disable PLLE clock */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value &= ~PLLE_BASE_ENABLE_CML; - value &= ~PLLE_BASE_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - /* clear lock enable and setup field */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value &= ~PLLE_MISC_LOCK_ENABLE; - value &= ~PLLE_MISC_SETUP_BASE(0xffff); - value &= ~PLLE_MISC_SETUP_EXT(0x3); - writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if ((value & PLLE_MISC_PLL_READY) == 0) { - err = tegra_plle_train(); - if (err < 0) { - error("failed to train PLLE: %d", err); - return err; - } - } - - /* configure PLLE */ - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - - value &= ~PLLE_BASE_PLDIV_CML(0x0f); - value |= PLLE_BASE_PLDIV_CML(cpcon); - - value &= ~PLLE_BASE_PLDIV(0x3f); - value |= PLLE_BASE_PLDIV(p); - - value &= ~PLLE_BASE_NDIV(0xff); - value |= PLLE_BASE_NDIV(n); - - value &= ~PLLE_BASE_MDIV(0xff); - value |= PLLE_BASE_MDIV(m); - - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - value |= PLLE_MISC_SETUP_BASE(0x7); - value |= PLLE_MISC_LOCK_ENABLE; - value |= PLLE_MISC_SETUP_EXT(0); - writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | - PLLE_SS_CNTL_BYPASS_SS; - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); - value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; - writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); - - do { - value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); - if (value & PLLE_MISC_LOCK) - break; - - udelay(2); - } while (--timeout); - - if (timeout == 0) { - error("timeout waiting for PLLE to lock"); - return -ETIMEDOUT; - } - - udelay(50); - - value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); - value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); - - value &= ~PLLE_SS_CNTL_SSCINC(0xff); - value |= PLLE_SS_CNTL_SSCINC(0x01); - - value &= ~PLLE_SS_CNTL_SSCBYP; - value &= ~PLLE_SS_CNTL_INTERP_RESET; - value &= ~PLLE_SS_CNTL_BYPASS_SS; - - value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); - value |= PLLE_SS_CNTL_SSCMAX(0x24); - writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); - - return 0; -} diff --git a/arch/arm/cpu/tegra30-common/funcmux.c b/arch/arm/cpu/tegra30-common/funcmux.c deleted file mode 100644 index 409335ce1d..0000000000 --- a/arch/arm/cpu/tegra30-common/funcmux.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tegra30 high-level function multiplexing */ - -#include -#include -#include -#include - -int funcmux_select(enum periph_id id, int config) -{ - int bad_config = config != FUNCMUX_DEFAULT; - - switch (id) { - case PERIPH_ID_UART1: - switch (config) { - case FUNCMUX_UART1_ULPI: - pinmux_set_func(PMUX_PINGRP_ULPI_DATA0_PO1, - PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_ULPI_DATA1_PO2, - PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_ULPI_DATA2_PO3, - PMUX_FUNC_UARTA); - pinmux_set_func(PMUX_PINGRP_ULPI_DATA3_PO4, - PMUX_FUNC_UARTA); - pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA0_PO1); - pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA1_PO2); - pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA2_PO3); - pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA3_PO4); - break; - } - break; - - /* Add other periph IDs here as needed */ - - default: - debug("%s: invalid periph_id %d", __func__, id); - return -1; - } - - if (bad_config) { - debug("%s: invalid config %d for periph_id %d", __func__, - config, id); - return -1; - } - return 0; -} diff --git a/arch/arm/cpu/tegra30-common/pinmux.c b/arch/arm/cpu/tegra30-common/pinmux.c deleted file mode 100644 index 7eb05743b4..0000000000 --- a/arch/arm/cpu/tegra30-common/pinmux.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define PIN(pin, f0, f1, f2, f3) \ - { \ - .funcs = { \ - PMUX_FUNC_##f0, \ - PMUX_FUNC_##f1, \ - PMUX_FUNC_##f2, \ - PMUX_FUNC_##f3, \ - }, \ - } - -#define PIN_RESERVED {} - -static const struct pmux_pingrp_desc tegra30_pingroups[] = { - /* pin, f0, f1, f2, f3 */ - /* Offset 0x3000 */ - PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), - PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), - PIN(ULPI_CLK_PY0, SPI1, RSVD2, UARTD, ULPI), - PIN(ULPI_DIR_PY1, SPI1, RSVD2, UARTD, ULPI), - PIN(ULPI_NXT_PY2, SPI1, RSVD2, UARTD, ULPI), - PIN(ULPI_STP_PY3, SPI1, RSVD2, UARTD, ULPI), - PIN(DAP3_FS_PP0, I2S2, RSVD2, DISPLAYA, DISPLAYB), - PIN(DAP3_DIN_PP1, I2S2, RSVD2, DISPLAYA, DISPLAYB), - PIN(DAP3_DOUT_PP2, I2S2, RSVD2, DISPLAYA, DISPLAYB), - PIN(DAP3_SCLK_PP3, I2S2, RSVD2, DISPLAYA, DISPLAYB), - PIN(PV0, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), - PIN(SDMMC1_CLK_PZ0, SDMMC1, RSVD2, RSVD3, UARTA), - PIN(SDMMC1_CMD_PZ1, SDMMC1, RSVD2, RSVD3, UARTA), - PIN(SDMMC1_DAT3_PY4, SDMMC1, RSVD2, UARTE, UARTA), - PIN(SDMMC1_DAT2_PY5, SDMMC1, RSVD2, UARTE, UARTA), - PIN(SDMMC1_DAT1_PY6, SDMMC1, RSVD2, UARTE, UARTA), - PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, UARTE, UARTA), - PIN(PV2, OWR, RSVD2, RSVD3, RSVD4), - PIN(PV3, CLK_12M_OUT, RSVD2, RSVD3, RSVD4), - PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), - PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), - PIN(LCD_PWR1_PC1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_PWR2_PC6, DISPLAYA, DISPLAYB, SPI5, HDCP), - PIN(LCD_SDIN_PZ2, DISPLAYA, DISPLAYB, SPI5, RSVD4), - PIN(LCD_SDOUT_PN5, DISPLAYA, DISPLAYB, SPI5, HDCP), - PIN(LCD_WR_N_PZ3, DISPLAYA, DISPLAYB, SPI5, HDCP), - PIN(LCD_CS0_N_PN4, DISPLAYA, DISPLAYB, SPI5, RSVD4), - PIN(LCD_DC0_PN6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_SCK_PZ4, DISPLAYA, DISPLAYB, SPI5, HDCP), - PIN(LCD_PWR0_PB2, DISPLAYA, DISPLAYB, SPI5, HDCP), - PIN(LCD_PCLK_PB3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_DE_PJ1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_HSYNC_PJ3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_VSYNC_PJ4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D0_PE0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D1_PE1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D2_PE2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D3_PE3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D4_PE4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D5_PE5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D6_PE6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D7_PE7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D8_PF0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D9_PF1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D10_PF2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D11_PF3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D12_PF4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D13_PF5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D14_PF6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D15_PF7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D16_PM0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D17_PM1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D18_PM2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D19_PM3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D20_PM4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D21_PM5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D22_PM6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_D23_PM7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_CS1_N_PW0, DISPLAYA, DISPLAYB, SPI5, RSVD4), - PIN(LCD_M1_PW1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(LCD_DC1_PD2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), - PIN(HDMI_INT_PN7, HDMI, RSVD2, RSVD3, RSVD4), - PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), - PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), - PIN(CRT_HSYNC_PV6, CRT, RSVD2, RSVD3, RSVD4), - PIN(CRT_VSYNC_PV7, CRT, RSVD2, RSVD3, RSVD4), - PIN(VI_D0_PT4, DDR, RSVD2, VI, RSVD4), - PIN(VI_D1_PD5, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D2_PL0, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D3_PL1, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D4_PL2, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D5_PL3, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D6_PL4, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D7_PL5, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D8_PL6, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D9_PL7, DDR, SDMMC2, VI, RSVD4), - PIN(VI_D10_PT2, DDR, RSVD2, VI, RSVD4), - PIN(VI_D11_PT3, DDR, RSVD2, VI, RSVD4), - PIN(VI_PCLK_PT0, RSVD1, SDMMC2, VI, RSVD4), - PIN(VI_MCLK_PT1, VI, VI_ALT1, VI_ALT2, VI_ALT3), - PIN(VI_VSYNC_PD6, DDR, RSVD2, VI, RSVD4), - PIN(VI_HSYNC_PD7, DDR, RSVD2, VI, RSVD4), - PIN(UART2_RXD_PC3, UARTB, SPDIF, UARTA, SPI4), - PIN(UART2_TXD_PC2, UARTB, SPDIF, UARTA, SPI4), - PIN(UART2_RTS_N_PJ6, UARTA, UARTB, GMI, SPI4), - PIN(UART2_CTS_N_PJ5, UARTA, UARTB, GMI, SPI4), - PIN(UART3_TXD_PW6, UARTC, RSVD2, GMI, RSVD4), - PIN(UART3_RXD_PW7, UARTC, RSVD2, GMI, RSVD4), - PIN(UART3_CTS_N_PA1, UARTC, RSVD2, GMI, RSVD4), - PIN(UART3_RTS_N_PC0, UARTC, PWM0, GMI, RSVD4), - PIN(PU0, OWR, UARTA, GMI, RSVD4), - PIN(PU1, RSVD1, UARTA, GMI, RSVD4), - PIN(PU2, RSVD1, UARTA, GMI, RSVD4), - PIN(PU3, PWM0, UARTA, GMI, RSVD4), - PIN(PU4, PWM1, UARTA, GMI, RSVD4), - PIN(PU5, PWM2, UARTA, GMI, RSVD4), - PIN(PU6, PWM3, UARTA, GMI, RSVD4), - PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), - PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), - PIN(DAP4_FS_PP4, I2S3, RSVD2, GMI, RSVD4), - PIN(DAP4_DIN_PP5, I2S3, RSVD2, GMI, RSVD4), - PIN(DAP4_DOUT_PP6, I2S3, RSVD2, GMI, RSVD4), - PIN(DAP4_SCLK_PP7, I2S3, RSVD2, GMI, RSVD4), - PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), - PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), - PIN(GMI_WP_N_PC7, RSVD1, NAND, GMI, GMI_ALT), - PIN(GMI_IORDY_PI5, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_WAIT_PI7, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_ADV_N_PK0, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_CLK_PK1, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_CS0_N_PJ0, RSVD1, NAND, GMI, DTV), - PIN(GMI_CS1_N_PJ2, RSVD1, NAND, GMI, DTV), - PIN(GMI_CS2_N_PK3, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_CS3_N_PK4, RSVD1, NAND, GMI, GMI_ALT), - PIN(GMI_CS4_N_PK2, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_CS6_N_PI3, NAND, NAND_ALT, GMI, SATA), - PIN(GMI_CS7_N_PI6, NAND, NAND_ALT, GMI, GMI_ALT), - PIN(GMI_AD0_PG0, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD1_PG1, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD2_PG2, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD3_PG3, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD4_PG4, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD5_PG5, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD6_PG6, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD7_PG7, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD8_PH0, PWM0, NAND, GMI, RSVD4), - PIN(GMI_AD9_PH1, PWM1, NAND, GMI, RSVD4), - PIN(GMI_AD10_PH2, PWM2, NAND, GMI, RSVD4), - PIN(GMI_AD11_PH3, PWM3, NAND, GMI, RSVD4), - PIN(GMI_AD12_PH4, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD13_PH5, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD14_PH6, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_AD15_PH7, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_A16_PJ7, UARTD, SPI4, GMI, GMI_ALT), - PIN(GMI_A17_PB0, UARTD, SPI4, GMI, DTV), - PIN(GMI_A18_PB1, UARTD, SPI4, GMI, DTV), - PIN(GMI_A19_PK7, UARTD, SPI4, GMI, RSVD4), - PIN(GMI_WR_N_PI0, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_OE_N_PI1, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_DQS_PI2, RSVD1, NAND, GMI, RSVD4), - PIN(GMI_RST_N_PI4, NAND, NAND_ALT, GMI, RSVD4), - PIN(GEN2_I2C_SCL_PT5, I2C2, HDCP, GMI, RSVD4), - PIN(GEN2_I2C_SDA_PT6, I2C2, HDCP, GMI, RSVD4), - PIN(SDMMC4_CLK_PCC4, INVALID, NAND, GMI, SDMMC4), - PIN(SDMMC4_CMD_PT7, I2C3, NAND, GMI, SDMMC4), - PIN(SDMMC4_DAT0_PAA0, UARTE, SPI3, GMI, SDMMC4), - PIN(SDMMC4_DAT1_PAA1, UARTE, SPI3, GMI, SDMMC4), - PIN(SDMMC4_DAT2_PAA2, UARTE, SPI3, GMI, SDMMC4), - PIN(SDMMC4_DAT3_PAA3, UARTE, SPI3, GMI, SDMMC4), - PIN(SDMMC4_DAT4_PAA4, I2C3, I2S4, GMI, SDMMC4), - PIN(SDMMC4_DAT5_PAA5, VGP3, I2S4, GMI, SDMMC4), - PIN(SDMMC4_DAT6_PAA6, VGP4, I2S4, GMI, SDMMC4), - PIN(SDMMC4_DAT7_PAA7, VGP5, I2S4, GMI, SDMMC4), - PIN(SDMMC4_RST_N_PCC3, VGP6, RSVD2, RSVD3, SDMMC4), - PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, SDMMC4), - PIN(PCC1, I2S4, RSVD2, RSVD3, SDMMC4), - PIN(PBB0, I2S4, RSVD2, RSVD3, SDMMC4), - PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, SDMMC4), - PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, SDMMC4), - PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, SDMMC4), - PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, SDMMC4), - PIN(PBB5, VGP5, DISPLAYA, DISPLAYB, SDMMC4), - PIN(PBB6, VGP6, DISPLAYA, DISPLAYB, SDMMC4), - PIN(PBB7, I2S4, RSVD2, RSVD3, SDMMC4), - PIN(PCC2, I2S4, RSVD2, RSVD3, RSVD4), - PIN(JTAG_RTCK_PU7, RTCK, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), - PIN(KB_ROW0_PR0, KBC, NAND, RSVD3, RSVD4), - PIN(KB_ROW1_PR1, KBC, NAND, RSVD3, RSVD4), - PIN(KB_ROW2_PR2, KBC, NAND, RSVD3, RSVD4), - PIN(KB_ROW3_PR3, KBC, NAND, RSVD3, INVALID), - PIN(KB_ROW4_PR4, KBC, NAND, TRACE, RSVD4), - PIN(KB_ROW5_PR5, KBC, NAND, TRACE, OWR), - PIN(KB_ROW6_PR6, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW7_PR7, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW8_PS0, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW9_PS1, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW10_PS2, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW11_PS3, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW12_PS4, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW13_PS5, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW14_PS6, KBC, NAND, SDMMC2, MIO), - PIN(KB_ROW15_PS7, KBC, NAND, SDMMC2, MIO), - PIN(KB_COL0_PQ0, KBC, NAND, TRACE, TEST), - PIN(KB_COL1_PQ1, KBC, NAND, TRACE, TEST), - PIN(KB_COL2_PQ2, KBC, NAND, TRACE, RSVD4), - PIN(KB_COL3_PQ3, KBC, NAND, TRACE, RSVD4), - PIN(KB_COL4_PQ4, KBC, NAND, TRACE, RSVD4), - PIN(KB_COL5_PQ5, KBC, NAND, TRACE, RSVD4), - PIN(KB_COL6_PQ6, KBC, NAND, TRACE, MIO), - PIN(KB_COL7_PQ7, KBC, NAND, TRACE, MIO), - PIN(CLK_32K_OUT_PA0, BLINK, RSVD2, RSVD3, RSVD4), - PIN(SYS_CLK_REQ_PZ5, SYSCLK, RSVD2, RSVD3, RSVD4), - PIN(CORE_PWR_REQ, CORE_PWR_REQ, RSVD2, RSVD3, RSVD4), - PIN(CPU_PWR_REQ, CPU_PWR_REQ, RSVD2, RSVD3, RSVD4), - PIN(PWR_INT_N, PWR_INT_N, RSVD2, RSVD3, RSVD4), - PIN(CLK_32K_IN, CLK_32K_IN, RSVD2, RSVD3, RSVD4), - PIN(OWR, OWR, CEC, RSVD3, RSVD4), - PIN(DAP1_FS_PN0, I2S0, HDA, GMI, SDMMC2), - PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, SDMMC2), - PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, SDMMC2), - PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, SDMMC2), - PIN(CLK1_REQ_PEE2, DAP, HDA, RSVD3, RSVD4), - PIN(CLK1_OUT_PW4, EXTPERIPH1, RSVD2, RSVD3, RSVD4), - PIN(SPDIF_IN_PK6, SPDIF, HDA, I2C1, SDMMC2), - PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, I2C1, SDMMC2), - PIN(DAP2_FS_PA2, I2S1, HDA, RSVD3, GMI), - PIN(DAP2_DIN_PA4, I2S1, HDA, RSVD3, GMI), - PIN(DAP2_DOUT_PA5, I2S1, HDA, RSVD3, GMI), - PIN(DAP2_SCLK_PA3, I2S1, HDA, RSVD3, GMI), - PIN(SPI2_MOSI_PX0, SPI6, SPI2, SPI3, GMI), - PIN(SPI2_MISO_PX1, SPI6, SPI2, SPI3, GMI), - PIN(SPI2_CS0_N_PX3, SPI6, SPI2, SPI3, GMI), - PIN(SPI2_SCK_PX2, SPI6, SPI2, SPI3, GMI), - PIN(SPI1_MOSI_PX4, SPI2, SPI1, SPI2_ALT, GMI), - PIN(SPI1_SCK_PX5, SPI2, SPI1, SPI2_ALT, GMI), - PIN(SPI1_CS0_N_PX6, SPI2, SPI1, SPI2_ALT, GMI), - PIN(SPI1_MISO_PX7, SPI3, SPI1, SPI2_ALT, RSVD4), - PIN(SPI2_CS1_N_PW2, SPI3, SPI2, SPI2_ALT, I2C1), - PIN(SPI2_CS2_N_PW3, SPI3, SPI2, SPI2_ALT, I2C1), - PIN(SDMMC3_CLK_PA6, UARTA, PWM2, SDMMC3, SPI3), - PIN(SDMMC3_CMD_PA7, UARTA, PWM3, SDMMC3, SPI2), - PIN(SDMMC3_DAT0_PB7, RSVD1, RSVD2, SDMMC3, SPI3), - PIN(SDMMC3_DAT1_PB6, RSVD1, RSVD2, SDMMC3, SPI3), - PIN(SDMMC3_DAT2_PB5, RSVD1, PWM1, SDMMC3, SPI3), - PIN(SDMMC3_DAT3_PB4, RSVD1, PWM0, SDMMC3, SPI3), - PIN(SDMMC3_DAT4_PD1, PWM1, SPI4, SDMMC3, SPI2), - PIN(SDMMC3_DAT5_PD0, PWM0, SPI4, SDMMC3, SPI2), - PIN(SDMMC3_DAT6_PD3, SPDIF, SPI4, SDMMC3, SPI2), - PIN(SDMMC3_DAT7_PD4, SPDIF, SPI4, SDMMC3, SPI2), - PIN(PEX_L0_PRSNT_N_PDD0, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L0_RST_N_PDD1, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L0_CLKREQ_N_PDD2, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_WAKE_N_PDD3, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L1_PRSNT_N_PDD4, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L1_RST_N_PDD5, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L1_CLKREQ_N_PDD6, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L2_PRSNT_N_PDD7, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L2_RST_N_PCC6, PCIE, HDA, RSVD3, RSVD4), - PIN(PEX_L2_CLKREQ_N_PCC7, PCIE, HDA, RSVD3, RSVD4), - PIN(HDMI_CEC_PEE3, CEC, RSVD2, RSVD3, RSVD4), -}; -const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra30_pingroups; diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig new file mode 100644 index 0000000000..3a8e2b19d6 --- /dev/null +++ b/arch/arm/mach-tegra/Kconfig @@ -0,0 +1,52 @@ +if TEGRA + +choice + prompt "Tegra SoC select" + +config TEGRA20 + bool "Tegra20 family" + +config TEGRA30 + bool "Tegra30 family" + +config TEGRA114 + bool "Tegra114 family" + +config TEGRA124 + bool "Tegra124 family" + +endchoice + +config SYS_MALLOC_F + default y + +config SYS_MALLOC_F_LEN + default 0x1800 + +config USE_PRIVATE_LIBGCC + default y if SPL_BUILD + +config DM + default y if !SPL_BUILD + +config DM_SERIAL + default y if !SPL_BUILD + +config DM_SPI + default y if !SPL_BUILD + +config DM_SPI_FLASH + default y if !SPL_BUILD + +config DM_I2C + default y if !SPL_BUILD + +config DM_GPIO + default y if !SPL_BUILD + +source "arch/arm/mach-tegra/tegra20/Kconfig" +source "arch/arm/mach-tegra/tegra30/Kconfig" +source "arch/arm/mach-tegra/tegra114/Kconfig" +source "arch/arm/mach-tegra/tegra124/Kconfig" + +endif diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile new file mode 100644 index 0000000000..04cef0a252 --- /dev/null +++ b/arch/arm/mach-tegra/Makefile @@ -0,0 +1,31 @@ +# +# (C) Copyright 2010,2011 Nvidia Corporation. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-y += cpu.o +else +obj-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o +endif + +obj-y += ap.o +obj-y += board.o +obj-y += cache.o +obj-y += clock.o +obj-y += lowlevel_init.o +obj-y += pinmux-common.o +obj-y += powergate.o +obj-y += xusb-padctl.o +obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o +obj-$(CONFIG_TEGRA124) += vpr.o + +obj-$(CONFIG_TEGRA20) += tegra20/ +obj-$(CONFIG_TEGRA30) += tegra30/ +obj-$(CONFIG_TEGRA114) += tegra114/ +obj-$(CONFIG_TEGRA124) += tegra124/ diff --git a/arch/arm/mach-tegra/ap.c b/arch/arm/mach-tegra/ap.c new file mode 100644 index 0000000000..a17dfd1e22 --- /dev/null +++ b/arch/arm/mach-tegra/ap.c @@ -0,0 +1,169 @@ +/* +* (C) Copyright 2010-2014 +* NVIDIA Corporation +* + * SPDX-License-Identifier: GPL-2.0+ +*/ + +/* Tegra AP (Application Processor) code */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int tegra_get_chip(void) +{ + int rev; + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + + /* + * This is undocumented, Chip ID is bits 15:8 of the register + * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for + * Tegra30, 0x35 for T114, and 0x40 for Tegra124. + */ + rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; + debug("%s: CHIPID is 0x%02X\n", __func__, rev); + + return rev; +} + +int tegra_get_sku_info(void) +{ + int sku_id; + struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; + + sku_id = readl(&fuse->sku_info) & 0xff; + debug("%s: SKU info byte is 0x%02X\n", __func__, sku_id); + + return sku_id; +} + +int tegra_get_chip_sku(void) +{ + uint sku_id, chip_id; + + chip_id = tegra_get_chip(); + sku_id = tegra_get_sku_info(); + + switch (chip_id) { + case CHIPID_TEGRA20: + switch (sku_id) { + case SKU_ID_T20_7: + case SKU_ID_T20: + return TEGRA_SOC_T20; + case SKU_ID_T25SE: + case SKU_ID_AP25: + case SKU_ID_T25: + case SKU_ID_AP25E: + case SKU_ID_T25E: + return TEGRA_SOC_T25; + } + break; + case CHIPID_TEGRA30: + switch (sku_id) { + case SKU_ID_T33: + case SKU_ID_T30: + case SKU_ID_TM30MQS_P_A3: + default: + return TEGRA_SOC_T30; + } + break; + case CHIPID_TEGRA114: + switch (sku_id) { + case SKU_ID_T114_ENG: + case SKU_ID_T114_1: + default: + return TEGRA_SOC_T114; + } + break; + case CHIPID_TEGRA124: + switch (sku_id) { + case SKU_ID_T124_ENG: + default: + return TEGRA_SOC_T124; + } + break; + } + + /* unknown chip/sku id */ + printf("%s: ERROR: UNKNOWN CHIP/SKU ID COMBO (0x%02X/0x%02X)\n", + __func__, chip_id, sku_id); + return TEGRA_SOC_UNKNOWN; +} + +static void enable_scu(void) +{ + struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; + u32 reg; + + /* Only enable the SCU on T20/T25 */ + if (tegra_get_chip() != CHIPID_TEGRA20) + return; + + /* If SCU already setup/enabled, return */ + if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) + return; + + /* Invalidate all ways for all processors */ + writel(0xFFFF, &scu->scu_inv_all); + + /* Enable SCU - bit 0 */ + reg = readl(&scu->scu_ctrl); + reg |= SCU_CTRL_ENABLE; + writel(reg, &scu->scu_ctrl); +} + +static u32 get_odmdata(void) +{ + /* + * ODMDATA is stored in the BCT in IRAM by the BootROM. + * The BCT start and size are stored in the BIT in IRAM. + * Read the data @ bct_start + (bct_size - 12). This works + * on BCTs for currently supported SoCs, which are locked down. + * If this changes in new chips, we can revisit this algorithm. + */ + + u32 bct_start, odmdata; + + bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); + odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); + + return odmdata; +} + +static void init_pmc_scratch(void) +{ + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 odmdata; + int i; + + /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ + for (i = 0; i < 23; i++) + writel(0, &pmc->pmc_scratch1+i); + + /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ + odmdata = get_odmdata(); + writel(odmdata, &pmc->pmc_scratch20); +} + +void s_init(void) +{ + /* Init PMC scratch memory */ + init_pmc_scratch(); + + enable_scu(); + + /* init the cache */ + config_cache(); + + /* init vpr */ + config_vpr(); +} diff --git a/arch/arm/mach-tegra/board.c b/arch/arm/mach-tegra/board.c new file mode 100644 index 0000000000..b6a84a5774 --- /dev/null +++ b/arch/arm/mach-tegra/board.c @@ -0,0 +1,159 @@ +/* + * (C) Copyright 2010-2014 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +enum { + /* UARTs which we can enable */ + UARTA = 1 << 0, + UARTB = 1 << 1, + UARTC = 1 << 2, + UARTD = 1 << 3, + UARTE = 1 << 4, + UART_COUNT = 5, +}; + +/* Read the RAM size directly from the memory controller */ +unsigned int query_sdram_size(void) +{ + struct mc_ctlr *const mc = (struct mc_ctlr *)NV_PA_MC_BASE; + u32 size_mb; + + size_mb = readl(&mc->mc_emem_cfg); +#if defined(CONFIG_TEGRA20) + debug("mc->mc_emem_cfg (MEM_SIZE_KB) = 0x%08x\n", size_mb); + size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024); +#else + debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", size_mb); + size_mb = get_ram_size((void *)PHYS_SDRAM_1, size_mb * 1024 * 1024); +#endif + +#if defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) + /* External memory limited to 2047 MB due to IROM/HI-VEC */ + if (size_mb == SZ_2G) size_mb -= SZ_1M; +#endif + + return size_mb; +} + +int dram_init(void) +{ + /* We do not initialise DRAM here. We just query the size */ + gd->ram_size = query_sdram_size(); + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("Board: %s\n", sysinfo.board_string); + return 0; +} +#endif /* CONFIG_DISPLAY_BOARDINFO */ + +static int uart_configs[] = { +#if defined(CONFIG_TEGRA20) + #if defined(CONFIG_TEGRA_UARTA_UAA_UAB) + FUNCMUX_UART1_UAA_UAB, + #elif defined(CONFIG_TEGRA_UARTA_GPU) + FUNCMUX_UART1_GPU, + #elif defined(CONFIG_TEGRA_UARTA_SDIO1) + FUNCMUX_UART1_SDIO1, + #else + FUNCMUX_UART1_IRRX_IRTX, +#endif + FUNCMUX_UART2_UAD, + -1, + FUNCMUX_UART4_GMC, + -1, +#elif defined(CONFIG_TEGRA30) + FUNCMUX_UART1_ULPI, /* UARTA */ + -1, + -1, + -1, + -1, +#elif defined(CONFIG_TEGRA114) + -1, + -1, + -1, + FUNCMUX_UART4_GMI, /* UARTD */ + -1, +#else /* Tegra124 */ + FUNCMUX_UART1_KBC, /* UARTA */ + -1, + -1, + FUNCMUX_UART4_GPIO, /* UARTD */ + -1, +#endif +}; + +/** + * Set up the specified uarts + * + * @param uarts_ids Mask containing UARTs to init (UARTx) + */ +static void setup_uarts(int uart_ids) +{ + static enum periph_id id_for_uart[] = { + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_UART4, + PERIPH_ID_UART5, + }; + size_t i; + + for (i = 0; i < UART_COUNT; i++) { + if (uart_ids & (1 << i)) { + enum periph_id id = id_for_uart[i]; + + funcmux_select(id, uart_configs[i]); + clock_ll_start_uart(id); + } + } +} + +void board_init_uart_f(void) +{ + int uart_ids = 0; /* bit mask of which UART ids to enable */ + +#ifdef CONFIG_TEGRA_ENABLE_UARTA + uart_ids |= UARTA; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTB + uart_ids |= UARTB; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTC + uart_ids |= UARTC; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTD + uart_ids |= UARTD; +#endif +#ifdef CONFIG_TEGRA_ENABLE_UARTE + uart_ids |= UARTE; +#endif + setup_uarts(uart_ids); +} + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif diff --git a/arch/arm/mach-tegra/cache.c b/arch/arm/mach-tegra/cache.c new file mode 100644 index 0000000000..94f5bce90e --- /dev/null +++ b/arch/arm/mach-tegra/cache.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra cache routines */ + +#include +#include +#include +#include + +void config_cache(void) +{ + u32 reg = 0; + + /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */ + asm volatile( + "mrc p15, 0, r0, c1, c0, 1\n" + "orr r0, r0, #0x41\n" + "mcr p15, 0, r0, c1, c0, 1\n"); + + /* Currently, only Tegra114+ needs this L2 cache change to boot Linux */ + if (tegra_get_chip() < CHIPID_TEGRA114) + return; + + /* + * Systems with an architectural L2 cache must not use the PL310. + * Config L2CTLR here for a data RAM latency of 3 cycles. + */ + asm("mrc p15, 1, %0, c9, c0, 2" : : "r" (reg)); + reg &= ~7; + reg |= 2; + asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg)); +} diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c new file mode 100644 index 0000000000..11c7435505 --- /dev/null +++ b/arch/arm/mach-tegra/clock.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra SoC common clock control functions */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This is our record of the current clock rate of each clock. We don't + * fill all of these in since we are only really interested in clocks which + * we use as parents. + */ +static unsigned pll_rate[CLOCK_ID_COUNT]; + +/* + * The oscillator frequency is fixed to one of four set values. Based on this + * the other clocks are set up appropriately. + */ +static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { + 13000000, + 19200000, + 12000000, + 26000000, +}; + +/* return 1 if a peripheral ID is in range */ +#define clock_type_id_isvalid(id) ((id) >= 0 && \ + (id) < CLOCK_TYPE_COUNT) + +char pllp_valid = 1; /* PLLP is set up correctly */ + +/* return 1 if a periphc_internal_id is in range */ +#define periphc_internal_id_isvalid(id) ((id) >= 0 && \ + (id) < PERIPHC_COUNT) + +/* number of clock outputs of a PLL */ +static const u8 pll_num_clkouts[] = { + 1, /* PLLC */ + 1, /* PLLM */ + 4, /* PLLP */ + 1, /* PLLA */ + 0, /* PLLU */ + 0, /* PLLD */ +}; + +int clock_get_osc_bypass(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT; +} + +/* Returns a pointer to the registers of the given pll */ +static struct clk_pll *get_pll(enum clock_id clkid) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + assert(clock_id_is_pll(clkid)); + return &clkrst->crc_pll[clkid]; +} + +int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn, + u32 *divp, u32 *cpcon, u32 *lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + assert(clkid != CLOCK_ID_USB); + + /* Safety check, adds to code size but is small */ + if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB) + return -1; + data = readl(&pll->pll_base); + *divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + *divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT; + *divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + data = readl(&pll->pll_misc); + *cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT; + *lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT; + + return 0; +} + +unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon) +{ + struct clk_pll *pll = get_pll(clkid); + u32 data; + + /* + * We cheat by treating all PLL (except PLLU) in the same fashion. + * This works only because: + * - same fields are always mapped at same offsets, except DCCON + * - DCCON is always 0, doesn't conflict + * - M,N, P of PLLP values are ignored for PLLP + */ + data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT); + writel(data, &pll->pll_misc); + + data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) | + (0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT); + + if (clkid == CLOCK_ID_USB) + data |= divp << PLLU_VCO_FREQ_SHIFT; + else + data |= divp << PLL_DIVP_SHIFT; + writel(data, &pll->pll_base); + + /* calculate the stable time */ + return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US; +} + +void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, + unsigned divisor) +{ + u32 *reg = get_periph_source_reg(periph_id); + u32 value; + + value = readl(reg); + + value &= ~OUT_CLK_SOURCE_31_30_MASK; + value |= source << OUT_CLK_SOURCE_31_30_SHIFT; + + value &= ~OUT_CLK_DIVISOR_MASK; + value |= divisor << OUT_CLK_DIVISOR_SHIFT; + + writel(value, reg); +} + +void clock_ll_set_source(enum periph_id periph_id, unsigned source) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_SOURCE_31_30_MASK, + source << OUT_CLK_SOURCE_31_30_SHIFT); +} + +/** + * Given the parent's rate and the required rate for the children, this works + * out the peripheral clock divider to use, in 7.1 binary format. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @return divider which should be used + */ +static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate) +{ + u64 divider = parent_rate * 2; + unsigned max_divider = 1 << divider_bits; + + divider += rate - 1; + do_div(divider, rate); + + if ((s64)divider - 2 < 0) + return 0; + + if ((s64)divider - 2 >= max_divider) + return -1; + + return divider - 2; +} + +int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate) +{ + struct clk_pll *pll = get_pll(clkid); + int data = 0, div = 0, offset = 0; + + if (!clock_id_is_pll(clkid)) + return -1; + + if (pllout + 1 > pll_num_clkouts[clkid]) + return -1; + + div = clk_get_divider(8, pll_rate[clkid], rate); + + if (div < 0) + return -1; + + /* out2 and out4 are in the high part of the register */ + if (pllout == PLL_OUT2 || pllout == PLL_OUT4) + offset = 16; + + data = (div << PLL_OUT_RATIO_SHIFT) | + PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN; + clrsetbits_le32(&pll->pll_out[pllout >> 1], + PLL_OUT_RATIO_MASK << offset, data << offset); + + return 0; +} + +/** + * Given the parent's rate and the divider in 7.1 format, this works out the + * resulting peripheral clock rate. + * + * @param parent_rate clock rate of parent clock in Hz + * @param divider which should be used in 7.1 format + * @return effective clock rate of peripheral + */ +static unsigned long get_rate_from_divider(unsigned long parent_rate, + int divider) +{ + u64 rate; + + rate = (u64)parent_rate * 2; + do_div(rate, divider + 2); + return rate; +} + +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent) +{ + u32 *reg = get_periph_source_reg(periph_id); + + return get_rate_from_divider(pll_rate[parent], + (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT); +} + +/** + * Find the best available 7.1 format divisor given a parent clock rate and + * required child clock rate. This function assumes that a second-stage + * divisor is available which can divide by powers of 2 from 1 to 256. + * + * @param divider_bits number of divider bits (8 or 16) + * @param parent_rate clock rate of parent clock in Hz + * @param rate required clock rate for this clock + * @param extra_div value for the second-stage divisor (not set if this + * function returns -1. + * @return divider which should be used, or -1 if nothing is valid + * + */ +static int find_best_divider(unsigned divider_bits, unsigned long parent_rate, + unsigned long rate, int *extra_div) +{ + int shift; + int best_divider = -1; + int best_error = rate; + + /* try dividers from 1 to 256 and find closest match */ + for (shift = 0; shift <= 8 && best_error > 0; shift++) { + unsigned divided_parent = parent_rate >> shift; + int divider = clk_get_divider(divider_bits, divided_parent, + rate); + unsigned effective_rate = get_rate_from_divider(divided_parent, + divider); + int error = rate - effective_rate; + + /* Given a valid divider, look for the lowest error */ + if (divider != -1 && error < best_error) { + best_error = error; + *extra_div = 1 << shift; + best_divider = divider; + } + } + + /* return what we found - *extra_div will already be set */ + return best_divider; +} + +/** + * Adjust peripheral PLL to use the given divider and source. + * + * @param periph_id peripheral to adjust + * @param source Source number (0-3 or 0-7) + * @param mux_bits Number of mux bits (2 or 4) + * @param divider Required divider in 7.1 or 15.1 format + * @return 0 if ok, -1 on error (requesting a parent clock which is not valid + * for this peripheral) + */ +static int adjust_periph_pll(enum periph_id periph_id, int source, + int mux_bits, unsigned divider) +{ + u32 *reg = get_periph_source_reg(periph_id); + + clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK, + divider << OUT_CLK_DIVISOR_SHIFT); + udelay(1); + + /* work out the source clock and set it */ + if (source < 0) + return -1; + + switch (mux_bits) { + case MASK_BITS_31_30: + clrsetbits_le32(reg, OUT_CLK_SOURCE_31_30_MASK, + source << OUT_CLK_SOURCE_31_30_SHIFT); + break; + + case MASK_BITS_31_29: + clrsetbits_le32(reg, OUT_CLK_SOURCE_31_29_MASK, + source << OUT_CLK_SOURCE_31_29_SHIFT); + break; + + case MASK_BITS_31_28: + clrsetbits_le32(reg, OUT_CLK_SOURCE_31_28_MASK, + source << OUT_CLK_SOURCE_31_28_SHIFT); + break; + + default: + return -1; + } + + udelay(2); + return 0; +} + +unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, + enum clock_id parent, unsigned rate, int *extra_div) +{ + unsigned effective_rate; + int mux_bits, divider_bits, source; + int divider; + int xdiv = 0; + + /* work out the source clock and set it */ + source = get_periph_clock_source(periph_id, parent, &mux_bits, + ÷r_bits); + + divider = find_best_divider(divider_bits, pll_rate[parent], + rate, &xdiv); + if (extra_div) + *extra_div = xdiv; + + assert(divider >= 0); + if (adjust_periph_pll(periph_id, source, mux_bits, divider)) + return -1U; + debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate, + get_periph_source_reg(periph_id), + readl(get_periph_source_reg(periph_id))); + + /* Check what we ended up with. This shouldn't matter though */ + effective_rate = clock_get_periph_rate(periph_id, parent); + if (extra_div) + effective_rate /= *extra_div; + if (rate != effective_rate) + debug("Requested clock rate %u not honored (got %u)\n", + rate, effective_rate); + return effective_rate; +} + +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate) +{ + unsigned effective_rate; + + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + + effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate, + NULL); + + reset_set_enable(periph_id, 0); + return effective_rate; +} + +void clock_enable(enum periph_id clkid) +{ + clock_set_enable(clkid, 1); +} + +void clock_disable(enum periph_id clkid) +{ + clock_set_enable(clkid, 0); +} + +void reset_periph(enum periph_id periph_id, int us_delay) +{ + /* Put peripheral into reset */ + reset_set_enable(periph_id, 1); + udelay(us_delay); + + /* Remove reset */ + reset_set_enable(periph_id, 0); + + udelay(us_delay); +} + +void reset_cmplx_set_enable(int cpu, int which, int reset) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 mask; + + /* Form the mask, which depends on the cpu chosen (2 or 4) */ + assert(cpu >= 0 && cpu < MAX_NUM_CPU); + mask = which << cpu; + + /* either enable or disable those reset for that CPU */ + if (reset) + writel(mask, &clkrst->crc_cpu_cmplx_set); + else + writel(mask, &clkrst->crc_cpu_cmplx_clr); +} + +unsigned clock_get_rate(enum clock_id clkid) +{ + struct clk_pll *pll; + u32 base; + u32 divm; + u64 parent_rate; + u64 rate; + + parent_rate = osc_freq[clock_get_osc_freq()]; + if (clkid == CLOCK_ID_OSC) + return parent_rate; + + pll = get_pll(clkid); + base = readl(&pll->pll_base); + + /* Oh for bf_unpack()... */ + rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT); + divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT; + if (clkid == CLOCK_ID_USB) + divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT; + else + divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT; + do_div(rate, divm); + return rate; +} + +/** + * Set the output frequency you want for each PLL clock. + * PLL output frequencies are programmed by setting their N, M and P values. + * The governing equations are: + * VCO = (Fi / m) * n, Fo = VCO / (2^p) + * where Fo is the output frequency from the PLL. + * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi) + * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1 + * Please see Tegra TRM section 5.3 to get the detail for PLL Programming + * + * @param n PLL feedback divider(DIVN) + * @param m PLL input divider(DIVN) + * @param p post divider(DIVP) + * @param cpcon base PLL charge pump(CPCON) + * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot + * be overriden), 1 if PLL is already correct + */ +int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) +{ + u32 base_reg; + u32 misc_reg; + struct clk_pll *pll; + + pll = get_pll(clkid); + + base_reg = readl(&pll->pll_base); + + /* Set BYPASS, m, n and p to PLL_BASE */ + base_reg &= ~PLL_DIVM_MASK; + base_reg |= m << PLL_DIVM_SHIFT; + + base_reg &= ~PLL_DIVN_MASK; + base_reg |= n << PLL_DIVN_SHIFT; + + base_reg &= ~PLL_DIVP_MASK; + base_reg |= p << PLL_DIVP_SHIFT; + + if (clkid == CLOCK_ID_PERIPH) { + /* + * If the PLL is already set up, check that it is correct + * and record this info for clock_verify() to check. + */ + if (base_reg & PLL_BASE_OVRRIDE_MASK) { + base_reg |= PLL_ENABLE_MASK; + if (base_reg != readl(&pll->pll_base)) + pllp_valid = 0; + return pllp_valid ? 1 : -1; + } + base_reg |= PLL_BASE_OVRRIDE_MASK; + } + + base_reg |= PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + /* Set cpcon to PLL_MISC */ + misc_reg = readl(&pll->pll_misc); + misc_reg &= ~PLL_CPCON_MASK; + misc_reg |= cpcon << PLL_CPCON_SHIFT; + writel(misc_reg, &pll->pll_misc); + + /* Enable PLL */ + base_reg |= PLL_ENABLE_MASK; + writel(base_reg, &pll->pll_base); + + /* Disable BYPASS */ + base_reg &= ~PLL_BYPASS_MASK; + writel(base_reg, &pll->pll_base); + + return 0; +} + +void clock_ll_start_uart(enum periph_id periph_id) +{ + /* Assert UART reset and enable clock */ + reset_set_enable(periph_id, 1); + clock_enable(periph_id); + clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */ + + /* wait for 2us */ + udelay(2); + + /* De-assert reset to UART */ + reset_set_enable(periph_id, 0); +} + +#ifdef CONFIG_OF_CONTROL +int clock_decode_periph_id(const void *blob, int node) +{ + enum periph_id id; + u32 cell[2]; + int err; + + err = fdtdec_get_int_array(blob, node, "clocks", cell, + ARRAY_SIZE(cell)); + if (err) + return -1; + id = clk_id_to_periph_id(cell[1]); + assert(clock_periph_id_isvalid(id)); + return id; +} +#endif /* CONFIG_OF_CONTROL */ + +int clock_verify(void) +{ + struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH); + u32 reg = readl(&pll->pll_base); + + if (!pllp_valid) { + printf("Warning: PLLP %x is not correct\n", reg); + return -1; + } + debug("PLLP %x is correct\n", reg); + return 0; +} + +void clock_init(void) +{ + pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY); + pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH); + pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL); + pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC); + pll_rate[CLOCK_ID_SFROM32KHZ] = 32768; + pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU); + debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]); + debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]); + debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]); + debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]); + debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]); + + /* Do any special system timer/TSC setup */ + arch_timer_init(); +} + +static void set_avp_clock_source(u32 src) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 val; + + val = (src << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | + (src << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | + (src << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | + (src << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | + (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); + writel(val, &clkrst->crc_sclk_brst_pol); + udelay(3); +} + +/* + * This function is useful on Tegra30, and any later SoCs that have compatible + * PLLP configuration registers. + */ +void tegra30_set_up_pllp(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + /* + * Based on the Tegra TRM, the system clock (which is the AVP clock) can + * run up to 275MHz. On power on, the default sytem clock source is set + * to PLLP_OUT0. This function sets PLLP's (hence PLLP_OUT0's) rate to + * 408MHz which is beyond system clock's upper limit. + * + * The fix is to set the system clock to CLK_M before initializing PLLP, + * and then switch back to PLLP_OUT4, which has an appropriate divider + * configured, after PLLP has been configured + */ + set_avp_clock_source(SCLK_SOURCE_CLKM); + + /* + * PLLP output frequency set to 408Mhz + * PLLC output frequency set to 228Mhz + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } + + /* Set PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ + + /* OUT1, 2 */ + /* Assert RSTN before enable */ + reg = PLLP_OUT2_RSTN_EN | PLLP_OUT1_RSTN_EN; + writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); + /* Set divisor and reenable */ + reg = (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) + | PLLP_OUT2_OVR | PLLP_OUT2_CLKEN | PLLP_OUT2_RSTN_DIS + | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) + | PLLP_OUT1_OVR | PLLP_OUT1_CLKEN | PLLP_OUT1_RSTN_DIS; + writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]); + + /* OUT3, 4 */ + /* Assert RSTN before enable */ + reg = PLLP_OUT4_RSTN_EN | PLLP_OUT3_RSTN_EN; + writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); + /* Set divisor and reenable */ + reg = (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) + | PLLP_OUT4_OVR | PLLP_OUT4_CLKEN | PLLP_OUT4_RSTN_DIS + | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) + | PLLP_OUT3_OVR | PLLP_OUT3_CLKEN | PLLP_OUT3_RSTN_DIS; + writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]); + + set_avp_clock_source(SCLK_SOURCE_PLLP_OUT4); +} diff --git a/arch/arm/mach-tegra/cmd_enterrcm.c b/arch/arm/mach-tegra/cmd_enterrcm.c new file mode 100644 index 0000000000..a94ec93e7b --- /dev/null +++ b/arch/arm/mach-tegra/cmd_enterrcm.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * Derived from code (arch/arm/lib/reset.c) that is: + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * (C) Copyright 2004 Texas Insturments + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +static int do_enterrcm(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + puts("Entering RCM...\n"); + udelay(50000); + + pmc->pmc_scratch0 = 2; + disable_interrupts(); + reset_cpu(0); + + return 0; +} + +U_BOOT_CMD( + enterrcm, 1, 0, do_enterrcm, + "reset Tegra and enter USB Recovery Mode", + "" +); diff --git a/arch/arm/mach-tegra/cpu.c b/arch/arm/mach-tegra/cpu.c new file mode 100644 index 0000000000..c6f3b029a1 --- /dev/null +++ b/arch/arm/mach-tegra/cpu.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cpu.h" + +int get_num_cpus(void) +{ + struct apb_misc_gp_ctlr *gp; + uint rev; + + gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; + + switch (rev) { + case CHIPID_TEGRA20: + return 2; + break; + case CHIPID_TEGRA30: + case CHIPID_TEGRA114: + default: + return 4; + break; + } +} + +/* + * Timing tables for each SOC for all four oscillator options. + */ +struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { + /* + * T20: 1 GHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 22:20 3 + * PLLX_BASE n 17: 8 10 + * PLLX_BASE m 4: 0 5 + * PLLX_MISC cpcon 11: 8 4 + */ + { + { .n = 1000, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ + { .n = 625, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 1000, .m = 12, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ + { .n = 1000, .m = 26, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ + }, + /* + * T25: 1.2 GHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 22:20 3 + * PLLX_BASE n 17: 8 10 + * PLLX_BASE m 4: 0 5 + * PLLX_MISC cpcon 11: 8 4 + */ + { + { .n = 923, .m = 10, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ + { .n = 750, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 600, .m = 6, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ + { .n = 600, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ + }, + /* + * T30: 600 MHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 22:20 3 + * PLLX_BASE n 17: 8 10 + * PLLX_BASE m 4: 0 5 + * PLLX_MISC cpcon 11: 8 4 + */ + { + { .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 13.0 MHz */ + { .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 12.0 MHz */ + { .n = 600, .m = 26, .p = 0, .cpcon = 8 }, /* OSC: 26.0 MHz */ + }, + /* + * T114: 700 MHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 23:20 4 + * PLLX_BASE n 15: 8 8 + * PLLX_BASE m 7: 0 8 + */ + { + { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ + { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ + }, + + /* + * T124: 700 MHz + * + * Register Field Bits Width + * ------------------------------ + * PLLX_BASE p 23:20 4 + * PLLX_BASE n 15: 8 8 + * PLLX_BASE m 7: 0 8 + */ + { + { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ + { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ + }, +}; + +static inline void pllx_set_iddq(void) +{ +#if defined(CONFIG_TEGRA124) + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + /* Disable IDDQ */ + reg = readl(&clkrst->crc_pllx_misc3); + reg &= ~PLLX_IDDQ_MASK; + writel(reg, &clkrst->crc_pllx_misc3); + udelay(2); + debug("%s: IDDQ: PLLX IDDQ = 0x%08X\n", __func__, + readl(&clkrst->crc_pllx_misc3)); +#endif +} + +int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm, + u32 divp, u32 cpcon) +{ + int chip = tegra_get_chip(); + u32 reg; + + /* If PLLX is already enabled, just return */ + if (readl(&pll->pll_base) & PLL_ENABLE_MASK) { + debug("pllx_set_rate: PLLX already enabled, returning\n"); + return 0; + } + + debug(" pllx_set_rate entry\n"); + + pllx_set_iddq(); + + /* Set BYPASS, m, n and p to PLLX_BASE */ + reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT); + reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT)); + writel(reg, &pll->pll_base); + + /* Set cpcon to PLLX_MISC */ + if (chip == CHIPID_TEGRA20 || chip == CHIPID_TEGRA30) + reg = (cpcon << PLL_CPCON_SHIFT); + else + reg = 0; + + /* Set dccon to PLLX_MISC if freq > 600MHz */ + if (divn > 600) + reg |= (1 << PLL_DCCON_SHIFT); + writel(reg, &pll->pll_misc); + + /* Disable BYPASS */ + reg = readl(&pll->pll_base); + reg &= ~PLL_BYPASS_MASK; + writel(reg, &pll->pll_base); + debug("pllx_set_rate: base = 0x%08X\n", reg); + + /* Set lock_enable to PLLX_MISC */ + reg = readl(&pll->pll_misc); + reg |= PLL_LOCK_ENABLE_MASK; + writel(reg, &pll->pll_misc); + debug("pllx_set_rate: misc = 0x%08X\n", reg); + + /* Enable PLLX last, once it's all configured */ + reg = readl(&pll->pll_base); + reg |= PLL_ENABLE_MASK; + writel(reg, &pll->pll_base); + debug("pllx_set_rate: base final = 0x%08X\n", reg); + + return 0; +} + +void init_pllx(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX]; + int soc_type, sku_info, chip_sku; + enum clock_osc_freq osc; + struct clk_pll_table *sel; + + debug("init_pllx entry\n"); + + /* get SOC (chip) type */ + soc_type = tegra_get_chip(); + debug(" init_pllx: SoC = 0x%02X\n", soc_type); + + /* get SKU info */ + sku_info = tegra_get_sku_info(); + debug(" init_pllx: SKU info byte = 0x%02X\n", sku_info); + + /* get chip SKU, combo of the above info */ + chip_sku = tegra_get_chip_sku(); + debug(" init_pllx: Chip SKU = %d\n", chip_sku); + + /* get osc freq */ + osc = clock_get_osc_freq(); + debug(" init_pllx: osc = %d\n", osc); + + /* set pllx */ + sel = &tegra_pll_x_table[chip_sku][osc]; + pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); +} + +void enable_cpu_clock(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 clk; + + /* + * NOTE: + * Regardless of whether the request is to enable or disable the CPU + * clock, every processor in the CPU complex except the master (CPU 0) + * will have it's clock stopped because the AVP only talks to the + * master. + */ + + if (enable) { + /* Initialize PLLX */ + init_pllx(); + + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + } + + /* + * Read the register containing the individual CPU clock enables and + * always stop the clocks to CPUs > 0. + */ + clk = readl(&clkrst->crc_clk_cpu_cmplx); + clk |= 1 << CPU1_CLK_STP_SHIFT; + if (get_num_cpus() == 4) + clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT); + + /* Stop/Unstop the CPU clock */ + clk &= ~CPU0_CLK_STP_MASK; + clk |= !enable << CPU0_CLK_STP_SHIFT; + writel(clk, &clkrst->crc_clk_cpu_cmplx); + + clock_enable(PERIPH_ID_CPU); +} + +static int is_cpu_powered(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; +} + +static void remove_cpu_io_clamps(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Remove the clamps on the CPU I/O signals */ + reg = readl(&pmc->pmc_remove_clamping); + reg |= CPU_CLMP; + writel(reg, &pmc->pmc_remove_clamping); + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); +} + +void powerup_cpu(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + int timeout = IO_STABILIZATION_DELAY; + + if (!is_cpu_powered()) { + /* Toggle the CPU power state (OFF -> ON) */ + reg = readl(&pmc->pmc_pwrgate_toggle); + reg &= PARTID_CP; + reg |= START_CP; + writel(reg, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_cpu_powered()) { + if (timeout-- == 0) + printf("CPU failed to power up!\n"); + else + udelay(10); + } + + /* + * Remove the I/O clamps from CPU power partition. + * Recommended only on a Warm boot, if the CPU partition gets + * power gated. Shouldn't cause any harm when called after a + * cold boot according to HW, probably just redundant. + */ + remove_cpu_io_clamps(); + } +} + +void reset_A9_cpu(int reset) +{ + /* + * NOTE: Regardless of whether the request is to hold the CPU in reset + * or take it out of reset, every processor in the CPU complex + * except the master (CPU 0) will be held in reset because the + * AVP only talks to the master. The AVP does not know that there + * are multiple processors in the CPU complex. + */ + int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; + int num_cpus = get_num_cpus(); + int cpu; + + debug("reset_a9_cpu entry\n"); + /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ + for (cpu = 1; cpu < num_cpus; cpu++) + reset_cmplx_set_enable(cpu, mask, 1); + reset_cmplx_set_enable(0, mask, reset); + + /* Enable/Disable master CPU reset */ + reset_set_enable(PERIPH_ID_CPU, reset); +} + +void clock_enable_coresight(int enable) +{ + u32 rst, src = 2; + + debug("clock_enable_coresight entry\n"); + clock_set_enable(PERIPH_ID_CORESIGHT, enable); + reset_set_enable(PERIPH_ID_CORESIGHT, !enable); + + if (enable) { + /* + * Put CoreSight on PLLP_OUT0 and divide it down as per + * PLLP base frequency based on SoC type (T20/T30+). + * Clock divider request would setup CSITE clock as 144MHz + * for PLLP base 216MHz and 204MHz for PLLP base 408MHz + */ + src = CLK_DIVIDER(NVBL_PLLP_KHZ, CSITE_KHZ); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); + + /* Unlock the CPU CoreSight interfaces */ + rst = CORESIGHT_UNLOCK; + writel(rst, CSITE_CPU_DBG0_LAR); + writel(rst, CSITE_CPU_DBG1_LAR); + if (get_num_cpus() == 4) { + writel(rst, CSITE_CPU_DBG2_LAR); + writel(rst, CSITE_CPU_DBG3_LAR); + } + } +} + +void halt_avp(void) +{ + for (;;) { + writel(HALT_COP_EVENT_JTAG | (FLOW_MODE_STOP << 29), + FLOW_CTLR_HALT_COP_EVENTS); + } +} diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h new file mode 100644 index 0000000000..b4ca44fce1 --- /dev/null +++ b/arch/arm/mach-tegra/cpu.h @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2010-2014 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +/* Stabilization delays, in usec */ +#define PLL_STABILIZATION_DELAY (300) +#define IO_STABILIZATION_DELAY (1000) + +#if defined(CONFIG_TEGRA20) +#define NVBL_PLLP_KHZ 216000 +#define CSITE_KHZ 144000 +#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) || \ + defined(CONFIG_TEGRA124) +#define NVBL_PLLP_KHZ 408000 +#define CSITE_KHZ 204000 +#else +#error "Unknown Tegra chip!" +#endif + +#define PLLX_ENABLED (1 << 30) +#define CCLK_BURST_POLICY 0x20008888 +#define SUPER_CCLK_DIVIDER 0x80000000 + +/* Calculate clock fractional divider value from ref and target frequencies */ +#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) + +/* Calculate clock frequency value from reference and clock divider value */ +#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) + +/* AVP/CPU ID */ +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ +#define PG_UP_TAG_0 0x0 + +#define CORESIGHT_UNLOCK 0xC5ACCE55; + +#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) +#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) +#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) +#define CSITE_CPU_DBG2_LAR (NV_PA_CSITE_BASE + 0x14FB0) +#define CSITE_CPU_DBG3_LAR (NV_PA_CSITE_BASE + 0x16FB0) + +#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) +#define FLOW_MODE_STOP 2 +#define HALT_COP_EVENT_JTAG (1 << 28) +#define HALT_COP_EVENT_IRQ_1 (1 << 11) +#define HALT_COP_EVENT_FIQ_1 (1 << 9) + +#define FLOW_MODE_NONE 0 + +#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) + +struct clk_pll_table { + u16 n; + u16 m; + u8 p; + u8 cpcon; +}; + +void clock_enable_coresight(int enable); +void enable_cpu_clock(int enable); +void halt_avp(void) __attribute__ ((noreturn)); +void init_pllx(void); +void powerup_cpu(void); +void reset_A9_cpu(int reset); +void start_cpu(u32 reset_vector); +int tegra_get_chip(void); +int tegra_get_sku_info(void); +int tegra_get_chip_sku(void); +void adjust_pllp_out_freqs(void); +void pmic_enable_cpu_vdd(void); diff --git a/arch/arm/mach-tegra/lowlevel_init.S b/arch/arm/mach-tegra/lowlevel_init.S new file mode 100644 index 0000000000..a211bb3b1a --- /dev/null +++ b/arch/arm/mach-tegra/lowlevel_init.S @@ -0,0 +1,26 @@ +/* + * SoC-specific setup info + * + * (C) Copyright 2010,2011 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + + .align 5 +ENTRY(reset_cpu) + ldr r1, rstctl @ get addr for global reset + @ reg + ldr r3, [r1] + orr r3, r3, #0x10 + str r3, [r1] @ force reset + mov r0, r0 +_loop_forever: + b _loop_forever +rstctl: + .word PRM_RSTCTRL +ENDPROC(reset_cpu) diff --git a/arch/arm/mach-tegra/pinmux-common.c b/arch/arm/mach-tegra/pinmux-common.c new file mode 100644 index 0000000000..6e3ab0c14c --- /dev/null +++ b/arch/arm/mach-tegra/pinmux-common.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* return 1 if a pingrp is in range */ +#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PMUX_PINGRP_COUNT)) + +/* return 1 if a pmux_func is in range */ +#define pmux_func_isvalid(func) \ + (((func) >= 0) && ((func) < PMUX_FUNC_COUNT)) + +/* return 1 if a pin_pupd_is in range */ +#define pmux_pin_pupd_isvalid(pupd) \ + (((pupd) >= PMUX_PULL_NORMAL) && ((pupd) <= PMUX_PULL_UP)) + +/* return 1 if a pin_tristate_is in range */ +#define pmux_pin_tristate_isvalid(tristate) \ + (((tristate) >= PMUX_TRI_NORMAL) && ((tristate) <= PMUX_TRI_TRISTATE)) + +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC +/* return 1 if a pin_io_is in range */ +#define pmux_pin_io_isvalid(io) \ + (((io) >= PMUX_PIN_OUTPUT) && ((io) <= PMUX_PIN_INPUT)) + +/* return 1 if a pin_lock is in range */ +#define pmux_pin_lock_isvalid(lock) \ + (((lock) >= PMUX_PIN_LOCK_DISABLE) && ((lock) <= PMUX_PIN_LOCK_ENABLE)) + +/* return 1 if a pin_od is in range */ +#define pmux_pin_od_isvalid(od) \ + (((od) >= PMUX_PIN_OD_DISABLE) && ((od) <= PMUX_PIN_OD_ENABLE)) + +/* return 1 if a pin_ioreset_is in range */ +#define pmux_pin_ioreset_isvalid(ioreset) \ + (((ioreset) >= PMUX_PIN_IO_RESET_DISABLE) && \ + ((ioreset) <= PMUX_PIN_IO_RESET_ENABLE)) + +#ifdef TEGRA_PMX_HAS_RCV_SEL +/* return 1 if a pin_rcv_sel_is in range */ +#define pmux_pin_rcv_sel_isvalid(rcv_sel) \ + (((rcv_sel) >= PMUX_PIN_RCV_SEL_NORMAL) && \ + ((rcv_sel) <= PMUX_PIN_RCV_SEL_HIGH)) +#endif /* TEGRA_PMX_HAS_RCV_SEL */ +#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ + +#define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset)) + +#if defined(CONFIG_TEGRA20) + +#define MUX_REG(grp) _R(0x80 + ((tegra_soc_pingroups[grp].ctl_id / 16) * 4)) +#define MUX_SHIFT(grp) ((tegra_soc_pingroups[grp].ctl_id % 16) * 2) + +#define PULL_REG(grp) _R(0xa0 + ((tegra_soc_pingroups[grp].pull_id / 16) * 4)) +#define PULL_SHIFT(grp) ((tegra_soc_pingroups[grp].pull_id % 16) * 2) + +#define TRI_REG(grp) _R(0x14 + (((grp) / 32) * 4)) +#define TRI_SHIFT(grp) ((grp) % 32) + +#else + +#define REG(pin) _R(0x3000 + ((pin) * 4)) + +#define MUX_REG(pin) REG(pin) +#define MUX_SHIFT(pin) 0 + +#define PULL_REG(pin) REG(pin) +#define PULL_SHIFT(pin) 2 + +#define TRI_REG(pin) REG(pin) +#define TRI_SHIFT(pin) 4 + +#endif /* CONFIG_TEGRA20 */ + +#define DRV_REG(group) _R(0x868 + ((group) * 4)) + +#define IO_SHIFT 5 +#define OD_SHIFT 6 +#define LOCK_SHIFT 7 +#define IO_RESET_SHIFT 8 +#define RCV_SEL_SHIFT 9 + +#if !defined(CONFIG_TEGRA20) && !defined(CONFIG_TEGRA30) +/* This register/field only exists on Tegra114 and later */ +#define APB_MISC_PP_PINMUX_GLOBAL_0 0x40 +#define CLAMP_INPUTS_WHEN_TRISTATED 1 + +void pinmux_set_tristate_input_clamping(void) +{ + u32 *reg = _R(APB_MISC_PP_PINMUX_GLOBAL_0); + u32 val; + + val = readl(reg); + val |= CLAMP_INPUTS_WHEN_TRISTATED; + writel(val, reg); +} +#endif + +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func) +{ + u32 *reg = MUX_REG(pin); + int i, mux = -1; + u32 val; + + if (func == PMUX_FUNC_DEFAULT) + return; + + /* Error check on pin and func */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_func_isvalid(func)); + + if (func >= PMUX_FUNC_RSVD1) { + mux = (func - PMUX_FUNC_RSVD1) & 3; + } else { + /* Search for the appropriate function */ + for (i = 0; i < 4; i++) { + if (tegra_soc_pingroups[pin].funcs[i] == func) { + mux = i; + break; + } + } + } + assert(mux != -1); + + val = readl(reg); + val &= ~(3 << MUX_SHIFT(pin)); + val |= (mux << MUX_SHIFT(pin)); + writel(val, reg); +} + +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd) +{ + u32 *reg = PULL_REG(pin); + u32 val; + + /* Error check on pin and pupd */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_pupd_isvalid(pupd)); + + val = readl(reg); + val &= ~(3 << PULL_SHIFT(pin)); + val |= (pupd << PULL_SHIFT(pin)); + writel(val, reg); +} + +static void pinmux_set_tristate(enum pmux_pingrp pin, int tri) +{ + u32 *reg = TRI_REG(pin); + u32 val; + + /* Error check on pin */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_tristate_isvalid(tri)); + + val = readl(reg); + if (tri == PMUX_TRI_TRISTATE) + val |= (1 << TRI_SHIFT(pin)); + else + val &= ~(1 << TRI_SHIFT(pin)); + writel(val, reg); +} + +void pinmux_tristate_enable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, PMUX_TRI_TRISTATE); +} + +void pinmux_tristate_disable(enum pmux_pingrp pin) +{ + pinmux_set_tristate(pin, PMUX_TRI_NORMAL); +} + +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC +void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io) +{ + u32 *reg = REG(pin); + u32 val; + + if (io == PMUX_PIN_NONE) + return; + + /* Error check on pin and io */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_io_isvalid(io)); + + val = readl(reg); + if (io == PMUX_PIN_INPUT) + val |= (io & 1) << IO_SHIFT; + else + val &= ~(1 << IO_SHIFT); + writel(val, reg); +} + +static void pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock) +{ + u32 *reg = REG(pin); + u32 val; + + if (lock == PMUX_PIN_LOCK_DEFAULT) + return; + + /* Error check on pin and lock */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_lock_isvalid(lock)); + + val = readl(reg); + if (lock == PMUX_PIN_LOCK_ENABLE) { + val |= (1 << LOCK_SHIFT); + } else { + if (val & (1 << LOCK_SHIFT)) + printf("%s: Cannot clear LOCK bit!\n", __func__); + val &= ~(1 << LOCK_SHIFT); + } + writel(val, reg); + + return; +} + +static void pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od) +{ + u32 *reg = REG(pin); + u32 val; + + if (od == PMUX_PIN_OD_DEFAULT) + return; + + /* Error check on pin and od */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_od_isvalid(od)); + + val = readl(reg); + if (od == PMUX_PIN_OD_ENABLE) + val |= (1 << OD_SHIFT); + else + val &= ~(1 << OD_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_ioreset(enum pmux_pingrp pin, + enum pmux_pin_ioreset ioreset) +{ + u32 *reg = REG(pin); + u32 val; + + if (ioreset == PMUX_PIN_IO_RESET_DEFAULT) + return; + + /* Error check on pin and ioreset */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_ioreset_isvalid(ioreset)); + + val = readl(reg); + if (ioreset == PMUX_PIN_IO_RESET_ENABLE) + val |= (1 << IO_RESET_SHIFT); + else + val &= ~(1 << IO_RESET_SHIFT); + writel(val, reg); + + return; +} + +#ifdef TEGRA_PMX_HAS_RCV_SEL +static void pinmux_set_rcv_sel(enum pmux_pingrp pin, + enum pmux_pin_rcv_sel rcv_sel) +{ + u32 *reg = REG(pin); + u32 val; + + if (rcv_sel == PMUX_PIN_RCV_SEL_DEFAULT) + return; + + /* Error check on pin and rcv_sel */ + assert(pmux_pingrp_isvalid(pin)); + assert(pmux_pin_rcv_sel_isvalid(rcv_sel)); + + val = readl(reg); + if (rcv_sel == PMUX_PIN_RCV_SEL_HIGH) + val |= (1 << RCV_SEL_SHIFT); + else + val &= ~(1 << RCV_SEL_SHIFT); + writel(val, reg); + + return; +} +#endif /* TEGRA_PMX_HAS_RCV_SEL */ +#endif /* TEGRA_PMX_HAS_PIN_IO_BIT_ETC */ + +static void pinmux_config_pingrp(const struct pmux_pingrp_config *config) +{ + enum pmux_pingrp pin = config->pingrp; + + pinmux_set_func(pin, config->func); + pinmux_set_pullupdown(pin, config->pull); + pinmux_set_tristate(pin, config->tristate); +#ifdef TEGRA_PMX_HAS_PIN_IO_BIT_ETC + pinmux_set_io(pin, config->io); + pinmux_set_lock(pin, config->lock); + pinmux_set_od(pin, config->od); + pinmux_set_ioreset(pin, config->ioreset); +#ifdef TEGRA_PMX_HAS_RCV_SEL + pinmux_set_rcv_sel(pin, config->rcv_sel); +#endif +#endif +} + +void pinmux_config_pingrp_table(const struct pmux_pingrp_config *config, + int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_pingrp(&config[i]); +} + +#ifdef TEGRA_PMX_HAS_DRVGRPS + +#define pmux_drvgrp_isvalid(pd) (((pd) >= 0) && ((pd) < PMUX_DRVGRP_COUNT)) + +#define pmux_slw_isvalid(slw) \ + (((slw) >= PMUX_SLWF_MIN) && ((slw) <= PMUX_SLWF_MAX)) + +#define pmux_drv_isvalid(drv) \ + (((drv) >= PMUX_DRVUP_MIN) && ((drv) <= PMUX_DRVUP_MAX)) + +#define pmux_lpmd_isvalid(lpm) \ + (((lpm) >= PMUX_LPMD_X8) && ((lpm) <= PMUX_LPMD_X)) + +#define pmux_schmt_isvalid(schmt) \ + (((schmt) >= PMUX_SCHMT_DISABLE) && ((schmt) <= PMUX_SCHMT_ENABLE)) + +#define pmux_hsm_isvalid(hsm) \ + (((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE)) + +#define HSM_SHIFT 2 +#define SCHMT_SHIFT 3 +#define LPMD_SHIFT 4 +#define LPMD_MASK (3 << LPMD_SHIFT) +#define DRVDN_SHIFT 12 +#define DRVDN_MASK (0x7F << DRVDN_SHIFT) +#define DRVUP_SHIFT 20 +#define DRVUP_MASK (0x7F << DRVUP_SHIFT) +#define SLWR_SHIFT 28 +#define SLWR_MASK (3 << SLWR_SHIFT) +#define SLWF_SHIFT 30 +#define SLWF_MASK (3 << SLWF_SHIFT) + +static void pinmux_set_drvup_slwf(enum pmux_drvgrp grp, int slwf) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (slwf == PMUX_SLWF_NONE) + return; + + /* Error check on pad and slwf */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_slw_isvalid(slwf)); + + val = readl(reg); + val &= ~SLWF_MASK; + val |= (slwf << SLWF_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_drvdn_slwr(enum pmux_drvgrp grp, int slwr) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (slwr == PMUX_SLWR_NONE) + return; + + /* Error check on pad and slwr */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_slw_isvalid(slwr)); + + val = readl(reg); + val &= ~SLWR_MASK; + val |= (slwr << SLWR_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_drvup(enum pmux_drvgrp grp, int drvup) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (drvup == PMUX_DRVUP_NONE) + return; + + /* Error check on pad and drvup */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_drv_isvalid(drvup)); + + val = readl(reg); + val &= ~DRVUP_MASK; + val |= (drvup << DRVUP_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_drvdn(enum pmux_drvgrp grp, int drvdn) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (drvdn == PMUX_DRVDN_NONE) + return; + + /* Error check on pad and drvdn */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_drv_isvalid(drvdn)); + + val = readl(reg); + val &= ~DRVDN_MASK; + val |= (drvdn << DRVDN_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_lpmd(enum pmux_drvgrp grp, enum pmux_lpmd lpmd) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (lpmd == PMUX_LPMD_NONE) + return; + + /* Error check pad and lpmd value */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_lpmd_isvalid(lpmd)); + + val = readl(reg); + val &= ~LPMD_MASK; + val |= (lpmd << LPMD_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_schmt(enum pmux_drvgrp grp, enum pmux_schmt schmt) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (schmt == PMUX_SCHMT_NONE) + return; + + /* Error check pad */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_schmt_isvalid(schmt)); + + val = readl(reg); + if (schmt == PMUX_SCHMT_ENABLE) + val |= (1 << SCHMT_SHIFT); + else + val &= ~(1 << SCHMT_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_set_hsm(enum pmux_drvgrp grp, enum pmux_hsm hsm) +{ + u32 *reg = DRV_REG(grp); + u32 val; + + /* NONE means unspecified/do not change/use POR value */ + if (hsm == PMUX_HSM_NONE) + return; + + /* Error check pad */ + assert(pmux_drvgrp_isvalid(grp)); + assert(pmux_hsm_isvalid(hsm)); + + val = readl(reg); + if (hsm == PMUX_HSM_ENABLE) + val |= (1 << HSM_SHIFT); + else + val &= ~(1 << HSM_SHIFT); + writel(val, reg); + + return; +} + +static void pinmux_config_drvgrp(const struct pmux_drvgrp_config *config) +{ + enum pmux_drvgrp grp = config->drvgrp; + + pinmux_set_drvup_slwf(grp, config->slwf); + pinmux_set_drvdn_slwr(grp, config->slwr); + pinmux_set_drvup(grp, config->drvup); + pinmux_set_drvdn(grp, config->drvdn); + pinmux_set_lpmd(grp, config->lpmd); + pinmux_set_schmt(grp, config->schmt); + pinmux_set_hsm(grp, config->hsm); +} + +void pinmux_config_drvgrp_table(const struct pmux_drvgrp_config *config, + int len) +{ + int i; + + for (i = 0; i < len; i++) + pinmux_config_drvgrp(&config[i]); +} +#endif /* TEGRA_PMX_HAS_DRVGRPS */ diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c new file mode 100644 index 0000000000..439cff36b9 --- /dev/null +++ b/arch/arm/mach-tegra/powergate.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include + +#include +#include + +#include +#include + +#define PWRGATE_TOGGLE 0x30 +#define PWRGATE_TOGGLE_START (1 << 8) + +#define REMOVE_CLAMPING 0x34 + +#define PWRGATE_STATUS 0x38 + +static int tegra_powergate_set(enum tegra_powergate id, bool state) +{ + u32 value, mask = state ? (1 << id) : 0, old_mask; + unsigned long start, timeout = 25; + + value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); + old_mask = value & (1 << id); + + if (mask == old_mask) + return 0; + + writel(PWRGATE_TOGGLE_START | id, NV_PA_PMC_BASE + PWRGATE_TOGGLE); + + start = get_timer(0); + + while (get_timer(start) < timeout) { + value = readl(NV_PA_PMC_BASE + PWRGATE_STATUS); + if ((value & (1 << id)) == mask) + return 0; + } + + return -ETIMEDOUT; +} + +static int tegra_powergate_power_on(enum tegra_powergate id) +{ + return tegra_powergate_set(id, true); +} + +int tegra_powergate_power_off(enum tegra_powergate id) +{ + return tegra_powergate_set(id, false); +} + +static int tegra_powergate_remove_clamping(enum tegra_powergate id) +{ + unsigned long value; + + /* + * The REMOVE_CLAMPING register has the bits for the PCIE and VDEC + * partitions reversed. This was originally introduced on Tegra20 but + * has since been carried forward for backwards-compatibility. + */ + if (id == TEGRA_POWERGATE_VDEC) + value = 1 << TEGRA_POWERGATE_PCIE; + else if (id == TEGRA_POWERGATE_PCIE) + value = 1 << TEGRA_POWERGATE_VDEC; + else + value = 1 << id; + + writel(value, NV_PA_PMC_BASE + REMOVE_CLAMPING); + + return 0; +} + +int tegra_powergate_sequence_power_up(enum tegra_powergate id, + enum periph_id periph) +{ + int err; + + reset_set_enable(periph, 1); + + err = tegra_powergate_power_on(id); + if (err < 0) + return err; + + clock_enable(periph); + + udelay(10); + + err = tegra_powergate_remove_clamping(id); + if (err < 0) + return err; + + udelay(10); + + reset_set_enable(periph, 0); + + return 0; +} diff --git a/arch/arm/mach-tegra/spl.c b/arch/arm/mach-tegra/spl.c new file mode 100644 index 0000000000..e0f9d5b6b4 --- /dev/null +++ b/arch/arm/mach-tegra/spl.c @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2012 + * NVIDIA Inc, + * + * Allen Martin + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "cpu.h" + +void spl_board_init(void) +{ + struct apb_misc_pp_ctlr *apb_misc = + (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; + + /* enable JTAG */ + writel(0xC0, &apb_misc->cfg_ctl); + + board_init_uart_f(); + + /* Initialize periph GPIOs */ + gpio_early_init_uart(); + + clock_early_init(); + preloader_console_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_RAM; +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + debug("image entry point: 0x%X\n", spl_image->entry_point); + + start_cpu((u32)spl_image->entry_point); + halt_avp(); +} diff --git a/arch/arm/mach-tegra/sys_info.c b/arch/arm/mach-tegra/sys_info.c new file mode 100644 index 0000000000..5933c35ddd --- /dev/null +++ b/arch/arm/mach-tegra/sys_info.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2010,2011 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +static void upstring(char *s) +{ + while (*s) { + *s = toupper(*s); + s++; + } +} + +/* Print CPU information */ +int print_cpuinfo(void) +{ + char soc_name[10]; + + strncpy(soc_name, CONFIG_SYS_SOC, 10); + upstring(soc_name); + puts(soc_name); + puts("\n"); + + /* TBD: Add printf of major/minor rev info, stepping, etc. */ + return 0; +} diff --git a/arch/arm/mach-tegra/tegra114/Kconfig b/arch/arm/mach-tegra/tegra114/Kconfig new file mode 100644 index 0000000000..31012bc770 --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/Kconfig @@ -0,0 +1,16 @@ +if TEGRA114 + +choice + prompt "Tegra114 board select" + +config TARGET_DALMORE + bool "NVIDIA Tegra114 Dalmore evaluation board" + +endchoice + +config SYS_SOC + default "tegra114" + +source "board/nvidia/dalmore/Kconfig" + +endif diff --git a/arch/arm/mach-tegra/tegra114/Makefile b/arch/arm/mach-tegra/tegra114/Makefile new file mode 100644 index 0000000000..7489f5f146 --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +obj-$(CONFIG_SPL_BUILD) += cpu.o + +obj-y += clock.o funcmux.o pinmux.o diff --git a/arch/arm/mach-tegra/tegra114/clock.c b/arch/arm/mach-tegra/tegra114/clock.c new file mode 100644 index 0000000000..d5194e11b5 --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/clock.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra114 Clock control functions */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Clock types that we can use as a source. The Tegra114 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCMT16, + CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_28} +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_I2C5, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x38h */ /* Jumps to reg offset 0x3B0h */ + TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), + + /* 0x40 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x48 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x50 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RTC), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(RESERVED16), + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 24 */ + PERIPHC_G3D, + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(RESERVED39), + + /* 40 */ + NONE(KFUSE), + NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, + PERIPHC_I2C5, + + /* 48 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + NONE(CSI), + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + PERIPHC_SPEEDO, + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(DTV), + + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 88 */ + NONE(CRAM2), + NONE(RESERVED89), + NONE(MDOUBLER), + NONE(RESERVED91), + NONE(SUSOUT), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(RESERVED95), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + PERIPHC_G3D2, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 08 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 16 */ + NONE(ATOMICS), + NONE(RESERVED17), + NONE(RESERVED18), + NONE(RESERVED19), + NONE(RESERVED20), + NONE(RESERVED21), + NONE(RESERVED22), + PERIPHC_ACTMON, + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + NONE(RESERVED26), + NONE(RESERVED27), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(RESERVED30), + NONE(RESERVED31), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(RESERVED1_SATACOLD), + NONE(RESERVED2_PCIERX0), + NONE(RESERVED3_PCIERX1), + NONE(RESERVED4_PCIERX2), + NONE(RESERVED5_PCIERX3), + NONE(RESERVED6_PCIERX4), + NONE(RESERVED7_PCIERX5), + + /* 40 */ + NONE(CEC), + NONE(PCIE2_IOBIST), + NONE(EMC_IOBIST), + NONE(HDMI_IOBIST), + NONE(SATA_IOBIST), + NONE(MIPI_IOBIST), + NONE(EMC1_IOBIST), + NONE(XUSB), + + /* 48 */ + NONE(CILAB), + NONE(CILCD), + NONE(CILE), + NONE(DSIA_LP), + NONE(DSIB_LP), + NONE(RESERVED21_ENTROPY), + NONE(RESERVED22_W), + NONE(RESERVED23_W), + + /* 56 */ + NONE(RESERVED24_W), + NONE(AMX0), + NONE(ADX0), + NONE(DVFS), + NONE(XUSB_SS), + NONE(EMC_DLL), + NONE(MC1), + NONE(EMC1), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. Note that T30/T114 support 3 new higher freqs, but we map back + * to the old T20 freqs. Support for the higher oscillators is TBD. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + if (reg & 1) /* one of the newer freqs */ + printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); + + return reg >> 2; /* Map to most common (T20) freqs */ +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else + return &clkrst->crc_clk_src[internal_id]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + if (type == CLOCK_TYPE_PCMT16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra114 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED3: + case PERIPH_ID_RESERVED16: + case PERIPH_ID_RESERVED24: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED43: + case PERIPH_ID_RESERVED45: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED89: + case PERIPH_ID_RESERVED91: + case PERIPH_ID_RESERVED93: + case PERIPH_ID_RESERVED94: + case PERIPH_ID_RESERVED95: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + tegra30_set_up_pllp(); + + /* + * PLLC output frequency set to 600Mhz + * PLLD output frequency set to 925Mhz + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } + + /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ + writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); + + /* PLLC_MISC: Set LOCK_ENABLE */ + writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); + udelay(2); + + /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ + writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); + udelay(2); +} + +void arch_timer_init(void) +{ + struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; + u32 freq, val; + + freq = clock_get_rate(CLOCK_ID_OSC); + debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq); + + /* ARM CNTFRQ */ + asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); + + /* Only T114 has the System Counter regs */ + debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); + writel(freq, &sysctr->cntfid0); + + val = readl(&sysctr->cntcr); + val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; + writel(val, &sysctr->cntcr); + debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); +} diff --git a/arch/arm/mach-tegra/tegra114/cpu.c b/arch/arm/mach-tegra/tegra114/cpu.c new file mode 100644 index 0000000000..18dc1af1b4 --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/cpu.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../cpu.h" + +/* Tegra114-specific CPU init code */ +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("enable_cpu_power_rail entry\n"); + + /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ + pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); + pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SDA_PZ7); + + /* + * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), + * set it for 25ms (102MHz * .025) + */ + reg = 0x26E8F0; + writel(reg, &pmc->pmc_cpupwrgood_timer); + + /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ + clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); + setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); + + /* + * Set CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0_CAR2PMC_CPU_ACK_WIDTH + * to 408 to satisfy the requirement of having at least 16 CPU clock + * cycles before clamp removal. + */ + + clrbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 0xFFF); + setbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 408); +} + +static void enable_cpu_clocks(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("enable_cpu_clocks entry\n"); + + /* Wait for PLL-X to lock */ + do { + reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + } while ((reg & PLL_LOCK_MASK) == 0); + + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + + /* Always enable the main CPU complex clocks */ + clock_enable(PERIPH_ID_CPU); + clock_enable(PERIPH_ID_CPULP); + clock_enable(PERIPH_ID_CPUG); +} + +static void remove_cpu_resets(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("remove_cpu_resets entry\n"); + /* Take the slow non-CPU partition out of reset */ + reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); + writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr); + + /* Take the fast non-CPU partition out of reset */ + reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); + writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpug_cmplx_clr); + + /* Clear the SW-controlled reset of the slow cluster */ + reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr); + reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); + writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); + + /* Clear the SW-controlled reset of the fast cluster */ + reg = readl(&clkrst->crc_rst_cpug_cmplx_clr); + reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0); + reg |= (CLR_CPURESET1+CLR_DBGRESET1+CLR_CORERESET1+CLR_CXRESET1); + reg |= (CLR_CPURESET2+CLR_DBGRESET2+CLR_CORERESET2+CLR_CXRESET2); + reg |= (CLR_CPURESET3+CLR_DBGRESET3+CLR_CORERESET3+CLR_CXRESET3); + writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); +} + +/** + * The T114 requires some special clock initialization, including setting up + * the DVC I2C, turning on MSELECT and selecting the G CPU cluster + */ +void t114_init_clocks(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + u32 val; + + debug("t114_init_clocks entry\n"); + + /* Set active CPU cluster to G */ + clrbits_le32(&flow->cluster_control, 1); + + writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); + + debug("Setting up PLLX\n"); + init_pllx(); + + val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Enable clocks to required peripherals. TBD - minimize this list */ + debug("Enabling clocks\n"); + + clock_set_enable(PERIPH_ID_CACHE2, 1); + clock_set_enable(PERIPH_ID_GPIO, 1); + clock_set_enable(PERIPH_ID_TMR, 1); + clock_set_enable(PERIPH_ID_RTC, 1); + clock_set_enable(PERIPH_ID_CPU, 1); + clock_set_enable(PERIPH_ID_EMC, 1); + clock_set_enable(PERIPH_ID_I2C5, 1); + clock_set_enable(PERIPH_ID_FUSE, 1); + clock_set_enable(PERIPH_ID_PMC, 1); + clock_set_enable(PERIPH_ID_APBDMA, 1); + clock_set_enable(PERIPH_ID_MEM, 1); + clock_set_enable(PERIPH_ID_IRAMA, 1); + clock_set_enable(PERIPH_ID_IRAMB, 1); + clock_set_enable(PERIPH_ID_IRAMC, 1); + clock_set_enable(PERIPH_ID_IRAMD, 1); + clock_set_enable(PERIPH_ID_CORESIGHT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_EMC1, 1); + clock_set_enable(PERIPH_ID_MC1, 1); + clock_set_enable(PERIPH_ID_DVFS, 1); + + /* + * Set MSELECT clock source as PLLP (00), and ask for a clock + * divider that would set the MSELECT clock at 102MHz for a + * PLLP base of 408MHz. + */ + clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, + CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); + + /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ + clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); + + /* Give clocks time to stabilize */ + udelay(1000); + + /* Take required peripherals out of reset */ + debug("Taking periphs out of reset\n"); + reset_set_enable(PERIPH_ID_CACHE2, 0); + reset_set_enable(PERIPH_ID_GPIO, 0); + reset_set_enable(PERIPH_ID_TMR, 0); + reset_set_enable(PERIPH_ID_COP, 0); + reset_set_enable(PERIPH_ID_EMC, 0); + reset_set_enable(PERIPH_ID_I2C5, 0); + reset_set_enable(PERIPH_ID_FUSE, 0); + reset_set_enable(PERIPH_ID_APBDMA, 0); + reset_set_enable(PERIPH_ID_MEM, 0); + reset_set_enable(PERIPH_ID_CORESIGHT, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); + reset_set_enable(PERIPH_ID_EMC1, 0); + reset_set_enable(PERIPH_ID_MC1, 0); + reset_set_enable(PERIPH_ID_DVFS, 0); + + debug("t114_init_clocks exit\n"); +} + +static bool is_partition_powered(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Get power gate status */ + reg = readl(&pmc->pmc_pwrgate_status); + return !!(reg & (1 << partid)); +} + +static bool is_clamp_enabled(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Get clamp status. */ + reg = readl(&pmc->pmc_clamp_status); + return !!(reg & (1 << partid)); +} + +static void power_partition(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("%s: part ID = %08X\n", __func__, partid); + /* Is the partition already on? */ + if (!is_partition_powered(partid)) { + /* No, toggle the partition power state (OFF -> ON) */ + debug("power_partition, toggling state\n"); + writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_partition_powered(partid)) + ; + + /* Wait for the clamp status to be cleared */ + while (is_clamp_enabled(partid)) + ; + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + } +} + +void powerup_cpus(void) +{ + debug("powerup_cpus entry\n"); + + /* We boot to the fast cluster */ + debug("powerup_cpus entry: G cluster\n"); + /* Power up the fast cluster rail partition */ + power_partition(CRAIL); + + /* Power up the fast cluster non-CPU partition */ + power_partition(C0NC); + + /* Power up the fast cluster CPU0 partition */ + power_partition(CE0); +} + +void start_cpu(u32 reset_vector) +{ + u32 imme, inst; + + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + + t114_init_clocks(); + + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + /* Get the CPU(s) running */ + enable_cpu_clocks(); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* Take CPU(s) out of reset */ + remove_cpu_resets(); + + /* Set the entry point for CPU execution from reset */ + + /* + * A01P with patched boot ROM; vector hard-coded to 0x4003fffc. + * See nvbug 1193357 for details. + */ + + /* mov r0, #lsb(reset_vector) */ + imme = reset_vector & 0xffff; + inst = imme & 0xfff; + inst |= ((imme >> 12) << 16); + inst |= 0xe3000000; + writel(inst, 0x4003fff0); + + /* movt r0, #msb(reset_vector) */ + imme = (reset_vector >> 16) & 0xffff; + inst = imme & 0xfff; + inst |= ((imme >> 12) << 16); + inst |= 0xe3400000; + writel(inst, 0x4003fff4); + + /* bx r0 */ + writel(0xe12fff10, 0x4003fff8); + + /* b -12 */ + imme = (u32)-20; + inst = (imme >> 2) & 0xffffff; + inst |= 0xea000000; + writel(inst, 0x4003fffc); + + /* Write to orignal location for compatibility */ + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* If the CPU(s) don't already have power, power 'em up */ + powerup_cpus(); +} diff --git a/arch/arm/mach-tegra/tegra114/funcmux.c b/arch/arm/mach-tegra/tegra114/funcmux.c new file mode 100644 index 0000000000..52441c71e6 --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/funcmux.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra114 high-level function multiplexing */ + +#include +#include +#include +#include + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART4: + switch (config) { + case FUNCMUX_UART4_GMI: + pinmux_set_func(PMUX_PINGRP_GMI_A16_PJ7, + PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_GMI_A17_PB0, + PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_GMI_A18_PB1, + PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_GMI_A19_PK7, + PMUX_FUNC_UARTD); + + pinmux_set_io(PMUX_PINGRP_GMI_A16_PJ7, PMUX_PIN_OUTPUT); + pinmux_set_io(PMUX_PINGRP_GMI_A17_PB0, PMUX_PIN_INPUT); + pinmux_set_io(PMUX_PINGRP_GMI_A18_PB1, PMUX_PIN_INPUT); + pinmux_set_io(PMUX_PINGRP_GMI_A19_PK7, PMUX_PIN_OUTPUT); + + pinmux_tristate_disable(PMUX_PINGRP_GMI_A16_PJ7); + pinmux_tristate_disable(PMUX_PINGRP_GMI_A17_PB0); + pinmux_tristate_disable(PMUX_PINGRP_GMI_A18_PB1); + pinmux_tristate_disable(PMUX_PINGRP_GMI_A19_PK7); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/mach-tegra/tegra114/pinmux.c b/arch/arm/mach-tegra/tegra114/pinmux.c new file mode 100644 index 0000000000..3e5acb93ce --- /dev/null +++ b/arch/arm/mach-tegra/tegra114/pinmux.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define PIN(pin, f0, f1, f2, f3) \ + { \ + .funcs = { \ + PMUX_FUNC_##f0, \ + PMUX_FUNC_##f1, \ + PMUX_FUNC_##f2, \ + PMUX_FUNC_##f3, \ + }, \ + } + +#define PIN_RESERVED {} + +static const struct pmux_pingrp_desc tegra114_pingroups[] = { + /* pin, f0, f1, f2, f3 */ + /* Offset 0x3000 */ + PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_CLK_PY0, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_DIR_PY1, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_NXT_PY2, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_STP_PY3, SPI1, SPI5, UARTD, ULPI), + PIN(DAP3_FS_PP0, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(DAP3_DIN_PP1, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(DAP3_DOUT_PP2, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(DAP3_SCLK_PP3, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(PV0, USB, RSVD2, RSVD3, RSVD4), + PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(SDMMC1_CLK_PZ0, SDMMC1, CLK12, RSVD3, RSVD4), + PIN(SDMMC1_CMD_PZ1, SDMMC1, SPDIF, SPI4, UARTA), + PIN(SDMMC1_DAT3_PY4, SDMMC1, SPDIF, SPI4, UARTA), + PIN(SDMMC1_DAT2_PY5, SDMMC1, PWM0, SPI4, UARTA), + PIN(SDMMC1_DAT1_PY6, SDMMC1, PWM1, SPI4, UARTA), + PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, SPI4, UARTA), + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3068 */ + PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), + PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3110 */ + PIN(HDMI_INT_PN7, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), + PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3164 */ + PIN(UART2_RXD_PC3, IRDA, SPDIF, UARTA, SPI4), + PIN(UART2_TXD_PC2, IRDA, SPDIF, UARTA, SPI4), + PIN(UART2_RTS_N_PJ6, UARTA, UARTB, RSVD3, SPI4), + PIN(UART2_CTS_N_PJ5, UARTA, UARTB, RSVD3, SPI4), + PIN(UART3_TXD_PW6, UARTC, RSVD2, RSVD3, SPI4), + PIN(UART3_RXD_PW7, UARTC, RSVD2, RSVD3, SPI4), + PIN(UART3_CTS_N_PA1, UARTC, SDMMC1, DTV, SPI4), + PIN(UART3_RTS_N_PC0, UARTC, PWM0, DTV, DISPLAYA), + PIN(PU0, OWR, UARTA, RSVD3, RSVD4), + PIN(PU1, RSVD1, UARTA, RSVD3, RSVD4), + PIN(PU2, RSVD1, UARTA, RSVD3, RSVD4), + PIN(PU3, PWM0, UARTA, DISPLAYA, DISPLAYB), + PIN(PU4, PWM1, UARTA, DISPLAYA, DISPLAYB), + PIN(PU5, PWM2, UARTA, DISPLAYA, DISPLAYB), + PIN(PU6, PWM3, UARTA, USB, DISPLAYB), + PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), + PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), + PIN(DAP4_FS_PP4, I2S3, RSVD2, DTV, RSVD4), + PIN(DAP4_DIN_PP5, I2S3, RSVD2, RSVD3, RSVD4), + PIN(DAP4_DOUT_PP6, I2S3, RSVD2, DTV, RSVD4), + PIN(DAP4_SCLK_PP7, I2S3, RSVD2, RSVD3, RSVD4), + PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), + PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), + PIN(GMI_WP_N_PC7, RSVD1, NAND, GMI, GMI_ALT), + PIN(GMI_IORDY_PI5, SDMMC2, RSVD2, GMI, TRACE), + PIN(GMI_WAIT_PI7, SPI4, NAND, GMI, DTV), + PIN(GMI_ADV_N_PK0, RSVD1, NAND, GMI, TRACE), + PIN(GMI_CLK_PK1, SDMMC2, NAND, GMI, TRACE), + PIN(GMI_CS0_N_PJ0, RSVD1, NAND, GMI, USB), + PIN(GMI_CS1_N_PJ2, RSVD1, NAND, GMI, SOC), + PIN(GMI_CS2_N_PK3, SDMMC2, NAND, GMI, TRACE), + PIN(GMI_CS3_N_PK4, SDMMC2, NAND, GMI, GMI_ALT), + PIN(GMI_CS4_N_PK2, USB, NAND, GMI, TRACE), + PIN(GMI_CS6_N_PI3, NAND, NAND_ALT, GMI, SPI4), + PIN(GMI_CS7_N_PI6, NAND, NAND_ALT, GMI, SDMMC2), + PIN(GMI_AD0_PG0, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD1_PG1, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD2_PG2, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD3_PG3, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD4_PG4, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD5_PG5, RSVD1, NAND, GMI, SPI4), + PIN(GMI_AD6_PG6, RSVD1, NAND, GMI, SPI4), + PIN(GMI_AD7_PG7, RSVD1, NAND, GMI, SPI4), + PIN(GMI_AD8_PH0, PWM0, NAND, GMI, DTV), + PIN(GMI_AD9_PH1, PWM1, NAND, GMI, CLDVFS), + PIN(GMI_AD10_PH2, PWM2, NAND, GMI, CLDVFS), + PIN(GMI_AD11_PH3, PWM3, NAND, GMI, USB), + PIN(GMI_AD12_PH4, SDMMC2, NAND, GMI, RSVD4), + PIN(GMI_AD13_PH5, SDMMC2, NAND, GMI, RSVD4), + PIN(GMI_AD14_PH6, SDMMC2, NAND, GMI, DTV), + PIN(GMI_AD15_PH7, SDMMC2, NAND, GMI, DTV), + PIN(GMI_A16_PJ7, UARTD, TRACE, GMI, GMI_ALT), + PIN(GMI_A17_PB0, UARTD, RSVD2, GMI, TRACE), + PIN(GMI_A18_PB1, UARTD, RSVD2, GMI, TRACE), + PIN(GMI_A19_PK7, UARTD, SPI4, GMI, TRACE), + PIN(GMI_WR_N_PI0, RSVD1, NAND, GMI, SPI4), + PIN(GMI_OE_N_PI1, RSVD1, NAND, GMI, SOC), + PIN(GMI_DQS_P_PJ3, SDMMC2, NAND, GMI, TRACE), + PIN(GMI_RST_N_PI4, NAND, NAND_ALT, GMI, RSVD4), + PIN(GEN2_I2C_SCL_PT5, I2C2, RSVD2, GMI, RSVD4), + PIN(GEN2_I2C_SDA_PT6, I2C2, RSVD2, GMI, RSVD4), + PIN(SDMMC4_CLK_PCC4, SDMMC4, RSVD2, GMI, RSVD4), + PIN(SDMMC4_CMD_PT7, SDMMC4, RSVD2, GMI, RSVD4), + PIN(SDMMC4_DAT0_PAA0, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT1_PAA1, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT2_PAA2, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT3_PAA3, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT4_PAA4, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT5_PAA5, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT6_PAA6, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT7_PAA7, SDMMC4, RSVD2, GMI, RSVD4), + PIN_RESERVED, + /* Offset 0x3284 */ + PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, RSVD4), + PIN(PCC1, I2S4, RSVD2, RSVD3, RSVD4), + PIN(PBB0, I2S4, VI, VI_ALT1, VI_ALT3), + PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, RSVD4), + PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, RSVD4), + PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, RSVD4), + PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, RSVD4), + PIN(PBB5, VGP5, DISPLAYA, DISPLAYB, RSVD4), + PIN(PBB6, VGP6, DISPLAYA, DISPLAYB, RSVD4), + PIN(PBB7, I2S4, RSVD2, RSVD3, RSVD4), + PIN(PCC2, I2S4, RSVD2, RSVD3, RSVD4), + PIN(JTAG_RTCK, RTCK, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW0_PR0, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW1_PR1, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW2_PR2, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW3_PR3, KBC, DISPLAYA, RSVD3, DISPLAYB), + PIN(KB_ROW4_PR4, KBC, DISPLAYA, SPI2, DISPLAYB), + PIN(KB_ROW5_PR5, KBC, DISPLAYA, SPI2, DISPLAYB), + PIN(KB_ROW6_PR6, KBC, DISPLAYA, DISPLAYA_ALT, DISPLAYB), + PIN(KB_ROW7_PR7, KBC, RSVD2, CLDVFS, UARTA), + PIN(KB_ROW8_PS0, KBC, RSVD2, CLDVFS, UARTA), + PIN(KB_ROW9_PS1, KBC, RSVD2, RSVD3, UARTA), + PIN(KB_ROW10_PS2, KBC, RSVD2, RSVD3, UARTA), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x32fc */ + PIN(KB_COL0_PQ0, KBC, USB, SPI2, EMC_DLL), + PIN(KB_COL1_PQ1, KBC, RSVD2, SPI2, EMC_DLL), + PIN(KB_COL2_PQ2, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_COL3_PQ3, KBC, DISPLAYA, PWM2, UARTA), + PIN(KB_COL4_PQ4, KBC, OWR, SDMMC3, UARTA), + PIN(KB_COL5_PQ5, KBC, RSVD2, SDMMC1, RSVD4), + PIN(KB_COL6_PQ6, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_COL7_PQ7, KBC, RSVD2, SPI2, RSVD4), + PIN(CLK_32K_OUT_PA0, BLINK, SOC, RSVD3, RSVD4), + PIN(SYS_CLK_REQ_PZ5, SYSCLK, RSVD2, RSVD3, RSVD4), + PIN(CORE_PWR_REQ, PWRON, RSVD2, RSVD3, RSVD4), + PIN(CPU_PWR_REQ, CPU, RSVD2, RSVD3, RSVD4), + PIN(PWR_INT_N, PMI, RSVD2, RSVD3, RSVD4), + PIN(CLK_32K_IN, CLK, RSVD2, RSVD3, RSVD4), + PIN(OWR, OWR, RSVD2, RSVD3, RSVD4), + PIN(DAP1_FS_PN0, I2S0, HDA, GMI, RSVD4), + PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, RSVD4), + PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, RSVD4), + PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, RSVD4), + PIN(CLK1_REQ_PEE2, DAP, DAP1, RSVD3, RSVD4), + PIN(CLK1_OUT_PW4, EXTPERIPH1, DAP2, RSVD3, RSVD4), + PIN(SPDIF_IN_PK6, SPDIF, USB, RSVD3, RSVD4), + PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, RSVD3, RSVD4), + PIN(DAP2_FS_PA2, I2S1, HDA, RSVD3, RSVD4), + PIN(DAP2_DIN_PA4, I2S1, HDA, RSVD3, RSVD4), + PIN(DAP2_DOUT_PA5, I2S1, HDA, RSVD3, RSVD4), + PIN(DAP2_SCLK_PA3, I2S1, HDA, RSVD3, RSVD4), + PIN(DVFS_PWM_PX0, SPI6, CLDVFS, RSVD3, RSVD4), + PIN(GPIO_X1_AUD_PX1, SPI6, RSVD2, RSVD3, RSVD4), + PIN(GPIO_X3_AUD_PX3, SPI6, SPI1, RSVD3, RSVD4), + PIN(DVFS_CLK_PX2, SPI6, CLDVFS, RSVD3, RSVD4), + PIN(GPIO_X4_AUD_PX4, RSVD1, SPI1, SPI2, DAP2), + PIN(GPIO_X5_AUD_PX5, RSVD1, SPI1, SPI2, RSVD4), + PIN(GPIO_X6_AUD_PX6, SPI6, SPI1, SPI2, RSVD4), + PIN(GPIO_X7_AUD_PX7, RSVD1, SPI1, SPI2, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3390 */ + PIN(SDMMC3_CLK_PA6, SDMMC3, RSVD2, RSVD3, SPI3), + PIN(SDMMC3_CMD_PA7, SDMMC3, PWM3, UARTA, SPI3), + PIN(SDMMC3_DAT0_PB7, SDMMC3, RSVD2, RSVD3, SPI3), + PIN(SDMMC3_DAT1_PB6, SDMMC3, PWM2, UARTA, SPI3), + PIN(SDMMC3_DAT2_PB5, SDMMC3, PWM1, DISPLAYA, SPI3), + PIN(SDMMC3_DAT3_PB4, SDMMC3, PWM0, DISPLAYB, SPI3), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x33e0 */ + PIN(HDMI_CEC_PEE3, CEC, SDMMC3, RSVD3, SOC), + PIN(SDMMC1_WP_N_PV3, SDMMC1, CLK12, SPI4, UARTA), + PIN(SDMMC3_CD_N_PV2, SDMMC3, OWR, RSVD3, RSVD4), + PIN(GPIO_W2_AUD_PW2, SPI6, RSVD2, SPI2, I2C1), + PIN(GPIO_W3_AUD_PW3, SPI6, SPI1, SPI2, I2C1), + PIN(USB_VBUS_EN0_PN4, USB, RSVD2, RSVD3, RSVD4), + PIN(USB_VBUS_EN1_PN5, USB, RSVD2, RSVD3, RSVD4), + PIN(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, RSVD2, RSVD3, RSVD4), + PIN(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, RSVD2, RSVD3, RSVD4), + PIN(GMI_CLK_LB, SDMMC2, NAND, GMI, RSVD4), + PIN(RESET_OUT_N, RSVD1, RSVD2, RSVD3, RESET_OUT_N), +}; +const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra114_pingroups; diff --git a/arch/arm/mach-tegra/tegra124/Kconfig b/arch/arm/mach-tegra/tegra124/Kconfig new file mode 100644 index 0000000000..88f627c932 --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/Kconfig @@ -0,0 +1,30 @@ +if TEGRA124 + +choice + prompt "Tegra124 board select" + +config TARGET_JETSON_TK1 + bool "NVIDIA Tegra124 Jetson TK1 board" + +config TARGET_NYAN_BIG + bool "Google/NVIDIA Nyan-big Chrombook" + help + Nyan Big is a Tegra124 clamshell board that is very similar + to venice2, but it has a different panel, the sdcard CD and WP + sense are flipped, and it has a different revision of the AS3722 + PMIC. The retail name is the Acer Chromebook 13 CB5-311-T7NN + (13.3-inch HD, NVIDIA Tegra K1, 2GB). + +config TARGET_VENICE2 + bool "NVIDIA Tegra124 Venice2" + +endchoice + +config SYS_SOC + default "tegra124" + +source "board/nvidia/jetson-tk1/Kconfig" +source "board/nvidia/nyan-big/Kconfig" +source "board/nvidia/venice2/Kconfig" + +endif diff --git a/arch/arm/mach-tegra/tegra124/Makefile b/arch/arm/mach-tegra/tegra124/Makefile new file mode 100644 index 0000000000..ef2da29f30 --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2013-2014 +# NVIDIA Corporation +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SPL_BUILD) += cpu.o + +obj-y += clock.o +obj-y += funcmux.o +obj-y += pinmux.o +obj-y += xusb-padctl.o diff --git a/arch/arm/mach-tegra/tegra124/clock.c b/arch/arm/mach-tegra/tegra124/clock.c new file mode 100644 index 0000000000..fc8bd194dd --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/clock.c @@ -0,0 +1,935 @@ +/* + * (C) Copyright 2013 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Tegra124 Clock control functions */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Clock types that we can use as a source. The Tegra124 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST, + + CLOCK_TYPE_PC2CC3M, + CLOCK_TYPE_PC2CC3S_T, + CLOCK_TYPE_PC2CC3M_T, + CLOCK_TYPE_PC2CC3M_T16, /* PC2CC3M_T, but w/16-bit divisor (I2C) */ + CLOCK_TYPE_MC2CC3P_A, + CLOCK_TYPE_M, + CLOCK_TYPE_MCPTM2C2C3, + CLOCK_TYPE_PC2CC3T_S, + CLOCK_TYPE_AC2CC3P_TS2, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_28}, + + /* Additional clock types on Tegra114+ */ + /* CLOCK_TYPE_PC2CC3M */ + { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_PC2CC3S_T */ + { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(SFROM32KHZ), CLK(NONE), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_PC2CC3M_T */ + { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_PC2CC3M_T, w/16-bit divisor (I2C) */ + { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_MC2CC3P_A */ + { CLK(MEMORY), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(PERIPH), CLK(NONE), CLK(AUDIO), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_M */ + { CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + /* CLOCK_TYPE_MCPTM2C2C3 */ + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(MEMORY2), CLK(CGENERAL2), CLK(CGENERAL3), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_PC2CC3T_S */ + { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(OSC), CLK(NONE), CLK(SFROM32KHZ), CLK(NONE), + MASK_BITS_31_29}, + /* CLOCK_TYPE_AC2CC3P_TS2 */ + { CLK(AUDIO), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3), + CLK(PERIPH), CLK(NONE), CLK(OSC), CLK(SRC2), + MASK_BITS_31_29}, +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PC2CC3M), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PC2CC3S_T), + TYPE(PERIPHC_05h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PC2CC3M_T), + + /* 0x08 */ + TYPE(PERIPHC_08h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PC2CC3M_T16), + TYPE(PERIPHC_I2C5, CLOCK_TYPE_PC2CC3M_T16), + TYPE(PERIPHC_0bh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_0ch, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), + + /* 0x10 */ + TYPE(PERIPHC_10h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_11h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MC2CC3P_A), + TYPE(PERIPHC_13h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_16h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_17h, CLOCK_TYPE_NONE), + + /* 0x18 */ + TYPE(PERIPHC_18h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_1Bh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_1Ch, CLOCK_TYPE_NONE), + TYPE(PERIPHC_HSI, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_UART1, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PC2CC3M_T), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MC2CC3P_A), + TYPE(PERIPHC_21h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_22h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_24h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_25h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PC2CC3M_T16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPTM2C2C3), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_29h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI_SENSOR, CLOCK_TYPE_MC2CC3P_A), + TYPE(PERIPHC_2bh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_2ch, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PC2CC3M_T16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PC2CC3M_T), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_DTV, CLOCK_TYPE_NONE), + + /* 0x38 */ + TYPE(PERIPHC_38h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_39h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_3ah, CLOCK_TYPE_NONE), + TYPE(PERIPHC_3bh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_MSENC, CLOCK_TYPE_MC2CC3P_A), + TYPE(PERIPHC_TSEC, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_3eh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_OSC, CLOCK_TYPE_NONE), + + /* 0x40 */ + TYPE(PERIPHC_40h, CLOCK_TYPE_NONE), /* start with 0x3b0 */ + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PC2CC3T_S), + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PC2CC3M_T16), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PC2CC3M_T), + + /* 0x48 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_49h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PC2CC3S_T), + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x50 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_52h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PC2CC3S_T), + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_55h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_56h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_57h, CLOCK_TYPE_NONE), + + /* 0x58 */ + TYPE(PERIPHC_58h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_59h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_5ah, CLOCK_TYPE_NONE), + TYPE(PERIPHC_5bh, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PC2CC3M_T), + TYPE(PERIPHC_5fh, CLOCK_TYPE_NONE), + + /* 0x60 */ + TYPE(PERIPHC_XUSB_CORE_HOST, CLOCK_TYPE_NONE), + TYPE(PERIPHC_XUSB_FALCON, CLOCK_TYPE_NONE), + TYPE(PERIPHC_XUSB_FS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_XUSB_CORE_DEV, CLOCK_TYPE_NONE), + TYPE(PERIPHC_XUSB_SS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_CILAB, CLOCK_TYPE_NONE), + TYPE(PERIPHC_CILCD, CLOCK_TYPE_NONE), + TYPE(PERIPHC_CILE, CLOCK_TYPE_NONE), + + /* 0x68 */ + TYPE(PERIPHC_DSIA_LP, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DSIB_LP, CLOCK_TYPE_NONE), + TYPE(PERIPHC_ENTROPY, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DVFS_REF, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DVFS_SOC, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TRACECLKIN, CLOCK_TYPE_NONE), + TYPE(PERIPHC_ADX0, CLOCK_TYPE_NONE), + TYPE(PERIPHC_AMX0, CLOCK_TYPE_NONE), + + /* 0x70 */ + TYPE(PERIPHC_EMC_LATENCY, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SOC_THERM, CLOCK_TYPE_NONE), + TYPE(PERIPHC_72h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_73h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_74h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_75h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI_SENSOR2, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C6, CLOCK_TYPE_PC2CC3M_T16), + + /* 0x78 */ + TYPE(PERIPHC_78h, CLOCK_TYPE_NONE), + TYPE(PERIPHC_EMC_DLL, CLOCK_TYPE_MCPTM2C2C3), + TYPE(PERIPHC_HDMI_AUDIO, CLOCK_TYPE_NONE), + TYPE(PERIPHC_CLK72MHZ, CLOCK_TYPE_NONE), + TYPE(PERIPHC_ADX1, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_AMX1, CLOCK_TYPE_AC2CC3P_TS2), + TYPE(PERIPHC_VIC, CLOCK_TYPE_NONE), + TYPE(PERIPHC_7Fh, CLOCK_TYPE_NONE), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(ISPB), + NONE(RESERVED4), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + PERIPHC_SPDIF_IN, + PERIPHC_I2S1, + PERIPHC_I2C1, + NONE(RESERVED13), + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(TCW), + PERIPHC_PWM, + PERIPHC_I2S2, + NONE(RESERVED19), + PERIPHC_VI, + NONE(RESERVED21), + NONE(USBD), + NONE(ISP), + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(FUSE), + + /* 40 */ + NONE(KFUSE), + PERIPHC_SBC1, /* SBCx = SPIx */ + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(XIO), + PERIPHC_SBC3, + PERIPHC_I2C5, + + /* 48 */ + NONE(DSI), + NONE(RESERVED49), + PERIPHC_HSI, + PERIPHC_HDMI, + NONE(CSI), + NONE(RESERVED53), + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(MIPI_CAL), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + NONE(RESERVED60), + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + NONE(RESERVED64), + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(LA), + NONE(TRACECLKIN), + NONE(SOC_THERM), + NONE(DTV), + + /* 80 */ + NONE(RESERVED80), + PERIPHC_I2CSLOW, + NONE(DSIB), + PERIPHC_TSEC, + NONE(RESERVED84), + NONE(RESERVED85), + NONE(RESERVED86), + NONE(EMUCIF), + + /* 88 */ + NONE(RESERVED88), + NONE(XUSB_HOST), + NONE(RESERVED90), + PERIPHC_MSENC, + NONE(RESERVED92), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(XUSB_DEV), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + NONE(V_RESERVED2), + PERIPHC_MSELECT, + NONE(V_RESERVED4), + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 104 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 112 */ + NONE(ATOMICS), + NONE(V_RESERVED17), + NONE(V_RESERVED18), + NONE(V_RESERVED19), + NONE(V_RESERVED20), + NONE(V_RESERVED21), + NONE(V_RESERVED22), + PERIPHC_ACTMON, + + /* 120 */ + NONE(EXTPERIPH1), + NONE(EXTPERIPH2), + NONE(EXTPERIPH3), + NONE(OOB), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(TZRAM), + NONE(SE), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(SATACOLD), + NONE(W_RESERVED2), + NONE(W_RESERVED3), + NONE(W_RESERVED4), + NONE(W_RESERVED5), + NONE(W_RESERVED6), + NONE(W_RESERVED7), + + /* 136 */ + NONE(CEC), + NONE(W_RESERVED9), + NONE(W_RESERVED10), + NONE(W_RESERVED11), + NONE(W_RESERVED12), + NONE(W_RESERVED13), + NONE(XUSB_PADCTL), + NONE(W_RESERVED15), + + /* 144 */ + NONE(W_RESERVED16), + NONE(W_RESERVED17), + NONE(W_RESERVED18), + NONE(W_RESERVED19), + NONE(W_RESERVED20), + NONE(ENTROPY), + NONE(DDS), + NONE(W_RESERVED23), + + /* 152 */ + NONE(DP2), + NONE(AMX0), + NONE(ADX0), + NONE(DVFS), + NONE(XUSB_SS), + NONE(W_RESERVED29), + NONE(W_RESERVED30), + NONE(W_RESERVED31), + + /* X word: 31:0 */ + NONE(SPARE), + NONE(X_RESERVED1), + NONE(X_RESERVED2), + NONE(X_RESERVED3), + NONE(CAM_MCLK), + NONE(CAM_MCLK2), + PERIPHC_I2C6, + NONE(X_RESERVED7), + + /* 168 */ + NONE(X_RESERVED8), + NONE(X_RESERVED9), + NONE(X_RESERVED10), + NONE(VIM2_CLK), + NONE(X_RESERVED12), + NONE(X_RESERVED13), + NONE(EMC_DLL), + NONE(X_RESERVED15), + + /* 176 */ + NONE(HDMI_AUDIO), + NONE(CLK72MHZ), + NONE(VIC), + NONE(X_RESERVED19), + NONE(ADX1), + NONE(DPAUX), + NONE(SOR0), + NONE(X_RESERVED23), + + /* 184 */ + NONE(GPU), + NONE(AMX1), + NONE(X_RESERVED26), + NONE(X_RESERVED27), + NONE(X_RESERVED28), + NONE(X_RESERVED29), + NONE(X_RESERVED30), + NONE(X_RESERVED31), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. Note that Tegra30+ support 3 new higher freqs, but we map back + * to the old T20 freqs. Support for the higher oscillators is TBD. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + if (reg & 1) /* one of the newer freqs */ + printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); + + return reg >> 2; /* Map to most common (T20) freqs */ +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else { + return &clkrst->crc_clk_src[internal_id]; + } +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + if (type == CLOCK_TYPE_PC2CC3M_T16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra124 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED4: + case PERIPH_ID_RESERVED25: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED36: + case PERIPH_ID_RESERVED38: + case PERIPH_ID_RESERVED43: + case PERIPH_ID_RESERVED49: + case PERIPH_ID_RESERVED53: + case PERIPH_ID_RESERVED64: + case PERIPH_ID_RESERVED84: + case PERIPH_ID_RESERVED85: + case PERIPH_ID_RESERVED86: + case PERIPH_ID_RESERVED88: + case PERIPH_ID_RESERVED90: + case PERIPH_ID_RESERVED92: + case PERIPH_ID_RESERVED93: + case PERIPH_ID_RESERVED94: + case PERIPH_ID_V_RESERVED2: + case PERIPH_ID_V_RESERVED4: + case PERIPH_ID_V_RESERVED17: + case PERIPH_ID_V_RESERVED18: + case PERIPH_ID_V_RESERVED19: + case PERIPH_ID_V_RESERVED20: + case PERIPH_ID_V_RESERVED21: + case PERIPH_ID_V_RESERVED22: + case PERIPH_ID_W_RESERVED2: + case PERIPH_ID_W_RESERVED3: + case PERIPH_ID_W_RESERVED4: + case PERIPH_ID_W_RESERVED5: + case PERIPH_ID_W_RESERVED6: + case PERIPH_ID_W_RESERVED7: + case PERIPH_ID_W_RESERVED9: + case PERIPH_ID_W_RESERVED10: + case PERIPH_ID_W_RESERVED11: + case PERIPH_ID_W_RESERVED12: + case PERIPH_ID_W_RESERVED13: + case PERIPH_ID_W_RESERVED15: + case PERIPH_ID_W_RESERVED16: + case PERIPH_ID_W_RESERVED17: + case PERIPH_ID_W_RESERVED18: + case PERIPH_ID_W_RESERVED19: + case PERIPH_ID_W_RESERVED20: + case PERIPH_ID_W_RESERVED23: + case PERIPH_ID_W_RESERVED29: + case PERIPH_ID_W_RESERVED30: + case PERIPH_ID_W_RESERVED31: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + + tegra30_set_up_pllp(); + + /* + * PLLC output frequency set to 600Mhz + * PLLD output frequency set to 925Mhz + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } + + /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */ + writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]); + + /* PLLC_MISC: Set LOCK_ENABLE */ + writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc); + udelay(2); + + /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */ + writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); + udelay(2); +} + +void arch_timer_init(void) +{ + struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE; + u32 freq, val; + + freq = clock_get_rate(CLOCK_ID_OSC); + debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq); + + /* ARM CNTFRQ */ + asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq)); + + /* Only Tegra114+ has the System Counter regs */ + debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq); + writel(freq, &sysctr->cntfid0); + + val = readl(&sysctr->cntcr); + val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG; + writel(val, &sysctr->cntcr); + debug("%s: TSC CNTCR = 0x%08X\n", __func__, val); +} + +#define PLLE_SS_CNTL 0x68 +#define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24) +#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) +#define PLLE_SS_CNTL_SSCINVERT (1 << 15) +#define PLLE_SS_CNTL_SSCCENTER (1 << 14) +#define PLLE_SS_CNTL_SSCBYP (1 << 12) +#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) +#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) +#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) + +#define PLLE_BASE 0x0e8 +#define PLLE_BASE_ENABLE (1 << 30) +#define PLLE_BASE_LOCK_OVERRIDE (1 << 29) +#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) +#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) +#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) + +#define PLLE_MISC 0x0ec +#define PLLE_MISC_IDDQ_SWCTL (1 << 14) +#define PLLE_MISC_IDDQ_OVERRIDE (1 << 13) +#define PLLE_MISC_LOCK_ENABLE (1 << 9) +#define PLLE_MISC_PTS (1 << 8) +#define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4) +#define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2) + +#define PLLE_AUX 0x48c +#define PLLE_AUX_SEQ_ENABLE (1 << 24) +#define PLLE_AUX_ENABLE_SWCTL (1 << 4) + +int tegra_plle_enable(void) +{ + unsigned int m = 1, n = 200, cpcon = 13; + u32 value; + + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value &= ~PLLE_BASE_LOCK_OVERRIDE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX); + value |= PLLE_AUX_ENABLE_SWCTL; + value &= ~PLLE_AUX_SEQ_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX); + + udelay(1); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value |= PLLE_MISC_IDDQ_SWCTL; + value &= ~PLLE_MISC_IDDQ_OVERRIDE; + value |= PLLE_MISC_LOCK_ENABLE; + value |= PLLE_MISC_PTS; + value |= PLLE_MISC_VREG_BG_CTRL(3); + value |= PLLE_MISC_VREG_CTRL(2); + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + udelay(5); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | + PLLE_SS_CNTL_BYPASS_SS; + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value &= ~PLLE_BASE_PLDIV_CML(0xf); + value &= ~PLLE_BASE_NDIV(0xff); + value &= ~PLLE_BASE_MDIV(0xff); + value |= PLLE_BASE_PLDIV_CML(cpcon); + value |= PLLE_BASE_NDIV(n); + value |= PLLE_BASE_MDIV(m); + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + udelay(1); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value |= PLLE_BASE_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + /* wait for lock */ + udelay(300); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value &= ~PLLE_SS_CNTL_SSCINVERT; + value &= ~PLLE_SS_CNTL_SSCCENTER; + + value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f); + value &= ~PLLE_SS_CNTL_SSCINC(0xff); + value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); + + value |= PLLE_SS_CNTL_SSCINCINTR(0x20); + value |= PLLE_SS_CNTL_SSCINC(0x01); + value |= PLLE_SS_CNTL_SSCMAX(0x25); + + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value &= ~PLLE_SS_CNTL_SSCBYP; + value &= ~PLLE_SS_CNTL_BYPASS_SS; + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + udelay(1); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value &= ~PLLE_SS_CNTL_INTERP_RESET; + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + udelay(1); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c new file mode 100644 index 0000000000..974f203f12 --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/cpu.c @@ -0,0 +1,265 @@ +/* + * (C) Copyright 2013 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../cpu.h" + +/* Tegra124-specific CPU init code */ + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("enable_cpu_power_rail entry\n"); + + /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */ + pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6); + pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SDA_PZ7); + + pmic_enable_cpu_vdd(); + + /* + * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz), + * set it for 5ms as per SysEng (102MHz*5ms = 510000 (7C830h). + */ + writel(0x7C830, &pmc->pmc_cpupwrgood_timer); + + /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */ + clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL); + setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE); +} + +static void enable_cpu_clocks(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("enable_cpu_clocks entry\n"); + + /* Wait for PLL-X to lock */ + do { + reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + debug("%s: PLLX base = 0x%08X\n", __func__, reg); + } while ((reg & PLL_LOCK_MASK) == 0); + + debug("%s: PLLX locked, delay for stable clocks\n", __func__); + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + debug("%s: Setting CCLK_BURST and DIVIDER\n", __func__); + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + + debug("%s: Enabling clock to all CPUs\n", __func__); + /* Enable the clock to all CPUs */ + reg = CLR_CPU3_CLK_STP | CLR_CPU2_CLK_STP | CLR_CPU1_CLK_STP | + CLR_CPU0_CLK_STP; + writel(reg, &clkrst->crc_clk_cpu_cmplx_clr); + + debug("%s: Enabling main CPU complex clocks\n", __func__); + /* Always enable the main CPU complex clocks */ + clock_enable(PERIPH_ID_CPU); + clock_enable(PERIPH_ID_CPULP); + clock_enable(PERIPH_ID_CPUG); + + debug("%s: Done\n", __func__); +} + +static void remove_cpu_resets(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + debug("remove_cpu_resets entry\n"); + + /* Take the slow and fast partitions out of reset */ + reg = CLR_NONCPURESET; + writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); + writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); + + /* Clear the SW-controlled reset of the slow cluster */ + reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | + CLR_L2RESET | CLR_PRESETDBG; + writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr); + + /* Clear the SW-controlled reset of the fast cluster */ + reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 | + CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 | + CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 | + CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3 | + CLR_L2RESET | CLR_PRESETDBG; + writel(reg, &clkrst->crc_rst_cpug_cmplx_clr); +} + +/** + * The Tegra124 requires some special clock initialization, including setting up + * the DVC I2C, turning on MSELECT and selecting the G CPU cluster + */ +void tegra124_init_clocks(void) +{ + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 val; + + debug("tegra124_init_clocks entry\n"); + + /* Set active CPU cluster to G */ + clrbits_le32(&flow->cluster_control, 1); + + /* Change the oscillator drive strength */ + val = readl(&clkrst->crc_osc_ctrl); + val &= ~OSC_XOFS_MASK; + val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); + writel(val, &clkrst->crc_osc_ctrl); + + /* Update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot */ + val = readl(&pmc->pmc_osc_edpd_over); + val &= ~PMC_XOFS_MASK; + val |= (OSC_DRIVE_STRENGTH << PMC_XOFS_SHIFT); + writel(val, &pmc->pmc_osc_edpd_over); + + /* Set HOLD_CKE_LOW_EN to 1 */ + setbits_le32(&pmc->pmc_cntrl2, HOLD_CKE_LOW_EN); + + debug("Setting up PLLX\n"); + init_pllx(); + + val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Enable clocks to required peripherals. TBD - minimize this list */ + debug("Enabling clocks\n"); + + clock_set_enable(PERIPH_ID_CACHE2, 1); + clock_set_enable(PERIPH_ID_GPIO, 1); + clock_set_enable(PERIPH_ID_TMR, 1); + clock_set_enable(PERIPH_ID_CPU, 1); + clock_set_enable(PERIPH_ID_EMC, 1); + clock_set_enable(PERIPH_ID_I2C5, 1); + clock_set_enable(PERIPH_ID_APBDMA, 1); + clock_set_enable(PERIPH_ID_MEM, 1); + clock_set_enable(PERIPH_ID_CORESIGHT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_DVFS, 1); + + /* + * Set MSELECT clock source as PLLP (00), and ask for a clock + * divider that would set the MSELECT clock at 102MHz for a + * PLLP base of 408MHz. + */ + clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, + CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); + + /* Give clock time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + + /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ + clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); + + /* Give clock time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + + /* Take required peripherals out of reset */ + debug("Taking periphs out of reset\n"); + reset_set_enable(PERIPH_ID_CACHE2, 0); + reset_set_enable(PERIPH_ID_GPIO, 0); + reset_set_enable(PERIPH_ID_TMR, 0); + reset_set_enable(PERIPH_ID_COP, 0); + reset_set_enable(PERIPH_ID_EMC, 0); + reset_set_enable(PERIPH_ID_I2C5, 0); + reset_set_enable(PERIPH_ID_APBDMA, 0); + reset_set_enable(PERIPH_ID_MEM, 0); + reset_set_enable(PERIPH_ID_CORESIGHT, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); + reset_set_enable(PERIPH_ID_DVFS, 0); + + debug("tegra124_init_clocks exit\n"); +} + +static bool is_partition_powered(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + /* Get power gate status */ + reg = readl(&pmc->pmc_pwrgate_status); + return !!(reg & (1 << partid)); +} + +static void power_partition(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("%s: part ID = %08X\n", __func__, partid); + /* Is the partition already on? */ + if (!is_partition_powered(partid)) { + /* No, toggle the partition power state (OFF -> ON) */ + debug("power_partition, toggling state\n"); + writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_partition_powered(partid)) + ; + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + } +} + +void powerup_cpus(void) +{ + debug("powerup_cpus entry\n"); + + /* We boot to the fast cluster */ + debug("powerup_cpus entry: G cluster\n"); + + /* Power up the fast cluster rail partition */ + debug("powerup_cpus: CRAIL\n"); + power_partition(CRAIL); + + /* Power up the fast cluster non-CPU partition */ + debug("powerup_cpus: C0NC\n"); + power_partition(C0NC); + + /* Power up the fast cluster CPU0 partition */ + debug("powerup_cpus: CE0\n"); + power_partition(CE0); + + debug("powerup_cpus: done\n"); +} + +void start_cpu(u32 reset_vector) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + + tegra124_init_clocks(); + + /* Set power-gating timer multiplier */ + writel((MULT_8 << TIMER_MULT_SHIFT) | (MULT_8 << TIMER_MULT_CPU_SHIFT), + &pmc->pmc_pwrgate_timer_mult); + + enable_cpu_power_rail(); + enable_cpu_clocks(); + clock_enable_coresight(1); + remove_cpu_resets(); + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + powerup_cpus(); + debug("start_cpu exit, should continue @ reset_vector\n"); +} diff --git a/arch/arm/mach-tegra/tegra124/funcmux.c b/arch/arm/mach-tegra/tegra124/funcmux.c new file mode 100644 index 0000000000..cced787e6b --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/funcmux.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2013 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Tegra124 high-level function multiplexing */ + +#include +#include +#include +#include + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART4: + switch (config) { + case FUNCMUX_UART4_GPIO: /* TXD,RXD,CTS,RTS */ + pinmux_set_func(PMUX_PINGRP_PJ7, PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_PB0, PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_PB1, PMUX_FUNC_UARTD); + pinmux_set_func(PMUX_PINGRP_PK7, PMUX_FUNC_UARTD); + + pinmux_set_io(PMUX_PINGRP_PJ7, PMUX_PIN_OUTPUT); + pinmux_set_io(PMUX_PINGRP_PB0, PMUX_PIN_INPUT); + pinmux_set_io(PMUX_PINGRP_PB1, PMUX_PIN_INPUT); + pinmux_set_io(PMUX_PINGRP_PK7, PMUX_PIN_OUTPUT); + + pinmux_tristate_disable(PMUX_PINGRP_PJ7); + pinmux_tristate_disable(PMUX_PINGRP_PB0); + pinmux_tristate_disable(PMUX_PINGRP_PB1); + pinmux_tristate_disable(PMUX_PINGRP_PK7); + break; + } + break; + + case PERIPH_ID_UART1: + switch (config) { + case FUNCMUX_UART1_KBC: + pinmux_set_func(PMUX_PINGRP_KB_ROW9_PS1, + PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_KB_ROW10_PS2, + PMUX_FUNC_UARTA); + + pinmux_set_io(PMUX_PINGRP_KB_ROW9_PS1, PMUX_PIN_OUTPUT); + pinmux_set_io(PMUX_PINGRP_KB_ROW10_PS2, PMUX_PIN_INPUT); + + pinmux_tristate_disable(PMUX_PINGRP_KB_ROW9_PS1); + pinmux_tristate_disable(PMUX_PINGRP_KB_ROW10_PS2); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/mach-tegra/tegra124/pinmux.c b/arch/arm/mach-tegra/tegra124/pinmux.c new file mode 100644 index 0000000000..c6685eaae1 --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/pinmux.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define PIN(pin, f0, f1, f2, f3) \ + { \ + .funcs = { \ + PMUX_FUNC_##f0, \ + PMUX_FUNC_##f1, \ + PMUX_FUNC_##f2, \ + PMUX_FUNC_##f3, \ + }, \ + } + +#define PIN_RESERVED {} + +static const struct pmux_pingrp_desc tegra124_pingroups[] = { + /* pin, f0, f1, f2, f3 */ + /* Offset 0x3000 */ + PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_CLK_PY0, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_DIR_PY1, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_NXT_PY2, SPI1, SPI5, UARTD, ULPI), + PIN(ULPI_STP_PY3, SPI1, SPI5, UARTD, ULPI), + PIN(DAP3_FS_PP0, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(DAP3_DIN_PP1, I2S2, SPI5, DISPLAYA, DISPLAYB), + PIN(DAP3_DOUT_PP2, I2S2, SPI5, DISPLAYA, RSVD4), + PIN(DAP3_SCLK_PP3, I2S2, SPI5, RSVD3, DISPLAYB), + PIN(PV0, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(SDMMC1_CLK_PZ0, SDMMC1, CLK12, RSVD3, RSVD4), + PIN(SDMMC1_CMD_PZ1, SDMMC1, SPDIF, SPI4, UARTA), + PIN(SDMMC1_DAT3_PY4, SDMMC1, SPDIF, SPI4, UARTA), + PIN(SDMMC1_DAT2_PY5, SDMMC1, PWM0, SPI4, UARTA), + PIN(SDMMC1_DAT1_PY6, SDMMC1, PWM1, SPI4, UARTA), + PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, SPI4, UARTA), + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3068 */ + PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), + PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3110 */ + PIN(HDMI_INT_PN7, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), + PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3164 */ + PIN(UART2_RXD_PC3, IRDA, SPDIF, UARTA, SPI4), + PIN(UART2_TXD_PC2, IRDA, SPDIF, UARTA, SPI4), + PIN(UART2_RTS_N_PJ6, UARTA, UARTB, GMI, SPI4), + PIN(UART2_CTS_N_PJ5, UARTA, UARTB, GMI, SPI4), + PIN(UART3_TXD_PW6, UARTC, RSVD2, GMI, SPI4), + PIN(UART3_RXD_PW7, UARTC, RSVD2, GMI, SPI4), + PIN(UART3_CTS_N_PA1, UARTC, SDMMC1, DTV, GMI), + PIN(UART3_RTS_N_PC0, UARTC, PWM0, DTV, GMI), + PIN(PU0, OWR, UARTA, GMI, RSVD4), + PIN(PU1, RSVD1, UARTA, GMI, RSVD4), + PIN(PU2, RSVD1, UARTA, GMI, RSVD4), + PIN(PU3, PWM0, UARTA, GMI, DISPLAYB), + PIN(PU4, PWM1, UARTA, GMI, DISPLAYB), + PIN(PU5, PWM2, UARTA, GMI, DISPLAYB), + PIN(PU6, PWM3, UARTA, RSVD3, GMI), + PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), + PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), + PIN(DAP4_FS_PP4, I2S3, GMI, DTV, RSVD4), + PIN(DAP4_DIN_PP5, I2S3, GMI, RSVD3, RSVD4), + PIN(DAP4_DOUT_PP6, I2S3, GMI, DTV, RSVD4), + PIN(DAP4_SCLK_PP7, I2S3, GMI, RSVD3, RSVD4), + PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), + PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), + PIN(PC7, RSVD1, RSVD2, GMI, GMI_ALT), + PIN(PI5, SDMMC2, RSVD2, GMI, RSVD4), + PIN(PI7, RSVD1, TRACE, GMI, DTV), + PIN(PK0, RSVD1, SDMMC3, GMI, SOC), + PIN(PK1, SDMMC2, TRACE, GMI, RSVD4), + PIN(PJ0, RSVD1, RSVD2, GMI, USB), + PIN(PJ2, RSVD1, RSVD2, GMI, SOC), + PIN(PK3, SDMMC2, TRACE, GMI, CCLA), + PIN(PK4, SDMMC2, RSVD2, GMI, GMI_ALT), + PIN(PK2, RSVD1, RSVD2, GMI, RSVD4), + PIN(PI3, RSVD1, RSVD2, GMI, SPI4), + PIN(PI6, RSVD1, RSVD2, GMI, SDMMC2), + PIN(PG0, RSVD1, RSVD2, GMI, RSVD4), + PIN(PG1, RSVD1, RSVD2, GMI, RSVD4), + PIN(PG2, RSVD1, TRACE, GMI, RSVD4), + PIN(PG3, RSVD1, TRACE, GMI, RSVD4), + PIN(PG4, RSVD1, TMDS, GMI, SPI4), + PIN(PG5, RSVD1, RSVD2, GMI, SPI4), + PIN(PG6, RSVD1, RSVD2, GMI, SPI4), + PIN(PG7, RSVD1, RSVD2, GMI, SPI4), + PIN(PH0, PWM0, TRACE, GMI, DTV), + PIN(PH1, PWM1, TMDS, GMI, DISPLAYA), + PIN(PH2, PWM2, TMDS, GMI, CLDVFS), + PIN(PH3, PWM3, SPI4, GMI, CLDVFS), + PIN(PH4, SDMMC2, RSVD2, GMI, RSVD4), + PIN(PH5, SDMMC2, RSVD2, GMI, RSVD4), + PIN(PH6, SDMMC2, TRACE, GMI, DTV), + PIN(PH7, SDMMC2, TRACE, GMI, DTV), + PIN(PJ7, UARTD, RSVD2, GMI, GMI_ALT), + PIN(PB0, UARTD, RSVD2, GMI, RSVD4), + PIN(PB1, UARTD, RSVD2, GMI, RSVD4), + PIN(PK7, UARTD, RSVD2, GMI, RSVD4), + PIN(PI0, RSVD1, RSVD2, GMI, RSVD4), + PIN(PI1, RSVD1, RSVD2, GMI, RSVD4), + PIN(PI2, SDMMC2, TRACE, GMI, RSVD4), + PIN(PI4, SPI4, TRACE, GMI, DISPLAYA), + PIN(GEN2_I2C_SCL_PT5, I2C2, RSVD2, GMI, RSVD4), + PIN(GEN2_I2C_SDA_PT6, I2C2, RSVD2, GMI, RSVD4), + PIN(SDMMC4_CLK_PCC4, SDMMC4, RSVD2, GMI, RSVD4), + PIN(SDMMC4_CMD_PT7, SDMMC4, RSVD2, GMI, RSVD4), + PIN(SDMMC4_DAT0_PAA0, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT1_PAA1, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT2_PAA2, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT3_PAA3, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT4_PAA4, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT5_PAA5, SDMMC4, SPI3, RSVD3, RSVD4), + PIN(SDMMC4_DAT6_PAA6, SDMMC4, SPI3, GMI, RSVD4), + PIN(SDMMC4_DAT7_PAA7, SDMMC4, RSVD2, GMI, RSVD4), + PIN_RESERVED, + /* Offset 0x3284 */ + PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, SDMMC2), + PIN(PCC1, I2S4, RSVD2, RSVD3, SDMMC2), + PIN(PBB0, VGP6, VIMCLK2, SDMMC2, VIMCLK2_ALT), + PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, SDMMC2), + PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, SDMMC2), + PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, SDMMC2), + PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, SDMMC2), + PIN(PBB5, VGP5, DISPLAYA, RSVD3, SDMMC2), + PIN(PBB6, I2S4, RSVD2, DISPLAYB, SDMMC2), + PIN(PBB7, I2S4, RSVD2, RSVD3, SDMMC2), + PIN(PCC2, I2S4, RSVD2, SDMMC3, SDMMC2), + PIN(JTAG_RTCK, RTCK, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW0_PR0, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW1_PR1, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW2_PR2, KBC, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW3_PR3, KBC, DISPLAYA, SYS, DISPLAYB), + PIN(KB_ROW4_PR4, KBC, DISPLAYA, RSVD3, DISPLAYB), + PIN(KB_ROW5_PR5, KBC, DISPLAYA, RSVD3, DISPLAYB), + PIN(KB_ROW6_PR6, KBC, DISPLAYA, DISPLAYA_ALT, DISPLAYB), + PIN(KB_ROW7_PR7, KBC, RSVD2, CLDVFS, UARTA), + PIN(KB_ROW8_PS0, KBC, RSVD2, CLDVFS, UARTA), + PIN(KB_ROW9_PS1, KBC, RSVD2, RSVD3, UARTA), + PIN(KB_ROW10_PS2, KBC, RSVD2, RSVD3, UARTA), + PIN(KB_ROW11_PS3, KBC, RSVD2, RSVD3, IRDA), + PIN(KB_ROW12_PS4, KBC, RSVD2, RSVD3, IRDA), + PIN(KB_ROW13_PS5, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_ROW14_PS6, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_ROW15_PS7, KBC, SOC, RSVD3, RSVD4), + PIN(KB_COL0_PQ0, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_COL1_PQ1, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_COL2_PQ2, KBC, RSVD2, SPI2, RSVD4), + PIN(KB_COL3_PQ3, KBC, DISPLAYA, PWM2, UARTA), + PIN(KB_COL4_PQ4, KBC, OWR, SDMMC3, UARTA), + PIN(KB_COL5_PQ5, KBC, RSVD2, SDMMC3, RSVD4), + PIN(KB_COL6_PQ6, KBC, RSVD2, SPI2, UARTD), + PIN(KB_COL7_PQ7, KBC, RSVD2, SPI2, UARTD), + PIN(CLK_32K_OUT_PA0, BLINK, SOC, RSVD3, RSVD4), + PIN_RESERVED, + /* Offset 0x3324 */ + PIN(CORE_PWR_REQ, PWRON, RSVD2, RSVD3, RSVD4), + PIN(CPU_PWR_REQ, CPU, RSVD2, RSVD3, RSVD4), + PIN(PWR_INT_N, PMI, RSVD2, RSVD3, RSVD4), + PIN(CLK_32K_IN, CLK, RSVD2, RSVD3, RSVD4), + PIN(OWR, OWR, RSVD2, RSVD3, RSVD4), + PIN(DAP1_FS_PN0, I2S0, HDA, GMI, RSVD4), + PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, RSVD4), + PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, SATA), + PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, RSVD4), + PIN(DAP_MCLK1_REQ_PEE2, DAP, DAP1, SATA, RSVD4), + PIN(DAP_MCLK1_PW4, EXTPERIPH1, DAP2, RSVD3, RSVD4), + PIN(SPDIF_IN_PK6, SPDIF, RSVD2, RSVD3, I2C3), + PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, RSVD3, I2C3), + PIN(DAP2_FS_PA2, I2S1, HDA, GMI, RSVD4), + PIN(DAP2_DIN_PA4, I2S1, HDA, GMI, RSVD4), + PIN(DAP2_DOUT_PA5, I2S1, HDA, GMI, RSVD4), + PIN(DAP2_SCLK_PA3, I2S1, HDA, GMI, RSVD4), + PIN(DVFS_PWM_PX0, SPI6, CLDVFS, GMI, RSVD4), + PIN(GPIO_X1_AUD_PX1, SPI6, RSVD2, GMI, RSVD4), + PIN(GPIO_X3_AUD_PX3, SPI6, SPI1, GMI, RSVD4), + PIN(DVFS_CLK_PX2, SPI6, CLDVFS, GMI, RSVD4), + PIN(GPIO_X4_AUD_PX4, GMI, SPI1, SPI2, DAP2), + PIN(GPIO_X5_AUD_PX5, GMI, SPI1, SPI2, RSVD4), + PIN(GPIO_X6_AUD_PX6, SPI6, SPI1, SPI2, GMI), + PIN(GPIO_X7_AUD_PX7, RSVD1, SPI1, SPI2, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3390 */ + PIN(SDMMC3_CLK_PA6, SDMMC3, RSVD2, RSVD3, SPI3), + PIN(SDMMC3_CMD_PA7, SDMMC3, PWM3, UARTA, SPI3), + PIN(SDMMC3_DAT0_PB7, SDMMC3, RSVD2, RSVD3, SPI3), + PIN(SDMMC3_DAT1_PB6, SDMMC3, PWM2, UARTA, SPI3), + PIN(SDMMC3_DAT2_PB5, SDMMC3, PWM1, DISPLAYA, SPI3), + PIN(SDMMC3_DAT3_PB4, SDMMC3, PWM0, DISPLAYB, SPI3), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x33bc */ + PIN(PEX_L0_RST_N_PDD1, PE0, RSVD2, RSVD3, RSVD4), + PIN(PEX_L0_CLKREQ_N_PDD2, PE0, RSVD2, RSVD3, RSVD4), + PIN(PEX_WAKE_N_PDD3, PE, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + /* Offset 0x33cc */ + PIN(PEX_L1_RST_N_PDD5, PE1, RSVD2, RSVD3, RSVD4), + PIN(PEX_L1_CLKREQ_N_PDD6, PE1, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x33e0 */ + PIN(HDMI_CEC_PEE3, CEC, RSVD2, RSVD3, RSVD4), + PIN(SDMMC1_WP_N_PV3, SDMMC1, CLK12, SPI4, UARTA), + PIN(SDMMC3_CD_N_PV2, SDMMC3, OWR, RSVD3, RSVD4), + PIN(GPIO_W2_AUD_PW2, SPI6, RSVD2, SPI2, I2C1), + PIN(GPIO_W3_AUD_PW3, SPI6, SPI1, SPI2, I2C1), + PIN(USB_VBUS_EN0_PN4, USB, RSVD2, RSVD3, RSVD4), + PIN(USB_VBUS_EN1_PN5, USB, RSVD2, RSVD3, RSVD4), + PIN(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, RSVD2, RSVD3, RSVD4), + PIN(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, RSVD2, RSVD3, RSVD4), + PIN(GMI_CLK_LB, SDMMC2, RSVD2, GMI, RSVD4), + PIN(RESET_OUT_N, RSVD1, RSVD2, RSVD3, RESET_OUT_N), + PIN(KB_ROW16_PT0, KBC, RSVD2, RSVD3, UARTC), + PIN(KB_ROW17_PT1, KBC, RSVD2, RSVD3, UARTC), + PIN(USB_VBUS_EN2_PFF1, USB, RSVD2, RSVD3, RSVD4), + PIN(PFF2, SATA, RSVD2, RSVD3, RSVD4), + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + PIN_RESERVED, + /* Offset 0x3430 */ + PIN(DP_HPD_PFF0, DP, RSVD2, RSVD3, RSVD4), +}; +const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra124_pingroups; diff --git a/arch/arm/mach-tegra/tegra124/xusb-padctl.c b/arch/arm/mach-tegra/tegra124/xusb-padctl.c new file mode 100644 index 0000000000..43af883f2c --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/xusb-padctl.c @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#define XUSB_PADCTL_ELPG_PROGRAM 0x01c +#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) +#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) +#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) + +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) + +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) +#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) + +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) +#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) + +#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 +#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) +#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) + +enum tegra124_function { + TEGRA124_FUNC_SNPS, + TEGRA124_FUNC_XUSB, + TEGRA124_FUNC_UART, + TEGRA124_FUNC_PCIE, + TEGRA124_FUNC_USB3, + TEGRA124_FUNC_SATA, + TEGRA124_FUNC_RSVD, +}; + +static const char *const tegra124_functions[] = { + "snps", + "xusb", + "uart", + "pcie", + "usb3", + "sata", + "rsvd", +}; + +static const unsigned int tegra124_otg_functions[] = { + TEGRA124_FUNC_SNPS, + TEGRA124_FUNC_XUSB, + TEGRA124_FUNC_UART, + TEGRA124_FUNC_RSVD, +}; + +static const unsigned int tegra124_usb_functions[] = { + TEGRA124_FUNC_SNPS, + TEGRA124_FUNC_XUSB, +}; + +static const unsigned int tegra124_pci_functions[] = { + TEGRA124_FUNC_PCIE, + TEGRA124_FUNC_USB3, + TEGRA124_FUNC_SATA, + TEGRA124_FUNC_RSVD, +}; + +struct tegra_xusb_padctl_lane { + const char *name; + + unsigned int offset; + unsigned int shift; + unsigned int mask; + unsigned int iddq; + + const unsigned int *funcs; + unsigned int num_funcs; +}; + +#define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \ + { \ + .name = _name, \ + .offset = _offset, \ + .shift = _shift, \ + .mask = _mask, \ + .iddq = _iddq, \ + .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \ + .funcs = tegra124_##_funcs##_functions, \ + } + +static const struct tegra_xusb_padctl_lane tegra124_lanes[] = { + TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg), + TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg), + TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg), + TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb), + TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb), + TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb), + TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci), + TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci), + TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci), + TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci), + TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci), + TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci), +}; + +struct tegra_xusb_phy_ops { + int (*prepare)(struct tegra_xusb_phy *phy); + int (*enable)(struct tegra_xusb_phy *phy); + int (*disable)(struct tegra_xusb_phy *phy); + int (*unprepare)(struct tegra_xusb_phy *phy); +}; + +struct tegra_xusb_phy { + const struct tegra_xusb_phy_ops *ops; + + struct tegra_xusb_padctl *padctl; +}; + +struct tegra_xusb_padctl_pin { + const struct tegra_xusb_padctl_lane *lane; + + unsigned int func; + int iddq; +}; + +#define MAX_GROUPS 3 +#define MAX_PINS 6 + +struct tegra_xusb_padctl_group { + const char *name; + + const char *pins[MAX_PINS]; + unsigned int num_pins; + + const char *func; + int iddq; +}; + +struct tegra_xusb_padctl_config { + const char *name; + + struct tegra_xusb_padctl_group groups[MAX_GROUPS]; + unsigned int num_groups; +}; + +struct tegra_xusb_padctl { + struct fdt_resource regs; + + unsigned int enable; + + struct tegra_xusb_phy phys[2]; + + const struct tegra_xusb_padctl_lane *lanes; + unsigned int num_lanes; + + const char *const *functions; + unsigned int num_functions; + + struct tegra_xusb_padctl_config config; +}; + +static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, + unsigned long offset) +{ + return readl(padctl->regs.start + offset); +} + +static inline void padctl_writel(struct tegra_xusb_padctl *padctl, + u32 value, unsigned long offset) +{ + writel(value, padctl->regs.start + offset); +} + +static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) +{ + u32 value; + + if (padctl->enable++ > 0) + return 0; + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + udelay(100); + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + udelay(100); + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + return 0; +} + +static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) +{ + u32 value; + + if (padctl->enable == 0) { + error("tegra-xusb-padctl: unbalanced enable/disable"); + return 0; + } + + if (--padctl->enable > 0) + return 0; + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + udelay(100); + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + udelay(100); + + value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); + value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; + padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); + + return 0; +} + +static int phy_prepare(struct tegra_xusb_phy *phy) +{ + return tegra_xusb_padctl_enable(phy->padctl); +} + +static int phy_unprepare(struct tegra_xusb_phy *phy) +{ + return tegra_xusb_padctl_disable(phy->padctl); +} + +static int pcie_phy_enable(struct tegra_xusb_phy *phy) +{ + struct tegra_xusb_padctl *padctl = phy->padctl; + int err = -ETIMEDOUT; + unsigned long start; + u32 value; + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); + value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | + XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | + XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + + start = get_timer(0); + + while (get_timer(start) < 50) { + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { + err = 0; + break; + } + } + + return err; +} + +static int pcie_phy_disable(struct tegra_xusb_phy *phy) +{ + struct tegra_xusb_padctl *padctl = phy->padctl; + u32 value; + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); + + return 0; +} + +static int sata_phy_enable(struct tegra_xusb_phy *phy) +{ + struct tegra_xusb_padctl *padctl = phy->padctl; + int err = -ETIMEDOUT; + unsigned long start; + u32 value; + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; + value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; + value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + start = get_timer(0); + + while (get_timer(start) < 50) { + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { + err = 0; + break; + } + } + + return err; +} + +static int sata_phy_disable(struct tegra_xusb_phy *phy) +{ + struct tegra_xusb_padctl *padctl = phy->padctl; + u32 value; + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; + value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); + + value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); + value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; + value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; + padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); + + return 0; +} + +static const struct tegra_xusb_phy_ops pcie_phy_ops = { + .prepare = phy_prepare, + .enable = pcie_phy_enable, + .disable = pcie_phy_disable, + .unprepare = phy_unprepare, +}; + +static const struct tegra_xusb_phy_ops sata_phy_ops = { + .prepare = phy_prepare, + .enable = sata_phy_enable, + .disable = sata_phy_disable, + .unprepare = phy_unprepare, +}; + +static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) { + .phys = { + [0] = { + .ops = &pcie_phy_ops, + }, + [1] = { + .ops = &sata_phy_ops, + }, + }, +}; + +static const struct tegra_xusb_padctl_lane * +tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name) +{ + unsigned int i; + + for (i = 0; i < padctl->num_lanes; i++) + if (strcmp(name, padctl->lanes[i].name) == 0) + return &padctl->lanes[i]; + + return NULL; +} + +static int +tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_group *group, + const void *fdt, int node) +{ + unsigned int i; + int len, err; + + group->name = fdt_get_name(fdt, node, &len); + + len = fdt_count_strings(fdt, node, "nvidia,lanes"); + if (len < 0) { + error("tegra-xusb-padctl: failed to parse \"nvidia,lanes\" property"); + return -EINVAL; + } + + group->num_pins = len; + + for (i = 0; i < group->num_pins; i++) { + err = fdt_get_string_index(fdt, node, "nvidia,lanes", i, + &group->pins[i]); + if (err < 0) { + error("tegra-xusb-padctl: failed to read string from \"nvidia,lanes\" property"); + return -EINVAL; + } + } + + group->num_pins = len; + + err = fdt_get_string(fdt, node, "nvidia,function", &group->func); + if (err < 0) { + error("tegra-xusb-padctl: failed to parse \"nvidia,func\" property"); + return -EINVAL; + } + + group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); + + return 0; +} + +static int tegra_xusb_padctl_find_function(struct tegra_xusb_padctl *padctl, + const char *name) +{ + unsigned int i; + + for (i = 0; i < padctl->num_functions; i++) + if (strcmp(name, padctl->functions[i]) == 0) + return i; + + return -ENOENT; +} + +static int +tegra_xusb_padctl_lane_find_function(struct tegra_xusb_padctl *padctl, + const struct tegra_xusb_padctl_lane *lane, + const char *name) +{ + unsigned int i; + int func; + + func = tegra_xusb_padctl_find_function(padctl, name); + if (func < 0) + return func; + + for (i = 0; i < lane->num_funcs; i++) + if (lane->funcs[i] == func) + return i; + + return -ENOENT; +} + +static int +tegra_xusb_padctl_group_apply(struct tegra_xusb_padctl *padctl, + const struct tegra_xusb_padctl_group *group) +{ + unsigned int i; + + for (i = 0; i < group->num_pins; i++) { + const struct tegra_xusb_padctl_lane *lane; + unsigned int func; + u32 value; + + lane = tegra_xusb_padctl_find_lane(padctl, group->pins[i]); + if (!lane) { + error("tegra-xusb-padctl: no lane for pin %s", + group->pins[i]); + continue; + } + + func = tegra_xusb_padctl_lane_find_function(padctl, lane, + group->func); + if (func < 0) { + error("tegra-xusb-padctl: function %s invalid for lane %s: %d", + group->func, lane->name, func); + continue; + } + + value = padctl_readl(padctl, lane->offset); + + /* set pin function */ + value &= ~(lane->mask << lane->shift); + value |= func << lane->shift; + + /* + * Set IDDQ if supported on the lane and specified in the + * configuration. + */ + if (lane->iddq > 0 && group->iddq >= 0) { + if (group->iddq != 0) + value &= ~(1 << lane->iddq); + else + value |= 1 << lane->iddq; + } + + padctl_writel(padctl, value, lane->offset); + } + + return 0; +} + +static int +tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_config *config) +{ + unsigned int i; + + for (i = 0; i < config->num_groups; i++) { + const struct tegra_xusb_padctl_group *group; + int err; + + group = &config->groups[i]; + + err = tegra_xusb_padctl_group_apply(padctl, group); + if (err < 0) { + error("tegra-xusb-padctl: failed to apply group %s: %d", + group->name, err); + continue; + } + } + + return 0; +} + +static int +tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, + struct tegra_xusb_padctl_config *config, + const void *fdt, int node) +{ + int subnode; + + config->name = fdt_get_name(fdt, node, NULL); + + fdt_for_each_subnode(fdt, subnode, node) { + struct tegra_xusb_padctl_group *group; + int err; + + group = &config->groups[config->num_groups]; + + err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt, + subnode); + if (err < 0) { + error("tegra-xusb-padctl: failed to parse group %s", + group->name); + return err; + } + + config->num_groups++; + } + + return 0; +} + +static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, + const void *fdt, int node) +{ + int subnode, err; + + err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); + if (err < 0) { + error("tegra-xusb-padctl: registers not found"); + return err; + } + + fdt_for_each_subnode(fdt, subnode, node) { + struct tegra_xusb_padctl_config *config = &padctl->config; + + err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt, + subnode); + if (err < 0) { + error("tegra-xusb-padctl: failed to parse entry %s: %d", + config->name, err); + continue; + } + } + + return 0; +} + +static int process_nodes(const void *fdt, int nodes[], unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + enum fdt_compat_id id; + int err; + + if (!fdtdec_get_is_enabled(fdt, nodes[i])) + continue; + + id = fdtdec_lookup(fdt, nodes[i]); + switch (id) { + case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: + break; + + default: + error("tegra-xusb-padctl: unsupported compatible: %s", + fdtdec_get_compatible(id)); + continue; + } + + padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); + padctl->lanes = tegra124_lanes; + + padctl->num_functions = ARRAY_SIZE(tegra124_functions); + padctl->functions = tegra124_functions; + + err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); + if (err < 0) { + error("tegra-xusb-padctl: failed to parse DT: %d", + err); + continue; + } + + /* deassert XUSB padctl reset */ + reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); + + err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); + if (err < 0) { + error("tegra-xusb-padctl: failed to apply pinmux: %d", + err); + continue; + } + + /* only a single instance is supported */ + break; + } + + return 0; +} + +struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type) +{ + struct tegra_xusb_phy *phy = NULL; + + switch (type) { + case TEGRA_XUSB_PADCTL_PCIE: + phy = &padctl->phys[0]; + phy->padctl = padctl; + break; + + case TEGRA_XUSB_PADCTL_SATA: + phy = &padctl->phys[1]; + phy->padctl = padctl; + break; + } + + return phy; +} + +int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->prepare) + return phy->ops->prepare(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->enable) + return phy->ops->enable(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->disable) + return phy->ops->disable(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) +{ + if (phy && phy->ops && phy->ops->unprepare) + return phy->ops->unprepare(phy); + + return phy ? -ENOSYS : -EINVAL; +} + +void tegra_xusb_padctl_init(const void *fdt) +{ + int count, nodes[1]; + + count = fdtdec_find_aliases_for_id(fdt, "padctl", + COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, + nodes, ARRAY_SIZE(nodes)); + if (process_nodes(fdt, nodes, count)) + return; +} diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig new file mode 100644 index 0000000000..a354e2ad1f --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -0,0 +1,52 @@ +if TEGRA20 + +choice + prompt "Tegra20 board select" + +config TARGET_HARMONY + bool "NVIDIA Tegra20 Harmony evaluation board" + +config TARGET_MEDCOM_WIDE + bool "Avionic Design Medcom-Wide board" + +config TARGET_PAZ00 + bool "Paz00 board" + +config TARGET_PLUTUX + bool "Avionic Design Plutux board" + +config TARGET_SEABOARD + bool "NVIDIA Seaboard" + +config TARGET_TEC + bool "Avionic Design Tamonten Evaluation Carrier" + +config TARGET_TRIMSLICE + bool "Compulab TrimSlice board" + +config TARGET_VENTANA + bool "NVIDIA Tegra20 Ventana evaluation board" + +config TARGET_WHISTLER + bool "NVIDIA Tegra20 Whistler evaluation board" + +config TARGET_COLIBRI_T20_IRIS + bool "Toradex Colibri T20 board" + +endchoice + +config SYS_SOC + default "tegra20" + +source "board/nvidia/harmony/Kconfig" +source "board/avionic-design/medcom-wide/Kconfig" +source "board/compal/paz00/Kconfig" +source "board/avionic-design/plutux/Kconfig" +source "board/nvidia/seaboard/Kconfig" +source "board/avionic-design/tec/Kconfig" +source "board/compulab/trimslice/Kconfig" +source "board/nvidia/ventana/Kconfig" +source "board/nvidia/whistler/Kconfig" +source "board/toradex/colibri_t20_iris/Kconfig" + +endif diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile new file mode 100644 index 0000000000..d48f9bb325 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/Makefile @@ -0,0 +1,21 @@ +# +# (C) Copyright 2010,2011 Nvidia Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +obj-y += cpu.o +else +obj-$(CONFIG_PWM_TEGRA) += pwm.o +obj-$(CONFIG_VIDEO_TEGRA) += display.o +endif + +# The AVP is ARMv4T architecture so we must use special compiler +# flags for any startup files it might use. +CFLAGS_warmboot_avp.o += -march=armv4t + +obj-y += clock.o funcmux.o pinmux.o +obj-$(CONFIG_TEGRA_LP0) += warmboot.o crypto.o warmboot_avp.o +obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o +obj-$(CONFIG_TEGRA_PMU) += pmu.o diff --git a/arch/arm/mach-tegra/tegra20/clock.c b/arch/arm/mach-tegra/tegra20/clock.c new file mode 100644 index 0000000000..7b9e10cd93 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/clock.c @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Tegra20 Clock control functions */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Clock types that we can use as a source. The Tegra20 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCMT16, /* CLOCK_TYPE_PCMT with 16-bit divider */ + CLOCK_TYPE_PCXTS, + CLOCK_TYPE_PDCT, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 4 /* number of source options for each clock */ +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS + * is special as it has 5 sources. Since it also has a different number of + * bits in its register for the source, we just handle it with a special + * case in the code. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, + { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, +}; + +/* + * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is + * not in the header file since it is for purely internal use - we want + * callers to use the PERIPH_ID for all access to peripheral clocks to avoid + * confusion bewteen PERIPH_ID_... and PERIPHC_... + * + * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be + * confusing. + * + * Note to SOC vendors: perhaps define a unified numbering for peripherals and + * use it for reset, clock enable, clock source/divider and even pinmuxing + * if you can. + */ +enum periphc_internal_id { + /* 0x00 */ + PERIPHC_I2S1, + PERIPHC_I2S2, + PERIPHC_SPDIF_OUT, + PERIPHC_SPDIF_IN, + PERIPHC_PWM, + PERIPHC_SPI1, + PERIPHC_SPI2, + PERIPHC_SPI3, + + /* 0x08 */ + PERIPHC_XIO, + PERIPHC_I2C1, + PERIPHC_DVC_I2C, + PERIPHC_TWC, + PERIPHC_0c, + PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ + PERIPHC_DISP1, + PERIPHC_DISP2, + + /* 0x10 */ + PERIPHC_CVE, + PERIPHC_IDE0, + PERIPHC_VI, + PERIPHC_1c, + PERIPHC_SDMMC1, + PERIPHC_SDMMC2, + PERIPHC_G3D, + PERIPHC_G2D, + + /* 0x18 */ + PERIPHC_NDFLASH, + PERIPHC_SDMMC4, + PERIPHC_VFIR, + PERIPHC_EPP, + PERIPHC_MPE, + PERIPHC_MIPI, + PERIPHC_UART1, + PERIPHC_UART2, + + /* 0x20 */ + PERIPHC_HOST1X, + PERIPHC_21, + PERIPHC_TVO, + PERIPHC_HDMI, + PERIPHC_24, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_EMC, + + /* 0x28 */ + PERIPHC_UART3, + PERIPHC_29, + PERIPHC_VI_SENSOR, + PERIPHC_2b, + PERIPHC_2c, + PERIPHC_SPI4, + PERIPHC_I2C3, + PERIPHC_SDMMC3, + + /* 0x30 */ + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_VDE, + PERIPHC_OWR, + PERIPHC_NOR, + PERIPHC_CSITE, + + PERIPHC_COUNT, + + PERIPHC_NONE = -1, +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS), + TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(RESERVED1), + NONE(RESERVED2), + NONE(AC97), + NONE(RTC), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 0x08 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 0x10 */ + PERIPHC_TWC, + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 0x18 */ + PERIPHC_G3D, + PERIPHC_IDE0, + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + NONE(RESERVED30), + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(KBC), + NONE(STAT_MON), + NONE(PMC), + NONE(FUSE), + + /* 0x28 */ + NONE(KFUSE), + NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ + PERIPHC_NOR, + PERIPHC_SPI1, + PERIPHC_SPI2, + PERIPHC_XIO, + PERIPHC_SPI3, + PERIPHC_DVC_I2C, + + /* 0x30 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + PERIPHC_CSITE, + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 0x38 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + NONE(SPEEDO), + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SPI4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 0x48 */ + NONE(AFI), + NONE(CORESIGHT), + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(RESERVED79), + + /* 0x50 */ + NONE(RESERVED80), + NONE(RESERVED81), + NONE(RESERVED82), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 0x58 */ + NONE(CRAM2), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. T20 has 4 frequencies that it supports. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + assert(clock_periph_id_isvalid(periph_id)); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + return &clkrst->crc_clk_src[internal_id]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + /* + * Special cases here for the clock with a 4-bit source mux and I2C + * with its 16-bit divisor + */ + if (type == CLOCK_TYPE_PCXTS) + *mux_bits = MASK_BITS_31_28; + else + *mux_bits = MASK_BITS_31_30; + if (type == CLOCK_TYPE_PCMT16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* + * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS + * which is not in our table. If not, then they are asking for a + * source which this peripheral can't access through its mux. + */ + assert(type == CLOCK_TYPE_PCXTS); + assert(parent == CLOCK_ID_SFROM32KHZ); + if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) + return 4; /* mux value for this clock */ + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra20 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED1: + case PERIPH_ID_RESERVED2: + case PERIPH_ID_RESERVED30: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_PCIEXCLK: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED79: + case PERIPH_ID_RESERVED80: + case PERIPH_ID_RESERVED81: + case PERIPH_ID_RESERVED82: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED91: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + /* + * PLLP output frequency set to 216MHz + * PLLC output frequency set to 600Mhz + * + * TODO: Can we calculate these values instead of hard-coding? + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); + break; + + case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8); + clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); + break; + case CLOCK_OSC_FREQ_19_2: + default: + /* + * These are not supported. It is too early to print a + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } +} + +void arch_timer_init(void) +{ +} + +#define PMC_SATA_PWRGT 0x1ac +#define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) +#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) + +#define PLLE_SS_CNTL 0x68 +#define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) +#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) +#define PLLE_SS_CNTL_SSCBYP (1 << 12) +#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) +#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) +#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) + +#define PLLE_BASE 0x0e8 +#define PLLE_BASE_ENABLE_CML (1 << 31) +#define PLLE_BASE_ENABLE (1 << 30) +#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) +#define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) +#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) +#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) + +#define PLLE_MISC 0x0ec +#define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) +#define PLLE_MISC_PLL_READY (1 << 15) +#define PLLE_MISC_LOCK (1 << 11) +#define PLLE_MISC_LOCK_ENABLE (1 << 9) +#define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) + +static int tegra_plle_train(void) +{ + unsigned int timeout = 2000; + unsigned long value; + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + do { + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if (value & PLLE_MISC_PLL_READY) + break; + + udelay(100); + } while (--timeout); + + if (timeout == 0) { + error("timeout waiting for PLLE to become ready"); + return -ETIMEDOUT; + } + + return 0; +} + +int tegra_plle_enable(void) +{ + unsigned int timeout = 1000; + u32 value; + int err; + + /* disable PLLE clock */ + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value &= ~PLLE_BASE_ENABLE_CML; + value &= ~PLLE_BASE_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + /* clear lock enable and setup field */ + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value &= ~PLLE_MISC_LOCK_ENABLE; + value &= ~PLLE_MISC_SETUP_BASE(0xffff); + value &= ~PLLE_MISC_SETUP_EXT(0x3); + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if ((value & PLLE_MISC_PLL_READY) == 0) { + err = tegra_plle_train(); + if (err < 0) { + error("failed to train PLLE: %d", err); + return err; + } + } + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value |= PLLE_MISC_SETUP_BASE(0x7); + value |= PLLE_MISC_LOCK_ENABLE; + value |= PLLE_MISC_SETUP_EXT(0); + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | + PLLE_SS_CNTL_BYPASS_SS; + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + do { + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if (value & PLLE_MISC_LOCK) + break; + + udelay(2); + } while (--timeout); + + if (timeout == 0) { + error("timeout waiting for PLLE to lock"); + return -ETIMEDOUT; + } + + udelay(50); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); + value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); + + value &= ~PLLE_SS_CNTL_SSCINC(0xff); + value |= PLLE_SS_CNTL_SSCINC(0x01); + + value &= ~PLLE_SS_CNTL_SSCBYP; + value &= ~PLLE_SS_CNTL_INTERP_RESET; + value &= ~PLLE_SS_CNTL_BYPASS_SS; + + value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); + value |= PLLE_SS_CNTL_SSCMAX(0x24); + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra20/cpu.c b/arch/arm/mach-tegra/tegra20/cpu.c new file mode 100644 index 0000000000..67f49d7756 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/cpu.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include "../cpu.h" + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* + * The TI PMU65861C needs a 3.75ms delay between enabling + * the power rail and enabling the CPU clock. This delay + * between SM1EN and SM1 is for switching time + the ramp + * up of the voltage to the CPU (VDD_CPU from PMU). + */ + udelay(3750); +} + +void start_cpu(u32 reset_vector) +{ + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + /* Hold the CPUs in reset */ + reset_A9_cpu(1); + + /* Disable the CPU clock */ + enable_cpu_clock(0); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* + * Set the entry point for CPU execution from reset, + * if it's a non-zero value. + */ + if (reset_vector) + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Enable the CPU clock */ + enable_cpu_clock(1); + + /* If the CPU doesn't already have power, power it up */ + powerup_cpu(); + + /* Take the CPU out of reset */ + reset_A9_cpu(0); +} diff --git a/arch/arm/mach-tegra/tegra20/crypto.c b/arch/arm/mach-tegra/tegra20/crypto.c new file mode 100644 index 0000000000..ec95d7ceb1 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/crypto.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010 - 2011 NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include "crypto.h" +#include "aes.h" + +static u8 zero_key[16]; + +#define AES_CMAC_CONST_RB 0x87 /* from RFC 4493, Figure 2.2 */ + +enum security_op { + SECURITY_SIGN = 1 << 0, /* Sign the data */ + SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */ +}; + +/** + * Shift a vector left by one bit + * + * \param in Input vector + * \param out Output vector + * \param size Length of vector in bytes + */ +static void left_shift_vector(u8 *in, u8 *out, int size) +{ + int carry = 0; + int i; + + for (i = size - 1; i >= 0; i--) { + out[i] = (in[i] << 1) | carry; + carry = in[i] >> 7; /* get most significant bit */ + } +} + +/** + * Sign a block of data, putting the result into dst. + * + * \param key Input AES key, length AES_KEY_LENGTH + * \param key_schedule Expanded key to use + * \param src Source data of length 'num_aes_blocks' blocks + * \param dst Destination buffer, length AES_KEY_LENGTH + * \param num_aes_blocks Number of AES blocks to encrypt + */ +static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, + u32 num_aes_blocks) +{ + u8 tmp_data[AES_KEY_LENGTH]; + u8 left[AES_KEY_LENGTH]; + u8 k1[AES_KEY_LENGTH]; + u8 *cbc_chain_data; + unsigned i; + + cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ + + /* compute K1 constant needed by AES-CMAC calculation */ + for (i = 0; i < AES_KEY_LENGTH; i++) + tmp_data[i] = 0; + + aes_cbc_encrypt_blocks(key_schedule, tmp_data, left, 1); + + left_shift_vector(left, k1, sizeof(left)); + + if ((left[0] >> 7) != 0) /* get MSB of L */ + k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB; + + /* compute the AES-CMAC value */ + for (i = 0; i < num_aes_blocks; i++) { + /* Apply the chain data */ + aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data); + + /* for the final block, XOR K1 into the IV */ + if (i == num_aes_blocks - 1) + aes_apply_cbc_chain_data(tmp_data, k1, tmp_data); + + /* encrypt the AES block */ + aes_encrypt(tmp_data, key_schedule, dst); + + debug("sign_obj: block %d of %d\n", i, num_aes_blocks); + + /* Update pointers for next loop. */ + cbc_chain_data = dst; + src += AES_KEY_LENGTH; + } +} + +/** + * Encrypt and sign a block of data (depending on security mode). + * + * \param key Input AES key, length AES_KEY_LENGTH + * \param oper Security operations mask to perform (enum security_op) + * \param src Source data + * \param length Size of source data + * \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes + */ +static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, + u32 length, u8 *sig_dst) +{ + u32 num_aes_blocks; + u8 key_schedule[AES_EXPAND_KEY_LENGTH]; + + debug("encrypt_and_sign: length = %d\n", length); + + /* + * The only need for a key is for signing/checksum purposes, so + * if not encrypting, expand a key of 0s. + */ + aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule); + + num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH; + + if (oper & SECURITY_ENCRYPT) { + /* Perform this in place, resulting in src being encrypted. */ + debug("encrypt_and_sign: begin encryption\n"); + aes_cbc_encrypt_blocks(key_schedule, src, src, num_aes_blocks); + debug("encrypt_and_sign: end encryption\n"); + } + + if (oper & SECURITY_SIGN) { + /* encrypt the data, overwriting the result in signature. */ + debug("encrypt_and_sign: begin signing\n"); + sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); + debug("encrypt_and_sign: end signing\n"); + } + + return 0; +} + +int sign_data_block(u8 *source, unsigned length, u8 *signature) +{ + return encrypt_and_sign(zero_key, SECURITY_SIGN, source, + length, signature); +} diff --git a/arch/arm/mach-tegra/tegra20/crypto.h b/arch/arm/mach-tegra/tegra20/crypto.h new file mode 100644 index 0000000000..f59b92768a --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/crypto.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010 - 2011 NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +/** + * Sign a block of data + * + * \param source Source data + * \param length Size of source data + * \param signature Destination address for signature, AES_KEY_LENGTH bytes + */ +int sign_data_block(u8 *source, unsigned length, u8 *signature); + +#endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/mach-tegra/tegra20/display.c b/arch/arm/mach-tegra/tegra20/display.c new file mode 100644 index 0000000000..61efed6464 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/display.c @@ -0,0 +1,394 @@ +/* + * (C) Copyright 2010 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct fdt_disp_config config; + +static void update_window(struct dc_ctlr *dc, struct disp_ctl_win *win) +{ + unsigned h_dda, v_dda; + unsigned long val; + + val = readl(&dc->cmd.disp_win_header); + val |= WINDOW_A_SELECT; + writel(val, &dc->cmd.disp_win_header); + + writel(win->fmt, &dc->win.color_depth); + + clrsetbits_le32(&dc->win.byte_swap, BYTE_SWAP_MASK, + BYTE_SWAP_NOSWAP << BYTE_SWAP_SHIFT); + + val = win->out_x << H_POSITION_SHIFT; + val |= win->out_y << V_POSITION_SHIFT; + writel(val, &dc->win.pos); + + val = win->out_w << H_SIZE_SHIFT; + val |= win->out_h << V_SIZE_SHIFT; + writel(val, &dc->win.size); + + val = (win->w * win->bpp / 8) << H_PRESCALED_SIZE_SHIFT; + val |= win->h << V_PRESCALED_SIZE_SHIFT; + writel(val, &dc->win.prescaled_size); + + writel(0, &dc->win.h_initial_dda); + writel(0, &dc->win.v_initial_dda); + + h_dda = (win->w * 0x1000) / max(win->out_w - 1, 1U); + v_dda = (win->h * 0x1000) / max(win->out_h - 1, 1U); + + val = h_dda << H_DDA_INC_SHIFT; + val |= v_dda << V_DDA_INC_SHIFT; + writel(val, &dc->win.dda_increment); + + writel(win->stride, &dc->win.line_stride); + writel(0, &dc->win.buf_stride); + + val = WIN_ENABLE; + if (win->bpp < 24) + val |= COLOR_EXPAND; + writel(val, &dc->win.win_opt); + + writel((unsigned long)win->phys_addr, &dc->winbuf.start_addr); + writel(win->x, &dc->winbuf.addr_h_offset); + writel(win->y, &dc->winbuf.addr_v_offset); + + writel(0xff00, &dc->win.blend_nokey); + writel(0xff00, &dc->win.blend_1win); + + val = GENERAL_ACT_REQ | WIN_A_ACT_REQ; + val |= GENERAL_UPDATE | WIN_A_UPDATE; + writel(val, &dc->cmd.state_ctrl); +} + +static void write_pair(struct fdt_disp_config *config, int item, u32 *reg) +{ + writel(config->horiz_timing[item] | + (config->vert_timing[item] << 16), reg); +} + +static int update_display_mode(struct dc_disp_reg *disp, + struct fdt_disp_config *config) +{ + unsigned long val; + unsigned long rate; + unsigned long div; + + writel(0x0, &disp->disp_timing_opt); + write_pair(config, FDT_LCD_TIMING_REF_TO_SYNC, &disp->ref_to_sync); + write_pair(config, FDT_LCD_TIMING_SYNC_WIDTH, &disp->sync_width); + write_pair(config, FDT_LCD_TIMING_BACK_PORCH, &disp->back_porch); + write_pair(config, FDT_LCD_TIMING_FRONT_PORCH, &disp->front_porch); + + writel(config->width | (config->height << 16), &disp->disp_active); + + val = DE_SELECT_ACTIVE << DE_SELECT_SHIFT; + val |= DE_CONTROL_NORMAL << DE_CONTROL_SHIFT; + writel(val, &disp->data_enable_opt); + + val = DATA_FORMAT_DF1P1C << DATA_FORMAT_SHIFT; + val |= DATA_ALIGNMENT_MSB << DATA_ALIGNMENT_SHIFT; + val |= DATA_ORDER_RED_BLUE << DATA_ORDER_SHIFT; + writel(val, &disp->disp_interface_ctrl); + + /* + * The pixel clock divider is in 7.1 format (where the bottom bit + * represents 0.5). Here we calculate the divider needed to get from + * the display clock (typically 600MHz) to the pixel clock. We round + * up or down as requried. + */ + rate = clock_get_periph_rate(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL); + div = ((rate * 2 + config->pixel_clock / 2) / config->pixel_clock) - 2; + debug("Display clock %lu, divider %lu\n", rate, div); + + writel(0x00010001, &disp->shift_clk_opt); + + val = PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT; + val |= div << SHIFT_CLK_DIVIDER_SHIFT; + writel(val, &disp->disp_clk_ctrl); + + return 0; +} + +/* Start up the display and turn on power to PWMs */ +static void basic_init(struct dc_cmd_reg *cmd) +{ + u32 val; + + writel(0x00000100, &cmd->gen_incr_syncpt_ctrl); + writel(0x0000011a, &cmd->cont_syncpt_vsync); + writel(0x00000000, &cmd->int_type); + writel(0x00000000, &cmd->int_polarity); + writel(0x00000000, &cmd->int_mask); + writel(0x00000000, &cmd->int_enb); + + val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE; + val |= PW3_ENABLE | PW4_ENABLE | PM0_ENABLE; + val |= PM1_ENABLE; + writel(val, &cmd->disp_pow_ctrl); + + val = readl(&cmd->disp_cmd); + val |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT; + writel(val, &cmd->disp_cmd); +} + +static void basic_init_timer(struct dc_disp_reg *disp) +{ + writel(0x00000020, &disp->mem_high_pri); + writel(0x00000001, &disp->mem_high_pri_timer); +} + +static const u32 rgb_enb_tab[PIN_REG_COUNT] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +static const u32 rgb_polarity_tab[PIN_REG_COUNT] = { + 0x00000000, + 0x01000000, + 0x00000000, + 0x00000000, +}; + +static const u32 rgb_data_tab[PIN_REG_COUNT] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +static const u32 rgb_sel_tab[PIN_OUTPUT_SEL_COUNT] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00210222, + 0x00002200, + 0x00020000, +}; + +static void rgb_enable(struct dc_com_reg *com) +{ + int i; + + for (i = 0; i < PIN_REG_COUNT; i++) { + writel(rgb_enb_tab[i], &com->pin_output_enb[i]); + writel(rgb_polarity_tab[i], &com->pin_output_polarity[i]); + writel(rgb_data_tab[i], &com->pin_output_data[i]); + } + + for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++) + writel(rgb_sel_tab[i], &com->pin_output_sel[i]); +} + +static int setup_window(struct disp_ctl_win *win, + struct fdt_disp_config *config) +{ + win->x = 0; + win->y = 0; + win->w = config->width; + win->h = config->height; + win->out_x = 0; + win->out_y = 0; + win->out_w = config->width; + win->out_h = config->height; + win->phys_addr = config->frame_buffer; + win->stride = config->width * (1 << config->log2_bpp) / 8; + debug("%s: depth = %d\n", __func__, config->log2_bpp); + switch (config->log2_bpp) { + case 5: + case 24: + win->fmt = COLOR_DEPTH_R8G8B8A8; + win->bpp = 32; + break; + case 4: + win->fmt = COLOR_DEPTH_B5G6R5; + win->bpp = 16; + break; + + default: + debug("Unsupported LCD bit depth"); + return -1; + } + + return 0; +} + +struct fdt_disp_config *tegra_display_get_config(void) +{ + return config.valid ? &config : NULL; +} + +static void debug_timing(const char *name, unsigned int timing[]) +{ +#ifdef DEBUG + int i; + + debug("%s timing: ", name); + for (i = 0; i < FDT_LCD_TIMING_COUNT; i++) + debug("%d ", timing[i]); + debug("\n"); +#endif +} + +/** + * Decode panel information from the fdt, according to a standard binding + * + * @param blob fdt blob + * @param node offset of fdt node to read from + * @param config structure to store fdt config into + * @return 0 if ok, -ve on error + */ +static int tegra_decode_panel(const void *blob, int node, + struct fdt_disp_config *config) +{ + int front, back, ref; + + config->width = fdtdec_get_int(blob, node, "xres", -1); + config->height = fdtdec_get_int(blob, node, "yres", -1); + config->pixel_clock = fdtdec_get_int(blob, node, "clock", 0); + if (!config->pixel_clock || config->width == -1 || + config->height == -1) { + debug("%s: Pixel parameters missing\n", __func__); + return -FDT_ERR_NOTFOUND; + } + + back = fdtdec_get_int(blob, node, "left-margin", -1); + front = fdtdec_get_int(blob, node, "right-margin", -1); + ref = fdtdec_get_int(blob, node, "hsync-len", -1); + if ((back | front | ref) == -1) { + debug("%s: Horizontal parameters missing\n", __func__); + return -FDT_ERR_NOTFOUND; + } + + /* Use a ref-to-sync of 1 always, and take this from the front porch */ + config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; + config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; + config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back; + config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - + config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC]; + debug_timing("horiz", config->horiz_timing); + + back = fdtdec_get_int(blob, node, "upper-margin", -1); + front = fdtdec_get_int(blob, node, "lower-margin", -1); + ref = fdtdec_get_int(blob, node, "vsync-len", -1); + if ((back | front | ref) == -1) { + debug("%s: Vertical parameters missing\n", __func__); + return -FDT_ERR_NOTFOUND; + } + + config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1; + config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref; + config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back; + config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front - + config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC]; + debug_timing("vert", config->vert_timing); + + return 0; +} + +/** + * Decode the display controller information from the fdt. + * + * @param blob fdt blob + * @param config structure to store fdt config into + * @return 0 if ok, -ve on error + */ +static int tegra_display_decode_config(const void *blob, + struct fdt_disp_config *config) +{ + int node, rgb; + int bpp, bit; + + /* TODO: Support multiple controllers */ + node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC); + if (node < 0) { + debug("%s: Cannot find display controller node in fdt\n", + __func__); + return node; + } + config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg"); + if (!config->disp) { + debug("%s: No display controller address\n", __func__); + return -1; + } + + rgb = fdt_subnode_offset(blob, node, "rgb"); + + config->panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel"); + if (config->panel_node < 0) { + debug("%s: Cannot find panel information\n", __func__); + return -1; + } + + if (tegra_decode_panel(blob, config->panel_node, config)) { + debug("%s: Failed to decode panel information\n", __func__); + return -1; + } + + bpp = fdtdec_get_int(blob, config->panel_node, "nvidia,bits-per-pixel", + -1); + bit = ffs(bpp) - 1; + if (bpp == (1 << bit)) + config->log2_bpp = bit; + else + config->log2_bpp = bpp; + if (bpp == -1) { + debug("%s: Pixel bpp parameters missing\n", __func__); + return -FDT_ERR_NOTFOUND; + } + config->bpp = bpp; + + config->valid = 1; /* we have a valid configuration */ + + return 0; +} + +int tegra_display_probe(const void *blob, void *default_lcd_base) +{ + struct disp_ctl_win window; + struct dc_ctlr *dc; + + if (tegra_display_decode_config(blob, &config)) + return -1; + + config.frame_buffer = (u32)default_lcd_base; + + dc = (struct dc_ctlr *)config.disp; + + /* + * A header file for clock constants was NAKed upstream. + * TODO: Put this into the FDT and fdt_lcd struct when we have clock + * support there + */ + clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, + 144 * 1000000); + clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL, + 600 * 1000000); + basic_init(&dc->cmd); + basic_init_timer(&dc->disp); + rgb_enable(&dc->com); + + if (config.pixel_clock) + update_display_mode(&dc->disp, &config); + + if (setup_window(&window, &config)) + return -1; + + update_window(dc, &window); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra20/emc.c b/arch/arm/mach-tegra/tegra20/emc.c new file mode 100644 index 0000000000..ed2462ab0f --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/emc.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The EMC registers have shadow registers. When the EMC clock is updated + * in the clock controller, the shadow registers are copied to the active + * registers, allowing glitchless memory bus frequency changes. + * This function updates the shadow registers for a new clock frequency, + * and relies on the clock lock on the emc clock to avoid races between + * multiple frequency changes + */ + +/* + * This table defines the ordering of the registers provided to + * tegra_set_mmc() + * TODO: Convert to fdt version once available + */ +static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = { + 0x2c, /* RC */ + 0x30, /* RFC */ + 0x34, /* RAS */ + 0x38, /* RP */ + 0x3c, /* R2W */ + 0x40, /* W2R */ + 0x44, /* R2P */ + 0x48, /* W2P */ + 0x4c, /* RD_RCD */ + 0x50, /* WR_RCD */ + 0x54, /* RRD */ + 0x58, /* REXT */ + 0x5c, /* WDV */ + 0x60, /* QUSE */ + 0x64, /* QRST */ + 0x68, /* QSAFE */ + 0x6c, /* RDV */ + 0x70, /* REFRESH */ + 0x74, /* BURST_REFRESH_NUM */ + 0x78, /* PDEX2WR */ + 0x7c, /* PDEX2RD */ + 0x80, /* PCHG2PDEN */ + 0x84, /* ACT2PDEN */ + 0x88, /* AR2PDEN */ + 0x8c, /* RW2PDEN */ + 0x90, /* TXSR */ + 0x94, /* TCKE */ + 0x98, /* TFAW */ + 0x9c, /* TRPAB */ + 0xa0, /* TCLKSTABLE */ + 0xa4, /* TCLKSTOP */ + 0xa8, /* TREFBW */ + 0xac, /* QUSE_EXTRA */ + 0x114, /* FBIO_CFG6 */ + 0xb0, /* ODT_WRITE */ + 0xb4, /* ODT_READ */ + 0x104, /* FBIO_CFG5 */ + 0x2bc, /* CFG_DIG_DLL */ + 0x2c0, /* DLL_XFORM_DQS */ + 0x2c4, /* DLL_XFORM_QUSE */ + 0x2e0, /* ZCAL_REF_CNT */ + 0x2e4, /* ZCAL_WAIT_CNT */ + 0x2a8, /* AUTO_CAL_INTERVAL */ + 0x2d0, /* CFG_CLKTRIM_0 */ + 0x2d4, /* CFG_CLKTRIM_1 */ + 0x2d8, /* CFG_CLKTRIM_2 */ +}; + +struct emc_ctlr *emc_get_controller(const void *blob) +{ + fdt_addr_t addr; + int node; + + node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); + if (node > 0) { + addr = fdtdec_get_addr(blob, node, "reg"); + if (addr != FDT_ADDR_T_NONE) + return (struct emc_ctlr *)addr; + } + return NULL; +} + +/* Error codes we use */ +enum { + ERR_NO_EMC_NODE = -10, + ERR_NO_EMC_REG, + ERR_NO_FREQ, + ERR_FREQ_NOT_FOUND, + ERR_BAD_REGS, + ERR_NO_RAM_CODE, + ERR_RAM_CODE_NOT_FOUND, +}; + +/** + * Find EMC tables for the given ram code. + * + * The tegra EMC binding has two options, one using the ram code and one not. + * We detect which is in use by looking for the nvidia,use-ram-code property. + * If this is not present, then the EMC tables are directly below 'node', + * otherwise we select the correct emc-tables subnode based on the 'ram_code' + * value. + * + * @param blob Device tree blob + * @param node EMC node (nvidia,tegra20-emc compatible string) + * @param ram_code RAM code to select (0-3, or -1 if unknown) + * @return 0 if ok, otherwise a -ve ERR_ code (see enum above) + */ +static int find_emc_tables(const void *blob, int node, int ram_code) +{ + int need_ram_code; + int depth; + int offset; + + /* If we are using RAM codes, scan through the tables for our code */ + need_ram_code = fdtdec_get_bool(blob, node, "nvidia,use-ram-code"); + if (!need_ram_code) + return node; + if (ram_code == -1) { + debug("%s: RAM code required but not supplied\n", __func__); + return ERR_NO_RAM_CODE; + } + + offset = node; + depth = 0; + do { + /* + * Sadly there is no compatible string so we cannot use + * fdtdec_next_compatible_subnode(). + */ + offset = fdt_next_node(blob, offset, &depth); + if (depth <= 0) + break; + + /* Make sure this is a direct subnode */ + if (depth != 1) + continue; + if (strcmp("emc-tables", fdt_get_name(blob, offset, NULL))) + continue; + + if (fdtdec_get_int(blob, offset, "nvidia,ram-code", -1) + == ram_code) + return offset; + } while (1); + + debug("%s: Could not find tables for RAM code %d\n", __func__, + ram_code); + return ERR_RAM_CODE_NOT_FOUND; +} + +/** + * Decode the EMC node of the device tree, returning a pointer to the emc + * controller and the table to be used for the given rate. + * + * @param blob Device tree blob + * @param rate Clock speed of memory controller in Hz (=2x memory bus rate) + * @param emcp Returns address of EMC controller registers + * @param tablep Returns pointer to table to program into EMC. There are + * TEGRA_EMC_NUM_REGS entries, destined for offsets as per the + * emc_reg_addr array. + * @return 0 if ok, otherwise a -ve error code which will allow someone to + * figure out roughly what went wrong by looking at this code. + */ +static int decode_emc(const void *blob, unsigned rate, struct emc_ctlr **emcp, + const u32 **tablep) +{ + struct apb_misc_pp_ctlr *pp = + (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; + int ram_code; + int depth; + int node; + + ram_code = (readl(&pp->strapping_opt_a) & RAM_CODE_MASK) + >> RAM_CODE_SHIFT; + /* + * The EMC clock rate is twice the bus rate, and the bus rate is + * measured in kHz + */ + rate = rate / 2 / 1000; + + node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_EMC); + if (node < 0) { + debug("%s: No EMC node found in FDT\n", __func__); + return ERR_NO_EMC_NODE; + } + *emcp = (struct emc_ctlr *)fdtdec_get_addr(blob, node, "reg"); + if (*emcp == (struct emc_ctlr *)FDT_ADDR_T_NONE) { + debug("%s: No EMC node reg property\n", __func__); + return ERR_NO_EMC_REG; + } + + /* Work out the parent node which contains our EMC tables */ + node = find_emc_tables(blob, node, ram_code & 3); + if (node < 0) + return node; + + depth = 0; + for (;;) { + int node_rate; + + node = fdtdec_next_compatible_subnode(blob, node, + COMPAT_NVIDIA_TEGRA20_EMC_TABLE, &depth); + if (node < 0) + break; + node_rate = fdtdec_get_int(blob, node, "clock-frequency", -1); + if (node_rate == -1) { + debug("%s: Missing clock-frequency\n", __func__); + return ERR_NO_FREQ; /* we expect this property */ + } + + if (node_rate == rate) + break; + } + if (node < 0) { + debug("%s: No node found for clock frequency %d\n", __func__, + rate); + return ERR_FREQ_NOT_FOUND; + } + + *tablep = fdtdec_locate_array(blob, node, "nvidia,emc-registers", + TEGRA_EMC_NUM_REGS); + if (!*tablep) { + debug("%s: node '%s' array missing / wrong size\n", __func__, + fdt_get_name(blob, node, NULL)); + return ERR_BAD_REGS; + } + + /* All seems well */ + return 0; +} + +int tegra_set_emc(const void *blob, unsigned rate) +{ + struct emc_ctlr *emc; + const u32 *table = NULL; + int err, i; + + err = decode_emc(blob, rate, &emc, &table); + if (err) { + debug("Warning: no valid EMC (%d), memory timings unset\n", + err); + return err; + } + + debug("%s: Table found, setting EMC values as follows:\n", __func__); + for (i = 0; i < TEGRA_EMC_NUM_REGS; i++) { + u32 value = fdt32_to_cpu(table[i]); + u32 addr = (uintptr_t)emc + emc_reg_addr[i]; + + debug(" %#x: %#x\n", addr, value); + writel(value, addr); + } + + /* trigger emc with new settings */ + clock_adjust_periph_pll_div(PERIPH_ID_EMC, CLOCK_ID_MEMORY, + clock_get_rate(CLOCK_ID_MEMORY), NULL); + debug("EMC clock set to %lu\n", + clock_get_periph_rate(PERIPH_ID_EMC, CLOCK_ID_MEMORY)); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra20/funcmux.c b/arch/arm/mach-tegra/tegra20/funcmux.c new file mode 100644 index 0000000000..0df4a0738d --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/funcmux.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Tegra20 high-level function multiplexing */ +#include +#include +#include +#include + +/* + * The PINMUX macro is used to set up pinmux tables. + */ +#define PINMUX(grp, mux, pupd, tri) \ + {PMUX_PINGRP_##grp, PMUX_FUNC_##mux, PMUX_PULL_##pupd, PMUX_TRI_##tri} + +static const struct pmux_pingrp_config disp1_default[] = { + PINMUX(LDI, DISPA, NORMAL, NORMAL), + PINMUX(LHP0, DISPA, NORMAL, NORMAL), + PINMUX(LHP1, DISPA, NORMAL, NORMAL), + PINMUX(LHP2, DISPA, NORMAL, NORMAL), + PINMUX(LHS, DISPA, NORMAL, NORMAL), + PINMUX(LM0, RSVD4, NORMAL, NORMAL), + PINMUX(LPP, DISPA, NORMAL, NORMAL), + PINMUX(LPW0, DISPA, NORMAL, NORMAL), + PINMUX(LPW2, DISPA, NORMAL, NORMAL), + PINMUX(LSC0, DISPA, NORMAL, NORMAL), + PINMUX(LSPI, DISPA, NORMAL, NORMAL), + PINMUX(LVP1, DISPA, NORMAL, NORMAL), + PINMUX(LVS, DISPA, NORMAL, NORMAL), + PINMUX(SLXD, SPDIF, NORMAL, NORMAL), +}; + + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART1: + switch (config) { + case FUNCMUX_UART1_IRRX_IRTX: + pinmux_set_func(PMUX_PINGRP_IRRX, PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_IRTX, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PMUX_PINGRP_IRRX); + pinmux_tristate_disable(PMUX_PINGRP_IRTX); + break; + case FUNCMUX_UART1_UAA_UAB: + pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PMUX_PINGRP_UAA); + pinmux_tristate_disable(PMUX_PINGRP_UAB); + bad_config = 0; + break; + case FUNCMUX_UART1_GPU: + pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PMUX_PINGRP_GPU); + bad_config = 0; + break; + case FUNCMUX_UART1_SDIO1: + pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PMUX_PINGRP_SDIO1); + bad_config = 0; + break; + } + if (!bad_config) { + /* + * Tegra appears to boot with function UARTA pre- + * selected on mux group SDB. If two mux groups are + * both set to the same function, it's unclear which + * group's pins drive the RX signals into the HW. + * For UARTA, SDB certainly overrides group IRTX in + * practice. To solve this, configure some alternative + * function on SDB to avoid the conflict. Also, tri- + * state the group to avoid driving any signal onto it + * until we know what's connected. + */ + pinmux_tristate_enable(PMUX_PINGRP_SDB); + pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); + } + break; + + case PERIPH_ID_UART2: + if (config == FUNCMUX_UART2_UAD) { + pinmux_set_func(PMUX_PINGRP_UAD, PMUX_FUNC_UARTB); + pinmux_tristate_disable(PMUX_PINGRP_UAD); + } + break; + + case PERIPH_ID_UART4: + if (config == FUNCMUX_UART4_GMC) { + pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_UARTD); + pinmux_tristate_disable(PMUX_PINGRP_GMC); + } + break; + + case PERIPH_ID_DVC_I2C: + /* there is only one selection, pinmux_config is ignored */ + if (config == FUNCMUX_DVC_I2CP) { + pinmux_set_func(PMUX_PINGRP_I2CP, PMUX_FUNC_I2C); + pinmux_tristate_disable(PMUX_PINGRP_I2CP); + } + break; + + case PERIPH_ID_I2C1: + /* support pinmux_config of 0 for now, */ + if (config == FUNCMUX_I2C1_RM) { + pinmux_set_func(PMUX_PINGRP_RM, PMUX_FUNC_I2C); + pinmux_tristate_disable(PMUX_PINGRP_RM); + } + break; + case PERIPH_ID_I2C2: /* I2C2 */ + switch (config) { + case FUNCMUX_I2C2_DDC: /* DDC pin group, select I2C2 */ + pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_I2C2); + /* PTA to HDMI */ + pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_HDMI); + pinmux_tristate_disable(PMUX_PINGRP_DDC); + break; + case FUNCMUX_I2C2_PTA: /* PTA pin group, select I2C2 */ + pinmux_set_func(PMUX_PINGRP_PTA, PMUX_FUNC_I2C2); + /* set DDC_SEL to RSVDx (RSVD2 works for now) */ + pinmux_set_func(PMUX_PINGRP_DDC, PMUX_FUNC_RSVD2); + pinmux_tristate_disable(PMUX_PINGRP_PTA); + bad_config = 0; + break; + } + break; + case PERIPH_ID_I2C3: /* I2C3 */ + /* support pinmux_config of 0 for now */ + if (config == FUNCMUX_I2C3_DTF) { + pinmux_set_func(PMUX_PINGRP_DTF, PMUX_FUNC_I2C3); + pinmux_tristate_disable(PMUX_PINGRP_DTF); + } + break; + + case PERIPH_ID_SDMMC1: + if (config == FUNCMUX_SDMMC1_SDIO1_4BIT) { + pinmux_set_func(PMUX_PINGRP_SDIO1, PMUX_FUNC_SDIO1); + pinmux_tristate_disable(PMUX_PINGRP_SDIO1); + } + break; + + case PERIPH_ID_SDMMC2: + if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { + pinmux_set_func(PMUX_PINGRP_DTA, PMUX_FUNC_SDIO2); + pinmux_set_func(PMUX_PINGRP_DTD, PMUX_FUNC_SDIO2); + + pinmux_tristate_disable(PMUX_PINGRP_DTA); + pinmux_tristate_disable(PMUX_PINGRP_DTD); + } + break; + + case PERIPH_ID_SDMMC3: + switch (config) { + case FUNCMUX_SDMMC3_SDB_SLXA_8BIT: + pinmux_set_func(PMUX_PINGRP_SLXA, PMUX_FUNC_SDIO3); + pinmux_set_func(PMUX_PINGRP_SLXC, PMUX_FUNC_SDIO3); + pinmux_set_func(PMUX_PINGRP_SLXD, PMUX_FUNC_SDIO3); + pinmux_set_func(PMUX_PINGRP_SLXK, PMUX_FUNC_SDIO3); + + pinmux_tristate_disable(PMUX_PINGRP_SLXA); + pinmux_tristate_disable(PMUX_PINGRP_SLXC); + pinmux_tristate_disable(PMUX_PINGRP_SLXD); + pinmux_tristate_disable(PMUX_PINGRP_SLXK); + /* fall through */ + + case FUNCMUX_SDMMC3_SDB_4BIT: + pinmux_set_func(PMUX_PINGRP_SDB, PMUX_FUNC_SDIO3); + pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_SDIO3); + pinmux_set_func(PMUX_PINGRP_SDD, PMUX_FUNC_SDIO3); + + pinmux_tristate_disable(PMUX_PINGRP_SDB); + pinmux_tristate_disable(PMUX_PINGRP_SDC); + pinmux_tristate_disable(PMUX_PINGRP_SDD); + bad_config = 0; + break; + } + break; + + case PERIPH_ID_SDMMC4: + switch (config) { + case FUNCMUX_SDMMC4_ATC_ATD_8BIT: + pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_SDIO4); + pinmux_set_func(PMUX_PINGRP_ATD, PMUX_FUNC_SDIO4); + + pinmux_tristate_disable(PMUX_PINGRP_ATC); + pinmux_tristate_disable(PMUX_PINGRP_ATD); + break; + + case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT: + pinmux_set_func(PMUX_PINGRP_GME, PMUX_FUNC_SDIO4); + pinmux_tristate_disable(PMUX_PINGRP_GME); + /* fall through */ + + case FUNCMUX_SDMMC4_ATB_GMA_4_BIT: + pinmux_set_func(PMUX_PINGRP_ATB, PMUX_FUNC_SDIO4); + pinmux_set_func(PMUX_PINGRP_GMA, PMUX_FUNC_SDIO4); + + pinmux_tristate_disable(PMUX_PINGRP_ATB); + pinmux_tristate_disable(PMUX_PINGRP_GMA); + bad_config = 0; + break; + } + break; + + case PERIPH_ID_KBC: + if (config == FUNCMUX_DEFAULT) { + enum pmux_pingrp grp[] = {PMUX_PINGRP_KBCA, + PMUX_PINGRP_KBCB, PMUX_PINGRP_KBCC, + PMUX_PINGRP_KBCD, PMUX_PINGRP_KBCE, + PMUX_PINGRP_KBCF}; + int i; + + for (i = 0; i < ARRAY_SIZE(grp); i++) { + pinmux_tristate_disable(grp[i]); + pinmux_set_func(grp[i], PMUX_FUNC_KBC); + pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); + } + } + break; + + case PERIPH_ID_USB2: + if (config == FUNCMUX_USB2_ULPI) { + pinmux_set_func(PMUX_PINGRP_UAA, PMUX_FUNC_ULPI); + pinmux_set_func(PMUX_PINGRP_UAB, PMUX_FUNC_ULPI); + pinmux_set_func(PMUX_PINGRP_UDA, PMUX_FUNC_ULPI); + + pinmux_tristate_disable(PMUX_PINGRP_UAA); + pinmux_tristate_disable(PMUX_PINGRP_UAB); + pinmux_tristate_disable(PMUX_PINGRP_UDA); + } + break; + + case PERIPH_ID_SPI1: + if (config == FUNCMUX_SPI1_GMC_GMD) { + pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH); + pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH); + + pinmux_tristate_disable(PMUX_PINGRP_GMC); + pinmux_tristate_disable(PMUX_PINGRP_GMD); + } + break; + + case PERIPH_ID_NDFLASH: + switch (config) { + case FUNCMUX_NDFLASH_ATC: + pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_NAND); + pinmux_tristate_disable(PMUX_PINGRP_ATC); + break; + case FUNCMUX_NDFLASH_KBC_8_BIT: + pinmux_set_func(PMUX_PINGRP_KBCA, PMUX_FUNC_NAND); + pinmux_set_func(PMUX_PINGRP_KBCC, PMUX_FUNC_NAND); + pinmux_set_func(PMUX_PINGRP_KBCD, PMUX_FUNC_NAND); + pinmux_set_func(PMUX_PINGRP_KBCE, PMUX_FUNC_NAND); + pinmux_set_func(PMUX_PINGRP_KBCF, PMUX_FUNC_NAND); + + pinmux_tristate_disable(PMUX_PINGRP_KBCA); + pinmux_tristate_disable(PMUX_PINGRP_KBCC); + pinmux_tristate_disable(PMUX_PINGRP_KBCD); + pinmux_tristate_disable(PMUX_PINGRP_KBCE); + pinmux_tristate_disable(PMUX_PINGRP_KBCF); + + bad_config = 0; + break; + } + break; + case PERIPH_ID_DISP1: + if (config == FUNCMUX_DEFAULT) { + int i; + + for (i = PMUX_PINGRP_LD0; i <= PMUX_PINGRP_LD17; i++) { + pinmux_set_func(i, PMUX_FUNC_DISPA); + pinmux_tristate_disable(i); + pinmux_set_pullupdown(i, PMUX_PULL_NORMAL); + } + pinmux_config_pingrp_table(disp1_default, + ARRAY_SIZE(disp1_default)); + } + break; + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra20/pinmux.c b/arch/arm/mach-tegra/tegra20/pinmux.c new file mode 100644 index 0000000000..e484f991bf --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/pinmux.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Tegra20 pin multiplexing functions */ + +#include +#include +#include + +/* + * This defines the order of the pin mux control bits in the registers. For + * some reason there is no correspendence between the tristate, pin mux and + * pullup/pulldown registers. + */ +enum pmux_ctlid { + /* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */ + MUXCTL_UAA, + MUXCTL_UAB, + MUXCTL_UAC, + MUXCTL_UAD, + MUXCTL_UDA, + MUXCTL_RESERVED5, + MUXCTL_ATE, + MUXCTL_RM, + + MUXCTL_ATB, + MUXCTL_RESERVED9, + MUXCTL_ATD, + MUXCTL_ATC, + MUXCTL_ATA, + MUXCTL_KBCF, + MUXCTL_KBCE, + MUXCTL_SDMMC1, + + /* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */ + MUXCTL_GMA, + MUXCTL_GMC, + MUXCTL_HDINT, + MUXCTL_SLXA, + MUXCTL_OWC, + MUXCTL_SLXC, + MUXCTL_SLXD, + MUXCTL_SLXK, + + MUXCTL_UCA, + MUXCTL_UCB, + MUXCTL_DTA, + MUXCTL_DTB, + MUXCTL_RESERVED28, + MUXCTL_DTC, + MUXCTL_DTD, + MUXCTL_DTE, + + /* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */ + MUXCTL_DDC, + MUXCTL_CDEV1, + MUXCTL_CDEV2, + MUXCTL_CSUS, + MUXCTL_I2CP, + MUXCTL_KBCA, + MUXCTL_KBCB, + MUXCTL_KBCC, + + MUXCTL_IRTX, + MUXCTL_IRRX, + MUXCTL_DAP1, + MUXCTL_DAP2, + MUXCTL_DAP3, + MUXCTL_DAP4, + MUXCTL_GMB, + MUXCTL_GMD, + + /* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */ + MUXCTL_GME, + MUXCTL_GPV, + MUXCTL_GPU, + MUXCTL_SPDO, + MUXCTL_SPDI, + MUXCTL_SDB, + MUXCTL_SDC, + MUXCTL_SDD, + + MUXCTL_SPIH, + MUXCTL_SPIG, + MUXCTL_SPIF, + MUXCTL_SPIE, + MUXCTL_SPID, + MUXCTL_SPIC, + MUXCTL_SPIB, + MUXCTL_SPIA, + + /* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */ + MUXCTL_LPW0, + MUXCTL_LPW1, + MUXCTL_LPW2, + MUXCTL_LSDI, + MUXCTL_LSDA, + MUXCTL_LSPI, + MUXCTL_LCSN, + MUXCTL_LDC, + + MUXCTL_LSCK, + MUXCTL_LSC0, + MUXCTL_LSC1, + MUXCTL_LHS, + MUXCTL_LVS, + MUXCTL_LM0, + MUXCTL_LM1, + MUXCTL_LVP0, + + /* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */ + MUXCTL_LD0, + MUXCTL_LD1, + MUXCTL_LD2, + MUXCTL_LD3, + MUXCTL_LD4, + MUXCTL_LD5, + MUXCTL_LD6, + MUXCTL_LD7, + + MUXCTL_LD8, + MUXCTL_LD9, + MUXCTL_LD10, + MUXCTL_LD11, + MUXCTL_LD12, + MUXCTL_LD13, + MUXCTL_LD14, + MUXCTL_LD15, + + /* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */ + MUXCTL_LD16, + MUXCTL_LD17, + MUXCTL_LHP1, + MUXCTL_LHP2, + MUXCTL_LVP1, + MUXCTL_LHP0, + MUXCTL_RESERVED102, + MUXCTL_LPP, + + MUXCTL_LDI, + MUXCTL_PMC, + MUXCTL_CRTP, + MUXCTL_PTA, + MUXCTL_RESERVED108, + MUXCTL_KBCD, + MUXCTL_GPU7, + MUXCTL_DTF, + + MUXCTL_NONE = -1, +}; + +/* + * And this defines the order of the pullup/pulldown controls which are again + * in a different order + */ +enum pmux_pullid { + /* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */ + PUCTL_ATA, + PUCTL_ATB, + PUCTL_ATC, + PUCTL_ATD, + PUCTL_ATE, + PUCTL_DAP1, + PUCTL_DAP2, + PUCTL_DAP3, + + PUCTL_DAP4, + PUCTL_DTA, + PUCTL_DTB, + PUCTL_DTC, + PUCTL_DTD, + PUCTL_DTE, + PUCTL_DTF, + PUCTL_GPV, + + /* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */ + PUCTL_RM, + PUCTL_I2CP, + PUCTL_PTA, + PUCTL_GPU7, + PUCTL_KBCA, + PUCTL_KBCB, + PUCTL_KBCC, + PUCTL_KBCD, + + PUCTL_SPDI, + PUCTL_SPDO, + PUCTL_GPSLXAU, + PUCTL_CRTP, + PUCTL_SLXC, + PUCTL_SLXD, + PUCTL_SLXK, + + /* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */ + PUCTL_CDEV1, + PUCTL_CDEV2, + PUCTL_SPIA, + PUCTL_SPIB, + PUCTL_SPIC, + PUCTL_SPID, + PUCTL_SPIE, + PUCTL_SPIF, + + PUCTL_SPIG, + PUCTL_SPIH, + PUCTL_IRTX, + PUCTL_IRRX, + PUCTL_GME, + PUCTL_RESERVED45, + PUCTL_XM2D, + PUCTL_XM2C, + + /* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */ + PUCTL_UAA, + PUCTL_UAB, + PUCTL_UAC, + PUCTL_UAD, + PUCTL_UCA, + PUCTL_UCB, + PUCTL_LD17, + PUCTL_LD19_18, + + PUCTL_LD21_20, + PUCTL_LD23_22, + PUCTL_LS, + PUCTL_LC, + PUCTL_CSUS, + PUCTL_DDRC, + PUCTL_SDC, + PUCTL_SDD, + + /* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */ + PUCTL_KBCF, + PUCTL_KBCE, + PUCTL_PMCA, + PUCTL_PMCB, + PUCTL_PMCC, + PUCTL_PMCD, + PUCTL_PMCE, + PUCTL_CK32, + + PUCTL_UDA, + PUCTL_SDMMC1, + PUCTL_GMA, + PUCTL_GMB, + PUCTL_GMC, + PUCTL_GMD, + PUCTL_DDC, + PUCTL_OWC, + + PUCTL_NONE = -1 +}; + +/* Convenient macro for defining pin group properties */ +#define PINALL(pingrp, f0, f1, f2, f3, mux, pupd) \ + { \ + .funcs = { \ + PMUX_FUNC_ ## f0, \ + PMUX_FUNC_ ## f1, \ + PMUX_FUNC_ ## f2, \ + PMUX_FUNC_ ## f3, \ + }, \ + .ctl_id = mux, \ + .pull_id = pupd \ + } + +/* A normal pin group where the mux name and pull-up name match */ +#define PIN(pingrp, f0, f1, f2, f3) \ + PINALL(pingrp, f0, f1, f2, f3, MUXCTL_##pingrp, PUCTL_##pingrp) + +/* A pin group where the pull-up name doesn't have a 1-1 mapping */ +#define PINP(pingrp, f0, f1, f2, f3, pupd) \ + PINALL(pingrp, f0, f1, f2, f3, MUXCTL_##pingrp, PUCTL_##pupd) + +/* A pin group number which is not used */ +#define PIN_RESERVED \ + PIN(NONE, RSVD1, RSVD2, RSVD3, RSVD4) + +#define DRVGRP(drvgrp) \ + PINALL(drvgrp, RSVD1, RSVD2, RSVD3, RSVD4, MUXCTL_NONE, PUCTL_NONE) + +static const struct pmux_pingrp_desc tegra20_pingroups[] = { + PIN(ATA, IDE, NAND, GMI, RSVD4), + PIN(ATB, IDE, NAND, GMI, SDIO4), + PIN(ATC, IDE, NAND, GMI, SDIO4), + PIN(ATD, IDE, NAND, GMI, SDIO4), + PIN(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC), + PIN(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4), + PIN(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK), + PIN(DAP1, DAP1, RSVD2, GMI, SDIO2), + + PIN(DAP2, DAP2, TWC, RSVD3, GMI), + PIN(DAP3, DAP3, RSVD2, RSVD3, RSVD4), + PIN(DAP4, DAP4, RSVD2, GMI, RSVD4), + PIN(DTA, RSVD1, SDIO2, VI, RSVD4), + PIN(DTB, RSVD1, RSVD2, VI, SPI1), + PIN(DTC, RSVD1, RSVD2, VI, RSVD4), + PIN(DTD, RSVD1, SDIO2, VI, RSVD4), + PIN(DTE, RSVD1, RSVD2, VI, SPI1), + + PINP(GPU, PWM, UARTA, GMI, RSVD4, GPSLXAU), + PIN(GPV, PCIE, RSVD2, RSVD3, RSVD4), + PIN(I2CP, I2C, RSVD2, RSVD3, RSVD4), + PIN(IRTX, UARTA, UARTB, GMI, SPI4), + PIN(IRRX, UARTA, UARTB, GMI, SPI4), + PIN(KBCB, KBC, NAND, SDIO2, MIO), + PIN(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL), + PINP(PMC, PWR_ON, PWR_INTR, RSVD3, RSVD4, NONE), + + PIN(PTA, I2C2, HDMI, GMI, RSVD4), + PIN(RM, I2C, RSVD2, RSVD3, RSVD4), + PIN(KBCE, KBC, NAND, OWR, RSVD4), + PIN(KBCF, KBC, NAND, TRACE, MIO), + PIN(GMA, UARTE, SPI3, GMI, SDIO4), + PIN(GMC, UARTD, SPI4, GMI, SFLASH), + PIN(SDMMC1, SDIO1, RSVD2, UARTE, UARTA), + PIN(OWC, OWR, RSVD2, RSVD3, RSVD4), + + PIN(GME, RSVD1, DAP5, GMI, SDIO4), + PIN(SDC, PWM, TWC, SDIO3, SPI3), + PIN(SDD, UARTA, PWM, SDIO3, SPI3), + PIN_RESERVED, + PINP(SLXA, PCIE, SPI4, SDIO3, SPI2, CRTP), + PIN(SLXC, SPDIF, SPI4, SDIO3, SPI2), + PIN(SLXD, SPDIF, SPI4, SDIO3, SPI2), + PIN(SLXK, PCIE, SPI4, SDIO3, SPI2), + + PIN(SPDI, SPDIF, RSVD2, I2C, SDIO2), + PIN(SPDO, SPDIF, RSVD2, I2C, SDIO2), + PIN(SPIA, SPI1, SPI2, SPI3, GMI), + PIN(SPIB, SPI1, SPI2, SPI3, GMI), + PIN(SPIC, SPI1, SPI2, SPI3, GMI), + PIN(SPID, SPI2, SPI1, SPI2_ALT, GMI), + PIN(SPIE, SPI2, SPI1, SPI2_ALT, GMI), + PIN(SPIF, SPI3, SPI1, SPI2, RSVD4), + + PIN(SPIG, SPI3, SPI2, SPI2_ALT, I2C), + PIN(SPIH, SPI3, SPI2, SPI2_ALT, I2C), + PIN(UAA, SPI3, MIPI_HS, UARTA, ULPI), + PIN(UAB, SPI2, MIPI_HS, UARTA, ULPI), + PIN(UAC, OWR, RSVD2, RSVD3, RSVD4), + PIN(UAD, UARTB, SPDIF, UARTA, SPI4), + PIN(UCA, UARTC, RSVD2, GMI, RSVD4), + PIN(UCB, UARTC, PWM, GMI, RSVD4), + + PIN_RESERVED, + PIN(ATE, IDE, NAND, GMI, RSVD4), + PIN(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL), + PIN_RESERVED, + PIN_RESERVED, + PIN(GMB, IDE, NAND, GMI, GMI_INT), + PIN(GMD, RSVD1, NAND, GMI, SFLASH), + PIN(DDC, I2C2, RSVD2, RSVD3, RSVD4), + + /* 64 */ + PINP(LD0, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD1, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD2, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD3, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD4, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD5, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD6, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD7, DISPA, DISPB, XIO, RSVD4, LD17), + + PINP(LD8, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD9, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD10, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD11, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD12, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD13, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD14, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD15, DISPA, DISPB, XIO, RSVD4, LD17), + + PINP(LD16, DISPA, DISPB, XIO, RSVD4, LD17), + PINP(LD17, DISPA, DISPB, RSVD3, RSVD4, LD17), + PINP(LHP0, DISPA, DISPB, RSVD3, RSVD4, LD21_20), + PINP(LHP1, DISPA, DISPB, RSVD3, RSVD4, LD19_18), + PINP(LHP2, DISPA, DISPB, RSVD3, RSVD4, LD19_18), + PINP(LVP0, DISPA, DISPB, RSVD3, RSVD4, LC), + PINP(LVP1, DISPA, DISPB, RSVD3, RSVD4, LD21_20), + PINP(HDINT, HDMI, RSVD2, RSVD3, RSVD4, LC), + + PINP(LM0, DISPA, DISPB, SPI3, RSVD4, LC), + PINP(LM1, DISPA, DISPB, RSVD3, CRT, LC), + PINP(LVS, DISPA, DISPB, XIO, RSVD4, LC), + PINP(LSC0, DISPA, DISPB, XIO, RSVD4, LC), + PINP(LSC1, DISPA, DISPB, SPI3, HDMI, LS), + PINP(LSCK, DISPA, DISPB, SPI3, HDMI, LS), + PINP(LDC, DISPA, DISPB, RSVD3, RSVD4, LS), + PINP(LCSN, DISPA, DISPB, SPI3, RSVD4, LS), + + /* 96 */ + PINP(LSPI, DISPA, DISPB, XIO, HDMI, LC), + PINP(LSDA, DISPA, DISPB, SPI3, HDMI, LS), + PINP(LSDI, DISPA, DISPB, SPI3, RSVD4, LS), + PINP(LPW0, DISPA, DISPB, SPI3, HDMI, LS), + PINP(LPW1, DISPA, DISPB, RSVD3, RSVD4, LS), + PINP(LPW2, DISPA, DISPB, SPI3, HDMI, LS), + PINP(LDI, DISPA, DISPB, RSVD3, RSVD4, LD23_22), + PINP(LHS, DISPA, DISPB, XIO, RSVD4, LC), + + PINP(LPP, DISPA, DISPB, RSVD3, RSVD4, LD23_22), + PIN_RESERVED, + PIN(KBCD, KBC, NAND, SDIO2, MIO), + PIN(GPU7, RTCK, RSVD2, RSVD3, RSVD4), + PIN(DTF, I2C3, RSVD2, VI, RSVD4), + PIN(UDA, SPI1, RSVD2, UARTD, ULPI), + PIN(CRTP, CRT, RSVD2, RSVD3, RSVD4), + PINP(SDB, UARTA, PWM, SDIO3, SPI2, NONE), + + /* these pin groups only have pullup and pull down control */ + DRVGRP(CK32), + DRVGRP(DDRC), + DRVGRP(PMCA), + DRVGRP(PMCB), + DRVGRP(PMCC), + DRVGRP(PMCD), + DRVGRP(PMCE), + DRVGRP(XM2C), + DRVGRP(XM2D), +}; +const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra20_pingroups; diff --git a/arch/arm/mach-tegra/tegra20/pmu.c b/arch/arm/mach-tegra/tegra20/pmu.c new file mode 100644 index 0000000000..a774246a27 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/pmu.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010,2011 NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define VDD_CORE_NOMINAL_T25 0x17 /* 1.3v */ +#define VDD_CPU_NOMINAL_T25 0x10 /* 1.125v */ + +#define VDD_CORE_NOMINAL_T20 0x16 /* 1.275v */ +#define VDD_CPU_NOMINAL_T20 0x0f /* 1.1v */ + +#define VDD_RELATION 0x02 /* 50mv */ +#define VDD_TRANSITION_STEP 0x06 /* 150mv */ +#define VDD_TRANSITION_RATE 0x06 /* 3.52mv/us */ + +#define PMI_I2C_ADDRESS 0x34 /* chip requires this address */ + +int pmu_set_nominal(void) +{ + struct udevice *bus, *dev; + int core, cpu; + int ret; + + /* by default, the table has been filled with T25 settings */ + switch (tegra_get_chip_sku()) { + case TEGRA_SOC_T20: + core = VDD_CORE_NOMINAL_T20; + cpu = VDD_CPU_NOMINAL_T20; + break; + case TEGRA_SOC_T25: + core = VDD_CORE_NOMINAL_T25; + cpu = VDD_CPU_NOMINAL_T25; + break; + default: + debug("%s: Unknown SKU id\n", __func__); + return -1; + } + + ret = tegra_i2c_get_dvc_bus(&bus); + if (ret) { + debug("%s: Cannot find DVC I2C bus\n", __func__); + return ret; + } + ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, 1, &dev); + if (ret) { + debug("%s: Cannot find DVC I2C chip\n", __func__); + return ret; + } + + tps6586x_init(dev); + tps6586x_set_pwm_mode(TPS6586X_PWM_SM1); + return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP, + VDD_TRANSITION_RATE, VDD_RELATION); +} diff --git a/arch/arm/mach-tegra/tegra20/pwm.c b/arch/arm/mach-tegra/tegra20/pwm.c new file mode 100644 index 0000000000..5b886363f8 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/pwm.c @@ -0,0 +1,86 @@ +/* + * Tegra2 pulse width frequency modulator definitions + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +struct pwm_info { + struct pwm_ctlr *pwm; /* Registers for our pwm controller */ + int pwm_node; /* PWM device tree node */ +} local; + +void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider) +{ + u32 reg; + + assert(channel < PWM_NUM_CHANNELS); + + /* TODO: Can we use clock_adjust_periph_pll_div() here? */ + clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, rate); + + reg = PWM_ENABLE_MASK; + reg |= pulse_width << PWM_WIDTH_SHIFT; + reg |= freq_divider << PWM_DIVIDER_SHIFT; + writel(reg, &local.pwm[channel].control); + debug("%s: channel=%d, rate=%d\n", __func__, channel, rate); +} + +int pwm_request(const void *blob, int node, const char *prop_name) +{ + int pwm_node; + u32 data[3]; + + if (fdtdec_get_int_array(blob, node, prop_name, data, + ARRAY_SIZE(data))) { + debug("%s: Cannot decode PWM property '%s'\n", __func__, + prop_name); + return -1; + } + + pwm_node = fdt_node_offset_by_phandle(blob, data[0]); + if (pwm_node != local.pwm_node) { + debug("%s: PWM property '%s' phandle %d not recognised" + "- expecting %d\n", __func__, prop_name, data[0], + local.pwm_node); + return -1; + } + if (data[1] >= PWM_NUM_CHANNELS) { + debug("%s: PWM property '%s': invalid channel %u\n", __func__, + prop_name, data[1]); + return -1; + } + + /* + * TODO: We could maintain a list of requests, but it might not be + * worth it for U-Boot. + */ + return data[1]; +} + +int pwm_init(const void *blob) +{ + local.pwm_node = fdtdec_next_compatible(blob, 0, + COMPAT_NVIDIA_TEGRA20_PWM); + if (local.pwm_node < 0) { + debug("%s: Cannot find device tree node\n", __func__); + return -1; + } + + local.pwm = (struct pwm_ctlr *)fdtdec_get_addr(blob, local.pwm_node, + "reg"); + if (local.pwm == (struct pwm_ctlr *)FDT_ADDR_T_NONE) { + debug("%s: Cannot find pwm reg address\n", __func__); + return -1; + } + debug("Tegra PWM at %p, node %d\n", local.pwm, local.pwm_node); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra20/warmboot.c b/arch/arm/mach-tegra/tegra20/warmboot.c new file mode 100644 index 0000000000..5fdc4bbb50 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/warmboot.c @@ -0,0 +1,372 @@ +/* + * (C) Copyright 2010 - 2011 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_TEGRA_CLOCK_SCALING +#error "You must enable CONFIG_TEGRA_CLOCK_SCALING to use CONFIG_TEGRA_LP0" +#endif + +/* + * This is the place in SRAM where the SDRAM parameters are stored. There + * are 4 blocks, one for each RAM code + */ +#define SDRAM_PARAMS_BASE (NV_PA_BASE_SRAM + 0x188) + +/* TODO: If we later add support for the Misc GP controller, refactor this */ +union xm2cfga_reg { + struct { + u32 reserved0:2; + u32 hsm_en:1; + u32 reserved1:2; + u32 preemp_en:1; + u32 vref_en:1; + u32 reserved2:5; + u32 cal_drvdn:5; + u32 reserved3:3; + u32 cal_drvup:5; + u32 reserved4:3; + u32 cal_drvdn_slwr:2; + u32 cal_drvup_slwf:2; + }; + u32 word; +}; + +union xm2cfgd_reg { + struct { + u32 reserved0:2; + u32 hsm_en:1; + u32 schmt_en:1; + u32 lpmd:2; + u32 vref_en:1; + u32 reserved1:5; + u32 cal_drvdn:5; + u32 reserved2:3; + u32 cal_drvup:5; + u32 reserved3:3; + u32 cal_drvdn_slwr:2; + u32 cal_drvup_slwf:2; + }; + u32 word; +}; + +/* + * TODO: This register is not documented in the TRM yet. We could move this + * into the EMC and give it a proper interface, but not while it is + * undocumented. + */ +union fbio_spare_reg { + struct { + u32 reserved:24; + u32 cfg_wb0:8; + }; + u32 word; +}; + +/* We pack the resume information into these unions for later */ +union scratch2_reg { + struct { + u32 pllm_base_divm:5; + u32 pllm_base_divn:10; + u32 pllm_base_divp:3; + u32 pllm_misc_lfcon:4; + u32 pllm_misc_cpcon:4; + u32 gp_xm2cfga_padctrl_preemp:1; + u32 gp_xm2cfgd_padctrl_schmt:1; + u32 osc_ctrl_xobp:1; + u32 memory_type:3; + }; + u32 word; +}; + +union scratch4_reg { + struct { + u32 emc_clock_divider:8; + u32 pllm_stable_time:8; + u32 pllx_stable_time:8; + u32 emc_fbio_spare_cfg_wb0:8; + }; + u32 word; +}; + +union scratch24_reg { + struct { + u32 emc_auto_cal_wait:8; + u32 emc_pin_program_wait:8; + u32 warmboot_wait:8; + u32 reserved:8; + }; + u32 word; +}; + +int warmboot_save_sdram_params(void) +{ + u32 ram_code; + struct sdram_params sdram; + struct apb_misc_pp_ctlr *apb_misc = + (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + struct emc_ctlr *emc = emc_get_controller(gd->fdt_blob); + union scratch2_reg scratch2; + union scratch4_reg scratch4; + union scratch24_reg scratch24; + union xm2cfga_reg xm2cfga; + union xm2cfgd_reg xm2cfgd; + union fbio_spare_reg fbio_spare; + + /* get ram code that is used as index to array sdram_params in BCT */ + ram_code = (readl(&apb_misc->strapping_opt_a) >> + STRAP_OPT_A_RAM_CODE_SHIFT) & 3; + memcpy(&sdram, + (char *)((struct sdram_params *)SDRAM_PARAMS_BASE + ram_code), + sizeof(sdram)); + + xm2cfga.word = readl(&gp->xm2cfga); + xm2cfgd.word = readl(&gp->xm2cfgd); + + scratch2.word = 0; + scratch2.osc_ctrl_xobp = clock_get_osc_bypass(); + + /* Get the memory PLL settings */ + { + u32 divm, divn, divp, cpcon, lfcon; + + if (clock_ll_read_pll(CLOCK_ID_MEMORY, &divm, &divn, &divp, + &cpcon, &lfcon)) + return -1; + scratch2.pllm_base_divm = divm; + scratch2.pllm_base_divn = divn; + scratch2.pllm_base_divp = divp; + scratch2.pllm_misc_cpcon = cpcon; + scratch2.pllm_misc_lfcon = lfcon; + } + + scratch2.gp_xm2cfga_padctrl_preemp = xm2cfga.preemp_en; + scratch2.gp_xm2cfgd_padctrl_schmt = xm2cfgd.schmt_en; + scratch2.memory_type = sdram.memory_type; + writel(scratch2.word, &pmc->pmc_scratch2); + + /* collect data from various sources for pmc_scratch4 */ + fbio_spare.word = readl(&emc->fbio_spare); + scratch4.word = 0; + scratch4.emc_fbio_spare_cfg_wb0 = fbio_spare.cfg_wb0; + scratch4.emc_clock_divider = sdram.emc_clock_divider; + scratch4.pllm_stable_time = -1; + scratch4.pllx_stable_time = -1; + writel(scratch4.word, &pmc->pmc_scratch4); + + /* collect various data from sdram for pmc_scratch24 */ + scratch24.word = 0; + scratch24.emc_pin_program_wait = sdram.emc_pin_program_wait; + scratch24.emc_auto_cal_wait = sdram.emc_auto_cal_wait; + scratch24.warmboot_wait = sdram.warm_boot_wait; + writel(scratch24.word, &pmc->pmc_scratch24); + + return 0; +} + +static u32 get_major_version(void) +{ + u32 major_id; + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + + major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >> + HIDREV_MAJORPREV_SHIFT; + return major_id; +} + +static int is_production_mode_fuse_set(struct fuse_regs *fuse) +{ + return readl(&fuse->production_mode); +} + +static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse) +{ + return readl(&fuse->security_mode); +} + +static int is_failure_analysis_mode(struct fuse_regs *fuse) +{ + return readl(&fuse->fa); +} + +static int ap20_is_odm_production_mode(void) +{ + struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; + + if (!is_failure_analysis_mode(fuse) && + is_odm_production_mode_fuse_set(fuse)) + return 1; + else + return 0; +} + +static int ap20_is_production_mode(void) +{ + struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; + + if (get_major_version() == 0) + return 1; + + if (!is_failure_analysis_mode(fuse) && + is_production_mode_fuse_set(fuse) && + !is_odm_production_mode_fuse_set(fuse)) + return 1; + else + return 0; +} + +static enum fuse_operating_mode fuse_get_operation_mode(void) +{ + u32 chip_id; + struct apb_misc_gp_ctlr *gp = + (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; + + chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> + HIDREV_CHIPID_SHIFT; + if (chip_id == CHIPID_TEGRA20) { + if (ap20_is_odm_production_mode()) { + printf("!! odm_production_mode is not supported !!\n"); + return MODE_UNDEFINED; + } else + if (ap20_is_production_mode()) + return MODE_PRODUCTION; + else + return MODE_UNDEFINED; + } + return MODE_UNDEFINED; +} + +static void determine_crypto_options(int *is_encrypted, int *is_signed, + int *use_zero_key) +{ + switch (fuse_get_operation_mode()) { + case MODE_PRODUCTION: + *is_encrypted = 0; + *is_signed = 1; + *use_zero_key = 1; + break; + case MODE_UNDEFINED: + default: + *is_encrypted = 0; + *is_signed = 0; + *use_zero_key = 0; + break; + } +} + +static int sign_wb_code(u32 start, u32 length, int use_zero_key) +{ + int err; + u8 *source; /* Pointer to source */ + u8 *hash; + + /* Calculate AES block parameters. */ + source = (u8 *)(start + offsetof(struct wb_header, random_aes_block)); + length -= offsetof(struct wb_header, random_aes_block); + hash = (u8 *)(start + offsetof(struct wb_header, hash)); + err = sign_data_block(source, length, hash); + + return err; +} + +int warmboot_prepare_code(u32 seg_address, u32 seg_length) +{ + int err = 0; + u32 length; /* length of the signed/encrypt code */ + struct wb_header *dst_header; /* Pointer to dest WB header */ + int is_encrypted; /* Segment is encrypted */ + int is_signed; /* Segment is signed */ + int use_zero_key; /* Use key of all zeros */ + + /* Determine crypto options. */ + determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key); + + /* Get the actual code limits. */ + length = roundup(((u32)wb_end - (u32)wb_start), 16); + + /* + * The region specified by seg_address must be in SDRAM and must be + * nonzero in length. + */ + if (seg_length == 0 || seg_address < NV_PA_SDRAM_BASE || + seg_address + seg_length >= NV_PA_SDRAM_BASE + gd->ram_size) { + err = -EFAULT; + goto fail; + } + + /* Things must be 16-byte aligned. */ + if ((seg_length & 0xF) || (seg_address & 0xF)) { + err = -EINVAL; + goto fail; + } + + /* Will the code fit? (destination includes wb_header + wb code) */ + if (seg_length < (length + sizeof(struct wb_header))) { + err = -EINVAL; + goto fail; + } + + dst_header = (struct wb_header *)seg_address; + memset((char *)dst_header, 0, sizeof(struct wb_header)); + + /* Populate the random_aes_block as requested. */ + { + u32 *aes_block = (u32 *)&(dst_header->random_aes_block); + u32 *end = (u32 *)(((u32)aes_block) + + sizeof(dst_header->random_aes_block)); + + do { + *aes_block++ = 0; + } while (aes_block < end); + } + + /* Populate the header. */ + dst_header->length_insecure = length + sizeof(struct wb_header); + dst_header->length_secure = length + sizeof(struct wb_header); + dst_header->destination = NV_WB_RUN_ADDRESS; + dst_header->entry_point = NV_WB_RUN_ADDRESS; + dst_header->code_length = length; + + if (is_encrypted) { + printf("!!!! Encryption is not supported !!!!\n"); + dst_header->length_insecure = 0; + err = -EACCES; + goto fail; + } else + /* copy the wb code directly following dst_header. */ + memcpy((char *)(dst_header+1), (char *)wb_start, length); + + if (is_signed) + err = sign_wb_code(seg_address, dst_header->length_insecure, + use_zero_key); + +fail: + if (err) + printf("Warning: warmboot code copy failed (error=%d)\n", err); + + return err; +} diff --git a/arch/arm/mach-tegra/tegra20/warmboot_avp.c b/arch/arm/mach-tegra/tegra20/warmboot_avp.c new file mode 100644 index 0000000000..27ce5f480f --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/warmboot_avp.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2010 - 2011 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "warmboot_avp.h" + +#define DEBUG_RESET_CORESIGHT + +void wb_start(void) +{ + struct apb_misc_pp_ctlr *apb_misc = + (struct apb_misc_pp_ctlr *)NV_PA_APB_MISC_BASE; + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + union osc_ctrl_reg osc_ctrl; + union pllx_base_reg pllx_base; + union pllx_misc_reg pllx_misc; + union scratch3_reg scratch3; + u32 reg; + + /* enable JTAG & TBE */ + writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &apb_misc->cfg_ctl); + + /* Are we running where we're supposed to be? */ + asm volatile ( + "adr %0, wb_start;" /* reg: wb_start address */ + : "=r"(reg) /* output */ + /* no input, no clobber list */ + ); + + if (reg != NV_WB_RUN_ADDRESS) + goto do_reset; + + /* Are we running with AVP? */ + if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP) + goto do_reset; + +#ifdef DEBUG_RESET_CORESIGHT + /* Assert CoreSight reset */ + reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); + reg |= SWR_CSITE_RST; + writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); +#endif + + /* TODO: Set the drive strength - maybe make this a board parameter? */ + osc_ctrl.word = readl(&clkrst->crc_osc_ctrl); + osc_ctrl.xofs = 4; + osc_ctrl.xoe = 1; + writel(osc_ctrl.word, &clkrst->crc_osc_ctrl); + + /* Power up the CPU complex if necessary */ + if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) { + reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START; + writel(reg, &pmc->pmc_pwrgate_toggle); + while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) + ; + } + + /* Remove the I/O clamps from the CPU power partition. */ + reg = readl(&pmc->pmc_remove_clamping); + reg |= CPU_CLMP; + writel(reg, &pmc->pmc_remove_clamping); + + reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP; + writel(reg, &flow->halt_cop_events); + + /* Assert CPU complex reset */ + reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); + reg |= CPU_RST; + writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); + + /* Hold both CPUs in reset */ + reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 | + CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1; + writel(reg, &clkrst->crc_cpu_cmplx_set); + + /* Halt CPU1 at the flow controller for uni-processor configurations */ + writel(EVENT_MODE_STOP, &flow->halt_cpu1_events); + + /* + * Set the CPU reset vector. SCRATCH41 contains the physical + * address of the CPU-side restoration code. + */ + reg = readl(&pmc->pmc_scratch41); + writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Select CPU complex clock source */ + writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + + /* Start the CPU0 clock and stop the CPU1 clock */ + reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN | + CPU_CMPLX_CPU1_CLK_STP_STOP; + writel(reg, &clkrst->crc_clk_cpu_cmplx); + + /* Enable the CPU complex clock */ + reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]); + reg |= CLK_ENB_CPU; + writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]); + + /* Make sure the resets were held for at least 2 microseconds */ + reg = readl(TIMER_USEC_CNTR); + while (readl(TIMER_USEC_CNTR) <= (reg + 2)) + ; + +#ifdef DEBUG_RESET_CORESIGHT + /* + * De-assert CoreSight reset. + * NOTE: We're leaving the CoreSight clock on the oscillator for + * now. It will be restored to its original clock source + * when the CPU-side restoration code runs. + */ + reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]); + reg &= ~SWR_CSITE_RST; + writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]); +#endif + + /* Unlock the CPU CoreSight interfaces */ + reg = 0xC5ACCE55; + writel(reg, CSITE_CPU_DBG0_LAR); + writel(reg, CSITE_CPU_DBG1_LAR); + + /* + * Sample the microsecond timestamp again. This is the time we must + * use when returning from LP0 for PLL stabilization delays. + */ + reg = readl(TIMER_USEC_CNTR); + writel(reg, &pmc->pmc_scratch1); + + pllx_base.word = 0; + pllx_misc.word = 0; + scratch3.word = readl(&pmc->pmc_scratch3); + + /* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */ + reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1; + + /* + * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and + * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz. + * + * reg is used to calculate the pllx freq, which is used to determine if + * to set dccon or not. + */ + if (reg > 26) + reg = 19; + + /* PLLX_BASE.PLLX_DIVM */ + if (scratch3.pllx_base_divm == reg) + reg = 0; + else + reg = 1; + + /* PLLX_BASE.PLLX_DIVN */ + pllx_base.divn = scratch3.pllx_base_divn; + reg = scratch3.pllx_base_divn << reg; + + /* PLLX_BASE.PLLX_DIVP */ + pllx_base.divp = scratch3.pllx_base_divp; + reg = reg >> scratch3.pllx_base_divp; + + pllx_base.bypass = 1; + + /* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */ + if (reg > 600) + pllx_misc.dccon = 1; + + /* PLLX_MISC_LFCON */ + pllx_misc.lfcon = scratch3.pllx_misc_lfcon; + + /* PLLX_MISC_CPCON */ + pllx_misc.cpcon = scratch3.pllx_misc_cpcon; + + writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc); + writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + + pllx_base.enable = 1; + writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + pllx_base.bypass = 0; + writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base); + + writel(0, flow->halt_cpu_events); + + reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0; + writel(reg, &clkrst->crc_cpu_cmplx_clr); + + reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE | + PLLM_OUT1_RATIO_VAL_8; + writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out[0]); + + reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 | + SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 | + SCLK_SYS_STATE_IDLE; + writel(reg, &clkrst->crc_sclk_brst_pol); + + /* avp_resume: no return after the write */ + reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]); + reg &= ~CPU_RST; + writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]); + + /* avp_halt: */ +avp_halt: + reg = EVENT_MODE_STOP | EVENT_JTAG; + writel(reg, flow->halt_cop_events); + goto avp_halt; + +do_reset: + /* + * Execution comes here if something goes wrong. The chip is reset and + * a cold boot is performed. + */ + writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]); + goto do_reset; +} + +/* + * wb_end() is a dummy function, and must be directly following wb_start(), + * and is used to calculate the size of wb_start(). + */ +void wb_end(void) +{ +} diff --git a/arch/arm/mach-tegra/tegra20/warmboot_avp.h b/arch/arm/mach-tegra/tegra20/warmboot_avp.h new file mode 100644 index 0000000000..7b86acb156 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/warmboot_avp.h @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2010, 2011 + * NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _WARMBOOT_AVP_H_ +#define _WARMBOOT_AVP_H_ + +#define TEGRA_DEV_L 0 +#define TEGRA_DEV_H 1 +#define TEGRA_DEV_U 2 + +#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE) +#define SIMPLE_PLLE (CLOCK_ID_EPCI - CLOCK_ID_FIRST_SIMPLE) + +#define TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0) +#define TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4) + +#define USEC_CFG_DIVISOR_MASK 0xffff + +#define CONFIG_CTL_TBE (1 << 7) +#define CONFIG_CTL_JTAG (1 << 6) + +#define CPU_RST (1 << 0) +#define CLK_ENB_CPU (1 << 0) +#define SWR_TRIG_SYS_RST (1 << 2) +#define SWR_CSITE_RST (1 << 9) + +#define PWRGATE_STATUS_CPU (1 << 0) +#define PWRGATE_TOGGLE_PARTID_CPU (0 << 0) +#define PWRGATE_TOGGLE_START (1 << 8) + +#define CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 (3 << 0) +#define CPU_CMPLX_CPU0_CLK_STP_STOP (1 << 8) +#define CPU_CMPLX_CPU0_CLK_STP_RUN (0 << 8) +#define CPU_CMPLX_CPU1_CLK_STP_STOP (1 << 9) +#define CPU_CMPLX_CPU1_CLK_STP_RUN (0 << 9) + +#define CPU_CMPLX_CPURESET0 (1 << 0) +#define CPU_CMPLX_CPURESET1 (1 << 1) +#define CPU_CMPLX_DERESET0 (1 << 4) +#define CPU_CMPLX_DERESET1 (1 << 5) +#define CPU_CMPLX_DBGRESET0 (1 << 12) +#define CPU_CMPLX_DBGRESET1 (1 << 13) + +#define PLLM_OUT1_RSTN_RESET_DISABLE (1 << 0) +#define PLLM_OUT1_CLKEN_ENABLE (1 << 1) +#define PLLM_OUT1_RATIO_VAL_8 (8 << 8) + +#define SCLK_SYS_STATE_IDLE (1 << 28) +#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 (7 << 12) +#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 (7 << 8) +#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1 (7 << 4) +#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 (7 << 0) + +#define EVENT_ZERO_VAL_20 (20 << 0) +#define EVENT_MSEC (1 << 24) +#define EVENT_JTAG (1 << 28) +#define EVENT_MODE_STOP (2 << 29) + +#define CCLK_PLLP_BURST_POLICY 0x20004444 + +#endif diff --git a/arch/arm/mach-tegra/tegra30/Kconfig b/arch/arm/mach-tegra/tegra30/Kconfig new file mode 100644 index 0000000000..3abdc7ba17 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/Kconfig @@ -0,0 +1,32 @@ +if TEGRA30 + +choice + prompt "Tegra30 board select" + +config TARGET_APALIS_T30 + bool "Toradex Apalis T30 board" + +config TARGET_BEAVER + bool "NVIDIA Tegra30 Beaver evaluation board" + +config TARGET_CARDHU + bool "NVIDIA Tegra30 Cardhu evaluation board" + +config TARGET_COLIBRI_T30 + bool "Toradex Colibri T30 board" + +config TARGET_TEC_NG + bool "Avionic Design TEC-NG board" + +endchoice + +config SYS_SOC + default "tegra30" + +source "board/toradex/apalis_t30/Kconfig" +source "board/nvidia/beaver/Kconfig" +source "board/nvidia/cardhu/Kconfig" +source "board/toradex/colibri_t30/Kconfig" +source "board/avionic-design/tec-ng/Kconfig" + +endif diff --git a/arch/arm/mach-tegra/tegra30/Makefile b/arch/arm/mach-tegra/tegra30/Makefile new file mode 100644 index 0000000000..bc250deba8 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +obj-$(CONFIG_SPL_BUILD) += cpu.o + +obj-y += clock.o funcmux.o pinmux.o diff --git a/arch/arm/mach-tegra/tegra30/clock.c b/arch/arm/mach-tegra/tegra30/clock.c new file mode 100644 index 0000000000..0eb0f0ade3 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/clock.c @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra30 Clock control functions */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Clock types that we can use as a source. The Tegra30 has muxes for the + * peripheral clocks, and in most cases there are four options for the clock + * source. This gives us a clock 'type' and exploits what commonality exists + * in the device. + * + * Letters are obvious, except for T which means CLK_M, and S which means the + * clock derived from 32KHz. Beware that CLK_M (also called OSC in the + * datasheet) and PLL_M are different things. The former is the basic + * clock supplied to the SOC from an external oscillator. The latter is the + * memory clock PLL. + * + * See definitions in clock_id in the header file. + */ +enum clock_type_id { + CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ + CLOCK_TYPE_MCPA, /* and so on */ + CLOCK_TYPE_MCPT, + CLOCK_TYPE_PCM, + CLOCK_TYPE_PCMT, + CLOCK_TYPE_PCMT16, + CLOCK_TYPE_PDCT, + CLOCK_TYPE_ACPT, + CLOCK_TYPE_ASPTE, + CLOCK_TYPE_PMDACD2T, + CLOCK_TYPE_PCST, + + CLOCK_TYPE_COUNT, + CLOCK_TYPE_NONE = -1, /* invalid clock type */ +}; + +enum { + CLOCK_MAX_MUX = 8 /* number of source options for each clock */ +}; + +/* + * Clock source mux for each clock type. This just converts our enum into + * a list of mux sources for use by the code. + * + * Note: + * The extra column in each clock source array is used to store the mask + * bits in its register for the source. + */ +#define CLK(x) CLOCK_ID_ ## x +static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { + { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_30}, + { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), + CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), + CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), + MASK_BITS_31_29}, + { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), + CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), + MASK_BITS_31_28} +}; + +/* + * Clock type for each peripheral clock source. We put the name in each + * record just so it is easy to match things up + */ +#define TYPE(name, type) type +static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { + /* 0x00 */ + TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), + TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), + + /* 0x08 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), + + /* 0x10 */ + TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), + + /* 0x18 */ + TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ + TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), + + /* 0x20 */ + TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), + TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), + + /* 0x28 */ + TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), + + /* 0x30 */ + TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x38h */ /* Jumps to reg offset 0x3B0h - new for T30 */ + TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), + TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ + TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), + TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), + TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), + + /* 0x40 */ + TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), + TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), + + /* 0x48 */ + TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), + TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ + TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + + /* 0x50 */ + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), + TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ + TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), + TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), +}; + +/* + * This array translates a periph_id to a periphc_internal_id + * + * Not present/matched up: + * uint vi_sensor; _VI_SENSOR_0, 0x1A8 + * SPDIF - which is both 0x08 and 0x0c + * + */ +#define NONE(name) (-1) +#define OFFSET(name, value) PERIPHC_ ## name +static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { + /* Low word: 31:0 */ + NONE(CPU), + NONE(COP), + NONE(TRIGSYS), + NONE(RESERVED3), + NONE(RESERVED4), + NONE(TMR), + PERIPHC_UART1, + PERIPHC_UART2, /* and vfir 0x68 */ + + /* 8 */ + NONE(GPIO), + PERIPHC_SDMMC2, + NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ + PERIPHC_I2S1, + PERIPHC_I2C1, + PERIPHC_NDFLASH, + PERIPHC_SDMMC1, + PERIPHC_SDMMC4, + + /* 16 */ + NONE(RESERVED16), + PERIPHC_PWM, + PERIPHC_I2S2, + PERIPHC_EPP, + PERIPHC_VI, + PERIPHC_G2D, + NONE(USBD), + NONE(ISP), + + /* 24 */ + PERIPHC_G3D, + NONE(RESERVED25), + PERIPHC_DISP2, + PERIPHC_DISP1, + PERIPHC_HOST1X, + NONE(VCP), + PERIPHC_I2S0, + NONE(CACHE2), + + /* Middle word: 63:32 */ + NONE(MEM), + NONE(AHBDMA), + NONE(APBDMA), + NONE(RESERVED35), + NONE(RESERVED36), + NONE(STAT_MON), + NONE(RESERVED38), + NONE(RESERVED39), + + /* 40 */ + NONE(KFUSE), + PERIPHC_SBC1, + PERIPHC_NOR, + NONE(RESERVED43), + PERIPHC_SBC2, + NONE(RESERVED45), + PERIPHC_SBC3, + PERIPHC_DVC_I2C, + + /* 48 */ + NONE(DSI), + PERIPHC_TVO, /* also CVE 0x40 */ + PERIPHC_MIPI, + PERIPHC_HDMI, + NONE(CSI), + PERIPHC_TVDAC, + PERIPHC_I2C2, + PERIPHC_UART3, + + /* 56 */ + NONE(RESERVED56), + PERIPHC_EMC, + NONE(USB2), + NONE(USB3), + PERIPHC_MPE, + PERIPHC_VDE, + NONE(BSEA), + NONE(BSEV), + + /* Upper word 95:64 */ + PERIPHC_SPEEDO, + PERIPHC_UART4, + PERIPHC_UART5, + PERIPHC_I2C3, + PERIPHC_SBC4, + PERIPHC_SDMMC3, + NONE(PCIE), + PERIPHC_OWR, + + /* 72 */ + NONE(AFI), + PERIPHC_CSITE, + NONE(PCIEXCLK), + NONE(AVPUCQ), + NONE(RESERVED76), + NONE(RESERVED77), + NONE(RESERVED78), + NONE(DTV), + + /* 80 */ + PERIPHC_NANDSPEED, + PERIPHC_I2CSLOW, + NONE(DSIB), + NONE(RESERVED83), + NONE(IRAMA), + NONE(IRAMB), + NONE(IRAMC), + NONE(IRAMD), + + /* 88 */ + NONE(CRAM2), + NONE(RESERVED89), + NONE(MDOUBLER), + NONE(RESERVED91), + NONE(SUSOUT), + NONE(RESERVED93), + NONE(RESERVED94), + NONE(RESERVED95), + + /* V word: 31:0 */ + NONE(CPUG), + NONE(CPULP), + PERIPHC_G3D2, + PERIPHC_MSELECT, + PERIPHC_TSENSOR, + PERIPHC_I2S3, + PERIPHC_I2S4, + PERIPHC_I2C4, + + /* 08 */ + PERIPHC_SBC5, + PERIPHC_SBC6, + PERIPHC_AUDIO, + NONE(APBIF), + PERIPHC_DAM0, + PERIPHC_DAM1, + PERIPHC_DAM2, + PERIPHC_HDA2CODEC2X, + + /* 16 */ + NONE(ATOMICS), + NONE(RESERVED17), + NONE(RESERVED18), + NONE(RESERVED19), + NONE(RESERVED20), + NONE(RESERVED21), + NONE(RESERVED22), + PERIPHC_ACTMON, + + /* 24 */ + NONE(RESERVED24), + NONE(RESERVED25), + NONE(RESERVED26), + NONE(RESERVED27), + PERIPHC_SATA, + PERIPHC_HDA, + NONE(RESERVED30), + NONE(RESERVED31), + + /* W word: 31:0 */ + NONE(HDA2HDMICODEC), + NONE(SATACOLD), + NONE(RESERVED0_PCIERX0), + NONE(RESERVED1_PCIERX1), + NONE(RESERVED2_PCIERX2), + NONE(RESERVED3_PCIERX3), + NONE(RESERVED4_PCIERX4), + NONE(RESERVED5_PCIERX5), + + /* 40 */ + NONE(CEC), + NONE(RESERVED6_PCIE2), + NONE(RESERVED7_EMC), + NONE(RESERVED8_HDMI), + NONE(RESERVED9_SATA), + NONE(RESERVED10_MIPI), + NONE(EX_RESERVED46), + NONE(EX_RESERVED47), +}; + +/* + * Get the oscillator frequency, from the corresponding hardware configuration + * field. Note that T30 supports 3 new higher freqs, but we map back + * to the old T20 freqs. Support for the higher oscillators is TBD. + */ +enum clock_osc_freq clock_get_osc_freq(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 reg; + + reg = readl(&clkrst->crc_osc_ctrl); + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + if (reg & 1) /* one of the newer freqs */ + printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); + + return reg >> 2; /* Map to most common (T20) freqs */ +} + +/* Returns a pointer to the clock source register for a peripheral */ +u32 *get_periph_source_reg(enum periph_id periph_id) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + enum periphc_internal_id internal_id; + + /* Coresight is a special case */ + if (periph_id == PERIPH_ID_CSI) + return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; + + assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); + internal_id = periph_id_to_internal_id[periph_id]; + assert(internal_id != -1); + if (internal_id >= PERIPHC_VW_FIRST) { + internal_id -= PERIPHC_VW_FIRST; + return &clkrst->crc_clk_src_vw[internal_id]; + } else + return &clkrst->crc_clk_src[internal_id]; +} + +/** + * Given a peripheral ID and the required source clock, this returns which + * value should be programmed into the source mux for that peripheral. + * + * There is special code here to handle the one source type with 5 sources. + * + * @param periph_id peripheral to start + * @param source PLL id of required parent clock + * @param mux_bits Set to number of bits in mux register: 2 or 4 + * @param divider_bits Set to number of divider bits (8 or 16) + * @return mux value (0-4, or -1 if not found) + */ +int get_periph_clock_source(enum periph_id periph_id, + enum clock_id parent, int *mux_bits, int *divider_bits) +{ + enum clock_type_id type; + enum periphc_internal_id internal_id; + int mux; + + assert(clock_periph_id_isvalid(periph_id)); + + internal_id = periph_id_to_internal_id[periph_id]; + assert(periphc_internal_id_isvalid(internal_id)); + + type = clock_periph_type[internal_id]; + assert(clock_type_id_isvalid(type)); + + *mux_bits = clock_source[type][CLOCK_MAX_MUX]; + + if (type == CLOCK_TYPE_PCMT16) + *divider_bits = 16; + else + *divider_bits = 8; + + for (mux = 0; mux < CLOCK_MAX_MUX; mux++) + if (clock_source[type][mux] == parent) + return mux; + + /* if we get here, either us or the caller has made a mistake */ + printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, + parent); + return -1; +} + +void clock_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *clk; + u32 reg; + + /* Enable/disable the clock to this peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) + clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; + else + clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; + reg = readl(clk); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, clk); +} + +void reset_set_enable(enum periph_id periph_id, int enable) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 *reset; + u32 reg; + + /* Enable/disable reset to the peripheral */ + assert(clock_periph_id_isvalid(periph_id)); + if (periph_id < PERIPH_ID_VW_FIRST) + reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; + else + reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; + reg = readl(reset); + if (enable) + reg |= PERIPH_MASK(periph_id); + else + reg &= ~PERIPH_MASK(periph_id); + writel(reg, reset); +} + +#ifdef CONFIG_OF_CONTROL +/* + * Convert a device tree clock ID to our peripheral ID. They are mostly + * the same but we are very cautious so we check that a valid clock ID is + * provided. + * + * @param clk_id Clock ID according to tegra30 device tree binding + * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid + */ +enum periph_id clk_id_to_periph_id(int clk_id) +{ + if (clk_id > PERIPH_ID_COUNT) + return PERIPH_ID_NONE; + + switch (clk_id) { + case PERIPH_ID_RESERVED3: + case PERIPH_ID_RESERVED4: + case PERIPH_ID_RESERVED16: + case PERIPH_ID_RESERVED24: + case PERIPH_ID_RESERVED35: + case PERIPH_ID_RESERVED43: + case PERIPH_ID_RESERVED45: + case PERIPH_ID_RESERVED56: + case PERIPH_ID_PCIEXCLK: + case PERIPH_ID_RESERVED76: + case PERIPH_ID_RESERVED77: + case PERIPH_ID_RESERVED78: + case PERIPH_ID_RESERVED83: + case PERIPH_ID_RESERVED89: + case PERIPH_ID_RESERVED91: + case PERIPH_ID_RESERVED93: + case PERIPH_ID_RESERVED94: + case PERIPH_ID_RESERVED95: + return PERIPH_ID_NONE; + default: + return clk_id; + } +} +#endif /* CONFIG_OF_CONTROL */ + +void clock_early_init(void) +{ + tegra30_set_up_pllp(); +} + +void arch_timer_init(void) +{ +} + +#define PMC_SATA_PWRGT 0x1ac +#define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) +#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) + +#define PLLE_SS_CNTL 0x68 +#define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) +#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) +#define PLLE_SS_CNTL_SSCBYP (1 << 12) +#define PLLE_SS_CNTL_INTERP_RESET (1 << 11) +#define PLLE_SS_CNTL_BYPASS_SS (1 << 10) +#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) + +#define PLLE_BASE 0x0e8 +#define PLLE_BASE_ENABLE_CML (1 << 31) +#define PLLE_BASE_ENABLE (1 << 30) +#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) +#define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) +#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) +#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) + +#define PLLE_MISC 0x0ec +#define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) +#define PLLE_MISC_PLL_READY (1 << 15) +#define PLLE_MISC_LOCK (1 << 11) +#define PLLE_MISC_LOCK_ENABLE (1 << 9) +#define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) + +static int tegra_plle_train(void) +{ + unsigned int timeout = 2000; + unsigned long value; + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); + value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; + writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); + + do { + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if (value & PLLE_MISC_PLL_READY) + break; + + udelay(100); + } while (--timeout); + + if (timeout == 0) { + error("timeout waiting for PLLE to become ready"); + return -ETIMEDOUT; + } + + return 0; +} + +int tegra_plle_enable(void) +{ + unsigned int cpcon = 11, p = 18, n = 150, m = 1, timeout = 1000; + u32 value; + int err; + + /* disable PLLE clock */ + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value &= ~PLLE_BASE_ENABLE_CML; + value &= ~PLLE_BASE_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + /* clear lock enable and setup field */ + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value &= ~PLLE_MISC_LOCK_ENABLE; + value &= ~PLLE_MISC_SETUP_BASE(0xffff); + value &= ~PLLE_MISC_SETUP_EXT(0x3); + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if ((value & PLLE_MISC_PLL_READY) == 0) { + err = tegra_plle_train(); + if (err < 0) { + error("failed to train PLLE: %d", err); + return err; + } + } + + /* configure PLLE */ + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + + value &= ~PLLE_BASE_PLDIV_CML(0x0f); + value |= PLLE_BASE_PLDIV_CML(cpcon); + + value &= ~PLLE_BASE_PLDIV(0x3f); + value |= PLLE_BASE_PLDIV(p); + + value &= ~PLLE_BASE_NDIV(0xff); + value |= PLLE_BASE_NDIV(n); + + value &= ~PLLE_BASE_MDIV(0xff); + value |= PLLE_BASE_MDIV(m); + + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + value |= PLLE_MISC_SETUP_BASE(0x7); + value |= PLLE_MISC_LOCK_ENABLE; + value |= PLLE_MISC_SETUP_EXT(0); + writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | + PLLE_SS_CNTL_BYPASS_SS; + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); + value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; + writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); + + do { + value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); + if (value & PLLE_MISC_LOCK) + break; + + udelay(2); + } while (--timeout); + + if (timeout == 0) { + error("timeout waiting for PLLE to lock"); + return -ETIMEDOUT; + } + + udelay(50); + + value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); + value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); + + value &= ~PLLE_SS_CNTL_SSCINC(0xff); + value |= PLLE_SS_CNTL_SSCINC(0x01); + + value &= ~PLLE_SS_CNTL_SSCBYP; + value &= ~PLLE_SS_CNTL_INTERP_RESET; + value &= ~PLLE_SS_CNTL_BYPASS_SS; + + value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); + value |= PLLE_SS_CNTL_SSCMAX(0x24); + writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); + + return 0; +} diff --git a/arch/arm/mach-tegra/tegra30/cpu.c b/arch/arm/mach-tegra/tegra30/cpu.c new file mode 100644 index 0000000000..c76e74c65f --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/cpu.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../cpu.h" + +/* Tegra30-specific CPU init code */ +void tegra_i2c_ll_write_addr(uint addr, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(config, ®->cnfg); +} + +void tegra_i2c_ll_write_data(uint data, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(data, ®->cmd_data1); + writel(config, ®->cnfg); +} + +#define TPS62366A_I2C_ADDR 0xC0 +#define TPS62366A_SET1_REG 0x01 +#define TPS62366A_SET1_DATA (0x4600 | TPS62366A_SET1_REG) + +#define TPS62361B_I2C_ADDR 0xC0 +#define TPS62361B_SET3_REG 0x03 +#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG) + +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) +#define I2C_SEND_2_BYTES 0x0A02 + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + u32 reg; + + debug("enable_cpu_power_rail entry\n"); + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* Set VDD_CORE to 1.200V. */ +#ifdef CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1 + tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES); +#endif +#ifdef CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3 + tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES); +#endif + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} + +/** + * The T30 requires some special clock initialization, including setting up + * the dvc i2c, turning on mselect and selecting the G CPU cluster + */ +void t30_init_clocks(void) +{ + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + u32 val; + + debug("t30_init_clocks entry\n"); + /* Set active CPU cluster to G */ + clrbits_le32(flow->cluster_control, 1 << 0); + + writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); + + val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | + (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | + (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | + (0 << CLK_SYS_RATE_APB_RATE_SHIFT); + writel(val, &clkrst->crc_clk_sys_rate); + + /* Put i2c, mselect in reset and enable clocks */ + reset_set_enable(PERIPH_ID_DVC_I2C, 1); + clock_set_enable(PERIPH_ID_DVC_I2C, 1); + reset_set_enable(PERIPH_ID_MSELECT, 1); + clock_set_enable(PERIPH_ID_MSELECT, 1); + + /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */ + clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2); + + /* + * Our high-level clock routines are not available prior to + * relocation. We use the low-level functions which require a + * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) + */ + clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); + + /* + * Give clocks time to stabilize, then take i2c and mselect out of + * reset + */ + udelay(1000); + reset_set_enable(PERIPH_ID_DVC_I2C, 0); + reset_set_enable(PERIPH_ID_MSELECT, 0); +} + +static void set_cpu_running(int run) +{ + struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; + + debug("set_cpu_running entry, run = %d\n", run); + writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events); +} + +void start_cpu(u32 reset_vector) +{ + debug("start_cpu entry, reset_vector = %x\n", reset_vector); + t30_init_clocks(); + + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + set_cpu_running(0); + + /* Hold the CPUs in reset */ + reset_A9_cpu(1); + + /* Disable the CPU clock */ + enable_cpu_clock(0); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* + * Set the entry point for CPU execution from reset, + * if it's a non-zero value. + */ + if (reset_vector) + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Enable the CPU clock */ + enable_cpu_clock(1); + + /* If the CPU doesn't already have power, power it up */ + powerup_cpu(); + + /* Take the CPU out of reset */ + reset_A9_cpu(0); + + set_cpu_running(1); +} diff --git a/arch/arm/mach-tegra/tegra30/funcmux.c b/arch/arm/mach-tegra/tegra30/funcmux.c new file mode 100644 index 0000000000..409335ce1d --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/funcmux.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra30 high-level function multiplexing */ + +#include +#include +#include +#include + +int funcmux_select(enum periph_id id, int config) +{ + int bad_config = config != FUNCMUX_DEFAULT; + + switch (id) { + case PERIPH_ID_UART1: + switch (config) { + case FUNCMUX_UART1_ULPI: + pinmux_set_func(PMUX_PINGRP_ULPI_DATA0_PO1, + PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_ULPI_DATA1_PO2, + PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_ULPI_DATA2_PO3, + PMUX_FUNC_UARTA); + pinmux_set_func(PMUX_PINGRP_ULPI_DATA3_PO4, + PMUX_FUNC_UARTA); + pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA0_PO1); + pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA1_PO2); + pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA2_PO3); + pinmux_tristate_disable(PMUX_PINGRP_ULPI_DATA3_PO4); + break; + } + break; + + /* Add other periph IDs here as needed */ + + default: + debug("%s: invalid periph_id %d", __func__, id); + return -1; + } + + if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; +} diff --git a/arch/arm/mach-tegra/tegra30/pinmux.c b/arch/arm/mach-tegra/tegra30/pinmux.c new file mode 100644 index 0000000000..7eb05743b4 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/pinmux.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define PIN(pin, f0, f1, f2, f3) \ + { \ + .funcs = { \ + PMUX_FUNC_##f0, \ + PMUX_FUNC_##f1, \ + PMUX_FUNC_##f2, \ + PMUX_FUNC_##f3, \ + }, \ + } + +#define PIN_RESERVED {} + +static const struct pmux_pingrp_desc tegra30_pingroups[] = { + /* pin, f0, f1, f2, f3 */ + /* Offset 0x3000 */ + PIN(ULPI_DATA0_PO1, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA1_PO2, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA2_PO3, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA3_PO4, SPI3, HSI, UARTA, ULPI), + PIN(ULPI_DATA4_PO5, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA5_PO6, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA6_PO7, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_DATA7_PO0, SPI2, HSI, UARTA, ULPI), + PIN(ULPI_CLK_PY0, SPI1, RSVD2, UARTD, ULPI), + PIN(ULPI_DIR_PY1, SPI1, RSVD2, UARTD, ULPI), + PIN(ULPI_NXT_PY2, SPI1, RSVD2, UARTD, ULPI), + PIN(ULPI_STP_PY3, SPI1, RSVD2, UARTD, ULPI), + PIN(DAP3_FS_PP0, I2S2, RSVD2, DISPLAYA, DISPLAYB), + PIN(DAP3_DIN_PP1, I2S2, RSVD2, DISPLAYA, DISPLAYB), + PIN(DAP3_DOUT_PP2, I2S2, RSVD2, DISPLAYA, DISPLAYB), + PIN(DAP3_SCLK_PP3, I2S2, RSVD2, DISPLAYA, DISPLAYB), + PIN(PV0, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(PV1, RSVD1, RSVD2, RSVD3, RSVD4), + PIN(SDMMC1_CLK_PZ0, SDMMC1, RSVD2, RSVD3, UARTA), + PIN(SDMMC1_CMD_PZ1, SDMMC1, RSVD2, RSVD3, UARTA), + PIN(SDMMC1_DAT3_PY4, SDMMC1, RSVD2, UARTE, UARTA), + PIN(SDMMC1_DAT2_PY5, SDMMC1, RSVD2, UARTE, UARTA), + PIN(SDMMC1_DAT1_PY6, SDMMC1, RSVD2, UARTE, UARTA), + PIN(SDMMC1_DAT0_PY7, SDMMC1, RSVD2, UARTE, UARTA), + PIN(PV2, OWR, RSVD2, RSVD3, RSVD4), + PIN(PV3, CLK_12M_OUT, RSVD2, RSVD3, RSVD4), + PIN(CLK2_OUT_PW5, EXTPERIPH2, RSVD2, RSVD3, RSVD4), + PIN(CLK2_REQ_PCC5, DAP, RSVD2, RSVD3, RSVD4), + PIN(LCD_PWR1_PC1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_PWR2_PC6, DISPLAYA, DISPLAYB, SPI5, HDCP), + PIN(LCD_SDIN_PZ2, DISPLAYA, DISPLAYB, SPI5, RSVD4), + PIN(LCD_SDOUT_PN5, DISPLAYA, DISPLAYB, SPI5, HDCP), + PIN(LCD_WR_N_PZ3, DISPLAYA, DISPLAYB, SPI5, HDCP), + PIN(LCD_CS0_N_PN4, DISPLAYA, DISPLAYB, SPI5, RSVD4), + PIN(LCD_DC0_PN6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_SCK_PZ4, DISPLAYA, DISPLAYB, SPI5, HDCP), + PIN(LCD_PWR0_PB2, DISPLAYA, DISPLAYB, SPI5, HDCP), + PIN(LCD_PCLK_PB3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_DE_PJ1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_HSYNC_PJ3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_VSYNC_PJ4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D0_PE0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D1_PE1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D2_PE2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D3_PE3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D4_PE4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D5_PE5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D6_PE6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D7_PE7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D8_PF0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D9_PF1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D10_PF2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D11_PF3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D12_PF4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D13_PF5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D14_PF6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D15_PF7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D16_PM0, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D17_PM1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D18_PM2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D19_PM3, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D20_PM4, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D21_PM5, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D22_PM6, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_D23_PM7, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_CS1_N_PW0, DISPLAYA, DISPLAYB, SPI5, RSVD4), + PIN(LCD_M1_PW1, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(LCD_DC1_PD2, DISPLAYA, DISPLAYB, RSVD3, RSVD4), + PIN(HDMI_INT_PN7, HDMI, RSVD2, RSVD3, RSVD4), + PIN(DDC_SCL_PV4, I2C4, RSVD2, RSVD3, RSVD4), + PIN(DDC_SDA_PV5, I2C4, RSVD2, RSVD3, RSVD4), + PIN(CRT_HSYNC_PV6, CRT, RSVD2, RSVD3, RSVD4), + PIN(CRT_VSYNC_PV7, CRT, RSVD2, RSVD3, RSVD4), + PIN(VI_D0_PT4, DDR, RSVD2, VI, RSVD4), + PIN(VI_D1_PD5, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D2_PL0, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D3_PL1, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D4_PL2, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D5_PL3, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D6_PL4, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D7_PL5, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D8_PL6, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D9_PL7, DDR, SDMMC2, VI, RSVD4), + PIN(VI_D10_PT2, DDR, RSVD2, VI, RSVD4), + PIN(VI_D11_PT3, DDR, RSVD2, VI, RSVD4), + PIN(VI_PCLK_PT0, RSVD1, SDMMC2, VI, RSVD4), + PIN(VI_MCLK_PT1, VI, VI_ALT1, VI_ALT2, VI_ALT3), + PIN(VI_VSYNC_PD6, DDR, RSVD2, VI, RSVD4), + PIN(VI_HSYNC_PD7, DDR, RSVD2, VI, RSVD4), + PIN(UART2_RXD_PC3, UARTB, SPDIF, UARTA, SPI4), + PIN(UART2_TXD_PC2, UARTB, SPDIF, UARTA, SPI4), + PIN(UART2_RTS_N_PJ6, UARTA, UARTB, GMI, SPI4), + PIN(UART2_CTS_N_PJ5, UARTA, UARTB, GMI, SPI4), + PIN(UART3_TXD_PW6, UARTC, RSVD2, GMI, RSVD4), + PIN(UART3_RXD_PW7, UARTC, RSVD2, GMI, RSVD4), + PIN(UART3_CTS_N_PA1, UARTC, RSVD2, GMI, RSVD4), + PIN(UART3_RTS_N_PC0, UARTC, PWM0, GMI, RSVD4), + PIN(PU0, OWR, UARTA, GMI, RSVD4), + PIN(PU1, RSVD1, UARTA, GMI, RSVD4), + PIN(PU2, RSVD1, UARTA, GMI, RSVD4), + PIN(PU3, PWM0, UARTA, GMI, RSVD4), + PIN(PU4, PWM1, UARTA, GMI, RSVD4), + PIN(PU5, PWM2, UARTA, GMI, RSVD4), + PIN(PU6, PWM3, UARTA, GMI, RSVD4), + PIN(GEN1_I2C_SDA_PC5, I2C1, RSVD2, RSVD3, RSVD4), + PIN(GEN1_I2C_SCL_PC4, I2C1, RSVD2, RSVD3, RSVD4), + PIN(DAP4_FS_PP4, I2S3, RSVD2, GMI, RSVD4), + PIN(DAP4_DIN_PP5, I2S3, RSVD2, GMI, RSVD4), + PIN(DAP4_DOUT_PP6, I2S3, RSVD2, GMI, RSVD4), + PIN(DAP4_SCLK_PP7, I2S3, RSVD2, GMI, RSVD4), + PIN(CLK3_OUT_PEE0, EXTPERIPH3, RSVD2, RSVD3, RSVD4), + PIN(CLK3_REQ_PEE1, DEV3, RSVD2, RSVD3, RSVD4), + PIN(GMI_WP_N_PC7, RSVD1, NAND, GMI, GMI_ALT), + PIN(GMI_IORDY_PI5, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_WAIT_PI7, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_ADV_N_PK0, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_CLK_PK1, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_CS0_N_PJ0, RSVD1, NAND, GMI, DTV), + PIN(GMI_CS1_N_PJ2, RSVD1, NAND, GMI, DTV), + PIN(GMI_CS2_N_PK3, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_CS3_N_PK4, RSVD1, NAND, GMI, GMI_ALT), + PIN(GMI_CS4_N_PK2, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_CS6_N_PI3, NAND, NAND_ALT, GMI, SATA), + PIN(GMI_CS7_N_PI6, NAND, NAND_ALT, GMI, GMI_ALT), + PIN(GMI_AD0_PG0, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD1_PG1, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD2_PG2, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD3_PG3, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD4_PG4, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD5_PG5, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD6_PG6, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD7_PG7, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD8_PH0, PWM0, NAND, GMI, RSVD4), + PIN(GMI_AD9_PH1, PWM1, NAND, GMI, RSVD4), + PIN(GMI_AD10_PH2, PWM2, NAND, GMI, RSVD4), + PIN(GMI_AD11_PH3, PWM3, NAND, GMI, RSVD4), + PIN(GMI_AD12_PH4, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD13_PH5, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD14_PH6, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_AD15_PH7, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_A16_PJ7, UARTD, SPI4, GMI, GMI_ALT), + PIN(GMI_A17_PB0, UARTD, SPI4, GMI, DTV), + PIN(GMI_A18_PB1, UARTD, SPI4, GMI, DTV), + PIN(GMI_A19_PK7, UARTD, SPI4, GMI, RSVD4), + PIN(GMI_WR_N_PI0, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_OE_N_PI1, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_DQS_PI2, RSVD1, NAND, GMI, RSVD4), + PIN(GMI_RST_N_PI4, NAND, NAND_ALT, GMI, RSVD4), + PIN(GEN2_I2C_SCL_PT5, I2C2, HDCP, GMI, RSVD4), + PIN(GEN2_I2C_SDA_PT6, I2C2, HDCP, GMI, RSVD4), + PIN(SDMMC4_CLK_PCC4, INVALID, NAND, GMI, SDMMC4), + PIN(SDMMC4_CMD_PT7, I2C3, NAND, GMI, SDMMC4), + PIN(SDMMC4_DAT0_PAA0, UARTE, SPI3, GMI, SDMMC4), + PIN(SDMMC4_DAT1_PAA1, UARTE, SPI3, GMI, SDMMC4), + PIN(SDMMC4_DAT2_PAA2, UARTE, SPI3, GMI, SDMMC4), + PIN(SDMMC4_DAT3_PAA3, UARTE, SPI3, GMI, SDMMC4), + PIN(SDMMC4_DAT4_PAA4, I2C3, I2S4, GMI, SDMMC4), + PIN(SDMMC4_DAT5_PAA5, VGP3, I2S4, GMI, SDMMC4), + PIN(SDMMC4_DAT6_PAA6, VGP4, I2S4, GMI, SDMMC4), + PIN(SDMMC4_DAT7_PAA7, VGP5, I2S4, GMI, SDMMC4), + PIN(SDMMC4_RST_N_PCC3, VGP6, RSVD2, RSVD3, SDMMC4), + PIN(CAM_MCLK_PCC0, VI, VI_ALT1, VI_ALT3, SDMMC4), + PIN(PCC1, I2S4, RSVD2, RSVD3, SDMMC4), + PIN(PBB0, I2S4, RSVD2, RSVD3, SDMMC4), + PIN(CAM_I2C_SCL_PBB1, VGP1, I2C3, RSVD3, SDMMC4), + PIN(CAM_I2C_SDA_PBB2, VGP2, I2C3, RSVD3, SDMMC4), + PIN(PBB3, VGP3, DISPLAYA, DISPLAYB, SDMMC4), + PIN(PBB4, VGP4, DISPLAYA, DISPLAYB, SDMMC4), + PIN(PBB5, VGP5, DISPLAYA, DISPLAYB, SDMMC4), + PIN(PBB6, VGP6, DISPLAYA, DISPLAYB, SDMMC4), + PIN(PBB7, I2S4, RSVD2, RSVD3, SDMMC4), + PIN(PCC2, I2S4, RSVD2, RSVD3, RSVD4), + PIN(JTAG_RTCK_PU7, RTCK, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SCL_PZ6, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(PWR_I2C_SDA_PZ7, I2CPWR, RSVD2, RSVD3, RSVD4), + PIN(KB_ROW0_PR0, KBC, NAND, RSVD3, RSVD4), + PIN(KB_ROW1_PR1, KBC, NAND, RSVD3, RSVD4), + PIN(KB_ROW2_PR2, KBC, NAND, RSVD3, RSVD4), + PIN(KB_ROW3_PR3, KBC, NAND, RSVD3, INVALID), + PIN(KB_ROW4_PR4, KBC, NAND, TRACE, RSVD4), + PIN(KB_ROW5_PR5, KBC, NAND, TRACE, OWR), + PIN(KB_ROW6_PR6, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW7_PR7, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW8_PS0, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW9_PS1, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW10_PS2, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW11_PS3, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW12_PS4, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW13_PS5, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW14_PS6, KBC, NAND, SDMMC2, MIO), + PIN(KB_ROW15_PS7, KBC, NAND, SDMMC2, MIO), + PIN(KB_COL0_PQ0, KBC, NAND, TRACE, TEST), + PIN(KB_COL1_PQ1, KBC, NAND, TRACE, TEST), + PIN(KB_COL2_PQ2, KBC, NAND, TRACE, RSVD4), + PIN(KB_COL3_PQ3, KBC, NAND, TRACE, RSVD4), + PIN(KB_COL4_PQ4, KBC, NAND, TRACE, RSVD4), + PIN(KB_COL5_PQ5, KBC, NAND, TRACE, RSVD4), + PIN(KB_COL6_PQ6, KBC, NAND, TRACE, MIO), + PIN(KB_COL7_PQ7, KBC, NAND, TRACE, MIO), + PIN(CLK_32K_OUT_PA0, BLINK, RSVD2, RSVD3, RSVD4), + PIN(SYS_CLK_REQ_PZ5, SYSCLK, RSVD2, RSVD3, RSVD4), + PIN(CORE_PWR_REQ, CORE_PWR_REQ, RSVD2, RSVD3, RSVD4), + PIN(CPU_PWR_REQ, CPU_PWR_REQ, RSVD2, RSVD3, RSVD4), + PIN(PWR_INT_N, PWR_INT_N, RSVD2, RSVD3, RSVD4), + PIN(CLK_32K_IN, CLK_32K_IN, RSVD2, RSVD3, RSVD4), + PIN(OWR, OWR, CEC, RSVD3, RSVD4), + PIN(DAP1_FS_PN0, I2S0, HDA, GMI, SDMMC2), + PIN(DAP1_DIN_PN1, I2S0, HDA, GMI, SDMMC2), + PIN(DAP1_DOUT_PN2, I2S0, HDA, GMI, SDMMC2), + PIN(DAP1_SCLK_PN3, I2S0, HDA, GMI, SDMMC2), + PIN(CLK1_REQ_PEE2, DAP, HDA, RSVD3, RSVD4), + PIN(CLK1_OUT_PW4, EXTPERIPH1, RSVD2, RSVD3, RSVD4), + PIN(SPDIF_IN_PK6, SPDIF, HDA, I2C1, SDMMC2), + PIN(SPDIF_OUT_PK5, SPDIF, RSVD2, I2C1, SDMMC2), + PIN(DAP2_FS_PA2, I2S1, HDA, RSVD3, GMI), + PIN(DAP2_DIN_PA4, I2S1, HDA, RSVD3, GMI), + PIN(DAP2_DOUT_PA5, I2S1, HDA, RSVD3, GMI), + PIN(DAP2_SCLK_PA3, I2S1, HDA, RSVD3, GMI), + PIN(SPI2_MOSI_PX0, SPI6, SPI2, SPI3, GMI), + PIN(SPI2_MISO_PX1, SPI6, SPI2, SPI3, GMI), + PIN(SPI2_CS0_N_PX3, SPI6, SPI2, SPI3, GMI), + PIN(SPI2_SCK_PX2, SPI6, SPI2, SPI3, GMI), + PIN(SPI1_MOSI_PX4, SPI2, SPI1, SPI2_ALT, GMI), + PIN(SPI1_SCK_PX5, SPI2, SPI1, SPI2_ALT, GMI), + PIN(SPI1_CS0_N_PX6, SPI2, SPI1, SPI2_ALT, GMI), + PIN(SPI1_MISO_PX7, SPI3, SPI1, SPI2_ALT, RSVD4), + PIN(SPI2_CS1_N_PW2, SPI3, SPI2, SPI2_ALT, I2C1), + PIN(SPI2_CS2_N_PW3, SPI3, SPI2, SPI2_ALT, I2C1), + PIN(SDMMC3_CLK_PA6, UARTA, PWM2, SDMMC3, SPI3), + PIN(SDMMC3_CMD_PA7, UARTA, PWM3, SDMMC3, SPI2), + PIN(SDMMC3_DAT0_PB7, RSVD1, RSVD2, SDMMC3, SPI3), + PIN(SDMMC3_DAT1_PB6, RSVD1, RSVD2, SDMMC3, SPI3), + PIN(SDMMC3_DAT2_PB5, RSVD1, PWM1, SDMMC3, SPI3), + PIN(SDMMC3_DAT3_PB4, RSVD1, PWM0, SDMMC3, SPI3), + PIN(SDMMC3_DAT4_PD1, PWM1, SPI4, SDMMC3, SPI2), + PIN(SDMMC3_DAT5_PD0, PWM0, SPI4, SDMMC3, SPI2), + PIN(SDMMC3_DAT6_PD3, SPDIF, SPI4, SDMMC3, SPI2), + PIN(SDMMC3_DAT7_PD4, SPDIF, SPI4, SDMMC3, SPI2), + PIN(PEX_L0_PRSNT_N_PDD0, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L0_RST_N_PDD1, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L0_CLKREQ_N_PDD2, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_WAKE_N_PDD3, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L1_PRSNT_N_PDD4, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L1_RST_N_PDD5, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L1_CLKREQ_N_PDD6, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L2_PRSNT_N_PDD7, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L2_RST_N_PCC6, PCIE, HDA, RSVD3, RSVD4), + PIN(PEX_L2_CLKREQ_N_PCC7, PCIE, HDA, RSVD3, RSVD4), + PIN(HDMI_CEC_PEE3, CEC, RSVD2, RSVD3, RSVD4), +}; +const struct pmux_pingrp_desc *tegra_soc_pingroups = tegra30_pingroups; diff --git a/arch/arm/mach-tegra/vpr.c b/arch/arm/mach-tegra/vpr.c new file mode 100644 index 0000000000..f695811c9b --- /dev/null +++ b/arch/arm/mach-tegra/vpr.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Tegra vpr routines */ + +#include +#include +#include +#include + +/* Configures VPR. Right now, all we do is turn it off. */ +void config_vpr(void) +{ + struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE; + + /* Turn VPR off */ + writel(0, &mc->mc_video_protect_size_mb); + writel(TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED, + &mc->mc_video_protect_reg_ctrl); + /* read back to ensure the write went through */ + readl(&mc->mc_video_protect_reg_ctrl); +} diff --git a/arch/arm/mach-tegra/xusb-padctl.c b/arch/arm/mach-tegra/xusb-padctl.c new file mode 100644 index 0000000000..65f8d2ea96 --- /dev/null +++ b/arch/arm/mach-tegra/xusb-padctl.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include + +#include + +struct tegra_xusb_phy * __weak tegra_xusb_phy_get(unsigned int type) +{ + return NULL; +} + +int __weak tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy) +{ + return -ENOSYS; +} + +int __weak tegra_xusb_phy_enable(struct tegra_xusb_phy *phy) +{ + return -ENOSYS; +} + +int __weak tegra_xusb_phy_disable(struct tegra_xusb_phy *phy) +{ + return -ENOSYS; +} + +int __weak tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) +{ + return -ENOSYS; +} + +void __weak tegra_xusb_padctl_init(const void *fdt) +{ +} -- cgit From 601fbec7cf815bc2b26ba2546ac5e8501fc7edae Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:05 +0900 Subject: ARM: davinci: move SoC sources to mach-davinci Move arch/arm/cpu/arm926ejs/davinci/* -> arch/arm/mach-davinci/* Signed-off-by: Masahiro Yamada Cc: Tom Rini --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 1 + arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/davinci/Kconfig | 78 --- arch/arm/cpu/arm926ejs/davinci/Makefile | 28 - arch/arm/cpu/arm926ejs/davinci/config.mk | 8 - arch/arm/cpu/arm926ejs/davinci/cpu.c | 223 -------- arch/arm/cpu/arm926ejs/davinci/da830_pinmux.c | 139 ----- arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c | 313 ----------- arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c | 181 ------- arch/arm/cpu/arm926ejs/davinci/dm355.c | 30 - arch/arm/cpu/arm926ejs/davinci/dm365.c | 20 - arch/arm/cpu/arm926ejs/davinci/dm365_lowlevel.c | 460 ---------------- arch/arm/cpu/arm926ejs/davinci/dm644x.c | 81 --- arch/arm/cpu/arm926ejs/davinci/dm646x.c | 26 - arch/arm/cpu/arm926ejs/davinci/dp83848.c | 128 ----- arch/arm/cpu/arm926ejs/davinci/et1011c.c | 42 -- arch/arm/cpu/arm926ejs/davinci/ksz8873.c | 53 -- arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S | 693 ------------------------ arch/arm/cpu/arm926ejs/davinci/lxt972.c | 113 ---- arch/arm/cpu/arm926ejs/davinci/misc.c | 138 ----- arch/arm/cpu/arm926ejs/davinci/pinmux.c | 90 --- arch/arm/cpu/arm926ejs/davinci/psc.c | 160 ------ arch/arm/cpu/arm926ejs/davinci/reset.c | 32 -- arch/arm/cpu/arm926ejs/davinci/spl.c | 65 --- arch/arm/cpu/arm926ejs/davinci/timer.c | 128 ----- arch/arm/mach-davinci/Kconfig | 78 +++ arch/arm/mach-davinci/Makefile | 28 + arch/arm/mach-davinci/config.mk | 8 + arch/arm/mach-davinci/cpu.c | 223 ++++++++ arch/arm/mach-davinci/da830_pinmux.c | 139 +++++ arch/arm/mach-davinci/da850_lowlevel.c | 313 +++++++++++ arch/arm/mach-davinci/da850_pinmux.c | 181 +++++++ arch/arm/mach-davinci/dm355.c | 30 + arch/arm/mach-davinci/dm365.c | 20 + arch/arm/mach-davinci/dm365_lowlevel.c | 460 ++++++++++++++++ arch/arm/mach-davinci/dm644x.c | 81 +++ arch/arm/mach-davinci/dm646x.c | 26 + arch/arm/mach-davinci/dp83848.c | 128 +++++ arch/arm/mach-davinci/et1011c.c | 42 ++ arch/arm/mach-davinci/ksz8873.c | 53 ++ arch/arm/mach-davinci/lowlevel_init.S | 693 ++++++++++++++++++++++++ arch/arm/mach-davinci/lxt972.c | 113 ++++ arch/arm/mach-davinci/misc.c | 138 +++++ arch/arm/mach-davinci/pinmux.c | 90 +++ arch/arm/mach-davinci/psc.c | 160 ++++++ arch/arm/mach-davinci/reset.c | 32 ++ arch/arm/mach-davinci/spl.c | 65 +++ arch/arm/mach-davinci/timer.c | 128 +++++ 49 files changed, 3231 insertions(+), 3231 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/davinci/Kconfig delete mode 100644 arch/arm/cpu/arm926ejs/davinci/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/davinci/config.mk delete mode 100644 arch/arm/cpu/arm926ejs/davinci/cpu.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/da830_pinmux.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dm355.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dm365.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dm365_lowlevel.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dm644x.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dm646x.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/dp83848.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/et1011c.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/ksz8873.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S delete mode 100644 arch/arm/cpu/arm926ejs/davinci/lxt972.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/misc.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/pinmux.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/psc.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/reset.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/spl.c delete mode 100644 arch/arm/cpu/arm926ejs/davinci/timer.c create mode 100644 arch/arm/mach-davinci/Kconfig create mode 100644 arch/arm/mach-davinci/Makefile create mode 100644 arch/arm/mach-davinci/config.mk create mode 100644 arch/arm/mach-davinci/cpu.c create mode 100644 arch/arm/mach-davinci/da830_pinmux.c create mode 100644 arch/arm/mach-davinci/da850_lowlevel.c create mode 100644 arch/arm/mach-davinci/da850_pinmux.c create mode 100644 arch/arm/mach-davinci/dm355.c create mode 100644 arch/arm/mach-davinci/dm365.c create mode 100644 arch/arm/mach-davinci/dm365_lowlevel.c create mode 100644 arch/arm/mach-davinci/dm644x.c create mode 100644 arch/arm/mach-davinci/dm646x.c create mode 100644 arch/arm/mach-davinci/dp83848.c create mode 100644 arch/arm/mach-davinci/et1011c.c create mode 100644 arch/arm/mach-davinci/ksz8873.c create mode 100644 arch/arm/mach-davinci/lowlevel_init.S create mode 100644 arch/arm/mach-davinci/lxt972.c create mode 100644 arch/arm/mach-davinci/misc.c create mode 100644 arch/arm/mach-davinci/pinmux.c create mode 100644 arch/arm/mach-davinci/psc.c create mode 100644 arch/arm/mach-davinci/reset.c create mode 100644 arch/arm/mach-davinci/spl.c create mode 100644 arch/arm/mach-davinci/timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index adecafcad1..887c0d5b6e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -716,7 +716,7 @@ endchoice source "arch/arm/mach-at91/Kconfig" -source "arch/arm/cpu/arm926ejs/davinci/Kconfig" +source "arch/arm/mach-davinci/Kconfig" source "arch/arm/cpu/arm1176/bcm2835/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index f1ae929154..e321057a0e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -5,6 +5,7 @@ # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) += at91 +machine-$(CONFIG_ARCH_DAVINCI) += davinci # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA machine-$(CONFIG_TEGRA) += tegra diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index f41357aaeb..27b4353a9d 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -15,7 +15,6 @@ endif endif obj-$(CONFIG_ARMADA100) += armada100/ -obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_KIRKWOOD) += kirkwood/ obj-$(if $(filter lpc32xx,$(SOC)),y) += lpc32xx/ obj-$(CONFIG_MB86R0x) += mb86r0x/ diff --git a/arch/arm/cpu/arm926ejs/davinci/Kconfig b/arch/arm/cpu/arm926ejs/davinci/Kconfig deleted file mode 100644 index 613f04d8b0..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/Kconfig +++ /dev/null @@ -1,78 +0,0 @@ -if ARCH_DAVINCI - -choice - prompt "DaVinci board select" - -config TARGET_ENBW_CMC - bool "EnBW CMC board" - -config TARGET_IPAM390 - bool "IPAM390 board" - select SUPPORT_SPL - -config TARGET_DA830EVM - bool "DA830 EVM board" - -config TARGET_DA850EVM - bool "DA850 EVM board" - select SUPPORT_SPL - -config TARGET_CAM_ENC_4XX - bool "CAM ENC 4xx board" - select SUPPORT_SPL - -config TARGET_HAWKBOARD - bool "Hawkboard" - select SUPPORT_SPL - -config TARGET_DAVINCI_DM355EVM - bool "DM355 EVM board" - -config TARGET_DAVINCI_DM355LEOPARD - bool "DM355 Leopard board" - -config TARGET_DAVINCI_DM365EVM - bool "DM365 EVM board" - -config TARGET_DAVINCI_DM6467EVM - bool "DM6467 EVM board" - -config TARGET_DAVINCI_DVEVM - bool "DVEVM board" - -config TARGET_EA20 - bool "EA20 board" - -config TARGET_DAVINCI_SCHMOOGIE - bool "Schmoogie board" - -config TARGET_DAVINCI_SFFSDR - bool "SFFSDR board" - -config TARGET_DAVINCI_SONATA - bool "Sonata board" - -config TARGET_CALIMAIN - bool "Calimain board" - -endchoice - -config SYS_SOC - default "davinci" - -source "board/enbw/enbw_cmc/Kconfig" -source "board/ait/cam_enc_4xx/Kconfig" -source "board/Barix/ipam390/Kconfig" -source "board/davinci/da8xxevm/Kconfig" -source "board/davinci/dm355evm/Kconfig" -source "board/davinci/dm355leopard/Kconfig" -source "board/davinci/dm365evm/Kconfig" -source "board/davinci/dm6467evm/Kconfig" -source "board/davinci/dvevm/Kconfig" -source "board/davinci/ea20/Kconfig" -source "board/davinci/schmoogie/Kconfig" -source "board/davinci/sffsdr/Kconfig" -source "board/davinci/sonata/Kconfig" -source "board/omicron/calimain/Kconfig" - -endif diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile deleted file mode 100644 index 7d67191de8..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# Copyright (C) 2007 Sergey Kubushyn -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += cpu.o misc.o timer.o psc.o pinmux.o reset.o -obj-$(CONFIG_DA850_LOWLEVEL) += da850_lowlevel.o -obj-$(CONFIG_SOC_DM355) += dm355.o -obj-$(CONFIG_SOC_DM365) += dm365.o -obj-$(CONFIG_SOC_DM644X) += dm644x.o -obj-$(CONFIG_SOC_DM646X) += dm646x.o -obj-$(CONFIG_SOC_DA830) += da830_pinmux.o -obj-$(CONFIG_SOC_DA850) += da850_pinmux.o -obj-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_SPL_FRAMEWORK) += spl.o -obj-$(CONFIG_SOC_DM365) += dm365_lowlevel.o -obj-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o -endif - -ifndef CONFIG_SKIP_LOWLEVEL_INIT -obj-y += lowlevel_init.o -endif diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk deleted file mode 100644 index 69e9d5ab21..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/config.mk +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (C) 2012, Texas Instruments, Incorporated - http://www.ti.com/ -# -# SPDX-License-Identifier: GPL-2.0+ -# -ifndef CONFIG_SPL_BUILD -ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.ais -endif diff --git a/arch/arm/cpu/arm926ejs/davinci/cpu.c b/arch/arm/cpu/arm926ejs/davinci/cpu.c deleted file mode 100644 index ff61147757..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/cpu.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2004 Texas Instruments. - * Copyright (C) 2009 David Brownell - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* offsets from PLL controller base */ -#define PLLC_PLLCTL 0x100 -#define PLLC_PLLM 0x110 -#define PLLC_PREDIV 0x114 -#define PLLC_PLLDIV1 0x118 -#define PLLC_PLLDIV2 0x11c -#define PLLC_PLLDIV3 0x120 -#define PLLC_POSTDIV 0x128 -#define PLLC_BPDIV 0x12c -#define PLLC_PLLDIV4 0x160 -#define PLLC_PLLDIV5 0x164 -#define PLLC_PLLDIV6 0x168 -#define PLLC_PLLDIV7 0x16c -#define PLLC_PLLDIV8 0x170 -#define PLLC_PLLDIV9 0x174 - -#define BIT(x) (1 << (x)) - -/* SOC-specific pll info */ -#ifdef CONFIG_SOC_DM355 -#define ARM_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - -#ifdef CONFIG_SOC_DM644X -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DSP_PLLDIV PLLC_PLLDIV1 -#define DDR_PLLDIV PLLC_PLLDIV2 -#endif - -#ifdef CONFIG_SOC_DM646X -#define DSP_PLLDIV PLLC_PLLDIV1 -#define ARM_PLLDIV PLLC_PLLDIV2 -#define DDR_PLLDIV PLLC_PLLDIV1 -#endif - -#ifdef CONFIG_SOC_DA8XX -unsigned int sysdiv[9] = { - PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5, - PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9 -}; - -int clk_get(enum davinci_clk_ids id) -{ - int pre_div; - int pllm; - int post_div; - int pll_out; - unsigned int pll_base; - - pll_out = CONFIG_SYS_OSCIN_FREQ; - - if (id == DAVINCI_AUXCLK_CLKID) - goto out; - - if ((id >> 16) == 1) - pll_base = (unsigned int)davinci_pllc1_regs; - else - pll_base = (unsigned int)davinci_pllc0_regs; - - id &= 0xFFFF; - - /* - * Lets keep this simple. Combining operations can result in - * unexpected approximations - */ - pre_div = (readl(pll_base + PLLC_PREDIV) & - DAVINCI_PLLC_DIV_MASK) + 1; - pllm = readl(pll_base + PLLC_PLLM) + 1; - - pll_out /= pre_div; - pll_out *= pllm; - - if (id == DAVINCI_PLLM_CLKID) - goto out; - - post_div = (readl(pll_base + PLLC_POSTDIV) & - DAVINCI_PLLC_DIV_MASK) + 1; - - pll_out /= post_div; - - if (id == DAVINCI_PLLC_CLKID) - goto out; - - pll_out /= (readl(pll_base + sysdiv[id - 1]) & - DAVINCI_PLLC_DIV_MASK) + 1; - -out: - return pll_out; -} - -int set_cpu_clk_info(void) -{ - gd->bd->bi_arm_freq = clk_get(DAVINCI_ARM_CLKID) / 1000000; - /* DDR PHY uses an x2 input clock */ - gd->bd->bi_ddr_freq = cpu_is_da830() ? 0 : - (clk_get(DAVINCI_DDR_CLKID) / 1000000); - gd->bd->bi_dsp_freq = 0; - return 0; -} - -#else /* CONFIG_SOC_DA8XX */ - -static unsigned pll_div(volatile void *pllbase, unsigned offset) -{ - u32 div; - - div = REG(pllbase + offset); - return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; -} - -static inline unsigned pll_prediv(volatile void *pllbase) -{ -#ifdef CONFIG_SOC_DM355 - /* this register read seems to fail on pll0 */ - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return 8; - else - return pll_div(pllbase, PLLC_PREDIV); -#elif defined(CONFIG_SOC_DM365) - return pll_div(pllbase, PLLC_PREDIV); -#endif - return 1; -} - -static inline unsigned pll_postdiv(volatile void *pllbase) -{ -#if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365) - return pll_div(pllbase, PLLC_POSTDIV); -#elif defined(CONFIG_SOC_DM6446) - if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) - return pll_div(pllbase, PLLC_POSTDIV); -#endif - return 1; -} - -static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) -{ - volatile void *pllbase = (volatile void *) pll_addr; -#ifdef CONFIG_SOC_DM646X - unsigned base = CONFIG_REFCLK_FREQ / 1000; -#else - unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; -#endif - - /* the PLL might be bypassed */ - if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) { - base /= pll_prediv(pllbase); -#if defined(CONFIG_SOC_DM365) - base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff); -#else - base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); -#endif - base /= pll_postdiv(pllbase); - } - return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); -} - -#ifdef DAVINCI_DM6467EVM -unsigned int davinci_arm_clk_get() -{ - return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000; -} -#endif - -#if defined(CONFIG_SOC_DM365) -unsigned int davinci_clk_get(unsigned int div) -{ - return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000; -} -#endif - -int set_cpu_clk_info(void) -{ - unsigned int pllbase = DAVINCI_PLL_CNTRL0_BASE; -#if defined(CONFIG_SOC_DM365) - pllbase = DAVINCI_PLL_CNTRL1_BASE; -#endif - gd->bd->bi_arm_freq = pll_sysclk_mhz(pllbase, ARM_PLLDIV); - -#ifdef DSP_PLLDIV - gd->bd->bi_dsp_freq = - pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV); -#else - gd->bd->bi_dsp_freq = 0; -#endif - - pllbase = DAVINCI_PLL_CNTRL1_BASE; -#if defined(CONFIG_SOC_DM365) - pllbase = DAVINCI_PLL_CNTRL0_BASE; -#endif - gd->bd->bi_ddr_freq = pll_sysclk_mhz(pllbase, DDR_PLLDIV) / 2; - - return 0; -} - -#endif /* !CONFIG_SOC_DA8XX */ - -/* - * Initializes on-chip ethernet controllers. - * to override, implement board_eth_init() - */ -int cpu_eth_init(bd_t *bis) -{ -#if defined(CONFIG_DRIVER_TI_EMAC) - davinci_emac_initialize(); -#endif - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/da830_pinmux.c b/arch/arm/cpu/arm926ejs/davinci/da830_pinmux.c deleted file mode 100644 index edaab45327..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/da830_pinmux.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Pinmux configurations for the DA830 SoCs - * - * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* SPI0 pin muxer settings */ -const struct pinmux_config spi0_pins_base[] = { - { pinmux(7), 1, 3 }, /* SPI0_SOMI */ - { pinmux(7), 1, 4 }, /* SPI0_SIMO */ - { pinmux(7), 1, 6 } /* SPI0_CLK */ -}; - -const struct pinmux_config spi0_pins_scs0[] = { - { pinmux(7), 1, 7 } /* SPI0_SCS[0] */ -}; - -const struct pinmux_config spi0_pins_ena[] = { - { pinmux(7), 1, 5 } /* SPI0_ENA */ -}; - -/* NAND pin muxer settings */ -const struct pinmux_config emifa_pins_cs0[] = { - { pinmux(18), 1, 2 } /* EMA_CS[0] */ -}; - -const struct pinmux_config emifa_pins_cs2[] = { - { pinmux(18), 1, 3 } /* EMA_CS[2] */ -}; - -const struct pinmux_config emifa_pins_cs3[] = { - { pinmux(18), 1, 4 } /* EMA_CS[3] */ -}; - -#ifdef CONFIG_USE_NAND -const struct pinmux_config emifa_pins[] = { - { pinmux(13), 1, 6 }, /* EMA_D[0] */ - { pinmux(13), 1, 7 }, /* EMA_D[1] */ - { pinmux(14), 1, 0 }, /* EMA_D[2] */ - { pinmux(14), 1, 1 }, /* EMA_D[3] */ - { pinmux(14), 1, 2 }, /* EMA_D[4] */ - { pinmux(14), 1, 3 }, /* EMA_D[5] */ - { pinmux(14), 1, 4 }, /* EMA_D[6] */ - { pinmux(14), 1, 5 }, /* EMA_D[7] */ - { pinmux(14), 1, 6 }, /* EMA_D[8] */ - { pinmux(14), 1, 7 }, /* EMA_D[9] */ - { pinmux(15), 1, 0 }, /* EMA_D[10] */ - { pinmux(15), 1, 1 }, /* EMA_D[11] */ - { pinmux(15), 1, 2 }, /* EMA_D[12] */ - { pinmux(15), 1, 3 }, /* EMA_D[13] */ - { pinmux(15), 1, 4 }, /* EMA_D[14] */ - { pinmux(15), 1, 5 }, /* EMA_D[15] */ - { pinmux(15), 1, 6 }, /* EMA_A[0] */ - { pinmux(15), 1, 7 }, /* EMA_A[1] */ - { pinmux(16), 1, 0 }, /* EMA_A[2] */ - { pinmux(16), 1, 1 }, /* EMA_A[3] */ - { pinmux(16), 1, 2 }, /* EMA_A[4] */ - { pinmux(16), 1, 3 }, /* EMA_A[5] */ - { pinmux(16), 1, 4 }, /* EMA_A[6] */ - { pinmux(16), 1, 5 }, /* EMA_A[7] */ - { pinmux(16), 1, 6 }, /* EMA_A[8] */ - { pinmux(16), 1, 7 }, /* EMA_A[9] */ - { pinmux(17), 1, 0 }, /* EMA_A[10] */ - { pinmux(17), 1, 1 }, /* EMA_A[11] */ - { pinmux(17), 1, 2 }, /* EMA_A[12] */ - { pinmux(17), 1, 3 }, /* EMA_BA[1] */ - { pinmux(17), 1, 4 }, /* EMA_BA[0] */ - { pinmux(17), 1, 5 }, /* EMA_CLK */ - { pinmux(17), 1, 6 }, /* EMA_SDCKE */ - { pinmux(17), 1, 7 }, /* EMA_CAS */ - { pinmux(18), 1, 0 }, /* EMA_CAS */ - { pinmux(18), 1, 1 }, /* EMA_WE */ - { pinmux(18), 1, 5 }, /* EMA_OE */ - { pinmux(18), 1, 6 }, /* EMA_WE_DQM[1] */ - { pinmux(18), 1, 7 }, /* EMA_WE_DQM[0] */ - { pinmux(10), 1, 0 } /* Tristate */ -}; -#endif - -/* EMAC PHY interface pins */ -const struct pinmux_config emac_pins_rmii[] = { - { pinmux(10), 2, 1 }, /* RMII_TXD[0] */ - { pinmux(10), 2, 2 }, /* RMII_TXD[1] */ - { pinmux(10), 2, 3 }, /* RMII_TXEN */ - { pinmux(10), 2, 4 }, /* RMII_CRS_DV */ - { pinmux(10), 2, 5 }, /* RMII_RXD[0] */ - { pinmux(10), 2, 6 }, /* RMII_RXD[1] */ - { pinmux(10), 2, 7 } /* RMII_RXER */ -}; - -const struct pinmux_config emac_pins_mdio[] = { - { pinmux(11), 2, 0 }, /* MDIO_CLK */ - { pinmux(11), 2, 1 } /* MDIO_D */ -}; - -const struct pinmux_config emac_pins_rmii_clk_source[] = { - { pinmux(9), 0, 5 } /* ref.clk from external source */ -}; - -/* UART2 pin muxer settings */ -const struct pinmux_config uart2_pins_txrx[] = { - { pinmux(8), 2, 7 }, /* UART2_RXD */ - { pinmux(9), 2, 0 } /* UART2_TXD */ -}; - -/* I2C0 pin muxer settings */ -const struct pinmux_config i2c0_pins[] = { - { pinmux(8), 2, 3 }, /* I2C0_SDA */ - { pinmux(8), 2, 4 } /* I2C0_SCL */ -}; - -/* USB0_DRVVBUS pin muxer settings */ -const struct pinmux_config usb_pins[] = { - { pinmux(9), 1, 1 } /* USB0_DRVVBUS */ -}; - -#ifdef CONFIG_DAVINCI_MMC -/* MMC0 pin muxer settings */ -const struct pinmux_config mmc0_pins_8bit[] = { - { pinmux(15), 2, 7 }, /* MMCSD0_CLK */ - { pinmux(16), 2, 0 }, /* MMCSD0_CMD */ - { pinmux(13), 2, 6 }, /* MMCSD0_DAT_0 */ - { pinmux(13), 2, 7 }, /* MMCSD0_DAT_1 */ - { pinmux(14), 2, 0 }, /* MMCSD0_DAT_2 */ - { pinmux(14), 2, 1 }, /* MMCSD0_DAT_3 */ - { pinmux(14), 2, 2 }, /* MMCSD0_DAT_4 */ - { pinmux(14), 2, 3 }, /* MMCSD0_DAT_5 */ - { pinmux(14), 2, 4 }, /* MMCSD0_DAT_6 */ - { pinmux(14), 2, 5 } /* MMCSD0_DAT_7 */ - /* DA830 supports 8-bit mode */ -}; -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c b/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c deleted file mode 100644 index 19730cef8c..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/da850_lowlevel.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * SoC-specific lowlevel code for DA850 - * - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x00006001; -} - -#if defined(CONFIG_SYS_DA850_PLL_INIT) -static void da850_waitloop(unsigned long loopcnt) -{ - unsigned long i; - - for (i = 0; i < loopcnt; i++) - asm(" NOP"); -} - -static int da850_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult) -{ - if (reg == davinci_pllc0_regs) - /* Unlock PLL registers. */ - clrbits_le32(&davinci_syscfg_regs->cfgchip0, PLL_MASTER_LOCK); - - /* - * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled - * through MMR - */ - clrbits_le32(®->pllctl, PLLCTL_PLLENSRC); - /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ - clrbits_le32(®->pllctl, PLLCTL_EXTCLKSRC); - - /* Set PLLEN=0 => PLL BYPASS MODE */ - clrbits_le32(®->pllctl, PLLCTL_PLLEN); - - da850_waitloop(150); - - if (reg == davinci_pllc0_regs) { - /* - * Select the Clock Mode bit 8 as External Clock or On Chip - * Oscilator - */ - dv_maskbits(®->pllctl, ~PLLCTL_RES_9); - setbits_le32(®->pllctl, - (CONFIG_SYS_DV_CLKMODE << PLLCTL_CLOCK_MODE_SHIFT)); - } - - /* Clear PLLRST bit to reset the PLL */ - clrbits_le32(®->pllctl, PLLCTL_PLLRST); - - /* Disable the PLL output */ - setbits_le32(®->pllctl, PLLCTL_PLLDIS); - - /* PLL initialization sequence */ - /* - * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of - * power down bit - */ - clrbits_le32(®->pllctl, PLLCTL_PLLPWRDN); - - /* Enable the PLL from Disable Mode PLLDIS bit to 0 */ - clrbits_le32(®->pllctl, PLLCTL_PLLDIS); - -#if defined(CONFIG_SYS_DA850_PLL0_PREDIV) - /* program the prediv */ - if (reg == davinci_pllc0_regs && CONFIG_SYS_DA850_PLL0_PREDIV) - writel((PLL_DIVEN | CONFIG_SYS_DA850_PLL0_PREDIV), - ®->prediv); -#endif - - /* Program the required multiplier value in PLLM */ - writel(pllmult, ®->pllm); - - /* program the postdiv */ - if (reg == davinci_pllc0_regs) - writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL0_POSTDIV), - ®->postdiv); - else - writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL1_POSTDIV), - ®->postdiv); - - /* - * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that - * no GO operation is currently in progress - */ - while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT) - ; - - if (reg == davinci_pllc0_regs) { - writel(CONFIG_SYS_DA850_PLL0_PLLDIV1, ®->plldiv1); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV2, ®->plldiv2); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV3, ®->plldiv3); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV4, ®->plldiv4); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV5, ®->plldiv5); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV6, ®->plldiv6); - writel(CONFIG_SYS_DA850_PLL0_PLLDIV7, ®->plldiv7); - } else { - writel(CONFIG_SYS_DA850_PLL1_PLLDIV1, ®->plldiv1); - writel(CONFIG_SYS_DA850_PLL1_PLLDIV2, ®->plldiv2); - writel(CONFIG_SYS_DA850_PLL1_PLLDIV3, ®->plldiv3); - } - - /* - * Set the GOSET bit in PLLCMD to 1 to initiate a new divider - * transition. - */ - setbits_le32(®->pllcmd, PLLCMD_GOSTAT); - - /* - * Wait for the GOSTAT bit in PLLSTAT to clear to 0 - * (completion of phase alignment). - */ - while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT) - ; - - /* Wait for PLL to reset properly. See PLL spec for PLL reset time */ - da850_waitloop(200); - - /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */ - setbits_le32(®->pllctl, PLLCTL_PLLRST); - - /* Wait for PLL to lock. See PLL spec for PLL lock time */ - da850_waitloop(2400); - - /* - * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass - * mode - */ - setbits_le32(®->pllctl, PLLCTL_PLLEN); - - - /* - * clear EMIFA and EMIFB clock source settings, let them - * run off SYSCLK - */ - if (reg == davinci_pllc0_regs) - dv_maskbits(&davinci_syscfg_regs->cfgchip3, - ~(PLL_SCSCFG3_DIV45PENA | PLL_SCSCFG3_EMA_CLKSRC)); - - return 0; -} -#endif /* CONFIG_SYS_DA850_PLL_INIT */ - -#if defined(CONFIG_SYS_DA850_DDR_INIT) -static int da850_ddr_setup(void) -{ - unsigned long tmp; - - /* Enable the Clock to DDR2/mDDR */ - lpsc_on(DAVINCI_LPSC_DDR_EMIF); - - tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); - if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) { - /* Begin VTP Calibration */ - clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); - clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); - setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); - clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); - setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); - - /* Polling READY bit to see when VTP calibration is done */ - tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); - while ((tmp & VTP_READY) != VTP_READY) - tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); - - setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); - setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); - } - setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN); - writel(CONFIG_SYS_DA850_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr); - - if (CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT)) { - /* DDR2 */ - clrbits_le32(&davinci_syscfg1_regs->ddr_slew, - (1 << DDR_SLEW_DDR_PDENA_BIT) | - (1 << DDR_SLEW_CMOSEN_BIT)); - } else { - /* MOBILE DDR */ - setbits_le32(&davinci_syscfg1_regs->ddr_slew, - (1 << DDR_SLEW_DDR_PDENA_BIT) | - (1 << DDR_SLEW_CMOSEN_BIT)); - } - - /* - * SDRAM Configuration Register (SDCR): - * First set the BOOTUNLOCK bit to make configuration bits - * writeable. - */ - setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK); - - /* - * Write the new value of these bits and clear BOOTUNLOCK. - * At the same time, set the TIMUNLOCK bit to allow changing - * the timing registers - */ - tmp = CONFIG_SYS_DA850_DDR2_SDBCR; - tmp &= ~DV_DDR_BOOTUNLOCK; - tmp |= DV_DDR_TIMUNLOCK; - writel(tmp, &dv_ddr2_regs_ctrl->sdbcr); - - /* write memory configuration and timing */ - if (!(CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT))) { - /* MOBILE DDR only*/ - writel(CONFIG_SYS_DA850_DDR2_SDBCR2, - &dv_ddr2_regs_ctrl->sdbcr2); - } - writel(CONFIG_SYS_DA850_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr); - writel(CONFIG_SYS_DA850_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2); - - /* clear the TIMUNLOCK bit and write the value of the CL field */ - tmp &= ~DV_DDR_TIMUNLOCK; - writel(tmp, &dv_ddr2_regs_ctrl->sdbcr); - - /* - * LPMODEN and MCLKSTOPEN must be set! - * Without this bits set, PSC don;t switch states !! - */ - writel(CONFIG_SYS_DA850_DDR2_SDRCR | - (1 << DV_DDR_SRCR_LPMODEN_SHIFT) | - (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT), - &dv_ddr2_regs_ctrl->sdrcr); - - /* SyncReset the Clock to EMIF3A SDRAM */ - lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); - /* Enable the Clock to EMIF3A SDRAM */ - lpsc_on(DAVINCI_LPSC_DDR_EMIF); - - /* disable self refresh */ - clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, - DV_DDR_SDRCR_LPMODEN | DV_DDR_SDRCR_MCLKSTOPEN); - writel(CONFIG_SYS_DA850_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr); - - return 0; -} -#endif /* CONFIG_SYS_DA850_DDR_INIT */ - -__attribute__((weak)) -void board_gpio_init(void) -{ - return; -} - -int arch_cpu_init(void) -{ - /* Unlock kick registers */ - writel(DV_SYSCFG_KICK0_UNLOCK, &davinci_syscfg_regs->kick0); - writel(DV_SYSCFG_KICK1_UNLOCK, &davinci_syscfg_regs->kick1); - - dv_maskbits(&davinci_syscfg_regs->suspsrc, - CONFIG_SYS_DA850_SYSCFG_SUSPSRC); - - /* configure pinmux settings */ - if (davinci_configure_pin_mux_items(pinmuxes, pinmuxes_size)) - return 1; - -#if defined(CONFIG_SYS_DA850_PLL_INIT) - /* PLL setup */ - da850_pll_init(davinci_pllc0_regs, CONFIG_SYS_DA850_PLL0_PLLM); - da850_pll_init(davinci_pllc1_regs, CONFIG_SYS_DA850_PLL1_PLLM); -#endif - /* setup CSn config */ -#if defined(CONFIG_SYS_DA850_CS2CFG) - writel(CONFIG_SYS_DA850_CS2CFG, &davinci_emif_regs->ab1cr); -#endif -#if defined(CONFIG_SYS_DA850_CS3CFG) - writel(CONFIG_SYS_DA850_CS3CFG, &davinci_emif_regs->ab2cr); -#endif - - da8xx_configure_lpsc_items(lpsc, lpsc_size); - - /* GPIO setup */ - board_gpio_init(); - - - NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), - CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); - - /* - * Fix Power and Emulation Management Register - * see sprufw3a.pdf page 37 Table 24 - */ - writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | - DAVINCI_UART_PWREMU_MGMT_UTRST), -#if (CONFIG_SYS_NS16550_COM1 == DAVINCI_UART0_BASE) - &davinci_uart0_ctrl_regs->pwremu_mgmt); -#else - &davinci_uart2_ctrl_regs->pwremu_mgmt); -#endif - -#if defined(CONFIG_SYS_DA850_DDR_INIT) - da850_ddr_setup(); -#endif - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c b/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c deleted file mode 100644 index 6105f6390c..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/da850_pinmux.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Pinmux configurations for the DA850 SoCs - * - * Copyright (C) 2011 OMICRON electronics GmbH - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* SPI pin muxer settings */ -const struct pinmux_config spi1_pins_base[] = { - { pinmux(5), 1, 2 }, /* SPI1_CLK */ - { pinmux(5), 1, 4 }, /* SPI1_SOMI */ - { pinmux(5), 1, 5 }, /* SPI1_SIMO */ -}; - -const struct pinmux_config spi1_pins_scs0[] = { - { pinmux(5), 1, 1 }, /* SPI1_SCS[0] */ -}; - -/* UART pin muxer settings */ -const struct pinmux_config uart0_pins_txrx[] = { - { pinmux(3), 2, 4 }, /* UART0_RXD */ - { pinmux(3), 2, 5 }, /* UART0_TXD */ -}; - -const struct pinmux_config uart0_pins_rtscts[] = { - { pinmux(3), 2, 6 }, - { pinmux(3), 2, 7 }, -}; - -const struct pinmux_config uart1_pins_txrx[] = { - { pinmux(4), 2, 6 }, /* UART1_RXD */ - { pinmux(4), 2, 7 }, /* UART1_TXD */ -}; - -const struct pinmux_config uart2_pins_txrx[] = { - { pinmux(4), 2, 4 }, /* UART2_RXD */ - { pinmux(4), 2, 5 }, /* UART2_TXD */ -}; - -const struct pinmux_config uart2_pins_rtscts[] = { - { pinmux(0), 4, 6 }, /* UART2_RTS */ - { pinmux(0), 4, 7 }, /* UART2_CTS */ -}; - -/* EMAC pin muxer settings*/ -const struct pinmux_config emac_pins_rmii[] = { - { pinmux(14), 8, 2 }, /* RMII_TXD[1] */ - { pinmux(14), 8, 3 }, /* RMII_TXD[0] */ - { pinmux(14), 8, 4 }, /* RMII_TXEN */ - { pinmux(14), 8, 5 }, /* RMII_RXD[1] */ - { pinmux(14), 8, 6 }, /* RMII_RXD[0] */ - { pinmux(14), 8, 7 }, /* RMII_RXER */ - { pinmux(15), 0, 0 }, /* RMII_MHz_50_CLK */ - { pinmux(15), 8, 1 }, /* RMII_CRS_DV */ -}; - -const struct pinmux_config emac_pins_mii[] = { - { pinmux(2), 8, 1 }, /* MII_TXEN */ - { pinmux(2), 8, 2 }, /* MII_TXCLK */ - { pinmux(2), 8, 3 }, /* MII_COL */ - { pinmux(2), 8, 4 }, /* MII_TXD[3] */ - { pinmux(2), 8, 5 }, /* MII_TXD[2] */ - { pinmux(2), 8, 6 }, /* MII_TXD[1] */ - { pinmux(2), 8, 7 }, /* MII_TXD[0] */ - { pinmux(3), 8, 0 }, /* MII_RXCLK */ - { pinmux(3), 8, 1 }, /* MII_RXDV */ - { pinmux(3), 8, 2 }, /* MII_RXER */ - { pinmux(3), 8, 3 }, /* MII_CRS */ - { pinmux(3), 8, 4 }, /* MII_RXD[3] */ - { pinmux(3), 8, 5 }, /* MII_RXD[2] */ - { pinmux(3), 8, 6 }, /* MII_RXD[1] */ - { pinmux(3), 8, 7 }, /* MII_RXD[0] */ -}; - -const struct pinmux_config emac_pins_mdio[] = { - { pinmux(4), 8, 0 }, /* MDIO_CLK */ - { pinmux(4), 8, 1 }, /* MDIO_D */ -}; - -/* I2C pin muxer settings */ -const struct pinmux_config i2c0_pins[] = { - { pinmux(4), 2, 2 }, /* I2C0_SCL */ - { pinmux(4), 2, 3 }, /* I2C0_SDA */ -}; - -const struct pinmux_config i2c1_pins[] = { - { pinmux(4), 4, 4 }, /* I2C1_SCL */ - { pinmux(4), 4, 5 }, /* I2C1_SDA */ -}; - -/* EMIFA pin muxer settings */ -const struct pinmux_config emifa_pins_cs2[] = { - { pinmux(7), 1, 0 }, /* EMA_CS2 */ -}; - -const struct pinmux_config emifa_pins_cs3[] = { - { pinmux(7), 1, 1 }, /* EMA_CS[3] */ -}; - -const struct pinmux_config emifa_pins_cs4[] = { - { pinmux(7), 1, 2 }, /* EMA_CS[4] */ -}; - -const struct pinmux_config emifa_pins_nand[] = { - { pinmux(7), 1, 4 }, /* EMA_WE */ - { pinmux(7), 1, 5 }, /* EMA_OE */ - { pinmux(9), 1, 0 }, /* EMA_D[7] */ - { pinmux(9), 1, 1 }, /* EMA_D[6] */ - { pinmux(9), 1, 2 }, /* EMA_D[5] */ - { pinmux(9), 1, 3 }, /* EMA_D[4] */ - { pinmux(9), 1, 4 }, /* EMA_D[3] */ - { pinmux(9), 1, 5 }, /* EMA_D[2] */ - { pinmux(9), 1, 6 }, /* EMA_D[1] */ - { pinmux(9), 1, 7 }, /* EMA_D[0] */ - { pinmux(12), 1, 5 }, /* EMA_A[2] */ - { pinmux(12), 1, 6 }, /* EMA_A[1] */ -}; - -/* NOR pin muxer settings */ -const struct pinmux_config emifa_pins_nor[] = { - { pinmux(5), 1, 6 }, /* EMA_BA[1] */ - { pinmux(6), 1, 6 }, /* EMA_WAIT[1] */ - { pinmux(7), 1, 4 }, /* EMA_WE */ - { pinmux(7), 1, 5 }, /* EMA_OE */ - { pinmux(8), 1, 0 }, /* EMA_D[15] */ - { pinmux(8), 1, 1 }, /* EMA_D[14] */ - { pinmux(8), 1, 2 }, /* EMA_D[13] */ - { pinmux(8), 1, 3 }, /* EMA_D[12] */ - { pinmux(8), 1, 4 }, /* EMA_D[11] */ - { pinmux(8), 1, 5 }, /* EMA_D[10] */ - { pinmux(8), 1, 6 }, /* EMA_D[9] */ - { pinmux(8), 1, 7 }, /* EMA_D[8] */ - { pinmux(9), 1, 0 }, /* EMA_D[7] */ - { pinmux(9), 1, 1 }, /* EMA_D[6] */ - { pinmux(9), 1, 2 }, /* EMA_D[5] */ - { pinmux(9), 1, 3 }, /* EMA_D[4] */ - { pinmux(9), 1, 4 }, /* EMA_D[3] */ - { pinmux(9), 1, 5 }, /* EMA_D[2] */ - { pinmux(9), 1, 6 }, /* EMA_D[1] */ - { pinmux(9), 1, 7 }, /* EMA_D[0] */ - { pinmux(10), 1, 1 }, /* EMA_A[22] */ - { pinmux(10), 1, 2 }, /* EMA_A[21] */ - { pinmux(10), 1, 3 }, /* EMA_A[20] */ - { pinmux(10), 1, 4 }, /* EMA_A[19] */ - { pinmux(10), 1, 5 }, /* EMA_A[18] */ - { pinmux(10), 1, 6 }, /* EMA_A[17] */ - { pinmux(10), 1, 7 }, /* EMA_A[16] */ - { pinmux(11), 1, 0 }, /* EMA_A[15] */ - { pinmux(11), 1, 1 }, /* EMA_A[14] */ - { pinmux(11), 1, 2 }, /* EMA_A[13] */ - { pinmux(11), 1, 3 }, /* EMA_A[12] */ - { pinmux(11), 1, 4 }, /* EMA_A[11] */ - { pinmux(11), 1, 5 }, /* EMA_A[10] */ - { pinmux(11), 1, 6 }, /* EMA_A[9] */ - { pinmux(11), 1, 7 }, /* EMA_A[8] */ - { pinmux(12), 1, 0 }, /* EMA_A[7] */ - { pinmux(12), 1, 1 }, /* EMA_A[6] */ - { pinmux(12), 1, 2 }, /* EMA_A[5] */ - { pinmux(12), 1, 3 }, /* EMA_A[4] */ - { pinmux(12), 1, 4 }, /* EMA_A[3] */ - { pinmux(12), 1, 5 }, /* EMA_A[2] */ - { pinmux(12), 1, 6 }, /* EMA_A[1] */ - { pinmux(12), 1, 7 }, /* EMA_A[0] */ -}; - -/* MMC0 pin muxer settings */ -const struct pinmux_config mmc0_pins[] = { - { pinmux(10), 2, 0 }, /* MMCSD0_CLK */ - { pinmux(10), 2, 1 }, /* MMCSD0_CMD */ - { pinmux(10), 2, 2 }, /* MMCSD0_DAT_0 */ - { pinmux(10), 2, 3 }, /* MMCSD0_DAT_1 */ - { pinmux(10), 2, 4 }, /* MMCSD0_DAT_2 */ - { pinmux(10), 2, 5 }, /* MMCSD0_DAT_3 */ - /* DA850 supports only 4-bit mode, remaining pins are not configured */ -}; diff --git a/arch/arm/cpu/arm926ejs/davinci/dm355.c b/arch/arm/cpu/arm926ejs/davinci/dm355.c deleted file mode 100644 index f9550a16d3..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dm355.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SoC-specific code for tms320dm355 and similar chips - * - * Copyright (C) 2009 David Brownell - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x00006001; -} - - -#ifdef CONFIG_SYS_I2C_DAVINCI -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); - - /* Enable I2C pin Mux */ - REG(PINMUX3) |= (1 << 20) | (1 << 19); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm365.c b/arch/arm/cpu/arm926ejs/davinci/dm365.c deleted file mode 100644 index f6ca527e74..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dm365.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * SoC-specific code for tms320dm365 and similar chips - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); -} - -#ifdef CONFIG_SYS_I2C_DAVINCI -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dm365_lowlevel.c b/arch/arm/cpu/arm926ejs/davinci/dm365_lowlevel.c deleted file mode 100644 index c8b44988d3..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dm365_lowlevel.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * SoC-specific lowlevel code for tms320dm365 and similar chips - * Actually used for booting from NAND with nand_spl. - * - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include -#include -#include - -void dm365_waitloop(unsigned long loopcnt) -{ - unsigned long i; - - for (i = 0; i < loopcnt; i++) - asm(" NOP"); -} - -int dm365_pll1_init(unsigned long pllmult, unsigned long prediv) -{ - unsigned int clksrc = 0x0; - - /* Power up the PLL */ - clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLPWRDN); - - clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_RES_9); - setbits_le32(&dv_pll0_regs->pllctl, - clksrc << PLLCTL_CLOCK_MODE_SHIFT); - - /* - * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled - * through MMR - */ - clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLENSRC); - - /* Set PLLEN=0 => PLL BYPASS MODE */ - clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN); - - dm365_waitloop(150); - - /* PLLRST=1(reset assert) */ - setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST); - - dm365_waitloop(300); - - /*Bring PLL out of Reset*/ - clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST); - - /* Program the Multiper and Pre-Divider for PLL1 */ - writel(pllmult, &dv_pll0_regs->pllm); - writel(prediv, &dv_pll0_regs->prediv); - - /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE | - PLLSECCTL_TINITZ, &dv_pll0_regs->secctl); - /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE, - &dv_pll0_regs->secctl); - /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */ - writel(PLLSECCTL_STOPMODE, &dv_pll0_regs->secctl); - /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll0_regs->secctl); - - /* Program the PostDiv for PLL1 */ - writel(PLL_POSTDEN, &dv_pll0_regs->postdiv); - - /* Post divider setting for PLL1 */ - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV1, &dv_pll0_regs->plldiv1); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV2, &dv_pll0_regs->plldiv2); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV3, &dv_pll0_regs->plldiv3); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV4, &dv_pll0_regs->plldiv4); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV5, &dv_pll0_regs->plldiv5); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV6, &dv_pll0_regs->plldiv6); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV7, &dv_pll0_regs->plldiv7); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV8, &dv_pll0_regs->plldiv8); - writel(CONFIG_SYS_DM36x_PLL1_PLLDIV9, &dv_pll0_regs->plldiv9); - - dm365_waitloop(300); - - /* Set the GOSET bit */ - writel(PLLCMD_GOSET, &dv_pll0_regs->pllcmd); /* Go */ - - dm365_waitloop(300); - - /* Wait for PLL to LOCK */ - while (!((readl(&dv_sys_module_regs->pll0_config) & PLL0_LOCK) - == PLL0_LOCK)) - ; - - /* Enable the PLL Bit of PLLCTL*/ - setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN); - - return 0; -} - -int dm365_pll2_init(unsigned long pllm, unsigned long prediv) -{ - unsigned int clksrc = 0x0; - - /* Power up the PLL*/ - clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLPWRDN); - - /* - * Select the Clock Mode as Onchip Oscilator or External Clock on - * MXI pin - * VDB has input on MXI pin - */ - clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_RES_9); - setbits_le32(&dv_pll1_regs->pllctl, - clksrc << PLLCTL_CLOCK_MODE_SHIFT); - - /* - * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled - * through MMR - */ - clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLENSRC); - - /* Set PLLEN=0 => PLL BYPASS MODE */ - clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN); - - dm365_waitloop(50); - - /* PLLRST=1(reset assert) */ - setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST); - - dm365_waitloop(300); - - /* Bring PLL out of Reset */ - clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST); - - /* Program the Multiper and Pre-Divider for PLL2 */ - writel(pllm, &dv_pll1_regs->pllm); - writel(prediv, &dv_pll1_regs->prediv); - - writel(PLL_POSTDEN, &dv_pll1_regs->postdiv); - - /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE | - PLLSECCTL_TINITZ, &dv_pll1_regs->secctl); - /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE, - &dv_pll1_regs->secctl); - /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */ - writel(PLLSECCTL_STOPMODE, &dv_pll1_regs->secctl); - /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */ - writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll1_regs->secctl); - - /* Post divider setting for PLL2 */ - writel(CONFIG_SYS_DM36x_PLL2_PLLDIV1, &dv_pll1_regs->plldiv1); - writel(CONFIG_SYS_DM36x_PLL2_PLLDIV2, &dv_pll1_regs->plldiv2); - writel(CONFIG_SYS_DM36x_PLL2_PLLDIV3, &dv_pll1_regs->plldiv3); - writel(CONFIG_SYS_DM36x_PLL2_PLLDIV4, &dv_pll1_regs->plldiv4); - writel(CONFIG_SYS_DM36x_PLL2_PLLDIV5, &dv_pll1_regs->plldiv5); - - /* GoCmd for PostDivider to take effect */ - writel(PLLCMD_GOSET, &dv_pll1_regs->pllcmd); - - dm365_waitloop(150); - - /* Wait for PLL to LOCK */ - while (!((readl(&dv_sys_module_regs->pll1_config) & PLL1_LOCK) - == PLL1_LOCK)) - ; - - dm365_waitloop(4100); - - /* Enable the PLL2 */ - setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN); - - /* do this after PLL's have been set up */ - writel(CONFIG_SYS_DM36x_PERI_CLK_CTRL, - &dv_sys_module_regs->peri_clkctl); - - return 0; -} - -int dm365_ddr_setup(void) -{ - lpsc_on(DAVINCI_LPSC_DDR_EMIF); - clrbits_le32(&dv_sys_module_regs->vtpiocr, - VPTIO_IOPWRDN | VPTIO_CLRZ | VPTIO_LOCK | VPTIO_PWRDN); - - /* Set bit CLRZ (bit 13) */ - setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_CLRZ); - - /* Check VTP READY Status */ - while (!(readl(&dv_sys_module_regs->vtpiocr) & VPTIO_RDY)) - ; - - /* Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) */ - setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_IOPWRDN); - - /* Set bit LOCK(bit7) */ - setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_LOCK); - - /* - * Powerdown VTP as it is locked (bit 6) - * Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) - */ - setbits_le32(&dv_sys_module_regs->vtpiocr, - VPTIO_IOPWRDN | VPTIO_PWRDN); - - /* Wait for calibration to complete */ - dm365_waitloop(150); - - /* Set the DDR2 to synreset, then enable it again */ - lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); - lpsc_on(DAVINCI_LPSC_DDR_EMIF); - - writel(CONFIG_SYS_DM36x_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr); - - /* Program SDRAM Bank Config Register */ - writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_BOOTUNLOCK), - &dv_ddr2_regs_ctrl->sdbcr); - writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_TIMUNLOCK), - &dv_ddr2_regs_ctrl->sdbcr); - - /* Program SDRAM Timing Control Register1 */ - writel(CONFIG_SYS_DM36x_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr); - /* Program SDRAM Timing Control Register2 */ - writel(CONFIG_SYS_DM36x_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2); - - writel(CONFIG_SYS_DM36x_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr); - - writel(CONFIG_SYS_DM36x_DDR2_SDBCR, &dv_ddr2_regs_ctrl->sdbcr); - - /* Program SDRAM Refresh Control Register */ - writel(CONFIG_SYS_DM36x_DDR2_SDRCR, &dv_ddr2_regs_ctrl->sdrcr); - - lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); - lpsc_on(DAVINCI_LPSC_DDR_EMIF); - - return 0; -} - -static void dm365_vpss_sync_reset(void) -{ - unsigned int PdNum = 0; - - /* VPSS_CLKMD 1:1 */ - setbits_le32(&dv_sys_module_regs->vpss_clkctl, - VPSS_CLK_CTL_VPSS_CLKMD); - - /* LPSC SyncReset DDR Clock Enable */ - writel(((readl(&dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]) & - ~PSC_MD_STATE_MSK) | PSC_SYNCRESET), - &dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]); - - writel((1 << PdNum), &dv_psc_regs->ptcmd); - - while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) == 0)) - ; - while (!((readl(&dv_psc_regs->mdstat[DAVINCI_LPSC_VPSSMASTER]) & - PSC_MD_STATE_MSK) == PSC_SYNCRESET)) - ; -} - -static void dm365_por_reset(void) -{ - struct davinci_timer *wdog = - (struct davinci_timer *)DAVINCI_WDOG_BASE; - - if (readl(&dv_pll0_regs->rstype) & - (PLL_RSTYPE_POR | PLL_RSTYPE_XWRST)) { - dm365_vpss_sync_reset(); - - writel(DV_TMPBUF_VAL, TMPBUF); - setbits_le32(TMPSTATUS, FLAG_PORRST); - writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1); - writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2); - - while (1); - } -} - -static void dm365_wdt_reset(void) -{ - struct davinci_timer *wdog = - (struct davinci_timer *)DAVINCI_WDOG_BASE; - - if (readl(TMPBUF) != DV_TMPBUF_VAL) { - writel(DV_TMPBUF_VAL, TMPBUF); - setbits_le32(TMPSTATUS, FLAG_PORRST); - setbits_le32(TMPSTATUS, FLAG_FLGOFF); - - dm365_waitloop(100); - - dm365_vpss_sync_reset(); - - writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1); - writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2); - - while (1); - } -} - -static void dm365_wdt_flag_on(void) -{ - /* VPSS_CLKMD 1:2 */ - clrbits_le32(&dv_sys_module_regs->vpss_clkctl, - VPSS_CLK_CTL_VPSS_CLKMD); - writel(0, TMPBUF); - setbits_le32(TMPSTATUS, FLAG_FLGON); -} - -void dm365_psc_init(void) -{ - unsigned char i = 0; - unsigned char lpsc_start; - unsigned char lpsc_end, lpscgroup, lpscmin, lpscmax; - unsigned int PdNum = 0; - - lpscmin = 0; - lpscmax = 2; - - for (lpscgroup = lpscmin; lpscgroup <= lpscmax; lpscgroup++) { - if (lpscgroup == 0) { - /* Enabling LPSC 3 to 28 SCR first */ - lpsc_start = DAVINCI_LPSC_VPSSMSTR; - lpsc_end = DAVINCI_LPSC_TIMER1; - } else if (lpscgroup == 1) { /* Skip locked LPSCs [29-37] */ - lpsc_start = DAVINCI_LPSC_CFG5; - lpsc_end = DAVINCI_LPSC_VPSSMASTER; - } else { - lpsc_start = DAVINCI_LPSC_MJCP; - lpsc_end = DAVINCI_LPSC_HDVICP; - } - - /* NEXT=0x3, Enable LPSC's */ - for (i = lpsc_start; i <= lpsc_end; i++) - setbits_le32(&dv_psc_regs->mdctl[i], PSC_ENABLE); - - /* - * Program goctl to start transition sequence for LPSCs - * CSL_PSC_0_REGS->PTCMD = (1<ptcmd); - - /* - * Wait for GOSTAT = NO TRANSITION from PSC for Powerdomain 0 - */ - while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) - == 0)) - ; - - /* Wait for MODSTAT = ENABLE from LPSC's */ - for (i = lpsc_start; i <= lpsc_end; i++) - while (!((readl(&dv_psc_regs->mdstat[i]) & - PSC_MD_STATE_MSK) == PSC_ENABLE)) - ; - } -} - -static void dm365_emif_init(void) -{ - writel(CONFIG_SYS_DM36x_AWCCR, &davinci_emif_regs->awccr); - writel(CONFIG_SYS_DM36x_AB1CR, &davinci_emif_regs->ab1cr); - - setbits_le32(&davinci_emif_regs->nandfcr, DAVINCI_NANDFCR_CS2NAND); - - writel(CONFIG_SYS_DM36x_AB2CR, &davinci_emif_regs->ab2cr); - - return; -} - -void dm365_pinmux_ctl(unsigned long offset, unsigned long mask, - unsigned long value) -{ - clrbits_le32(&dv_sys_module_regs->pinmux[offset], mask); - setbits_le32(&dv_sys_module_regs->pinmux[offset], (mask & value)); -} - -__attribute__((weak)) -void board_gpio_init(void) -{ - return; -} - -#if defined(CONFIG_POST) -int post_log(char *format, ...) -{ - return 0; -} -#endif - -void dm36x_lowlevel_init(ulong bootflag) -{ - struct davinci_uart_ctrl_regs *davinci_uart_ctrl_regs = - (struct davinci_uart_ctrl_regs *)(CONFIG_SYS_NS16550_COM1 + - DAVINCI_UART_CTRL_BASE); - - /* Mask all interrupts */ - writel(DV_AINTC_INTCTL_IDMODE, &dv_aintc_regs->intctl); - writel(0x0, &dv_aintc_regs->eabase); - writel(0x0, &dv_aintc_regs->eint0); - writel(0x0, &dv_aintc_regs->eint1); - - /* Clear all interrupts */ - writel(0xffffffff, &dv_aintc_regs->fiq0); - writel(0xffffffff, &dv_aintc_regs->fiq1); - writel(0xffffffff, &dv_aintc_regs->irq0); - writel(0xffffffff, &dv_aintc_regs->irq1); - - dm365_por_reset(); - dm365_wdt_reset(); - - /* System PSC setup - enable all */ - dm365_psc_init(); - - /* Setup Pinmux */ - dm365_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX0); - dm365_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX1); - dm365_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX2); - dm365_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX3); - dm365_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX4); - - /* PLL setup */ - dm365_pll1_init(CONFIG_SYS_DM36x_PLL1_PLLM, - CONFIG_SYS_DM36x_PLL1_PREDIV); - dm365_pll2_init(CONFIG_SYS_DM36x_PLL2_PLLM, - CONFIG_SYS_DM36x_PLL2_PREDIV); - - /* GPIO setup */ - board_gpio_init(); - - NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), - CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); - - /* - * Fix Power and Emulation Management Register - * see sprufh2.pdf page 38 Table 22 - */ - writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | - DAVINCI_UART_PWREMU_MGMT_UTRST), - &davinci_uart_ctrl_regs->pwremu_mgmt); - - puts("ddr init\n"); - dm365_ddr_setup(); - - puts("emif init\n"); - dm365_emif_init(); - - dm365_wdt_flag_on(); - -#if defined(CONFIG_POST) - /* - * Do memory tests, calls arch_memory_failure_handle() - * if error detected. - */ - memory_post_test(0); -#endif -} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm644x.c b/arch/arm/cpu/arm926ejs/davinci/dm644x.c deleted file mode 100644 index c58e271e28..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dm644x.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SoC-specific code for tms320dm644x chips - * - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - - -#define PINMUX0_EMACEN (1 << 31) -#define PINMUX0_AECS5 (1 << 11) -#define PINMUX0_AECS4 (1 << 10) - -#define PINMUX1_I2C (1 << 7) -#define PINMUX1_UART1 (1 << 1) -#define PINMUX1_UART0 (1 << 0) - - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_LPSC_UART0); - - /* Bringup UART0 out of reset */ - REG(UART0_PWREMU_MGMT) = 0x00006001; - - /* Enable UART0 MUX lines */ - REG(PINMUX1) |= PINMUX1_UART0; -} - -#ifdef CONFIG_DRIVER_TI_EMAC -void davinci_enable_emac(void) -{ - lpsc_on(DAVINCI_LPSC_EMAC); - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); - lpsc_on(DAVINCI_LPSC_MDIO); - - /* Enable GIO3.3V cells used for EMAC */ - REG(VDD3P3V_PWDN) = 0; - - /* Enable EMAC. */ - REG(PINMUX0) |= PINMUX0_EMACEN; -} -#endif - -#ifdef CONFIG_SYS_I2C_DAVINCI -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_LPSC_I2C); - - /* Enable I2C pin Mux */ - REG(PINMUX1) |= PINMUX1_I2C; -} -#endif - -void davinci_errata_workarounds(void) -{ - /* - * Workaround for TMS320DM6446 errata 1.3.22: - * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset - * Revision(s) Affected: 1.3 and earlier - */ - REG(PSC_SILVER_BULLET) = 0; - - /* - * Set the PR_OLD_COUNT bits in the Bus Burst Priority Register (PBBPR) - * as suggested in TMS320DM6446 errata 2.1.2: - * - * On DM6446 Silicon Revision 2.1 and earlier, under certain conditions - * low priority modules can occupy the bus and prevent high priority - * modules like the VPSS from getting the required DDR2 throughput. - * A hex value of 0x20 should provide a good ARM (cache enabled) - * performance and still allow good utilization by the VPSS or other - * modules. - */ - REG(VBPR) = 0x20; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/dm646x.c b/arch/arm/cpu/arm926ejs/davinci/dm646x.c deleted file mode 100644 index cfea8300de..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dm646x.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SoC-specific code for TMS320DM646x chips - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -void davinci_enable_uart0(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_UART0); -} - -#ifdef CONFIG_DRIVER_TI_EMAC -void davinci_enable_emac(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_EMAC); -} -#endif - -#ifdef CONFIG_SYS_I2C_DAVINCI -void davinci_enable_i2c(void) -{ - lpsc_on(DAVINCI_DM646X_LPSC_I2C); -} -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/dp83848.c b/arch/arm/cpu/arm926ejs/davinci/dp83848.c deleted file mode 100644 index 603d507c70..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/dp83848.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * National Semiconductor DP83848 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * -------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include "../../../../../drivers/net/davinci_emac.h" - -#ifdef CONFIG_DRIVER_TI_EMAC - -#ifdef CONFIG_CMD_NET - -int dp83848_is_phy_connected(int phy_addr) -{ - u_int16_t id1, id2; - - if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) - return(0); - if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) - return(0); - - if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) - return(1); - - return(0); -} - -int dp83848_get_link_speed(int phy_addr) -{ - u_int16_t tmp; - volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; - - if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) - return(0); - - if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ - return(0); - - if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) - return(0); - - /* Speed doesn't matter, there is no setting for it in EMAC... */ - if (tmp & DP83848_DUPLEX) { - /* set DM644x EMAC for Full Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE; - } else { - /*set DM644x EMAC for Half Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; - } - - return(1); -} - - -int dp83848_init_phy(int phy_addr) -{ - int ret = 1; - - if (!dp83848_get_link_speed(phy_addr)) { - /* Try another time */ - udelay(100000); - ret = dp83848_get_link_speed(phy_addr); - } - - /* Disable PHY Interrupts */ - davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); - - return(ret); -} - - -int dp83848_auto_negotiate(int phy_addr) -{ - u_int16_t tmp; - - - if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) - return(0); - - /* Restart Auto_negotiation */ - tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ - tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /* Set the Auto_negotiation Advertisement Register - * MII advertising for Next page, 100BaseTxFD and HD, - * 10BaseTFD and HD, IEEE 802.3 - */ - tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | - DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; - davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); - - - /* Read Control Register */ - if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) - return(0); - - tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /* Restart Auto_negotiation */ - tmp |= DP83848_RESTART_AUTONEG; - davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); - - /*check AutoNegotiate complete */ - udelay(10000); - if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) - return(0); - - if (!(tmp & DP83848_AUTONEG_COMP)) - return(0); - - return (dp83848_get_link_speed(phy_addr)); -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/et1011c.c b/arch/arm/cpu/arm926ejs/davinci/et1011c.c deleted file mode 100644 index 9d53875b93..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/et1011c.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * LSI ET1011C PHY Driver for TI DaVinci(TMS320DM6467) board. - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include "../../../../../drivers/net/davinci_emac.h" - -#ifdef CONFIG_DRIVER_TI_EMAC - -#ifdef CONFIG_CMD_NET - -/* LSI PHYSICAL LAYER TRANSCEIVER ET1011C */ - -#define MII_PHY_CONFIG_REG 22 - -/* PHY Config bits */ -#define PHY_SYS_CLK_EN (1 << 4) - -int et1011c_get_link_speed(int phy_addr) -{ - u_int16_t data; - - if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &data) && (data & 0x04)) { - davinci_eth_phy_read(phy_addr, MII_PHY_CONFIG_REG, &data); - /* Enable 125MHz clock sourced from PHY */ - davinci_eth_phy_write(phy_addr, MII_PHY_CONFIG_REG, - data | PHY_SYS_CLK_EN); - return (1); - } - return (0); -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/ksz8873.c b/arch/arm/cpu/arm926ejs/davinci/ksz8873.c deleted file mode 100644 index 4af5dd2135..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/ksz8873.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Micrel KSZ8873 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2011 Heiko Schocher - * - * based on: - * National Semiconductor DP83848 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * -------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include "../../../../../drivers/net/davinci_emac.h" - -int ksz8873_is_phy_connected(int phy_addr) -{ - u_int16_t dummy; - - return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); -} - -int ksz8873_get_link_speed(int phy_addr) -{ - emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; - - /* we always have a link to the switch, 100 FD */ - writel((EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE), - &emac->MACCONTROL); - return 1; -} - - -int ksz8873_init_phy(int phy_addr) -{ - return 1; -} - - -int ksz8873_auto_negotiate(int phy_addr) -{ - return dp83848_get_link_speed(phy_addr); -} diff --git a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S b/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S deleted file mode 100644 index e91623497c..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/lowlevel_init.S +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Low-level board setup code for TI DaVinci SoC based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * Partially based on TI sources, original copyrights follow: - */ - -/* - * Board specific setup info - * - * (C) Copyright 2003 - * Texas Instruments, - * Kshitij Gupta - * - * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004 - * - * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004 - * - * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005 - * - * Modified for DV-EVM board by Swaminathan S, Nov 2005 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#define MDSTAT_STATE 0x3f - -.globl lowlevel_init -lowlevel_init: -#ifdef CONFIG_SOC_DM644X - - /*-------------------------------------------------------* - * Mask all IRQs by setting all bits in the EINT default * - *-------------------------------------------------------*/ - mov r1, $0 - ldr r0, =EINT_ENABLE0 - str r1, [r0] - ldr r0, =EINT_ENABLE1 - str r1, [r0] - - /*------------------------------------------------------* - * Put the GEM in reset * - *------------------------------------------------------*/ - - /* Put the GEM in reset */ - ldr r8, PSC_GEM_FLAG_CLEAR - ldr r6, MDCTL_GEM - ldr r7, [r6] - and r7, r7, r8 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x02 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStopGem: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x02 - bne checkStatClkStopGem - - /* Check for GEM Reset Completion */ -checkGemStatClkStop: - ldr r6, MDSTAT_GEM - ldr r7, [r6] - ands r7, r7, $0x100 - bne checkGemStatClkStop - - /* Do this for enabling a WDT initiated reset this is a workaround - for a chip bug. Not required under normal situations */ - ldr r6, P1394 - mov r10, $0 - str r10, [r6] - - /*------------------------------------------------------* - * Enable L1 & L2 Memories in Fast mode * - *------------------------------------------------------*/ - ldr r6, DFT_ENABLE - mov r10, $0x01 - str r10, [r6] - - ldr r6, MMARG_BRF0 - ldr r10, MMARG_BRF0_VAL - str r10, [r6] - - ldr r6, DFT_ENABLE - mov r10, $0 - str r10, [r6] - - /*------------------------------------------------------* - * DDR2 PLL Initialization * - *------------------------------------------------------*/ - - /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ - mov r10, $0 - ldr r6, PLL2_CTL - ldr r7, PLL_CLKSRC_MASK - ldr r8, [r6] - and r8, r8, r7 - mov r9, r10, lsl $8 - orr r8, r8, r9 - str r8, [r6] - - /* Select the PLLEN source */ - ldr r7, PLL_ENSRC_MASK - and r8, r8, r7 - str r8, [r6] - - /* Bypass the PLL */ - ldr r7, PLL_BYPASS_MASK - and r8, r8, r7 - str r8, [r6] - - /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ - mov r10, $0x20 -WaitPPL2Loop: - subs r10, r10, $1 - bne WaitPPL2Loop - - /* Reset the PLL */ - ldr r7, PLL_RESET_MASK - and r8, r8, r7 - str r8, [r6] - - /* Power up the PLL */ - ldr r7, PLL_PWRUP_MASK - and r8, r8, r7 - str r8, [r6] - - /* Enable the PLL from Disable Mode */ - ldr r7, PLL_DISABLE_ENABLE_MASK - and r8, r8, r7 - str r8, [r6] - - /* Program the PLL Multiplier */ - ldr r6, PLL2_PLLM - mov r2, $0x17 /* 162 MHz */ - str r2, [r6] - - /* Program the PLL2 Divisor Value */ - ldr r6, PLL2_DIV2 - mov r3, $0x01 - str r3, [r6] - - /* Program the PLL2 Divisor Value */ - ldr r6, PLL2_DIV1 - mov r4, $0x0b /* 54 MHz */ - str r4, [r6] - - /* PLL2 DIV2 MMR */ - ldr r8, PLL2_DIV_MASK - ldr r6, PLL2_DIV2 - ldr r9, [r6] - and r8, r8, r9 - mov r9, $0x01 - mov r9, r9, lsl $15 - orr r8, r8, r9 - str r8, [r6] - - /* Program the GOSET bit to take new divider values */ - ldr r6, PLL2_PLLCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Wait for Done */ - ldr r6, PLL2_PLLSTAT -doneLoop_0: - ldr r7, [r6] - ands r7, r7, $0x01 - bne doneLoop_0 - - /* PLL2 DIV1 MMR */ - ldr r8, PLL2_DIV_MASK - ldr r6, PLL2_DIV1 - ldr r9, [r6] - and r8, r8, r9 - mov r9, $0x01 - mov r9, r9, lsl $15 - orr r8, r8, r9 - str r8, [r6] - - /* Program the GOSET bit to take new divider values */ - ldr r6, PLL2_PLLCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Wait for Done */ - ldr r6, PLL2_PLLSTAT -doneLoop: - ldr r7, [r6] - ands r7, r7, $0x01 - bne doneLoop - - /* Wait for PLL to Reset Properly */ - mov r10, $0x218 -ResetPPL2Loop: - subs r10, r10, $1 - bne ResetPPL2Loop - - /* Bring PLL out of Reset */ - ldr r6, PLL2_CTL - ldr r8, [r6] - orr r8, r8, $0x08 - str r8, [r6] - - /* Wait for PLL to Lock */ - ldr r10, PLL_LOCK_COUNT -PLL2Lock: - subs r10, r10, $1 - bne PLL2Lock - - /* Enable the PLL */ - ldr r6, PLL2_CTL - ldr r8, [r6] - orr r8, r8, $0x01 - str r8, [r6] - - /*------------------------------------------------------* - * Issue Soft Reset to DDR Module * - *------------------------------------------------------*/ - - /* Shut down the DDR2 LPSC Module */ - ldr r8, PSC_FLAG_CLEAR - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - and r7, r7, r8 - orr r7, r7, $0x03 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStop: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkStop - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkStop: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $MDSTAT_STATE - cmp r7, $0x03 - bne checkDDRStatClkStop - - /*------------------------------------------------------* - * Program DDR2 MMRs for 162MHz Setting * - *------------------------------------------------------*/ - - /* Program PHY Control Register */ - ldr r6, DDRCTL - ldr r7, DDRCTL_VAL - str r7, [r6] - - /* Program SDRAM Bank Config Register */ - ldr r6, SDCFG - ldr r7, SDCFG_VAL - str r7, [r6] - - /* Program SDRAM TIM-0 Config Register */ - ldr r6, SDTIM0 - ldr r7, SDTIM0_VAL_162MHz - str r7, [r6] - - /* Program SDRAM TIM-1 Config Register */ - ldr r6, SDTIM1 - ldr r7, SDTIM1_VAL_162MHz - str r7, [r6] - - /* Program the SDRAM Bank Config Control Register */ - ldr r10, MASK_VAL - ldr r8, SDCFG - ldr r9, SDCFG_VAL - and r9, r9, r10 - str r9, [r8] - - /* Program SDRAM SDREF Config Register */ - ldr r6, SDREF - ldr r7, SDREF_VAL - str r7, [r6] - - /*------------------------------------------------------* - * Issue Soft Reset to DDR Module * - *------------------------------------------------------*/ - - /* Issue a Dummy DDR2 read/write */ - ldr r8, DDR2_START_ADDR - ldr r7, DUMMY_VAL - str r7, [r8] - ldr r7, [r8] - - /* Shut down the DDR2 LPSC Module */ - ldr r8, PSC_FLAG_CLEAR - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - and r7, r7, r8 - orr r7, r7, $0x01 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkStop2: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkStop2 - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkStop2: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $MDSTAT_STATE - cmp r7, $0x01 - bne checkDDRStatClkStop2 - - /*------------------------------------------------------* - * Turn DDR2 Controller Clocks On * - *------------------------------------------------------*/ - - /* Enable the DDR2 LPSC Module */ - ldr r6, MDCTL_DDR2 - ldr r7, [r6] - orr r7, r7, $0x03 - str r7, [r6] - - /* Enable the Power Domain Transition Command */ - ldr r6, PTCMD - ldr r7, [r6] - orr r7, r7, $0x01 - str r7, [r6] - - /* Check for Transition Complete(PTSTAT) */ -checkStatClkEn2: - ldr r6, PTSTAT - ldr r7, [r6] - ands r7, r7, $0x01 - bne checkStatClkEn2 - - /* Check for DDR2 Controller Enable Completion */ -checkDDRStatClkEn2: - ldr r6, MDSTAT_DDR2 - ldr r7, [r6] - and r7, r7, $MDSTAT_STATE - cmp r7, $0x03 - bne checkDDRStatClkEn2 - - /* DDR Writes and Reads */ - ldr r6, CFGTEST - mov r3, $0x01 - str r3, [r6] - - /*------------------------------------------------------* - * System PLL Initialization * - *------------------------------------------------------*/ - - /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ - mov r2, $0 - ldr r6, PLL1_CTL - ldr r7, PLL_CLKSRC_MASK - ldr r8, [r6] - and r8, r8, r7 - mov r9, r2, lsl $8 - orr r8, r8, r9 - str r8, [r6] - - /* Select the PLLEN source */ - ldr r7, PLL_ENSRC_MASK - and r8, r8, r7 - str r8, [r6] - - /* Bypass the PLL */ - ldr r7, PLL_BYPASS_MASK - and r8, r8, r7 - str r8, [r6] - - /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ - mov r10, $0x20 - -WaitLoop: - subs r10, r10, $1 - bne WaitLoop - - /* Reset the PLL */ - ldr r7, PLL_RESET_MASK - and r8, r8, r7 - str r8, [r6] - - /* Disable the PLL */ - orr r8, r8, $0x10 - str r8, [r6] - - /* Power up the PLL */ - ldr r7, PLL_PWRUP_MASK - and r8, r8, r7 - str r8, [r6] - - /* Enable the PLL from Disable Mode */ - ldr r7, PLL_DISABLE_ENABLE_MASK - and r8, r8, r7 - str r8, [r6] - - /* Program the PLL Multiplier */ - ldr r6, PLL1_PLLM - mov r3, $0x15 /* For 594MHz */ - str r3, [r6] - - /* Wait for PLL to Reset Properly */ - mov r10, $0xff - -ResetLoop: - subs r10, r10, $1 - bne ResetLoop - - /* Bring PLL out of Reset */ - ldr r6, PLL1_CTL - orr r8, r8, $0x08 - str r8, [r6] - - /* Wait for PLL to Lock */ - ldr r10, PLL_LOCK_COUNT - -PLL1Lock: - subs r10, r10, $1 - bne PLL1Lock - - /* Enable the PLL */ - orr r8, r8, $0x01 - str r8, [r6] - - nop - nop - nop - nop - - /*------------------------------------------------------* - * AEMIF configuration for NOR Flash (double check) * - *------------------------------------------------------*/ - ldr r0, _PINMUX0 - ldr r1, _DEV_SETTING - str r1, [r0] - - ldr r0, WAITCFG - ldr r1, WAITCFG_VAL - ldr r2, [r0] - orr r2, r2, r1 - str r2, [r0] - - ldr r0, ACFG3 - ldr r1, ACFG3_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - ldr r0, ACFG4 - ldr r1, ACFG4_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - ldr r0, ACFG5 - ldr r1, ACFG5_VAL - ldr r2, [r0] - and r1, r2, r1 - str r1, [r0] - - /*--------------------------------------* - * VTP manual Calibration * - *--------------------------------------*/ - ldr r0, VTPIOCR - ldr r1, VTP_MMR0 - str r1, [r0] - - ldr r0, VTPIOCR - ldr r1, VTP_MMR1 - str r1, [r0] - - /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ - ldr r10, VTP_LOCK_COUNT -VTPLock: - subs r10, r10, $1 - bne VTPLock - - ldr r6, DFT_ENABLE - mov r10, $0x01 - str r10, [r6] - - ldr r6, DDRVTPR - ldr r7, [r6] - mov r8, r7, LSL #32-10 - mov r8, r8, LSR #32-10 /* grab low 10 bits */ - ldr r7, VTP_RECAL - orr r8, r7, r8 - ldr r7, VTP_EN - orr r8, r7, r8 - str r8, [r0] - - - /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ - ldr r10, VTP_LOCK_COUNT -VTP1Lock: - subs r10, r10, $1 - bne VTP1Lock - - ldr r1, [r0] - ldr r2, VTP_MASK - and r2, r1, r2 - str r2, [r0] - - ldr r6, DFT_ENABLE - mov r10, $0 - str r10, [r6] - - /* - * Call board-specific lowlevel init. - * That MUST be present and THAT returns - * back to arch calling code with "mov pc, lr." - */ - b dv_board_init - -.ltorg - -_PINMUX0: - .word 0x01c40000 /* Device Configuration Registers */ -_PINMUX1: - .word 0x01c40004 /* Device Configuration Registers */ - -_DEV_SETTING: - .word 0x00000c1f - -WAITCFG: - .word 0x01e00004 -WAITCFG_VAL: - .word 0 -ACFG3: - .word 0x01e00014 -ACFG3_VAL: - .word 0x3ffffffd -ACFG4: - .word 0x01e00018 -ACFG4_VAL: - .word 0x3ffffffd -ACFG5: - .word 0x01e0001c -ACFG5_VAL: - .word 0x3ffffffd - -MDCTL_DDR2: - .word 0x01c41a34 -MDSTAT_DDR2: - .word 0x01c41834 - -PTCMD: - .word 0x01c41120 -PTSTAT: - .word 0x01c41128 - -EINT_ENABLE0: - .word 0x01c48018 -EINT_ENABLE1: - .word 0x01c4801c - -PSC_FLAG_CLEAR: - .word 0xffffffe0 -PSC_GEM_FLAG_CLEAR: - .word 0xfffffeff - -/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ -DDRCTL: - .word 0x200000e4 -DDRCTL_VAL: - .word 0x50006405 -SDREF: - .word 0x2000000c -SDREF_VAL: - .word 0x000005c3 -SDCFG: - .word 0x20000008 -SDCFG_VAL: -#ifdef DDR_4BANKS - .word 0x00178622 -#elif defined DDR_8BANKS - .word 0x00178632 -#else -#error "Unknown DDR configuration!!!" -#endif -SDTIM0: - .word 0x20000010 -SDTIM0_VAL_162MHz: - .word 0x28923211 -SDTIM1: - .word 0x20000014 -SDTIM1_VAL_162MHz: - .word 0x0016c722 -VTPIOCR: - .word 0x200000f0 /* VTP IO Control register */ -DDRVTPR: - .word 0x01c42030 /* DDR VPTR MMR */ -VTP_MMR0: - .word 0x201f -VTP_MMR1: - .word 0xa01f -DFT_ENABLE: - .word 0x01c4004c -VTP_LOCK_COUNT: - .word 0x5b0 -VTP_MASK: - .word 0xffffdfff -VTP_RECAL: - .word 0x08000 -VTP_EN: - .word 0x02000 -CFGTEST: - .word 0x80010000 -MASK_VAL: - .word 0x00000fff - -/* GEM Power Up & LPSC Control Register */ -MDCTL_GEM: - .word 0x01c41a9c -MDSTAT_GEM: - .word 0x01c4189c - -/* For WDT reset chip bug */ -P1394: - .word 0x01c41a20 - -PLL_CLKSRC_MASK: - .word 0xfffffeff /* Mask the Clock Mode bit */ -PLL_ENSRC_MASK: - .word 0xffffffdf /* Select the PLLEN source */ -PLL_BYPASS_MASK: - .word 0xfffffffe /* Put the PLL in BYPASS */ -PLL_RESET_MASK: - .word 0xfffffff7 /* Put the PLL in Reset Mode */ -PLL_PWRUP_MASK: - .word 0xfffffffd /* PLL Power up Mask Bit */ -PLL_DISABLE_ENABLE_MASK: - .word 0xffffffef /* Enable the PLL from Disable */ -PLL_LOCK_COUNT: - .word 0x2000 - -/* PLL1-SYSTEM PLL MMRs */ -PLL1_CTL: - .word 0x01c40900 -PLL1_PLLM: - .word 0x01c40910 - -/* PLL2-SYSTEM PLL MMRs */ -PLL2_CTL: - .word 0x01c40d00 -PLL2_PLLM: - .word 0x01c40d10 -PLL2_DIV1: - .word 0x01c40d18 -PLL2_DIV2: - .word 0x01c40d1c -PLL2_PLLCMD: - .word 0x01c40d38 -PLL2_PLLSTAT: - .word 0x01c40d3c -PLL2_DIV_MASK: - .word 0xffff7fff - -MMARG_BRF0: - .word 0x01c42010 /* BRF margin mode 0 (R/W)*/ -MMARG_BRF0_VAL: - .word 0x00444400 - -DDR2_START_ADDR: - .word 0x80000000 -DUMMY_VAL: - .word 0xa55aa55a -#else /* CONFIG_SOC_DM644X */ - mov pc, lr -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/lxt972.c b/arch/arm/cpu/arm926ejs/davinci/lxt972.c deleted file mode 100644 index c482fd9378..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/lxt972.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Intel LXT971/LXT972 PHY Driver for TI DaVinci - * (TMS320DM644x) based boards. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * -------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include "../../../../../drivers/net/davinci_emac.h" - -#ifdef CONFIG_DRIVER_TI_EMAC - -#ifdef CONFIG_CMD_NET - -int lxt972_is_phy_connected(int phy_addr) -{ - u_int16_t id1, id2; - - if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1)) - return(0); - if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2)) - return(0); - - if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) - return(1); - - return(0); -} - -int lxt972_get_link_speed(int phy_addr) -{ - u_int16_t stat1, tmp; - volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; - - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) - return(0); - - if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ - return(0); - - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) - return(0); - - tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; - - davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); - /* Read back */ - if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) - return(0); - - /* Speed doesn't matter, there is no setting for it in EMAC... */ - if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { - /* set DM644x EMAC for Full Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE; - } else { - /*set DM644x EMAC for Half Duplex */ - emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; - } - - return(1); -} - - -int lxt972_init_phy(int phy_addr) -{ - int ret = 1; - - if (!lxt972_get_link_speed(phy_addr)) { - /* Try another time */ - ret = lxt972_get_link_speed(phy_addr); - } - - /* Disable PHY Interrupts */ - davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); - - return(ret); -} - - -int lxt972_auto_negotiate(int phy_addr) -{ - u_int16_t tmp; - - if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) - return(0); - - /* Restart Auto_negotiation */ - tmp |= BMCR_ANRESTART; - davinci_eth_phy_write(phy_addr, MII_BMCR, tmp); - - /*check AutoNegotiate complete */ - udelay (10000); - if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) - return(0); - - if (!(tmp & BMSR_ANEGCOMPLETE)) - return(0); - - return (lxt972_get_link_speed(phy_addr)); -} - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/cpu/arm926ejs/davinci/misc.c b/arch/arm/cpu/arm926ejs/davinci/misc.c deleted file mode 100644 index e18bdfc729..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/misc.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Miscelaneous DaVinci functions. - * - * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_SPL_BUILD -int dram_init(void) -{ - /* dram_init must store complete ramsize in gd->ram_size */ - gd->ram_size = get_ram_size( - (void *)CONFIG_SYS_SDRAM_BASE, - CONFIG_MAX_RAM_BANK_SIZE); - return 0; -} - -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - gd->bd->bi_dram[0].size = gd->ram_size; -} -#endif - -#ifdef CONFIG_DRIVER_TI_EMAC -/* - * Read ethernet MAC address from EEPROM for DVEVM compatible boards. - * Returns 1 if found, 0 otherwise. - */ -int dvevm_read_mac_address(uint8_t *buf) -{ -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR - /* Read MAC address. */ - if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7F00, - CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &buf[0], 6)) - goto i2cerr; - - /* Check that MAC address is valid. */ - if (!is_valid_ether_addr(buf)) - goto err; - - return 1; /* Found */ - -i2cerr: - printf("Read from EEPROM @ 0x%02x failed\n", - CONFIG_SYS_I2C_EEPROM_ADDR); -err: -#endif /* CONFIG_SYS_I2C_EEPROM_ADDR */ - - return 0; -} - -/* - * Set the mii mode as MII or RMII - */ -#if defined(CONFIG_SOC_DA8XX) -void davinci_emac_mii_mode_sel(int mode_sel) -{ - int val; - - val = readl(&davinci_syscfg_regs->cfgchip3); - if (mode_sel == 0) - val &= ~(1 << 8); - else - val |= (1 << 8); - writel(val, &davinci_syscfg_regs->cfgchip3); -} -#endif -/* - * If there is no MAC address in the environment, then it will be initialized - * (silently) from the value in the EEPROM. - */ -void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr) -{ - uint8_t env_enetaddr[6]; - int ret; - - ret = eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr); - if (!ret) { - /* - * There is no MAC address in the environment, so we - * initialize it from the value in the EEPROM. - */ - debug("### Setting environment from EEPROM MAC address = " - "\"%pM\"\n", - env_enetaddr); - ret = !eth_setenv_enetaddr("ethaddr", rom_enetaddr); - } - if (!ret) - printf("Failed to set mac address from EEPROM: %d\n", ret); -} -#endif /* CONFIG_DRIVER_TI_EMAC */ - -#if defined(CONFIG_SOC_DA8XX) -#ifndef CONFIG_USE_IRQ -void irq_init(void) -{ - /* - * Mask all IRQs by clearing the global enable and setting - * the enable clear for all the 90 interrupts. - */ - writel(0, &davinci_aintc_regs->ger); - - writel(0, &davinci_aintc_regs->hier); - - writel(0xffffffff, &davinci_aintc_regs->ecr1); - writel(0xffffffff, &davinci_aintc_regs->ecr2); - writel(0xffffffff, &davinci_aintc_regs->ecr3); -} -#endif - -/* - * Enable PSC for various peripherals. - */ -int da8xx_configure_lpsc_items(const struct lpsc_resource *item, - const int n_items) -{ - int i; - - for (i = 0; i < n_items; i++) - lpsc_on(item[i].lpsc_no); - - return 0; -} -#endif diff --git a/arch/arm/cpu/arm926ejs/davinci/pinmux.c b/arch/arm/cpu/arm926ejs/davinci/pinmux.c deleted file mode 100644 index e9d8c87cc8..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/pinmux.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * DaVinci pinmux functions. - * - * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* - * Change the setting of a pin multiplexer field. - * - * Takes an array of pinmux settings similar to: - * - * struct pinmux_config uart_pins[] = { - * { &davinci_syscfg_regs->pinmux[8], 2, 7 }, - * { &davinci_syscfg_regs->pinmux[9], 2, 0 } - * }; - * - * Stepping through the array, each pinmux[n] register has the given value - * set in the pin mux field specified. - * - * The number of pins in the array must be passed (ARRAY_SIZE can provide - * this value conveniently). - * - * Returns 0 if all field numbers and values are in the correct range, - * else returns -1. - */ -int davinci_configure_pin_mux(const struct pinmux_config *pins, - const int n_pins) -{ - int i; - - /* check for invalid pinmux values */ - for (i = 0; i < n_pins; i++) { - if (pins[i].field >= PIN_MUX_NUM_FIELDS || - (pins[i].value & ~PIN_MUX_FIELD_MASK) != 0) - return -1; - } - - /* configure the pinmuxes */ - for (i = 0; i < n_pins; i++) { - const int offset = pins[i].field * PIN_MUX_FIELD_SIZE; - const unsigned int value = pins[i].value << offset; - const unsigned int mask = PIN_MUX_FIELD_MASK << offset; - const dv_reg *mux = pins[i].mux; - - writel(value | (readl(mux) & (~mask)), mux); - } - - return 0; -} - -/* - * Configure multiple pinmux resources. - * - * Takes an pinmux_resource array of pinmux_config and pin counts: - * - * const struct pinmux_resource pinmuxes[] = { - * PINMUX_ITEM(uart_pins), - * PINMUX_ITEM(i2c_pins), - * }; - * - * The number of items in the array must be passed (ARRAY_SIZE can provide - * this value conveniently). - * - * Each item entry is configured in the defined order. If configuration - * of any item fails, -1 is returned and none of the following items are - * configured. On success, 0 is returned. - */ -int davinci_configure_pin_mux_items(const struct pinmux_resource *item, - const int n_items) -{ - int i; - - for (i = 0; i < n_items; i++) { - if (davinci_configure_pin_mux(item[i].pins, - item[i].n_pins) != 0) - return -1; - } - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/psc.c b/arch/arm/cpu/arm926ejs/davinci/psc.c deleted file mode 100644 index 8d99e2e997..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/psc.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Power and Sleep Controller (PSC) functions. - * - * Copyright (C) 2007 Sergey Kubushyn - * Copyright (C) 2008 Lyrtech - * Copyright (C) 2004 Texas Instruments. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -/* - * The PSC manages three inputs to a "module" which may be a peripheral or - * CPU. Those inputs are the module's: clock; reset signal; and sometimes - * its power domain. For our purposes, we only care whether clock and power - * are active, and the module is out of reset. - * - * DaVinci chips may include two separate power domains: "Always On" and "DSP". - * Chips without a DSP generally have only one domain. - * - * The "Always On" power domain is always on when the chip is on, and is - * powered by the VDD pins (on DM644X). The majority of DaVinci modules - * lie within the "Always On" power domain. - * - * A separate domain called the "DSP" domain houses the C64x+ and other video - * hardware such as VICP. In some chips, the "DSP" domain is not always on. - * The "DSP" power domain is powered by the CVDDDSP pins (on DM644X). - */ - -/* Works on Always On power domain only (no PD argument) */ -static void lpsc_transition(unsigned int id, unsigned int state) -{ - dv_reg_p mdstat, mdctl, ptstat, ptcmd; -#ifdef CONFIG_SOC_DA8XX - struct davinci_psc_regs *psc_regs; -#endif - -#ifndef CONFIG_SOC_DA8XX - if (id >= DAVINCI_LPSC_GEM) - return; /* Don't work on DSP Power Domain */ - - mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); - mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); - ptstat = REG_P(PSC_PTSTAT); - ptcmd = REG_P(PSC_PTCMD); -#else - if (id < DAVINCI_LPSC_PSC1_BASE) { - if (id >= PSC_PSC0_MODULE_ID_CNT) - return; - psc_regs = davinci_psc0_regs; - mdstat = &psc_regs->psc0.mdstat[id]; - mdctl = &psc_regs->psc0.mdctl[id]; - } else { - id -= DAVINCI_LPSC_PSC1_BASE; - if (id >= PSC_PSC1_MODULE_ID_CNT) - return; - psc_regs = davinci_psc1_regs; - mdstat = &psc_regs->psc1.mdstat[id]; - mdctl = &psc_regs->psc1.mdctl[id]; - } - ptstat = &psc_regs->ptstat; - ptcmd = &psc_regs->ptcmd; -#endif - - while (readl(ptstat) & 0x01) - continue; - - if ((readl(mdstat) & PSC_MDSTAT_STATE) == state) - return; /* Already in that state */ - - writel((readl(mdctl) & ~PSC_MDCTL_NEXT) | state, mdctl); - - switch (id) { -#ifdef CONFIG_SOC_DM644X - /* Special treatment for some modules as for sprue14 p.7.4.2 */ - case DAVINCI_LPSC_VPSSSLV: - case DAVINCI_LPSC_EMAC: - case DAVINCI_LPSC_EMAC_WRAPPER: - case DAVINCI_LPSC_MDIO: - case DAVINCI_LPSC_USB: - case DAVINCI_LPSC_ATA: - case DAVINCI_LPSC_VLYNQ: - case DAVINCI_LPSC_UHPI: - case DAVINCI_LPSC_DDR_EMIF: - case DAVINCI_LPSC_AEMIF: - case DAVINCI_LPSC_MMC_SD: - case DAVINCI_LPSC_MEMSTICK: - case DAVINCI_LPSC_McBSP: - case DAVINCI_LPSC_GPIO: - writel(readl(mdctl) | 0x200, mdctl); - break; -#endif - } - - writel(0x01, ptcmd); - - while (readl(ptstat) & 0x01) - continue; - while ((readl(mdstat) & PSC_MDSTAT_STATE) != state) - continue; -} - -void lpsc_on(unsigned int id) -{ - lpsc_transition(id, 0x03); -} - -void lpsc_syncreset(unsigned int id) -{ - lpsc_transition(id, 0x01); -} - -void lpsc_disable(unsigned int id) -{ - lpsc_transition(id, 0x0); -} - -/* Not all DaVinci chips have a DSP power domain. */ -#ifdef CONFIG_SOC_DM644X - -/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ -#if !defined(CONFIG_SYS_USE_DSPLINK) -void dsp_on(void) -{ - int i; - - if (REG(PSC_PDSTAT1) & 0x1f) - return; /* Already on */ - - REG(PSC_GBLCTL) |= 0x01; - REG(PSC_PDCTL1) |= 0x01; - REG(PSC_PDCTL1) &= ~0x100; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; - REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; - REG(PSC_PTCMD) = 0x02; - - for (i = 0; i < 100; i++) { - if (REG(PSC_EPCPR) & 0x02) - break; - } - - REG(PSC_CHP_SHRTSW) = 0x01; - REG(PSC_PDCTL1) |= 0x100; - REG(PSC_EPCCR) = 0x02; - - for (i = 0; i < 100; i++) { - if (!(REG(PSC_PTSTAT) & 0x02)) - break; - } - - REG(PSC_GBLCTL) &= ~0x1f; -} -#endif /* CONFIG_SYS_USE_DSPLINK */ - -#endif /* have a DSP */ diff --git a/arch/arm/cpu/arm926ejs/davinci/reset.c b/arch/arm/cpu/arm926ejs/davinci/reset.c deleted file mode 100644 index 6b0f15428a..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/reset.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Processor reset using WDT. - * - * Copyright (C) 2012 Dmitry Bondar - * Copyright (C) 2007 Sergey Kubushyn - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -void reset_cpu(unsigned long a) -{ - struct davinci_timer *const wdttimer = - (struct davinci_timer *)DAVINCI_WDOG_BASE; - writel(0x08, &wdttimer->tgcr); - writel(readl(&wdttimer->tgcr) | 0x03, &wdttimer->tgcr); - writel(0, &wdttimer->tim12); - writel(0, &wdttimer->tim34); - writel(0, &wdttimer->prd12); - writel(0, &wdttimer->prd34); - writel(readl(&wdttimer->tcr) | 0x40, &wdttimer->tcr); - writel(readl(&wdttimer->wdtcr) | 0x4000, &wdttimer->wdtcr); - writel(0xa5c64000, &wdttimer->wdtcr); - writel(0xda7e4000, &wdttimer->wdtcr); - writel(0x4000, &wdttimer->wdtcr); - while (1) - /*nothing*/; -} diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c deleted file mode 100644 index 49349da179..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_SPL_LIBCOMMON_SUPPORT -void puts(const char *str) -{ - while (*str) - putc(*str++); -} - -void putc(char c) -{ - if (c == '\n') - NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), '\r'); - - NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); -} -#endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ - -void spl_board_init(void) -{ -#ifdef CONFIG_SOC_DM365 - dm36x_lowlevel_init(0); -#endif -#ifdef CONFIG_SOC_DA8XX - arch_cpu_init(); -#endif - preloader_console_init(); -} - -u32 spl_boot_mode(void) -{ - return MMCSD_MODE_RAW; -} - -u32 spl_boot_device(void) -{ -#ifdef CONFIG_SPL_NAND_SIMPLE - return BOOT_DEVICE_NAND; -#elif defined(CONFIG_SPL_SPI_LOAD) - return BOOT_DEVICE_SPI; -#elif defined(CONFIG_SPL_MMC_LOAD) - return BOOT_DEVICE_MMC1; -#else - puts("Unknown boot device\n"); - hang(); -#endif -} diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c deleted file mode 100644 index c7d0652e83..0000000000 --- a/arch/arm/cpu/arm926ejs/davinci/timer.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * Copyright (C) 2007 Sergey Kubushyn - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static struct davinci_timer * const timer = - (struct davinci_timer *)CONFIG_SYS_TIMERBASE; - -#define TIMER_LOAD_VAL 0xffffffff - -#define TIM_CLK_DIV 16 - -int timer_init(void) -{ - /* We are using timer34 in unchained 32-bit mode, full speed */ - writel(0x0, &timer->tcr); - writel(0x0, &timer->tgcr); - writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); - writel(0x0, &timer->tim34); - writel(TIMER_LOAD_VAL, &timer->prd34); - writel(2 << 22, &timer->tcr); - gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; - gd->arch.timer_reset_value = 0; - - return(0); -} - -/* - * Get the current 64 bit timer tick count - */ -unsigned long long get_ticks(void) -{ - unsigned long now = readl(&timer->tim34); - - /* increment tbu if tbl has rolled over */ - if (now < gd->arch.tbl) - gd->arch.tbu++; - gd->arch.tbl = now; - - return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; -} - -ulong get_timer(ulong base) -{ - unsigned long long timer_diff; - - timer_diff = get_ticks() - gd->arch.timer_reset_value; - - return lldiv(timer_diff, - (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base; -} - -void __udelay(unsigned long usec) -{ - unsigned long long endtime; - - endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, - 1000000UL); - endtime += get_ticks(); - - while (get_ticks() < endtime) - ; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return gd->arch.timer_rate_hz; -} - -#ifdef CONFIG_HW_WATCHDOG -static struct davinci_timer * const wdttimer = - (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; - -/* - * See prufw2.pdf for using Timer as a WDT - */ -void davinci_hw_watchdog_enable(void) -{ - writel(0x0, &wdttimer->tcr); - writel(0x0, &wdttimer->tgcr); - /* TIMMODE = 2h */ - writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr); - writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12); - writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34); - writel(2 << 22, &wdttimer->tcr); - writel(0x0, &wdttimer->tim12); - writel(0x0, &wdttimer->tim34); - /* set WDEN bit, WDKEY 0xa5c6 */ - writel(0xa5c64000, &wdttimer->wdtcr); - /* clear counter register */ - writel(0xda7e4000, &wdttimer->wdtcr); -} - -void davinci_hw_watchdog_reset(void) -{ - writel(0xa5c64000, &wdttimer->wdtcr); - writel(0xda7e4000, &wdttimer->wdtcr); -} -#endif diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig new file mode 100644 index 0000000000..613f04d8b0 --- /dev/null +++ b/arch/arm/mach-davinci/Kconfig @@ -0,0 +1,78 @@ +if ARCH_DAVINCI + +choice + prompt "DaVinci board select" + +config TARGET_ENBW_CMC + bool "EnBW CMC board" + +config TARGET_IPAM390 + bool "IPAM390 board" + select SUPPORT_SPL + +config TARGET_DA830EVM + bool "DA830 EVM board" + +config TARGET_DA850EVM + bool "DA850 EVM board" + select SUPPORT_SPL + +config TARGET_CAM_ENC_4XX + bool "CAM ENC 4xx board" + select SUPPORT_SPL + +config TARGET_HAWKBOARD + bool "Hawkboard" + select SUPPORT_SPL + +config TARGET_DAVINCI_DM355EVM + bool "DM355 EVM board" + +config TARGET_DAVINCI_DM355LEOPARD + bool "DM355 Leopard board" + +config TARGET_DAVINCI_DM365EVM + bool "DM365 EVM board" + +config TARGET_DAVINCI_DM6467EVM + bool "DM6467 EVM board" + +config TARGET_DAVINCI_DVEVM + bool "DVEVM board" + +config TARGET_EA20 + bool "EA20 board" + +config TARGET_DAVINCI_SCHMOOGIE + bool "Schmoogie board" + +config TARGET_DAVINCI_SFFSDR + bool "SFFSDR board" + +config TARGET_DAVINCI_SONATA + bool "Sonata board" + +config TARGET_CALIMAIN + bool "Calimain board" + +endchoice + +config SYS_SOC + default "davinci" + +source "board/enbw/enbw_cmc/Kconfig" +source "board/ait/cam_enc_4xx/Kconfig" +source "board/Barix/ipam390/Kconfig" +source "board/davinci/da8xxevm/Kconfig" +source "board/davinci/dm355evm/Kconfig" +source "board/davinci/dm355leopard/Kconfig" +source "board/davinci/dm365evm/Kconfig" +source "board/davinci/dm6467evm/Kconfig" +source "board/davinci/dvevm/Kconfig" +source "board/davinci/ea20/Kconfig" +source "board/davinci/schmoogie/Kconfig" +source "board/davinci/sffsdr/Kconfig" +source "board/davinci/sonata/Kconfig" +source "board/omicron/calimain/Kconfig" + +endif diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile new file mode 100644 index 0000000000..7d67191de8 --- /dev/null +++ b/arch/arm/mach-davinci/Makefile @@ -0,0 +1,28 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2007 Sergey Kubushyn +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o misc.o timer.o psc.o pinmux.o reset.o +obj-$(CONFIG_DA850_LOWLEVEL) += da850_lowlevel.o +obj-$(CONFIG_SOC_DM355) += dm355.o +obj-$(CONFIG_SOC_DM365) += dm365.o +obj-$(CONFIG_SOC_DM644X) += dm644x.o +obj-$(CONFIG_SOC_DM646X) += dm646x.o +obj-$(CONFIG_SOC_DA830) += da830_pinmux.o +obj-$(CONFIG_SOC_DA850) += da850_pinmux.o +obj-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o + +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_FRAMEWORK) += spl.o +obj-$(CONFIG_SOC_DM365) += dm365_lowlevel.o +obj-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o +endif + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y += lowlevel_init.o +endif diff --git a/arch/arm/mach-davinci/config.mk b/arch/arm/mach-davinci/config.mk new file mode 100644 index 0000000000..69e9d5ab21 --- /dev/null +++ b/arch/arm/mach-davinci/config.mk @@ -0,0 +1,8 @@ +# +# Copyright (C) 2012, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifndef CONFIG_SPL_BUILD +ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.ais +endif diff --git a/arch/arm/mach-davinci/cpu.c b/arch/arm/mach-davinci/cpu.c new file mode 100644 index 0000000000..ff61147757 --- /dev/null +++ b/arch/arm/mach-davinci/cpu.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2004 Texas Instruments. + * Copyright (C) 2009 David Brownell + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* offsets from PLL controller base */ +#define PLLC_PLLCTL 0x100 +#define PLLC_PLLM 0x110 +#define PLLC_PREDIV 0x114 +#define PLLC_PLLDIV1 0x118 +#define PLLC_PLLDIV2 0x11c +#define PLLC_PLLDIV3 0x120 +#define PLLC_POSTDIV 0x128 +#define PLLC_BPDIV 0x12c +#define PLLC_PLLDIV4 0x160 +#define PLLC_PLLDIV5 0x164 +#define PLLC_PLLDIV6 0x168 +#define PLLC_PLLDIV7 0x16c +#define PLLC_PLLDIV8 0x170 +#define PLLC_PLLDIV9 0x174 + +#define BIT(x) (1 << (x)) + +/* SOC-specific pll info */ +#ifdef CONFIG_SOC_DM355 +#define ARM_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DM644X +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DSP_PLLDIV PLLC_PLLDIV1 +#define DDR_PLLDIV PLLC_PLLDIV2 +#endif + +#ifdef CONFIG_SOC_DM646X +#define DSP_PLLDIV PLLC_PLLDIV1 +#define ARM_PLLDIV PLLC_PLLDIV2 +#define DDR_PLLDIV PLLC_PLLDIV1 +#endif + +#ifdef CONFIG_SOC_DA8XX +unsigned int sysdiv[9] = { + PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5, + PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9 +}; + +int clk_get(enum davinci_clk_ids id) +{ + int pre_div; + int pllm; + int post_div; + int pll_out; + unsigned int pll_base; + + pll_out = CONFIG_SYS_OSCIN_FREQ; + + if (id == DAVINCI_AUXCLK_CLKID) + goto out; + + if ((id >> 16) == 1) + pll_base = (unsigned int)davinci_pllc1_regs; + else + pll_base = (unsigned int)davinci_pllc0_regs; + + id &= 0xFFFF; + + /* + * Lets keep this simple. Combining operations can result in + * unexpected approximations + */ + pre_div = (readl(pll_base + PLLC_PREDIV) & + DAVINCI_PLLC_DIV_MASK) + 1; + pllm = readl(pll_base + PLLC_PLLM) + 1; + + pll_out /= pre_div; + pll_out *= pllm; + + if (id == DAVINCI_PLLM_CLKID) + goto out; + + post_div = (readl(pll_base + PLLC_POSTDIV) & + DAVINCI_PLLC_DIV_MASK) + 1; + + pll_out /= post_div; + + if (id == DAVINCI_PLLC_CLKID) + goto out; + + pll_out /= (readl(pll_base + sysdiv[id - 1]) & + DAVINCI_PLLC_DIV_MASK) + 1; + +out: + return pll_out; +} + +int set_cpu_clk_info(void) +{ + gd->bd->bi_arm_freq = clk_get(DAVINCI_ARM_CLKID) / 1000000; + /* DDR PHY uses an x2 input clock */ + gd->bd->bi_ddr_freq = cpu_is_da830() ? 0 : + (clk_get(DAVINCI_DDR_CLKID) / 1000000); + gd->bd->bi_dsp_freq = 0; + return 0; +} + +#else /* CONFIG_SOC_DA8XX */ + +static unsigned pll_div(volatile void *pllbase, unsigned offset) +{ + u32 div; + + div = REG(pllbase + offset); + return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; +} + +static inline unsigned pll_prediv(volatile void *pllbase) +{ +#ifdef CONFIG_SOC_DM355 + /* this register read seems to fail on pll0 */ + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return 8; + else + return pll_div(pllbase, PLLC_PREDIV); +#elif defined(CONFIG_SOC_DM365) + return pll_div(pllbase, PLLC_PREDIV); +#endif + return 1; +} + +static inline unsigned pll_postdiv(volatile void *pllbase) +{ +#if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365) + return pll_div(pllbase, PLLC_POSTDIV); +#elif defined(CONFIG_SOC_DM6446) + if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) + return pll_div(pllbase, PLLC_POSTDIV); +#endif + return 1; +} + +static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) +{ + volatile void *pllbase = (volatile void *) pll_addr; +#ifdef CONFIG_SOC_DM646X + unsigned base = CONFIG_REFCLK_FREQ / 1000; +#else + unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; +#endif + + /* the PLL might be bypassed */ + if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) { + base /= pll_prediv(pllbase); +#if defined(CONFIG_SOC_DM365) + base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff); +#else + base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); +#endif + base /= pll_postdiv(pllbase); + } + return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); +} + +#ifdef DAVINCI_DM6467EVM +unsigned int davinci_arm_clk_get() +{ + return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000; +} +#endif + +#if defined(CONFIG_SOC_DM365) +unsigned int davinci_clk_get(unsigned int div) +{ + return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000; +} +#endif + +int set_cpu_clk_info(void) +{ + unsigned int pllbase = DAVINCI_PLL_CNTRL0_BASE; +#if defined(CONFIG_SOC_DM365) + pllbase = DAVINCI_PLL_CNTRL1_BASE; +#endif + gd->bd->bi_arm_freq = pll_sysclk_mhz(pllbase, ARM_PLLDIV); + +#ifdef DSP_PLLDIV + gd->bd->bi_dsp_freq = + pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV); +#else + gd->bd->bi_dsp_freq = 0; +#endif + + pllbase = DAVINCI_PLL_CNTRL1_BASE; +#if defined(CONFIG_SOC_DM365) + pllbase = DAVINCI_PLL_CNTRL0_BASE; +#endif + gd->bd->bi_ddr_freq = pll_sysclk_mhz(pllbase, DDR_PLLDIV) / 2; + + return 0; +} + +#endif /* !CONFIG_SOC_DA8XX */ + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_DRIVER_TI_EMAC) + davinci_emac_initialize(); +#endif + return 0; +} diff --git a/arch/arm/mach-davinci/da830_pinmux.c b/arch/arm/mach-davinci/da830_pinmux.c new file mode 100644 index 0000000000..edaab45327 --- /dev/null +++ b/arch/arm/mach-davinci/da830_pinmux.c @@ -0,0 +1,139 @@ +/* + * Pinmux configurations for the DA830 SoCs + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* SPI0 pin muxer settings */ +const struct pinmux_config spi0_pins_base[] = { + { pinmux(7), 1, 3 }, /* SPI0_SOMI */ + { pinmux(7), 1, 4 }, /* SPI0_SIMO */ + { pinmux(7), 1, 6 } /* SPI0_CLK */ +}; + +const struct pinmux_config spi0_pins_scs0[] = { + { pinmux(7), 1, 7 } /* SPI0_SCS[0] */ +}; + +const struct pinmux_config spi0_pins_ena[] = { + { pinmux(7), 1, 5 } /* SPI0_ENA */ +}; + +/* NAND pin muxer settings */ +const struct pinmux_config emifa_pins_cs0[] = { + { pinmux(18), 1, 2 } /* EMA_CS[0] */ +}; + +const struct pinmux_config emifa_pins_cs2[] = { + { pinmux(18), 1, 3 } /* EMA_CS[2] */ +}; + +const struct pinmux_config emifa_pins_cs3[] = { + { pinmux(18), 1, 4 } /* EMA_CS[3] */ +}; + +#ifdef CONFIG_USE_NAND +const struct pinmux_config emifa_pins[] = { + { pinmux(13), 1, 6 }, /* EMA_D[0] */ + { pinmux(13), 1, 7 }, /* EMA_D[1] */ + { pinmux(14), 1, 0 }, /* EMA_D[2] */ + { pinmux(14), 1, 1 }, /* EMA_D[3] */ + { pinmux(14), 1, 2 }, /* EMA_D[4] */ + { pinmux(14), 1, 3 }, /* EMA_D[5] */ + { pinmux(14), 1, 4 }, /* EMA_D[6] */ + { pinmux(14), 1, 5 }, /* EMA_D[7] */ + { pinmux(14), 1, 6 }, /* EMA_D[8] */ + { pinmux(14), 1, 7 }, /* EMA_D[9] */ + { pinmux(15), 1, 0 }, /* EMA_D[10] */ + { pinmux(15), 1, 1 }, /* EMA_D[11] */ + { pinmux(15), 1, 2 }, /* EMA_D[12] */ + { pinmux(15), 1, 3 }, /* EMA_D[13] */ + { pinmux(15), 1, 4 }, /* EMA_D[14] */ + { pinmux(15), 1, 5 }, /* EMA_D[15] */ + { pinmux(15), 1, 6 }, /* EMA_A[0] */ + { pinmux(15), 1, 7 }, /* EMA_A[1] */ + { pinmux(16), 1, 0 }, /* EMA_A[2] */ + { pinmux(16), 1, 1 }, /* EMA_A[3] */ + { pinmux(16), 1, 2 }, /* EMA_A[4] */ + { pinmux(16), 1, 3 }, /* EMA_A[5] */ + { pinmux(16), 1, 4 }, /* EMA_A[6] */ + { pinmux(16), 1, 5 }, /* EMA_A[7] */ + { pinmux(16), 1, 6 }, /* EMA_A[8] */ + { pinmux(16), 1, 7 }, /* EMA_A[9] */ + { pinmux(17), 1, 0 }, /* EMA_A[10] */ + { pinmux(17), 1, 1 }, /* EMA_A[11] */ + { pinmux(17), 1, 2 }, /* EMA_A[12] */ + { pinmux(17), 1, 3 }, /* EMA_BA[1] */ + { pinmux(17), 1, 4 }, /* EMA_BA[0] */ + { pinmux(17), 1, 5 }, /* EMA_CLK */ + { pinmux(17), 1, 6 }, /* EMA_SDCKE */ + { pinmux(17), 1, 7 }, /* EMA_CAS */ + { pinmux(18), 1, 0 }, /* EMA_CAS */ + { pinmux(18), 1, 1 }, /* EMA_WE */ + { pinmux(18), 1, 5 }, /* EMA_OE */ + { pinmux(18), 1, 6 }, /* EMA_WE_DQM[1] */ + { pinmux(18), 1, 7 }, /* EMA_WE_DQM[0] */ + { pinmux(10), 1, 0 } /* Tristate */ +}; +#endif + +/* EMAC PHY interface pins */ +const struct pinmux_config emac_pins_rmii[] = { + { pinmux(10), 2, 1 }, /* RMII_TXD[0] */ + { pinmux(10), 2, 2 }, /* RMII_TXD[1] */ + { pinmux(10), 2, 3 }, /* RMII_TXEN */ + { pinmux(10), 2, 4 }, /* RMII_CRS_DV */ + { pinmux(10), 2, 5 }, /* RMII_RXD[0] */ + { pinmux(10), 2, 6 }, /* RMII_RXD[1] */ + { pinmux(10), 2, 7 } /* RMII_RXER */ +}; + +const struct pinmux_config emac_pins_mdio[] = { + { pinmux(11), 2, 0 }, /* MDIO_CLK */ + { pinmux(11), 2, 1 } /* MDIO_D */ +}; + +const struct pinmux_config emac_pins_rmii_clk_source[] = { + { pinmux(9), 0, 5 } /* ref.clk from external source */ +}; + +/* UART2 pin muxer settings */ +const struct pinmux_config uart2_pins_txrx[] = { + { pinmux(8), 2, 7 }, /* UART2_RXD */ + { pinmux(9), 2, 0 } /* UART2_TXD */ +}; + +/* I2C0 pin muxer settings */ +const struct pinmux_config i2c0_pins[] = { + { pinmux(8), 2, 3 }, /* I2C0_SDA */ + { pinmux(8), 2, 4 } /* I2C0_SCL */ +}; + +/* USB0_DRVVBUS pin muxer settings */ +const struct pinmux_config usb_pins[] = { + { pinmux(9), 1, 1 } /* USB0_DRVVBUS */ +}; + +#ifdef CONFIG_DAVINCI_MMC +/* MMC0 pin muxer settings */ +const struct pinmux_config mmc0_pins_8bit[] = { + { pinmux(15), 2, 7 }, /* MMCSD0_CLK */ + { pinmux(16), 2, 0 }, /* MMCSD0_CMD */ + { pinmux(13), 2, 6 }, /* MMCSD0_DAT_0 */ + { pinmux(13), 2, 7 }, /* MMCSD0_DAT_1 */ + { pinmux(14), 2, 0 }, /* MMCSD0_DAT_2 */ + { pinmux(14), 2, 1 }, /* MMCSD0_DAT_3 */ + { pinmux(14), 2, 2 }, /* MMCSD0_DAT_4 */ + { pinmux(14), 2, 3 }, /* MMCSD0_DAT_5 */ + { pinmux(14), 2, 4 }, /* MMCSD0_DAT_6 */ + { pinmux(14), 2, 5 } /* MMCSD0_DAT_7 */ + /* DA830 supports 8-bit mode */ +}; +#endif diff --git a/arch/arm/mach-davinci/da850_lowlevel.c b/arch/arm/mach-davinci/da850_lowlevel.c new file mode 100644 index 0000000000..19730cef8c --- /dev/null +++ b/arch/arm/mach-davinci/da850_lowlevel.c @@ -0,0 +1,313 @@ +/* + * SoC-specific lowlevel code for DA850 + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; +} + +#if defined(CONFIG_SYS_DA850_PLL_INIT) +static void da850_waitloop(unsigned long loopcnt) +{ + unsigned long i; + + for (i = 0; i < loopcnt; i++) + asm(" NOP"); +} + +static int da850_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult) +{ + if (reg == davinci_pllc0_regs) + /* Unlock PLL registers. */ + clrbits_le32(&davinci_syscfg_regs->cfgchip0, PLL_MASTER_LOCK); + + /* + * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled + * through MMR + */ + clrbits_le32(®->pllctl, PLLCTL_PLLENSRC); + /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ + clrbits_le32(®->pllctl, PLLCTL_EXTCLKSRC); + + /* Set PLLEN=0 => PLL BYPASS MODE */ + clrbits_le32(®->pllctl, PLLCTL_PLLEN); + + da850_waitloop(150); + + if (reg == davinci_pllc0_regs) { + /* + * Select the Clock Mode bit 8 as External Clock or On Chip + * Oscilator + */ + dv_maskbits(®->pllctl, ~PLLCTL_RES_9); + setbits_le32(®->pllctl, + (CONFIG_SYS_DV_CLKMODE << PLLCTL_CLOCK_MODE_SHIFT)); + } + + /* Clear PLLRST bit to reset the PLL */ + clrbits_le32(®->pllctl, PLLCTL_PLLRST); + + /* Disable the PLL output */ + setbits_le32(®->pllctl, PLLCTL_PLLDIS); + + /* PLL initialization sequence */ + /* + * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of + * power down bit + */ + clrbits_le32(®->pllctl, PLLCTL_PLLPWRDN); + + /* Enable the PLL from Disable Mode PLLDIS bit to 0 */ + clrbits_le32(®->pllctl, PLLCTL_PLLDIS); + +#if defined(CONFIG_SYS_DA850_PLL0_PREDIV) + /* program the prediv */ + if (reg == davinci_pllc0_regs && CONFIG_SYS_DA850_PLL0_PREDIV) + writel((PLL_DIVEN | CONFIG_SYS_DA850_PLL0_PREDIV), + ®->prediv); +#endif + + /* Program the required multiplier value in PLLM */ + writel(pllmult, ®->pllm); + + /* program the postdiv */ + if (reg == davinci_pllc0_regs) + writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL0_POSTDIV), + ®->postdiv); + else + writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL1_POSTDIV), + ®->postdiv); + + /* + * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that + * no GO operation is currently in progress + */ + while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT) + ; + + if (reg == davinci_pllc0_regs) { + writel(CONFIG_SYS_DA850_PLL0_PLLDIV1, ®->plldiv1); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV2, ®->plldiv2); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV3, ®->plldiv3); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV4, ®->plldiv4); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV5, ®->plldiv5); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV6, ®->plldiv6); + writel(CONFIG_SYS_DA850_PLL0_PLLDIV7, ®->plldiv7); + } else { + writel(CONFIG_SYS_DA850_PLL1_PLLDIV1, ®->plldiv1); + writel(CONFIG_SYS_DA850_PLL1_PLLDIV2, ®->plldiv2); + writel(CONFIG_SYS_DA850_PLL1_PLLDIV3, ®->plldiv3); + } + + /* + * Set the GOSET bit in PLLCMD to 1 to initiate a new divider + * transition. + */ + setbits_le32(®->pllcmd, PLLCMD_GOSTAT); + + /* + * Wait for the GOSTAT bit in PLLSTAT to clear to 0 + * (completion of phase alignment). + */ + while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT) + ; + + /* Wait for PLL to reset properly. See PLL spec for PLL reset time */ + da850_waitloop(200); + + /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */ + setbits_le32(®->pllctl, PLLCTL_PLLRST); + + /* Wait for PLL to lock. See PLL spec for PLL lock time */ + da850_waitloop(2400); + + /* + * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass + * mode + */ + setbits_le32(®->pllctl, PLLCTL_PLLEN); + + + /* + * clear EMIFA and EMIFB clock source settings, let them + * run off SYSCLK + */ + if (reg == davinci_pllc0_regs) + dv_maskbits(&davinci_syscfg_regs->cfgchip3, + ~(PLL_SCSCFG3_DIV45PENA | PLL_SCSCFG3_EMA_CLKSRC)); + + return 0; +} +#endif /* CONFIG_SYS_DA850_PLL_INIT */ + +#if defined(CONFIG_SYS_DA850_DDR_INIT) +static int da850_ddr_setup(void) +{ + unsigned long tmp; + + /* Enable the Clock to DDR2/mDDR */ + lpsc_on(DAVINCI_LPSC_DDR_EMIF); + + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) { + /* Begin VTP Calibration */ + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ); + + /* Polling READY bit to see when VTP calibration is done */ + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + while ((tmp & VTP_READY) != VTP_READY) + tmp = readl(&davinci_syscfg1_regs->vtpio_ctl); + + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK); + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN); + } + setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN); + writel(CONFIG_SYS_DA850_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr); + + if (CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT)) { + /* DDR2 */ + clrbits_le32(&davinci_syscfg1_regs->ddr_slew, + (1 << DDR_SLEW_DDR_PDENA_BIT) | + (1 << DDR_SLEW_CMOSEN_BIT)); + } else { + /* MOBILE DDR */ + setbits_le32(&davinci_syscfg1_regs->ddr_slew, + (1 << DDR_SLEW_DDR_PDENA_BIT) | + (1 << DDR_SLEW_CMOSEN_BIT)); + } + + /* + * SDRAM Configuration Register (SDCR): + * First set the BOOTUNLOCK bit to make configuration bits + * writeable. + */ + setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK); + + /* + * Write the new value of these bits and clear BOOTUNLOCK. + * At the same time, set the TIMUNLOCK bit to allow changing + * the timing registers + */ + tmp = CONFIG_SYS_DA850_DDR2_SDBCR; + tmp &= ~DV_DDR_BOOTUNLOCK; + tmp |= DV_DDR_TIMUNLOCK; + writel(tmp, &dv_ddr2_regs_ctrl->sdbcr); + + /* write memory configuration and timing */ + if (!(CONFIG_SYS_DA850_DDR2_SDBCR & (1 << DV_DDR_SDCR_DDR2EN_SHIFT))) { + /* MOBILE DDR only*/ + writel(CONFIG_SYS_DA850_DDR2_SDBCR2, + &dv_ddr2_regs_ctrl->sdbcr2); + } + writel(CONFIG_SYS_DA850_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr); + writel(CONFIG_SYS_DA850_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2); + + /* clear the TIMUNLOCK bit and write the value of the CL field */ + tmp &= ~DV_DDR_TIMUNLOCK; + writel(tmp, &dv_ddr2_regs_ctrl->sdbcr); + + /* + * LPMODEN and MCLKSTOPEN must be set! + * Without this bits set, PSC don;t switch states !! + */ + writel(CONFIG_SYS_DA850_DDR2_SDRCR | + (1 << DV_DDR_SRCR_LPMODEN_SHIFT) | + (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT), + &dv_ddr2_regs_ctrl->sdrcr); + + /* SyncReset the Clock to EMIF3A SDRAM */ + lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); + /* Enable the Clock to EMIF3A SDRAM */ + lpsc_on(DAVINCI_LPSC_DDR_EMIF); + + /* disable self refresh */ + clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, + DV_DDR_SDRCR_LPMODEN | DV_DDR_SDRCR_MCLKSTOPEN); + writel(CONFIG_SYS_DA850_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr); + + return 0; +} +#endif /* CONFIG_SYS_DA850_DDR_INIT */ + +__attribute__((weak)) +void board_gpio_init(void) +{ + return; +} + +int arch_cpu_init(void) +{ + /* Unlock kick registers */ + writel(DV_SYSCFG_KICK0_UNLOCK, &davinci_syscfg_regs->kick0); + writel(DV_SYSCFG_KICK1_UNLOCK, &davinci_syscfg_regs->kick1); + + dv_maskbits(&davinci_syscfg_regs->suspsrc, + CONFIG_SYS_DA850_SYSCFG_SUSPSRC); + + /* configure pinmux settings */ + if (davinci_configure_pin_mux_items(pinmuxes, pinmuxes_size)) + return 1; + +#if defined(CONFIG_SYS_DA850_PLL_INIT) + /* PLL setup */ + da850_pll_init(davinci_pllc0_regs, CONFIG_SYS_DA850_PLL0_PLLM); + da850_pll_init(davinci_pllc1_regs, CONFIG_SYS_DA850_PLL1_PLLM); +#endif + /* setup CSn config */ +#if defined(CONFIG_SYS_DA850_CS2CFG) + writel(CONFIG_SYS_DA850_CS2CFG, &davinci_emif_regs->ab1cr); +#endif +#if defined(CONFIG_SYS_DA850_CS3CFG) + writel(CONFIG_SYS_DA850_CS3CFG, &davinci_emif_regs->ab2cr); +#endif + + da8xx_configure_lpsc_items(lpsc, lpsc_size); + + /* GPIO setup */ + board_gpio_init(); + + + NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), + CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); + + /* + * Fix Power and Emulation Management Register + * see sprufw3a.pdf page 37 Table 24 + */ + writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | + DAVINCI_UART_PWREMU_MGMT_UTRST), +#if (CONFIG_SYS_NS16550_COM1 == DAVINCI_UART0_BASE) + &davinci_uart0_ctrl_regs->pwremu_mgmt); +#else + &davinci_uart2_ctrl_regs->pwremu_mgmt); +#endif + +#if defined(CONFIG_SYS_DA850_DDR_INIT) + da850_ddr_setup(); +#endif + + return 0; +} diff --git a/arch/arm/mach-davinci/da850_pinmux.c b/arch/arm/mach-davinci/da850_pinmux.c new file mode 100644 index 0000000000..6105f6390c --- /dev/null +++ b/arch/arm/mach-davinci/da850_pinmux.c @@ -0,0 +1,181 @@ +/* + * Pinmux configurations for the DA850 SoCs + * + * Copyright (C) 2011 OMICRON electronics GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* SPI pin muxer settings */ +const struct pinmux_config spi1_pins_base[] = { + { pinmux(5), 1, 2 }, /* SPI1_CLK */ + { pinmux(5), 1, 4 }, /* SPI1_SOMI */ + { pinmux(5), 1, 5 }, /* SPI1_SIMO */ +}; + +const struct pinmux_config spi1_pins_scs0[] = { + { pinmux(5), 1, 1 }, /* SPI1_SCS[0] */ +}; + +/* UART pin muxer settings */ +const struct pinmux_config uart0_pins_txrx[] = { + { pinmux(3), 2, 4 }, /* UART0_RXD */ + { pinmux(3), 2, 5 }, /* UART0_TXD */ +}; + +const struct pinmux_config uart0_pins_rtscts[] = { + { pinmux(3), 2, 6 }, + { pinmux(3), 2, 7 }, +}; + +const struct pinmux_config uart1_pins_txrx[] = { + { pinmux(4), 2, 6 }, /* UART1_RXD */ + { pinmux(4), 2, 7 }, /* UART1_TXD */ +}; + +const struct pinmux_config uart2_pins_txrx[] = { + { pinmux(4), 2, 4 }, /* UART2_RXD */ + { pinmux(4), 2, 5 }, /* UART2_TXD */ +}; + +const struct pinmux_config uart2_pins_rtscts[] = { + { pinmux(0), 4, 6 }, /* UART2_RTS */ + { pinmux(0), 4, 7 }, /* UART2_CTS */ +}; + +/* EMAC pin muxer settings*/ +const struct pinmux_config emac_pins_rmii[] = { + { pinmux(14), 8, 2 }, /* RMII_TXD[1] */ + { pinmux(14), 8, 3 }, /* RMII_TXD[0] */ + { pinmux(14), 8, 4 }, /* RMII_TXEN */ + { pinmux(14), 8, 5 }, /* RMII_RXD[1] */ + { pinmux(14), 8, 6 }, /* RMII_RXD[0] */ + { pinmux(14), 8, 7 }, /* RMII_RXER */ + { pinmux(15), 0, 0 }, /* RMII_MHz_50_CLK */ + { pinmux(15), 8, 1 }, /* RMII_CRS_DV */ +}; + +const struct pinmux_config emac_pins_mii[] = { + { pinmux(2), 8, 1 }, /* MII_TXEN */ + { pinmux(2), 8, 2 }, /* MII_TXCLK */ + { pinmux(2), 8, 3 }, /* MII_COL */ + { pinmux(2), 8, 4 }, /* MII_TXD[3] */ + { pinmux(2), 8, 5 }, /* MII_TXD[2] */ + { pinmux(2), 8, 6 }, /* MII_TXD[1] */ + { pinmux(2), 8, 7 }, /* MII_TXD[0] */ + { pinmux(3), 8, 0 }, /* MII_RXCLK */ + { pinmux(3), 8, 1 }, /* MII_RXDV */ + { pinmux(3), 8, 2 }, /* MII_RXER */ + { pinmux(3), 8, 3 }, /* MII_CRS */ + { pinmux(3), 8, 4 }, /* MII_RXD[3] */ + { pinmux(3), 8, 5 }, /* MII_RXD[2] */ + { pinmux(3), 8, 6 }, /* MII_RXD[1] */ + { pinmux(3), 8, 7 }, /* MII_RXD[0] */ +}; + +const struct pinmux_config emac_pins_mdio[] = { + { pinmux(4), 8, 0 }, /* MDIO_CLK */ + { pinmux(4), 8, 1 }, /* MDIO_D */ +}; + +/* I2C pin muxer settings */ +const struct pinmux_config i2c0_pins[] = { + { pinmux(4), 2, 2 }, /* I2C0_SCL */ + { pinmux(4), 2, 3 }, /* I2C0_SDA */ +}; + +const struct pinmux_config i2c1_pins[] = { + { pinmux(4), 4, 4 }, /* I2C1_SCL */ + { pinmux(4), 4, 5 }, /* I2C1_SDA */ +}; + +/* EMIFA pin muxer settings */ +const struct pinmux_config emifa_pins_cs2[] = { + { pinmux(7), 1, 0 }, /* EMA_CS2 */ +}; + +const struct pinmux_config emifa_pins_cs3[] = { + { pinmux(7), 1, 1 }, /* EMA_CS[3] */ +}; + +const struct pinmux_config emifa_pins_cs4[] = { + { pinmux(7), 1, 2 }, /* EMA_CS[4] */ +}; + +const struct pinmux_config emifa_pins_nand[] = { + { pinmux(7), 1, 4 }, /* EMA_WE */ + { pinmux(7), 1, 5 }, /* EMA_OE */ + { pinmux(9), 1, 0 }, /* EMA_D[7] */ + { pinmux(9), 1, 1 }, /* EMA_D[6] */ + { pinmux(9), 1, 2 }, /* EMA_D[5] */ + { pinmux(9), 1, 3 }, /* EMA_D[4] */ + { pinmux(9), 1, 4 }, /* EMA_D[3] */ + { pinmux(9), 1, 5 }, /* EMA_D[2] */ + { pinmux(9), 1, 6 }, /* EMA_D[1] */ + { pinmux(9), 1, 7 }, /* EMA_D[0] */ + { pinmux(12), 1, 5 }, /* EMA_A[2] */ + { pinmux(12), 1, 6 }, /* EMA_A[1] */ +}; + +/* NOR pin muxer settings */ +const struct pinmux_config emifa_pins_nor[] = { + { pinmux(5), 1, 6 }, /* EMA_BA[1] */ + { pinmux(6), 1, 6 }, /* EMA_WAIT[1] */ + { pinmux(7), 1, 4 }, /* EMA_WE */ + { pinmux(7), 1, 5 }, /* EMA_OE */ + { pinmux(8), 1, 0 }, /* EMA_D[15] */ + { pinmux(8), 1, 1 }, /* EMA_D[14] */ + { pinmux(8), 1, 2 }, /* EMA_D[13] */ + { pinmux(8), 1, 3 }, /* EMA_D[12] */ + { pinmux(8), 1, 4 }, /* EMA_D[11] */ + { pinmux(8), 1, 5 }, /* EMA_D[10] */ + { pinmux(8), 1, 6 }, /* EMA_D[9] */ + { pinmux(8), 1, 7 }, /* EMA_D[8] */ + { pinmux(9), 1, 0 }, /* EMA_D[7] */ + { pinmux(9), 1, 1 }, /* EMA_D[6] */ + { pinmux(9), 1, 2 }, /* EMA_D[5] */ + { pinmux(9), 1, 3 }, /* EMA_D[4] */ + { pinmux(9), 1, 4 }, /* EMA_D[3] */ + { pinmux(9), 1, 5 }, /* EMA_D[2] */ + { pinmux(9), 1, 6 }, /* EMA_D[1] */ + { pinmux(9), 1, 7 }, /* EMA_D[0] */ + { pinmux(10), 1, 1 }, /* EMA_A[22] */ + { pinmux(10), 1, 2 }, /* EMA_A[21] */ + { pinmux(10), 1, 3 }, /* EMA_A[20] */ + { pinmux(10), 1, 4 }, /* EMA_A[19] */ + { pinmux(10), 1, 5 }, /* EMA_A[18] */ + { pinmux(10), 1, 6 }, /* EMA_A[17] */ + { pinmux(10), 1, 7 }, /* EMA_A[16] */ + { pinmux(11), 1, 0 }, /* EMA_A[15] */ + { pinmux(11), 1, 1 }, /* EMA_A[14] */ + { pinmux(11), 1, 2 }, /* EMA_A[13] */ + { pinmux(11), 1, 3 }, /* EMA_A[12] */ + { pinmux(11), 1, 4 }, /* EMA_A[11] */ + { pinmux(11), 1, 5 }, /* EMA_A[10] */ + { pinmux(11), 1, 6 }, /* EMA_A[9] */ + { pinmux(11), 1, 7 }, /* EMA_A[8] */ + { pinmux(12), 1, 0 }, /* EMA_A[7] */ + { pinmux(12), 1, 1 }, /* EMA_A[6] */ + { pinmux(12), 1, 2 }, /* EMA_A[5] */ + { pinmux(12), 1, 3 }, /* EMA_A[4] */ + { pinmux(12), 1, 4 }, /* EMA_A[3] */ + { pinmux(12), 1, 5 }, /* EMA_A[2] */ + { pinmux(12), 1, 6 }, /* EMA_A[1] */ + { pinmux(12), 1, 7 }, /* EMA_A[0] */ +}; + +/* MMC0 pin muxer settings */ +const struct pinmux_config mmc0_pins[] = { + { pinmux(10), 2, 0 }, /* MMCSD0_CLK */ + { pinmux(10), 2, 1 }, /* MMCSD0_CMD */ + { pinmux(10), 2, 2 }, /* MMCSD0_DAT_0 */ + { pinmux(10), 2, 3 }, /* MMCSD0_DAT_1 */ + { pinmux(10), 2, 4 }, /* MMCSD0_DAT_2 */ + { pinmux(10), 2, 5 }, /* MMCSD0_DAT_3 */ + /* DA850 supports only 4-bit mode, remaining pins are not configured */ +}; diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c new file mode 100644 index 0000000000..f9550a16d3 --- /dev/null +++ b/arch/arm/mach-davinci/dm355.c @@ -0,0 +1,30 @@ +/* + * SoC-specific code for tms320dm355 and similar chips + * + * Copyright (C) 2009 David Brownell + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; +} + + +#ifdef CONFIG_SYS_I2C_DAVINCI +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX3) |= (1 << 20) | (1 << 19); +} +#endif diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c new file mode 100644 index 0000000000..f6ca527e74 --- /dev/null +++ b/arch/arm/mach-davinci/dm365.c @@ -0,0 +1,20 @@ +/* + * SoC-specific code for tms320dm365 and similar chips + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); +} + +#ifdef CONFIG_SYS_I2C_DAVINCI +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); +} +#endif diff --git a/arch/arm/mach-davinci/dm365_lowlevel.c b/arch/arm/mach-davinci/dm365_lowlevel.c new file mode 100644 index 0000000000..c8b44988d3 --- /dev/null +++ b/arch/arm/mach-davinci/dm365_lowlevel.c @@ -0,0 +1,460 @@ +/* + * SoC-specific lowlevel code for tms320dm365 and similar chips + * Actually used for booting from NAND with nand_spl. + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include + +void dm365_waitloop(unsigned long loopcnt) +{ + unsigned long i; + + for (i = 0; i < loopcnt; i++) + asm(" NOP"); +} + +int dm365_pll1_init(unsigned long pllmult, unsigned long prediv) +{ + unsigned int clksrc = 0x0; + + /* Power up the PLL */ + clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLPWRDN); + + clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_RES_9); + setbits_le32(&dv_pll0_regs->pllctl, + clksrc << PLLCTL_CLOCK_MODE_SHIFT); + + /* + * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled + * through MMR + */ + clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLENSRC); + + /* Set PLLEN=0 => PLL BYPASS MODE */ + clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN); + + dm365_waitloop(150); + + /* PLLRST=1(reset assert) */ + setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST); + + dm365_waitloop(300); + + /*Bring PLL out of Reset*/ + clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST); + + /* Program the Multiper and Pre-Divider for PLL1 */ + writel(pllmult, &dv_pll0_regs->pllm); + writel(prediv, &dv_pll0_regs->prediv); + + /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE | + PLLSECCTL_TINITZ, &dv_pll0_regs->secctl); + /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE, + &dv_pll0_regs->secctl); + /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */ + writel(PLLSECCTL_STOPMODE, &dv_pll0_regs->secctl); + /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll0_regs->secctl); + + /* Program the PostDiv for PLL1 */ + writel(PLL_POSTDEN, &dv_pll0_regs->postdiv); + + /* Post divider setting for PLL1 */ + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV1, &dv_pll0_regs->plldiv1); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV2, &dv_pll0_regs->plldiv2); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV3, &dv_pll0_regs->plldiv3); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV4, &dv_pll0_regs->plldiv4); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV5, &dv_pll0_regs->plldiv5); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV6, &dv_pll0_regs->plldiv6); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV7, &dv_pll0_regs->plldiv7); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV8, &dv_pll0_regs->plldiv8); + writel(CONFIG_SYS_DM36x_PLL1_PLLDIV9, &dv_pll0_regs->plldiv9); + + dm365_waitloop(300); + + /* Set the GOSET bit */ + writel(PLLCMD_GOSET, &dv_pll0_regs->pllcmd); /* Go */ + + dm365_waitloop(300); + + /* Wait for PLL to LOCK */ + while (!((readl(&dv_sys_module_regs->pll0_config) & PLL0_LOCK) + == PLL0_LOCK)) + ; + + /* Enable the PLL Bit of PLLCTL*/ + setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN); + + return 0; +} + +int dm365_pll2_init(unsigned long pllm, unsigned long prediv) +{ + unsigned int clksrc = 0x0; + + /* Power up the PLL*/ + clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLPWRDN); + + /* + * Select the Clock Mode as Onchip Oscilator or External Clock on + * MXI pin + * VDB has input on MXI pin + */ + clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_RES_9); + setbits_le32(&dv_pll1_regs->pllctl, + clksrc << PLLCTL_CLOCK_MODE_SHIFT); + + /* + * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled + * through MMR + */ + clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLENSRC); + + /* Set PLLEN=0 => PLL BYPASS MODE */ + clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN); + + dm365_waitloop(50); + + /* PLLRST=1(reset assert) */ + setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST); + + dm365_waitloop(300); + + /* Bring PLL out of Reset */ + clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST); + + /* Program the Multiper and Pre-Divider for PLL2 */ + writel(pllm, &dv_pll1_regs->pllm); + writel(prediv, &dv_pll1_regs->prediv); + + writel(PLL_POSTDEN, &dv_pll1_regs->postdiv); + + /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE | + PLLSECCTL_TINITZ, &dv_pll1_regs->secctl); + /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE, + &dv_pll1_regs->secctl); + /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */ + writel(PLLSECCTL_STOPMODE, &dv_pll1_regs->secctl); + /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */ + writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll1_regs->secctl); + + /* Post divider setting for PLL2 */ + writel(CONFIG_SYS_DM36x_PLL2_PLLDIV1, &dv_pll1_regs->plldiv1); + writel(CONFIG_SYS_DM36x_PLL2_PLLDIV2, &dv_pll1_regs->plldiv2); + writel(CONFIG_SYS_DM36x_PLL2_PLLDIV3, &dv_pll1_regs->plldiv3); + writel(CONFIG_SYS_DM36x_PLL2_PLLDIV4, &dv_pll1_regs->plldiv4); + writel(CONFIG_SYS_DM36x_PLL2_PLLDIV5, &dv_pll1_regs->plldiv5); + + /* GoCmd for PostDivider to take effect */ + writel(PLLCMD_GOSET, &dv_pll1_regs->pllcmd); + + dm365_waitloop(150); + + /* Wait for PLL to LOCK */ + while (!((readl(&dv_sys_module_regs->pll1_config) & PLL1_LOCK) + == PLL1_LOCK)) + ; + + dm365_waitloop(4100); + + /* Enable the PLL2 */ + setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN); + + /* do this after PLL's have been set up */ + writel(CONFIG_SYS_DM36x_PERI_CLK_CTRL, + &dv_sys_module_regs->peri_clkctl); + + return 0; +} + +int dm365_ddr_setup(void) +{ + lpsc_on(DAVINCI_LPSC_DDR_EMIF); + clrbits_le32(&dv_sys_module_regs->vtpiocr, + VPTIO_IOPWRDN | VPTIO_CLRZ | VPTIO_LOCK | VPTIO_PWRDN); + + /* Set bit CLRZ (bit 13) */ + setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_CLRZ); + + /* Check VTP READY Status */ + while (!(readl(&dv_sys_module_regs->vtpiocr) & VPTIO_RDY)) + ; + + /* Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) */ + setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_IOPWRDN); + + /* Set bit LOCK(bit7) */ + setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_LOCK); + + /* + * Powerdown VTP as it is locked (bit 6) + * Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) + */ + setbits_le32(&dv_sys_module_regs->vtpiocr, + VPTIO_IOPWRDN | VPTIO_PWRDN); + + /* Wait for calibration to complete */ + dm365_waitloop(150); + + /* Set the DDR2 to synreset, then enable it again */ + lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); + lpsc_on(DAVINCI_LPSC_DDR_EMIF); + + writel(CONFIG_SYS_DM36x_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr); + + /* Program SDRAM Bank Config Register */ + writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_BOOTUNLOCK), + &dv_ddr2_regs_ctrl->sdbcr); + writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_TIMUNLOCK), + &dv_ddr2_regs_ctrl->sdbcr); + + /* Program SDRAM Timing Control Register1 */ + writel(CONFIG_SYS_DM36x_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr); + /* Program SDRAM Timing Control Register2 */ + writel(CONFIG_SYS_DM36x_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2); + + writel(CONFIG_SYS_DM36x_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr); + + writel(CONFIG_SYS_DM36x_DDR2_SDBCR, &dv_ddr2_regs_ctrl->sdbcr); + + /* Program SDRAM Refresh Control Register */ + writel(CONFIG_SYS_DM36x_DDR2_SDRCR, &dv_ddr2_regs_ctrl->sdrcr); + + lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF); + lpsc_on(DAVINCI_LPSC_DDR_EMIF); + + return 0; +} + +static void dm365_vpss_sync_reset(void) +{ + unsigned int PdNum = 0; + + /* VPSS_CLKMD 1:1 */ + setbits_le32(&dv_sys_module_regs->vpss_clkctl, + VPSS_CLK_CTL_VPSS_CLKMD); + + /* LPSC SyncReset DDR Clock Enable */ + writel(((readl(&dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]) & + ~PSC_MD_STATE_MSK) | PSC_SYNCRESET), + &dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]); + + writel((1 << PdNum), &dv_psc_regs->ptcmd); + + while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) == 0)) + ; + while (!((readl(&dv_psc_regs->mdstat[DAVINCI_LPSC_VPSSMASTER]) & + PSC_MD_STATE_MSK) == PSC_SYNCRESET)) + ; +} + +static void dm365_por_reset(void) +{ + struct davinci_timer *wdog = + (struct davinci_timer *)DAVINCI_WDOG_BASE; + + if (readl(&dv_pll0_regs->rstype) & + (PLL_RSTYPE_POR | PLL_RSTYPE_XWRST)) { + dm365_vpss_sync_reset(); + + writel(DV_TMPBUF_VAL, TMPBUF); + setbits_le32(TMPSTATUS, FLAG_PORRST); + writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1); + writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2); + + while (1); + } +} + +static void dm365_wdt_reset(void) +{ + struct davinci_timer *wdog = + (struct davinci_timer *)DAVINCI_WDOG_BASE; + + if (readl(TMPBUF) != DV_TMPBUF_VAL) { + writel(DV_TMPBUF_VAL, TMPBUF); + setbits_le32(TMPSTATUS, FLAG_PORRST); + setbits_le32(TMPSTATUS, FLAG_FLGOFF); + + dm365_waitloop(100); + + dm365_vpss_sync_reset(); + + writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1); + writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2); + + while (1); + } +} + +static void dm365_wdt_flag_on(void) +{ + /* VPSS_CLKMD 1:2 */ + clrbits_le32(&dv_sys_module_regs->vpss_clkctl, + VPSS_CLK_CTL_VPSS_CLKMD); + writel(0, TMPBUF); + setbits_le32(TMPSTATUS, FLAG_FLGON); +} + +void dm365_psc_init(void) +{ + unsigned char i = 0; + unsigned char lpsc_start; + unsigned char lpsc_end, lpscgroup, lpscmin, lpscmax; + unsigned int PdNum = 0; + + lpscmin = 0; + lpscmax = 2; + + for (lpscgroup = lpscmin; lpscgroup <= lpscmax; lpscgroup++) { + if (lpscgroup == 0) { + /* Enabling LPSC 3 to 28 SCR first */ + lpsc_start = DAVINCI_LPSC_VPSSMSTR; + lpsc_end = DAVINCI_LPSC_TIMER1; + } else if (lpscgroup == 1) { /* Skip locked LPSCs [29-37] */ + lpsc_start = DAVINCI_LPSC_CFG5; + lpsc_end = DAVINCI_LPSC_VPSSMASTER; + } else { + lpsc_start = DAVINCI_LPSC_MJCP; + lpsc_end = DAVINCI_LPSC_HDVICP; + } + + /* NEXT=0x3, Enable LPSC's */ + for (i = lpsc_start; i <= lpsc_end; i++) + setbits_le32(&dv_psc_regs->mdctl[i], PSC_ENABLE); + + /* + * Program goctl to start transition sequence for LPSCs + * CSL_PSC_0_REGS->PTCMD = (1<ptcmd); + + /* + * Wait for GOSTAT = NO TRANSITION from PSC for Powerdomain 0 + */ + while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) + == 0)) + ; + + /* Wait for MODSTAT = ENABLE from LPSC's */ + for (i = lpsc_start; i <= lpsc_end; i++) + while (!((readl(&dv_psc_regs->mdstat[i]) & + PSC_MD_STATE_MSK) == PSC_ENABLE)) + ; + } +} + +static void dm365_emif_init(void) +{ + writel(CONFIG_SYS_DM36x_AWCCR, &davinci_emif_regs->awccr); + writel(CONFIG_SYS_DM36x_AB1CR, &davinci_emif_regs->ab1cr); + + setbits_le32(&davinci_emif_regs->nandfcr, DAVINCI_NANDFCR_CS2NAND); + + writel(CONFIG_SYS_DM36x_AB2CR, &davinci_emif_regs->ab2cr); + + return; +} + +void dm365_pinmux_ctl(unsigned long offset, unsigned long mask, + unsigned long value) +{ + clrbits_le32(&dv_sys_module_regs->pinmux[offset], mask); + setbits_le32(&dv_sys_module_regs->pinmux[offset], (mask & value)); +} + +__attribute__((weak)) +void board_gpio_init(void) +{ + return; +} + +#if defined(CONFIG_POST) +int post_log(char *format, ...) +{ + return 0; +} +#endif + +void dm36x_lowlevel_init(ulong bootflag) +{ + struct davinci_uart_ctrl_regs *davinci_uart_ctrl_regs = + (struct davinci_uart_ctrl_regs *)(CONFIG_SYS_NS16550_COM1 + + DAVINCI_UART_CTRL_BASE); + + /* Mask all interrupts */ + writel(DV_AINTC_INTCTL_IDMODE, &dv_aintc_regs->intctl); + writel(0x0, &dv_aintc_regs->eabase); + writel(0x0, &dv_aintc_regs->eint0); + writel(0x0, &dv_aintc_regs->eint1); + + /* Clear all interrupts */ + writel(0xffffffff, &dv_aintc_regs->fiq0); + writel(0xffffffff, &dv_aintc_regs->fiq1); + writel(0xffffffff, &dv_aintc_regs->irq0); + writel(0xffffffff, &dv_aintc_regs->irq1); + + dm365_por_reset(); + dm365_wdt_reset(); + + /* System PSC setup - enable all */ + dm365_psc_init(); + + /* Setup Pinmux */ + dm365_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX0); + dm365_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX1); + dm365_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX2); + dm365_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX3); + dm365_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX4); + + /* PLL setup */ + dm365_pll1_init(CONFIG_SYS_DM36x_PLL1_PLLM, + CONFIG_SYS_DM36x_PLL1_PREDIV); + dm365_pll2_init(CONFIG_SYS_DM36x_PLL2_PLLM, + CONFIG_SYS_DM36x_PLL2_PREDIV); + + /* GPIO setup */ + board_gpio_init(); + + NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1), + CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); + + /* + * Fix Power and Emulation Management Register + * see sprufh2.pdf page 38 Table 22 + */ + writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | + DAVINCI_UART_PWREMU_MGMT_UTRST), + &davinci_uart_ctrl_regs->pwremu_mgmt); + + puts("ddr init\n"); + dm365_ddr_setup(); + + puts("emif init\n"); + dm365_emif_init(); + + dm365_wdt_flag_on(); + +#if defined(CONFIG_POST) + /* + * Do memory tests, calls arch_memory_failure_handle() + * if error detected. + */ + memory_post_test(0); +#endif +} diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c new file mode 100644 index 0000000000..c58e271e28 --- /dev/null +++ b/arch/arm/mach-davinci/dm644x.c @@ -0,0 +1,81 @@ +/* + * SoC-specific code for tms320dm644x chips + * + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + + +#define PINMUX0_EMACEN (1 << 31) +#define PINMUX0_AECS5 (1 << 11) +#define PINMUX0_AECS4 (1 << 10) + +#define PINMUX1_I2C (1 << 7) +#define PINMUX1_UART1 (1 << 1) +#define PINMUX1_UART0 (1 << 0) + + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_LPSC_UART0); + + /* Bringup UART0 out of reset */ + REG(UART0_PWREMU_MGMT) = 0x00006001; + + /* Enable UART0 MUX lines */ + REG(PINMUX1) |= PINMUX1_UART0; +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_LPSC_EMAC); + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER); + lpsc_on(DAVINCI_LPSC_MDIO); + + /* Enable GIO3.3V cells used for EMAC */ + REG(VDD3P3V_PWDN) = 0; + + /* Enable EMAC. */ + REG(PINMUX0) |= PINMUX0_EMACEN; +} +#endif + +#ifdef CONFIG_SYS_I2C_DAVINCI +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_LPSC_I2C); + + /* Enable I2C pin Mux */ + REG(PINMUX1) |= PINMUX1_I2C; +} +#endif + +void davinci_errata_workarounds(void) +{ + /* + * Workaround for TMS320DM6446 errata 1.3.22: + * PSC: PTSTAT Register Does Not Clear After Warm/Maximum Reset + * Revision(s) Affected: 1.3 and earlier + */ + REG(PSC_SILVER_BULLET) = 0; + + /* + * Set the PR_OLD_COUNT bits in the Bus Burst Priority Register (PBBPR) + * as suggested in TMS320DM6446 errata 2.1.2: + * + * On DM6446 Silicon Revision 2.1 and earlier, under certain conditions + * low priority modules can occupy the bus and prevent high priority + * modules like the VPSS from getting the required DDR2 throughput. + * A hex value of 0x20 should provide a good ARM (cache enabled) + * performance and still allow good utilization by the VPSS or other + * modules. + */ + REG(VBPR) = 0x20; +} diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c new file mode 100644 index 0000000000..cfea8300de --- /dev/null +++ b/arch/arm/mach-davinci/dm646x.c @@ -0,0 +1,26 @@ +/* + * SoC-specific code for TMS320DM646x chips + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +void davinci_enable_uart0(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_UART0); +} + +#ifdef CONFIG_DRIVER_TI_EMAC +void davinci_enable_emac(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_EMAC); +} +#endif + +#ifdef CONFIG_SYS_I2C_DAVINCI +void davinci_enable_i2c(void) +{ + lpsc_on(DAVINCI_DM646X_LPSC_I2C); +} +#endif diff --git a/arch/arm/mach-davinci/dp83848.c b/arch/arm/mach-davinci/dp83848.c new file mode 100644 index 0000000000..6387e956b2 --- /dev/null +++ b/arch/arm/mach-davinci/dp83848.c @@ -0,0 +1,128 @@ +/* + * National Semiconductor DP83848 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * -------------------------------------------------------- + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include "../../../drivers/net/davinci_emac.h" + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int dp83848_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID1_REG, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, DP83848_PHYID2_REG, &id2)) + return(0); + + if ((id1 == DP83848_PHYID1_OUI) && (id2 == DP83848_PHYID2_OUI)) + return(1); + + return(0); +} + +int dp83848_get_link_speed(int phy_addr) +{ + u_int16_t tmp; + volatile emac_regs* emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_LINK_STATUS)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, DP83848_PHY_STAT_REG, &tmp)) + return(0); + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (tmp & DP83848_DUPLEX) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); +} + + +int dp83848_init_phy(int phy_addr) +{ + int ret = 1; + + if (!dp83848_get_link_speed(phy_addr)) { + /* Try another time */ + udelay(100000); + ret = dp83848_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + davinci_eth_phy_write(phy_addr, DP83848_PHY_INTR_CTRL_REG, 0); + + return(ret); +} + + +int dp83848_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp &= ~DP83848_AUTONEG; /* remove autonegotiation enable */ + tmp |= DP83848_ISOLATE; /* Electrically isolate PHY */ + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Set the Auto_negotiation Advertisement Register + * MII advertising for Next page, 100BaseTxFD and HD, + * 10BaseTFD and HD, IEEE 802.3 + */ + tmp = DP83848_NP | DP83848_TX_FDX | DP83848_TX_HDX | + DP83848_10_FDX | DP83848_10_HDX | DP83848_AN_IEEE_802_3; + davinci_eth_phy_write(phy_addr, DP83848_ANA_REG, tmp); + + + /* Read Control Register */ + if (!davinci_eth_phy_read(phy_addr, DP83848_CTL_REG, &tmp)) + return(0); + + tmp |= DP83848_SPEED_SELECT | DP83848_AUTONEG | DP83848_DUPLEX_MODE; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /* Restart Auto_negotiation */ + tmp |= DP83848_RESTART_AUTONEG; + davinci_eth_phy_write(phy_addr, DP83848_CTL_REG, tmp); + + /*check AutoNegotiate complete */ + udelay(10000); + if (!davinci_eth_phy_read(phy_addr, DP83848_STAT_REG, &tmp)) + return(0); + + if (!(tmp & DP83848_AUTONEG_COMP)) + return(0); + + return (dp83848_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/mach-davinci/et1011c.c b/arch/arm/mach-davinci/et1011c.c new file mode 100644 index 0000000000..151020d45a --- /dev/null +++ b/arch/arm/mach-davinci/et1011c.c @@ -0,0 +1,42 @@ +/* + * LSI ET1011C PHY Driver for TI DaVinci(TMS320DM6467) board. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include "../../../drivers/net/davinci_emac.h" + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +/* LSI PHYSICAL LAYER TRANSCEIVER ET1011C */ + +#define MII_PHY_CONFIG_REG 22 + +/* PHY Config bits */ +#define PHY_SYS_CLK_EN (1 << 4) + +int et1011c_get_link_speed(int phy_addr) +{ + u_int16_t data; + + if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &data) && (data & 0x04)) { + davinci_eth_phy_read(phy_addr, MII_PHY_CONFIG_REG, &data); + /* Enable 125MHz clock sourced from PHY */ + davinci_eth_phy_write(phy_addr, MII_PHY_CONFIG_REG, + data | PHY_SYS_CLK_EN); + return (1); + } + return (0); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/mach-davinci/ksz8873.c b/arch/arm/mach-davinci/ksz8873.c new file mode 100644 index 0000000000..75af13538d --- /dev/null +++ b/arch/arm/mach-davinci/ksz8873.c @@ -0,0 +1,53 @@ +/* + * Micrel KSZ8873 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2011 Heiko Schocher + * + * based on: + * National Semiconductor DP83848 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * -------------------------------------------------------- + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include "../../../drivers/net/davinci_emac.h" + +int ksz8873_is_phy_connected(int phy_addr) +{ + u_int16_t dummy; + + return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); +} + +int ksz8873_get_link_speed(int phy_addr) +{ + emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; + + /* we always have a link to the switch, 100 FD */ + writel((EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE), + &emac->MACCONTROL); + return 1; +} + + +int ksz8873_init_phy(int phy_addr) +{ + return 1; +} + + +int ksz8873_auto_negotiate(int phy_addr) +{ + return dp83848_get_link_speed(phy_addr); +} diff --git a/arch/arm/mach-davinci/lowlevel_init.S b/arch/arm/mach-davinci/lowlevel_init.S new file mode 100644 index 0000000000..e91623497c --- /dev/null +++ b/arch/arm/mach-davinci/lowlevel_init.S @@ -0,0 +1,693 @@ +/* + * Low-level board setup code for TI DaVinci SoC based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * Partially based on TI sources, original copyrights follow: + */ + +/* + * Board specific setup info + * + * (C) Copyright 2003 + * Texas Instruments, + * Kshitij Gupta + * + * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004 + * + * Modified for OMAP 5912 OSK board by Rishi Bhattacharya, Apr 2004 + * + * Modified for DV-EVM board by Rishi Bhattacharya, Apr 2005 + * + * Modified for DV-EVM board by Swaminathan S, Nov 2005 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define MDSTAT_STATE 0x3f + +.globl lowlevel_init +lowlevel_init: +#ifdef CONFIG_SOC_DM644X + + /*-------------------------------------------------------* + * Mask all IRQs by setting all bits in the EINT default * + *-------------------------------------------------------*/ + mov r1, $0 + ldr r0, =EINT_ENABLE0 + str r1, [r0] + ldr r0, =EINT_ENABLE1 + str r1, [r0] + + /*------------------------------------------------------* + * Put the GEM in reset * + *------------------------------------------------------*/ + + /* Put the GEM in reset */ + ldr r8, PSC_GEM_FLAG_CLEAR + ldr r6, MDCTL_GEM + ldr r7, [r6] + and r7, r7, r8 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x02 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStopGem: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x02 + bne checkStatClkStopGem + + /* Check for GEM Reset Completion */ +checkGemStatClkStop: + ldr r6, MDSTAT_GEM + ldr r7, [r6] + ands r7, r7, $0x100 + bne checkGemStatClkStop + + /* Do this for enabling a WDT initiated reset this is a workaround + for a chip bug. Not required under normal situations */ + ldr r6, P1394 + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * Enable L1 & L2 Memories in Fast mode * + *------------------------------------------------------*/ + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, MMARG_BRF0 + ldr r10, MMARG_BRF0_VAL + str r10, [r6] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /*------------------------------------------------------* + * DDR2 PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r10, $0 + ldr r6, PLL2_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r10, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 +WaitPPL2Loop: + subs r10, r10, $1 + bne WaitPPL2Loop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL2_PLLM + mov r2, $0x17 /* 162 MHz */ + str r2, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV2 + mov r3, $0x01 + str r3, [r6] + + /* Program the PLL2 Divisor Value */ + ldr r6, PLL2_DIV1 + mov r4, $0x0b /* 54 MHz */ + str r4, [r6] + + /* PLL2 DIV2 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV2 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop_0: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop_0 + + /* PLL2 DIV1 MMR */ + ldr r8, PLL2_DIV_MASK + ldr r6, PLL2_DIV1 + ldr r9, [r6] + and r8, r8, r9 + mov r9, $0x01 + mov r9, r9, lsl $15 + orr r8, r8, r9 + str r8, [r6] + + /* Program the GOSET bit to take new divider values */ + ldr r6, PLL2_PLLCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Wait for Done */ + ldr r6, PLL2_PLLSTAT +doneLoop: + ldr r7, [r6] + ands r7, r7, $0x01 + bne doneLoop + + /* Wait for PLL to Reset Properly */ + mov r10, $0x218 +ResetPPL2Loop: + subs r10, r10, $1 + bne ResetPPL2Loop + + /* Bring PLL out of Reset */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT +PLL2Lock: + subs r10, r10, $1 + bne PLL2Lock + + /* Enable the PLL */ + ldr r6, PLL2_CTL + ldr r8, [r6] + orr r8, r8, $0x01 + str r8, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $MDSTAT_STATE + cmp r7, $0x03 + bne checkDDRStatClkStop + + /*------------------------------------------------------* + * Program DDR2 MMRs for 162MHz Setting * + *------------------------------------------------------*/ + + /* Program PHY Control Register */ + ldr r6, DDRCTL + ldr r7, DDRCTL_VAL + str r7, [r6] + + /* Program SDRAM Bank Config Register */ + ldr r6, SDCFG + ldr r7, SDCFG_VAL + str r7, [r6] + + /* Program SDRAM TIM-0 Config Register */ + ldr r6, SDTIM0 + ldr r7, SDTIM0_VAL_162MHz + str r7, [r6] + + /* Program SDRAM TIM-1 Config Register */ + ldr r6, SDTIM1 + ldr r7, SDTIM1_VAL_162MHz + str r7, [r6] + + /* Program the SDRAM Bank Config Control Register */ + ldr r10, MASK_VAL + ldr r8, SDCFG + ldr r9, SDCFG_VAL + and r9, r9, r10 + str r9, [r8] + + /* Program SDRAM SDREF Config Register */ + ldr r6, SDREF + ldr r7, SDREF_VAL + str r7, [r6] + + /*------------------------------------------------------* + * Issue Soft Reset to DDR Module * + *------------------------------------------------------*/ + + /* Issue a Dummy DDR2 read/write */ + ldr r8, DDR2_START_ADDR + ldr r7, DUMMY_VAL + str r7, [r8] + ldr r7, [r8] + + /* Shut down the DDR2 LPSC Module */ + ldr r8, PSC_FLAG_CLEAR + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + and r7, r7, r8 + orr r7, r7, $0x01 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkStop2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkStop2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkStop2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $MDSTAT_STATE + cmp r7, $0x01 + bne checkDDRStatClkStop2 + + /*------------------------------------------------------* + * Turn DDR2 Controller Clocks On * + *------------------------------------------------------*/ + + /* Enable the DDR2 LPSC Module */ + ldr r6, MDCTL_DDR2 + ldr r7, [r6] + orr r7, r7, $0x03 + str r7, [r6] + + /* Enable the Power Domain Transition Command */ + ldr r6, PTCMD + ldr r7, [r6] + orr r7, r7, $0x01 + str r7, [r6] + + /* Check for Transition Complete(PTSTAT) */ +checkStatClkEn2: + ldr r6, PTSTAT + ldr r7, [r6] + ands r7, r7, $0x01 + bne checkStatClkEn2 + + /* Check for DDR2 Controller Enable Completion */ +checkDDRStatClkEn2: + ldr r6, MDSTAT_DDR2 + ldr r7, [r6] + and r7, r7, $MDSTAT_STATE + cmp r7, $0x03 + bne checkDDRStatClkEn2 + + /* DDR Writes and Reads */ + ldr r6, CFGTEST + mov r3, $0x01 + str r3, [r6] + + /*------------------------------------------------------* + * System PLL Initialization * + *------------------------------------------------------*/ + + /* Select the Clock Mode Depending on the Value written in the Boot Table by the run script */ + mov r2, $0 + ldr r6, PLL1_CTL + ldr r7, PLL_CLKSRC_MASK + ldr r8, [r6] + and r8, r8, r7 + mov r9, r2, lsl $8 + orr r8, r8, r9 + str r8, [r6] + + /* Select the PLLEN source */ + ldr r7, PLL_ENSRC_MASK + and r8, r8, r7 + str r8, [r6] + + /* Bypass the PLL */ + ldr r7, PLL_BYPASS_MASK + and r8, r8, r7 + str r8, [r6] + + /* Wait for few cycles to allow PLLEN Mux switch properly to bypass Clock */ + mov r10, $0x20 + +WaitLoop: + subs r10, r10, $1 + bne WaitLoop + + /* Reset the PLL */ + ldr r7, PLL_RESET_MASK + and r8, r8, r7 + str r8, [r6] + + /* Disable the PLL */ + orr r8, r8, $0x10 + str r8, [r6] + + /* Power up the PLL */ + ldr r7, PLL_PWRUP_MASK + and r8, r8, r7 + str r8, [r6] + + /* Enable the PLL from Disable Mode */ + ldr r7, PLL_DISABLE_ENABLE_MASK + and r8, r8, r7 + str r8, [r6] + + /* Program the PLL Multiplier */ + ldr r6, PLL1_PLLM + mov r3, $0x15 /* For 594MHz */ + str r3, [r6] + + /* Wait for PLL to Reset Properly */ + mov r10, $0xff + +ResetLoop: + subs r10, r10, $1 + bne ResetLoop + + /* Bring PLL out of Reset */ + ldr r6, PLL1_CTL + orr r8, r8, $0x08 + str r8, [r6] + + /* Wait for PLL to Lock */ + ldr r10, PLL_LOCK_COUNT + +PLL1Lock: + subs r10, r10, $1 + bne PLL1Lock + + /* Enable the PLL */ + orr r8, r8, $0x01 + str r8, [r6] + + nop + nop + nop + nop + + /*------------------------------------------------------* + * AEMIF configuration for NOR Flash (double check) * + *------------------------------------------------------*/ + ldr r0, _PINMUX0 + ldr r1, _DEV_SETTING + str r1, [r0] + + ldr r0, WAITCFG + ldr r1, WAITCFG_VAL + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + + ldr r0, ACFG3 + ldr r1, ACFG3_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG4 + ldr r1, ACFG4_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + ldr r0, ACFG5 + ldr r1, ACFG5_VAL + ldr r2, [r0] + and r1, r2, r1 + str r1, [r0] + + /*--------------------------------------* + * VTP manual Calibration * + *--------------------------------------*/ + ldr r0, VTPIOCR + ldr r1, VTP_MMR0 + str r1, [r0] + + ldr r0, VTPIOCR + ldr r1, VTP_MMR1 + str r1, [r0] + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTPLock: + subs r10, r10, $1 + bne VTPLock + + ldr r6, DFT_ENABLE + mov r10, $0x01 + str r10, [r6] + + ldr r6, DDRVTPR + ldr r7, [r6] + mov r8, r7, LSL #32-10 + mov r8, r8, LSR #32-10 /* grab low 10 bits */ + ldr r7, VTP_RECAL + orr r8, r7, r8 + ldr r7, VTP_EN + orr r8, r7, r8 + str r8, [r0] + + + /* Wait for 33 VTP CLK cycles. VRP operates at 27 MHz */ + ldr r10, VTP_LOCK_COUNT +VTP1Lock: + subs r10, r10, $1 + bne VTP1Lock + + ldr r1, [r0] + ldr r2, VTP_MASK + and r2, r1, r2 + str r2, [r0] + + ldr r6, DFT_ENABLE + mov r10, $0 + str r10, [r6] + + /* + * Call board-specific lowlevel init. + * That MUST be present and THAT returns + * back to arch calling code with "mov pc, lr." + */ + b dv_board_init + +.ltorg + +_PINMUX0: + .word 0x01c40000 /* Device Configuration Registers */ +_PINMUX1: + .word 0x01c40004 /* Device Configuration Registers */ + +_DEV_SETTING: + .word 0x00000c1f + +WAITCFG: + .word 0x01e00004 +WAITCFG_VAL: + .word 0 +ACFG3: + .word 0x01e00014 +ACFG3_VAL: + .word 0x3ffffffd +ACFG4: + .word 0x01e00018 +ACFG4_VAL: + .word 0x3ffffffd +ACFG5: + .word 0x01e0001c +ACFG5_VAL: + .word 0x3ffffffd + +MDCTL_DDR2: + .word 0x01c41a34 +MDSTAT_DDR2: + .word 0x01c41834 + +PTCMD: + .word 0x01c41120 +PTSTAT: + .word 0x01c41128 + +EINT_ENABLE0: + .word 0x01c48018 +EINT_ENABLE1: + .word 0x01c4801c + +PSC_FLAG_CLEAR: + .word 0xffffffe0 +PSC_GEM_FLAG_CLEAR: + .word 0xfffffeff + +/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */ +DDRCTL: + .word 0x200000e4 +DDRCTL_VAL: + .word 0x50006405 +SDREF: + .word 0x2000000c +SDREF_VAL: + .word 0x000005c3 +SDCFG: + .word 0x20000008 +SDCFG_VAL: +#ifdef DDR_4BANKS + .word 0x00178622 +#elif defined DDR_8BANKS + .word 0x00178632 +#else +#error "Unknown DDR configuration!!!" +#endif +SDTIM0: + .word 0x20000010 +SDTIM0_VAL_162MHz: + .word 0x28923211 +SDTIM1: + .word 0x20000014 +SDTIM1_VAL_162MHz: + .word 0x0016c722 +VTPIOCR: + .word 0x200000f0 /* VTP IO Control register */ +DDRVTPR: + .word 0x01c42030 /* DDR VPTR MMR */ +VTP_MMR0: + .word 0x201f +VTP_MMR1: + .word 0xa01f +DFT_ENABLE: + .word 0x01c4004c +VTP_LOCK_COUNT: + .word 0x5b0 +VTP_MASK: + .word 0xffffdfff +VTP_RECAL: + .word 0x08000 +VTP_EN: + .word 0x02000 +CFGTEST: + .word 0x80010000 +MASK_VAL: + .word 0x00000fff + +/* GEM Power Up & LPSC Control Register */ +MDCTL_GEM: + .word 0x01c41a9c +MDSTAT_GEM: + .word 0x01c4189c + +/* For WDT reset chip bug */ +P1394: + .word 0x01c41a20 + +PLL_CLKSRC_MASK: + .word 0xfffffeff /* Mask the Clock Mode bit */ +PLL_ENSRC_MASK: + .word 0xffffffdf /* Select the PLLEN source */ +PLL_BYPASS_MASK: + .word 0xfffffffe /* Put the PLL in BYPASS */ +PLL_RESET_MASK: + .word 0xfffffff7 /* Put the PLL in Reset Mode */ +PLL_PWRUP_MASK: + .word 0xfffffffd /* PLL Power up Mask Bit */ +PLL_DISABLE_ENABLE_MASK: + .word 0xffffffef /* Enable the PLL from Disable */ +PLL_LOCK_COUNT: + .word 0x2000 + +/* PLL1-SYSTEM PLL MMRs */ +PLL1_CTL: + .word 0x01c40900 +PLL1_PLLM: + .word 0x01c40910 + +/* PLL2-SYSTEM PLL MMRs */ +PLL2_CTL: + .word 0x01c40d00 +PLL2_PLLM: + .word 0x01c40d10 +PLL2_DIV1: + .word 0x01c40d18 +PLL2_DIV2: + .word 0x01c40d1c +PLL2_PLLCMD: + .word 0x01c40d38 +PLL2_PLLSTAT: + .word 0x01c40d3c +PLL2_DIV_MASK: + .word 0xffff7fff + +MMARG_BRF0: + .word 0x01c42010 /* BRF margin mode 0 (R/W)*/ +MMARG_BRF0_VAL: + .word 0x00444400 + +DDR2_START_ADDR: + .word 0x80000000 +DUMMY_VAL: + .word 0xa55aa55a +#else /* CONFIG_SOC_DM644X */ + mov pc, lr +#endif diff --git a/arch/arm/mach-davinci/lxt972.c b/arch/arm/mach-davinci/lxt972.c new file mode 100644 index 0000000000..a7356f9672 --- /dev/null +++ b/arch/arm/mach-davinci/lxt972.c @@ -0,0 +1,113 @@ +/* + * Intel LXT971/LXT972 PHY Driver for TI DaVinci + * (TMS320DM644x) based boards. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * -------------------------------------------------------- + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include "../../../drivers/net/davinci_emac.h" + +#ifdef CONFIG_DRIVER_TI_EMAC + +#ifdef CONFIG_CMD_NET + +int lxt972_is_phy_connected(int phy_addr) +{ + u_int16_t id1, id2; + + if (!davinci_eth_phy_read(phy_addr, MII_PHYSID1, &id1)) + return(0); + if (!davinci_eth_phy_read(phy_addr, MII_PHYSID2, &id2)) + return(0); + + if ((id1 == (0x0013)) && ((id2 & 0xfff0) == 0x78e0)) + return(1); + + return(0); +} + +int lxt972_get_link_speed(int phy_addr) +{ + u_int16_t stat1, tmp; + volatile emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR; + + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_STAT2, &stat1)) + return(0); + + if (!(stat1 & PHY_LXT971_STAT2_LINK)) /* link up? */ + return(0); + + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + tmp |= PHY_LXT971_DIG_CFG_MII_DRIVE; + + davinci_eth_phy_write(phy_addr, PHY_LXT971_DIG_CFG, tmp); + /* Read back */ + if (!davinci_eth_phy_read(phy_addr, PHY_LXT971_DIG_CFG, &tmp)) + return(0); + + /* Speed doesn't matter, there is no setting for it in EMAC... */ + if (stat1 & PHY_LXT971_STAT2_DUPLEX_MODE) { + /* set DM644x EMAC for Full Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE | + EMAC_MACCONTROL_FULLDUPLEX_ENABLE; + } else { + /*set DM644x EMAC for Half Duplex */ + emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE; + } + + return(1); +} + + +int lxt972_init_phy(int phy_addr) +{ + int ret = 1; + + if (!lxt972_get_link_speed(phy_addr)) { + /* Try another time */ + ret = lxt972_get_link_speed(phy_addr); + } + + /* Disable PHY Interrupts */ + davinci_eth_phy_write(phy_addr, PHY_LXT971_INT_ENABLE, 0); + + return(ret); +} + + +int lxt972_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) + return(0); + + /* Restart Auto_negotiation */ + tmp |= BMCR_ANRESTART; + davinci_eth_phy_write(phy_addr, MII_BMCR, tmp); + + /*check AutoNegotiate complete */ + udelay (10000); + if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) + return(0); + + if (!(tmp & BMSR_ANEGCOMPLETE)) + return(0); + + return (lxt972_get_link_speed(phy_addr)); +} + +#endif /* CONFIG_CMD_NET */ + +#endif /* CONFIG_DRIVER_ETHER */ diff --git a/arch/arm/mach-davinci/misc.c b/arch/arm/mach-davinci/misc.c new file mode 100644 index 0000000000..e18bdfc729 --- /dev/null +++ b/arch/arm/mach-davinci/misc.c @@ -0,0 +1,138 @@ +/* + * Miscelaneous DaVinci functions. + * + * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SPL_BUILD +int dram_init(void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size( + (void *)CONFIG_SYS_SDRAM_BASE, + CONFIG_MAX_RAM_BANK_SIZE); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} +#endif + +#ifdef CONFIG_DRIVER_TI_EMAC +/* + * Read ethernet MAC address from EEPROM for DVEVM compatible boards. + * Returns 1 if found, 0 otherwise. + */ +int dvevm_read_mac_address(uint8_t *buf) +{ +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR + /* Read MAC address. */ + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7F00, + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &buf[0], 6)) + goto i2cerr; + + /* Check that MAC address is valid. */ + if (!is_valid_ether_addr(buf)) + goto err; + + return 1; /* Found */ + +i2cerr: + printf("Read from EEPROM @ 0x%02x failed\n", + CONFIG_SYS_I2C_EEPROM_ADDR); +err: +#endif /* CONFIG_SYS_I2C_EEPROM_ADDR */ + + return 0; +} + +/* + * Set the mii mode as MII or RMII + */ +#if defined(CONFIG_SOC_DA8XX) +void davinci_emac_mii_mode_sel(int mode_sel) +{ + int val; + + val = readl(&davinci_syscfg_regs->cfgchip3); + if (mode_sel == 0) + val &= ~(1 << 8); + else + val |= (1 << 8); + writel(val, &davinci_syscfg_regs->cfgchip3); +} +#endif +/* + * If there is no MAC address in the environment, then it will be initialized + * (silently) from the value in the EEPROM. + */ +void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr) +{ + uint8_t env_enetaddr[6]; + int ret; + + ret = eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr); + if (!ret) { + /* + * There is no MAC address in the environment, so we + * initialize it from the value in the EEPROM. + */ + debug("### Setting environment from EEPROM MAC address = " + "\"%pM\"\n", + env_enetaddr); + ret = !eth_setenv_enetaddr("ethaddr", rom_enetaddr); + } + if (!ret) + printf("Failed to set mac address from EEPROM: %d\n", ret); +} +#endif /* CONFIG_DRIVER_TI_EMAC */ + +#if defined(CONFIG_SOC_DA8XX) +#ifndef CONFIG_USE_IRQ +void irq_init(void) +{ + /* + * Mask all IRQs by clearing the global enable and setting + * the enable clear for all the 90 interrupts. + */ + writel(0, &davinci_aintc_regs->ger); + + writel(0, &davinci_aintc_regs->hier); + + writel(0xffffffff, &davinci_aintc_regs->ecr1); + writel(0xffffffff, &davinci_aintc_regs->ecr2); + writel(0xffffffff, &davinci_aintc_regs->ecr3); +} +#endif + +/* + * Enable PSC for various peripherals. + */ +int da8xx_configure_lpsc_items(const struct lpsc_resource *item, + const int n_items) +{ + int i; + + for (i = 0; i < n_items; i++) + lpsc_on(item[i].lpsc_no); + + return 0; +} +#endif diff --git a/arch/arm/mach-davinci/pinmux.c b/arch/arm/mach-davinci/pinmux.c new file mode 100644 index 0000000000..e9d8c87cc8 --- /dev/null +++ b/arch/arm/mach-davinci/pinmux.c @@ -0,0 +1,90 @@ +/* + * DaVinci pinmux functions. + * + * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +/* + * Change the setting of a pin multiplexer field. + * + * Takes an array of pinmux settings similar to: + * + * struct pinmux_config uart_pins[] = { + * { &davinci_syscfg_regs->pinmux[8], 2, 7 }, + * { &davinci_syscfg_regs->pinmux[9], 2, 0 } + * }; + * + * Stepping through the array, each pinmux[n] register has the given value + * set in the pin mux field specified. + * + * The number of pins in the array must be passed (ARRAY_SIZE can provide + * this value conveniently). + * + * Returns 0 if all field numbers and values are in the correct range, + * else returns -1. + */ +int davinci_configure_pin_mux(const struct pinmux_config *pins, + const int n_pins) +{ + int i; + + /* check for invalid pinmux values */ + for (i = 0; i < n_pins; i++) { + if (pins[i].field >= PIN_MUX_NUM_FIELDS || + (pins[i].value & ~PIN_MUX_FIELD_MASK) != 0) + return -1; + } + + /* configure the pinmuxes */ + for (i = 0; i < n_pins; i++) { + const int offset = pins[i].field * PIN_MUX_FIELD_SIZE; + const unsigned int value = pins[i].value << offset; + const unsigned int mask = PIN_MUX_FIELD_MASK << offset; + const dv_reg *mux = pins[i].mux; + + writel(value | (readl(mux) & (~mask)), mux); + } + + return 0; +} + +/* + * Configure multiple pinmux resources. + * + * Takes an pinmux_resource array of pinmux_config and pin counts: + * + * const struct pinmux_resource pinmuxes[] = { + * PINMUX_ITEM(uart_pins), + * PINMUX_ITEM(i2c_pins), + * }; + * + * The number of items in the array must be passed (ARRAY_SIZE can provide + * this value conveniently). + * + * Each item entry is configured in the defined order. If configuration + * of any item fails, -1 is returned and none of the following items are + * configured. On success, 0 is returned. + */ +int davinci_configure_pin_mux_items(const struct pinmux_resource *item, + const int n_items) +{ + int i; + + for (i = 0; i < n_items; i++) { + if (davinci_configure_pin_mux(item[i].pins, + item[i].n_pins) != 0) + return -1; + } + + return 0; +} diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c new file mode 100644 index 0000000000..8d99e2e997 --- /dev/null +++ b/arch/arm/mach-davinci/psc.c @@ -0,0 +1,160 @@ +/* + * Power and Sleep Controller (PSC) functions. + * + * Copyright (C) 2007 Sergey Kubushyn + * Copyright (C) 2008 Lyrtech + * Copyright (C) 2004 Texas Instruments. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * The PSC manages three inputs to a "module" which may be a peripheral or + * CPU. Those inputs are the module's: clock; reset signal; and sometimes + * its power domain. For our purposes, we only care whether clock and power + * are active, and the module is out of reset. + * + * DaVinci chips may include two separate power domains: "Always On" and "DSP". + * Chips without a DSP generally have only one domain. + * + * The "Always On" power domain is always on when the chip is on, and is + * powered by the VDD pins (on DM644X). The majority of DaVinci modules + * lie within the "Always On" power domain. + * + * A separate domain called the "DSP" domain houses the C64x+ and other video + * hardware such as VICP. In some chips, the "DSP" domain is not always on. + * The "DSP" power domain is powered by the CVDDDSP pins (on DM644X). + */ + +/* Works on Always On power domain only (no PD argument) */ +static void lpsc_transition(unsigned int id, unsigned int state) +{ + dv_reg_p mdstat, mdctl, ptstat, ptcmd; +#ifdef CONFIG_SOC_DA8XX + struct davinci_psc_regs *psc_regs; +#endif + +#ifndef CONFIG_SOC_DA8XX + if (id >= DAVINCI_LPSC_GEM) + return; /* Don't work on DSP Power Domain */ + + mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4)); + mdctl = REG_P(PSC_MDCTL_BASE + (id * 4)); + ptstat = REG_P(PSC_PTSTAT); + ptcmd = REG_P(PSC_PTCMD); +#else + if (id < DAVINCI_LPSC_PSC1_BASE) { + if (id >= PSC_PSC0_MODULE_ID_CNT) + return; + psc_regs = davinci_psc0_regs; + mdstat = &psc_regs->psc0.mdstat[id]; + mdctl = &psc_regs->psc0.mdctl[id]; + } else { + id -= DAVINCI_LPSC_PSC1_BASE; + if (id >= PSC_PSC1_MODULE_ID_CNT) + return; + psc_regs = davinci_psc1_regs; + mdstat = &psc_regs->psc1.mdstat[id]; + mdctl = &psc_regs->psc1.mdctl[id]; + } + ptstat = &psc_regs->ptstat; + ptcmd = &psc_regs->ptcmd; +#endif + + while (readl(ptstat) & 0x01) + continue; + + if ((readl(mdstat) & PSC_MDSTAT_STATE) == state) + return; /* Already in that state */ + + writel((readl(mdctl) & ~PSC_MDCTL_NEXT) | state, mdctl); + + switch (id) { +#ifdef CONFIG_SOC_DM644X + /* Special treatment for some modules as for sprue14 p.7.4.2 */ + case DAVINCI_LPSC_VPSSSLV: + case DAVINCI_LPSC_EMAC: + case DAVINCI_LPSC_EMAC_WRAPPER: + case DAVINCI_LPSC_MDIO: + case DAVINCI_LPSC_USB: + case DAVINCI_LPSC_ATA: + case DAVINCI_LPSC_VLYNQ: + case DAVINCI_LPSC_UHPI: + case DAVINCI_LPSC_DDR_EMIF: + case DAVINCI_LPSC_AEMIF: + case DAVINCI_LPSC_MMC_SD: + case DAVINCI_LPSC_MEMSTICK: + case DAVINCI_LPSC_McBSP: + case DAVINCI_LPSC_GPIO: + writel(readl(mdctl) | 0x200, mdctl); + break; +#endif + } + + writel(0x01, ptcmd); + + while (readl(ptstat) & 0x01) + continue; + while ((readl(mdstat) & PSC_MDSTAT_STATE) != state) + continue; +} + +void lpsc_on(unsigned int id) +{ + lpsc_transition(id, 0x03); +} + +void lpsc_syncreset(unsigned int id) +{ + lpsc_transition(id, 0x01); +} + +void lpsc_disable(unsigned int id) +{ + lpsc_transition(id, 0x0); +} + +/* Not all DaVinci chips have a DSP power domain. */ +#ifdef CONFIG_SOC_DM644X + +/* If DSPLINK is used, we don't want U-Boot to power on the DSP. */ +#if !defined(CONFIG_SYS_USE_DSPLINK) +void dsp_on(void) +{ + int i; + + if (REG(PSC_PDSTAT1) & 0x1f) + return; /* Already on */ + + REG(PSC_GBLCTL) |= 0x01; + REG(PSC_PDCTL1) |= 0x01; + REG(PSC_PDCTL1) &= ~0x100; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03; + REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff; + REG(PSC_PTCMD) = 0x02; + + for (i = 0; i < 100; i++) { + if (REG(PSC_EPCPR) & 0x02) + break; + } + + REG(PSC_CHP_SHRTSW) = 0x01; + REG(PSC_PDCTL1) |= 0x100; + REG(PSC_EPCCR) = 0x02; + + for (i = 0; i < 100; i++) { + if (!(REG(PSC_PTSTAT) & 0x02)) + break; + } + + REG(PSC_GBLCTL) &= ~0x1f; +} +#endif /* CONFIG_SYS_USE_DSPLINK */ + +#endif /* have a DSP */ diff --git a/arch/arm/mach-davinci/reset.c b/arch/arm/mach-davinci/reset.c new file mode 100644 index 0000000000..6b0f15428a --- /dev/null +++ b/arch/arm/mach-davinci/reset.c @@ -0,0 +1,32 @@ +/* + * Processor reset using WDT. + * + * Copyright (C) 2012 Dmitry Bondar + * Copyright (C) 2007 Sergey Kubushyn + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +void reset_cpu(unsigned long a) +{ + struct davinci_timer *const wdttimer = + (struct davinci_timer *)DAVINCI_WDOG_BASE; + writel(0x08, &wdttimer->tgcr); + writel(readl(&wdttimer->tgcr) | 0x03, &wdttimer->tgcr); + writel(0, &wdttimer->tim12); + writel(0, &wdttimer->tim34); + writel(0, &wdttimer->prd12); + writel(0, &wdttimer->prd34); + writel(readl(&wdttimer->tcr) | 0x40, &wdttimer->tcr); + writel(readl(&wdttimer->wdtcr) | 0x4000, &wdttimer->wdtcr); + writel(0xa5c64000, &wdttimer->wdtcr); + writel(0xda7e4000, &wdttimer->wdtcr); + writel(0x4000, &wdttimer->wdtcr); + while (1) + /*nothing*/; +} diff --git a/arch/arm/mach-davinci/spl.c b/arch/arm/mach-davinci/spl.c new file mode 100644 index 0000000000..49349da179 --- /dev/null +++ b/arch/arm/mach-davinci/spl.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SPL_LIBCOMMON_SUPPORT +void puts(const char *str) +{ + while (*str) + putc(*str++); +} + +void putc(char c) +{ + if (c == '\n') + NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), '\r'); + + NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); +} +#endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ + +void spl_board_init(void) +{ +#ifdef CONFIG_SOC_DM365 + dm36x_lowlevel_init(0); +#endif +#ifdef CONFIG_SOC_DA8XX + arch_cpu_init(); +#endif + preloader_console_init(); +} + +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_NAND_SIMPLE + return BOOT_DEVICE_NAND; +#elif defined(CONFIG_SPL_SPI_LOAD) + return BOOT_DEVICE_SPI; +#elif defined(CONFIG_SPL_MMC_LOAD) + return BOOT_DEVICE_MMC1; +#else + puts("Unknown boot device\n"); + hang(); +#endif +} diff --git a/arch/arm/mach-davinci/timer.c b/arch/arm/mach-davinci/timer.c new file mode 100644 index 0000000000..c7d0652e83 --- /dev/null +++ b/arch/arm/mach-davinci/timer.c @@ -0,0 +1,128 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * Copyright (C) 2007 Sergey Kubushyn + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct davinci_timer * const timer = + (struct davinci_timer *)CONFIG_SYS_TIMERBASE; + +#define TIMER_LOAD_VAL 0xffffffff + +#define TIM_CLK_DIV 16 + +int timer_init(void) +{ + /* We are using timer34 in unchained 32-bit mode, full speed */ + writel(0x0, &timer->tcr); + writel(0x0, &timer->tgcr); + writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); + writel(0x0, &timer->tim34); + writel(TIMER_LOAD_VAL, &timer->prd34); + writel(2 << 22, &timer->tcr); + gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; + gd->arch.timer_reset_value = 0; + + return(0); +} + +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) +{ + unsigned long now = readl(&timer->tim34); + + /* increment tbu if tbl has rolled over */ + if (now < gd->arch.tbl) + gd->arch.tbu++; + gd->arch.tbl = now; + + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + +ulong get_timer(ulong base) +{ + unsigned long long timer_diff; + + timer_diff = get_ticks() - gd->arch.timer_reset_value; + + return lldiv(timer_diff, + (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base; +} + +void __udelay(unsigned long usec) +{ + unsigned long long endtime; + + endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, + 1000000UL); + endtime += get_ticks(); + + while (get_ticks() < endtime) + ; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +} + +#ifdef CONFIG_HW_WATCHDOG +static struct davinci_timer * const wdttimer = + (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; + +/* + * See prufw2.pdf for using Timer as a WDT + */ +void davinci_hw_watchdog_enable(void) +{ + writel(0x0, &wdttimer->tcr); + writel(0x0, &wdttimer->tgcr); + /* TIMMODE = 2h */ + writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr); + writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12); + writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34); + writel(2 << 22, &wdttimer->tcr); + writel(0x0, &wdttimer->tim12); + writel(0x0, &wdttimer->tim34); + /* set WDEN bit, WDKEY 0xa5c6 */ + writel(0xa5c64000, &wdttimer->wdtcr); + /* clear counter register */ + writel(0xda7e4000, &wdttimer->wdtcr); +} + +void davinci_hw_watchdog_reset(void) +{ + writel(0xa5c64000, &wdttimer->wdtcr); + writel(0xda7e4000, &wdttimer->wdtcr); +} +#endif -- cgit From 56f86e39e80c5cbb17bec42cf6931cd203176830 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:06 +0900 Subject: ARM: kirkwood: move SOC sources to mach-kirkwood Move arch/arm/cpu/arm926ejs/kirkwood/* -> arch/arm/mach-kirkwood/* Note: Perhaps, can we merge arch/arm/mach-kirkwood and arch/arm/mvebu-common into arch/arm/mach-mvebu, like Linux? Signed-off-by: Masahiro Yamada Acked-by: Stefan Roese Cc: Prafulla Wadaskar Cc: Luka Perkov --- MAINTAINERS | 2 +- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 2 + arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/kirkwood/Kconfig | 88 --------- arch/arm/cpu/arm926ejs/kirkwood/Makefile | 11 -- arch/arm/cpu/arm926ejs/kirkwood/cache.c | 19 -- arch/arm/cpu/arm926ejs/kirkwood/cpu.c | 321 ------------------------------- arch/arm/cpu/arm926ejs/kirkwood/mpp.c | 90 --------- arch/arm/mach-kirkwood/Kconfig | 88 +++++++++ arch/arm/mach-kirkwood/Makefile | 11 ++ arch/arm/mach-kirkwood/cache.c | 19 ++ arch/arm/mach-kirkwood/cpu.c | 321 +++++++++++++++++++++++++++++++ arch/arm/mach-kirkwood/mpp.c | 90 +++++++++ 14 files changed, 533 insertions(+), 532 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/kirkwood/Kconfig delete mode 100644 arch/arm/cpu/arm926ejs/kirkwood/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/kirkwood/cache.c delete mode 100644 arch/arm/cpu/arm926ejs/kirkwood/cpu.c delete mode 100644 arch/arm/cpu/arm926ejs/kirkwood/mpp.c create mode 100644 arch/arm/mach-kirkwood/Kconfig create mode 100644 arch/arm/mach-kirkwood/Makefile create mode 100644 arch/arm/mach-kirkwood/cache.c create mode 100644 arch/arm/mach-kirkwood/cpu.c create mode 100644 arch/arm/mach-kirkwood/mpp.c diff --git a/MAINTAINERS b/MAINTAINERS index 63085fc16d..e4edf45e8d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -99,7 +99,7 @@ M: Prafulla Wadaskar M: Luka Perkov S: Maintained T: git git://git.denx.de/u-boot-marvell.git -F: arch/arm/cpu/arm926ejs/kirkwood/ +F: arch/arm/mach-kirkwood/ F: arch/arm/include/asm/arch-kirkwood/ ARM MARVELL PXA diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 887c0d5b6e..dba6518fb3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -726,7 +726,7 @@ source "arch/arm/cpu/armv7/highbank/Kconfig" source "arch/arm/cpu/armv7/keystone/Kconfig" -source "arch/arm/cpu/arm926ejs/kirkwood/Kconfig" +source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/cpu/arm926ejs/nomadik/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e321057a0e..e09de5182e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -6,6 +6,8 @@ # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_DAVINCI) += davinci +# TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD +machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA machine-$(CONFIG_TEGRA) += tegra diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index 27b4353a9d..0b43a90fbd 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -15,7 +15,6 @@ endif endif obj-$(CONFIG_ARMADA100) += armada100/ -obj-$(CONFIG_KIRKWOOD) += kirkwood/ obj-$(if $(filter lpc32xx,$(SOC)),y) += lpc32xx/ obj-$(CONFIG_MB86R0x) += mb86r0x/ obj-$(CONFIG_MX25) += mx25/ diff --git a/arch/arm/cpu/arm926ejs/kirkwood/Kconfig b/arch/arm/cpu/arm926ejs/kirkwood/Kconfig deleted file mode 100644 index 45c6687d0b..0000000000 --- a/arch/arm/cpu/arm926ejs/kirkwood/Kconfig +++ /dev/null @@ -1,88 +0,0 @@ -if KIRKWOOD - -choice - prompt "Marvell Kirkwood board select" - -config TARGET_OPENRD - bool "Marvell OpenRD Board" - -config TARGET_MV88F6281GTW_GE - bool "MV88f6281GTW_GE Board" - -config TARGET_RD6281A - bool "RD6281A Board" - -config TARGET_DREAMPLUG - bool "DreamPlug Board" - -config TARGET_GURUPLUG - bool "GuruPlug Board" - -config TARGET_SHEEVAPLUG - bool "SheevaPlug Board" - -config TARGET_LSXL - bool "lsxl Board" - -config TARGET_POGO_E02 - bool "pogo_e02 Board" - -config TARGET_DNS325 - bool "dns325 Board" - -config TARGET_ICONNECT - bool "iconnect Board" - -config TARGET_TK71 - bool "TK71 Board" - -config TARGET_KM_KIRKWOOD - bool "KM_KIRKWOOD Board" - -config TARGET_NET2BIG_V2 - bool "LaCie 2Big Network v2 NAS Board" - -config TARGET_NETSPACE_V2 - bool "LaCie netspace_v2 Board" - -config TARGET_WIRELESS_SPACE - bool "LaCie Wireless_space Board" - -config TARGET_IB62X0 - bool "ib62x0 Board" - -config TARGET_DOCKSTAR - bool "Dockstar Board" - -config TARGET_GOFLEXHOME - bool "GoFlex Home Board" - -config TARGET_NAS220 - bool "BlackArmor NAS220" - -endchoice - -config SYS_SOC - default "kirkwood" - -source "board/Marvell/openrd/Kconfig" -source "board/Marvell/mv88f6281gtw_ge/Kconfig" -source "board/Marvell/rd6281a/Kconfig" -source "board/Marvell/dreamplug/Kconfig" -source "board/Marvell/guruplug/Kconfig" -source "board/Marvell/sheevaplug/Kconfig" -source "board/buffalo/lsxl/Kconfig" -source "board/cloudengines/pogo_e02/Kconfig" -source "board/d-link/dns325/Kconfig" -source "board/iomega/iconnect/Kconfig" -source "board/karo/tk71/Kconfig" -source "board/keymile/km_arm/Kconfig" -source "board/LaCie/net2big_v2/Kconfig" -source "board/LaCie/netspace_v2/Kconfig" -source "board/LaCie/wireless_space/Kconfig" -source "board/raidsonic/ib62x0/Kconfig" -source "board/Seagate/dockstar/Kconfig" -source "board/Seagate/goflexhome/Kconfig" -source "board/Seagate/nas220/Kconfig" - -endif diff --git a/arch/arm/cpu/arm926ejs/kirkwood/Makefile b/arch/arm/cpu/arm926ejs/kirkwood/Makefile deleted file mode 100644 index df4756e4bd..0000000000 --- a/arch/arm/cpu/arm926ejs/kirkwood/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2009 -# Marvell Semiconductor -# Written-by: Prafulla Wadaskar -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = cpu.o -obj-y += cache.o -obj-y += mpp.o diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cache.c b/arch/arm/cpu/arm926ejs/kirkwood/cache.c deleted file mode 100644 index e18a3097dc..0000000000 --- a/arch/arm/cpu/arm926ejs/kirkwood/cache.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2012 Michael Walle - * Michael Walle - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include - -#define FEROCEON_EXTRA_FEATURE_L2C_EN (1<<22) - -void l2_cache_disable() -{ - u32 ctrl; - - ctrl = readfr_extra_feature_reg(); - ctrl &= ~FEROCEON_EXTRA_FEATURE_L2C_EN; - writefr_extra_feature_reg(ctrl); -} diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c deleted file mode 100644 index 4c9d3fde47..0000000000 --- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -void reset_cpu(unsigned long ignored) -{ - struct kwcpu_registers *cpureg = - (struct kwcpu_registers *)KW_CPU_REG_BASE; - - writel(readl(&cpureg->rstoutn_mask) | (1 << 2), - &cpureg->rstoutn_mask); - writel(readl(&cpureg->sys_soft_rst) | 1, - &cpureg->sys_soft_rst); - while (1) ; -} - -/* - * Window Size - * Used with the Base register to set the address window size and location. - * Must be programmed from LSB to MSB as sequence of ones followed by - * sequence of zeros. The number of ones specifies the size of the window in - * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). - * NOTE: A value of 0x0 specifies 64-KByte size. - */ -unsigned int kw_winctrl_calcsize(unsigned int sizeval) -{ - int i; - unsigned int j = 0; - u32 val = sizeval >> 1; - - for (i = 0; val >= 0x10000; i++) { - j |= (1 << i); - val = val >> 1; - } - return (0x0000ffff & j); -} - -/* - * kw_config_adr_windows - Configure address Windows - * - * There are 8 address windows supported by Kirkwood Soc to addess different - * devices. Each window can be configured for size, BAR and remap addr - * Below configuration is standard for most of the cases - * - * If remap function not used, remap_lo must be set as base - * - * Reference Documentation: - * Mbus-L to Mbus Bridge Registers Configuration. - * (Sec 25.1 and 25.3 of Datasheet) - */ -int kw_config_adr_windows(void) -{ - struct kwwin_registers *winregs = - (struct kwwin_registers *)KW_CPU_WIN_BASE; - - /* Window 0: PCIE MEM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); - - writel(KW_DEFADR_PCI_MEM, &winregs[0].base); - writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); - writel(0x0, &winregs[0].remap_hi); - - /* Window 1: PCIE IO address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); - writel(KW_DEFADR_PCI_IO, &winregs[1].base); - writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); - writel(0x0, &winregs[1].remap_hi); - - /* Window 2: NAND Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); - writel(KW_DEFADR_NANDF, &winregs[2].base); - writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); - writel(0x0, &winregs[2].remap_hi); - - /* Window 3: SPI Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); - writel(KW_DEFADR_SPIF, &winregs[3].base); - writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); - writel(0x0, &winregs[3].remap_hi); - - /* Window 4: BOOT Memory address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); - writel(KW_DEFADR_BOOTROM, &winregs[4].base); - - /* Window 5: Security SRAM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, - KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); - writel(KW_DEFADR_SASRAM, &winregs[5].base); - - /* Window 6-7: Disabled */ - writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); - writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); - - return 0; -} - -/* - * SYSRSTn Duration Counter Support - * - * Kirkwood SoC implements a hardware-based SYSRSTn duration counter. - * When SYSRSTn is asserted low, a SYSRSTn duration counter is running. - * The SYSRSTn duration counter is useful for implementing a manufacturer - * or factory reset. Upon a long reset assertion that is greater than a - * pre-configured environment variable value for sysrstdelay, - * The counter value is stored in the SYSRSTn Length Counter Register - * The counter is based on the 25-MHz reference clock (40ns) - * It is a 29-bit counter, yielding a maximum counting duration of - * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value, - * it remains at this value until counter reset is triggered by setting - * bit 31 of KW_REG_SYSRST_CNT - */ -static void kw_sysrst_action(void) -{ - int ret; - char *s = getenv("sysrstcmd"); - - if (!s) { - debug("Error.. %s failed, check sysrstcmd\n", - __FUNCTION__); - return; - } - - debug("Starting %s process...\n", __FUNCTION__); - ret = run_command(s, 0); - if (ret != 0) - debug("Error.. %s failed\n", __FUNCTION__); - else - debug("%s process finished\n", __FUNCTION__); -} - -static void kw_sysrst_check(void) -{ - u32 sysrst_cnt, sysrst_dly; - char *s; - - /* - * no action if sysrstdelay environment variable is not defined - */ - s = getenv("sysrstdelay"); - if (s == NULL) - return; - - /* read sysrstdelay value */ - sysrst_dly = (u32) simple_strtoul(s, NULL, 10); - - /* read SysRst Length counter register (bits 28:0) */ - sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT)); - debug("H/w Rst hold time: %d.%d secs\n", - sysrst_cnt / SYSRST_CNT_1SEC_VAL, - sysrst_cnt % SYSRST_CNT_1SEC_VAL); - - /* clear the counter for next valid read*/ - writel(1 << 31, KW_REG_SYSRST_CNT); - - /* - * sysrst_action: - * if H/w Reset key is pressed and hold for time - * more than sysrst_dly in seconds - */ - if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly) - kw_sysrst_action(); -} - -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - char *rev = "??"; - u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff; - u8 revid = readl(KW_REG_PCIE_REVID) & 0xff; - - if ((readl(KW_REG_DEVICE_ID) & 0x03) > 2) { - printf("Error.. %s:Unsupported Kirkwood SoC 88F%04x\n", __FUNCTION__, devid); - return -1; - } - - switch (revid) { - case 0: - if (devid == 0x6281) - rev = "Z0"; - else if (devid == 0x6282) - rev = "A0"; - break; - case 1: - rev = "A1"; - break; - case 2: - rev = "A0"; - break; - case 3: - rev = "A1"; - break; - default: - break; - } - - printf("SoC: Kirkwood 88F%04x_%s\n", devid, rev); - return 0; -} -#endif /* CONFIG_DISPLAY_CPUINFO */ - -#ifdef CONFIG_ARCH_CPU_INIT -int arch_cpu_init(void) -{ - u32 reg; - struct kwcpu_registers *cpureg = - (struct kwcpu_registers *)KW_CPU_REG_BASE; - - /* Linux expects` the internal registers to be at 0xf1000000 */ - writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); - - /* Enable and invalidate L2 cache in write through mode */ - writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); - invalidate_l2_cache(); - - kw_config_adr_windows(); - -#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 - /* - * Configures the I/O voltage of the pads connected to Egigabit - * Ethernet interface to 1.8V - * By default it is set to 3.3V - */ - reg = readl(KW_REG_MPP_OUT_DRV_REG); - reg |= (1 << 7); - writel(reg, KW_REG_MPP_OUT_DRV_REG); -#endif -#ifdef CONFIG_KIRKWOOD_EGIGA_INIT - /* - * Set egiga port0/1 in normal functional mode - * This is required becasue on kirkwood by default ports are in reset mode - * OS egiga driver may not have provision to set them in normal mode - * and if u-boot is build without network support, network may fail at OS level - */ - reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); - reg &= ~(1 << 4); /* Clear PortReset Bit */ - writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); - reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); - reg &= ~(1 << 4); /* Clear PortReset Bit */ - writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); -#endif -#ifdef CONFIG_KIRKWOOD_PCIE_INIT - /* - * Enable PCI Express Port0 - */ - reg = readl(&cpureg->ctrl_stat); - reg |= (1 << 0); /* Set PEX0En Bit */ - writel(reg, &cpureg->ctrl_stat); -#endif - return 0; -} -#endif /* CONFIG_ARCH_CPU_INIT */ - -/* - * SOC specific misc init - */ -#if defined(CONFIG_ARCH_MISC_INIT) -int arch_misc_init(void) -{ - volatile u32 temp; - - /*CPU streaming & write allocate */ - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 28); /* disable wr alloc */ - writefr_extra_feature_reg(temp); - - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 29); /* streaming disabled */ - writefr_extra_feature_reg(temp); - - /* L2Cache settings */ - temp = readfr_extra_feature_reg(); - /* Disable L2C pre fetch - Set bit 24 */ - temp |= (1 << 24); - /* enable L2C - Set bit 22 */ - temp |= (1 << 22); - writefr_extra_feature_reg(temp); - - icache_enable(); - /* Change reset vector to address 0x0 */ - temp = get_cr(); - set_cr(temp & ~CR_V); - - /* checks and execute resset to factory event */ - kw_sysrst_check(); - - return 0; -} -#endif /* CONFIG_ARCH_MISC_INIT */ - -#ifdef CONFIG_MVGBE -int cpu_eth_init(bd_t *bis) -{ - mvgbe_initialize(bis); - return 0; -} -#endif - -#ifdef CONFIG_MVEBU_MMC -int board_mmc_init(bd_t *bis) -{ - mvebu_mmc_init(bis); - return 0; -} -#endif /* CONFIG_MVEBU_MMC */ diff --git a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c b/arch/arm/cpu/arm926ejs/kirkwood/mpp.c deleted file mode 100644 index 7222504ed3..0000000000 --- a/arch/arm/cpu/arm926ejs/kirkwood/mpp.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * arch/arm/mach-kirkwood/mpp.c - * - * MPP functions for Marvell Kirkwood SoCs - * Referenced from Linux kernel source - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - -static u32 kirkwood_variant(void) -{ - switch (readl(KW_REG_DEVICE_ID) & 0x03) { - case 1: - return MPP_F6192_MASK; - case 2: - return MPP_F6281_MASK; - default: - debug("MPP setup: unknown kirkwood variant\n"); - return 0; - } -} - -#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) -#define MPP_NR_REGS (1 + MPP_MAX/8) - -void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save) -{ - u32 mpp_ctrl[MPP_NR_REGS]; - unsigned int variant_mask; - int i; - - variant_mask = kirkwood_variant(); - if (!variant_mask) - return; - - debug( "initial MPP regs:"); - for (i = 0; i < MPP_NR_REGS; i++) { - mpp_ctrl[i] = readl(MPP_CTRL(i)); - debug(" %08x", mpp_ctrl[i]); - } - debug("\n"); - - - while (*mpp_list) { - unsigned int num = MPP_NUM(*mpp_list); - unsigned int sel = MPP_SEL(*mpp_list); - unsigned int sel_save; - int shift; - - if (num > MPP_MAX) { - debug("kirkwood_mpp_conf: invalid MPP " - "number (%u)\n", num); - continue; - } - if (!(*mpp_list & variant_mask)) { - debug("kirkwood_mpp_conf: requested MPP%u config " - "unavailable on this hardware\n", num); - continue; - } - - shift = (num & 7) << 2; - - if (mpp_save) { - sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; - *mpp_save = num | (sel_save << 8) | variant_mask; - mpp_save++; - } - - mpp_ctrl[num / 8] &= ~(0xf << shift); - mpp_ctrl[num / 8] |= sel << shift; - - mpp_list++; - } - - debug(" final MPP regs:"); - for (i = 0; i < MPP_NR_REGS; i++) { - writel(mpp_ctrl[i], MPP_CTRL(i)); - debug(" %08x", mpp_ctrl[i]); - } - debug("\n"); - -} diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig new file mode 100644 index 0000000000..45c6687d0b --- /dev/null +++ b/arch/arm/mach-kirkwood/Kconfig @@ -0,0 +1,88 @@ +if KIRKWOOD + +choice + prompt "Marvell Kirkwood board select" + +config TARGET_OPENRD + bool "Marvell OpenRD Board" + +config TARGET_MV88F6281GTW_GE + bool "MV88f6281GTW_GE Board" + +config TARGET_RD6281A + bool "RD6281A Board" + +config TARGET_DREAMPLUG + bool "DreamPlug Board" + +config TARGET_GURUPLUG + bool "GuruPlug Board" + +config TARGET_SHEEVAPLUG + bool "SheevaPlug Board" + +config TARGET_LSXL + bool "lsxl Board" + +config TARGET_POGO_E02 + bool "pogo_e02 Board" + +config TARGET_DNS325 + bool "dns325 Board" + +config TARGET_ICONNECT + bool "iconnect Board" + +config TARGET_TK71 + bool "TK71 Board" + +config TARGET_KM_KIRKWOOD + bool "KM_KIRKWOOD Board" + +config TARGET_NET2BIG_V2 + bool "LaCie 2Big Network v2 NAS Board" + +config TARGET_NETSPACE_V2 + bool "LaCie netspace_v2 Board" + +config TARGET_WIRELESS_SPACE + bool "LaCie Wireless_space Board" + +config TARGET_IB62X0 + bool "ib62x0 Board" + +config TARGET_DOCKSTAR + bool "Dockstar Board" + +config TARGET_GOFLEXHOME + bool "GoFlex Home Board" + +config TARGET_NAS220 + bool "BlackArmor NAS220" + +endchoice + +config SYS_SOC + default "kirkwood" + +source "board/Marvell/openrd/Kconfig" +source "board/Marvell/mv88f6281gtw_ge/Kconfig" +source "board/Marvell/rd6281a/Kconfig" +source "board/Marvell/dreamplug/Kconfig" +source "board/Marvell/guruplug/Kconfig" +source "board/Marvell/sheevaplug/Kconfig" +source "board/buffalo/lsxl/Kconfig" +source "board/cloudengines/pogo_e02/Kconfig" +source "board/d-link/dns325/Kconfig" +source "board/iomega/iconnect/Kconfig" +source "board/karo/tk71/Kconfig" +source "board/keymile/km_arm/Kconfig" +source "board/LaCie/net2big_v2/Kconfig" +source "board/LaCie/netspace_v2/Kconfig" +source "board/LaCie/wireless_space/Kconfig" +source "board/raidsonic/ib62x0/Kconfig" +source "board/Seagate/dockstar/Kconfig" +source "board/Seagate/goflexhome/Kconfig" +source "board/Seagate/nas220/Kconfig" + +endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile new file mode 100644 index 0000000000..df4756e4bd --- /dev/null +++ b/arch/arm/mach-kirkwood/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor +# Written-by: Prafulla Wadaskar +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o +obj-y += cache.o +obj-y += mpp.o diff --git a/arch/arm/mach-kirkwood/cache.c b/arch/arm/mach-kirkwood/cache.c new file mode 100644 index 0000000000..e18a3097dc --- /dev/null +++ b/arch/arm/mach-kirkwood/cache.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2012 Michael Walle + * Michael Walle + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include + +#define FEROCEON_EXTRA_FEATURE_L2C_EN (1<<22) + +void l2_cache_disable() +{ + u32 ctrl; + + ctrl = readfr_extra_feature_reg(); + ctrl &= ~FEROCEON_EXTRA_FEATURE_L2C_EN; + writefr_extra_feature_reg(ctrl); +} diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c new file mode 100644 index 0000000000..4c9d3fde47 --- /dev/null +++ b/arch/arm/mach-kirkwood/cpu.c @@ -0,0 +1,321 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +void reset_cpu(unsigned long ignored) +{ + struct kwcpu_registers *cpureg = + (struct kwcpu_registers *)KW_CPU_REG_BASE; + + writel(readl(&cpureg->rstoutn_mask) | (1 << 2), + &cpureg->rstoutn_mask); + writel(readl(&cpureg->sys_soft_rst) | 1, + &cpureg->sys_soft_rst); + while (1) ; +} + +/* + * Window Size + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of ones followed by + * sequence of zeros. The number of ones specifies the size of the window in + * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte). + * NOTE: A value of 0x0 specifies 64-KByte size. + */ +unsigned int kw_winctrl_calcsize(unsigned int sizeval) +{ + int i; + unsigned int j = 0; + u32 val = sizeval >> 1; + + for (i = 0; val >= 0x10000; i++) { + j |= (1 << i); + val = val >> 1; + } + return (0x0000ffff & j); +} + +/* + * kw_config_adr_windows - Configure address Windows + * + * There are 8 address windows supported by Kirkwood Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * If remap function not used, remap_lo must be set as base + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int kw_config_adr_windows(void) +{ + struct kwwin_registers *winregs = + (struct kwwin_registers *)KW_CPU_WIN_BASE; + + /* Window 0: PCIE MEM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); + + writel(KW_DEFADR_PCI_MEM, &winregs[0].base); + writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); + writel(0x0, &winregs[0].remap_hi); + + /* Window 1: PCIE IO address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, + KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); + writel(KW_DEFADR_PCI_IO, &winregs[1].base); + writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); + writel(0x0, &winregs[1].remap_hi); + + /* Window 2: NAND Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); + writel(KW_DEFADR_NANDF, &winregs[2].base); + writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); + writel(0x0, &winregs[2].remap_hi); + + /* Window 3: SPI Flash address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); + writel(KW_DEFADR_SPIF, &winregs[3].base); + writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); + writel(0x0, &winregs[3].remap_hi); + + /* Window 4: BOOT Memory address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, + KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); + writel(KW_DEFADR_BOOTROM, &winregs[4].base); + + /* Window 5: Security SRAM address space */ + writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, + KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); + writel(KW_DEFADR_SASRAM, &winregs[5].base); + + /* Window 6-7: Disabled */ + writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); + writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); + + return 0; +} + +/* + * SYSRSTn Duration Counter Support + * + * Kirkwood SoC implements a hardware-based SYSRSTn duration counter. + * When SYSRSTn is asserted low, a SYSRSTn duration counter is running. + * The SYSRSTn duration counter is useful for implementing a manufacturer + * or factory reset. Upon a long reset assertion that is greater than a + * pre-configured environment variable value for sysrstdelay, + * The counter value is stored in the SYSRSTn Length Counter Register + * The counter is based on the 25-MHz reference clock (40ns) + * It is a 29-bit counter, yielding a maximum counting duration of + * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value, + * it remains at this value until counter reset is triggered by setting + * bit 31 of KW_REG_SYSRST_CNT + */ +static void kw_sysrst_action(void) +{ + int ret; + char *s = getenv("sysrstcmd"); + + if (!s) { + debug("Error.. %s failed, check sysrstcmd\n", + __FUNCTION__); + return; + } + + debug("Starting %s process...\n", __FUNCTION__); + ret = run_command(s, 0); + if (ret != 0) + debug("Error.. %s failed\n", __FUNCTION__); + else + debug("%s process finished\n", __FUNCTION__); +} + +static void kw_sysrst_check(void) +{ + u32 sysrst_cnt, sysrst_dly; + char *s; + + /* + * no action if sysrstdelay environment variable is not defined + */ + s = getenv("sysrstdelay"); + if (s == NULL) + return; + + /* read sysrstdelay value */ + sysrst_dly = (u32) simple_strtoul(s, NULL, 10); + + /* read SysRst Length counter register (bits 28:0) */ + sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT)); + debug("H/w Rst hold time: %d.%d secs\n", + sysrst_cnt / SYSRST_CNT_1SEC_VAL, + sysrst_cnt % SYSRST_CNT_1SEC_VAL); + + /* clear the counter for next valid read*/ + writel(1 << 31, KW_REG_SYSRST_CNT); + + /* + * sysrst_action: + * if H/w Reset key is pressed and hold for time + * more than sysrst_dly in seconds + */ + if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly) + kw_sysrst_action(); +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char *rev = "??"; + u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff; + u8 revid = readl(KW_REG_PCIE_REVID) & 0xff; + + if ((readl(KW_REG_DEVICE_ID) & 0x03) > 2) { + printf("Error.. %s:Unsupported Kirkwood SoC 88F%04x\n", __FUNCTION__, devid); + return -1; + } + + switch (revid) { + case 0: + if (devid == 0x6281) + rev = "Z0"; + else if (devid == 0x6282) + rev = "A0"; + break; + case 1: + rev = "A1"; + break; + case 2: + rev = "A0"; + break; + case 3: + rev = "A1"; + break; + default: + break; + } + + printf("SoC: Kirkwood 88F%04x_%s\n", devid, rev); + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + u32 reg; + struct kwcpu_registers *cpureg = + (struct kwcpu_registers *)KW_CPU_REG_BASE; + + /* Linux expects` the internal registers to be at 0xf1000000 */ + writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); + + /* Enable and invalidate L2 cache in write through mode */ + writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); + invalidate_l2_cache(); + + kw_config_adr_windows(); + +#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 + /* + * Configures the I/O voltage of the pads connected to Egigabit + * Ethernet interface to 1.8V + * By default it is set to 3.3V + */ + reg = readl(KW_REG_MPP_OUT_DRV_REG); + reg |= (1 << 7); + writel(reg, KW_REG_MPP_OUT_DRV_REG); +#endif +#ifdef CONFIG_KIRKWOOD_EGIGA_INIT + /* + * Set egiga port0/1 in normal functional mode + * This is required becasue on kirkwood by default ports are in reset mode + * OS egiga driver may not have provision to set them in normal mode + * and if u-boot is build without network support, network may fail at OS level + */ + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0))); + reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1)); + reg &= ~(1 << 4); /* Clear PortReset Bit */ + writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1))); +#endif +#ifdef CONFIG_KIRKWOOD_PCIE_INIT + /* + * Enable PCI Express Port0 + */ + reg = readl(&cpureg->ctrl_stat); + reg |= (1 << 0); /* Set PEX0En Bit */ + writel(reg, &cpureg->ctrl_stat); +#endif + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + volatile u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + /* checks and execute resset to factory event */ + kw_sysrst_check(); + + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_MVGBE +int cpu_eth_init(bd_t *bis) +{ + mvgbe_initialize(bis); + return 0; +} +#endif + +#ifdef CONFIG_MVEBU_MMC +int board_mmc_init(bd_t *bis) +{ + mvebu_mmc_init(bis); + return 0; +} +#endif /* CONFIG_MVEBU_MMC */ diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c new file mode 100644 index 0000000000..7222504ed3 --- /dev/null +++ b/arch/arm/mach-kirkwood/mpp.c @@ -0,0 +1,90 @@ +/* + * arch/arm/mach-kirkwood/mpp.c + * + * MPP functions for Marvell Kirkwood SoCs + * Referenced from Linux kernel source + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +static u32 kirkwood_variant(void) +{ + switch (readl(KW_REG_DEVICE_ID) & 0x03) { + case 1: + return MPP_F6192_MASK; + case 2: + return MPP_F6281_MASK; + default: + debug("MPP setup: unknown kirkwood variant\n"); + return 0; + } +} + +#define MPP_CTRL(i) (KW_MPP_BASE + (i* 4)) +#define MPP_NR_REGS (1 + MPP_MAX/8) + +void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save) +{ + u32 mpp_ctrl[MPP_NR_REGS]; + unsigned int variant_mask; + int i; + + variant_mask = kirkwood_variant(); + if (!variant_mask) + return; + + debug( "initial MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + mpp_ctrl[i] = readl(MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + + + while (*mpp_list) { + unsigned int num = MPP_NUM(*mpp_list); + unsigned int sel = MPP_SEL(*mpp_list); + unsigned int sel_save; + int shift; + + if (num > MPP_MAX) { + debug("kirkwood_mpp_conf: invalid MPP " + "number (%u)\n", num); + continue; + } + if (!(*mpp_list & variant_mask)) { + debug("kirkwood_mpp_conf: requested MPP%u config " + "unavailable on this hardware\n", num); + continue; + } + + shift = (num & 7) << 2; + + if (mpp_save) { + sel_save = (mpp_ctrl[num / 8] >> shift) & 0xf; + *mpp_save = num | (sel_save << 8) | variant_mask; + mpp_save++; + } + + mpp_ctrl[num / 8] &= ~(0xf << shift); + mpp_ctrl[num / 8] |= sel << shift; + + mpp_list++; + } + + debug(" final MPP regs:"); + for (i = 0; i < MPP_NR_REGS; i++) { + writel(mpp_ctrl[i], MPP_CTRL(i)); + debug(" %08x", mpp_ctrl[i]); + } + debug("\n"); + +} -- cgit From ef917ddb1d9240b075f3c03ddf6e246c89b86fa6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:07 +0900 Subject: ARM: nomadik: move SoC sources to mach-nomadik Move arch/arm/cpu/arm926ejs/nomadik/* -> arch/arm/mach-nomadik/* Signed-off-by: Masahiro Yamada Cc: Nomadik Linux Team Cc: Alessandro Rubini --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 1 + arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/nomadik/Kconfig | 16 ------- arch/arm/cpu/arm926ejs/nomadik/Makefile | 9 ---- arch/arm/cpu/arm926ejs/nomadik/gpio.c | 83 --------------------------------- arch/arm/cpu/arm926ejs/nomadik/reset.S | 14 ------ arch/arm/cpu/arm926ejs/nomadik/timer.c | 71 ---------------------------- arch/arm/mach-nomadik/Kconfig | 16 +++++++ arch/arm/mach-nomadik/Makefile | 9 ++++ arch/arm/mach-nomadik/gpio.c | 83 +++++++++++++++++++++++++++++++++ arch/arm/mach-nomadik/reset.S | 14 ++++++ arch/arm/mach-nomadik/timer.c | 71 ++++++++++++++++++++++++++++ 13 files changed, 195 insertions(+), 195 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/nomadik/Kconfig delete mode 100644 arch/arm/cpu/arm926ejs/nomadik/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/nomadik/gpio.c delete mode 100644 arch/arm/cpu/arm926ejs/nomadik/reset.S delete mode 100644 arch/arm/cpu/arm926ejs/nomadik/timer.c create mode 100644 arch/arm/mach-nomadik/Kconfig create mode 100644 arch/arm/mach-nomadik/Makefile create mode 100644 arch/arm/mach-nomadik/gpio.c create mode 100644 arch/arm/mach-nomadik/reset.S create mode 100644 arch/arm/mach-nomadik/timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dba6518fb3..1bac511531 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -728,7 +728,7 @@ source "arch/arm/cpu/armv7/keystone/Kconfig" source "arch/arm/mach-kirkwood/Kconfig" -source "arch/arm/cpu/arm926ejs/nomadik/Kconfig" +source "arch/arm/mach-nomadik/Kconfig" source "arch/arm/cpu/armv7/omap3/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e09de5182e..32d039c2d0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -9,6 +9,7 @@ machine-$(CONFIG_ARCH_DAVINCI) += davinci # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA +machine-$(CONFIG_ARCH_NOMADIK) += nomadik machine-$(CONFIG_TEGRA) += tegra machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index 0b43a90fbd..ed0cf0fa05 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_MB86R0x) += mb86r0x/ obj-$(CONFIG_MX25) += mx25/ obj-$(CONFIG_MX27) += mx27/ obj-$(if $(filter mxs,$(SOC)),y) += mxs/ -obj-$(CONFIG_ARCH_NOMADIK) += nomadik/ obj-$(CONFIG_ORION5X) += orion5x/ obj-$(CONFIG_PANTHEON) += pantheon/ obj-$(if $(filter spear,$(SOC)),y) += spear/ diff --git a/arch/arm/cpu/arm926ejs/nomadik/Kconfig b/arch/arm/cpu/arm926ejs/nomadik/Kconfig deleted file mode 100644 index 265f336469..0000000000 --- a/arch/arm/cpu/arm926ejs/nomadik/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -if ARCH_NOMADIK - -choice - prompt "Nomadik board select" - -config NOMADIK_NHK8815 - bool "ST 8815 Nomadik Hardware Kit" - -endchoice - -config SYS_SOC - default "nomadik" - -source "board/st/nhk8815/Kconfig" - -endif diff --git a/arch/arm/cpu/arm926ejs/nomadik/Makefile b/arch/arm/cpu/arm926ejs/nomadik/Makefile deleted file mode 100644 index cdf1345d58..0000000000 --- a/arch/arm/cpu/arm926ejs/nomadik/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = timer.o gpio.o -obj-y += reset.o diff --git a/arch/arm/cpu/arm926ejs/nomadik/gpio.c b/arch/arm/cpu/arm926ejs/nomadik/gpio.c deleted file mode 100644 index eff5b2b75e..0000000000 --- a/arch/arm/cpu/arm926ejs/nomadik/gpio.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -static unsigned long gpio_base[4] = { - NOMADIK_GPIO0_BASE, - NOMADIK_GPIO1_BASE, - NOMADIK_GPIO2_BASE, - NOMADIK_GPIO3_BASE -}; - -enum gpio_registers { - GPIO_DAT = 0x00, /* data register */ - GPIO_DATS = 0x04, /* data set */ - GPIO_DATC = 0x08, /* data clear */ - GPIO_PDIS = 0x0c, /* pull disable */ - GPIO_DIR = 0x10, /* direction */ - GPIO_DIRS = 0x14, /* direction set */ - GPIO_DIRC = 0x18, /* direction clear */ - GPIO_AFSLA = 0x20, /* alternate function select A */ - GPIO_AFSLB = 0x24, /* alternate function select B */ -}; - -static inline unsigned long gpio_to_base(int gpio) -{ - return gpio_base[gpio / 32]; -} - -static inline u32 gpio_to_bit(int gpio) -{ - return 1 << (gpio & 0x1f); -} - -void nmk_gpio_af(int gpio, int alternate_function) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - u32 afunc, bfunc; - - /* alternate function is 0..3, with one bit per register */ - afunc = readl(base + GPIO_AFSLA) & ~bit; - bfunc = readl(base + GPIO_AFSLB) & ~bit; - if (alternate_function & 1) afunc |= bit; - if (alternate_function & 2) bfunc |= bit; - writel(afunc, base + GPIO_AFSLA); - writel(bfunc, base + GPIO_AFSLB); -} - -void nmk_gpio_dir(int gpio, int dir) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - if (dir) - writel(bit, base + GPIO_DIRS); - else - writel(bit, base + GPIO_DIRC); -} - -void nmk_gpio_set(int gpio, int val) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - if (val) - writel(bit, base + GPIO_DATS); - else - writel(bit, base + GPIO_DATC); -} - -int nmk_gpio_get(int gpio) -{ - unsigned long base = gpio_to_base(gpio); - u32 bit = gpio_to_bit(gpio); - - return readl(base + GPIO_DAT) & bit; -} diff --git a/arch/arm/cpu/arm926ejs/nomadik/reset.S b/arch/arm/cpu/arm926ejs/nomadik/reset.S deleted file mode 100644 index ec954726ae..0000000000 --- a/arch/arm/cpu/arm926ejs/nomadik/reset.S +++ /dev/null @@ -1,14 +0,0 @@ -#include -/* - * Processor reset for Nomadik - */ - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ - ldr r1, =0x1 - str r1, [r0, #0x18] - -_loop_forever: - b _loop_forever diff --git a/arch/arm/cpu/arm926ejs/nomadik/timer.c b/arch/arm/cpu/arm926ejs/nomadik/timer.c deleted file mode 100644 index 775d0b7488..0000000000 --- a/arch/arm/cpu/arm926ejs/nomadik/timer.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -/* - * The timer is a decrementer, we'll left it free running at 2.4MHz. - * We have 2.4 ticks per microsecond and an overflow in almost 30min - */ -#define TIMER_CLOCK (24 * 100 * 1000) -#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ -#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ -#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) -#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) - -/* macro to read the decrementing 32 bit timer as an increasing count */ -#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) - -/* Configure a free-running, auto-wrap counter with no prescaler */ -int timer_init(void) -{ - ulong val; - - writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, - CONFIG_SYS_TIMERBASE + MTU_CR(0)); - - /* Reset the timer */ - writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); - /* - * The load-register isn't really immediate: it changes on clock - * edges, so we must wait for our newly-written value to appear. - * Since we might miss reading 0, wait for any change in value. - */ - val = READ_TIMER(); - while (READ_TIMER() == val) - ; - - return 0; -} - -/* Return how many HZ passed since "base" */ -ulong get_timer(ulong base) -{ - return TICKS_TO_HZ(READ_TIMER()) - base; -} - -/* Delay x useconds */ -void __udelay(unsigned long usec) -{ - ulong ini, end; - - ini = READ_TIMER(); - end = ini + USEC_TO_COUNT(usec); - while ((signed)(end - READ_TIMER()) > 0) - ; -} - -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig new file mode 100644 index 0000000000..265f336469 --- /dev/null +++ b/arch/arm/mach-nomadik/Kconfig @@ -0,0 +1,16 @@ +if ARCH_NOMADIK + +choice + prompt "Nomadik board select" + +config NOMADIK_NHK8815 + bool "ST 8815 Nomadik Hardware Kit" + +endchoice + +config SYS_SOC + default "nomadik" + +source "board/st/nhk8815/Kconfig" + +endif diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile new file mode 100644 index 0000000000..cdf1345d58 --- /dev/null +++ b/arch/arm/mach-nomadik/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = timer.o gpio.o +obj-y += reset.o diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c new file mode 100644 index 0000000000..eff5b2b75e --- /dev/null +++ b/arch/arm/mach-nomadik/gpio.c @@ -0,0 +1,83 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +static unsigned long gpio_base[4] = { + NOMADIK_GPIO0_BASE, + NOMADIK_GPIO1_BASE, + NOMADIK_GPIO2_BASE, + NOMADIK_GPIO3_BASE +}; + +enum gpio_registers { + GPIO_DAT = 0x00, /* data register */ + GPIO_DATS = 0x04, /* data set */ + GPIO_DATC = 0x08, /* data clear */ + GPIO_PDIS = 0x0c, /* pull disable */ + GPIO_DIR = 0x10, /* direction */ + GPIO_DIRS = 0x14, /* direction set */ + GPIO_DIRC = 0x18, /* direction clear */ + GPIO_AFSLA = 0x20, /* alternate function select A */ + GPIO_AFSLB = 0x24, /* alternate function select B */ +}; + +static inline unsigned long gpio_to_base(int gpio) +{ + return gpio_base[gpio / 32]; +} + +static inline u32 gpio_to_bit(int gpio) +{ + return 1 << (gpio & 0x1f); +} + +void nmk_gpio_af(int gpio, int alternate_function) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + u32 afunc, bfunc; + + /* alternate function is 0..3, with one bit per register */ + afunc = readl(base + GPIO_AFSLA) & ~bit; + bfunc = readl(base + GPIO_AFSLB) & ~bit; + if (alternate_function & 1) afunc |= bit; + if (alternate_function & 2) bfunc |= bit; + writel(afunc, base + GPIO_AFSLA); + writel(bfunc, base + GPIO_AFSLB); +} + +void nmk_gpio_dir(int gpio, int dir) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (dir) + writel(bit, base + GPIO_DIRS); + else + writel(bit, base + GPIO_DIRC); +} + +void nmk_gpio_set(int gpio, int val) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (val) + writel(bit, base + GPIO_DATS); + else + writel(bit, base + GPIO_DATC); +} + +int nmk_gpio_get(int gpio) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + return readl(base + GPIO_DAT) & bit; +} diff --git a/arch/arm/mach-nomadik/reset.S b/arch/arm/mach-nomadik/reset.S new file mode 100644 index 0000000000..ec954726ae --- /dev/null +++ b/arch/arm/mach-nomadik/reset.S @@ -0,0 +1,14 @@ +#include +/* + * Processor reset for Nomadik + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ + ldr r1, =0x1 + str r1, [r0, #0x18] + +_loop_forever: + b _loop_forever diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c new file mode 100644 index 0000000000..775d0b7488 --- /dev/null +++ b/arch/arm/mach-nomadik/timer.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * The timer is a decrementer, we'll left it free running at 2.4MHz. + * We have 2.4 ticks per microsecond and an overflow in almost 30min + */ +#define TIMER_CLOCK (24 * 100 * 1000) +#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ +#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ +#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) +#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) + +/* macro to read the decrementing 32 bit timer as an increasing count */ +#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) + +/* Configure a free-running, auto-wrap counter with no prescaler */ +int timer_init(void) +{ + ulong val; + + writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, + CONFIG_SYS_TIMERBASE + MTU_CR(0)); + + /* Reset the timer */ + writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); + /* + * The load-register isn't really immediate: it changes on clock + * edges, so we must wait for our newly-written value to appear. + * Since we might miss reading 0, wait for any change in value. + */ + val = READ_TIMER(); + while (READ_TIMER() == val) + ; + + return 0; +} + +/* Return how many HZ passed since "base" */ +ulong get_timer(ulong base) +{ + return TICKS_TO_HZ(READ_TIMER()) - base; +} + +/* Delay x useconds */ +void __udelay(unsigned long usec) +{ + ulong ini, end; + + ini = READ_TIMER(); + end = ini + USEC_TO_COUNT(usec); + while ((signed)(end - READ_TIMER()) > 0) + ; +} + +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} -- cgit From 72a8ff4b04771071023ff1024e268c2fbdf159e7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:08 +0900 Subject: ARM: highbank: move SoC sources to mach-highbank Move arch/arm/cpu/armv7/highbank/* -> arch/arm/mach-highbank/* Signed-off-by: Masahiro Yamada Cc: Rob Herring --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 1 + arch/arm/cpu/armv7/Makefile | 1 - arch/arm/cpu/armv7/highbank/Kconfig | 12 ------------ arch/arm/cpu/armv7/highbank/Makefile | 8 -------- arch/arm/cpu/armv7/highbank/timer.c | 34 ---------------------------------- arch/arm/mach-highbank/Kconfig | 12 ++++++++++++ arch/arm/mach-highbank/Makefile | 8 ++++++++ arch/arm/mach-highbank/timer.c | 34 ++++++++++++++++++++++++++++++++++ 9 files changed, 56 insertions(+), 56 deletions(-) delete mode 100644 arch/arm/cpu/armv7/highbank/Kconfig delete mode 100644 arch/arm/cpu/armv7/highbank/Makefile delete mode 100644 arch/arm/cpu/armv7/highbank/timer.c create mode 100644 arch/arm/mach-highbank/Kconfig create mode 100644 arch/arm/mach-highbank/Makefile create mode 100644 arch/arm/mach-highbank/timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1bac511531..f981541e4a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -722,7 +722,7 @@ source "arch/arm/cpu/arm1176/bcm2835/Kconfig" source "arch/arm/cpu/armv7/exynos/Kconfig" -source "arch/arm/cpu/armv7/highbank/Kconfig" +source "arch/arm/mach-highbank/Kconfig" source "arch/arm/cpu/armv7/keystone/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 32d039c2d0..97858fad10 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -6,6 +6,7 @@ # by CONFIG_* macro name. machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_DAVINCI) += davinci +machine-$(CONFIG_ARCH_HIGHBANK) += highbank # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 91e69233c3..29ba6e2125 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -43,7 +43,6 @@ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ obj-$(CONFIG_ARCH_EXYNOS) += exynos/ -obj-$(CONFIG_ARCH_HIGHBANK) += highbank/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/ obj-$(if $(filter mx5,$(SOC)),y) += mx5/ diff --git a/arch/arm/cpu/armv7/highbank/Kconfig b/arch/arm/cpu/armv7/highbank/Kconfig deleted file mode 100644 index 0e73c04142..0000000000 --- a/arch/arm/cpu/armv7/highbank/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -if ARCH_HIGHBANK - -config SYS_BOARD - default "highbank" - -config SYS_SOC - default "highbank" - -config SYS_CONFIG_NAME - default "highbank" - -endif diff --git a/arch/arm/cpu/armv7/highbank/Makefile b/arch/arm/cpu/armv7/highbank/Makefile deleted file mode 100644 index 876099d9a1..0000000000 --- a/arch/arm/cpu/armv7/highbank/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := timer.o diff --git a/arch/arm/cpu/armv7/highbank/timer.c b/arch/arm/cpu/armv7/highbank/timer.c deleted file mode 100644 index d56bf21133..0000000000 --- a/arch/arm/cpu/armv7/highbank/timer.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * - * Based on arm926ejs/mx27/timer.c - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#undef SYSTIMER_BASE -#define SYSTIMER_BASE 0xFFF34000 /* Timer 0 and 1 base */ - -static struct systimer *systimer_base = (struct systimer *)SYSTIMER_BASE; - -/* - * Start the timer - */ -int timer_init(void) -{ - /* - * Setup timer0 - */ - writel(0, &systimer_base->timer0control); - writel(SYSTIMER_RELOAD, &systimer_base->timer0load); - writel(SYSTIMER_RELOAD, &systimer_base->timer0value); - writel(SYSTIMER_EN | SYSTIMER_32BIT | SYSTIMER_PRESC_256, - &systimer_base->timer0control); - - return 0; - -} diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig new file mode 100644 index 0000000000..0e73c04142 --- /dev/null +++ b/arch/arm/mach-highbank/Kconfig @@ -0,0 +1,12 @@ +if ARCH_HIGHBANK + +config SYS_BOARD + default "highbank" + +config SYS_SOC + default "highbank" + +config SYS_CONFIG_NAME + default "highbank" + +endif diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile new file mode 100644 index 0000000000..876099d9a1 --- /dev/null +++ b/arch/arm/mach-highbank/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := timer.o diff --git a/arch/arm/mach-highbank/timer.c b/arch/arm/mach-highbank/timer.c new file mode 100644 index 0000000000..d56bf21133 --- /dev/null +++ b/arch/arm/mach-highbank/timer.c @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2011 Calxeda, Inc. + * + * Based on arm926ejs/mx27/timer.c + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#undef SYSTIMER_BASE +#define SYSTIMER_BASE 0xFFF34000 /* Timer 0 and 1 base */ + +static struct systimer *systimer_base = (struct systimer *)SYSTIMER_BASE; + +/* + * Start the timer + */ +int timer_init(void) +{ + /* + * Setup timer0 + */ + writel(0, &systimer_base->timer0control); + writel(SYSTIMER_RELOAD, &systimer_base->timer0load); + writel(SYSTIMER_RELOAD, &systimer_base->timer0value); + writel(SYSTIMER_EN | SYSTIMER_32BIT | SYSTIMER_PRESC_256, + &systimer_base->timer0control); + + return 0; + +} -- cgit From 3e93b4e6001104152fec850d4724ea9ffad03e05 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:09 +0900 Subject: ARM: orion5x: move SoC sources to mach-orion5x Move arch/arm/cpu/arm926ejs/orion5x/* -> arch/arm/mach-orion5x/* Signed-off-by: Masahiro Yamada Cc: Albert ARIBAUD --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 2 + arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/orion5x/Kconfig | 16 -- arch/arm/cpu/arm926ejs/orion5x/Makefile | 18 -- arch/arm/cpu/arm926ejs/orion5x/cpu.c | 294 ------------------------- arch/arm/cpu/arm926ejs/orion5x/dram.c | 55 ----- arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S | 277 ----------------------- arch/arm/cpu/arm926ejs/orion5x/timer.c | 171 -------------- arch/arm/mach-orion5x/Kconfig | 16 ++ arch/arm/mach-orion5x/Makefile | 18 ++ arch/arm/mach-orion5x/cpu.c | 294 +++++++++++++++++++++++++ arch/arm/mach-orion5x/dram.c | 55 +++++ arch/arm/mach-orion5x/lowlevel_init.S | 277 +++++++++++++++++++++++ arch/arm/mach-orion5x/timer.c | 171 ++++++++++++++ 15 files changed, 834 insertions(+), 833 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/Kconfig delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/cpu.c delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/dram.c delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S delete mode 100644 arch/arm/cpu/arm926ejs/orion5x/timer.c create mode 100644 arch/arm/mach-orion5x/Kconfig create mode 100644 arch/arm/mach-orion5x/Makefile create mode 100644 arch/arm/mach-orion5x/cpu.c create mode 100644 arch/arm/mach-orion5x/dram.c create mode 100644 arch/arm/mach-orion5x/lowlevel_init.S create mode 100644 arch/arm/mach-orion5x/timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f981541e4a..038961c5fd 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -736,7 +736,7 @@ source "arch/arm/cpu/armv7/omap4/Kconfig" source "arch/arm/cpu/armv7/omap5/Kconfig" -source "arch/arm/cpu/arm926ejs/orion5x/Kconfig" +source "arch/arm/mach-orion5x/Kconfig" source "arch/arm/cpu/armv7/rmobile/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 97858fad10..6bcf8ec715 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -11,6 +11,8 @@ machine-$(CONFIG_ARCH_HIGHBANK) += highbank machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA machine-$(CONFIG_ARCH_NOMADIK) += nomadik +# TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X +machine-$(CONFIG_ORION5X) += orion5x machine-$(CONFIG_TEGRA) += tegra machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index ed0cf0fa05..3cb741db1d 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_MB86R0x) += mb86r0x/ obj-$(CONFIG_MX25) += mx25/ obj-$(CONFIG_MX27) += mx27/ obj-$(if $(filter mxs,$(SOC)),y) += mxs/ -obj-$(CONFIG_ORION5X) += orion5x/ obj-$(CONFIG_PANTHEON) += pantheon/ obj-$(if $(filter spear,$(SOC)),y) += spear/ obj-$(CONFIG_ARCH_VERSATILE) += versatile/ diff --git a/arch/arm/cpu/arm926ejs/orion5x/Kconfig b/arch/arm/cpu/arm926ejs/orion5x/Kconfig deleted file mode 100644 index 5a542629c7..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -if ORION5X - -choice - prompt "Marvell Orion board select" - -config TARGET_EDMINIV2 - bool "LaCie Ethernet Disk mini V2" - -endchoice - -config SYS_SOC - default "orion5x" - -source "board/LaCie/edminiv2/Kconfig" - -endif diff --git a/arch/arm/cpu/arm926ejs/orion5x/Makefile b/arch/arm/cpu/arm926ejs/orion5x/Makefile deleted file mode 100644 index 546ebcb52e..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (C) 2010 Albert ARIBAUD -# -# Based on original Kirkwood support which is -# (C) Copyright 2009 -# Marvell Semiconductor -# Written-by: Prafulla Wadaskar -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = cpu.o -obj-y += dram.o -obj-y += timer.o - -ifndef CONFIG_SKIP_LOWLEVEL_INIT -obj-y += lowlevel_init.o -endif diff --git a/arch/arm/cpu/arm926ejs/orion5x/cpu.c b/arch/arm/cpu/arm926ejs/orion5x/cpu.c deleted file mode 100644 index f88db3b1f9..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/cpu.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirkwood support which is - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -#define BUFLEN 16 - -void reset_cpu(unsigned long ignored) -{ - struct orion5x_cpu_registers *cpureg = - (struct orion5x_cpu_registers *)ORION5X_CPU_REG_BASE; - - writel(readl(&cpureg->rstoutn_mask) | (1 << 2), - &cpureg->rstoutn_mask); - writel(readl(&cpureg->sys_soft_rst) | 1, - &cpureg->sys_soft_rst); - while (1) - ; -} - -/* - * Compute Window Size field value from size expressed in bytes - * Used with the Base register to set the address window size and location. - * Must be programmed from LSB to MSB as sequence of ones followed by - * sequence of zeros. The number of ones specifies the size of the window in - * 64 KiB granularity (e.g., a value of 0x00FF specifies 256 = 16 MiB). - * NOTES: - * 1) A sizeval equal to 0x0 specifies 4 GiB. - * 2) A return value of 0x0 specifies 64 KiB. - */ -unsigned int orion5x_winctrl_calcsize(unsigned int sizeval) -{ - /* - * Calculate the number of 64 KiB blocks needed minus one (rounding up). - * For sizeval > 0 this is equivalent to: - * sizeval = (u32) ceil((double) sizeval / 65536.0) - 1 - */ - sizeval = (sizeval - 1) >> 16; - - /* - * Propagate 'one' bits to the right by 'oring' them. - * We need only treat bits 15-0. - */ - sizeval |= sizeval >> 1; /* 'Or' bit 15 onto bit 14 */ - sizeval |= sizeval >> 2; /* 'Or' bits 15-14 onto bits 13-12 */ - sizeval |= sizeval >> 4; /* 'Or' bits 15-12 onto bits 11-8 */ - sizeval |= sizeval >> 8; /* 'Or' bits 15-8 onto bits 7-0*/ - - return sizeval; -} - -/* - * orion5x_config_adr_windows - Configure address Windows - * - * There are 8 address windows supported by Orion5x Soc to addess different - * devices. Each window can be configured for size, BAR and remap addr - * Below configuration is standard for most of the cases - * - * If remap function not used, remap_lo must be set as base - * - * NOTES: - * - * 1) in order to avoid windows with inconsistent control and base values - * (which could prevent access to BOOTCS and hence execution from FLASH) - * always disable window before writing the base value then reenable it - * by writing the control value. - * - * 2) in order to avoid losing access to BOOTCS when disabling window 7, - * first configure window 6 for BOOTCS, then configure window 7 for BOOTCS, - * then configure windows 6 for its own target. - * - * Reference Documentation: - * Mbus-L to Mbus Bridge Registers Configuration. - * (Sec 25.1 and 25.3 of Datasheet) - */ -int orion5x_config_adr_windows(void) -{ - struct orion5x_win_registers *winregs = - (struct orion5x_win_registers *)ORION5X_CPU_WIN_BASE; - -/* Disable window 0, configure it for its intended target, enable it. */ - writel(0, &winregs[0].ctrl); - writel(ORION5X_ADR_PCIE_MEM, &winregs[0].base); - writel(ORION5X_ADR_PCIE_MEM_REMAP_LO, &winregs[0].remap_lo); - writel(ORION5X_ADR_PCIE_MEM_REMAP_HI, &winregs[0].remap_hi); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_MEM, - ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_MEM, - ORION5X_WIN_ENABLE), &winregs[0].ctrl); -/* Disable window 1, configure it for its intended target, enable it. */ - writel(0, &winregs[1].ctrl); - writel(ORION5X_ADR_PCIE_IO, &winregs[1].base); - writel(ORION5X_ADR_PCIE_IO_REMAP_LO, &winregs[1].remap_lo); - writel(ORION5X_ADR_PCIE_IO_REMAP_HI, &winregs[1].remap_hi); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_IO, - ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_IO, - ORION5X_WIN_ENABLE), &winregs[1].ctrl); -/* Disable window 2, configure it for its intended target, enable it. */ - writel(0, &winregs[2].ctrl); - writel(ORION5X_ADR_PCI_MEM, &winregs[2].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_MEM, - ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_MEM, - ORION5X_WIN_ENABLE), &winregs[2].ctrl); -/* Disable window 3, configure it for its intended target, enable it. */ - writel(0, &winregs[3].ctrl); - writel(ORION5X_ADR_PCI_IO, &winregs[3].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_IO, - ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_IO, - ORION5X_WIN_ENABLE), &winregs[3].ctrl); -/* Disable window 4, configure it for its intended target, enable it. */ - writel(0, &winregs[4].ctrl); - writel(ORION5X_ADR_DEV_CS0, &winregs[4].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS0, - ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS0, - ORION5X_WIN_ENABLE), &winregs[4].ctrl); -/* Disable window 5, configure it for its intended target, enable it. */ - writel(0, &winregs[5].ctrl); - writel(ORION5X_ADR_DEV_CS1, &winregs[5].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS1, - ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS1, - ORION5X_WIN_ENABLE), &winregs[5].ctrl); -/* Disable window 6, configure it for FLASH, enable it. */ - writel(0, &winregs[6].ctrl); - writel(ORION5X_ADR_BOOTROM, &winregs[6].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, - ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, - ORION5X_WIN_ENABLE), &winregs[6].ctrl); -/* Disable window 7, configure it for FLASH, enable it. */ - writel(0, &winregs[7].ctrl); - writel(ORION5X_ADR_BOOTROM, &winregs[7].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, - ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, - ORION5X_WIN_ENABLE), &winregs[7].ctrl); -/* Disable window 6, configure it for its intended target, enable it. */ - writel(0, &winregs[6].ctrl); - writel(ORION5X_ADR_DEV_CS2, &winregs[6].base); - writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS2, - ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS2, - ORION5X_WIN_ENABLE), &winregs[6].ctrl); - - return 0; -} - -/* - * Orion5x identification is done through PCIE space. - */ - -u32 orion5x_device_id(void) -{ - return readl(PCIE_DEV_ID_OFF) >> 16; -} - -u32 orion5x_device_rev(void) -{ - return readl(PCIE_DEV_REV_OFF) & 0xff; -} - -#if defined(CONFIG_DISPLAY_CPUINFO) - -/* Display device and revision IDs. - * This function must cover all known device/revision - * combinations, not only the one for which u-boot is - * compiled; this way, one can identify actual HW in - * case of a mismatch. - */ -int print_cpuinfo(void) -{ - char dev_str[7]; /* room enough for 0x0000 plus null byte */ - char rev_str[5]; /* room enough for 0x00 plus null byte */ - char *dev_name = NULL; - char *rev_name = NULL; - - u32 dev = orion5x_device_id(); - u32 rev = orion5x_device_rev(); - - if (dev == MV88F5181_DEV_ID) { - dev_name = "MV88F5181"; - if (rev == MV88F5181_REV_B1) - rev_name = "B1"; - else if (rev == MV88F5181L_REV_A1) { - dev_name = "MV88F5181L"; - rev_name = "A1"; - } else if (rev == MV88F5181L_REV_A0) { - dev_name = "MV88F5181L"; - rev_name = "A0"; - } - } else if (dev == MV88F5182_DEV_ID) { - dev_name = "MV88F5182"; - if (rev == MV88F5182_REV_A2) - rev_name = "A2"; - } else if (dev == MV88F5281_DEV_ID) { - dev_name = "MV88F5281"; - if (rev == MV88F5281_REV_D2) - rev_name = "D2"; - else if (rev == MV88F5281_REV_D1) - rev_name = "D1"; - else if (rev == MV88F5281_REV_D0) - rev_name = "D0"; - } else if (dev == MV88F6183_DEV_ID) { - dev_name = "MV88F6183"; - if (rev == MV88F6183_REV_B0) - rev_name = "B0"; - } - if (dev_name == NULL) { - sprintf(dev_str, "0x%04x", dev); - dev_name = dev_str; - } - if (rev_name == NULL) { - sprintf(rev_str, "0x%02x", rev); - rev_name = rev_str; - } - - printf("SoC: Orion5x %s-%s\n", dev_name, rev_name); - - return 0; -} -#endif /* CONFIG_DISPLAY_CPUINFO */ - -#ifdef CONFIG_ARCH_CPU_INIT -int arch_cpu_init(void) -{ - /* Enable and invalidate L2 cache in write through mode */ - invalidate_l2_cache(); - - orion5x_config_adr_windows(); - - return 0; -} -#endif /* CONFIG_ARCH_CPU_INIT */ - -/* - * SOC specific misc init - */ -#if defined(CONFIG_ARCH_MISC_INIT) -int arch_misc_init(void) -{ - u32 temp; - - /*CPU streaming & write allocate */ - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 28); /* disable wr alloc */ - writefr_extra_feature_reg(temp); - - temp = readfr_extra_feature_reg(); - temp &= ~(1 << 29); /* streaming disabled */ - writefr_extra_feature_reg(temp); - - /* L2Cache settings */ - temp = readfr_extra_feature_reg(); - /* Disable L2C pre fetch - Set bit 24 */ - temp |= (1 << 24); - /* enable L2C - Set bit 22 */ - temp |= (1 << 22); - writefr_extra_feature_reg(temp); - - icache_enable(); - /* Change reset vector to address 0x0 */ - temp = get_cr(); - set_cr(temp & ~CR_V); - - /* Set CPIOs and MPPs - values provided by board - include file */ - writel(ORION5X_MPP0_7, ORION5X_MPP_BASE+0x00); - writel(ORION5X_MPP8_15, ORION5X_MPP_BASE+0x04); - writel(ORION5X_MPP16_23, ORION5X_MPP_BASE+0x50); - writel(ORION5X_GPIO_OUT_VALUE, ORION5X_GPIO_BASE+0x00); - writel(ORION5X_GPIO_OUT_ENABLE, ORION5X_GPIO_BASE+0x04); - writel(ORION5X_GPIO_IN_POLARITY, ORION5X_GPIO_BASE+0x0c); - - /* initialize timer */ - timer_init_r(); - return 0; -} -#endif /* CONFIG_ARCH_MISC_INIT */ - -#ifdef CONFIG_MVGBE -int cpu_eth_init(bd_t *bis) -{ - mvgbe_initialize(bis); - return 0; -} -#endif diff --git a/arch/arm/cpu/arm926ejs/orion5x/dram.c b/arch/arm/cpu/arm926ejs/orion5x/dram.c deleted file mode 100644 index 9ed93d25bc..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/dram.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirkwood support which is - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* - * orion5x_sdram_bar - reads SDRAM Base Address Register - */ -u32 orion5x_sdram_bar(enum memory_bank bank) -{ - struct orion5x_ddr_addr_decode_registers *winregs = - (struct orion5x_ddr_addr_decode_registers *) - ORION5X_DRAM_BASE; - - u32 result = 0; - u32 enable = 0x01 & winregs[bank].size; - - if ((!enable) || (bank > BANK3)) - return 0; - - result = winregs[bank].base; - return result; -} -int dram_init (void) -{ - /* dram_init must store complete ramsize in gd->ram_size */ - gd->ram_size = get_ram_size( - (long *) orion5x_sdram_bar(0), - CONFIG_MAX_RAM_BANK_SIZE); - return 0; -} - -void dram_init_banksize (void) -{ - int i; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - gd->bd->bi_dram[i].start = orion5x_sdram_bar(i); - gd->bd->bi_dram[i].size = get_ram_size( - (long *) (gd->bd->bi_dram[i].start), - CONFIG_MAX_RAM_BANK_SIZE); - } -} diff --git a/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S b/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S deleted file mode 100644 index 4dacc296e4..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/lowlevel_init.S +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include "asm/arch/orion5x.h" - -/* - * Configuration values for SDRAM access setup - */ - -#define SDRAM_CONFIG 0x3148400 -#define SDRAM_MODE 0x62 -#define SDRAM_CONTROL 0x4041000 -#define SDRAM_TIME_CTRL_LOW 0x11602220 -#define SDRAM_TIME_CTRL_HI 0x40c -#define SDRAM_OPEN_PAGE_EN 0x0 -/* DDR 1 2x 32M NANYA NT5DS16M16CS-6K ==> 64MB */ -#define SDRAM_BANK0_SIZE 0x3ff0001 -#define SDRAM_ADDR_CTRL 0x10 - -#define SDRAM_OP_NOP 0x05 -#define SDRAM_OP_SETMODE 0x03 - -#define SDRAM_PAD_CTRL_WR_EN 0x80000000 -#define SDRAM_PAD_CTRL_TUNE_EN 0x00010000 -#define SDRAM_PAD_CTRL_DRVN_MASK 0x0000003f -#define SDRAM_PAD_CTRL_DRVP_MASK 0x00000fc0 - -/* - * For Guideline MEM-3 - Drive Strength value - */ - -#define DDR1_PAD_STRENGTH_DEFAULT 0x00001000 -#define SDRAM_PAD_CTRL_DRV_STR_MASK 0x00003000 - -/* - * For Guideline MEM-4 - DQS Reference Delay Tuning - */ - -#define MSAR_ARMDDRCLCK_MASK 0x000000f0 -#define MSAR_ARMDDRCLCK_H_MASK 0x00000100 - -#define MSAR_ARMDDRCLCK_333_167 0x00000000 -#define MSAR_ARMDDRCLCK_500_167 0x00000030 -#define MSAR_ARMDDRCLCK_667_167 0x00000060 -#define MSAR_ARMDDRCLCK_400_200_1 0x000001E0 -#define MSAR_ARMDDRCLCK_400_200 0x00000010 -#define MSAR_ARMDDRCLCK_600_200 0x00000050 -#define MSAR_ARMDDRCLCK_800_200 0x00000070 - -#define FTDLL_DDR1_166MHZ 0x0047F001 - -#define FTDLL_DDR1_200MHZ 0x0044D001 - -/* - * Low-level init happens right after start.S has switched to SVC32, - * flushed and disabled caches and disabled MMU. We're still running - * from the boot chip select, so the first thing we should do is set - * up RAM for us to relocate into. - */ - -.globl lowlevel_init - -lowlevel_init: - - /* Use 'r4 as the base for internal register accesses */ - ldr r4, =ORION5X_REGS_PHY_BASE - - /* move internal registers from the default 0xD0000000 - * to their intended location, defined by SoC */ - ldr r3, =0xD0000000 - add r3, r3, #0x20000 - str r4, [r3, #0x80] - - /* Use R3 as the base for DRAM registers */ - add r3, r4, #0x01000 - - /*DDR SDRAM Initialization Control */ - ldr r6, =0x00000001 - str r6, [r3, #0x480] - - /* Use R3 as the base for PCI registers */ - add r3, r4, #0x31000 - - /* Disable arbiter */ - ldr r6, =0x00000030 - str r6, [r3, #0xd00] - - /* Use R3 as the base for DRAM registers */ - add r3, r4, #0x01000 - - /* set all dram windows to 0 */ - mov r6, #0 - str r6, [r3, #0x504] - str r6, [r3, #0x50C] - str r6, [r3, #0x514] - str r6, [r3, #0x51C] - - /* 1) Configure SDRAM */ - ldr r6, =SDRAM_CONFIG - str r6, [r3, #0x400] - - /* 2) Set SDRAM Control reg */ - ldr r6, =SDRAM_CONTROL - str r6, [r3, #0x404] - - /* 3) Write SDRAM address control register */ - ldr r6, =SDRAM_ADDR_CTRL - str r6, [r3, #0x410] - - /* 4) Write SDRAM bank 0 size register */ - ldr r6, =SDRAM_BANK0_SIZE - str r6, [r3, #0x504] - /* keep other banks disabled */ - - /* 5) Write SDRAM open pages control register */ - ldr r6, =SDRAM_OPEN_PAGE_EN - str r6, [r3, #0x414] - - /* 6) Write SDRAM timing Low register */ - ldr r6, =SDRAM_TIME_CTRL_LOW - str r6, [r3, #0x408] - - /* 7) Write SDRAM timing High register */ - ldr r6, =SDRAM_TIME_CTRL_HI - str r6, [r3, #0x40C] - - /* 8) Write SDRAM mode register */ - /* The CPU must not attempt to change the SDRAM Mode register setting */ - /* prior to DRAM controller completion of the DRAM initialization */ - /* sequence. To guarantee this restriction, it is recommended that */ - /* the CPU sets the SDRAM Operation register to NOP command, performs */ - /* read polling until the register is back in Normal operation value, */ - /* and then sets SDRAM Mode register to its new value. */ - - /* 8.1 write 'nop' to SDRAM operation */ - ldr r6, =SDRAM_OP_NOP - str r6, [r3, #0x418] - - /* 8.2 poll SDRAM operation until back in 'normal' mode. */ -1: - ldr r6, [r3, #0x418] - cmp r6, #0 - bne 1b - - /* 8.3 Now its safe to write new value to SDRAM Mode register */ - ldr r6, =SDRAM_MODE - str r6, [r3, #0x41C] - - /* 8.4 Set new mode */ - ldr r6, =SDRAM_OP_SETMODE - str r6, [r3, #0x418] - - /* 8.5 poll SDRAM operation until back in 'normal' mode. */ -2: - ldr r6, [r3, #0x418] - cmp r6, #0 - bne 2b - - /* DDR SDRAM Address/Control Pads Calibration */ - ldr r6, [r3, #0x4C0] - - /* Set Bit [31] to make the register writable */ - orr r6, r6, #SDRAM_PAD_CTRL_WR_EN - str r6, [r3, #0x4C0] - - bic r6, r6, #SDRAM_PAD_CTRL_WR_EN - bic r6, r6, #SDRAM_PAD_CTRL_TUNE_EN - bic r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK - bic r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK - - /* Get the final N locked value of driving strength [22:17] */ - mov r1, r6 - mov r1, r1, LSL #9 - mov r1, r1, LSR #26 /* r1[5:0] = r3[22:17] */ - orr r1, r1, r1, LSL #6 /* r1[11:6] = r1[5:0] */ - - /* Write to both bits [5:0] and bits [11:6] */ - orr r6, r6, r1 - str r6, [r3, #0x4C0] - - /* DDR SDRAM Data Pads Calibration */ - ldr r6, [r3, #0x4C4] - - /* Set Bit [31] to make the register writable */ - orr r6, r6, #SDRAM_PAD_CTRL_WR_EN - str r6, [r3, #0x4C4] - - bic r6, r6, #SDRAM_PAD_CTRL_WR_EN - bic r6, r6, #SDRAM_PAD_CTRL_TUNE_EN - bic r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK - bic r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK - - /* Get the final N locked value of driving strength [22:17] */ - mov r1, r6 - mov r1, r1, LSL #9 - mov r1, r1, LSR #26 - orr r1, r1, r1, LSL #6 /* r1[5:0] = r3[22:17] */ - - /* Write to both bits [5:0] and bits [11:6] */ - orr r6, r6, r1 - - str r6, [r3, #0x4C4] - - /* Implement Guideline (GL# MEM-3) Drive Strength Value */ - /* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0 */ - - ldr r1, =DDR1_PAD_STRENGTH_DEFAULT - - /* Enable writes to DDR SDRAM Addr/Ctrl Pads Calibration register */ - ldr r6, [r3, #0x4C0] - orr r6, r6, #SDRAM_PAD_CTRL_WR_EN - str r6, [r3, #0x4C0] - - /* Correct strength and disable writes again */ - bic r6, r6, #SDRAM_PAD_CTRL_WR_EN - bic r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK - orr r6, r6, r1 - str r6, [r3, #0x4C0] - - /* Enable writes to DDR SDRAM Data Pads Calibration register */ - ldr r6, [r3, #0x4C4] - orr r6, r6, #SDRAM_PAD_CTRL_WR_EN - str r6, [r3, #0x4C4] - - /* Correct strength and disable writes again */ - bic r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK - bic r6, r6, #SDRAM_PAD_CTRL_WR_EN - orr r6, r6, r1 - str r6, [r3, #0x4C4] - - /* Implement Guideline (GL# MEM-4) DQS Reference Delay Tuning */ - /* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0 */ - - /* Get the "sample on reset" register for the DDR frequancy */ - ldr r3, =0x10000 - ldr r6, [r3, #0x010] - ldr r1, =MSAR_ARMDDRCLCK_MASK - and r1, r6, r1 - - ldr r6, =FTDLL_DDR1_166MHZ - cmp r1, #MSAR_ARMDDRCLCK_333_167 - beq 3f - cmp r1, #MSAR_ARMDDRCLCK_500_167 - beq 3f - cmp r1, #MSAR_ARMDDRCLCK_667_167 - beq 3f - - ldr r6, =FTDLL_DDR1_200MHZ - cmp r1, #MSAR_ARMDDRCLCK_400_200_1 - beq 3f - cmp r1, #MSAR_ARMDDRCLCK_400_200 - beq 3f - cmp r1, #MSAR_ARMDDRCLCK_600_200 - beq 3f - cmp r1, #MSAR_ARMDDRCLCK_800_200 - beq 3f - - ldr r6, =0 - -3: - /* Use R3 as the base for DRAM registers */ - add r3, r4, #0x01000 - - ldr r2, [r3, #0x484] - orr r2, r2, r6 - str r2, [r3, #0x484] - - /* Return to U-boot via saved link register */ - mov pc, lr diff --git a/arch/arm/cpu/arm926ejs/orion5x/timer.c b/arch/arm/cpu/arm926ejs/orion5x/timer.c deleted file mode 100644 index ec4f6bee8e..0000000000 --- a/arch/arm/cpu/arm926ejs/orion5x/timer.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirkwood support which is - * Copyright (C) Marvell International Ltd. and its affiliates - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -#define UBOOT_CNTR 0 /* counter to use for uboot timer */ - -/* Timer reload and current value registers */ -struct orion5x_tmr_val { - u32 reload; /* Timer reload reg */ - u32 val; /* Timer value reg */ -}; - -/* Timer registers */ -struct orion5x_tmr_registers { - u32 ctrl; /* Timer control reg */ - u32 pad[3]; - struct orion5x_tmr_val tmr[2]; - u32 wdt_reload; - u32 wdt_val; -}; - -struct orion5x_tmr_registers *orion5x_tmr_regs = - (struct orion5x_tmr_registers *)ORION5X_TIMER_BASE; - -/* - * ARM Timers Registers Map - */ -#define CNTMR_CTRL_REG (&orion5x_tmr_regs->ctrl) -#define CNTMR_RELOAD_REG(tmrnum) (&orion5x_tmr_regs->tmr[tmrnum].reload) -#define CNTMR_VAL_REG(tmrnum) (&orion5x_tmr_regs->tmr[tmrnum].val) - -/* - * ARM Timers Control Register - * CPU_TIMERS_CTRL_REG (CTCR) - */ -#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) -#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) -#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) -#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) - -#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) -#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) -#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) -#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) - -/* - * ARM Timer\Watchdog Reload Register - * CNTMR_RELOAD_REG (TRR) - */ -#define TRG_ARM_TIMER_REL_OFFS 0 -#define TRG_ARM_TIMER_REL_MASK 0xffffffff - -/* - * ARM Timer\Watchdog Register - * CNTMR_VAL_REG (TVRG) - */ -#define TVR_ARM_TIMER_OFFS 0 -#define TVR_ARM_TIMER_MASK 0xffffffff -#define TVR_ARM_TIMER_MAX 0xffffffff -#define TIMER_LOAD_VAL 0xffffffff - -static inline ulong read_timer(void) -{ - return readl(CNTMR_VAL_REG(UBOOT_CNTR)) - / (CONFIG_SYS_TCLK / 1000); -} - -DECLARE_GLOBAL_DATA_PTR; - -#define timestamp gd->arch.tbl -#define lastdec gd->arch.lastinc - -ulong get_timer_masked(void) -{ - ulong now = read_timer(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + - (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; - } - lastdec = now; - - return timestamp; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -static inline ulong uboot_cntr_val(void) -{ - return readl(CNTMR_VAL_REG(UBOOT_CNTR)); -} - -void __udelay(unsigned long usec) -{ - uint current; - ulong delayticks; - - current = uboot_cntr_val(); - delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); - - if (current < delayticks) { - delayticks -= current; - while (uboot_cntr_val() < current) - ; - while ((TIMER_LOAD_VAL - delayticks) < uboot_cntr_val()) - ; - } else { - while (uboot_cntr_val() > (current - delayticks)) - ; - } -} - -/* - * init the counter - */ -int timer_init(void) -{ - unsigned int cntmrctrl; - - /* load value into timer */ - writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); - writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); - - /* enable timer in auto reload mode */ - cntmrctrl = readl(CNTMR_CTRL_REG); - cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); - cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); - writel(cntmrctrl, CNTMR_CTRL_REG); - return 0; -} - -void timer_init_r(void) -{ - /* init the timestamp and lastdec value */ - lastdec = read_timer(); - timestamp = 0; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - return (ulong)CONFIG_SYS_HZ; -} diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig new file mode 100644 index 0000000000..5a542629c7 --- /dev/null +++ b/arch/arm/mach-orion5x/Kconfig @@ -0,0 +1,16 @@ +if ORION5X + +choice + prompt "Marvell Orion board select" + +config TARGET_EDMINIV2 + bool "LaCie Ethernet Disk mini V2" + +endchoice + +config SYS_SOC + default "orion5x" + +source "board/LaCie/edminiv2/Kconfig" + +endif diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile new file mode 100644 index 0000000000..546ebcb52e --- /dev/null +++ b/arch/arm/mach-orion5x/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2010 Albert ARIBAUD +# +# Based on original Kirkwood support which is +# (C) Copyright 2009 +# Marvell Semiconductor +# Written-by: Prafulla Wadaskar +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o +obj-y += dram.o +obj-y += timer.o + +ifndef CONFIG_SKIP_LOWLEVEL_INIT +obj-y += lowlevel_init.o +endif diff --git a/arch/arm/mach-orion5x/cpu.c b/arch/arm/mach-orion5x/cpu.c new file mode 100644 index 0000000000..f88db3b1f9 --- /dev/null +++ b/arch/arm/mach-orion5x/cpu.c @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirkwood support which is + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#define BUFLEN 16 + +void reset_cpu(unsigned long ignored) +{ + struct orion5x_cpu_registers *cpureg = + (struct orion5x_cpu_registers *)ORION5X_CPU_REG_BASE; + + writel(readl(&cpureg->rstoutn_mask) | (1 << 2), + &cpureg->rstoutn_mask); + writel(readl(&cpureg->sys_soft_rst) | 1, + &cpureg->sys_soft_rst); + while (1) + ; +} + +/* + * Compute Window Size field value from size expressed in bytes + * Used with the Base register to set the address window size and location. + * Must be programmed from LSB to MSB as sequence of ones followed by + * sequence of zeros. The number of ones specifies the size of the window in + * 64 KiB granularity (e.g., a value of 0x00FF specifies 256 = 16 MiB). + * NOTES: + * 1) A sizeval equal to 0x0 specifies 4 GiB. + * 2) A return value of 0x0 specifies 64 KiB. + */ +unsigned int orion5x_winctrl_calcsize(unsigned int sizeval) +{ + /* + * Calculate the number of 64 KiB blocks needed minus one (rounding up). + * For sizeval > 0 this is equivalent to: + * sizeval = (u32) ceil((double) sizeval / 65536.0) - 1 + */ + sizeval = (sizeval - 1) >> 16; + + /* + * Propagate 'one' bits to the right by 'oring' them. + * We need only treat bits 15-0. + */ + sizeval |= sizeval >> 1; /* 'Or' bit 15 onto bit 14 */ + sizeval |= sizeval >> 2; /* 'Or' bits 15-14 onto bits 13-12 */ + sizeval |= sizeval >> 4; /* 'Or' bits 15-12 onto bits 11-8 */ + sizeval |= sizeval >> 8; /* 'Or' bits 15-8 onto bits 7-0*/ + + return sizeval; +} + +/* + * orion5x_config_adr_windows - Configure address Windows + * + * There are 8 address windows supported by Orion5x Soc to addess different + * devices. Each window can be configured for size, BAR and remap addr + * Below configuration is standard for most of the cases + * + * If remap function not used, remap_lo must be set as base + * + * NOTES: + * + * 1) in order to avoid windows with inconsistent control and base values + * (which could prevent access to BOOTCS and hence execution from FLASH) + * always disable window before writing the base value then reenable it + * by writing the control value. + * + * 2) in order to avoid losing access to BOOTCS when disabling window 7, + * first configure window 6 for BOOTCS, then configure window 7 for BOOTCS, + * then configure windows 6 for its own target. + * + * Reference Documentation: + * Mbus-L to Mbus Bridge Registers Configuration. + * (Sec 25.1 and 25.3 of Datasheet) + */ +int orion5x_config_adr_windows(void) +{ + struct orion5x_win_registers *winregs = + (struct orion5x_win_registers *)ORION5X_CPU_WIN_BASE; + +/* Disable window 0, configure it for its intended target, enable it. */ + writel(0, &winregs[0].ctrl); + writel(ORION5X_ADR_PCIE_MEM, &winregs[0].base); + writel(ORION5X_ADR_PCIE_MEM_REMAP_LO, &winregs[0].remap_lo); + writel(ORION5X_ADR_PCIE_MEM_REMAP_HI, &winregs[0].remap_hi); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_MEM, + ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_MEM, + ORION5X_WIN_ENABLE), &winregs[0].ctrl); +/* Disable window 1, configure it for its intended target, enable it. */ + writel(0, &winregs[1].ctrl); + writel(ORION5X_ADR_PCIE_IO, &winregs[1].base); + writel(ORION5X_ADR_PCIE_IO_REMAP_LO, &winregs[1].remap_lo); + writel(ORION5X_ADR_PCIE_IO_REMAP_HI, &winregs[1].remap_hi); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCIE_IO, + ORION5X_TARGET_PCIE, ORION5X_ATTR_PCIE_IO, + ORION5X_WIN_ENABLE), &winregs[1].ctrl); +/* Disable window 2, configure it for its intended target, enable it. */ + writel(0, &winregs[2].ctrl); + writel(ORION5X_ADR_PCI_MEM, &winregs[2].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_MEM, + ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_MEM, + ORION5X_WIN_ENABLE), &winregs[2].ctrl); +/* Disable window 3, configure it for its intended target, enable it. */ + writel(0, &winregs[3].ctrl); + writel(ORION5X_ADR_PCI_IO, &winregs[3].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_PCI_IO, + ORION5X_TARGET_PCI, ORION5X_ATTR_PCI_IO, + ORION5X_WIN_ENABLE), &winregs[3].ctrl); +/* Disable window 4, configure it for its intended target, enable it. */ + writel(0, &winregs[4].ctrl); + writel(ORION5X_ADR_DEV_CS0, &winregs[4].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS0, + ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS0, + ORION5X_WIN_ENABLE), &winregs[4].ctrl); +/* Disable window 5, configure it for its intended target, enable it. */ + writel(0, &winregs[5].ctrl); + writel(ORION5X_ADR_DEV_CS1, &winregs[5].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS1, + ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS1, + ORION5X_WIN_ENABLE), &winregs[5].ctrl); +/* Disable window 6, configure it for FLASH, enable it. */ + writel(0, &winregs[6].ctrl); + writel(ORION5X_ADR_BOOTROM, &winregs[6].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, + ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, + ORION5X_WIN_ENABLE), &winregs[6].ctrl); +/* Disable window 7, configure it for FLASH, enable it. */ + writel(0, &winregs[7].ctrl); + writel(ORION5X_ADR_BOOTROM, &winregs[7].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_BOOTROM, + ORION5X_TARGET_DEVICE, ORION5X_ATTR_BOOTROM, + ORION5X_WIN_ENABLE), &winregs[7].ctrl); +/* Disable window 6, configure it for its intended target, enable it. */ + writel(0, &winregs[6].ctrl); + writel(ORION5X_ADR_DEV_CS2, &winregs[6].base); + writel(ORION5X_CPU_WIN_CTRL_DATA(ORION5X_SZ_DEV_CS2, + ORION5X_TARGET_DEVICE, ORION5X_ATTR_DEV_CS2, + ORION5X_WIN_ENABLE), &winregs[6].ctrl); + + return 0; +} + +/* + * Orion5x identification is done through PCIE space. + */ + +u32 orion5x_device_id(void) +{ + return readl(PCIE_DEV_ID_OFF) >> 16; +} + +u32 orion5x_device_rev(void) +{ + return readl(PCIE_DEV_REV_OFF) & 0xff; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) + +/* Display device and revision IDs. + * This function must cover all known device/revision + * combinations, not only the one for which u-boot is + * compiled; this way, one can identify actual HW in + * case of a mismatch. + */ +int print_cpuinfo(void) +{ + char dev_str[7]; /* room enough for 0x0000 plus null byte */ + char rev_str[5]; /* room enough for 0x00 plus null byte */ + char *dev_name = NULL; + char *rev_name = NULL; + + u32 dev = orion5x_device_id(); + u32 rev = orion5x_device_rev(); + + if (dev == MV88F5181_DEV_ID) { + dev_name = "MV88F5181"; + if (rev == MV88F5181_REV_B1) + rev_name = "B1"; + else if (rev == MV88F5181L_REV_A1) { + dev_name = "MV88F5181L"; + rev_name = "A1"; + } else if (rev == MV88F5181L_REV_A0) { + dev_name = "MV88F5181L"; + rev_name = "A0"; + } + } else if (dev == MV88F5182_DEV_ID) { + dev_name = "MV88F5182"; + if (rev == MV88F5182_REV_A2) + rev_name = "A2"; + } else if (dev == MV88F5281_DEV_ID) { + dev_name = "MV88F5281"; + if (rev == MV88F5281_REV_D2) + rev_name = "D2"; + else if (rev == MV88F5281_REV_D1) + rev_name = "D1"; + else if (rev == MV88F5281_REV_D0) + rev_name = "D0"; + } else if (dev == MV88F6183_DEV_ID) { + dev_name = "MV88F6183"; + if (rev == MV88F6183_REV_B0) + rev_name = "B0"; + } + if (dev_name == NULL) { + sprintf(dev_str, "0x%04x", dev); + dev_name = dev_str; + } + if (rev_name == NULL) { + sprintf(rev_str, "0x%02x", rev); + rev_name = rev_str; + } + + printf("SoC: Orion5x %s-%s\n", dev_name, rev_name); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + /* Enable and invalidate L2 cache in write through mode */ + invalidate_l2_cache(); + + orion5x_config_adr_windows(); + + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + u32 temp; + + /*CPU streaming & write allocate */ + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 28); /* disable wr alloc */ + writefr_extra_feature_reg(temp); + + temp = readfr_extra_feature_reg(); + temp &= ~(1 << 29); /* streaming disabled */ + writefr_extra_feature_reg(temp); + + /* L2Cache settings */ + temp = readfr_extra_feature_reg(); + /* Disable L2C pre fetch - Set bit 24 */ + temp |= (1 << 24); + /* enable L2C - Set bit 22 */ + temp |= (1 << 22); + writefr_extra_feature_reg(temp); + + icache_enable(); + /* Change reset vector to address 0x0 */ + temp = get_cr(); + set_cr(temp & ~CR_V); + + /* Set CPIOs and MPPs - values provided by board + include file */ + writel(ORION5X_MPP0_7, ORION5X_MPP_BASE+0x00); + writel(ORION5X_MPP8_15, ORION5X_MPP_BASE+0x04); + writel(ORION5X_MPP16_23, ORION5X_MPP_BASE+0x50); + writel(ORION5X_GPIO_OUT_VALUE, ORION5X_GPIO_BASE+0x00); + writel(ORION5X_GPIO_OUT_ENABLE, ORION5X_GPIO_BASE+0x04); + writel(ORION5X_GPIO_IN_POLARITY, ORION5X_GPIO_BASE+0x0c); + + /* initialize timer */ + timer_init_r(); + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_MVGBE +int cpu_eth_init(bd_t *bis) +{ + mvgbe_initialize(bis); + return 0; +} +#endif diff --git a/arch/arm/mach-orion5x/dram.c b/arch/arm/mach-orion5x/dram.c new file mode 100644 index 0000000000..9ed93d25bc --- /dev/null +++ b/arch/arm/mach-orion5x/dram.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirkwood support which is + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * orion5x_sdram_bar - reads SDRAM Base Address Register + */ +u32 orion5x_sdram_bar(enum memory_bank bank) +{ + struct orion5x_ddr_addr_decode_registers *winregs = + (struct orion5x_ddr_addr_decode_registers *) + ORION5X_DRAM_BASE; + + u32 result = 0; + u32 enable = 0x01 & winregs[bank].size; + + if ((!enable) || (bank > BANK3)) + return 0; + + result = winregs[bank].base; + return result; +} +int dram_init (void) +{ + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size( + (long *) orion5x_sdram_bar(0), + CONFIG_MAX_RAM_BANK_SIZE); + return 0; +} + +void dram_init_banksize (void) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = orion5x_sdram_bar(i); + gd->bd->bi_dram[i].size = get_ram_size( + (long *) (gd->bd->bi_dram[i].start), + CONFIG_MAX_RAM_BANK_SIZE); + } +} diff --git a/arch/arm/mach-orion5x/lowlevel_init.S b/arch/arm/mach-orion5x/lowlevel_init.S new file mode 100644 index 0000000000..4dacc296e4 --- /dev/null +++ b/arch/arm/mach-orion5x/lowlevel_init.S @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include "asm/arch/orion5x.h" + +/* + * Configuration values for SDRAM access setup + */ + +#define SDRAM_CONFIG 0x3148400 +#define SDRAM_MODE 0x62 +#define SDRAM_CONTROL 0x4041000 +#define SDRAM_TIME_CTRL_LOW 0x11602220 +#define SDRAM_TIME_CTRL_HI 0x40c +#define SDRAM_OPEN_PAGE_EN 0x0 +/* DDR 1 2x 32M NANYA NT5DS16M16CS-6K ==> 64MB */ +#define SDRAM_BANK0_SIZE 0x3ff0001 +#define SDRAM_ADDR_CTRL 0x10 + +#define SDRAM_OP_NOP 0x05 +#define SDRAM_OP_SETMODE 0x03 + +#define SDRAM_PAD_CTRL_WR_EN 0x80000000 +#define SDRAM_PAD_CTRL_TUNE_EN 0x00010000 +#define SDRAM_PAD_CTRL_DRVN_MASK 0x0000003f +#define SDRAM_PAD_CTRL_DRVP_MASK 0x00000fc0 + +/* + * For Guideline MEM-3 - Drive Strength value + */ + +#define DDR1_PAD_STRENGTH_DEFAULT 0x00001000 +#define SDRAM_PAD_CTRL_DRV_STR_MASK 0x00003000 + +/* + * For Guideline MEM-4 - DQS Reference Delay Tuning + */ + +#define MSAR_ARMDDRCLCK_MASK 0x000000f0 +#define MSAR_ARMDDRCLCK_H_MASK 0x00000100 + +#define MSAR_ARMDDRCLCK_333_167 0x00000000 +#define MSAR_ARMDDRCLCK_500_167 0x00000030 +#define MSAR_ARMDDRCLCK_667_167 0x00000060 +#define MSAR_ARMDDRCLCK_400_200_1 0x000001E0 +#define MSAR_ARMDDRCLCK_400_200 0x00000010 +#define MSAR_ARMDDRCLCK_600_200 0x00000050 +#define MSAR_ARMDDRCLCK_800_200 0x00000070 + +#define FTDLL_DDR1_166MHZ 0x0047F001 + +#define FTDLL_DDR1_200MHZ 0x0044D001 + +/* + * Low-level init happens right after start.S has switched to SVC32, + * flushed and disabled caches and disabled MMU. We're still running + * from the boot chip select, so the first thing we should do is set + * up RAM for us to relocate into. + */ + +.globl lowlevel_init + +lowlevel_init: + + /* Use 'r4 as the base for internal register accesses */ + ldr r4, =ORION5X_REGS_PHY_BASE + + /* move internal registers from the default 0xD0000000 + * to their intended location, defined by SoC */ + ldr r3, =0xD0000000 + add r3, r3, #0x20000 + str r4, [r3, #0x80] + + /* Use R3 as the base for DRAM registers */ + add r3, r4, #0x01000 + + /*DDR SDRAM Initialization Control */ + ldr r6, =0x00000001 + str r6, [r3, #0x480] + + /* Use R3 as the base for PCI registers */ + add r3, r4, #0x31000 + + /* Disable arbiter */ + ldr r6, =0x00000030 + str r6, [r3, #0xd00] + + /* Use R3 as the base for DRAM registers */ + add r3, r4, #0x01000 + + /* set all dram windows to 0 */ + mov r6, #0 + str r6, [r3, #0x504] + str r6, [r3, #0x50C] + str r6, [r3, #0x514] + str r6, [r3, #0x51C] + + /* 1) Configure SDRAM */ + ldr r6, =SDRAM_CONFIG + str r6, [r3, #0x400] + + /* 2) Set SDRAM Control reg */ + ldr r6, =SDRAM_CONTROL + str r6, [r3, #0x404] + + /* 3) Write SDRAM address control register */ + ldr r6, =SDRAM_ADDR_CTRL + str r6, [r3, #0x410] + + /* 4) Write SDRAM bank 0 size register */ + ldr r6, =SDRAM_BANK0_SIZE + str r6, [r3, #0x504] + /* keep other banks disabled */ + + /* 5) Write SDRAM open pages control register */ + ldr r6, =SDRAM_OPEN_PAGE_EN + str r6, [r3, #0x414] + + /* 6) Write SDRAM timing Low register */ + ldr r6, =SDRAM_TIME_CTRL_LOW + str r6, [r3, #0x408] + + /* 7) Write SDRAM timing High register */ + ldr r6, =SDRAM_TIME_CTRL_HI + str r6, [r3, #0x40C] + + /* 8) Write SDRAM mode register */ + /* The CPU must not attempt to change the SDRAM Mode register setting */ + /* prior to DRAM controller completion of the DRAM initialization */ + /* sequence. To guarantee this restriction, it is recommended that */ + /* the CPU sets the SDRAM Operation register to NOP command, performs */ + /* read polling until the register is back in Normal operation value, */ + /* and then sets SDRAM Mode register to its new value. */ + + /* 8.1 write 'nop' to SDRAM operation */ + ldr r6, =SDRAM_OP_NOP + str r6, [r3, #0x418] + + /* 8.2 poll SDRAM operation until back in 'normal' mode. */ +1: + ldr r6, [r3, #0x418] + cmp r6, #0 + bne 1b + + /* 8.3 Now its safe to write new value to SDRAM Mode register */ + ldr r6, =SDRAM_MODE + str r6, [r3, #0x41C] + + /* 8.4 Set new mode */ + ldr r6, =SDRAM_OP_SETMODE + str r6, [r3, #0x418] + + /* 8.5 poll SDRAM operation until back in 'normal' mode. */ +2: + ldr r6, [r3, #0x418] + cmp r6, #0 + bne 2b + + /* DDR SDRAM Address/Control Pads Calibration */ + ldr r6, [r3, #0x4C0] + + /* Set Bit [31] to make the register writable */ + orr r6, r6, #SDRAM_PAD_CTRL_WR_EN + str r6, [r3, #0x4C0] + + bic r6, r6, #SDRAM_PAD_CTRL_WR_EN + bic r6, r6, #SDRAM_PAD_CTRL_TUNE_EN + bic r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK + bic r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK + + /* Get the final N locked value of driving strength [22:17] */ + mov r1, r6 + mov r1, r1, LSL #9 + mov r1, r1, LSR #26 /* r1[5:0] = r3[22:17] */ + orr r1, r1, r1, LSL #6 /* r1[11:6] = r1[5:0] */ + + /* Write to both bits [5:0] and bits [11:6] */ + orr r6, r6, r1 + str r6, [r3, #0x4C0] + + /* DDR SDRAM Data Pads Calibration */ + ldr r6, [r3, #0x4C4] + + /* Set Bit [31] to make the register writable */ + orr r6, r6, #SDRAM_PAD_CTRL_WR_EN + str r6, [r3, #0x4C4] + + bic r6, r6, #SDRAM_PAD_CTRL_WR_EN + bic r6, r6, #SDRAM_PAD_CTRL_TUNE_EN + bic r6, r6, #SDRAM_PAD_CTRL_DRVN_MASK + bic r6, r6, #SDRAM_PAD_CTRL_DRVP_MASK + + /* Get the final N locked value of driving strength [22:17] */ + mov r1, r6 + mov r1, r1, LSL #9 + mov r1, r1, LSR #26 + orr r1, r1, r1, LSL #6 /* r1[5:0] = r3[22:17] */ + + /* Write to both bits [5:0] and bits [11:6] */ + orr r6, r6, r1 + + str r6, [r3, #0x4C4] + + /* Implement Guideline (GL# MEM-3) Drive Strength Value */ + /* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0 */ + + ldr r1, =DDR1_PAD_STRENGTH_DEFAULT + + /* Enable writes to DDR SDRAM Addr/Ctrl Pads Calibration register */ + ldr r6, [r3, #0x4C0] + orr r6, r6, #SDRAM_PAD_CTRL_WR_EN + str r6, [r3, #0x4C0] + + /* Correct strength and disable writes again */ + bic r6, r6, #SDRAM_PAD_CTRL_WR_EN + bic r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK + orr r6, r6, r1 + str r6, [r3, #0x4C0] + + /* Enable writes to DDR SDRAM Data Pads Calibration register */ + ldr r6, [r3, #0x4C4] + orr r6, r6, #SDRAM_PAD_CTRL_WR_EN + str r6, [r3, #0x4C4] + + /* Correct strength and disable writes again */ + bic r6, r6, #SDRAM_PAD_CTRL_DRV_STR_MASK + bic r6, r6, #SDRAM_PAD_CTRL_WR_EN + orr r6, r6, r1 + str r6, [r3, #0x4C4] + + /* Implement Guideline (GL# MEM-4) DQS Reference Delay Tuning */ + /* Relevant for: 88F5181-A1/B0/B1 and 88F5281-A0/B0 */ + + /* Get the "sample on reset" register for the DDR frequancy */ + ldr r3, =0x10000 + ldr r6, [r3, #0x010] + ldr r1, =MSAR_ARMDDRCLCK_MASK + and r1, r6, r1 + + ldr r6, =FTDLL_DDR1_166MHZ + cmp r1, #MSAR_ARMDDRCLCK_333_167 + beq 3f + cmp r1, #MSAR_ARMDDRCLCK_500_167 + beq 3f + cmp r1, #MSAR_ARMDDRCLCK_667_167 + beq 3f + + ldr r6, =FTDLL_DDR1_200MHZ + cmp r1, #MSAR_ARMDDRCLCK_400_200_1 + beq 3f + cmp r1, #MSAR_ARMDDRCLCK_400_200 + beq 3f + cmp r1, #MSAR_ARMDDRCLCK_600_200 + beq 3f + cmp r1, #MSAR_ARMDDRCLCK_800_200 + beq 3f + + ldr r6, =0 + +3: + /* Use R3 as the base for DRAM registers */ + add r3, r4, #0x01000 + + ldr r2, [r3, #0x484] + orr r2, r2, r6 + str r2, [r3, #0x484] + + /* Return to U-boot via saved link register */ + mov pc, lr diff --git a/arch/arm/mach-orion5x/timer.c b/arch/arm/mach-orion5x/timer.c new file mode 100644 index 0000000000..ec4f6bee8e --- /dev/null +++ b/arch/arm/mach-orion5x/timer.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirkwood support which is + * Copyright (C) Marvell International Ltd. and its affiliates + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +#define UBOOT_CNTR 0 /* counter to use for uboot timer */ + +/* Timer reload and current value registers */ +struct orion5x_tmr_val { + u32 reload; /* Timer reload reg */ + u32 val; /* Timer value reg */ +}; + +/* Timer registers */ +struct orion5x_tmr_registers { + u32 ctrl; /* Timer control reg */ + u32 pad[3]; + struct orion5x_tmr_val tmr[2]; + u32 wdt_reload; + u32 wdt_val; +}; + +struct orion5x_tmr_registers *orion5x_tmr_regs = + (struct orion5x_tmr_registers *)ORION5X_TIMER_BASE; + +/* + * ARM Timers Registers Map + */ +#define CNTMR_CTRL_REG (&orion5x_tmr_regs->ctrl) +#define CNTMR_RELOAD_REG(tmrnum) (&orion5x_tmr_regs->tmr[tmrnum].reload) +#define CNTMR_VAL_REG(tmrnum) (&orion5x_tmr_regs->tmr[tmrnum].val) + +/* + * ARM Timers Control Register + * CPU_TIMERS_CTRL_REG (CTCR) + */ +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS) +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr)) + +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) (1 << 1) +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) + +/* + * ARM Timer\Watchdog Reload Register + * CNTMR_RELOAD_REG (TRR) + */ +#define TRG_ARM_TIMER_REL_OFFS 0 +#define TRG_ARM_TIMER_REL_MASK 0xffffffff + +/* + * ARM Timer\Watchdog Register + * CNTMR_VAL_REG (TVRG) + */ +#define TVR_ARM_TIMER_OFFS 0 +#define TVR_ARM_TIMER_MASK 0xffffffff +#define TVR_ARM_TIMER_MAX 0xffffffff +#define TIMER_LOAD_VAL 0xffffffff + +static inline ulong read_timer(void) +{ + return readl(CNTMR_VAL_REG(UBOOT_CNTR)) + / (CONFIG_SYS_TCLK / 1000); +} + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +ulong get_timer_masked(void) +{ + ulong now = read_timer(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; + } + lastdec = now; + + return timestamp; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +static inline ulong uboot_cntr_val(void) +{ + return readl(CNTMR_VAL_REG(UBOOT_CNTR)); +} + +void __udelay(unsigned long usec) +{ + uint current; + ulong delayticks; + + current = uboot_cntr_val(); + delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); + + if (current < delayticks) { + delayticks -= current; + while (uboot_cntr_val() < current) + ; + while ((TIMER_LOAD_VAL - delayticks) < uboot_cntr_val()) + ; + } else { + while (uboot_cntr_val() > (current - delayticks)) + ; + } +} + +/* + * init the counter + */ +int timer_init(void) +{ + unsigned int cntmrctrl; + + /* load value into timer */ + writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + + /* enable timer in auto reload mode */ + cntmrctrl = readl(CNTMR_CTRL_REG); + cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR); + cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR); + writel(cntmrctrl, CNTMR_CTRL_REG); + return 0; +} + +void timer_init_r(void) +{ + /* init the timestamp and lastdec value */ + lastdec = read_timer(); + timestamp = 0; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return (ulong)CONFIG_SYS_HZ; +} -- cgit From 63637a484614490685b68a70bdf93b435c063363 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:10 +0900 Subject: ARM: versatile: move SoC sources to mach-versatile Move arch/arm/cpu/arm926ejs/versatile/* -> arch/arm/mach-versatile/* Signed-off-by: Masahiro Yamada --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 1 + arch/arm/cpu/arm926ejs/Makefile | 1 - arch/arm/cpu/arm926ejs/versatile/Kconfig | 15 -------- arch/arm/cpu/arm926ejs/versatile/Makefile | 9 ----- arch/arm/cpu/arm926ejs/versatile/reset.S | 29 -------------- arch/arm/cpu/arm926ejs/versatile/timer.c | 64 ------------------------------- arch/arm/mach-versatile/Kconfig | 15 ++++++++ arch/arm/mach-versatile/Makefile | 9 +++++ arch/arm/mach-versatile/reset.S | 29 ++++++++++++++ arch/arm/mach-versatile/timer.c | 64 +++++++++++++++++++++++++++++++ 11 files changed, 119 insertions(+), 119 deletions(-) delete mode 100644 arch/arm/cpu/arm926ejs/versatile/Kconfig delete mode 100644 arch/arm/cpu/arm926ejs/versatile/Makefile delete mode 100644 arch/arm/cpu/arm926ejs/versatile/reset.S delete mode 100644 arch/arm/cpu/arm926ejs/versatile/timer.c create mode 100644 arch/arm/mach-versatile/Kconfig create mode 100644 arch/arm/mach-versatile/Makefile create mode 100644 arch/arm/mach-versatile/reset.S create mode 100644 arch/arm/mach-versatile/timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 038961c5fd..9302b2a0b6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -746,7 +746,7 @@ source "arch/arm/mach-tegra/Kconfig" source "arch/arm/cpu/armv7/uniphier/Kconfig" -source "arch/arm/cpu/arm926ejs/versatile/Kconfig" +source "arch/arm/mach-versatile/Kconfig" source "arch/arm/cpu/armv7/zynq/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6bcf8ec715..0699a4d472 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -14,6 +14,7 @@ machine-$(CONFIG_ARCH_NOMADIK) += nomadik # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X machine-$(CONFIG_ORION5X) += orion5x machine-$(CONFIG_TEGRA) += tegra +machine-$(CONFIG_ARCH_VERSATILE) += versatile machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index 3cb741db1d..f5944cc965 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -22,4 +22,3 @@ obj-$(CONFIG_MX27) += mx27/ obj-$(if $(filter mxs,$(SOC)),y) += mxs/ obj-$(CONFIG_PANTHEON) += pantheon/ obj-$(if $(filter spear,$(SOC)),y) += spear/ -obj-$(CONFIG_ARCH_VERSATILE) += versatile/ diff --git a/arch/arm/cpu/arm926ejs/versatile/Kconfig b/arch/arm/cpu/arm926ejs/versatile/Kconfig deleted file mode 100644 index d2e76f4afc..0000000000 --- a/arch/arm/cpu/arm926ejs/versatile/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -if ARCH_VERSATILE - -config SYS_BOARD - default "versatile" - -config SYS_VENDOR - default "armltd" - -config SYS_SOC - default "versatile" - -config SYS_CONFIG_NAME - default "versatile" - -endif diff --git a/arch/arm/cpu/arm926ejs/versatile/Makefile b/arch/arm/cpu/arm926ejs/versatile/Makefile deleted file mode 100644 index 907f5161a8..0000000000 --- a/arch/arm/cpu/arm926ejs/versatile/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = timer.o -obj-y += reset.o diff --git a/arch/arm/cpu/arm926ejs/versatile/reset.S b/arch/arm/cpu/arm926ejs/versatile/reset.S deleted file mode 100644 index 1c557b0d91..0000000000 --- a/arch/arm/cpu/arm926ejs/versatile/reset.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * armboot - Startup Code for ARM926EJS CPU-core - * - * Copyright (c) 2003 Texas Instruments - * - * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ - * - * Copyright (c) 2001 Marius Gröger - * Copyright (c) 2002 Alex Züpke - * Copyright (c) 2002 Gary Jennejohn - * Copyright (c) 2003 Richard Woodruff - * Copyright (c) 2003 Kshitij - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - .align 5 -.globl reset_cpu -reset_cpu: - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strh r3, [r1] /* clear it */ - mov r3, #0x8 - strh r3, [r1] /* force dsp+arm reset */ -_loop_forever: - b _loop_forever - -rstctl1: - .word 0xfffece10 diff --git a/arch/arm/cpu/arm926ejs/versatile/timer.c b/arch/arm/cpu/arm926ejs/versatile/timer.c deleted file mode 100644 index 5d694d85ef..0000000000 --- a/arch/arm/cpu/arm926ejs/versatile/timer.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#define TIMER_ENABLE (1 << 7) -#define TIMER_MODE_MSK (1 << 6) -#define TIMER_MODE_FR (0 << 6) -#define TIMER_MODE_PD (1 << 6) - -#define TIMER_INT_EN (1 << 5) -#define TIMER_PRS_MSK (3 << 2) -#define TIMER_PRS_8S (1 << 3) -#define TIMER_SIZE_MSK (1 << 2) -#define TIMER_ONE_SHT (1 << 0) - -int timer_init (void) -{ - ulong tmr_ctrl_val; - - /* 1st disable the Timer */ - tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); - tmr_ctrl_val &= ~TIMER_ENABLE; - *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; - - /* - * The Timer Control Register has one Undefined/Shouldn't Use Bit - * So we should do read/modify/write Operation - */ - - /* - * Timer Mode : Free Running - * Interrupt : Disabled - * Prescale : 8 Stage, Clk/256 - * Tmr Siz : 16 Bit Counter - * Tmr in Wrapping Mode - */ - tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); - tmr_ctrl_val &= ~(TIMER_MODE_MSK | TIMER_INT_EN | TIMER_PRS_MSK | TIMER_SIZE_MSK | TIMER_ONE_SHT ); - tmr_ctrl_val |= (TIMER_ENABLE | TIMER_PRS_8S); - - *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; - - return 0; -} - diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig new file mode 100644 index 0000000000..d2e76f4afc --- /dev/null +++ b/arch/arm/mach-versatile/Kconfig @@ -0,0 +1,15 @@ +if ARCH_VERSATILE + +config SYS_BOARD + default "versatile" + +config SYS_VENDOR + default "armltd" + +config SYS_SOC + default "versatile" + +config SYS_CONFIG_NAME + default "versatile" + +endif diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile new file mode 100644 index 0000000000..907f5161a8 --- /dev/null +++ b/arch/arm/mach-versatile/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = timer.o +obj-y += reset.o diff --git a/arch/arm/mach-versatile/reset.S b/arch/arm/mach-versatile/reset.S new file mode 100644 index 0000000000..1c557b0d91 --- /dev/null +++ b/arch/arm/mach-versatile/reset.S @@ -0,0 +1,29 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * Copyright (c) 2002 Gary Jennejohn + * Copyright (c) 2003 Richard Woodruff + * Copyright (c) 2003 Kshitij + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10 diff --git a/arch/arm/mach-versatile/timer.c b/arch/arm/mach-versatile/timer.c new file mode 100644 index 0000000000..5d694d85ef --- /dev/null +++ b/arch/arm/mach-versatile/timer.c @@ -0,0 +1,64 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#define TIMER_ENABLE (1 << 7) +#define TIMER_MODE_MSK (1 << 6) +#define TIMER_MODE_FR (0 << 6) +#define TIMER_MODE_PD (1 << 6) + +#define TIMER_INT_EN (1 << 5) +#define TIMER_PRS_MSK (3 << 2) +#define TIMER_PRS_8S (1 << 3) +#define TIMER_SIZE_MSK (1 << 2) +#define TIMER_ONE_SHT (1 << 0) + +int timer_init (void) +{ + ulong tmr_ctrl_val; + + /* 1st disable the Timer */ + tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); + tmr_ctrl_val &= ~TIMER_ENABLE; + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; + + /* + * The Timer Control Register has one Undefined/Shouldn't Use Bit + * So we should do read/modify/write Operation + */ + + /* + * Timer Mode : Free Running + * Interrupt : Disabled + * Prescale : 8 Stage, Clk/256 + * Tmr Siz : 16 Bit Counter + * Tmr in Wrapping Mode + */ + tmr_ctrl_val = *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8); + tmr_ctrl_val &= ~(TIMER_MODE_MSK | TIMER_INT_EN | TIMER_PRS_MSK | TIMER_SIZE_MSK | TIMER_ONE_SHT ); + tmr_ctrl_val |= (TIMER_ENABLE | TIMER_PRS_8S); + + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 8) = tmr_ctrl_val; + + return 0; +} + -- cgit From 39a723452f430a7ef89b0ffa934b2d4312890076 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:11 +0900 Subject: ARM: keystone: move SoC sources to mach-keystone Move arch/arm/cpu/armv7/keystone/* -> arch/arm/mach-keystone/* Signed-off-by: Masahiro Yamada Cc: Tom Rini --- arch/arm/Kconfig | 2 +- arch/arm/Makefile | 1 + arch/arm/cpu/armv7/Makefile | 1 - arch/arm/cpu/armv7/keystone/Kconfig | 22 -- arch/arm/cpu/armv7/keystone/Makefile | 18 -- arch/arm/cpu/armv7/keystone/clock-k2e.c | 117 --------- arch/arm/cpu/armv7/keystone/clock-k2hk.c | 145 ----------- arch/arm/cpu/armv7/keystone/clock-k2l.c | 138 ----------- arch/arm/cpu/armv7/keystone/clock.c | 272 --------------------- arch/arm/cpu/armv7/keystone/cmd_clock.c | 135 ----------- arch/arm/cpu/armv7/keystone/cmd_ddr3.c | 248 ------------------- arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 ---------- arch/arm/cpu/armv7/keystone/ddr3.c | 404 ------------------------------- arch/arm/cpu/armv7/keystone/init.c | 151 ------------ arch/arm/cpu/armv7/keystone/keystone.c | 87 ------- arch/arm/cpu/armv7/keystone/msmc.c | 94 ------- arch/arm/cpu/armv7/keystone/psc.c | 227 ----------------- arch/arm/mach-keystone/Kconfig | 22 ++ arch/arm/mach-keystone/Makefile | 18 ++ arch/arm/mach-keystone/clock-k2e.c | 117 +++++++++ arch/arm/mach-keystone/clock-k2hk.c | 145 +++++++++++ arch/arm/mach-keystone/clock-k2l.c | 138 +++++++++++ arch/arm/mach-keystone/clock.c | 272 +++++++++++++++++++++ arch/arm/mach-keystone/cmd_clock.c | 135 +++++++++++ arch/arm/mach-keystone/cmd_ddr3.c | 248 +++++++++++++++++++ arch/arm/mach-keystone/cmd_mon.c | 131 ++++++++++ arch/arm/mach-keystone/ddr3.c | 404 +++++++++++++++++++++++++++++++ arch/arm/mach-keystone/init.c | 151 ++++++++++++ arch/arm/mach-keystone/keystone.c | 87 +++++++ arch/arm/mach-keystone/msmc.c | 94 +++++++ arch/arm/mach-keystone/psc.c | 227 +++++++++++++++++ 31 files changed, 2191 insertions(+), 2191 deletions(-) delete mode 100644 arch/arm/cpu/armv7/keystone/Kconfig delete mode 100644 arch/arm/cpu/armv7/keystone/Makefile delete mode 100644 arch/arm/cpu/armv7/keystone/clock-k2e.c delete mode 100644 arch/arm/cpu/armv7/keystone/clock-k2hk.c delete mode 100644 arch/arm/cpu/armv7/keystone/clock-k2l.c delete mode 100644 arch/arm/cpu/armv7/keystone/clock.c delete mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c delete mode 100644 arch/arm/cpu/armv7/keystone/cmd_ddr3.c delete mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c delete mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c delete mode 100644 arch/arm/cpu/armv7/keystone/init.c delete mode 100644 arch/arm/cpu/armv7/keystone/keystone.c delete mode 100644 arch/arm/cpu/armv7/keystone/msmc.c delete mode 100644 arch/arm/cpu/armv7/keystone/psc.c create mode 100644 arch/arm/mach-keystone/Kconfig create mode 100644 arch/arm/mach-keystone/Makefile create mode 100644 arch/arm/mach-keystone/clock-k2e.c create mode 100644 arch/arm/mach-keystone/clock-k2hk.c create mode 100644 arch/arm/mach-keystone/clock-k2l.c create mode 100644 arch/arm/mach-keystone/clock.c create mode 100644 arch/arm/mach-keystone/cmd_clock.c create mode 100644 arch/arm/mach-keystone/cmd_ddr3.c create mode 100644 arch/arm/mach-keystone/cmd_mon.c create mode 100644 arch/arm/mach-keystone/ddr3.c create mode 100644 arch/arm/mach-keystone/init.c create mode 100644 arch/arm/mach-keystone/keystone.c create mode 100644 arch/arm/mach-keystone/msmc.c create mode 100644 arch/arm/mach-keystone/psc.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9302b2a0b6..083823e8c4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -724,7 +724,7 @@ source "arch/arm/cpu/armv7/exynos/Kconfig" source "arch/arm/mach-highbank/Kconfig" -source "arch/arm/cpu/armv7/keystone/Kconfig" +source "arch/arm/mach-keystone/Kconfig" source "arch/arm/mach-kirkwood/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0699a4d472..678ac132aa 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -7,6 +7,7 @@ machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_DAVINCI) += davinci machine-$(CONFIG_ARCH_HIGHBANK) += highbank +machine-$(CONFIG_ARCH_KEYSTONE) += keystone # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD machine-$(CONFIG_KIRKWOOD) += kirkwood # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 29ba6e2125..1a76982d6e 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -43,7 +43,6 @@ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ obj-$(CONFIG_ARCH_EXYNOS) += exynos/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/ obj-$(if $(filter mx5,$(SOC)),y) += mx5/ obj-$(CONFIG_MX6) += mx6/ diff --git a/arch/arm/cpu/armv7/keystone/Kconfig b/arch/arm/cpu/armv7/keystone/Kconfig deleted file mode 100644 index 134ae87fe1..0000000000 --- a/arch/arm/cpu/armv7/keystone/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -if ARCH_KEYSTONE - -choice - prompt "TI Keystone board select" - -config TARGET_K2HK_EVM - bool "TI Keystone 2 Kepler/Hawking EVM" - -config TARGET_K2E_EVM - bool "TI Keystone 2 Edison EVM" - -config TARGET_K2L_EVM - bool "TI Keystone 2 Lamar EVM" - -endchoice - -config SYS_SOC - default "keystone" - -source "board/ti/ks2_evm/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile deleted file mode 100644 index ed030db2c8..0000000000 --- a/arch/arm/cpu/armv7/keystone/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# (C) Copyright 2012-2014 -# Texas Instruments Incorporated, -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += init.o -obj-y += psc.o -obj-y += clock.o -obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o -obj-$(CONFIG_SOC_K2E) += clock-k2e.o -obj-$(CONFIG_SOC_K2L) += clock-k2l.o -obj-y += cmd_clock.o -obj-y += cmd_mon.o -obj-y += msmc.o -obj-y += ddr3.o cmd_ddr3.o -obj-y += keystone.o diff --git a/arch/arm/cpu/armv7/keystone/clock-k2e.c b/arch/arm/cpu/armv7/keystone/clock-k2e.c deleted file mode 100644 index 31f66613ef..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2e.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Keystone2: get clk rate for K2E - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -const struct keystone_pll_regs keystone_pll_regs[] = { - [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, - [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, - [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, -}; - -int dev_speeds[] = { - SPD800, - SPD850, - SPD1000, - SPD1250, - SPD1350, - SPD1400, - SPD1500, - SPD1400, - SPD1350, - SPD1250, - SPD1000, - SPD850, - SPD800 -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c deleted file mode 100644 index 1591960795..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2hk.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Keystone2: get clk rate for K2HK - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -const struct keystone_pll_regs keystone_pll_regs[] = { - [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, - [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, - [TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1}, - [DDR3A_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, - [DDR3B_PLL] = {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1}, -}; - -int dev_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD800, - SPD800, - SPD800, - SPD800, - SPD800, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -int arm_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD800, - SPD1400, - SPD1350, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3A_PLL: - ret = external_clk[ddr3a_clk]; - reg = KS2_DDR3APLLCTL0; - break; - case DDR3B_PLL: - ret = external_clk[ddr3b_clk]; - reg = KS2_DDR3BPLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3a_pll_clk: return pll_freq_get(DDR3A_PLL); - case ddr3b_pll_clk: return pll_freq_get(DDR3B_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock-k2l.c b/arch/arm/cpu/armv7/keystone/clock-k2l.c deleted file mode 100644 index 1c5e4d54d8..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock-k2l.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Keystone2: get clk rate for K2L - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -const struct keystone_pll_regs keystone_pll_regs[] = { - [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, - [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, - [TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1}, - [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, -}; - -int dev_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD800, - SPD800, - SPD800, - SPD800, - SPD800, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -int arm_speeds[] = { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD800, - SPD1400, - SPD1350, - SPD1200, - SPD1000, - SPD800, - SPD800, - SPD800, -}; - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c deleted file mode 100644 index d13fbc1a4b..0000000000 --- a/arch/arm/cpu/armv7/keystone/clock.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Keystone2: pll initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define MAX_SPEEDS 13 - -static void wait_for_completion(const struct pll_init_data *data) -{ - int i; - for (i = 0; i < 100; i++) { - sdelay(450); - if ((pllctl_reg_read(data->pll, stat) & PLLSTAT_GO) == 0) - break; - } -} - -void init_pll(const struct pll_init_data *data) -{ - u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj; - - pllm = data->pll_m - 1; - plld = (data->pll_d - 1) & PLL_DIV_MASK; - pllod = (data->pll_od - 1) & PLL_CLKOD_MASK; - - if (data->pll == MAIN_PLL) { - /* The requered delay before main PLL configuration */ - sdelay(210000); - - tmp = pllctl_reg_read(data->pll, secctl); - - if (tmp & (PLLCTL_BYPASS)) { - setbits_le32(keystone_pll_regs[data->pll].reg1, - BIT(MAIN_ENSAT_OFFSET)); - - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | - PLLCTL_PLLENSRC); - sdelay(340); - - pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS); - pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN); - sdelay(21000); - - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN); - } else { - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | - PLLCTL_PLLENSRC); - sdelay(340); - } - - pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK); - - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLLM_MULT_HI_SMASK, (pllm << 6)); - - /* Set the BWADJ (12 bit field) */ - tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */ - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLL_BWADJ_LO_SMASK, - (tmp_ctl << PLL_BWADJ_LO_SHIFT)); - clrsetbits_le32(keystone_pll_regs[data->pll].reg1, - PLL_BWADJ_HI_MASK, - (tmp_ctl >> 8)); - - /* - * Set the pll divider (6 bit field) * - * PLLD[5:0] is located in MAINPLLCTL0 - */ - clrsetbits_le32(keystone_pll_regs[data->pll].reg0, - PLL_DIV_MASK, plld); - - /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */ - pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK, - (pllod << PLL_CLKOD_SHIFT)); - wait_for_completion(data); - - pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1); - pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2); - pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3); - pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4); - pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5); - - pllctl_reg_setbits(data->pll, alnctl, 0x1f); - - /* - * Set GOSET bit in PLLCMD to initiate the GO operation - * to change the divide - */ - pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO); - sdelay(1500); /* wait for the phase adj */ - wait_for_completion(data); - - /* Reset PLL */ - pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST); - sdelay(21000); /* Wait for a minimum of 7 us*/ - pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST); - sdelay(105000); /* Wait for PLL Lock time (min 50 us) */ - - pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS); - - tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN); - -#ifndef CONFIG_SOC_K2E - } else if (data->pll == TETRIS_PLL) { - bwadj = pllm >> 1; - /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ - setbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - /* - * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass) - * only applicable for Kepler - */ - clrbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); - /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */ - setbits_le32(keystone_pll_regs[data->pll].reg1 , - PLL_PLLRST | PLLCTL_ENSAT); - - /* - * 3 Program PLLM and PLLD in PLLCTL0 register - * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in - * PLLCTL1 register. BWADJ value must be set - * to ((PLLM + 1) >> 1) – 1) - */ - tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | - (pllm << 6) | - (plld & PLL_DIV_MASK) | - (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS; - __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); - - /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); - tmp &= ~(PLL_BWADJ_HI_MASK); - tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); - __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); - /* - * 5 Wait for at least 5 us based on the reference - * clock (PLL reset time) - */ - sdelay(21000); /* Wait for a minimum of 7 us*/ - - /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */ - clrbits_le32(keystone_pll_regs[data->pll].reg1, PLL_PLLRST); - /* - * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1) - * (PLL lock time) - */ - sdelay(105000); - /* 8 disable bypass */ - clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - /* - * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass) - * only applicable for Kepler - */ - setbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); -#endif - } else { - setbits_le32(keystone_pll_regs[data->pll].reg1, PLLCTL_ENSAT); - /* - * process keeps state of Bypass bit while programming - * all other DDR PLL settings - */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg0); - tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */ - - /* - * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0, - * bypass disabled - */ - bwadj = pllm >> 1; - tmp |= ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | - (pllm << PLL_MULT_SHIFT) | - (plld & PLL_DIV_MASK) | - (pllod << PLL_CLKOD_SHIFT); - __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); - - /* Set BWADJ[11:8] bits */ - tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); - tmp &= ~(PLL_BWADJ_HI_MASK); - tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); - - __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); - - /* Reset bit: bit 14 for both DDR3 & PASS PLL */ - tmp = PLL_PLLRST; - /* Set RESET bit = 1 */ - setbits_le32(keystone_pll_regs[data->pll].reg1, tmp); - /* Wait for a minimum of 7 us*/ - sdelay(21000); - /* Clear RESET bit */ - clrbits_le32(keystone_pll_regs[data->pll].reg1, tmp); - sdelay(105000); - - /* clear BYPASS (Enable PLL Mode) */ - clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); - sdelay(21000); /* Wait for a minimum of 7 us*/ - } - - /* - * This is required to provide a delay between multiple - * consequent PPL configurations - */ - sdelay(210000); -} - -void init_plls(int num_pll, struct pll_init_data *config) -{ - int i; - - for (i = 0; i < num_pll; i++) - init_pll(&config[i]); -} - -static int get_max_speed(u32 val, int *speeds) -{ - int j; - - if (!val) - return speeds[0]; - - for (j = 1; j < MAX_SPEEDS; j++) { - if (val == 1) - return speeds[j]; - val >>= 1; - } - - return SPD800; -} - -#ifdef CONFIG_SOC_K2HK -static u32 read_efuse_bootrom(void) -{ - return (cpu_revision() > 1) ? __raw_readl(KS2_EFUSE_BOOTROM) : - __raw_readl(KS2_REV1_DEVSPEED); -} -#else -static inline u32 read_efuse_bootrom(void) -{ - return __raw_readl(KS2_EFUSE_BOOTROM); -} -#endif - -inline int get_max_dev_speed(void) -{ - return get_max_speed(read_efuse_bootrom() & 0xffff, dev_speeds); -} - -#ifndef CONFIG_SOC_K2E -inline int get_max_arm_speed(void) -{ - return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds); -} -#endif - -void pass_pll_pa_clk_enable(void) -{ - u32 reg; - - reg = readl(keystone_pll_regs[PASS_PLL].reg1); - - reg |= PLLCTL_PAPLL; - writel(reg, keystone_pll_regs[PASS_PLL].reg1); - - /* wait till clock is enabled */ - sdelay(15000); -} diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c deleted file mode 100644 index af1b701e82..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_clock.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * keystone2: commands for clocks - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -struct pll_init_data cmd_pll_data = { - .pll = MAIN_PLL, - .pll_m = 16, - .pll_d = 1, - .pll_od = 2, -}; - -int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - if (argc != 5) - goto pll_cmd_usage; - - if (strncmp(argv[1], "pa", 2) == 0) - cmd_pll_data.pll = PASS_PLL; -#ifndef CONFIG_SOC_K2E - else if (strncmp(argv[1], "arm", 3) == 0) - cmd_pll_data.pll = TETRIS_PLL; -#endif -#ifdef CONFIG_SOC_K2HK - else if (strncmp(argv[1], "ddr3a", 5) == 0) - cmd_pll_data.pll = DDR3A_PLL; - else if (strncmp(argv[1], "ddr3b", 5) == 0) - cmd_pll_data.pll = DDR3B_PLL; -#else - else if (strncmp(argv[1], "ddr3", 4) == 0) - cmd_pll_data.pll = DDR3_PLL; -#endif - else - goto pll_cmd_usage; - - cmd_pll_data.pll_m = simple_strtoul(argv[2], NULL, 10); - cmd_pll_data.pll_d = simple_strtoul(argv[3], NULL, 10); - cmd_pll_data.pll_od = simple_strtoul(argv[4], NULL, 10); - - printf("Trying to set pll %d; mult %d; div %d; OD %d\n", - cmd_pll_data.pll, cmd_pll_data.pll_m, - cmd_pll_data.pll_d, cmd_pll_data.pll_od); - init_pll(&cmd_pll_data); - - return 0; - -pll_cmd_usage: - return cmd_usage(cmdtp); -} - -U_BOOT_CMD( - pllset, 5, 0, do_pll_cmd, - "set pll multiplier and pre divider", - PLLSET_CMD_LIST "
\n" -); - -int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - unsigned int clk; - unsigned int freq; - - if (argc != 2) - goto getclk_cmd_usage; - - clk = simple_strtoul(argv[1], NULL, 10); - - freq = clk_get_rate(clk); - printf("clock index [%d] - frequency %u\n", clk, freq); - return 0; - -getclk_cmd_usage: - return cmd_usage(cmdtp); -} - -U_BOOT_CMD( - getclk, 2, 0, do_getclk_cmd, - "get clock rate", - "\n" - "The indexes for clocks:\n" - CLOCK_INDEXES_LIST -); - -int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - int psc_module; - int res; - - if (argc != 3) - goto psc_cmd_usage; - - psc_module = simple_strtoul(argv[1], NULL, 10); - if (strcmp(argv[2], "en") == 0) { - res = psc_enable_module(psc_module); - printf("psc_enable_module(%d) - %s\n", psc_module, - (res) ? "ERROR" : "OK"); - return 0; - } - - if (strcmp(argv[2], "di") == 0) { - res = psc_disable_module(psc_module); - printf("psc_disable_module(%d) - %s\n", psc_module, - (res) ? "ERROR" : "OK"); - return 0; - } - - if (strcmp(argv[2], "domain") == 0) { - res = psc_disable_domain(psc_module); - printf("psc_disable_domain(%d) - %s\n", psc_module, - (res) ? "ERROR" : "OK"); - return 0; - } - -psc_cmd_usage: - return cmd_usage(cmdtp); -} - -U_BOOT_CMD( - psc, 3, 0, do_psc_cmd, - "", - " \n" - "Intended to control Power and Sleep Controller (PSC) domains and\n" - "modules. The module or domain index exectly corresponds to ones\n" - "listed in official TRM. For instance, to enable MSMC RAM clock\n" - "domain use command: psc 14 en.\n" -); diff --git a/arch/arm/cpu/armv7/keystone/cmd_ddr3.c b/arch/arm/cpu/armv7/keystone/cmd_ddr3.c deleted file mode 100644 index ea78ad8fd5..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_ddr3.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Keystone2: DDR3 test commands - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE - -#define DDR_REMAP_ADDR 0x80000000 -#define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17) - -#define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \ - CONFIG_STACKSIZE) >> 17) - 2) - -#define DDR_TEST_BURST_SIZE 1024 - -static int ddr_memory_test(u32 start_address, u32 end_address, int quick) -{ - u32 index_start, value, index; - - index_start = start_address; - - while (1) { - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) - __raw_writel(index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) { - value = __raw_readl(index); - if (value != index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readl(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - if (quick) - continue; - - /* Write a pattern for complementary values */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) - __raw_writel((u32)~index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 4) { - value = __raw_readl(index); - if (value != ~index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readl(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 2) - __raw_writew((u16)index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 2) { - value = __raw_readw(index); - if (value != (u16)index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readw(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - - /* Write a pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 1) - __raw_writeb((u8)index, index); - - /* Read and check the pattern */ - for (index = index_start; - index < index_start + DDR_TEST_BURST_SIZE; - index += 1) { - value = __raw_readb(index); - if (value != (u8)index) { - printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", - index, value, __raw_readb(index)); - - return -1; - } - } - - index_start += DDR_TEST_BURST_SIZE; - if (index_start >= end_address) - break; - } - - puts("ddr memory test PASSED!\n"); - return 0; -} - -static int ddr_memory_compare(u32 address1, u32 address2, u32 size) -{ - u32 index, value, index2, value2; - - for (index = address1, index2 = address2; - index < address1 + size; - index += 4, index2 += 4) { - value = __raw_readl(index); - value2 = __raw_readl(index2); - - if (value != value2) { - printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n", - index, value, index2, value2); - - return -1; - } - } - - puts("ddr memory compare PASSED!\n"); - return 0; -} - -static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err) -{ - u32 value1, value2, value3; - - puts("Disabling DDR ECC ...\n"); - ddr3_disable_ecc(base); - - value1 = __raw_readl(address); - value2 = value1 ^ ecc_err; - __raw_writel(value2, address); - - value3 = __raw_readl(address); - printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n", - address, value1, value2, ecc_err, value3); - - __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16), - base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); - - puts("Enabling DDR ECC ...\n"); - ddr3_enable_ecc(base, 1); - - value1 = __raw_readl(address); - printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1); - - ddr3_check_ecc_int(base); - return 0; -} - -static int do_ddr_test(cmd_tbl_t *cmdtp, - int flag, int argc, char * const argv[]) -{ - u32 start_addr, end_addr, size, ecc_err; - - if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) { - if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) { - puts("ECC RMW isn't supported for this SOC\n"); - return 1; - } - - start_addr = simple_strtoul(argv[2], NULL, 16); - ecc_err = simple_strtoul(argv[3], NULL, 16); - - if ((start_addr < CONFIG_SYS_SDRAM_BASE) || - (start_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1))) { - puts("Invalid address!\n"); - return cmd_usage(cmdtp); - } - - ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE, - start_addr, ecc_err); - return 0; - } - - if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) || - ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0)))) - return cmd_usage(cmdtp); - - start_addr = simple_strtoul(argv[2], NULL, 16); - end_addr = simple_strtoul(argv[3], NULL, 16); - - if ((start_addr < CONFIG_SYS_SDRAM_BASE) || - (start_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1)) || - (end_addr < CONFIG_SYS_SDRAM_BASE) || - (end_addr > (CONFIG_SYS_SDRAM_BASE + - CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) { - puts("Invalid start or end address!\n"); - return cmd_usage(cmdtp); - } - - puts("Please wait ...\n"); - if (argc == 5) { - size = simple_strtoul(argv[4], NULL, 16); - ddr_memory_compare(start_addr, end_addr, size); - } else { - ddr_memory_test(start_addr, end_addr, 0); - } - - return 0; -} - -U_BOOT_CMD(ddr, 5, 1, do_ddr_test, - "DDR3 test", - "test - test DDR from start\n" - " address to end address\n" - "ddr compare -\n" - " compare DDR data of (size) bytes from start address to end\n" - " address\n" - "ddr ecc_err - generate bit errors\n" - " in DDR data at , the command will read a 32-bit data\n" - " from , and write (data ^ bit_err) back to \n" -); diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c deleted file mode 100644 index f9f58a37df..0000000000 --- a/arch/arm/cpu/armv7/keystone/cmd_mon.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * K2HK: secure kernel command file - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -asm(".arch_extension sec\n\t"); - -static int mon_install(u32 addr, u32 dpsc, u32 freq) -{ - int result; - - __asm__ __volatile__ ( - "stmfd r13!, {lr}\n" - "mov r0, %1\n" - "mov r1, %2\n" - "mov r2, %3\n" - "blx r0\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (addr), "r" (dpsc), "r" (freq) - : "cc", "r0", "r1", "r2", "memory"); - return result; -} - -static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - u32 addr, dpsc_base = 0x1E80000, freq; - int rcode = 0; - - if (argc < 2) - return CMD_RET_USAGE; - - freq = clk_get_rate(sys_clk0_6_clk); - - addr = simple_strtoul(argv[1], NULL, 16); - - rcode = mon_install(addr, dpsc_base, freq); - printf("## installed monitor, freq [%d], status %d\n", - freq, rcode); - - return 0; -} - -U_BOOT_CMD(mon_install, 2, 0, do_mon_install, - "Install boot kernel at 'addr'", - "" -); - -static void core_spin(void) -{ - while (1) - ; /* forever */; -} - -int mon_power_on(int core_id, void *ep) -{ - int result; - - asm volatile ( - "stmfd r13!, {lr}\n" - "mov r1, %1\n" - "mov r2, %2\n" - "mov r0, #0\n" - "smc #0\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (core_id), "r" (ep) - : "cc", "r0", "r1", "r2", "memory"); - return result; -} - -int mon_power_off(int core_id) -{ - int result; - - asm volatile ( - "stmfd r13!, {lr}\n" - "mov r1, %1\n" - "mov r0, #1\n" - "smc #1\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (core_id) - : "cc", "r0", "r1", "memory"); - return result; -} - -int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) -{ - int rcode = 0, core_id, on; - void (*fn)(void); - - fn = core_spin; - - if (argc < 3) - return CMD_RET_USAGE; - - core_id = simple_strtoul(argv[1], NULL, 16); - on = simple_strtoul(argv[2], NULL, 16); - - if (on) - rcode = mon_power_on(core_id, fn); - else - rcode = mon_power_off(core_id); - - if (on) { - if (!rcode) - printf("core %d powered on successfully\n", core_id); - else - printf("core %d power on failure\n", core_id); - } else { - printf("core %d powered off successfully\n", core_id); - } - - return 0; -} - -U_BOOT_CMD(mon_power, 3, 0, do_mon_power, - "Power On/Off secondary core", - "mon_power \n" - "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n" - "" -); diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c deleted file mode 100644 index dfb27b5ba2..0000000000 --- a/arch/arm/cpu/armv7/keystone/ddr3.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Keystone2: DDR3 initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -#include - -#define DDR3_EDMA_BLK_SIZE_SHIFT 10 -#define DDR3_EDMA_BLK_SIZE (1 << DDR3_EDMA_BLK_SIZE_SHIFT) -#define DDR3_EDMA_BCNT 0x8000 -#define DDR3_EDMA_CCNT 1 -#define DDR3_EDMA_XF_SIZE (DDR3_EDMA_BLK_SIZE * DDR3_EDMA_BCNT) -#define DDR3_EDMA_SLOT_NUM 1 - -void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg) -{ - unsigned int tmp; - - while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) - & 0x00000001) != 0x00000001) - ; - - __raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET); - - tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET); - tmp &= ~(phy_cfg->pgcr1_mask); - tmp |= phy_cfg->pgcr1_val; - __raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET); - - __raw_writel(phy_cfg->ptr0, base + KS2_DDRPHY_PTR0_OFFSET); - __raw_writel(phy_cfg->ptr1, base + KS2_DDRPHY_PTR1_OFFSET); - __raw_writel(phy_cfg->ptr3, base + KS2_DDRPHY_PTR3_OFFSET); - __raw_writel(phy_cfg->ptr4, base + KS2_DDRPHY_PTR4_OFFSET); - - tmp = __raw_readl(base + KS2_DDRPHY_DCR_OFFSET); - tmp &= ~(phy_cfg->dcr_mask); - tmp |= phy_cfg->dcr_val; - __raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET); - - __raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET); - __raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET); - __raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET); - __raw_writel(phy_cfg->mr0, base + KS2_DDRPHY_MR0_OFFSET); - __raw_writel(phy_cfg->mr1, base + KS2_DDRPHY_MR1_OFFSET); - __raw_writel(phy_cfg->mr2, base + KS2_DDRPHY_MR2_OFFSET); - __raw_writel(phy_cfg->dtcr, base + KS2_DDRPHY_DTCR_OFFSET); - __raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET); - - __raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET); - __raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET); - __raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET); - - __raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET); - while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) - ; - - __raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET); - while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) - ; -} - -void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg) -{ - __raw_writel(emif_cfg->sdcfg, base + KS2_DDR3_SDCFG_OFFSET); - __raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET); - __raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET); - __raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET); - __raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET); - __raw_writel(emif_cfg->zqcfg, base + KS2_DDR3_ZQCFG_OFFSET); - __raw_writel(emif_cfg->sdrfc, base + KS2_DDR3_SDRFC_OFFSET); -} - -int ddr3_ecc_support_rmw(u32 base) -{ - u32 value = __raw_readl(base + KS2_DDR3_MIDR_OFFSET); - - /* Check the DDR3 controller ID reg if the controllers - supports ECC RMW or not */ - if (value == 0x40461C02) - return 1; - - return 0; -} - -static void ddr3_ecc_config(u32 base, u32 value) -{ - u32 data; - - __raw_writel(value, base + KS2_DDR3_ECC_CTRL_OFFSET); - udelay(100000); /* delay required to synchronize across clock domains */ - - if (value & KS2_DDR3_ECC_EN) { - /* Clear the 1-bit error count */ - data = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); - __raw_writel(data, base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); - - /* enable the ECC interrupt */ - __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | - KS2_DDR3_WR_ECC_ERR_SYS, - base + KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET); - - /* Clear the ECC error interrupt status */ - __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | - KS2_DDR3_WR_ECC_ERR_SYS, - base + KS2_DDR3_ECC_INT_STATUS_OFFSET); - } -} - -static void ddr3_reset_data(u32 base, u32 ddr3_size) -{ - u32 mpax[2]; - u32 seg_num; - u32 seg, blks, dst, edma_blks; - struct edma3_slot_config slot; - struct edma3_channel_config edma_channel; - u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, }; - - /* Setup an edma to copy the 1k block to the entire DDR */ - puts("\nClear entire DDR3 memory to enable ECC\n"); - - /* save the SES MPAX regs */ - msmc_get_ses_mpax(8, 0, mpax); - - /* setup edma slot 1 configuration */ - slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | - EDMA3_SLOPT_COMP_CODE(0) | - EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; - slot.bcnt = DDR3_EDMA_BCNT; - slot.acnt = DDR3_EDMA_BLK_SIZE; - slot.ccnt = DDR3_EDMA_CCNT; - slot.src_bidx = 0; - slot.dst_bidx = DDR3_EDMA_BLK_SIZE; - slot.src_cidx = 0; - slot.dst_cidx = 0; - slot.link = EDMA3_PARSET_NULL_LINK; - slot.bcntrld = 0; - edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot); - - /* configure quik edma channel */ - edma_channel.slot = DDR3_EDMA_SLOT_NUM; - edma_channel.chnum = 0; - edma_channel.complete_code = 0; - /* event trigger after dst update */ - edma_channel.trigger_slot_word = EDMA3_TWORD(dst); - qedma3_start(KS2_EDMA0_BASE, &edma_channel); - - /* DDR3 size in segments (4KB seg size) */ - seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT); - - for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) { - /* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF - access slave interface so that edma driver can access */ - msmc_map_ses_segment(8, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT, - KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G); - - if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM) - edma_blks = KS2_MSMC_MAP_SEG_NUM << - (KS2_MSMC_SEG_SIZE_SHIFT - - DDR3_EDMA_BLK_SIZE_SHIFT); - else - edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT - - DDR3_EDMA_BLK_SIZE_SHIFT); - - /* Use edma driver to scrub 2GB DDR memory */ - for (dst = base, blks = 0; blks < edma_blks; - blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) { - edma3_set_src_addr(KS2_EDMA0_BASE, - edma_channel.slot, (u32)edma_src); - edma3_set_dest_addr(KS2_EDMA0_BASE, - edma_channel.slot, (u32)dst); - - while (edma3_check_for_transfer(KS2_EDMA0_BASE, - &edma_channel)) - udelay(10); - } - } - - qedma3_stop(KS2_EDMA0_BASE, &edma_channel); - - /* restore the SES MPAX regs */ - msmc_set_ses_mpax(8, 0, mpax); -} - -static void ddr3_ecc_init_range(u32 base) -{ - u32 ecc_val = KS2_DDR3_ECC_EN; - u32 rmw = ddr3_ecc_support_rmw(base); - - if (rmw) - ecc_val |= KS2_DDR3_ECC_RMW_EN; - - __raw_writel(0, base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); - - ddr3_ecc_config(base, ecc_val); -} - -void ddr3_enable_ecc(u32 base, int test) -{ - u32 ecc_val = KS2_DDR3_ECC_ENABLE; - u32 rmw = ddr3_ecc_support_rmw(base); - - if (test) - ecc_val |= KS2_DDR3_ECC_ADDR_RNG_1_EN; - - if (!rmw) { - if (!test) - /* by default, disable ecc when rmw = 0 and no - ecc test */ - ecc_val = 0; - } else { - ecc_val |= KS2_DDR3_ECC_RMW_EN; - } - - ddr3_ecc_config(base, ecc_val); -} - -void ddr3_disable_ecc(u32 base) -{ - ddr3_ecc_config(base, 0); -} - -#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) -static void cic_init(u32 base) -{ - /* Disable CIC global interrupts */ - __raw_writel(0, base + KS2_CIC_GLOBAL_ENABLE); - - /* Set to normal mode, no nesting, no priority hold */ - __raw_writel(0, base + KS2_CIC_CTRL); - __raw_writel(0, base + KS2_CIC_HOST_CTRL); - - /* Enable CIC global interrupts */ - __raw_writel(1, base + KS2_CIC_GLOBAL_ENABLE); -} - -static void cic_map_cic_to_gic(u32 base, u32 chan_num, u32 irq_num) -{ - /* Map the system interrupt to a CIC channel */ - __raw_writeb(chan_num, base + KS2_CIC_CHAN_MAP(0) + irq_num); - - /* Enable CIC system interrupt */ - __raw_writel(irq_num, base + KS2_CIC_SYS_ENABLE_IDX_SET); - - /* Enable CIC Host interrupt */ - __raw_writel(chan_num, base + KS2_CIC_HOST_ENABLE_IDX_SET); -} - -static void ddr3_map_ecc_cic2_irq(u32 base) -{ - cic_init(base); - cic_map_cic_to_gic(base, KS2_CIC2_DDR3_ECC_CHAN_NUM, - KS2_CIC2_DDR3_ECC_IRQ_NUM); -} -#endif - -void ddr3_init_ecc(u32 base, u32 ddr3_size) -{ - if (!ddr3_ecc_support_rmw(base)) { - ddr3_disable_ecc(base); - return; - } - - ddr3_ecc_init_range(base); - ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size); - - /* mapping DDR3 ECC system interrupt from CIC2 to GIC */ -#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) - ddr3_map_ecc_cic2_irq(KS2_CIC2_BASE); -#endif - ddr3_enable_ecc(base, 0); -} - -void ddr3_check_ecc_int(u32 base) -{ - char *env; - int ecc_test = 0; - u32 value = __raw_readl(base + KS2_DDR3_ECC_INT_STATUS_OFFSET); - - env = getenv("ecc_test"); - if (env) - ecc_test = simple_strtol(env, NULL, 0); - - if (value & KS2_DDR3_WR_ECC_ERR_SYS) - puts("DDR3 ECC write error interrupted\n"); - - if (value & KS2_DDR3_2B_ECC_ERR_SYS) { - puts("DDR3 ECC 2-bit error interrupted\n"); - - if (!ecc_test) { - puts("Reseting the device ...\n"); - reset_cpu(0); - } - } - - value = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); - if (value) { - printf("1-bit ECC err count: 0x%x\n", value); - value = __raw_readl(base + - KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET); - printf("1-bit ECC err address log: 0x%x\n", value); - } -} - -void ddr3_reset_ddrphy(void) -{ - u32 tmp; - - /* Assert DDR3A PHY reset */ - tmp = readl(KS2_DDR3APLLCTL1); - tmp |= KS2_DDR3_PLLCTRL_PHY_RESET; - writel(tmp, KS2_DDR3APLLCTL1); - - /* wait 10us to catch the reset */ - udelay(10); - - /* Release DDR3A PHY reset */ - tmp = readl(KS2_DDR3APLLCTL1); - tmp &= ~KS2_DDR3_PLLCTRL_PHY_RESET; - __raw_writel(tmp, KS2_DDR3APLLCTL1); -} - -#ifdef CONFIG_SOC_K2HK -/** - * ddr3_reset_workaround - reset workaround in case if leveling error - * detected for PG 1.0 and 1.1 k2hk SoCs - */ -void ddr3_err_reset_workaround(void) -{ - unsigned int tmp; - unsigned int tmp_a; - unsigned int tmp_b; - - /* - * Check for PGSR0 error bits of DDR3 PHY. - * Check for WLERR, QSGERR, WLAERR, - * RDERR, WDERR, REERR, WEERR error to see if they are set or not - */ - tmp_a = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); - tmp_b = __raw_readl(KS2_DDR3B_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); - - if (((tmp_a & 0x0FE00000) != 0) || ((tmp_b & 0x0FE00000) != 0)) { - printf("DDR Leveling Error Detected!\n"); - printf("DDR3A PGSR0 = 0x%x\n", tmp_a); - printf("DDR3B PGSR0 = 0x%x\n", tmp_b); - - /* - * Write Keys to KICK registers to enable writes to registers - * in boot config space - */ - __raw_writel(KS2_KICK0_MAGIC, KS2_KICK0); - __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1); - - /* - * Move DDR3A Module out of reset isolation by setting - * MDCTL23[12] = 0 - */ - tmp_a = __raw_readl(KS2_PSC_BASE + - PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); - - tmp_a = PSC_REG_MDCTL_SET_RESET_ISO(tmp_a, 0); - __raw_writel(tmp_a, KS2_PSC_BASE + - PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); - - /* - * Move DDR3B Module out of reset isolation by setting - * MDCTL24[12] = 0 - */ - tmp_b = __raw_readl(KS2_PSC_BASE + - PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); - tmp_b = PSC_REG_MDCTL_SET_RESET_ISO(tmp_b, 0); - __raw_writel(tmp_b, KS2_PSC_BASE + - PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); - - /* - * Write 0x5A69 Key to RSTCTRL[15:0] to unlock writes - * to RSTCTRL and RSTCFG - */ - tmp = __raw_readl(KS2_RSTCTRL); - tmp &= KS2_RSTCTRL_MASK; - tmp |= KS2_RSTCTRL_KEY; - __raw_writel(tmp, KS2_RSTCTRL); - - /* - * Set PLL Controller to drive hard reset on SW trigger by - * setting RSTCFG[13] = 0 - */ - tmp = __raw_readl(KS2_RSTCTRL_RSCFG); - tmp &= ~KS2_RSTYPE_PLL_SOFT; - __raw_writel(tmp, KS2_RSTCTRL_RSCFG); - - reset_cpu(0); - } -} -#endif diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c deleted file mode 100644 index c96845c4e2..0000000000 --- a/arch/arm/cpu/armv7/keystone/init.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Keystone2: Architecture initialization - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MAX_PCI_PORTS 2 -enum pci_mode { - ENDPOINT, - LEGACY_ENDPOINT, - ROOTCOMPLEX, -}; - -#define DEVCFG_MODE_MASK (BIT(2) | BIT(1)) -#define DEVCFG_MODE_SHIFT 1 - -void chip_configuration_unlock(void) -{ - __raw_writel(KS2_KICK0_MAGIC, KS2_KICK0); - __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1); -} - -#ifdef CONFIG_SOC_K2L -void osr_init(void) -{ - u32 i; - u32 j; - u32 val; - u32 base = KS2_OSR_CFG_BASE; - u32 ecc_ctrl[KS2_OSR_NUM_RAM_BANKS]; - - /* Enable the OSR clock domain */ - psc_enable_module(KS2_LPSC_OSR); - - /* Disable OSR ECC check for all the ram banks */ - for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) { - val = i | KS2_OSR_ECC_VEC_TRIG_RD | - (KS2_OSR_ECC_CTRL << KS2_OSR_ECC_VEC_RD_ADDR_SH); - - writel(val , base + KS2_OSR_ECC_VEC); - - /** - * wait till read is done. - * Print should be added after earlyprintk support is added. - */ - for (j = 0; j < 10000; j++) { - val = readl(base + KS2_OSR_ECC_VEC); - if (val & KS2_OSR_ECC_VEC_RD_DONE) - break; - } - - ecc_ctrl[i] = readl(base + KS2_OSR_ECC_CTRL) ^ - KS2_OSR_ECC_CTRL_CHK; - - writel(ecc_ctrl[i], KS2_MSMC_DATA_BASE + i * 4); - writel(ecc_ctrl[i], base + KS2_OSR_ECC_CTRL); - } - - /* Reset OSR memory to all zeros */ - for (i = 0; i < KS2_OSR_SIZE; i += 4) - writel(0, KS2_OSR_DATA_BASE + i); - - /* Enable OSR ECC check for all the ram banks */ - for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) - writel(ecc_ctrl[i] | - KS2_OSR_ECC_CTRL_CHK, base + KS2_OSR_ECC_CTRL); -} -#endif - -/* Function to set up PCIe mode */ -static void config_pcie_mode(int pcie_port, enum pci_mode mode) -{ - u32 val = __raw_readl(KS2_DEVCFG); - - if (pcie_port >= MAX_PCI_PORTS) - return; - - /** - * each pci port has two bits for mode and it starts at - * bit 1. So use port number to get the right bit position. - */ - pcie_port <<= 1; - val &= ~(DEVCFG_MODE_MASK << pcie_port); - val |= ((mode << DEVCFG_MODE_SHIFT) << pcie_port); - __raw_writel(val, KS2_DEVCFG); -} - -int arch_cpu_init(void) -{ - chip_configuration_unlock(); - icache_enable(); - - msmc_share_all_segments(KS2_MSMC_SEGMENT_TETRIS); - msmc_share_all_segments(KS2_MSMC_SEGMENT_NETCP); - msmc_share_all_segments(KS2_MSMC_SEGMENT_QM_PDSP); - msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE0); - - /* Initialize the PCIe-0 to work as Root Complex */ - config_pcie_mode(0, ROOTCOMPLEX); -#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) - msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE1); - /* Initialize the PCIe-1 to work as Root Complex */ - config_pcie_mode(1, ROOTCOMPLEX); -#endif -#ifdef CONFIG_SOC_K2L - osr_init(); -#endif - - /* - * just initialise the COM2 port so that TI specific - * UART register PWREMU_MGMT is initialized. Linux UART - * driver doesn't handle this. - */ - NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2), - CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); - - return 0; -} - -void reset_cpu(ulong addr) -{ - volatile u32 *rstctrl = (volatile u32 *)(KS2_RSTCTRL); - u32 tmp; - - tmp = *rstctrl & KS2_RSTCTRL_MASK; - *rstctrl = tmp | KS2_RSTCTRL_KEY; - - *rstctrl &= KS2_RSTCTRL_SWRST; - - for (;;) - ; -} - -void enable_caches(void) -{ -#ifndef CONFIG_SYS_DCACHE_OFF - /* Enable D-cache. I-cache is already enabled in start.S */ - dcache_enable(); -#endif -} diff --git a/arch/arm/cpu/armv7/keystone/keystone.c b/arch/arm/cpu/armv7/keystone/keystone.c deleted file mode 100644 index 11a9357db4..0000000000 --- a/arch/arm/cpu/armv7/keystone/keystone.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Keystone EVM : Board initialization - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -/** - * cpu_to_bus - swap bytes of the 32-bit data if the device is BE - * @ptr - array of data - * @length - lenght of data array - */ -int cpu_to_bus(u32 *ptr, u32 length) -{ - u32 i; - - if (!(readl(KS2_DEVSTAT) & 0x1)) - for (i = 0; i < length; i++, ptr++) - *ptr = cpu_to_be32(*ptr); - - return 0; -} - -static int turn_off_myself(void) -{ - printf("Turning off ourselves\r\n"); - mon_power_off(0); - - psc_disable_module(KS2_LPSC_TETRIS); - psc_disable_domain(KS2_TETRIS_PWR_DOMAIN); - - asm volatile ("isb\n" - "dsb\n" - "wfi\n"); - - printf("What! Should not see that\n"); - return 0; -} - -static void turn_off_all_dsps(int num_dsps) -{ - int i; - - for (i = 0; i < num_dsps; i++) { - if (psc_disable_module(i + KS2_LPSC_GEM_0)) - printf("Cannot disable module for #%d DSP", i); - - if (psc_disable_domain(i + 8)) - printf("Cannot disable domain for #%d DSP", i); - } -} - -int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - return turn_off_myself(); -} - -U_BOOT_CMD( - killme, 1, 0, do_killme_cmd, - "turn off main ARM core", - "turn off main ARM core. Should not live after that :(\n" -); - -int misc_init_r(void) -{ - char *env; - long ks2_debug = 0; - - env = getenv("ks2_debug"); - - if (env) - ks2_debug = simple_strtol(env, NULL, 0); - - if ((ks2_debug & DBG_LEAVE_DSPS_ON) == 0) - turn_off_all_dsps(KS2_NUM_DSPS); - - return 0; -} diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c deleted file mode 100644 index 7899141d54..0000000000 --- a/arch/arm/cpu/armv7/keystone/msmc.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * MSMC controller utilities - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -struct mpax { - u32 mpaxl; - u32 mpaxh; -}; - -struct msms_regs { - u32 pid; - u32 _res_04; - u32 smcerrar; - u32 smcerrxr; - u32 smedcc; - u32 smcea; - u32 smsecc; - u32 smpfar; - u32 smpfxr; - u32 smpfr; - u32 smpfcr; - u32 _res_2c; - u32 sbndc[8]; - u32 sbndm; - u32 sbnde; - u32 _res_58; - u32 cfglck; - u32 cfgulck; - u32 cfglckstat; - u32 sms_mpax_lck; - u32 sms_mpax_ulck; - u32 sms_mpax_lckstat; - u32 ses_mpax_lck; - u32 ses_mpax_ulck; - u32 ses_mpax_lckstat; - u32 smestat; - u32 smirstat; - u32 smirc; - u32 smiestat; - u32 smiec; - u32 _res_94_c0[12]; - u32 smncerrar; - u32 smncerrxr; - u32 smncea; - u32 _res_d0_1fc[76]; - struct mpax sms[16][8]; - struct mpax ses[16][8]; -}; - - -void msmc_share_all_segments(int priv_id) -{ - struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; - int j; - - for (j = 0; j < 8; j++) { - msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful; - msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful; - } -} - -void msmc_map_ses_segment(int priv_id, int ses_pair, - u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size) -{ - struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; - - msmc->ses[priv_id][ses_pair].mpaxh = src_pfn << 12 | - (size & 0x1f) | 0x80; - msmc->ses[priv_id][ses_pair].mpaxl = dst_pfn << 8 | 0x3f; -} - -void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax) -{ - struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; - - *mpax++ = msmc->ses[priv_id][ses_pair].mpaxl; - *mpax = msmc->ses[priv_id][ses_pair].mpaxh; -} - -void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax) -{ - struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; - - msmc->ses[priv_id][ses_pair].mpaxl = *mpax++; - msmc->ses[priv_id][ses_pair].mpaxh = *mpax; -} diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c deleted file mode 100644 index 237e776e87..0000000000 --- a/arch/arm/cpu/armv7/keystone/psc.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Keystone: PSC configuration module - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include - -int psc_delay(void) -{ - udelay(10); - return 10; -} - -/* - * FUNCTION PURPOSE: Wait for end of transitional state - * - * DESCRIPTION: Polls pstat for the selected domain and waits for transitions - * to be complete. - * - * Since this is boot loader code it is *ASSUMED* that interrupts - * are disabled and no other core is mucking around with the psc - * at the same time. - * - * Returns 0 when the domain is free. Returns -1 if a timeout - * occurred waiting for the completion. - */ -int psc_wait(u32 domain_num) -{ - u32 retry; - u32 ptstat; - - /* - * Do nothing if the power domain is in transition. This should never - * happen since the boot code is the only software accesses psc. - * It's still remotely possible that the hardware state machines - * initiate transitions. - * Don't trap if the domain (or a module in this domain) is - * stuck in transition. - */ - retry = 0; - - do { - ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT); - ptstat = ptstat & (1 << domain_num); - } while ((ptstat != 0) && ((retry += psc_delay()) < - PSC_PTSTAT_TIMEOUT_LIMIT)); - - if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT) - return -1; - - return 0; -} - -u32 psc_get_domain_num(u32 mod_num) -{ - u32 domain_num; - - /* Get the power domain associated with the module number */ - domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num)); - domain_num = PSC_REG_MDCFG_GET_PD(domain_num); - - return domain_num; -} - -/* - * FUNCTION PURPOSE: Power up/down a module - * - * DESCRIPTION: Powers up/down the requested module and the associated power - * domain if required. No action is taken it the module is - * already powered up/down. - * - * This only controls modules. The domain in which the module - * resides will be left in the power on state. Multiple modules - * can exist in a power domain, so powering down the domain based - * on a single module is not done. - * - * Returns 0 on success, -1 if the module can't be powered up, or - * if there is a timeout waiting for the transition. - */ -int psc_set_state(u32 mod_num, u32 state) -{ - u32 domain_num; - u32 pdctl; - u32 mdctl; - u32 ptcmd; - u32 reset_iso; - u32 v; - - /* - * Get the power domain associated with the module number, and reset - * isolation functionality - */ - v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num)); - domain_num = PSC_REG_MDCFG_GET_PD(v); - reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v); - - /* Wait for the status of the domain/module to be non-transitional */ - if (psc_wait(domain_num) != 0) - return -1; - - /* - * Perform configuration even if the current status matches the - * existing state - * - * Set the next state of the power domain to on. It's OK if the domain - * is always on. This code will not ever power down a domain, so no - * change is made if the new state is power down. - */ - if (state == PSC_REG_VAL_MDCTL_NEXT_ON) { - pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num)); - pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, - PSC_REG_VAL_PDCTL_NEXT_ON); - __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num)); - } - - /* Set the next state for the module to enabled/disabled */ - mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); - mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state); - mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso); - __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); - - /* Trigger the enable */ - ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD); - ptcmd |= (u32)(1< +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += init.o +obj-y += psc.o +obj-y += clock.o +obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o +obj-$(CONFIG_SOC_K2E) += clock-k2e.o +obj-$(CONFIG_SOC_K2L) += clock-k2l.o +obj-y += cmd_clock.o +obj-y += cmd_mon.o +obj-y += msmc.o +obj-y += ddr3.o cmd_ddr3.o +obj-y += keystone.o diff --git a/arch/arm/mach-keystone/clock-k2e.c b/arch/arm/mach-keystone/clock-k2e.c new file mode 100644 index 0000000000..31f66613ef --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2e.c @@ -0,0 +1,117 @@ +/* + * Keystone2: get clk rate for K2E + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +const struct keystone_pll_regs keystone_pll_regs[] = { + [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, + [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, + [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, +}; + +int dev_speeds[] = { + SPD800, + SPD850, + SPD1000, + SPD1250, + SPD1350, + SPD1400, + SPD1500, + SPD1400, + SPD1350, + SPD1250, + SPD1000, + SPD850, + SPD800 +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @pll: pll identifier + */ +static unsigned long pll_freq_get(int pll) +{ + unsigned long mult = 1, prediv = 1, output_div = 2; + unsigned long ret; + u32 tmp, reg; + + if (pll == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case DDR3_PLL: + ret = external_clk[ddr3_clk]; + reg = KS2_DDR3APLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock-k2hk.c b/arch/arm/mach-keystone/clock-k2hk.c new file mode 100644 index 0000000000..1591960795 --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2hk.c @@ -0,0 +1,145 @@ +/* + * Keystone2: get clk rate for K2HK + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +const struct keystone_pll_regs keystone_pll_regs[] = { + [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, + [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, + [TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1}, + [DDR3A_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, + [DDR3B_PLL] = {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1}, +}; + +int dev_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD800, + SPD800, + SPD800, + SPD800, + SPD800, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +int arm_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD800, + SPD1400, + SPD1350, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @pll: pll identifier + */ +static unsigned long pll_freq_get(int pll) +{ + unsigned long mult = 1, prediv = 1, output_div = 2; + unsigned long ret; + u32 tmp, reg; + + if (pll == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case TETRIS_PLL: + ret = external_clk[tetris_clk]; + reg = KS2_ARMPLLCTL0; + break; + case DDR3A_PLL: + ret = external_clk[ddr3a_clk]; + reg = KS2_DDR3APLLCTL0; + break; + case DDR3B_PLL: + ret = external_clk[ddr3b_clk]; + reg = KS2_DDR3BPLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); + case ddr3a_pll_clk: return pll_freq_get(DDR3A_PLL); + case ddr3b_pll_clk: return pll_freq_get(DDR3B_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock-k2l.c b/arch/arm/mach-keystone/clock-k2l.c new file mode 100644 index 0000000000..1c5e4d54d8 --- /dev/null +++ b/arch/arm/mach-keystone/clock-k2l.c @@ -0,0 +1,138 @@ +/* + * Keystone2: get clk rate for K2L + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +const struct keystone_pll_regs keystone_pll_regs[] = { + [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1}, + [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1}, + [TETRIS_PLL] = {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1}, + [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1}, +}; + +int dev_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD800, + SPD800, + SPD800, + SPD800, + SPD800, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +int arm_speeds[] = { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD800, + SPD1400, + SPD1350, + SPD1200, + SPD1000, + SPD800, + SPD800, + SPD800, +}; + +/** + * pll_freq_get - get pll frequency + * Fout = Fref * NF(mult) / NR(prediv) / OD + * @pll: pll identifier + */ +static unsigned long pll_freq_get(int pll) +{ + unsigned long mult = 1, prediv = 1, output_div = 2; + unsigned long ret; + u32 tmp, reg; + + if (pll == CORE_PLL) { + ret = external_clk[sys_clk]; + if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { + /* PLL mode */ + tmp = __raw_readl(KS2_MAINPLLCTL0); + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | + (pllctl_reg_read(pll, mult) & + PLLM_MULT_LO_MASK)) + 1; + output_div = ((pllctl_reg_read(pll, secctl) >> + PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; + + ret = ret / prediv / output_div * mult; + } + } else { + switch (pll) { + case PASS_PLL: + ret = external_clk[pa_clk]; + reg = KS2_PASSPLLCTL0; + break; + case TETRIS_PLL: + ret = external_clk[tetris_clk]; + reg = KS2_ARMPLLCTL0; + break; + case DDR3_PLL: + ret = external_clk[ddr3_clk]; + reg = KS2_DDR3APLLCTL0; + break; + default: + return 0; + } + + tmp = __raw_readl(reg); + if (!(tmp & PLLCTL_BYPASS)) { + /* Bypass disabled */ + prediv = (tmp & PLL_DIV_MASK) + 1; + mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; + output_div = ((tmp >> PLL_CLKOD_SHIFT) & + PLL_CLKOD_MASK) + 1; + ret = ((ret / prediv) * mult) / output_div; + } + } + + return ret; +} + +unsigned long clk_get_rate(unsigned int clk) +{ + switch (clk) { + case core_pll_clk: return pll_freq_get(CORE_PLL); + case pass_pll_clk: return pll_freq_get(PASS_PLL); + case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); + case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); + case sys_clk0_1_clk: + case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); + case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); + case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); + case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); + case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; + case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; + case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; + case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; + case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; + case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; + case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; + case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; + case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; + case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; + case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; + default: + break; + } + + return 0; +} diff --git a/arch/arm/mach-keystone/clock.c b/arch/arm/mach-keystone/clock.c new file mode 100644 index 0000000000..d13fbc1a4b --- /dev/null +++ b/arch/arm/mach-keystone/clock.c @@ -0,0 +1,272 @@ +/* + * Keystone2: pll initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define MAX_SPEEDS 13 + +static void wait_for_completion(const struct pll_init_data *data) +{ + int i; + for (i = 0; i < 100; i++) { + sdelay(450); + if ((pllctl_reg_read(data->pll, stat) & PLLSTAT_GO) == 0) + break; + } +} + +void init_pll(const struct pll_init_data *data) +{ + u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj; + + pllm = data->pll_m - 1; + plld = (data->pll_d - 1) & PLL_DIV_MASK; + pllod = (data->pll_od - 1) & PLL_CLKOD_MASK; + + if (data->pll == MAIN_PLL) { + /* The requered delay before main PLL configuration */ + sdelay(210000); + + tmp = pllctl_reg_read(data->pll, secctl); + + if (tmp & (PLLCTL_BYPASS)) { + setbits_le32(keystone_pll_regs[data->pll].reg1, + BIT(MAIN_ENSAT_OFFSET)); + + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | + PLLCTL_PLLENSRC); + sdelay(340); + + pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS); + pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN); + sdelay(21000); + + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN); + } else { + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN | + PLLCTL_PLLENSRC); + sdelay(340); + } + + pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK); + + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLLM_MULT_HI_SMASK, (pllm << 6)); + + /* Set the BWADJ (12 bit field) */ + tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */ + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLL_BWADJ_LO_SMASK, + (tmp_ctl << PLL_BWADJ_LO_SHIFT)); + clrsetbits_le32(keystone_pll_regs[data->pll].reg1, + PLL_BWADJ_HI_MASK, + (tmp_ctl >> 8)); + + /* + * Set the pll divider (6 bit field) * + * PLLD[5:0] is located in MAINPLLCTL0 + */ + clrsetbits_le32(keystone_pll_regs[data->pll].reg0, + PLL_DIV_MASK, plld); + + /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */ + pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK, + (pllod << PLL_CLKOD_SHIFT)); + wait_for_completion(data); + + pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1); + pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2); + pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3); + pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4); + pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5); + + pllctl_reg_setbits(data->pll, alnctl, 0x1f); + + /* + * Set GOSET bit in PLLCMD to initiate the GO operation + * to change the divide + */ + pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO); + sdelay(1500); /* wait for the phase adj */ + wait_for_completion(data); + + /* Reset PLL */ + pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST); + sdelay(21000); /* Wait for a minimum of 7 us*/ + pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST); + sdelay(105000); /* Wait for PLL Lock time (min 50 us) */ + + pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS); + + tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN); + +#ifndef CONFIG_SOC_K2E + } else if (data->pll == TETRIS_PLL) { + bwadj = pllm >> 1; + /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ + setbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass) + * only applicable for Kepler + */ + clrbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); + /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */ + setbits_le32(keystone_pll_regs[data->pll].reg1 , + PLL_PLLRST | PLLCTL_ENSAT); + + /* + * 3 Program PLLM and PLLD in PLLCTL0 register + * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in + * PLLCTL1 register. BWADJ value must be set + * to ((PLLM + 1) >> 1) – 1) + */ + tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | + (pllm << 6) | + (plld & PLL_DIV_MASK) | + (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS; + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); + /* + * 5 Wait for at least 5 us based on the reference + * clock (PLL reset time) + */ + sdelay(21000); /* Wait for a minimum of 7 us*/ + + /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */ + clrbits_le32(keystone_pll_regs[data->pll].reg1, PLL_PLLRST); + /* + * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1) + * (PLL lock time) + */ + sdelay(105000); + /* 8 disable bypass */ + clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass) + * only applicable for Kepler + */ + setbits_le32(KS2_MISC_CTRL, KS2_ARM_PLL_EN); +#endif + } else { + setbits_le32(keystone_pll_regs[data->pll].reg1, PLLCTL_ENSAT); + /* + * process keeps state of Bypass bit while programming + * all other DDR PLL settings + */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg0); + tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */ + + /* + * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0, + * bypass disabled + */ + bwadj = pllm >> 1; + tmp |= ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) | + (pllm << PLL_MULT_SHIFT) | + (plld & PLL_DIV_MASK) | + (pllod << PLL_CLKOD_SHIFT); + __raw_writel(tmp, keystone_pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(keystone_pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); + + __raw_writel(tmp, keystone_pll_regs[data->pll].reg1); + + /* Reset bit: bit 14 for both DDR3 & PASS PLL */ + tmp = PLL_PLLRST; + /* Set RESET bit = 1 */ + setbits_le32(keystone_pll_regs[data->pll].reg1, tmp); + /* Wait for a minimum of 7 us*/ + sdelay(21000); + /* Clear RESET bit */ + clrbits_le32(keystone_pll_regs[data->pll].reg1, tmp); + sdelay(105000); + + /* clear BYPASS (Enable PLL Mode) */ + clrbits_le32(keystone_pll_regs[data->pll].reg0, PLLCTL_BYPASS); + sdelay(21000); /* Wait for a minimum of 7 us*/ + } + + /* + * This is required to provide a delay between multiple + * consequent PPL configurations + */ + sdelay(210000); +} + +void init_plls(int num_pll, struct pll_init_data *config) +{ + int i; + + for (i = 0; i < num_pll; i++) + init_pll(&config[i]); +} + +static int get_max_speed(u32 val, int *speeds) +{ + int j; + + if (!val) + return speeds[0]; + + for (j = 1; j < MAX_SPEEDS; j++) { + if (val == 1) + return speeds[j]; + val >>= 1; + } + + return SPD800; +} + +#ifdef CONFIG_SOC_K2HK +static u32 read_efuse_bootrom(void) +{ + return (cpu_revision() > 1) ? __raw_readl(KS2_EFUSE_BOOTROM) : + __raw_readl(KS2_REV1_DEVSPEED); +} +#else +static inline u32 read_efuse_bootrom(void) +{ + return __raw_readl(KS2_EFUSE_BOOTROM); +} +#endif + +inline int get_max_dev_speed(void) +{ + return get_max_speed(read_efuse_bootrom() & 0xffff, dev_speeds); +} + +#ifndef CONFIG_SOC_K2E +inline int get_max_arm_speed(void) +{ + return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds); +} +#endif + +void pass_pll_pa_clk_enable(void) +{ + u32 reg; + + reg = readl(keystone_pll_regs[PASS_PLL].reg1); + + reg |= PLLCTL_PAPLL; + writel(reg, keystone_pll_regs[PASS_PLL].reg1); + + /* wait till clock is enabled */ + sdelay(15000); +} diff --git a/arch/arm/mach-keystone/cmd_clock.c b/arch/arm/mach-keystone/cmd_clock.c new file mode 100644 index 0000000000..af1b701e82 --- /dev/null +++ b/arch/arm/mach-keystone/cmd_clock.c @@ -0,0 +1,135 @@ +/* + * keystone2: commands for clocks + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +struct pll_init_data cmd_pll_data = { + .pll = MAIN_PLL, + .pll_m = 16, + .pll_d = 1, + .pll_od = 2, +}; + +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc != 5) + goto pll_cmd_usage; + + if (strncmp(argv[1], "pa", 2) == 0) + cmd_pll_data.pll = PASS_PLL; +#ifndef CONFIG_SOC_K2E + else if (strncmp(argv[1], "arm", 3) == 0) + cmd_pll_data.pll = TETRIS_PLL; +#endif +#ifdef CONFIG_SOC_K2HK + else if (strncmp(argv[1], "ddr3a", 5) == 0) + cmd_pll_data.pll = DDR3A_PLL; + else if (strncmp(argv[1], "ddr3b", 5) == 0) + cmd_pll_data.pll = DDR3B_PLL; +#else + else if (strncmp(argv[1], "ddr3", 4) == 0) + cmd_pll_data.pll = DDR3_PLL; +#endif + else + goto pll_cmd_usage; + + cmd_pll_data.pll_m = simple_strtoul(argv[2], NULL, 10); + cmd_pll_data.pll_d = simple_strtoul(argv[3], NULL, 10); + cmd_pll_data.pll_od = simple_strtoul(argv[4], NULL, 10); + + printf("Trying to set pll %d; mult %d; div %d; OD %d\n", + cmd_pll_data.pll, cmd_pll_data.pll_m, + cmd_pll_data.pll_d, cmd_pll_data.pll_od); + init_pll(&cmd_pll_data); + + return 0; + +pll_cmd_usage: + return cmd_usage(cmdtp); +} + +U_BOOT_CMD( + pllset, 5, 0, do_pll_cmd, + "set pll multiplier and pre divider", + PLLSET_CMD_LIST "
\n" +); + +int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int clk; + unsigned int freq; + + if (argc != 2) + goto getclk_cmd_usage; + + clk = simple_strtoul(argv[1], NULL, 10); + + freq = clk_get_rate(clk); + printf("clock index [%d] - frequency %u\n", clk, freq); + return 0; + +getclk_cmd_usage: + return cmd_usage(cmdtp); +} + +U_BOOT_CMD( + getclk, 2, 0, do_getclk_cmd, + "get clock rate", + "\n" + "The indexes for clocks:\n" + CLOCK_INDEXES_LIST +); + +int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int psc_module; + int res; + + if (argc != 3) + goto psc_cmd_usage; + + psc_module = simple_strtoul(argv[1], NULL, 10); + if (strcmp(argv[2], "en") == 0) { + res = psc_enable_module(psc_module); + printf("psc_enable_module(%d) - %s\n", psc_module, + (res) ? "ERROR" : "OK"); + return 0; + } + + if (strcmp(argv[2], "di") == 0) { + res = psc_disable_module(psc_module); + printf("psc_disable_module(%d) - %s\n", psc_module, + (res) ? "ERROR" : "OK"); + return 0; + } + + if (strcmp(argv[2], "domain") == 0) { + res = psc_disable_domain(psc_module); + printf("psc_disable_domain(%d) - %s\n", psc_module, + (res) ? "ERROR" : "OK"); + return 0; + } + +psc_cmd_usage: + return cmd_usage(cmdtp); +} + +U_BOOT_CMD( + psc, 3, 0, do_psc_cmd, + "", + " \n" + "Intended to control Power and Sleep Controller (PSC) domains and\n" + "modules. The module or domain index exectly corresponds to ones\n" + "listed in official TRM. For instance, to enable MSMC RAM clock\n" + "domain use command: psc 14 en.\n" +); diff --git a/arch/arm/mach-keystone/cmd_ddr3.c b/arch/arm/mach-keystone/cmd_ddr3.c new file mode 100644 index 0000000000..ea78ad8fd5 --- /dev/null +++ b/arch/arm/mach-keystone/cmd_ddr3.c @@ -0,0 +1,248 @@ +/* + * Keystone2: DDR3 test commands + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define DDR_MIN_ADDR CONFIG_SYS_SDRAM_BASE + +#define DDR_REMAP_ADDR 0x80000000 +#define ECC_START_ADDR1 ((DDR_MIN_ADDR - DDR_REMAP_ADDR) >> 17) + +#define ECC_END_ADDR1 (((gd->start_addr_sp - DDR_REMAP_ADDR - \ + CONFIG_STACKSIZE) >> 17) - 2) + +#define DDR_TEST_BURST_SIZE 1024 + +static int ddr_memory_test(u32 start_address, u32 end_address, int quick) +{ + u32 index_start, value, index; + + index_start = start_address; + + while (1) { + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) + __raw_writel(index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) { + value = __raw_readl(index); + if (value != index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readl(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + if (quick) + continue; + + /* Write a pattern for complementary values */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) + __raw_writel((u32)~index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 4) { + value = __raw_readl(index); + if (value != ~index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readl(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 2) + __raw_writew((u16)index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 2) { + value = __raw_readw(index); + if (value != (u16)index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readw(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + + /* Write a pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 1) + __raw_writeb((u8)index, index); + + /* Read and check the pattern */ + for (index = index_start; + index < index_start + DDR_TEST_BURST_SIZE; + index += 1) { + value = __raw_readb(index); + if (value != (u8)index) { + printf("ddr_memory_test: Failed at address index = 0x%x value = 0x%x *(index) = 0x%x\n", + index, value, __raw_readb(index)); + + return -1; + } + } + + index_start += DDR_TEST_BURST_SIZE; + if (index_start >= end_address) + break; + } + + puts("ddr memory test PASSED!\n"); + return 0; +} + +static int ddr_memory_compare(u32 address1, u32 address2, u32 size) +{ + u32 index, value, index2, value2; + + for (index = address1, index2 = address2; + index < address1 + size; + index += 4, index2 += 4) { + value = __raw_readl(index); + value2 = __raw_readl(index2); + + if (value != value2) { + printf("ddr_memory_test: Compare failed at address = 0x%x value = 0x%x, address2 = 0x%x value2 = 0x%x\n", + index, value, index2, value2); + + return -1; + } + } + + puts("ddr memory compare PASSED!\n"); + return 0; +} + +static int ddr_memory_ecc_err(u32 base, u32 address, u32 ecc_err) +{ + u32 value1, value2, value3; + + puts("Disabling DDR ECC ...\n"); + ddr3_disable_ecc(base); + + value1 = __raw_readl(address); + value2 = value1 ^ ecc_err; + __raw_writel(value2, address); + + value3 = __raw_readl(address); + printf("ECC err test, addr 0x%x, read data 0x%x, wrote data 0x%x, err pattern: 0x%x, read after write data 0x%x\n", + address, value1, value2, ecc_err, value3); + + __raw_writel(ECC_START_ADDR1 | (ECC_END_ADDR1 << 16), + base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); + + puts("Enabling DDR ECC ...\n"); + ddr3_enable_ecc(base, 1); + + value1 = __raw_readl(address); + printf("ECC err test, addr 0x%x, read data 0x%x\n", address, value1); + + ddr3_check_ecc_int(base); + return 0; +} + +static int do_ddr_test(cmd_tbl_t *cmdtp, + int flag, int argc, char * const argv[]) +{ + u32 start_addr, end_addr, size, ecc_err; + + if ((argc == 4) && (strncmp(argv[1], "ecc_err", 8) == 0)) { + if (!ddr3_ecc_support_rmw(KS2_DDR3A_EMIF_CTRL_BASE)) { + puts("ECC RMW isn't supported for this SOC\n"); + return 1; + } + + start_addr = simple_strtoul(argv[2], NULL, 16); + ecc_err = simple_strtoul(argv[3], NULL, 16); + + if ((start_addr < CONFIG_SYS_SDRAM_BASE) || + (start_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1))) { + puts("Invalid address!\n"); + return cmd_usage(cmdtp); + } + + ddr_memory_ecc_err(KS2_DDR3A_EMIF_CTRL_BASE, + start_addr, ecc_err); + return 0; + } + + if (!(((argc == 4) && (strncmp(argv[1], "test", 5) == 0)) || + ((argc == 5) && (strncmp(argv[1], "compare", 8) == 0)))) + return cmd_usage(cmdtp); + + start_addr = simple_strtoul(argv[2], NULL, 16); + end_addr = simple_strtoul(argv[3], NULL, 16); + + if ((start_addr < CONFIG_SYS_SDRAM_BASE) || + (start_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1)) || + (end_addr < CONFIG_SYS_SDRAM_BASE) || + (end_addr > (CONFIG_SYS_SDRAM_BASE + + CONFIG_MAX_RAM_BANK_SIZE - 1)) || (start_addr >= end_addr)) { + puts("Invalid start or end address!\n"); + return cmd_usage(cmdtp); + } + + puts("Please wait ...\n"); + if (argc == 5) { + size = simple_strtoul(argv[4], NULL, 16); + ddr_memory_compare(start_addr, end_addr, size); + } else { + ddr_memory_test(start_addr, end_addr, 0); + } + + return 0; +} + +U_BOOT_CMD(ddr, 5, 1, do_ddr_test, + "DDR3 test", + "test - test DDR from start\n" + " address to end address\n" + "ddr compare -\n" + " compare DDR data of (size) bytes from start address to end\n" + " address\n" + "ddr ecc_err - generate bit errors\n" + " in DDR data at , the command will read a 32-bit data\n" + " from , and write (data ^ bit_err) back to \n" +); diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c new file mode 100644 index 0000000000..f9f58a37df --- /dev/null +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -0,0 +1,131 @@ +/* + * K2HK: secure kernel command file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +asm(".arch_extension sec\n\t"); + +static int mon_install(u32 addr, u32 dpsc, u32 freq) +{ + int result; + + __asm__ __volatile__ ( + "stmfd r13!, {lr}\n" + "mov r0, %1\n" + "mov r1, %2\n" + "mov r2, %3\n" + "blx r0\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (addr), "r" (dpsc), "r" (freq) + : "cc", "r0", "r1", "r2", "memory"); + return result; +} + +static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 addr, dpsc_base = 0x1E80000, freq; + int rcode = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + freq = clk_get_rate(sys_clk0_6_clk); + + addr = simple_strtoul(argv[1], NULL, 16); + + rcode = mon_install(addr, dpsc_base, freq); + printf("## installed monitor, freq [%d], status %d\n", + freq, rcode); + + return 0; +} + +U_BOOT_CMD(mon_install, 2, 0, do_mon_install, + "Install boot kernel at 'addr'", + "" +); + +static void core_spin(void) +{ + while (1) + ; /* forever */; +} + +int mon_power_on(int core_id, void *ep) +{ + int result; + + asm volatile ( + "stmfd r13!, {lr}\n" + "mov r1, %1\n" + "mov r2, %2\n" + "mov r0, #0\n" + "smc #0\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (core_id), "r" (ep) + : "cc", "r0", "r1", "r2", "memory"); + return result; +} + +int mon_power_off(int core_id) +{ + int result; + + asm volatile ( + "stmfd r13!, {lr}\n" + "mov r1, %1\n" + "mov r0, #1\n" + "smc #1\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (core_id) + : "cc", "r0", "r1", "memory"); + return result; +} + +int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int rcode = 0, core_id, on; + void (*fn)(void); + + fn = core_spin; + + if (argc < 3) + return CMD_RET_USAGE; + + core_id = simple_strtoul(argv[1], NULL, 16); + on = simple_strtoul(argv[2], NULL, 16); + + if (on) + rcode = mon_power_on(core_id, fn); + else + rcode = mon_power_off(core_id); + + if (on) { + if (!rcode) + printf("core %d powered on successfully\n", core_id); + else + printf("core %d power on failure\n", core_id); + } else { + printf("core %d powered off successfully\n", core_id); + } + + return 0; +} + +U_BOOT_CMD(mon_power, 3, 0, do_mon_power, + "Power On/Off secondary core", + "mon_power \n" + "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n" + "" +); diff --git a/arch/arm/mach-keystone/ddr3.c b/arch/arm/mach-keystone/ddr3.c new file mode 100644 index 0000000000..dfb27b5ba2 --- /dev/null +++ b/arch/arm/mach-keystone/ddr3.c @@ -0,0 +1,404 @@ +/* + * Keystone2: DDR3 initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#include + +#define DDR3_EDMA_BLK_SIZE_SHIFT 10 +#define DDR3_EDMA_BLK_SIZE (1 << DDR3_EDMA_BLK_SIZE_SHIFT) +#define DDR3_EDMA_BCNT 0x8000 +#define DDR3_EDMA_CCNT 1 +#define DDR3_EDMA_XF_SIZE (DDR3_EDMA_BLK_SIZE * DDR3_EDMA_BCNT) +#define DDR3_EDMA_SLOT_NUM 1 + +void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg) +{ + unsigned int tmp; + + while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) + & 0x00000001) != 0x00000001) + ; + + __raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET); + + tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET); + tmp &= ~(phy_cfg->pgcr1_mask); + tmp |= phy_cfg->pgcr1_val; + __raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET); + + __raw_writel(phy_cfg->ptr0, base + KS2_DDRPHY_PTR0_OFFSET); + __raw_writel(phy_cfg->ptr1, base + KS2_DDRPHY_PTR1_OFFSET); + __raw_writel(phy_cfg->ptr3, base + KS2_DDRPHY_PTR3_OFFSET); + __raw_writel(phy_cfg->ptr4, base + KS2_DDRPHY_PTR4_OFFSET); + + tmp = __raw_readl(base + KS2_DDRPHY_DCR_OFFSET); + tmp &= ~(phy_cfg->dcr_mask); + tmp |= phy_cfg->dcr_val; + __raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET); + + __raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET); + __raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET); + __raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET); + __raw_writel(phy_cfg->mr0, base + KS2_DDRPHY_MR0_OFFSET); + __raw_writel(phy_cfg->mr1, base + KS2_DDRPHY_MR1_OFFSET); + __raw_writel(phy_cfg->mr2, base + KS2_DDRPHY_MR2_OFFSET); + __raw_writel(phy_cfg->dtcr, base + KS2_DDRPHY_DTCR_OFFSET); + __raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET); + + __raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET); + __raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET); + __raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET); + + __raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET); + while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) + ; + + __raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET); + while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1) + ; +} + +void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg) +{ + __raw_writel(emif_cfg->sdcfg, base + KS2_DDR3_SDCFG_OFFSET); + __raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET); + __raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET); + __raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET); + __raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET); + __raw_writel(emif_cfg->zqcfg, base + KS2_DDR3_ZQCFG_OFFSET); + __raw_writel(emif_cfg->sdrfc, base + KS2_DDR3_SDRFC_OFFSET); +} + +int ddr3_ecc_support_rmw(u32 base) +{ + u32 value = __raw_readl(base + KS2_DDR3_MIDR_OFFSET); + + /* Check the DDR3 controller ID reg if the controllers + supports ECC RMW or not */ + if (value == 0x40461C02) + return 1; + + return 0; +} + +static void ddr3_ecc_config(u32 base, u32 value) +{ + u32 data; + + __raw_writel(value, base + KS2_DDR3_ECC_CTRL_OFFSET); + udelay(100000); /* delay required to synchronize across clock domains */ + + if (value & KS2_DDR3_ECC_EN) { + /* Clear the 1-bit error count */ + data = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); + __raw_writel(data, base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); + + /* enable the ECC interrupt */ + __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | + KS2_DDR3_WR_ECC_ERR_SYS, + base + KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET); + + /* Clear the ECC error interrupt status */ + __raw_writel(KS2_DDR3_1B_ECC_ERR_SYS | KS2_DDR3_2B_ECC_ERR_SYS | + KS2_DDR3_WR_ECC_ERR_SYS, + base + KS2_DDR3_ECC_INT_STATUS_OFFSET); + } +} + +static void ddr3_reset_data(u32 base, u32 ddr3_size) +{ + u32 mpax[2]; + u32 seg_num; + u32 seg, blks, dst, edma_blks; + struct edma3_slot_config slot; + struct edma3_channel_config edma_channel; + u32 edma_src[DDR3_EDMA_BLK_SIZE/4] __aligned(16) = {0, }; + + /* Setup an edma to copy the 1k block to the entire DDR */ + puts("\nClear entire DDR3 memory to enable ECC\n"); + + /* save the SES MPAX regs */ + msmc_get_ses_mpax(8, 0, mpax); + + /* setup edma slot 1 configuration */ + slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + slot.bcnt = DDR3_EDMA_BCNT; + slot.acnt = DDR3_EDMA_BLK_SIZE; + slot.ccnt = DDR3_EDMA_CCNT; + slot.src_bidx = 0; + slot.dst_bidx = DDR3_EDMA_BLK_SIZE; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld = 0; + edma3_slot_configure(KS2_EDMA0_BASE, DDR3_EDMA_SLOT_NUM, &slot); + + /* configure quik edma channel */ + edma_channel.slot = DDR3_EDMA_SLOT_NUM; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* event trigger after dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + qedma3_start(KS2_EDMA0_BASE, &edma_channel); + + /* DDR3 size in segments (4KB seg size) */ + seg_num = ddr3_size << (30 - KS2_MSMC_SEG_SIZE_SHIFT); + + for (seg = 0; seg < seg_num; seg += KS2_MSMC_MAP_SEG_NUM) { + /* map 2GB 36-bit DDR address to 32-bit DDR address in EMIF + access slave interface so that edma driver can access */ + msmc_map_ses_segment(8, 0, base >> KS2_MSMC_SEG_SIZE_SHIFT, + KS2_MSMC_DST_SEG_BASE + seg, MPAX_SEG_2G); + + if ((seg_num - seg) > KS2_MSMC_MAP_SEG_NUM) + edma_blks = KS2_MSMC_MAP_SEG_NUM << + (KS2_MSMC_SEG_SIZE_SHIFT + - DDR3_EDMA_BLK_SIZE_SHIFT); + else + edma_blks = (seg_num - seg) << (KS2_MSMC_SEG_SIZE_SHIFT + - DDR3_EDMA_BLK_SIZE_SHIFT); + + /* Use edma driver to scrub 2GB DDR memory */ + for (dst = base, blks = 0; blks < edma_blks; + blks += DDR3_EDMA_BCNT, dst += DDR3_EDMA_XF_SIZE) { + edma3_set_src_addr(KS2_EDMA0_BASE, + edma_channel.slot, (u32)edma_src); + edma3_set_dest_addr(KS2_EDMA0_BASE, + edma_channel.slot, (u32)dst); + + while (edma3_check_for_transfer(KS2_EDMA0_BASE, + &edma_channel)) + udelay(10); + } + } + + qedma3_stop(KS2_EDMA0_BASE, &edma_channel); + + /* restore the SES MPAX regs */ + msmc_set_ses_mpax(8, 0, mpax); +} + +static void ddr3_ecc_init_range(u32 base) +{ + u32 ecc_val = KS2_DDR3_ECC_EN; + u32 rmw = ddr3_ecc_support_rmw(base); + + if (rmw) + ecc_val |= KS2_DDR3_ECC_RMW_EN; + + __raw_writel(0, base + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET); + + ddr3_ecc_config(base, ecc_val); +} + +void ddr3_enable_ecc(u32 base, int test) +{ + u32 ecc_val = KS2_DDR3_ECC_ENABLE; + u32 rmw = ddr3_ecc_support_rmw(base); + + if (test) + ecc_val |= KS2_DDR3_ECC_ADDR_RNG_1_EN; + + if (!rmw) { + if (!test) + /* by default, disable ecc when rmw = 0 and no + ecc test */ + ecc_val = 0; + } else { + ecc_val |= KS2_DDR3_ECC_RMW_EN; + } + + ddr3_ecc_config(base, ecc_val); +} + +void ddr3_disable_ecc(u32 base) +{ + ddr3_ecc_config(base, 0); +} + +#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) +static void cic_init(u32 base) +{ + /* Disable CIC global interrupts */ + __raw_writel(0, base + KS2_CIC_GLOBAL_ENABLE); + + /* Set to normal mode, no nesting, no priority hold */ + __raw_writel(0, base + KS2_CIC_CTRL); + __raw_writel(0, base + KS2_CIC_HOST_CTRL); + + /* Enable CIC global interrupts */ + __raw_writel(1, base + KS2_CIC_GLOBAL_ENABLE); +} + +static void cic_map_cic_to_gic(u32 base, u32 chan_num, u32 irq_num) +{ + /* Map the system interrupt to a CIC channel */ + __raw_writeb(chan_num, base + KS2_CIC_CHAN_MAP(0) + irq_num); + + /* Enable CIC system interrupt */ + __raw_writel(irq_num, base + KS2_CIC_SYS_ENABLE_IDX_SET); + + /* Enable CIC Host interrupt */ + __raw_writel(chan_num, base + KS2_CIC_HOST_ENABLE_IDX_SET); +} + +static void ddr3_map_ecc_cic2_irq(u32 base) +{ + cic_init(base); + cic_map_cic_to_gic(base, KS2_CIC2_DDR3_ECC_CHAN_NUM, + KS2_CIC2_DDR3_ECC_IRQ_NUM); +} +#endif + +void ddr3_init_ecc(u32 base, u32 ddr3_size) +{ + if (!ddr3_ecc_support_rmw(base)) { + ddr3_disable_ecc(base); + return; + } + + ddr3_ecc_init_range(base); + ddr3_reset_data(CONFIG_SYS_SDRAM_BASE, ddr3_size); + + /* mapping DDR3 ECC system interrupt from CIC2 to GIC */ +#if defined(CONFIG_SOC_K2HK) || defined(CONFIG_SOC_K2L) + ddr3_map_ecc_cic2_irq(KS2_CIC2_BASE); +#endif + ddr3_enable_ecc(base, 0); +} + +void ddr3_check_ecc_int(u32 base) +{ + char *env; + int ecc_test = 0; + u32 value = __raw_readl(base + KS2_DDR3_ECC_INT_STATUS_OFFSET); + + env = getenv("ecc_test"); + if (env) + ecc_test = simple_strtol(env, NULL, 0); + + if (value & KS2_DDR3_WR_ECC_ERR_SYS) + puts("DDR3 ECC write error interrupted\n"); + + if (value & KS2_DDR3_2B_ECC_ERR_SYS) { + puts("DDR3 ECC 2-bit error interrupted\n"); + + if (!ecc_test) { + puts("Reseting the device ...\n"); + reset_cpu(0); + } + } + + value = __raw_readl(base + KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET); + if (value) { + printf("1-bit ECC err count: 0x%x\n", value); + value = __raw_readl(base + + KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET); + printf("1-bit ECC err address log: 0x%x\n", value); + } +} + +void ddr3_reset_ddrphy(void) +{ + u32 tmp; + + /* Assert DDR3A PHY reset */ + tmp = readl(KS2_DDR3APLLCTL1); + tmp |= KS2_DDR3_PLLCTRL_PHY_RESET; + writel(tmp, KS2_DDR3APLLCTL1); + + /* wait 10us to catch the reset */ + udelay(10); + + /* Release DDR3A PHY reset */ + tmp = readl(KS2_DDR3APLLCTL1); + tmp &= ~KS2_DDR3_PLLCTRL_PHY_RESET; + __raw_writel(tmp, KS2_DDR3APLLCTL1); +} + +#ifdef CONFIG_SOC_K2HK +/** + * ddr3_reset_workaround - reset workaround in case if leveling error + * detected for PG 1.0 and 1.1 k2hk SoCs + */ +void ddr3_err_reset_workaround(void) +{ + unsigned int tmp; + unsigned int tmp_a; + unsigned int tmp_b; + + /* + * Check for PGSR0 error bits of DDR3 PHY. + * Check for WLERR, QSGERR, WLAERR, + * RDERR, WDERR, REERR, WEERR error to see if they are set or not + */ + tmp_a = __raw_readl(KS2_DDR3A_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); + tmp_b = __raw_readl(KS2_DDR3B_DDRPHYC + KS2_DDRPHY_PGSR0_OFFSET); + + if (((tmp_a & 0x0FE00000) != 0) || ((tmp_b & 0x0FE00000) != 0)) { + printf("DDR Leveling Error Detected!\n"); + printf("DDR3A PGSR0 = 0x%x\n", tmp_a); + printf("DDR3B PGSR0 = 0x%x\n", tmp_b); + + /* + * Write Keys to KICK registers to enable writes to registers + * in boot config space + */ + __raw_writel(KS2_KICK0_MAGIC, KS2_KICK0); + __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1); + + /* + * Move DDR3A Module out of reset isolation by setting + * MDCTL23[12] = 0 + */ + tmp_a = __raw_readl(KS2_PSC_BASE + + PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); + + tmp_a = PSC_REG_MDCTL_SET_RESET_ISO(tmp_a, 0); + __raw_writel(tmp_a, KS2_PSC_BASE + + PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3A)); + + /* + * Move DDR3B Module out of reset isolation by setting + * MDCTL24[12] = 0 + */ + tmp_b = __raw_readl(KS2_PSC_BASE + + PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); + tmp_b = PSC_REG_MDCTL_SET_RESET_ISO(tmp_b, 0); + __raw_writel(tmp_b, KS2_PSC_BASE + + PSC_REG_MDCTL(KS2_LPSC_EMIF4F_DDR3B)); + + /* + * Write 0x5A69 Key to RSTCTRL[15:0] to unlock writes + * to RSTCTRL and RSTCFG + */ + tmp = __raw_readl(KS2_RSTCTRL); + tmp &= KS2_RSTCTRL_MASK; + tmp |= KS2_RSTCTRL_KEY; + __raw_writel(tmp, KS2_RSTCTRL); + + /* + * Set PLL Controller to drive hard reset on SW trigger by + * setting RSTCFG[13] = 0 + */ + tmp = __raw_readl(KS2_RSTCTRL_RSCFG); + tmp &= ~KS2_RSTYPE_PLL_SOFT; + __raw_writel(tmp, KS2_RSTCTRL_RSCFG); + + reset_cpu(0); + } +} +#endif diff --git a/arch/arm/mach-keystone/init.c b/arch/arm/mach-keystone/init.c new file mode 100644 index 0000000000..c96845c4e2 --- /dev/null +++ b/arch/arm/mach-keystone/init.c @@ -0,0 +1,151 @@ +/* + * Keystone2: Architecture initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_PCI_PORTS 2 +enum pci_mode { + ENDPOINT, + LEGACY_ENDPOINT, + ROOTCOMPLEX, +}; + +#define DEVCFG_MODE_MASK (BIT(2) | BIT(1)) +#define DEVCFG_MODE_SHIFT 1 + +void chip_configuration_unlock(void) +{ + __raw_writel(KS2_KICK0_MAGIC, KS2_KICK0); + __raw_writel(KS2_KICK1_MAGIC, KS2_KICK1); +} + +#ifdef CONFIG_SOC_K2L +void osr_init(void) +{ + u32 i; + u32 j; + u32 val; + u32 base = KS2_OSR_CFG_BASE; + u32 ecc_ctrl[KS2_OSR_NUM_RAM_BANKS]; + + /* Enable the OSR clock domain */ + psc_enable_module(KS2_LPSC_OSR); + + /* Disable OSR ECC check for all the ram banks */ + for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) { + val = i | KS2_OSR_ECC_VEC_TRIG_RD | + (KS2_OSR_ECC_CTRL << KS2_OSR_ECC_VEC_RD_ADDR_SH); + + writel(val , base + KS2_OSR_ECC_VEC); + + /** + * wait till read is done. + * Print should be added after earlyprintk support is added. + */ + for (j = 0; j < 10000; j++) { + val = readl(base + KS2_OSR_ECC_VEC); + if (val & KS2_OSR_ECC_VEC_RD_DONE) + break; + } + + ecc_ctrl[i] = readl(base + KS2_OSR_ECC_CTRL) ^ + KS2_OSR_ECC_CTRL_CHK; + + writel(ecc_ctrl[i], KS2_MSMC_DATA_BASE + i * 4); + writel(ecc_ctrl[i], base + KS2_OSR_ECC_CTRL); + } + + /* Reset OSR memory to all zeros */ + for (i = 0; i < KS2_OSR_SIZE; i += 4) + writel(0, KS2_OSR_DATA_BASE + i); + + /* Enable OSR ECC check for all the ram banks */ + for (i = 0; i < KS2_OSR_NUM_RAM_BANKS; i++) + writel(ecc_ctrl[i] | + KS2_OSR_ECC_CTRL_CHK, base + KS2_OSR_ECC_CTRL); +} +#endif + +/* Function to set up PCIe mode */ +static void config_pcie_mode(int pcie_port, enum pci_mode mode) +{ + u32 val = __raw_readl(KS2_DEVCFG); + + if (pcie_port >= MAX_PCI_PORTS) + return; + + /** + * each pci port has two bits for mode and it starts at + * bit 1. So use port number to get the right bit position. + */ + pcie_port <<= 1; + val &= ~(DEVCFG_MODE_MASK << pcie_port); + val |= ((mode << DEVCFG_MODE_SHIFT) << pcie_port); + __raw_writel(val, KS2_DEVCFG); +} + +int arch_cpu_init(void) +{ + chip_configuration_unlock(); + icache_enable(); + + msmc_share_all_segments(KS2_MSMC_SEGMENT_TETRIS); + msmc_share_all_segments(KS2_MSMC_SEGMENT_NETCP); + msmc_share_all_segments(KS2_MSMC_SEGMENT_QM_PDSP); + msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE0); + + /* Initialize the PCIe-0 to work as Root Complex */ + config_pcie_mode(0, ROOTCOMPLEX); +#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) + msmc_share_all_segments(KS2_MSMC_SEGMENT_PCIE1); + /* Initialize the PCIe-1 to work as Root Complex */ + config_pcie_mode(1, ROOTCOMPLEX); +#endif +#ifdef CONFIG_SOC_K2L + osr_init(); +#endif + + /* + * just initialise the COM2 port so that TI specific + * UART register PWREMU_MGMT is initialized. Linux UART + * driver doesn't handle this. + */ + NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2), + CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE); + + return 0; +} + +void reset_cpu(ulong addr) +{ + volatile u32 *rstctrl = (volatile u32 *)(KS2_RSTCTRL); + u32 tmp; + + tmp = *rstctrl & KS2_RSTCTRL_MASK; + *rstctrl = tmp | KS2_RSTCTRL_KEY; + + *rstctrl &= KS2_RSTCTRL_SWRST; + + for (;;) + ; +} + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +#endif +} diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c new file mode 100644 index 0000000000..11a9357db4 --- /dev/null +++ b/arch/arm/mach-keystone/keystone.c @@ -0,0 +1,87 @@ +/* + * Keystone EVM : Board initialization + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +/** + * cpu_to_bus - swap bytes of the 32-bit data if the device is BE + * @ptr - array of data + * @length - lenght of data array + */ +int cpu_to_bus(u32 *ptr, u32 length) +{ + u32 i; + + if (!(readl(KS2_DEVSTAT) & 0x1)) + for (i = 0; i < length; i++, ptr++) + *ptr = cpu_to_be32(*ptr); + + return 0; +} + +static int turn_off_myself(void) +{ + printf("Turning off ourselves\r\n"); + mon_power_off(0); + + psc_disable_module(KS2_LPSC_TETRIS); + psc_disable_domain(KS2_TETRIS_PWR_DOMAIN); + + asm volatile ("isb\n" + "dsb\n" + "wfi\n"); + + printf("What! Should not see that\n"); + return 0; +} + +static void turn_off_all_dsps(int num_dsps) +{ + int i; + + for (i = 0; i < num_dsps; i++) { + if (psc_disable_module(i + KS2_LPSC_GEM_0)) + printf("Cannot disable module for #%d DSP", i); + + if (psc_disable_domain(i + 8)) + printf("Cannot disable domain for #%d DSP", i); + } +} + +int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return turn_off_myself(); +} + +U_BOOT_CMD( + killme, 1, 0, do_killme_cmd, + "turn off main ARM core", + "turn off main ARM core. Should not live after that :(\n" +); + +int misc_init_r(void) +{ + char *env; + long ks2_debug = 0; + + env = getenv("ks2_debug"); + + if (env) + ks2_debug = simple_strtol(env, NULL, 0); + + if ((ks2_debug & DBG_LEAVE_DSPS_ON) == 0) + turn_off_all_dsps(KS2_NUM_DSPS); + + return 0; +} diff --git a/arch/arm/mach-keystone/msmc.c b/arch/arm/mach-keystone/msmc.c new file mode 100644 index 0000000000..7899141d54 --- /dev/null +++ b/arch/arm/mach-keystone/msmc.c @@ -0,0 +1,94 @@ +/* + * MSMC controller utilities + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +struct mpax { + u32 mpaxl; + u32 mpaxh; +}; + +struct msms_regs { + u32 pid; + u32 _res_04; + u32 smcerrar; + u32 smcerrxr; + u32 smedcc; + u32 smcea; + u32 smsecc; + u32 smpfar; + u32 smpfxr; + u32 smpfr; + u32 smpfcr; + u32 _res_2c; + u32 sbndc[8]; + u32 sbndm; + u32 sbnde; + u32 _res_58; + u32 cfglck; + u32 cfgulck; + u32 cfglckstat; + u32 sms_mpax_lck; + u32 sms_mpax_ulck; + u32 sms_mpax_lckstat; + u32 ses_mpax_lck; + u32 ses_mpax_ulck; + u32 ses_mpax_lckstat; + u32 smestat; + u32 smirstat; + u32 smirc; + u32 smiestat; + u32 smiec; + u32 _res_94_c0[12]; + u32 smncerrar; + u32 smncerrxr; + u32 smncea; + u32 _res_d0_1fc[76]; + struct mpax sms[16][8]; + struct mpax ses[16][8]; +}; + + +void msmc_share_all_segments(int priv_id) +{ + struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; + int j; + + for (j = 0; j < 8; j++) { + msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful; + msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful; + } +} + +void msmc_map_ses_segment(int priv_id, int ses_pair, + u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size) +{ + struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; + + msmc->ses[priv_id][ses_pair].mpaxh = src_pfn << 12 | + (size & 0x1f) | 0x80; + msmc->ses[priv_id][ses_pair].mpaxl = dst_pfn << 8 | 0x3f; +} + +void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax) +{ + struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; + + *mpax++ = msmc->ses[priv_id][ses_pair].mpaxl; + *mpax = msmc->ses[priv_id][ses_pair].mpaxh; +} + +void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax) +{ + struct msms_regs *msmc = (struct msms_regs *)KS2_MSMC_CTRL_BASE; + + msmc->ses[priv_id][ses_pair].mpaxl = *mpax++; + msmc->ses[priv_id][ses_pair].mpaxh = *mpax; +} diff --git a/arch/arm/mach-keystone/psc.c b/arch/arm/mach-keystone/psc.c new file mode 100644 index 0000000000..237e776e87 --- /dev/null +++ b/arch/arm/mach-keystone/psc.c @@ -0,0 +1,227 @@ +/* + * Keystone: PSC configuration module + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +int psc_delay(void) +{ + udelay(10); + return 10; +} + +/* + * FUNCTION PURPOSE: Wait for end of transitional state + * + * DESCRIPTION: Polls pstat for the selected domain and waits for transitions + * to be complete. + * + * Since this is boot loader code it is *ASSUMED* that interrupts + * are disabled and no other core is mucking around with the psc + * at the same time. + * + * Returns 0 when the domain is free. Returns -1 if a timeout + * occurred waiting for the completion. + */ +int psc_wait(u32 domain_num) +{ + u32 retry; + u32 ptstat; + + /* + * Do nothing if the power domain is in transition. This should never + * happen since the boot code is the only software accesses psc. + * It's still remotely possible that the hardware state machines + * initiate transitions. + * Don't trap if the domain (or a module in this domain) is + * stuck in transition. + */ + retry = 0; + + do { + ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT); + ptstat = ptstat & (1 << domain_num); + } while ((ptstat != 0) && ((retry += psc_delay()) < + PSC_PTSTAT_TIMEOUT_LIMIT)); + + if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT) + return -1; + + return 0; +} + +u32 psc_get_domain_num(u32 mod_num) +{ + u32 domain_num; + + /* Get the power domain associated with the module number */ + domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num)); + domain_num = PSC_REG_MDCFG_GET_PD(domain_num); + + return domain_num; +} + +/* + * FUNCTION PURPOSE: Power up/down a module + * + * DESCRIPTION: Powers up/down the requested module and the associated power + * domain if required. No action is taken it the module is + * already powered up/down. + * + * This only controls modules. The domain in which the module + * resides will be left in the power on state. Multiple modules + * can exist in a power domain, so powering down the domain based + * on a single module is not done. + * + * Returns 0 on success, -1 if the module can't be powered up, or + * if there is a timeout waiting for the transition. + */ +int psc_set_state(u32 mod_num, u32 state) +{ + u32 domain_num; + u32 pdctl; + u32 mdctl; + u32 ptcmd; + u32 reset_iso; + u32 v; + + /* + * Get the power domain associated with the module number, and reset + * isolation functionality + */ + v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num)); + domain_num = PSC_REG_MDCFG_GET_PD(v); + reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v); + + /* Wait for the status of the domain/module to be non-transitional */ + if (psc_wait(domain_num) != 0) + return -1; + + /* + * Perform configuration even if the current status matches the + * existing state + * + * Set the next state of the power domain to on. It's OK if the domain + * is always on. This code will not ever power down a domain, so no + * change is made if the new state is power down. + */ + if (state == PSC_REG_VAL_MDCTL_NEXT_ON) { + pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num)); + pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, + PSC_REG_VAL_PDCTL_NEXT_ON); + __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num)); + } + + /* Set the next state for the module to enabled/disabled */ + mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state); + mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso); + __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + + /* Trigger the enable */ + ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD); + ptcmd |= (u32)(1< Date: Fri, 20 Feb 2015 17:04:12 +0900 Subject: kbuild: prepare for moving headers into mach-*/include/mach In U-Boot, SoC-specific headers are placed in arch/$(ARCH)/include/asm/arch-$(SOC) and a symbolic link to that directory is created at the early stage of the build process. Creating and removing a symbolic link during the build is not preferred. In fact, Linux Kernel did away with include/asm-$(ARCH) directories a long time time ago. As for ARM, now it is possible to collect SoC sources into arch/arm/mach-$(SOC). It is also reasonable to move SoC headers into arch/arm/mach-$(SOC)/include/mach. This commit prepares for that. If the directory arch/$(ARCH)/mach-$(SOC)/include/mach exists, a symbolic to that directory is created. Otherwise, a symbolic link to arch/$(ARCH)/include/asm/arch-$(SOC) or arch-$(CPU) is created. Signed-off-by: Masahiro Yamada --- scripts/Makefile.autoconf | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/Makefile.autoconf b/scripts/Makefile.autoconf index 8e9d71f89e..58e1642fb9 100644 --- a/scripts/Makefile.autoconf +++ b/scripts/Makefile.autoconf @@ -85,15 +85,26 @@ include/config.h: scripts/Makefile.autoconf create_symlink FORCE $(call filechk,config_h) # symbolic links +# If arch/$(ARCH)/mach-$(SOC)/include/mach exists, +# make a symbolic link to that directory. +# Otherwise, create a symbolic link to arch/$(ARCH)/include/asm/arch-$(SOC). PHONY += create_symlink create_symlink: ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm - $(Q)ln -fsn $(KBUILD_SRC)/arch/$(ARCH)/include/asm/arch-$(if $(SOC),$(SOC),$(CPU)) \ - include/asm/arch + $(Q)if [ -d $(KBUILD_SRC)/arch/$(ARCH)/mach-$(SOC)/include/mach ]; then \ + dest=arch/$(ARCH)/mach-$(SOC)/include/mach; \ + else \ + dest=arch/$(ARCH)/include/asm/arch-$(if $(SOC),$(SOC),$(CPU)); \ + fi; \ + ln -fsn $(KBUILD_SRC)/$$dest include/asm/arch else - $(Q)ln -fsn arch-$(if $(SOC),$(SOC),$(CPU)) \ - arch/$(ARCH)/include/asm/arch + $(Q)if [ -d arch/$(ARCH)/mach-$(SOC)/include/mach ]; then \ + dest=../../mach-$(SOC)/include/mach; \ + else \ + dest=arch-$(if $(SOC),$(SOC),$(CPU)); \ + fi; \ + ln -fsn $$dest arch/$(ARCH)/include/asm/arch endif PHONY += FORCE -- cgit From af9308276028924ff7f84770ddbd26bd7046d6c5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:13 +0900 Subject: ARM: at91: move SoC headers to mach-at91/include/mach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move arch/arm/include/asm/arch-at91/* -> arch/arm/mach-at91/include/mach/* Signed-off-by: Masahiro Yamada Acked-by: Andreas Bießmann --- MAINTAINERS | 1 - arch/arm/include/asm/arch-at91/at91_common.h | 38 --- arch/arm/include/asm/arch-at91/at91_dbu.h | 42 ---- arch/arm/include/asm/arch-at91/at91_eefc.h | 48 ---- arch/arm/include/asm/arch-at91/at91_emac.h | 127 ---------- arch/arm/include/asm/arch-at91/at91_gpbr.h | 42 ---- arch/arm/include/asm/arch-at91/at91_matrix.h | 238 ------------------- arch/arm/include/asm/arch-at91/at91_mc.h | 81 ------- arch/arm/include/asm/arch-at91/at91_pdc.h | 23 -- arch/arm/include/asm/arch-at91/at91_pio.h | 150 ------------ arch/arm/include/asm/arch-at91/at91_pit.h | 28 --- arch/arm/include/asm/arch-at91/at91_pmc.h | 238 ------------------- arch/arm/include/asm/arch-at91/at91_rstc.h | 50 ---- arch/arm/include/asm/arch-at91/at91_rtt.h | 33 --- arch/arm/include/asm/arch-at91/at91_spi.h | 123 ---------- arch/arm/include/asm/arch-at91/at91_st.h | 30 --- arch/arm/include/asm/arch-at91/at91_tc.h | 61 ----- arch/arm/include/asm/arch-at91/at91_wdt.h | 43 ---- arch/arm/include/asm/arch-at91/at91rm9200.h | 136 ----------- arch/arm/include/asm/arch-at91/at91sam9260.h | 172 -------------- .../arm/include/asm/arch-at91/at91sam9260_matrix.h | 70 ------ arch/arm/include/asm/arch-at91/at91sam9261.h | 136 ----------- .../arm/include/asm/arch-at91/at91sam9261_matrix.h | 56 ----- arch/arm/include/asm/arch-at91/at91sam9263.h | 147 ------------ .../arm/include/asm/arch-at91/at91sam9263_matrix.h | 64 ----- arch/arm/include/asm/arch-at91/at91sam9_matrix.h | 26 -- arch/arm/include/asm/arch-at91/at91sam9_sdramc.h | 117 --------- arch/arm/include/asm/arch-at91/at91sam9_smc.h | 76 ------ arch/arm/include/asm/arch-at91/at91sam9g45.h | 151 ------------ .../arm/include/asm/arch-at91/at91sam9g45_matrix.h | 92 -------- arch/arm/include/asm/arch-at91/at91sam9rl.h | 130 ---------- arch/arm/include/asm/arch-at91/at91sam9rl_matrix.h | 61 ----- arch/arm/include/asm/arch-at91/at91sam9x5.h | 184 --------------- arch/arm/include/asm/arch-at91/at91sam9x5_matrix.h | 99 -------- arch/arm/include/asm/arch-at91/atmel_mpddrc.h | 116 --------- arch/arm/include/asm/arch-at91/atmel_serial.h | 15 -- arch/arm/include/asm/arch-at91/atmel_usba_udc.h | 64 ----- arch/arm/include/asm/arch-at91/clk.h | 122 ---------- arch/arm/include/asm/arch-at91/gpio.h | 262 --------------------- arch/arm/include/asm/arch-at91/hardware.h | 34 --- arch/arm/include/asm/arch-at91/sama5_matrix.h | 37 --- arch/arm/include/asm/arch-at91/sama5_sfr.h | 38 --- arch/arm/include/asm/arch-at91/sama5d3.h | 210 ----------------- arch/arm/include/asm/arch-at91/sama5d3_smc.h | 77 ------ arch/arm/include/asm/arch-at91/sama5d4.h | 208 ---------------- arch/arm/mach-at91/include/mach/at91_common.h | 38 +++ arch/arm/mach-at91/include/mach/at91_dbu.h | 42 ++++ arch/arm/mach-at91/include/mach/at91_eefc.h | 48 ++++ arch/arm/mach-at91/include/mach/at91_emac.h | 127 ++++++++++ arch/arm/mach-at91/include/mach/at91_gpbr.h | 42 ++++ arch/arm/mach-at91/include/mach/at91_matrix.h | 238 +++++++++++++++++++ arch/arm/mach-at91/include/mach/at91_mc.h | 81 +++++++ arch/arm/mach-at91/include/mach/at91_pdc.h | 23 ++ arch/arm/mach-at91/include/mach/at91_pio.h | 150 ++++++++++++ arch/arm/mach-at91/include/mach/at91_pit.h | 28 +++ arch/arm/mach-at91/include/mach/at91_pmc.h | 238 +++++++++++++++++++ arch/arm/mach-at91/include/mach/at91_rstc.h | 50 ++++ arch/arm/mach-at91/include/mach/at91_rtt.h | 33 +++ arch/arm/mach-at91/include/mach/at91_spi.h | 123 ++++++++++ arch/arm/mach-at91/include/mach/at91_st.h | 30 +++ arch/arm/mach-at91/include/mach/at91_tc.h | 61 +++++ arch/arm/mach-at91/include/mach/at91_wdt.h | 43 ++++ arch/arm/mach-at91/include/mach/at91rm9200.h | 136 +++++++++++ arch/arm/mach-at91/include/mach/at91sam9260.h | 172 ++++++++++++++ .../mach-at91/include/mach/at91sam9260_matrix.h | 70 ++++++ arch/arm/mach-at91/include/mach/at91sam9261.h | 136 +++++++++++ .../mach-at91/include/mach/at91sam9261_matrix.h | 56 +++++ arch/arm/mach-at91/include/mach/at91sam9263.h | 147 ++++++++++++ .../mach-at91/include/mach/at91sam9263_matrix.h | 64 +++++ arch/arm/mach-at91/include/mach/at91sam9_matrix.h | 26 ++ arch/arm/mach-at91/include/mach/at91sam9_sdramc.h | 117 +++++++++ arch/arm/mach-at91/include/mach/at91sam9_smc.h | 76 ++++++ arch/arm/mach-at91/include/mach/at91sam9g45.h | 151 ++++++++++++ .../mach-at91/include/mach/at91sam9g45_matrix.h | 92 ++++++++ arch/arm/mach-at91/include/mach/at91sam9rl.h | 130 ++++++++++ .../arm/mach-at91/include/mach/at91sam9rl_matrix.h | 61 +++++ arch/arm/mach-at91/include/mach/at91sam9x5.h | 184 +++++++++++++++ .../arm/mach-at91/include/mach/at91sam9x5_matrix.h | 99 ++++++++ arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 116 +++++++++ arch/arm/mach-at91/include/mach/atmel_serial.h | 15 ++ arch/arm/mach-at91/include/mach/atmel_usba_udc.h | 64 +++++ arch/arm/mach-at91/include/mach/clk.h | 122 ++++++++++ arch/arm/mach-at91/include/mach/gpio.h | 262 +++++++++++++++++++++ arch/arm/mach-at91/include/mach/hardware.h | 34 +++ arch/arm/mach-at91/include/mach/sama5_matrix.h | 37 +++ arch/arm/mach-at91/include/mach/sama5_sfr.h | 38 +++ arch/arm/mach-at91/include/mach/sama5d3.h | 210 +++++++++++++++++ arch/arm/mach-at91/include/mach/sama5d3_smc.h | 77 ++++++ arch/arm/mach-at91/include/mach/sama5d4.h | 208 ++++++++++++++++ 89 files changed, 4295 insertions(+), 4296 deletions(-) delete mode 100644 arch/arm/include/asm/arch-at91/at91_common.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_dbu.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_eefc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_emac.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_gpbr.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_mc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_pdc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_pio.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_pit.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_pmc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_rstc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_rtt.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_spi.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_st.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_tc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91_wdt.h delete mode 100644 arch/arm/include/asm/arch-at91/at91rm9200.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9260.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9260_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9261.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9261_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9263.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9263_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9_sdramc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9_smc.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9g45.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9g45_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9rl.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9rl_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9x5.h delete mode 100644 arch/arm/include/asm/arch-at91/at91sam9x5_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/atmel_mpddrc.h delete mode 100644 arch/arm/include/asm/arch-at91/atmel_serial.h delete mode 100644 arch/arm/include/asm/arch-at91/atmel_usba_udc.h delete mode 100644 arch/arm/include/asm/arch-at91/clk.h delete mode 100644 arch/arm/include/asm/arch-at91/gpio.h delete mode 100644 arch/arm/include/asm/arch-at91/hardware.h delete mode 100644 arch/arm/include/asm/arch-at91/sama5_matrix.h delete mode 100644 arch/arm/include/asm/arch-at91/sama5_sfr.h delete mode 100644 arch/arm/include/asm/arch-at91/sama5d3.h delete mode 100644 arch/arm/include/asm/arch-at91/sama5d3_smc.h delete mode 100644 arch/arm/include/asm/arch-at91/sama5d4.h create mode 100644 arch/arm/mach-at91/include/mach/at91_common.h create mode 100644 arch/arm/mach-at91/include/mach/at91_dbu.h create mode 100644 arch/arm/mach-at91/include/mach/at91_eefc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_emac.h create mode 100644 arch/arm/mach-at91/include/mach/at91_gpbr.h create mode 100644 arch/arm/mach-at91/include/mach/at91_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91_mc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_pdc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_pio.h create mode 100644 arch/arm/mach-at91/include/mach/at91_pit.h create mode 100644 arch/arm/mach-at91/include/mach/at91_pmc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_rstc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_rtt.h create mode 100644 arch/arm/mach-at91/include/mach/at91_spi.h create mode 100644 arch/arm/mach-at91/include/mach/at91_st.h create mode 100644 arch/arm/mach-at91/include/mach/at91_tc.h create mode 100644 arch/arm/mach-at91/include/mach/at91_wdt.h create mode 100644 arch/arm/mach-at91/include/mach/at91rm9200.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9260.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9260_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9261.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9261_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9263.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9263_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9_sdramc.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9_smc.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9g45.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9rl.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9x5.h create mode 100644 arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/atmel_mpddrc.h create mode 100644 arch/arm/mach-at91/include/mach/atmel_serial.h create mode 100644 arch/arm/mach-at91/include/mach/atmel_usba_udc.h create mode 100644 arch/arm/mach-at91/include/mach/clk.h create mode 100644 arch/arm/mach-at91/include/mach/gpio.h create mode 100644 arch/arm/mach-at91/include/mach/hardware.h create mode 100644 arch/arm/mach-at91/include/mach/sama5_matrix.h create mode 100644 arch/arm/mach-at91/include/mach/sama5_sfr.h create mode 100644 arch/arm/mach-at91/include/mach/sama5d3.h create mode 100644 arch/arm/mach-at91/include/mach/sama5d3_smc.h create mode 100644 arch/arm/mach-at91/include/mach/sama5d4.h diff --git a/MAINTAINERS b/MAINTAINERS index e4edf45e8d..7a3e963100 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -77,7 +77,6 @@ M: Andreas Bießmann S: Maintained T: git git://git.denx.de/u-boot-atmel.git F: arch/arm/mach-at91/ -F: arch/arm/include/asm/arch-at91/ ARM FREESCALE IMX M: Stefano Babic diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h deleted file mode 100644 index efcd74ed90..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_COMMON_H -#define AT91_COMMON_H - -void at91_can_hw_init(void); -void at91_gmac_hw_init(void); -void at91_macb_hw_init(void); -void at91_mci_hw_init(void); -void at91_serial0_hw_init(void); -void at91_serial1_hw_init(void); -void at91_serial2_hw_init(void); -void at91_seriald_hw_init(void); -void at91_spi0_hw_init(unsigned long cs_mask); -void at91_spi1_hw_init(unsigned long cs_mask); -void at91_udp_hw_init(void); -void at91_uhp_hw_init(void); -void at91_lcd_hw_init(void); -void at91_plla_init(u32 pllar); -void at91_pllb_init(u32 pllar); -void at91_mck_init(u32 mckr); -void at91_pmc_init(void); -void mem_init(void); -void at91_phy_reset(void); -void at91_sdram_hw_init(void); -void at91_mck_init(u32 mckr); -void at91_spl_board_init(void); -void at91_disable_wdt(void); -void matrix_init(void); -void redirect_int_from_saic_to_aic(void); - -#endif /* AT91_COMMON_H */ diff --git a/arch/arm/include/asm/arch-at91/at91_dbu.h b/arch/arm/include/asm/arch-at91/at91_dbu.h deleted file mode 100644 index 7346fc0569..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_dbu.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * - * Debug Unit - * Based on AT91SAM9XE datasheet - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_DBU_H -#define AT91_DBU_H - -#ifndef __ASSEMBLY__ - -typedef struct at91_dbu { - u32 cr; /* Control Register WO */ - u32 mr; /* Mode Register RW */ - u32 ier; /* Interrupt Enable Register WO */ - u32 idr; /* Interrupt Disable Register WO */ - u32 imr; /* Interrupt Mask Register RO */ - u32 sr; /* Status Register RO */ - u32 rhr; /* Receive Holding Register RO */ - u32 thr; /* Transmit Holding Register WO */ - u32 brgr; /* Baud Rate Generator Register RW */ - u32 res1[7];/* 0x0024 - 0x003C Reserved */ - u32 cidr; /* Chip ID Register RO */ - u32 exid; /* Chip ID Extension Register RO */ - u32 fnr; /* Force NTRST Register RW */ -} at91_dbu_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_DBU_CID_ARCH_MASK 0x0ff00000 -#define AT91_DBU_CID_ARCH_9xx 0x01900000 -#define AT91_DBU_CID_ARCH_9XExx 0x02900000 - -#define AT91_DBU_CIDR_MASK 0x1f -#define AT91_DBU_CIDR 0x40 -#define AT91_DBU_EXID 0x44 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_eefc.h b/arch/arm/include/asm/arch-at91/at91_eefc.h deleted file mode 100644 index 7ffbaee27d..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_eefc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * - * Enhanced Embedded Flash Controller - * Based on AT91SAM9XE datasheet - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_EEFC_H -#define AT91_EEFC_H - -#ifndef __ASSEMBLY__ - -typedef struct at91_eefc { - u32 fmr; /* Flash Mode Register RW */ - u32 fcr; /* Flash Command Register WO */ - u32 fsr; /* Flash Status Register RO */ - u32 frr; /* Flash Result Register RO */ -} at91_eefc_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_EEFC_FMR_FWS_MASK 0x00000f00 -#define AT91_EEFC_FMR_FRDY_BIT 0x00000001 - -#define AT91_EEFC_FCR_KEY 0x5a000000 -#define AT91_EEFC_FCR_FARG_MASK 0x00ffff00 -#define AT91_EEFC_FCR_FARG_SHIFT 8 -#define AT91_EEFC_FCR_FCMD_GETD 0x0 -#define AT91_EEFC_FCR_FCMD_WP 0x1 -#define AT91_EEFC_FCR_FCMD_WPL 0x2 -#define AT91_EEFC_FCR_FCMD_EWP 0x3 -#define AT91_EEFC_FCR_FCMD_EWPL 0x4 -#define AT91_EEFC_FCR_FCMD_EA 0x5 -#define AT91_EEFC_FCR_FCMD_SLB 0x8 -#define AT91_EEFC_FCR_FCMD_CLB 0x9 -#define AT91_EEFC_FCR_FCMD_GLB 0xA -#define AT91_EEFC_FCR_FCMD_SGPB 0xB -#define AT91_EEFC_FCR_FCMD_CGPB 0xC -#define AT91_EEFC_FCR_FCMD_GGPB 0xD - -#define AT91_EEFC_FSR_FRDY 1 -#define AT91_EEFC_FSR_FCMDE 2 -#define AT91_EEFC_FSR_FLOCKE 4 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_emac.h b/arch/arm/include/asm/arch-at91/at91_emac.h deleted file mode 100644 index a0d74ab660..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_emac.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * based on AT91RM9200 datasheet revision I (36. Ethernet MAC (EMAC)) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_H -#define AT91_H - -typedef struct at91_emac { - u32 ctl; - u32 cfg; - u32 sr; - u32 tar; - u32 tcr; - u32 tsr; - u32 rbqp; - u32 reserved0; - u32 rsr; - u32 isr; - u32 ier; - u32 idr; - u32 imr; - u32 man; - u32 reserved1[2]; - u32 fra; - u32 scol; - u32 mocl; - u32 ok; - u32 seqe; - u32 ale; - u32 dte; - u32 lcol; - u32 ecol; - u32 cse; - u32 tue; - u32 cde; - u32 elr; - u32 rjb; - u32 usf; - u32 sqee; - u32 drfc; - u32 reserved2[3]; - u32 hsh; - u32 hsl; - u32 sa1l; - u32 sa1h; - u32 sa2l; - u32 sa2h; - u32 sa3l; - u32 sa3h; - u32 sa4l; - u32 sa4h; -} at91_emac_t; - -#define AT91_EMAC_CTL_LB 0x0001 -#define AT91_EMAC_CTL_LBL 0x0002 -#define AT91_EMAC_CTL_RE 0x0004 -#define AT91_EMAC_CTL_TE 0x0008 -#define AT91_EMAC_CTL_MPE 0x0010 -#define AT91_EMAC_CTL_CSR 0x0020 -#define AT91_EMAC_CTL_ISR 0x0040 -#define AT91_EMAC_CTL_WES 0x0080 -#define AT91_EMAC_CTL_BP 0x1000 - -#define AT91_EMAC_CFG_SPD 0x0001 -#define AT91_EMAC_CFG_FD 0x0002 -#define AT91_EMAC_CFG_BR 0x0004 -#define AT91_EMAC_CFG_CAF 0x0010 -#define AT91_EMAC_CFG_NBC 0x0020 -#define AT91_EMAC_CFG_MTI 0x0040 -#define AT91_EMAC_CFG_UNI 0x0080 -#define AT91_EMAC_CFG_BIG 0x0100 -#define AT91_EMAC_CFG_EAE 0x0200 -#define AT91_EMAC_CFG_CLK_MASK 0xFFFFF3FF -#define AT91_EMAC_CFG_MCLK_8 0x0000 -#define AT91_EMAC_CFG_MCLK_16 0x0400 -#define AT91_EMAC_CFG_MCLK_32 0x0800 -#define AT91_EMAC_CFG_MCLK_64 0x0C00 -#define AT91_EMAC_CFG_RTY 0x1000 -#define AT91_EMAC_CFG_RMII 0x2000 - -#define AT91_EMAC_SR_LINK 0x0001 -#define AT91_EMAC_SR_MDIO 0x0002 -#define AT91_EMAC_SR_IDLE 0x0004 - -#define AT91_EMAC_TCR_LEN(x) (x & 0x7FF) -#define AT91_EMAC_TCR_NCRC 0x8000 - -#define AT91_EMAC_TSR_OVR 0x0001 -#define AT91_EMAC_TSR_COL 0x0002 -#define AT91_EMAC_TSR_RLE 0x0004 -#define AT91_EMAC_TSR_TXIDLE 0x0008 -#define AT91_EMAC_TSR_BNQ 0x0010 -#define AT91_EMAC_TSR_COMP 0x0020 -#define AT91_EMAC_TSR_UND 0x0040 - -#define AT91_EMAC_RSR_BNA 0x0001 -#define AT91_EMAC_RSR_REC 0x0002 -#define AT91_EMAC_RSR_OVR 0x0004 - -/* ISR, IER, IDR, IMR use the same bits */ -#define AT91_EMAC_IxR_DONE 0x0001 -#define AT91_EMAC_IxR_RCOM 0x0002 -#define AT91_EMAC_IxR_RBNA 0x0004 -#define AT91_EMAC_IxR_TOVR 0x0008 -#define AT91_EMAC_IxR_TUND 0x0010 -#define AT91_EMAC_IxR_RTRY 0x0020 -#define AT91_EMAC_IxR_TBRE 0x0040 -#define AT91_EMAC_IxR_TCOM 0x0080 -#define AT91_EMAC_IxR_TIDLE 0x0100 -#define AT91_EMAC_IxR_LINK 0x0200 -#define AT91_EMAC_IxR_ROVR 0x0400 -#define AT91_EMAC_IxR_HRESP 0x0800 - -#define AT91_EMAC_MAN_DATA_MASK 0xFFFF -#define AT91_EMAC_MAN_CODE_802_3 0x00020000 -#define AT91_EMAC_MAN_REGA(reg) ((reg & 0x1F) << 18) -#define AT91_EMAC_MAN_PHYA(phy) ((phy & 0x1F) << 23) -#define AT91_EMAC_MAN_RW_R 0x20000000 -#define AT91_EMAC_MAN_RW_W 0x10000000 -#define AT91_EMAC_MAN_HIGH 0x40000000 -#define AT91_EMAC_MAN_LOW 0x80000000 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_gpbr.h b/arch/arm/include/asm/arch-at91/at91_gpbr.h deleted file mode 100644 index e781481e88..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_gpbr.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * - * General Purpose Backup Registers - * Based on AT91SAM9XE datasheet - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_GPBR_H -#define AT91_GPBR_H - -/* - * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile - * 32 Bit registers (buffered by the Vbu power). - * - * Please consider carefully before using this resource for tasks - * that do not really need nonvolatile registers. Maybe you can - * store information in EEPROM or FLASH instead. - * - * However, if you use a GPBR please document its use here and - * reference the define in your code! - * - * known typical uses of the GPBRs: - * GPBR[0]: offset for RTT timekeeping (u-boot, kernel) - * GPBR[1]: unused - * GPBR[2]: unused - * GPBR[3]: bootcount (u-boot) - */ -#define AT91_GPBR_INDEX_TIMEOFF 0 -#define AT91_GPBR_INDEX_BOOTCOUNT 3 - -#ifndef __ASSEMBLY__ - -typedef struct at91_gpbr { - u32 reg[4]; -} at91_gpbr_t; - -#endif /* __ASSEMBLY__ */ - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_matrix.h b/arch/arm/include/asm/arch-at91/at91_matrix.h deleted file mode 100644 index 2379dd40f8..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_matrix.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_MATRIX_H -#define AT91_MATRIX_H - -#ifdef __ASSEMBLY__ - -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) -#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x11C) -#elif defined(CONFIG_AT91SAM9261) -#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x30) -#elif defined(CONFIG_AT91SAM9263) -#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x120) -#elif defined(CONFIG_AT91SAM9G45) -#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x128) -#else -#error AT91_ASM_MATRIX_CSA0 is not definied for current CPU -#endif - -#define AT91_ASM_MATRIX_MCFG ATMEL_BASE_MATRIX - -#else -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) -#define AT91_MATRIX_MASTERS 6 -#define AT91_MATRIX_SLAVES 5 -#elif defined(CONFIG_AT91SAM9261) -#define AT91_MATRIX_MASTERS 1 -#define AT91_MATRIX_SLAVES 5 -#elif defined(CONFIG_AT91SAM9263) -#define AT91_MATRIX_MASTERS 9 -#define AT91_MATRIX_SLAVES 7 -#elif defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_MASTERS 11 -#define AT91_MATRIX_SLAVES 8 -#else -#error CPU not supported. Please update at91_matrix.h -#endif - -typedef struct at91_priority { - u32 a; - u32 b; -} at91_priority_t; - -typedef struct at91_matrix { - u32 mcfg[AT91_MATRIX_MASTERS]; -#if defined(CONFIG_AT91SAM9261) - u32 scfg[AT91_MATRIX_SLAVES]; - u32 res61_1[3]; - u32 tcr; - u32 res61_2[2]; - u32 csa; - u32 pucr; - u32 res61_3[114]; -#else - u32 reserve1[16 - AT91_MATRIX_MASTERS]; - u32 scfg[AT91_MATRIX_SLAVES]; - u32 reserve2[16 - AT91_MATRIX_SLAVES]; - at91_priority_t pr[AT91_MATRIX_SLAVES]; - u32 reserve3[32 - (2 * AT91_MATRIX_SLAVES)]; - u32 mrcr; /* 0x100 Master Remap Control */ - u32 reserve4[3]; -#if defined(CONFIG_AT91SAM9G45) - u32 ccr[52]; /* 0x110 - 0x1E0 Chip Configuration */ - u32 womr; /* 0x1E4 Write Protect Mode */ - u32 wpsr; /* 0x1E8 Write Protect Status */ - u32 resg45_1[10]; -#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) - u32 res60_1[3]; - u32 csa; - u32 res60_2[56]; -#elif defined(CONFIG_AT91SAM9263) - u32 res63_1; - u32 tcmr; - u32 res63_2[2]; - u32 csa[2]; - u32 res63_3[54]; -#else - u32 reserve5[60]; -#endif -#endif -} at91_matrix_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_CSA_DBPUC 0x00000100 -#define AT91_MATRIX_CSA_VDDIOMSEL_1_8V 0x00000000 -#define AT91_MATRIX_CSA_VDDIOMSEL_3_3V 0x00010000 - -#define AT91_MATRIX_CSA_EBI_CS1A 0x00000002 -#define AT91_MATRIX_CSA_EBI_CS3A 0x00000008 -#define AT91_MATRIX_CSA_EBI_CS4A 0x00000010 -#define AT91_MATRIX_CSA_EBI_CS5A 0x00000020 - -#define AT91_MATRIX_CSA_EBI1_CS2A 0x00000008 - -#if defined CONFIG_AT91SAM9261 -/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_MCFG_RCB0 (1 << 0) -/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_MCFG_RCB1 (1 << 1) -#endif - -/* Undefined Length Burst Type */ -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) || \ - defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_MCFG_ULBT_INFINITE 0x00000000 -#define AT91_MATRIX_MCFG_ULBT_SINGLE 0x00000001 -#define AT91_MATRIX_MCFG_ULBT_FOUR 0x00000002 -#define AT91_MATRIX_MCFG_ULBT_EIGHT 0x00000003 -#define AT91_MATRIX_MCFG_ULBT_SIXTEEN 0x00000004 -#endif -#if defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_MCFG_ULBT_THIRTYTWO 0x00000005 -#define AT91_MATRIX_MCFG_ULBT_SIXTYFOUR 0x00000006 -#define AT91_MATRIX_MCFG_ULBT_128 0x00000007 -#endif - -/* Default Master Type */ -#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_NONE 0x00000000 -#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_LAST 0x00010000 -#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_FIXED 0x00020000 - -/* Fixed Index of Default Master */ -#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9263) -#define AT91_MATRIX_SCFG_FIXED_DEFMSTR(x) ((x & 0xf) << 18) -#elif defined(CONFIG_AT91SAM9261) || defined(CONFIG_AT91SAM9260) -#define AT91_MATRIX_SCFG_FIXED_DEFMSTR(x) ((x & 7) << 18) -#endif - -/* Maximum Number of Allowed Cycles for a Burst */ -#if defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_SCFG_SLOT_CYCLE(x) ((x & 0x1ff) << 0) -#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ - defined(CONFIG_AT91SAM9263) -#define AT91_MATRIX_SCFG_SLOT_CYCLE(x) ((x & 0xff) << 0) -#endif - -/* Arbitration Type */ -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) -#define AT91_MATRIX_SCFG_ARBT_ROUND_ROBIN 0x00000000 -#define AT91_MATRIX_SCFG_ARBT_FIXED_PRIORITY 0x01000000 -#endif - -/* Master Remap Control Register */ -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) || \ - defined(CONFIG_AT91SAM9G45) -/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ -#define AT91_MATRIX_MRCR_RCB0 (1 << 0) -/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ -#define AT91_MATRIX_MRCR_RCB1 (1 << 1) -#endif -#if defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_MRCR_RCB2 0x00000004 -#define AT91_MATRIX_MRCR_RCB3 0x00000008 -#define AT91_MATRIX_MRCR_RCB4 0x00000010 -#define AT91_MATRIX_MRCR_RCB5 0x00000020 -#define AT91_MATRIX_MRCR_RCB6 0x00000040 -#define AT91_MATRIX_MRCR_RCB7 0x00000080 -#define AT91_MATRIX_MRCR_RCB8 0x00000100 -#endif -#if defined(CONFIG_AT91SAM9G45) -#define AT91_MATRIX_MRCR_RCB9 0x00000200 -#define AT91_MATRIX_MRCR_RCB10 0x00000400 -#define AT91_MATRIX_MRCR_RCB11 0x00000800 -#endif - -/* TCM Configuration Register */ -#if defined(CONFIG_AT91SAM9G45) -/* Size of ITCM enabled memory block */ -#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 -#define AT91_MATRIX_TCMR_ITCM_32 0x00000040 -/* Size of DTCM enabled memory block */ -#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 -#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 -#define AT91_MATRIX_TCMR_DTCM_64 0x00000070 -/* Wait state TCM register */ -#define AT91_MATRIX_TCMR_TCM_NO_WS 0x00000000 -#define AT91_MATRIX_TCMR_TCM_ONE_WS 0x00000800 -#endif -#if defined(CONFIG_AT91SAM9263) -/* Size of ITCM enabled memory block */ -#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 -#define AT91_MATRIX_TCMR_ITCM_16 0x00000005 -#define AT91_MATRIX_TCMR_ITCM_32 0x00000006 -/* Size of DTCM enabled memory block */ -#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 -#define AT91_MATRIX_TCMR_DTCM_16 0x00000050 -#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 -#endif -#if defined(CONFIG_AT91SAM9261) -/* Size of ITCM enabled memory block */ -#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 -#define AT91_MATRIX_TCMR_ITCM_16 0x00000005 -#define AT91_MATRIX_TCMR_ITCM_32 0x00000006 -#define AT91_MATRIX_TCMR_ITCM_64 0x00000007 -/* Size of DTCM enabled memory block */ -#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 -#define AT91_MATRIX_TCMR_DTCM_16 0x00000050 -#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 -#define AT91_MATRIX_TCMR_DTCM_64 0x00000070 -#endif - -#if defined(CONFIG_AT91SAM9G45) -/* Video Mode Configuration Register */ -#define AT91C_MATRIX_VDEC_SEL_OFF 0x00000000 -#define AT91C_MATRIX_VDEC_SEL_ON 0x00000001 -/* Write Protect Mode Register */ -#define AT91_MATRIX_WPMR_WP_WPDIS 0x00000000 -#define AT91_MATRIX_WPMR_WP_WPEN 0x00000001 -#define AT91_MATRIX_WPMR_WPKEY 0xFFFFFF00 /* Write Protect KEY */ -/* Write Protect Status Register */ -#define AT91_MATRIX_WPSR_NO_WPV 0x00000000 -#define AT91_MATRIX_WPSR_WPV 0x00000001 -#define AT91_MATRIX_WPSR_WPVSRC 0x00FFFF00 /* Write Protect Violation Source */ -#endif - -/* USB Pad Pull-Up Control Register */ -#if defined(CONFIG_AT91SAM9261) -#define AT91_MATRIX_USBPUCR_PUON 0x40000000 -#endif - -#define AT91_MATRIX_PRA_M0(x) ((x & 3) << 0) /* Master 0 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M1(x) ((x & 3) << 4) /* Master 1 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M2(x) ((x & 3) << 8) /* Master 2 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M3(x) ((x & 3) << 12) /* Master 3 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M4(x) ((x & 3) << 16) /* Master 4 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M5(x) ((x & 3) << 20) /* Master 5 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M6(x) ((x & 3) << 24) /* Master 6 Priority Reg. A*/ -#define AT91_MATRIX_PRA_M7(x) ((x & 3) << 28) /* Master 7 Priority Reg. A*/ -#define AT91_MATRIX_PRB_M8(x) ((x & 3) << 0) /* Master 8 Priority Reg. B) */ -#define AT91_MATRIX_PRB_M9(x) ((x & 3) << 4) /* Master 9 Priority Reg. B) */ -#define AT91_MATRIX_PRB_M10(x) ((x & 3) << 8) /* Master 10 Priority Reg. B) */ - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_mc.h b/arch/arm/include/asm/arch-at91/at91_mc.h deleted file mode 100644 index 2ace77931d..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_mc.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_MC_H -#define AT91_MC_H - -#define AT91_ASM_MC_EBI_CSA (ATMEL_BASE_MC + 0x60) -#define AT91_ASM_MC_EBI_CFG (ATMEL_BASE_MC + 0x64) -#define AT91_ASM_MC_SMC_CSR0 (ATMEL_BASE_MC + 0x70) -#define AT91_ASM_MC_SDRAMC_MR (ATMEL_BASE_MC + 0x90) -#define AT91_ASM_MC_SDRAMC_TR (ATMEL_BASE_MC + 0x94) -#define AT91_ASM_MC_SDRAMC_CR (ATMEL_BASE_MC + 0x98) - -#ifndef __ASSEMBLY__ - -typedef struct at91_ebi { - u32 csa; /* 0x00 Chip Select Assignment Register */ - u32 cfgr; /* 0x04 Configuration Register */ - u32 reserved[2]; -} at91_ebi_t; - -#define AT91_EBI_CSA_CS0A 0x0001 -#define AT91_EBI_CSA_CS1A 0x0002 - -#define AT91_EBI_CSA_CS3A 0x0008 -#define AT91_EBI_CSA_CS4A 0x0010 - -typedef struct at91_sdramc { - u32 mr; /* 0x00 SDRAMC Mode Register */ - u32 tr; /* 0x04 SDRAMC Refresh Timer Register */ - u32 cr; /* 0x08 SDRAMC Configuration Register */ - u32 ssr; /* 0x0C SDRAMC Self Refresh Register */ - u32 lpr; /* 0x10 SDRAMC Low Power Register */ - u32 ier; /* 0x14 SDRAMC Interrupt Enable Register */ - u32 idr; /* 0x18 SDRAMC Interrupt Disable Register */ - u32 imr; /* 0x1C SDRAMC Interrupt Mask Register */ - u32 icr; /* 0x20 SDRAMC Interrupt Status Register */ - u32 reserved[3]; -} at91_sdramc_t; - -typedef struct at91_smc { - u32 csr[8]; /* 0x00 SDRAMC Mode Register */ -} at91_smc_t; - -#define AT91_SMC_CSR_RWHOLD(x) ((x & 0x7) << 28) -#define AT91_SMC_CSR_RWSETUP(x) ((x & 0x7) << 24) -#define AT91_SMC_CSR_ACSS_STANDARD 0x00000000 -#define AT91_SMC_CSR_ACSS_1CYCLE 0x00010000 -#define AT91_SMC_CSR_ACSS_2CYCLE 0x00020000 -#define AT91_SMC_CSR_ACSS_3CYCLE 0x00030000 -#define AT91_SMC_CSR_DRP 0x00008000 -#define AT91_SMC_CSR_DBW_8 0x00004000 -#define AT91_SMC_CSR_DBW_16 0x00002000 -#define AT91_SMC_CSR_BAT_8 0x00000000 -#define AT91_SMC_CSR_BAT_16 0x00001000 -#define AT91_SMC_CSR_TDF(x) ((x & 0xF) << 8) -#define AT91_SMC_CSR_WSEN 0x00000080 -#define AT91_SMC_CSR_NWS(x) (x & 0x7F) - -typedef struct at91_bfc { - u32 mr; /* 0x00 SDRAMC Mode Register */ -} at91_bfc_t; - -typedef struct at91_mc { - u32 rcr; /* 0x00 MC Remap Control Register */ - u32 asr; /* 0x04 MC Abort Status Register */ - u32 aasr; /* 0x08 MC Abort Address Status Reg */ - u32 mpr; /* 0x0C MC Master Priority Register */ - u32 reserved1[20]; /* 0x10-0x5C */ - at91_ebi_t ebi; /* 0x60 - 0x6C EBI */ - at91_smc_t smc; /* 0x70 - 0x8C SMC User Interface */ - at91_sdramc_t sdramc; /* 0x90 - 0xBC SDRAMC User Interface */ - at91_bfc_t bfc; /* 0xC0 BFC User Interface */ - u32 reserved2[15]; -} at91_mc_t; - -#endif -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pdc.h b/arch/arm/include/asm/arch-at91/at91_pdc.h deleted file mode 100644 index 832ebb51c1..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_pdc.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_PDC_H -#define AT91_PDC_H - -typedef struct at91_pdc { - u32 rpr; /* 0x100 Receive Pointer Register */ - u32 rcr; /* 0x104 Receive Counter Register */ - u32 tpr; /* 0x108 Transmit Pointer Register */ - u32 tcr; /* 0x10C Transmit Counter Register */ - u32 pnpr; /* 0x110 Receive Next Pointer Register */ - u32 pncr; /* 0x114 Receive Next Counter Register */ - u32 tnpr; /* 0x118 Transmit Next Pointer Register */ - u32 tncr; /* 0x11C Transmit Next Counter Register */ - u32 ptcr; /* 0x120 Transfer Control Register */ - u32 ptsr; /* 0x124 Transfer Status Register */ -} at91_pdc_t; - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pio.h b/arch/arm/include/asm/arch-at91/at91_pio.h deleted file mode 100644 index 301227880a..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_pio.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91_pio.h] - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * Parallel I/O Controller (PIO) - System peripherals registers. - * Based on AT91RM9200 datasheet revision E. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_PIO_H -#define AT91_PIO_H - - -#define AT91_ASM_PIO_RANGE 0x200 -#define AT91_ASM_PIOC_ASR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x70) -#define AT91_ASM_PIOC_BSR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x74) -#define AT91_ASM_PIOC_PDR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x04) -#define AT91_ASM_PIOC_PUDR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x60) - -#define AT91_ASM_PIOD_PDR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x04) -#define AT91_ASM_PIOD_PUDR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x60) -#define AT91_ASM_PIOD_ASR \ - (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x70) - -#ifndef __ASSEMBLY__ - -typedef struct at91_port { - u32 per; /* 0x00 PIO Enable Register */ - u32 pdr; /* 0x04 PIO Disable Register */ - u32 psr; /* 0x08 PIO Status Register */ - u32 reserved0; - u32 oer; /* 0x10 Output Enable Register */ - u32 odr; /* 0x14 Output Disable Registerr */ - u32 osr; /* 0x18 Output Status Register */ - u32 reserved1; - u32 ifer; /* 0x20 Input Filter Enable Register */ - u32 ifdr; /* 0x24 Input Filter Disable Register */ - u32 ifsr; /* 0x28 Input Filter Status Register */ - u32 reserved2; - u32 sodr; /* 0x30 Set Output Data Register */ - u32 codr; /* 0x34 Clear Output Data Register */ - u32 odsr; /* 0x38 Output Data Status Register */ - u32 pdsr; /* 0x3C Pin Data Status Register */ - u32 ier; /* 0x40 Interrupt Enable Register */ - u32 idr; /* 0x44 Interrupt Disable Register */ - u32 imr; /* 0x48 Interrupt Mask Register */ - u32 isr; /* 0x4C Interrupt Status Register */ - u32 mder; /* 0x50 Multi-driver Enable Register */ - u32 mddr; /* 0x54 Multi-driver Disable Register */ - u32 mdsr; /* 0x58 Multi-driver Status Register */ - u32 reserved3; - u32 pudr; /* 0x60 Pull-up Disable Register */ - u32 puer; /* 0x64 Pull-up Enable Register */ - u32 pusr; /* 0x68 Pad Pull-up Status Register */ - u32 reserved4; -#if defined(CPU_HAS_PIO3) - u32 abcdsr1; /* 0x70 Peripheral ABCD Select Register 1 */ - u32 abcdsr2; /* 0x74 Peripheral ABCD Select Register 2 */ - u32 reserved5[2]; - u32 ifscdr; /* 0x80 Input Filter SCLK Disable Register */ - u32 ifscer; /* 0x84 Input Filter SCLK Enable Register */ - u32 ifscsr; /* 0x88 Input Filter SCLK Status Register */ - u32 scdr; /* 0x8C SCLK Divider Debouncing Register */ - u32 ppddr; /* 0x90 Pad Pull-down Disable Register */ - u32 ppder; /* 0x94 Pad Pull-down Enable Register */ - u32 ppdsr; /* 0x98 Pad Pull-down Status Register */ - u32 reserved6; /* */ -#else - u32 asr; /* 0x70 Select A Register */ - u32 bsr; /* 0x74 Select B Register */ - u32 absr; /* 0x78 AB Select Status Register */ - u32 reserved5[9]; /* */ -#endif - u32 ower; /* 0xA0 Output Write Enable Register */ - u32 owdr; /* 0xA4 Output Write Disable Register */ - u32 owsr; /* OxA8 Output Write Status Register */ -#if defined(CPU_HAS_PIO3) - u32 reserved7; /* */ - u32 aimer; /* 0xB0 Additional INT Modes Enable Register */ - u32 aimdr; /* 0xB4 Additional INT Modes Disable Register */ - u32 aimmr; /* 0xB8 Additional INT Modes Mask Register */ - u32 reserved8; /* */ - u32 esr; /* 0xC0 Edge Select Register */ - u32 lsr; /* 0xC4 Level Select Register */ - u32 elsr; /* 0xC8 Edge/Level Status Register */ - u32 reserved9; /* 0xCC */ - u32 fellsr; /* 0xD0 Falling /Low Level Select Register */ - u32 rehlsr; /* 0xD4 Rising /High Level Select Register */ - u32 frlhsr; /* 0xD8 Fall/Rise - Low/High Status Register */ - u32 reserved10; /* */ - u32 locksr; /* 0xE0 Lock Status */ - u32 wpmr; /* 0xE4 Write Protect Mode Register */ - u32 wpsr; /* 0xE8 Write Protect Status Register */ - u32 reserved11[5]; /* */ - u32 schmitt; /* 0x100 Schmitt Trigger Register */ - u32 reserved12[63]; -#else - u32 reserved6[85]; -#endif -} at91_port_t; - -typedef union at91_pio { - struct { - at91_port_t pioa; - at91_port_t piob; - at91_port_t pioc; - at91_port_t piod; /* not present in all hardware */ - at91_port_t pioe;/* not present in all hardware */ - }; - at91_port_t port[5]; -} at91_pio_t; - -#ifdef CONFIG_AT91_GPIO -int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup); -int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup); -#if defined(CPU_HAS_PIO3) -int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup); -int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup); -int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div); -int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on); -int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin); -#endif -int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup); -int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on); -int at91_set_pio_output(unsigned port, unsigned pin, int value); -int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup); -int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup); -int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on); -int at91_set_pio_value(unsigned port, unsigned pin, int value); -int at91_get_pio_value(unsigned port, unsigned pin); -#endif -#endif - -#define AT91_PIO_PORTA 0x0 -#define AT91_PIO_PORTB 0x1 -#define AT91_PIO_PORTC 0x2 -#define AT91_PIO_PORTD 0x3 -#define AT91_PIO_PORTE 0x4 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pit.h b/arch/arm/include/asm/arch-at91/at91_pit.h deleted file mode 100644 index 56724f15e7..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_pit.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91_pit.h] - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Periodic Interval Timer (PIT) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_PIT_H -#define AT91_PIT_H - -typedef struct at91_pit { - u32 mr; /* 0x00 Mode Register */ - u32 sr; /* 0x04 Status Register */ - u32 pivr; /* 0x08 Periodic Interval Value Register */ - u32 piir; /* 0x0C Periodic Interval Image Register */ -} at91_pit_t; - -#define AT91_PIT_MR_IEN 0x02000000 -#define AT91_PIT_MR_EN 0x01000000 -#define AT91_PIT_MR_PIV_MASK(x) (x & 0x000fffff) -#define AT91_PIT_MR_PIV(x) (x & AT91_PIT_MR_PIV_MASK) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_pmc.h b/arch/arm/include/asm/arch-at91/at91_pmc.h deleted file mode 100644 index 65691aba01..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_pmc.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_pmc.h] - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * Power Management Controller (PMC) - System peripherals registers. - * Based on AT91RM9200 datasheet revision E. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_PMC_H -#define AT91_PMC_H - -#ifdef __ASSEMBLY__ - -#define AT91_ASM_PMC_MOR (ATMEL_BASE_PMC + 0x20) -#define AT91_ASM_PMC_PLLAR (ATMEL_BASE_PMC + 0x28) -#define AT91_ASM_PMC_PLLBR (ATMEL_BASE_PMC + 0x2c) -#define AT91_ASM_PMC_MCKR (ATMEL_BASE_PMC + 0x30) -#define AT91_ASM_PMC_SR (ATMEL_BASE_PMC + 0x68) - -#else - -#include - -typedef struct at91_pmc { - u32 scer; /* 0x00 System Clock Enable Register */ - u32 scdr; /* 0x04 System Clock Disable Register */ - u32 scsr; /* 0x08 System Clock Status Register */ - u32 reserved0; - u32 pcer; /* 0x10 Peripheral Clock Enable Register */ - u32 pcdr; /* 0x14 Peripheral Clock Disable Register */ - u32 pcsr; /* 0x18 Peripheral Clock Status Register */ - u32 uckr; /* 0x1C UTMI Clock Register */ - u32 mor; /* 0x20 Main Oscilator Register */ - u32 mcfr; /* 0x24 Main Clock Frequency Register */ - u32 pllar; /* 0x28 PLL A Register */ - u32 pllbr; /* 0x2C PLL B Register */ - u32 mckr; /* 0x30 Master Clock Register */ - u32 reserved1; - u32 usb; /* 0x38 USB Clock Register */ - u32 reserved2; - u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */ - u32 reserved3[4]; - u32 ier; /* 0x60 Interrupt Enable Register */ - u32 idr; /* 0x64 Interrupt Disable Register */ - u32 sr; /* 0x68 Status Register */ - u32 imr; /* 0x6C Interrupt Mask Register */ - u32 reserved4[4]; - u32 pllicpr; /* 0x80 Change Pump Current Register (SAM9) */ - u32 reserved5[21]; - u32 wpmr; /* 0xE4 Write Protect Mode Register (CAP0) */ - u32 wpsr; /* 0xE8 Write Protect Status Register (CAP0) */ -#ifdef CPU_HAS_PCR - u32 reserved6[8]; - u32 pcer1; /* 0x100 Periperial Clock Enable Register 1 */ - u32 pcdr1; /* 0x104 Periperial Clock Disable Register 1 */ - u32 pcsr1; /* 0x108 Periperial Clock Status Register 1 */ - u32 pcr; /* 0x10c Periperial Control Register */ - u32 ocr; /* 0x110 Oscillator Calibration Register */ -#else - u32 reserved8[5]; -#endif -} at91_pmc_t; - -#endif /* end not assembly */ - -#define AT91_PMC_MOR_MOSCEN 0x01 -#define AT91_PMC_MOR_OSCBYPASS 0x02 -#define AT91_PMC_MOR_MOSCRCEN 0x08 -#define AT91_PMC_MOR_OSCOUNT(x) ((x & 0xff) << 8) -#define AT91_PMC_MOR_KEY(x) ((x & 0xff) << 16) -#define AT91_PMC_MOR_MOSCSEL (1 << 24) - -#define AT91_PMC_PLLXR_DIV(x) (x & 0xFF) -#define AT91_PMC_PLLXR_PLLCOUNT(x) ((x & 0x3F) << 8) -#define AT91_PMC_PLLXR_OUT(x) ((x & 0x03) << 14) -#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) -#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7F) << 18) -#else -#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7FF) << 16) -#endif -#define AT91_PMC_PLLAR_29 0x20000000 -#define AT91_PMC_PLLBR_USBDIV_1 0x00000000 -#define AT91_PMC_PLLBR_USBDIV_2 0x10000000 -#define AT91_PMC_PLLBR_USBDIV_4 0x20000000 - -#define AT91_PMC_MCFR_MAINRDY 0x00010000 -#define AT91_PMC_MCFR_MAINF_MASK 0x0000FFFF - -#define AT91_PMC_MCKR_CSS_SLOW 0x00000000 -#define AT91_PMC_MCKR_CSS_MAIN 0x00000001 -#define AT91_PMC_MCKR_CSS_PLLA 0x00000002 -#define AT91_PMC_MCKR_CSS_PLLB 0x00000003 -#define AT91_PMC_MCKR_CSS_MASK 0x00000003 - -#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) -#define AT91_PMC_MCKR_PRES_1 0x00000000 -#define AT91_PMC_MCKR_PRES_2 0x00000010 -#define AT91_PMC_MCKR_PRES_4 0x00000020 -#define AT91_PMC_MCKR_PRES_8 0x00000030 -#define AT91_PMC_MCKR_PRES_16 0x00000040 -#define AT91_PMC_MCKR_PRES_32 0x00000050 -#define AT91_PMC_MCKR_PRES_64 0x00000060 -#define AT91_PMC_MCKR_PRES_MASK 0x00000070 -#else -#define AT91_PMC_MCKR_PRES_1 0x00000000 -#define AT91_PMC_MCKR_PRES_2 0x00000004 -#define AT91_PMC_MCKR_PRES_4 0x00000008 -#define AT91_PMC_MCKR_PRES_8 0x0000000C -#define AT91_PMC_MCKR_PRES_16 0x00000010 -#define AT91_PMC_MCKR_PRES_32 0x00000014 -#define AT91_PMC_MCKR_PRES_64 0x00000018 -#define AT91_PMC_MCKR_PRES_MASK 0x0000001C -#endif - -#ifdef CONFIG_AT91RM9200 -#define AT91_PMC_MCKR_MDIV_1 0x00000000 -#define AT91_PMC_MCKR_MDIV_2 0x00000100 -#define AT91_PMC_MCKR_MDIV_3 0x00000200 -#define AT91_PMC_MCKR_MDIV_4 0x00000300 -#define AT91_PMC_MCKR_MDIV_MASK 0x00000300 -#else -#define AT91_PMC_MCKR_MDIV_1 0x00000000 -#define AT91_PMC_MCKR_MDIV_2 0x00000100 -#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) -#define AT91_PMC_MCKR_MDIV_3 0x00000300 -#endif -#define AT91_PMC_MCKR_MDIV_4 0x00000200 -#define AT91_PMC_MCKR_MDIV_MASK 0x00000300 -#endif - -#define AT91_PMC_MCKR_PLLADIV_MASK 0x00003000 -#define AT91_PMC_MCKR_PLLADIV_1 0x00000000 -#define AT91_PMC_MCKR_PLLADIV_2 0x00001000 - -#define AT91_PMC_MCKR_H32MXDIV 0x01000000 - -#define AT91_PMC_IXR_MOSCS 0x00000001 -#define AT91_PMC_IXR_LOCKA 0x00000002 -#define AT91_PMC_IXR_LOCKB 0x00000004 -#define AT91_PMC_IXR_MCKRDY 0x00000008 -#define AT91_PMC_IXR_LOCKU 0x00000040 -#define AT91_PMC_IXR_PCKRDY0 0x00000100 -#define AT91_PMC_IXR_PCKRDY1 0x00000200 -#define AT91_PMC_IXR_PCKRDY2 0x00000400 -#define AT91_PMC_IXR_PCKRDY3 0x00000800 -#define AT91_PMC_IXR_MOSCSELS 0x00010000 - -#define AT91_PMC_PCR_PID_MASK (0x3f) -#define AT91_PMC_PCR_CMD_WRITE (0x1 << 12) -#define AT91_PMC_PCR_EN (0x1 << 28) - -#define AT91_PMC_PCK (1 << 0) /* Processor Clock */ -#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ -#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ -#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ -#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ -#define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ -#define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ -#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ -#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */ -#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */ -#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ -#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */ - -#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ -#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ -#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ -#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */ - -#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ -#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */ -#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ - -#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ -#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ - -#define AT91_PMC_DIV (0xff << 0) /* Divider */ -#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ -#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ -#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ -#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ -#define AT91_PMC_USBDIV_1 (0 << 28) -#define AT91_PMC_USBDIV_2 (1 << 28) -#define AT91_PMC_USBDIV_4 (2 << 28) -#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ -#define AT91_PMC_PLLA_WR_ERRATA (1 << 29) /* Bit 29 must always be set to 1 when programming the CKGR_PLLAR register */ - -#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ -#define AT91_PMC_CSS_SLOW (0 << 0) -#define AT91_PMC_CSS_MAIN (1 << 0) -#define AT91_PMC_CSS_PLLA (2 << 0) -#define AT91_PMC_CSS_PLLB (3 << 0) -#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ -#define AT91_PMC_PRES_1 (0 << 2) -#define AT91_PMC_PRES_2 (1 << 2) -#define AT91_PMC_PRES_4 (2 << 2) -#define AT91_PMC_PRES_8 (3 << 2) -#define AT91_PMC_PRES_16 (4 << 2) -#define AT91_PMC_PRES_32 (5 << 2) -#define AT91_PMC_PRES_64 (6 << 2) -#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ -#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ -#define AT91RM9200_PMC_MDIV_2 (1 << 8) -#define AT91RM9200_PMC_MDIV_3 (2 << 8) -#define AT91RM9200_PMC_MDIV_4 (3 << 8) -#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */ -#define AT91SAM9_PMC_MDIV_2 (1 << 8) -#define AT91SAM9_PMC_MDIV_4 (2 << 8) -#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */ -#define AT91SAM9_PMC_MDIV_6 (3 << 8) -#define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */ -#define AT91_PMC_PDIV_1 (0 << 12) -#define AT91_PMC_PDIV_2 (1 << 12) - -#define AT91_PMC_USBS_USB_PLLA (0x0) /* USB Clock Input is PLLA */ -#define AT91_PMC_USBS_USB_UPLL (0x1) /* USB Clock Input is UPLL */ -#define AT91_PMC_USBS_USB_PLLB (0x1) /* USB Clock Input is PLLB, AT91SAM9N12 only */ -#define AT91_PMC_USB_DIV_2 (0x1 << 8) /* USB Clock divided by 2 */ -#define AT91_PMC_USBDIV_8 (0x7 << 8) /* USB Clock divided by 8 */ -#define AT91_PMC_USBDIV_10 (0x9 << 8) /* USB Clock divided by 10 */ - -#define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ -#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ -#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ -#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ -#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock */ -#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ -#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ -#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ -#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ - -#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_rstc.h b/arch/arm/include/asm/arch-at91/at91_rstc.h deleted file mode 100644 index e4eb3da03f..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_rstc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91_rstc.h] - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Reset Controller (RSTC) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_RSTC_H -#define AT91_RSTC_H - -/* Reset Controller Status Register */ -#define AT91_ASM_RSTC_SR (ATMEL_BASE_RSTC + 0x04) -#define AT91_ASM_RSTC_MR (ATMEL_BASE_RSTC + 0x08) - -#ifndef __ASSEMBLY__ - -typedef struct at91_rstc { - u32 cr; /* Reset Controller Control Register */ - u32 sr; /* Reset Controller Status Register */ - u32 mr; /* Reset Controller Mode Register */ -} at91_rstc_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_RSTC_KEY 0xA5000000 - -#define AT91_RSTC_CR_PROCRST 0x00000001 -#define AT91_RSTC_CR_PERRST 0x00000004 -#define AT91_RSTC_CR_EXTRST 0x00000008 - -#define AT91_RSTC_MR_URSTEN 0x00000001 -#define AT91_RSTC_MR_URSTIEN 0x00000010 -#define AT91_RSTC_MR_ERSTL(x) ((x & 0xf) << 8) -#define AT91_RSTC_MR_ERSTL_MASK 0x0000FF00 - -#define AT91_RSTC_SR_NRSTL 0x00010000 - -#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ -#define AT91_RSTC_RSTTYP_GENERAL (0 << 8) -#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8) -#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8) -#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8) -#define AT91_RSTC_RSTTYP_USER (4 << 8) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_rtt.h b/arch/arm/include/asm/arch-at91/at91_rtt.h deleted file mode 100644 index fe7619a932..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_rtt.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 - * Reinhard Meyer, reinhard.meyer@emk-elektronik.de - * - * Real-time Timer - * Based on AT91SAM9XE datasheet - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_RTT_H -#define AT91_RTT_H - -#ifndef __ASSEMBLY__ - -typedef struct at91_rtt { - u32 mr; /* Mode Register RW 0x00008000 */ - u32 ar; /* Alarm Register RW 0xFFFFFFFF */ - u32 vr; /* Value Register RO 0x00000000 */ - u32 sr; /* Status Register RO 0x00000000 */ -} at91_rtt_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_RTT_MR_RTPRES 0x0000ffff -#define AT91_RTT_MR_ALMIEN 0x00010000 -#define AT91_RTT_RTTINCIEN 0x00020000 -#define AT91_RTT_RTTRST 0x00040000 - -#define AT91_RTT_SR_ALMS 0x00000001 -#define AT91_RTT_SR_RTTINC 0x00000002 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_spi.h b/arch/arm/include/asm/arch-at91/at91_spi.h deleted file mode 100644 index b18665b62c..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_spi.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91_spi.h] - * - * Copyright (C) 2005 Ivan Kokshaysky - * Copyright (C) SAN People - * - * Serial Peripheral Interface (SPI) registers. - * Based on AT91RM9200 datasheet revision E. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_SPI_H -#define AT91_SPI_H - -#include - -typedef struct at91_spi { - u32 cr; /* 0x00 Control Register */ - u32 mr; /* 0x04 Mode Register */ - u32 rdr; /* 0x08 Receive Data Register */ - u32 tdr; /* 0x0C Transmit Data Register */ - u32 sr; /* 0x10 Status Register */ - u32 ier; /* 0x14 Interrupt Enable Register */ - u32 idr; /* 0x18 Interrupt Disable Register */ - u32 imr; /* 0x1C Interrupt Mask Register */ - u32 reserve1[4]; - u32 csr[4]; /* 0x30 Chip Select Register 0-3 */ - u32 reserve2[48]; - at91_pdc_t pdc; -} at91_spi_t; - -#ifdef CONFIG_ATMEL_LEGACY - -#define AT91_SPI_CR 0x00 /* Control Register */ -#define AT91_SPI_SPIEN (1 << 0) /* SPI Enable */ -#define AT91_SPI_SPIDIS (1 << 1) /* SPI Disable */ -#define AT91_SPI_SWRST (1 << 7) /* SPI Software Reset */ -#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ - -#define AT91_SPI_MR 0x04 /* Mode Register */ -#define AT91_SPI_MSTR (1 << 0) /* Master/Slave Mode */ -#define AT91_SPI_PS (1 << 1) /* Peripheral Select */ -#define AT91_SPI_PS_FIXED (0 << 1) -#define AT91_SPI_PS_VARIABLE (1 << 1) -#define AT91_SPI_PCSDEC (1 << 2) /* Chip Select Decode */ -#define AT91_SPI_DIV32 (1 << 3) /* Clock Selection [AT91RM9200 only] */ -#define AT91_SPI_MODFDIS (1 << 4) /* Mode Fault Detection */ -#define AT91_SPI_LLB (1 << 7) /* Local Loopback Enable */ -#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ -#define AT91_SPI_DLYBCS (0xff << 24) /* Delay Between Chip Selects */ - -#define AT91_SPI_RDR 0x08 /* Receive Data Register */ -#define AT91_SPI_RD (0xffff << 0) /* Receive Data */ -#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ - -#define AT91_SPI_TDR 0x0c /* Transmit Data Register */ -#define AT91_SPI_TD (0xffff << 0) /* Transmit Data */ -#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ -#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ - -#define AT91_SPI_SR 0x10 /* Status Register */ -#define AT91_SPI_RDRF (1 << 0) /* Receive Data Register Full */ -#define AT91_SPI_TDRE (1 << 1) /* Transmit Data Register Full */ -#define AT91_SPI_MODF (1 << 2) /* Mode Fault Error */ -#define AT91_SPI_OVRES (1 << 3) /* Overrun Error Status */ -#define AT91_SPI_ENDRX (1 << 4) /* End of RX buffer */ -#define AT91_SPI_ENDTX (1 << 5) /* End of TX buffer */ -#define AT91_SPI_RXBUFF (1 << 6) /* RX Buffer Full */ -#define AT91_SPI_TXBUFE (1 << 7) /* TX Buffer Empty */ -#define AT91_SPI_NSSR (1 << 8) /* NSS Rising [SAM9261 only] */ -#define AT91_SPI_TXEMPTY (1 << 9) /* Transmission Register Empty [SAM9261 only] */ -#define AT91_SPI_SPIENS (1 << 16) /* SPI Enable Status */ - -#define AT91_SPI_IER 0x14 /* Interrupt Enable Register */ -#define AT91_SPI_IDR 0x18 /* Interrupt Disable Register */ -#define AT91_SPI_IMR 0x1c /* Interrupt Mask Register */ - -#define AT91_SPI_CSR(n) (0x30 + ((n) * 4)) /* Chip Select Registers 0-3 */ -#define AT91_SPI_CPOL (1 << 0) /* Clock Polarity */ -#define AT91_SPI_NCPHA (1 << 1) /* Clock Phase */ -#define AT91_SPI_CSAAT (1 << 3) /* Chip Select Active After Transfer [SAM9261 only] */ -#define AT91_SPI_BITS (0xf << 4) /* Bits Per Transfer */ -#define AT91_SPI_BITS_8 (0 << 4) -#define AT91_SPI_BITS_9 (1 << 4) -#define AT91_SPI_BITS_10 (2 << 4) -#define AT91_SPI_BITS_11 (3 << 4) -#define AT91_SPI_BITS_12 (4 << 4) -#define AT91_SPI_BITS_13 (5 << 4) -#define AT91_SPI_BITS_14 (6 << 4) -#define AT91_SPI_BITS_15 (7 << 4) -#define AT91_SPI_BITS_16 (8 << 4) -#define AT91_SPI_SCBR (0xff << 8) /* Serial Clock Baud Rate */ -#define AT91_SPI_DLYBS (0xff << 16) /* Delay before SPCK */ -#define AT91_SPI_DLYBCT (0xff << 24) /* Delay between Consecutive Transfers */ - -#define AT91_SPI_RPR 0x0100 /* Receive Pointer Register */ - -#define AT91_SPI_RCR 0x0104 /* Receive Counter Register */ - -#define AT91_SPI_TPR 0x0108 /* Transmit Pointer Register */ - -#define AT91_SPI_TCR 0x010c /* Transmit Counter Register */ - -#define AT91_SPI_RNPR 0x0110 /* Receive Next Pointer Register */ - -#define AT91_SPI_RNCR 0x0114 /* Receive Next Counter Register */ - -#define AT91_SPI_TNPR 0x0118 /* Transmit Next Pointer Register */ - -#define AT91_SPI_TNCR 0x011c /* Transmit Next Counter Register */ - -#define AT91_SPI_PTCR 0x0120 /* PDC Transfer Control Register */ -#define AT91_SPI_RXTEN (0x1 << 0) /* Receiver Transfer Enable */ -#define AT91_SPI_RXTDIS (0x1 << 1) /* Receiver Transfer Disable */ -#define AT91_SPI_TXTEN (0x1 << 8) /* Transmitter Transfer Enable */ -#define AT91_SPI_TXTDIS (0x1 << 9) /* Transmitter Transfer Disable */ - -#define AT91_SPI_PTSR 0x0124 /* PDC Transfer Status Register */ - -#endif /* CONFIG_ATMEL_LEGACY */ - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_st.h b/arch/arm/include/asm/arch-at91/at91_st.h deleted file mode 100644 index b1ee1472e5..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_st.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_ST_H -#define AT91_ST_H - -typedef struct at91_st { - - u32 cr; - u32 pimr; - u32 wdmr; - u32 rtmr; - u32 sr; - u32 ier; - u32 idr; - u32 imr; - u32 rtar; - u32 crtr; -} at91_st_t ; - -#define AT91_ST_CR_WDRST 1 - -#define AT91_ST_WDMR_WDV(x) (x & 0xFFFF) -#define AT91_ST_WDMR_RSTEN 0x00010000 -#define AT91_ST_WDMR_EXTEN 0x00020000 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_tc.h b/arch/arm/include/asm/arch-at91/at91_tc.h deleted file mode 100644 index de0e266565..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_tc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_TC_H -#define AT91_TC_H - -typedef struct at91_tcc { - u32 ccr; /* 0x00 Channel Control Register */ - u32 cmr; /* 0x04 Channel Mode Register */ - u32 reserved1[2]; - u32 cv; /* 0x10 Counter Value */ - u32 ra; /* 0x14 Register A */ - u32 rb; /* 0x18 Register B */ - u32 rc; /* 0x1C Register C */ - u32 sr; /* 0x20 Status Register */ - u32 ier; /* 0x24 Interrupt Enable Register */ - u32 idr; /* 0x28 Interrupt Disable Register */ - u32 imr; /* 0x2C Interrupt Mask Register */ - u32 reserved3[4]; -} at91_tcc_t; - -#define AT91_TC_CCR_CLKEN 0x00000001 -#define AT91_TC_CCR_CLKDIS 0x00000002 -#define AT91_TC_CCR_SWTRG 0x00000004 - -#define AT91_TC_CMR_CPCTRG 0x00004000 - -#define AT91_TC_CMR_TCCLKS_CLOCK1 0x00000000 -#define AT91_TC_CMR_TCCLKS_CLOCK2 0x00000001 -#define AT91_TC_CMR_TCCLKS_CLOCK3 0x00000002 -#define AT91_TC_CMR_TCCLKS_CLOCK4 0x00000003 -#define AT91_TC_CMR_TCCLKS_CLOCK5 0x00000004 -#define AT91_TC_CMR_TCCLKS_XC0 0x00000005 -#define AT91_TC_CMR_TCCLKS_XC1 0x00000006 -#define AT91_TC_CMR_TCCLKS_XC2 0x00000007 - -typedef struct at91_tc { - at91_tcc_t tc[3]; /* 0x00 TC Channel 0-2 */ - u32 bcr; /* 0xC0 TC Block Control Register */ - u32 bmr; /* 0xC4 TC Block Mode Register */ -} at91_tc_t; - -#define AT91_TC_BMR_TC0XC0S_TCLK0 0x00000000 -#define AT91_TC_BMR_TC0XC0S_NONE 0x00000001 -#define AT91_TC_BMR_TC0XC0S_TIOA1 0x00000002 -#define AT91_TC_BMR_TC0XC0S_TIOA2 0x00000003 - -#define AT91_TC_BMR_TC1XC1S_TCLK1 0x00000000 -#define AT91_TC_BMR_TC1XC1S_NONE 0x00000004 -#define AT91_TC_BMR_TC1XC1S_TIOA0 0x00000008 -#define AT91_TC_BMR_TC1XC1S_TIOA2 0x0000000C - -#define AT91_TC_BMR_TC2XC2S_TCLK2 0x00000000 -#define AT91_TC_BMR_TC2XC2S_NONE 0x00000010 -#define AT91_TC_BMR_TC2XC2S_TIOA0 0x00000020 -#define AT91_TC_BMR_TC2XC2S_TIOA1 0x00000030 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91_wdt.h b/arch/arm/include/asm/arch-at91/at91_wdt.h deleted file mode 100644 index 0644bbf3c6..0000000000 --- a/arch/arm/include/asm/arch-at91/at91_wdt.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_wdt.h] - * - * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Watchdog Timer (WDT) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91_WDT_H -#define AT91_WDT_H - -#ifdef __ASSEMBLY__ - -#define AT91_ASM_WDT_MR (ATMEL_BASE_WDT + 0x04) - -#else - -typedef struct at91_wdt { - u32 cr; - u32 mr; - u32 sr; -} at91_wdt_t; - -#endif - -#define AT91_WDT_CR_WDRSTT 1 -#define AT91_WDT_CR_KEY 0xa5000000 /* KEY Password */ - -#define AT91_WDT_MR_WDV(x) (x & 0xfff) -#define AT91_WDT_MR_WDFIEN 0x00001000 -#define AT91_WDT_MR_WDRSTEN 0x00002000 -#define AT91_WDT_MR_WDRPROC 0x00004000 -#define AT91_WDT_MR_WDDIS 0x00008000 -#define AT91_WDT_MR_WDD(x) ((x & 0xfff) << 16) -#define AT91_WDT_MR_WDDBGHLT 0x10000000 -#define AT91_WDT_MR_WDIDLEHLT 0x20000000 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91rm9200.h b/arch/arm/include/asm/arch-at91/at91rm9200.h deleted file mode 100644 index d177bdcae5..0000000000 --- a/arch/arm/include/asm/arch-at91/at91rm9200.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __AT91RM9200_H__ -#define __AT91RM9200_H__ - -#define CONFIG_AT91FAMILY /* it's a member of AT91 family */ -#define CONFIG_ARCH_CPU_INIT /* we need arch_cpu_init() for hw timers */ -#define CONFIG_AT91_GPIO /* and require always gpio features */ - -/* Periperial Identifiers */ - -#define ATMEL_ID_SYS 1 /* System Peripheral */ -#define ATMEL_ID_PIOA 2 /* PIO port A */ -#define ATMEL_ID_PIOB 3 /* PIO port B */ -#define ATMEL_ID_PIOC 4 /* PIO port C */ -#define ATMEL_ID_PIOD 5 /* PIO port D BGA only */ -#define ATMEL_ID_USART0 6 /* USART 0 */ -#define ATMEL_ID_USART1 7 /* USART 1 */ -#define ATMEL_ID_USART2 8 /* USART 2 */ -#define ATMEL_ID_USART3 9 /* USART 3 */ -#define ATMEL_ID_MCI 10 /* Multimedia Card Interface */ -#define ATMEL_ID_UDP 11 /* USB Device Port */ -#define ATMEL_ID_TWI 12 /* Two Wire Interface */ -#define ATMEL_ID_SPI 13 /* Serial Peripheral Interface */ -#define ATMEL_ID_SSC0 14 /* Synch. Serial Controller 0 */ -#define ATMEL_ID_SSC1 15 /* Synch. Serial Controller 1 */ -#define ATMEL_ID_SSC2 16 /* Synch. Serial Controller 2 */ -#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ -#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ -#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ -#define ATMEL_ID_TC3 20 /* Timer Counter 3 */ -#define ATMEL_ID_TC4 21 /* Timer Counter 4 */ -#define ATMEL_ID_TC5 22 /* Timer Counter 5 */ -#define ATMEL_ID_UHP 23 /* OHCI USB Host Port */ -#define ATMEL_ID_EMAC 24 /* Ethernet MAC */ -#define ATMEL_ID_IRQ0 25 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ1 26 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ2 27 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ3 28 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ4 29 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ5 30 /* Advanced Interrupt Controller */ -#define ATMEL_ID_IRQ6 31 /* Advanced Interrupt Controller */ - -#define ATMEL_USB_HOST_BASE 0x00300000 - -#define ATMEL_BASE_TC 0xFFFA0000 -#define ATMEL_BASE_UDP 0xFFFB0000 -#define ATMEL_BASE_MCI 0xFFFB4000 -#define ATMEL_BASE_TWI 0xFFFB8000 -#define ATMEL_BASE_EMAC 0xFFFBC000 -#define ATMEL_BASE_USART 0xFFFC0000 /* 4x 0x4000 Offset */ -#define ATMEL_BASE_USART0 ATMEL_BASE_USART -#define ATMEL_BASE_USART1 (ATMEL_BASE_USART + 0x4000) -#define ATMEL_BASE_USART2 (ATMEL_BASE_USART + 0x8000) -#define ATMEL_BASE_USART3 (ATMEL_BASE_USART + 0xC000) - -#define ATMEL_BASE_SCC 0xFFFD0000 /* 4x 0x4000 Offset */ -#define ATMEL_BASE_SPI 0xFFFE0000 - -#define ATMEL_BASE_AIC 0xFFFFF000 -#define ATMEL_BASE_DBGU 0xFFFFF200 -#define ATMEL_BASE_PIO 0xFFFFF400 /* 4x 0x200 Offset */ -#define ATMEL_BASE_PIOA 0xFFFFF400 -#define ATMEL_BASE_PIOB 0xFFFFF600 -#define ATMEL_BASE_PIOC 0xFFFFF800 -#define ATMEL_BASE_PIOD 0xFFFFFA00 -#define ATMEL_BASE_PMC 0xFFFFFC00 -#define ATMEL_BASE_ST 0xFFFFFD00 -#define ATMEL_BASE_RTC 0xFFFFFE00 -#define ATMEL_BASE_MC 0xFFFFFF00 - -#define AT91_PIO_BASE ATMEL_BASE_PIO - -/* AT91RM9200 Periperial Multiplexing A */ -/* Port A */ -#define ATMEL_PMX_AA_EREFCK 0x00000080 -#define ATMEL_PMX_AA_ETXCK 0x00000080 -#define ATMEL_PMX_AA_ETXEN 0x00000100 -#define ATMEL_PMX_AA_ETX0 0x00000200 -#define ATMEL_PMX_AA_ETX1 0x00000400 -#define ATMEL_PMX_AA_ECRS 0x00000800 -#define ATMEL_PMX_AA_ECRSDV 0x00000800 -#define ATMEL_PMX_AA_ERX0 0x00001000 -#define ATMEL_PMX_AA_ERX1 0x00002000 -#define ATMEL_PMX_AA_ERXER 0x00004000 -#define ATMEL_PMX_AA_EMDC 0x00008000 -#define ATMEL_PMX_AA_EMDIO 0x00010000 - -#define ATMEL_PMX_AA_TXD2 0x00800000 - -#define ATMEL_PMX_AA_TWD 0x02000000 -#define ATMEL_PMX_AA_TWCK 0x04000000 - -/* Port B */ -#define ATMEL_PMX_BA_ERXCK 0x00080000 -#define ATMEL_PMX_BA_ECOL 0x00040000 -#define ATMEL_PMX_BA_ERXDV 0x00020000 -#define ATMEL_PMX_BA_ERX3 0x00010000 -#define ATMEL_PMX_BA_ERX2 0x00008000 -#define ATMEL_PMX_BA_ETXER 0x00004000 -#define ATMEL_PMX_BA_ETX3 0x00002000 -#define ATMEL_PMX_BA_ETX2 0x00001000 - -/* Port B */ - -#define ATMEL_PMX_CA_BFCK 0x00000001 -#define ATMEL_PMX_CA_BFRDY 0x00000002 -#define ATMEL_PMX_CA_SMOE 0x00000002 -#define ATMEL_PMX_CA_BFAVD 0x00000004 -#define ATMEL_PMX_CA_BFBAA 0x00000008 -#define ATMEL_PMX_CA_SMWE 0x00000008 -#define ATMEL_PMX_CA_BFOE 0x00000010 -#define ATMEL_PMX_CA_BFWE 0x00000020 -#define ATMEL_PMX_CA_NWAIT 0x00000040 -#define ATMEL_PMX_CA_A23 0x00000080 -#define ATMEL_PMX_CA_A24 0x00000100 -#define ATMEL_PMX_CA_A25 0x00000200 -#define ATMEL_PMX_CA_CFRNW 0x00000200 -#define ATMEL_PMX_CA_NCS4 0x00000400 -#define ATMEL_PMX_CA_CFCS 0x00000400 -#define ATMEL_PMX_CA_NCS5 0x00000800 -#define ATMEL_PMX_CA_CFCE1 0x00001000 -#define ATMEL_PMX_CA_NCS6 0x00001000 -#define ATMEL_PMX_CA_CFCE2 0x00002000 -#define ATMEL_PMX_CA_NCS7 0x00002000 -#define ATMEL_PMX_CA_D16_31 0xFFFF0000 - -#define ATMEL_PIO_PORTS 4 /* theese SoCs have 4 PIO */ -#define ATMEL_PMC_UHP AT91RM9200_PMC_UHP - -#define CONFIG_SYS_ATMEL_CPU_NAME "AT91RM9200" - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9260.h b/arch/arm/include/asm/arch-at91/at91sam9260.h deleted file mode 100644 index 8950d67409..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9260.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9260.h] - * - * (C) 2006 Andrew Victor - * (C) Copyright 2010 - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * - * Definitions for the SoCs: - * AT91SAM9260, AT91SAM9G20, AT91SAM9XE - * - * Note that those SoCs are mostly software and pin compatible, - * therefore this file applies to all of them. Differences between - * those SoCs are concentrated at the end of this file. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9260_H -#define AT91SAM9260_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Peripherals */ -#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ -#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ -#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ -#define ATMEL_ID_ADC 5 /* Analog-to-Digital Converter */ -#define ATMEL_ID_USART0 6 /* USART 0 */ -#define ATMEL_ID_USART1 7 /* USART 1 */ -#define ATMEL_ID_USART2 8 /* USART 2 */ -#define ATMEL_ID_MCI 9 /* Multimedia Card Interface */ -#define ATMEL_ID_UDP 10 /* USB Device Port */ -#define ATMEL_ID_TWI0 11 /* Two-Wire Interface 0 */ -#define ATMEL_ID_SPI0 12 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 13 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ -/* Reserved: 15 */ -/* Reserved: 16 */ -#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ -#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ -#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ -#define ATMEL_ID_UHP 20 /* USB Host port */ -#define ATMEL_ID_EMAC0 21 /* Ethernet 0 */ -#define ATMEL_ID_ISI 22 /* Image Sensor Interface */ -#define ATMEL_ID_USART3 23 /* USART 3 */ -#define ATMEL_ID_USART4 24 /* USART 4 */ -/* USART5 or TWI1: 25 */ -#define ATMEL_ID_TC3 26 /* Timer Counter 3 */ -#define ATMEL_ID_TC4 27 /* Timer Counter 4 */ -#define ATMEL_ID_TC5 28 /* Timer Counter 5 */ -#define ATMEL_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ -#define ATMEL_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ -#define ATMEL_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_TCB0 0xfffa0000 -#define ATMEL_BASE_TC0 0xfffa0000 -#define ATMEL_BASE_TC1 0xfffa0040 -#define ATMEL_BASE_TC2 0xfffa0080 -#define ATMEL_BASE_UDP0 0xfffa4000 -#define ATMEL_BASE_MCI 0xfffa8000 -#define ATMEL_BASE_TWI0 0xfffac000 -#define ATMEL_BASE_USART0 0xfffb0000 -#define ATMEL_BASE_USART1 0xfffb4000 -#define ATMEL_BASE_USART2 0xfffb8000 -#define ATMEL_BASE_SSC0 0xfffbc000 -#define ATMEL_BASE_ISI0 0xfffc0000 -#define ATMEL_BASE_EMAC0 0xfffc4000 -#define ATMEL_BASE_SPI0 0xfffc8000 -#define ATMEL_BASE_SPI1 0xfffcc000 -#define ATMEL_BASE_USART3 0xfffd0000 -#define ATMEL_BASE_USART4 0xfffd4000 -/* USART5 or TWI1: 0xfffd8000 */ -#define ATMEL_BASE_TCB1 0xfffdc000 -#define ATMEL_BASE_TC3 0xfffdc000 -#define ATMEL_BASE_TC4 0xfffdc040 -#define ATMEL_BASE_TC5 0xfffdc080 -#define ATMEL_BASE_ADC 0xfffe0000 -/* Reserved: 0xfffe4000 - 0xffffe7ff */ - -/* - * System Peripherals physical base addresses. - */ -#define ATMEL_BASE_SYS 0xffffe800 -#define ATMEL_BASE_SDRAMC 0xffffea00 -#define ATMEL_BASE_SMC 0xffffec00 -#define ATMEL_BASE_MATRIX 0xffffee00 -#define ATMEL_BASE_CCFG 0xffffef14 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_DBGU 0xfffff200 -#define ATMEL_BASE_PIOA 0xfffff400 -#define ATMEL_BASE_PIOB 0xfffff600 -#define ATMEL_BASE_PIOC 0xfffff800 -/* EEFC: 0xfffffa00 */ -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffd00 -#define ATMEL_BASE_SHDWN 0xfffffd10 -#define ATMEL_BASE_RTT 0xfffffd20 -#define ATMEL_BASE_PIT 0xfffffd30 -#define ATMEL_BASE_WDT 0xfffffd40 -/* GPBR(non-XE SoCs): 0xfffffd50 */ -/* GPBR(XE SoCs): 0xfffffd60 */ -/* Reserved: 0xfffffd70 - 0xffffffff */ - -/* - * Internal Memory common on all these SoCs - */ -#define ATMEL_BASE_BOOT 0x00000000 /* Boot mapped area */ -#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ -/* SRAM or FLASH: 0x00200000 */ -/* SRAM: 0x00300000 */ -/* Reserved: 0x00400000 */ -#define ATMEL_UHP_BASE 0x00500000 /* USB Host controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ -#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ -#define ATMEL_BASE_CS2 0x30000000 -#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ -#define ATMEL_BASE_CS4 0x50000000 -#define ATMEL_BASE_CS5 0x60000000 -#define ATMEL_BASE_CS6 0x70000000 -#define ATMEL_BASE_CS7 0x80000000 - -/* - * Other misc defines - */ -#ifndef CONFIG_DM_GPIO -#define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */ -#define ATMEL_BASE_PIO ATMEL_BASE_PIOA -#endif -#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP - -/* - * SoC specific defines - */ -#if defined(CONFIG_AT91SAM9XE) -# define ATMEL_CPU_NAME "AT91SAM9XE" -# define ATMEL_ID_TWI1 25 /* TWI 1 */ -# define ATMEL_BASE_FLASH 0x00200000 /* Internal FLASH */ -# define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM */ -# define ATMEL_BASE_TWI1 0xfffd8000 -# define ATMEL_BASE_EEFC 0xfffffa00 -# define ATMEL_BASE_GPBR 0xfffffd60 -#elif defined(CONFIG_AT91SAM9260) -# define ATMEL_CPU_NAME "AT91SAM9260" -# define ATMEL_ID_USART5 25 /* USART 5 */ -# define ATMEL_BASE_SRAM0 0x00200000 /* Internal SRAM 0 */ -# define ATMEL_BASE_SRAM1 0x00300000 /* Internal SRAM 1 */ -# define ATMEL_BASE_USART5 0xfffd8000 -# define ATMEL_BASE_GPBR 0xfffffd50 -#elif defined(CONFIG_AT91SAM9G20) -# define ATMEL_CPU_NAME "AT91SAM9G20" -# define ATMEL_ID_USART5 25 /* USART 5 */ -# define ATMEL_BASE_SRAM0 0x00200000 /* Internal SRAM 0 */ -# define ATMEL_BASE_SRAM1 0x00300000 /* Internal SRAM 1 */ -# define ATMEL_BASE_USART5 0xfffd8000 -# define ATMEL_BASE_GPBR 0xfffffd50 -#endif - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9260_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9260_matrix.h deleted file mode 100644 index dc61f48f52..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9260_matrix.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9260_matrix.h] - * - * Copyright (C) 2007 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9260 datasheet revision B. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9260_MATRIX_H -#define AT91SAM9260_MATRIX_H - -#ifndef __ASSEMBLY__ - -/* - * This struct defines access to the matrix' maximum of - * 16 masters and 16 slaves. - * However, on the AT91SAM9260/9G20/9XE there exist only - * 6 Masters and 5 Slaves! - */ -struct at91_matrix { - u32 mcfg[16]; /* Master Configuration Registers */ - u32 scfg[16]; /* Slave Configuration Registers */ - u32 pras[16][2]; /* Priority Assignment Slave Registers */ - u32 mrcr; /* Master Remap Control Register */ - u32 filler[0x06]; - u32 ebicsa; /* EBI Chip Select Assignment Register */ -}; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) - -#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_DBPUC (1 << 8) -#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) -#define AT91_MATRIX_EBI_IOSR_SEL (1 << 17) - -/* Maximum Number of Allowed Cycles for a Burst */ -#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) -#define AT91_MATRIX_SLOT_CYCLE_(x) (x << 0) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9261.h b/arch/arm/include/asm/arch-at91/at91sam9261.h deleted file mode 100644 index 6dfcf4c0c8..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9261.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261.h] - * - * Copyright (C) SAN People - * (C) Copyright 2010 - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * - * Definitions for the SoCs: - * AT91SAM9261, AT91SAM9G10 - * - * Note that those SoCs are mostly software and pin compatible, - * therefore this file applies to all of them. Differences between - * those SoCs are concentrated at the end of this file. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9261_H -#define AT91SAM9261_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Peripherals */ -#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ -#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ -#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ -/* Reserved: 5 */ -#define ATMEL_ID_USART0 6 /* USART 0 */ -#define ATMEL_ID_USART1 7 /* USART 1 */ -#define ATMEL_ID_USART2 8 /* USART 2 */ -#define ATMEL_ID_MCI 9 /* Multimedia Card Interface */ -#define ATMEL_ID_UDP 10 /* USB Device Port */ -#define ATMEL_ID_TWI0 11 /* Two-Wire Interface 0 */ -#define ATMEL_ID_SPI0 12 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 13 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ -#define ATMEL_ID_SSC1 15 /* Serial Synchronous Controller 1 */ -#define ATMEL_ID_SSC2 16 /* Serial Synchronous Controller 2 */ -#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ -#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ -#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ -#define ATMEL_ID_UHP 20 /* USB Host port */ -#define ATMEL_ID_LCDC 21 /* LDC Controller */ -/* Reserved: 22-28 */ -#define ATMEL_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ -#define ATMEL_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ -#define ATMEL_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_TCB0 0xfffa0000 -#define ATMEL_BASE_TC0 0xfffa0000 -#define ATMEL_BASE_TC1 0xfffa0040 -#define ATMEL_BASE_TC2 0xfffa0080 -#define ATMEL_BASE_UDP0 0xfffa4000 -#define ATMEL_BASE_MCI 0xfffa8000 -#define ATMEL_BASE_TWI0 0xfffac000 -#define ATMEL_BASE_USART0 0xfffb0000 -#define ATMEL_BASE_USART1 0xfffb4000 -#define ATMEL_BASE_USART2 0xfffb8000 -#define ATMEL_BASE_SSC0 0xfffbc000 -#define ATMEL_BASE_SSC1 0xfffc0000 -#define ATMEL_BASE_SSC2 0xfffc4000 -#define ATMEL_BASE_SPI0 0xfffc8000 -#define ATMEL_BASE_SPI1 0xfffcc000 -/* Reserved: 0xfffc4000 - 0xffffe9ff */ - -/* - * System Peripherals physical base addresses. - */ -#define ATMEL_BASE_SYS 0xffffea00 -#define ATMEL_BASE_SDRAMC 0xffffea00 -#define ATMEL_BASE_SMC 0xffffec00 -#define ATMEL_BASE_MATRIX 0xffffee00 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_DBGU 0xfffff200 -#define ATMEL_BASE_PIOA 0xfffff400 -#define ATMEL_BASE_PIOB 0xfffff600 -#define ATMEL_BASE_PIOC 0xfffff800 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffd00 -#define ATMEL_BASE_SHDWN 0xfffffd10 -#define ATMEL_BASE_RTT 0xfffffd20 -#define ATMEL_BASE_PIT 0xfffffd30 -#define ATMEL_BASE_WDT 0xfffffd40 -#define ATMEL_BASE_GPBR 0xfffffd50 - -/* - * Internal Memory common on all these SoCs - */ -#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ -#define ATMEL_SIZE_SRAM 0x00028000 /* Internal SRAM size (160Kb) */ - -#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ -#define ATMEL_SIZE_ROM 0x00008000 /* Internal ROM size (32Kb) */ - -#define ATMEL_BASE_UHP 0x00500000 /* USB Host controller */ -#define ATMEL_BASE_LCDC 0x00600000 /* LDC controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ -#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ -#define ATMEL_BASE_CS2 0x30000000 -#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ -#define ATMEL_BASE_CS4 0x50000000 -#define ATMEL_BASE_CS5 0x60000000 -#define ATMEL_BASE_CS6 0x70000000 -#define ATMEL_BASE_CS7 0x80000000 - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 3 /* theese SoCs have 3 PIO */ -#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP -#define ATMEL_BASE_PIO ATMEL_BASE_PIOA - -/* - * SoC specific defines - */ -#if defined(CONFIG_AT91SAM9261) -# define ATMEL_CPU_NAME "AT91SAM9261" -#elif defined(CONFIG_AT91SAM9G10) -# define ATMEL_CPU_NAME "AT91SAM9G10" -#endif - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9261_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9261_matrix.h deleted file mode 100644 index fc5f0831b8..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9261_matrix.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261_matrix.h] - * - * Copyright (C) 2007 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9261_MATRIX_H -#define AT91SAM9261_MATRIX_H - -#ifndef __ASSEMBLY__ - -struct at91_matrix { - u32 mcfg; /* Master Configuration Registers */ - u32 scfg[5]; /* Slave Configuration Registers */ - u32 filler[6]; - u32 ebicsa; /* EBI Chip Select Assignment Register */ -}; -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) - -#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_DBPUC (1 << 8) -#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9263.h b/arch/arm/include/asm/arch-at91/at91sam9263.h deleted file mode 100644 index 64a3888e22..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9263.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9263.h] - * - * (C) 2007 Atmel Corporation. - * (C) Copyright 2010 - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * - * Definitions for the SoC: - * AT91SAM9263 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9263_H -#define AT91SAM9263_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Peripherals */ -#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ -#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ -#define ATMEL_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */ -/* Reserved: 5 */ -/* Reserved: 6 */ -#define ATMEL_ID_USART0 7 /* USART 0 */ -#define ATMEL_ID_USART1 8 /* USART 1 */ -#define ATMEL_ID_USART2 9 /* USART 2 */ -#define ATMEL_ID_MCI0 10 /* Multimedia Card Interface 0 */ -#define ATMEL_ID_MCI1 11 /* Multimedia Card Interface 1 */ -#define ATMEL_ID_CAN 12 /* CAN */ -#define ATMEL_ID_TWI 13 /* Two-Wire Interface */ -#define ATMEL_ID_SPI0 14 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 15 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_SSC0 16 /* Serial Synchronous Controller 0 */ -#define ATMEL_ID_SSC1 17 /* Serial Synchronous Controller 1 */ -#define ATMEL_ID_AC97C 18 /* AC97 Controller */ -#define ATMEL_ID_TCB 19 /* Timer Counter 0, 1 and 2 */ -#define ATMEL_ID_PWMC 20 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_EMAC 21 /* Ethernet */ -/* Reserved: 22 */ -#define ATMEL_ID_2DGE 23 /* 2D Graphic Engine */ -#define ATMEL_ID_UDP 24 /* USB Device Port */ -#define ATMEL_ID_ISI 25 /* Image Sensor Interface */ -#define ATMEL_ID_LCDC 26 /* LCD Controller */ -#define ATMEL_ID_DMA 27 /* DMA Controller */ -/* Reserved: 28 */ -#define ATMEL_ID_UHP 29 /* USB Host port */ -#define ATMEL_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ -#define ATMEL_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_UDP 0xfff78000 -#define ATMEL_BASE_TCB0 0xfff7c000 -#define ATMEL_BASE_TC0 0xfff7c000 -#define ATMEL_BASE_TC1 0xfff7c040 -#define ATMEL_BASE_TC2 0xfff7c080 -#define ATMEL_BASE_MCI0 0xfff80000 -#define ATMEL_BASE_MCI1 0xfff84000 -#define ATMEL_BASE_TWI 0xfff88000 -#define ATMEL_BASE_USART0 0xfff8c000 -#define ATMEL_BASE_USART1 0xfff90000 -#define ATMEL_BASE_USART2 0xfff94000 -#define ATMEL_BASE_SSC0 0xfff98000 -#define ATMEL_BASE_SSC1 0xfff9c000 -#define ATMEL_BASE_AC97C 0xfffa0000 -#define ATMEL_BASE_SPI0 0xfffa4000 -#define ATMEL_BASE_SPI1 0xfffa8000 -#define ATMEL_BASE_CAN 0xfffac000 -#define ATMEL_BASE_PWMC 0xfffb8000 -#define ATMEL_BASE_EMAC 0xfffbc000 -#define ATMEL_BASE_ISI 0xfffc4000 -#define ATMEL_BASE_2DGE 0xfffc8000 - -/* - * System Peripherals physical base addresses. - */ -#define ATMEL_BASE_ECC0 0xffffe000 -#define ATMEL_BASE_SDRAMC0 0xffffe200 -#define ATMEL_BASE_SMC0 0xffffe400 -#define ATMEL_BASE_ECC1 0xffffe600 -#define ATMEL_BASE_SDRAMC1 0xffffe800 -#define ATMEL_BASE_SMC1 0xffffea00 -#define ATMEL_BASE_MATRIX 0xffffec00 -#define ATMEL_BASE_CCFG 0xffffed10 -#define ATMEL_BASE_DBGU 0xffffee00 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_PIOA 0xfffff200 -#define ATMEL_BASE_PIOB 0xfffff400 -#define ATMEL_BASE_PIOC 0xfffff600 -#define ATMEL_BASE_PIOD 0xfffff800 -#define ATMEL_BASE_PIOE 0xfffffa00 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffd00 -#define ATMEL_BASE_SHDWC 0xfffffd10 -#define ATMEL_BASE_RTT0 0xfffffd20 -#define ATMEL_BASE_PIT 0xfffffd30 -#define ATMEL_BASE_WDT 0xfffffd40 -#define ATMEL_BASE_RTT1 0xfffffd50 -#define ATMEL_BASE_GPBR 0xfffffd60 - -/* - * Internal Memory. - */ -#define ATMEL_BASE_SRAM0 0x00300000 /* Internal SRAM 0 */ - -#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM */ - -#define ATMEL_BASE_SRAM1 0x00500000 /* Internal SRAM 1 */ - -#define ATMEL_BASE_LCDC 0x00700000 /* LCD Controller */ -#define ATMEL_BASE_DMAC 0x00800000 /* DMA Controller */ -#define ATMEL_BASE_UHP 0x00a00000 /* USB Host controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ -#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ -#define ATMEL_BASE_CS2 0x30000000 -#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ -#define ATMEL_BASE_CS4 0x50000000 -#define ATMEL_BASE_CS5 0x60000000 -#define ATMEL_BASE_CS6 0x70000000 -#define ATMEL_BASE_CS7 0x80000000 - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 5 /* this SoCs has 5 PIO */ -#define ATMEL_BASE_PIO ATMEL_BASE_PIOA -#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP - -/* - * Cpu Name - */ -#define ATMEL_CPU_NAME "AT91SAM9263" - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9263_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9263_matrix.h deleted file mode 100644 index 54d862287b..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9263_matrix.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9263_matrix.h] - * - * Copyright (C) 2006 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9263 datasheet revision B (Preliminary). - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9263_MATRIX_H -#define AT91SAM9263_MATRIX_H - -#ifndef __ASSEMBLY__ - -/* - * This struct defines access to the matrix' maximum of - * 16 masters and 16 slaves. - * Note: not all masters/slaves are available - */ -struct at91_matrix { - u32 mcfg[16]; /* Master Configuration Registers */ - u32 scfg[16]; /* Slave Configuration Registers */ - u32 pras[16][2]; /* Priority Assignment Slave Registers */ - u32 mrcr; /* Master Remap Control Register */ - u32 filler[0x06]; - u32 ebicsa; /* EBI Chip Select Assignment Register */ -}; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) - -#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_DBPUC (1 << 8) -#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9_matrix.h deleted file mode 100644 index d0bf0c2e2b..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9_matrix.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_AT91SAM9_MATRIX_H -#define __ASM_ARCH_AT91SAM9_MATRIX_H - -#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) -#include -#elif defined(CONFIG_AT91SAM9261) -#include -#elif defined(CONFIG_AT91SAM9263) -#include -#elif defined(CONFIG_AT91SAM9RL) -#include -#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) -#include -#elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) -#include -#else -#error "Unsupported AT91SAM9/CAP9 processor" -#endif - -#endif /* __ASM_ARCH_AT91SAM9_MATRIX_H */ diff --git a/arch/arm/include/asm/arch-at91/at91sam9_sdramc.h b/arch/arm/include/asm/arch-at91/at91sam9_sdramc.h deleted file mode 100644 index 3a076c6b80..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9_sdramc.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_wdt.h] - * - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * SDRAM Controllers (SDRAMC) - System peripherals registers. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9_SDRAMC_H -#define AT91SAM9_SDRAMC_H - -#ifdef __ASSEMBLY__ - -#ifndef ATMEL_BASE_SDRAMC -#define ATMEL_BASE_SDRAMC ATMEL_BASE_SDRAMC0 -#endif - -#define AT91_ASM_SDRAMC_MR ATMEL_BASE_SDRAMC -#define AT91_ASM_SDRAMC_TR (ATMEL_BASE_SDRAMC + 0x04) -#define AT91_ASM_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08) -#define AT91_ASM_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24) - -#else -struct sdramc_reg { - u32 mr; - u32 tr; - u32 cr; - u32 lpr; - u32 ier; - u32 idr; - u32 imr; - u32 isr; - u32 mdr; -}; - -int sdramc_initialize(unsigned int sdram_address, - const struct sdramc_reg *p); -#endif - -/* SDRAM Controller (SDRAMC) registers */ -#define AT91_SDRAMC_MR (ATMEL_BASE_SDRAMC + 0x00) /* SDRAM Controller Mode Register */ -#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ -#define AT91_SDRAMC_MODE_NORMAL 0 -#define AT91_SDRAMC_MODE_NOP 1 -#define AT91_SDRAMC_MODE_PRECHARGE 2 -#define AT91_SDRAMC_MODE_LMR 3 -#define AT91_SDRAMC_MODE_REFRESH 4 -#define AT91_SDRAMC_MODE_EXT_LMR 5 -#define AT91_SDRAMC_MODE_DEEP 6 - -#define AT91_SDRAMC_TR (ATMEL_BASE_SDRAMC + 0x04) /* SDRAM Controller Refresh Timer Register */ -#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */ - -#define AT91_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08) /* SDRAM Controller Configuration Register */ -#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ -#define AT91_SDRAMC_NC_8 (0 << 0) -#define AT91_SDRAMC_NC_9 (1 << 0) -#define AT91_SDRAMC_NC_10 (2 << 0) -#define AT91_SDRAMC_NC_11 (3 << 0) -#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ -#define AT91_SDRAMC_NR_11 (0 << 2) -#define AT91_SDRAMC_NR_12 (1 << 2) -#define AT91_SDRAMC_NR_13 (2 << 2) -#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ -#define AT91_SDRAMC_NB_2 (0 << 4) -#define AT91_SDRAMC_NB_4 (1 << 4) -#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ -#define AT91_SDRAMC_CAS_1 (1 << 5) -#define AT91_SDRAMC_CAS_2 (2 << 5) -#define AT91_SDRAMC_CAS_3 (3 << 5) -#define AT91_SDRAMC_DBW (1 << 7) /* Data Bus Width */ -#define AT91_SDRAMC_DBW_32 (0 << 7) -#define AT91_SDRAMC_DBW_16 (1 << 7) -#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */ -#define AT91_SDRAMC_TWR_VAL(x) (x << 8) -#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */ -#define AT91_SDRAMC_TRC_VAL(x) (x << 12) -#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */ -#define AT91_SDRAMC_TRP_VAL(x) (x << 16) -#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */ -#define AT91_SDRAMC_TRCD_VAL(x) (x << 20) -#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */ -#define AT91_SDRAMC_TRAS_VAL(x) (x << 24) -#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */ -#define AT91_SDRAMC_TXSR_VAL(x) (x << 28) - -#define AT91_SDRAMC_LPR (ATMEL_BASE_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */ -#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */ -#define AT91_SDRAMC_LPCB_DISABLE 0 -#define AT91_SDRAMC_LPCB_SELF_REFRESH 1 -#define AT91_SDRAMC_LPCB_POWER_DOWN 2 -#define AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3 -#define AT91_SDRAMC_PASR (7 << 4) /* Partial Array Self Refresh */ -#define AT91_SDRAMC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ -#define AT91_SDRAMC_DS (3 << 10) /* Drive Strength */ -#define AT91_SDRAMC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ -#define AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES (0 << 12) -#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12) -#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12) - -#define AT91_SDRAMC_IER (ATMEL_BASE_SDRAMC + 0x14) /* SDRAM Controller Interrupt Enable Register */ -#define AT91_SDRAMC_IDR (ATMEL_BASE_SDRAMC + 0x18) /* SDRAM Controller Interrupt Disable Register */ -#define AT91_SDRAMC_IMR (ATMEL_BASE_SDRAMC + 0x1C) /* SDRAM Controller Interrupt Mask Register */ -#define AT91_SDRAMC_ISR (ATMEL_BASE_SDRAMC + 0x20) /* SDRAM Controller Interrupt Status Register */ -#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */ - -#define AT91_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24) /* SDRAM Memory Device Register */ -#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */ -#define AT91_SDRAMC_MD_SDRAM 0 -#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9_smc.h b/arch/arm/include/asm/arch-at91/at91sam9_smc.h deleted file mode 100644 index d29e98e711..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9_smc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9_smc.h] - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Static Memory Controllers (SMC) - System peripherals registers. - * Based on AT91SAM9261 datasheet revision D. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9_SMC_H -#define AT91SAM9_SMC_H - -#ifdef __ASSEMBLY__ - -#ifndef ATMEL_BASE_SMC -#define ATMEL_BASE_SMC ATMEL_BASE_SMC0 -#endif - -#define AT91_ASM_SMC_SETUP0 ATMEL_BASE_SMC -#define AT91_ASM_SMC_PULSE0 (ATMEL_BASE_SMC + 0x04) -#define AT91_ASM_SMC_CYCLE0 (ATMEL_BASE_SMC + 0x08) -#define AT91_ASM_SMC_MODE0 (ATMEL_BASE_SMC + 0x0C) - -#else - -typedef struct at91_cs { - u32 setup; /* 0x00 SMC Setup Register */ - u32 pulse; /* 0x04 SMC Pulse Register */ - u32 cycle; /* 0x08 SMC Cycle Register */ - u32 mode; /* 0x0C SMC Mode Register */ -} at91_cs_t; - -typedef struct at91_smc { - at91_cs_t cs[8]; -} at91_smc_t; - -#endif /* __ASSEMBLY__ */ - -#define AT91_SMC_SETUP_NWE(x) (x & 0x3f) -#define AT91_SMC_SETUP_NCS_WR(x) ((x & 0x3f) << 8) -#define AT91_SMC_SETUP_NRD(x) ((x & 0x3f) << 16) -#define AT91_SMC_SETUP_NCS_RD(x) ((x & 0x3f) << 24) - -#define AT91_SMC_PULSE_NWE(x) (x & 0x7f) -#define AT91_SMC_PULSE_NCS_WR(x) ((x & 0x7f) << 8) -#define AT91_SMC_PULSE_NRD(x) ((x & 0x7f) << 16) -#define AT91_SMC_PULSE_NCS_RD(x) ((x & 0x7f) << 24) - -#define AT91_SMC_CYCLE_NWE(x) (x & 0x1ff) -#define AT91_SMC_CYCLE_NRD(x) ((x & 0x1ff) << 16) - -#define AT91_SMC_MODE_RM_NCS 0x00000000 -#define AT91_SMC_MODE_RM_NRD 0x00000001 -#define AT91_SMC_MODE_WM_NCS 0x00000000 -#define AT91_SMC_MODE_WM_NWE 0x00000002 - -#define AT91_SMC_MODE_EXNW_DISABLE 0x00000000 -#define AT91_SMC_MODE_EXNW_FROZEN 0x00000020 -#define AT91_SMC_MODE_EXNW_READY 0x00000030 - -#define AT91_SMC_MODE_BAT 0x00000100 -#define AT91_SMC_MODE_DBW_8 0x00000000 -#define AT91_SMC_MODE_DBW_16 0x00001000 -#define AT91_SMC_MODE_DBW_32 0x00002000 -#define AT91_SMC_MODE_TDF_CYCLE(x) ((x & 0xf) << 16) -#define AT91_SMC_MODE_TDF 0x00100000 -#define AT91_SMC_MODE_PMEN 0x01000000 -#define AT91_SMC_MODE_PS_4 0x00000000 -#define AT91_SMC_MODE_PS_8 0x10000000 -#define AT91_SMC_MODE_PS_16 0x20000000 -#define AT91_SMC_MODE_PS_32 0x30000000 - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9g45.h b/arch/arm/include/asm/arch-at91/at91sam9g45.h deleted file mode 100644 index 6df8cdb56d..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9g45.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Chip-specific header file for the AT91SAM9M1x family - * - * (C) 2008 Atmel Corporation. - * - * Definitions for the SoC: - * AT91SAM9G45 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9G45_H -#define AT91SAM9G45_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ -#define ATMEL_ID_PIOA 2 /* Parallel I/O Controller A */ -#define ATMEL_ID_PIOB 3 /* Parallel I/O Controller B */ -#define ATMEL_ID_PIOC 4 /* Parallel I/O Controller C */ -#define ATMEL_ID_PIODE 5 /* Parallel I/O Controller D and E */ -#define ATMEL_ID_TRNG 6 /* True Random Number Generator */ -#define ATMEL_ID_USART0 7 /* USART 0 */ -#define ATMEL_ID_USART1 8 /* USART 1 */ -#define ATMEL_ID_USART2 9 /* USART 2 */ -#define ATMEL_ID_USART3 10 /* USART 3 */ -#define ATMEL_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */ -#define ATMEL_ID_TWI0 12 /* Two-Wire Interface 0 */ -#define ATMEL_ID_TWI1 13 /* Two-Wire Interface 1 */ -#define ATMEL_ID_SPI0 14 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 15 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_SSC0 16 /* Synchronous Serial Controller 0 */ -#define ATMEL_ID_SSC1 17 /* Synchronous Serial Controller 1 */ -#define ATMEL_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ -#define ATMEL_ID_PWMC 19 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_TSC 20 /* Touch Screen ADC Controller */ -#define ATMEL_ID_DMA 21 /* DMA Controller */ -#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */ -#define ATMEL_ID_LCDC 23 /* LCD Controller */ -#define ATMEL_ID_AC97C 24 /* AC97 Controller */ -#define ATMEL_ID_EMAC 25 /* Ethernet MAC */ -#define ATMEL_ID_ISI 26 /* Image Sensor Interface */ -#define ATMEL_ID_UDPHS 27 /* USB Device High Speed */ -#define ATMEL_ID_AESTDESSHA 28 /* AES + T-DES + SHA */ -#define ATMEL_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */ -#define ATMEL_ID_VDEC 30 /* Video Decoder */ -#define ATMEL_ID_IRQ0 31 /* Advanced Interrupt Controller */ - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_UDPHS 0xfff78000 -#define ATMEL_BASE_TC0 0xfff7c000 -#define ATMEL_BASE_TC1 0xfff7c040 -#define ATMEL_BASE_TC2 0xfff7c080 -#define ATMEL_BASE_MCI0 0xfff80000 -#define ATMEL_BASE_TWI0 0xfff84000 -#define ATMEL_BASE_TWI1 0xfff88000 -#define ATMEL_BASE_USART0 0xfff8c000 -#define ATMEL_BASE_USART1 0xfff90000 -#define ATMEL_BASE_USART2 0xfff94000 -#define ATMEL_BASE_USART3 0xfff98000 -#define ATMEL_BASE_SSC0 0xfff9c000 -#define ATMEL_BASE_SSC1 0xfffa0000 -#define ATMEL_BASE_SPI0 0xfffa4000 -#define ATMEL_BASE_SPI1 0xfffa8000 -#define ATMEL_BASE_AC97C 0xfffac000 -#define ATMEL_BASE_TSC 0xfffb0000 -#define ATMEL_BASE_ISI 0xfffb4000 -#define ATMEL_BASE_PWMC 0xfffb8000 -#define ATMEL_BASE_EMAC 0xfffbc000 -#define ATMEL_BASE_AES 0xfffc0000 -#define ATMEL_BASE_TDES 0xfffc4000 -#define ATMEL_BASE_SHA 0xfffc8000 -#define ATMEL_BASE_TRNG 0xfffcc000 -#define ATMEL_BASE_MCI1 0xfffd0000 -#define ATMEL_BASE_TC3 0xfffd4000 -#define ATMEL_BASE_TC4 0xfffd4040 -#define ATMEL_BASE_TC5 0xfffd4080 -/* Reserved: 0xfffd8000 - 0xffffe1ff */ - -/* - * System Peripherals physical base addresses. - */ -#define ATMEL_BASE_SYS 0xffffe200 -#define ATMEL_BASE_ECC 0xffffe200 -#define ATMEL_BASE_DDRSDRC1 0xffffe400 -#define ATMEL_BASE_DDRSDRC0 0xffffe600 -#define ATMEL_BASE_SMC 0xffffe800 -#define ATMEL_BASE_MATRIX 0xffffea00 -#define ATMEL_BASE_DMA 0xffffec00 -#define ATMEL_BASE_DBGU 0xffffee00 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_PIOA 0xfffff200 -#define ATMEL_BASE_PIOB 0xfffff400 -#define ATMEL_BASE_PIOC 0xfffff600 -#define ATMEL_BASE_PIOD 0xfffff800 -#define ATMEL_BASE_PIOE 0xfffffa00 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffd00 -#define ATMEL_BASE_SHDWN 0xfffffd10 -#define ATMEL_BASE_RTT 0xfffffd20 -#define ATMEL_BASE_PIT 0xfffffd30 -#define ATMEL_BASE_WDT 0xfffffd40 -#define ATMEL_BASE_GPBR 0xfffffd60 -#define ATMEL_BASE_RTC 0xfffffdb0 -/* Reserved: 0xfffffdc0 - 0xffffffff */ - -/* - * Internal Memory. - */ -#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ -#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ -#define ATMEL_BASE_LCDC 0x00500000 /* LCD Controller */ -#define ATMEL_BASE_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ -#define ATMEL_BASE_HCI 0x00700000 /* USB Host controller (OHCI) */ -#define ATMEL_BASE_EHCI 0x00800000 /* USB Host controller (EHCI) */ -#define ATMEL_BASE_VDEC 0x00900000 /* Video Decoder Controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 -#define ATMEL_BASE_CS1 0x20000000 -#define ATMEL_BASE_CS2 0x30000000 -#define ATMEL_BASE_CS3 0x40000000 -#define ATMEL_BASE_CS4 0x50000000 -#define ATMEL_BASE_CS5 0x60000000 -#define ATMEL_BASE_CS6 0x70000000 -#define ATMEL_BASE_CS7 0x80000000 - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 5 /* this SoCs has 5 PIO */ -#define ATMEL_BASE_PIO ATMEL_BASE_PIOA -#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP -#define ATMEL_ID_UHP ATMEL_ID_UHPHS -/* - * Cpu Name - */ -#define ATMEL_CPU_NAME "AT91SAM9G45" - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9g45_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9g45_matrix.h deleted file mode 100644 index 80e49e3430..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9g45_matrix.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Matrix-centric header file for the AT91SAM9M1x family - * - * Copyright (C) 2008 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9G45 preliminary datasheet. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef AT91SAM9G45_MATRIX_H -#define AT91SAM9G45_MATRIX_H - -#ifndef __ASSEMBLY__ - -struct at91_matrix { - u32 mcfg[16]; - u32 scfg[16]; - u32 pras[16][2]; - u32 mrcr; /* 0x100 Master Remap Control */ - u32 filler[3]; - u32 tcmr; - u32 filler2; - u32 ddrmpr; - u32 filler3[3]; - u32 ebicsa; - u32 filler4[47]; - u32 wpmr; - u32 wpsr; -}; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) -#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) -#define AT91_MATRIX_ULBT_128 (7 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 -#define AT91_MATRIX_M6PR_SHIFT 24 -#define AT91_MATRIX_M7PR_SHIFT 28 - -#define AT91_MATRIX_M8PR_SHIFT 0 /* register B */ -#define AT91_MATRIX_M9PR_SHIFT 4 /* register B */ -#define AT91_MATRIX_M10PR_SHIFT 8 /* register B */ -#define AT91_MATRIX_M11PR_SHIFT 12 /* register B */ - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) -#define AT91_MATRIX_RCB2 (1 << 2) -#define AT91_MATRIX_RCB3 (1 << 3) -#define AT91_MATRIX_RCB4 (1 << 4) -#define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_RCB6 (1 << 6) -#define AT91_MATRIX_RCB7 (1 << 7) -#define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_RCB9 (1 << 9) -#define AT91_MATRIX_RCB10 (1 << 10) - -#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) -#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4) -#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) -#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5) -#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) -#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) -#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) -#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) -#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) -#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) -#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9rl.h b/arch/arm/include/asm/arch-at91/at91sam9rl.h deleted file mode 100644 index 3a8e6d62ce..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9rl.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9rl.h] - * - * Copyright (C) 2007 Atmel Corporation - * - * Common definitions. - * Based on AT91SAM9RL datasheet revision A. (Preliminary) - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#ifndef AT91SAM9RL_H -#define AT91SAM9RL_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Peripherals */ -#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ -#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ -#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ -#define ATMEL_ID_PIOD 5 /* Parallel IO Controller D */ -#define ATMEL_ID_USART0 6 /* USART 0 */ -#define ATMEL_ID_USART1 7 /* USART 1 */ -#define ATMEL_ID_USART2 8 /* USART 2 */ -#define ATMEL_ID_USART3 9 /* USART 3 */ -#define ATMEL_ID_MCI 10 /* Multimedia Card Interface */ -#define ATMEL_ID_TWI0 11 /* TWI 0 */ -#define ATMEL_ID_TWI1 12 /* TWI 1 */ -#define ATMEL_ID_SPI 13 /* Serial Peripheral Interface */ -#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ -#define ATMEL_ID_SSC1 15 /* Serial Synchronous Controller 1 */ -#define ATMEL_ID_TC0 16 /* Timer Counter 0 */ -#define ATMEL_ID_TC1 17 /* Timer Counter 1 */ -#define ATMEL_ID_TC2 18 /* Timer Counter 2 */ -#define ATMEL_ID_PWMC 19 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_TSC 20 /* Touch Screen Controller */ -#define ATMEL_ID_DMA 21 /* DMA Controller */ -#define ATMEL_ID_UDPHS 22 /* USB Device HS */ -#define ATMEL_ID_LCDC 23 /* LCD Controller */ -#define ATMEL_ID_AC97C 24 /* AC97 Controller */ -#define ATMEL_ID_IRQ0 31 /* Advanced Interrupt Controller (IRQ0) */ - -/* - * User Peripheral physical base addresses. - */ -#define ATMEL_BASE_TCB0 0xfffa0000 -#define ATMEL_BASE_TC0 0xfffa0000 -#define ATMEL_BASE_TC1 0xfffa0040 -#define ATMEL_BASE_TC2 0xfffa0080 -#define ATMEL_BASE_MCI 0xfffa4000 -#define ATMEL_BASE_TWI0 0xfffa8000 -#define ATMEL_BASE_TWI1 0xfffac000 -#define ATMEL_BASE_USART0 0xfffb0000 -#define ATMEL_BASE_USART1 0xfffb4000 -#define ATMEL_BASE_USART2 0xfffb8000 -#define ATMEL_BASE_USART3 0xfffbc000 -#define ATMEL_BASE_SSC0 0xfffc0000 -#define ATMEL_BASE_SSC1 0xfffc4000 -#define ATMEL_BASE_PWMC 0xfffc8000 -#define ATMEL_BASE_SPI0 0xfffcc000 -#define ATMEL_BASE_TSC 0xfffd0000 -#define ATMEL_BASE_UDPHS 0xfffd4000 -#define ATMEL_BASE_AC97C 0xfffd8000 -#define ATMEL_BASE_SYS 0xffffc000 - -/* - * System Peripherals - */ -#define ATMEL_BASE_DMA 0xffffe600 -#define ATMEL_BASE_ECC 0xffffe800 -#define ATMEL_BASE_SDRAMC 0xffffea00 -#define ATMEL_BASE_SMC 0xffffec00 -#define ATMEL_BASE_MATRIX 0xffffee00 -#define ATMEL_BASE_CCFG 0xffffef10 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_DBGU 0xfffff200 -#define ATMEL_BASE_PIOA 0xfffff400 -#define ATMEL_BASE_PIOB 0xfffff600 -#define ATMEL_BASE_PIOC 0xfffff800 -#define ATMEL_BASE_PIOD 0xfffffa00 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffd00 -#define ATMEL_BASE_SHDWC 0xfffffd10 -#define ATMEL_BASE_RTT 0xfffffd20 -#define ATMEL_BASE_PIT 0xfffffd30 -#define ATMEL_BASE_WDT 0xfffffd40 -#define ATMEL_BASE_SCKCR 0xfffffd50 -#define ATMEL_BASE_GPBR 0xfffffd60 -#define ATMEL_BASE_RTC 0xfffffe00 - -/* - * Internal Memory. - */ -#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ -#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ - -#define ATMEL_BASE_LCDC 0x00500000 /* LCD Controller */ -#define ATMEL_UHP_BASE 0x00600000 /* USB Device HS controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 -#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ -#define ATMEL_BASE_CS2 0x30000000 -#define ATMEL_BASE_CS3 0x40000000 /* NAND */ -#define ATMEL_BASE_CS4 0x50000000 /* Compact Flash Slot 0 */ -#define ATMEL_BASE_CS5 0x60000000 /* Compact Flash Slot 1 */ - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 4 /* this SoC has 4 PIO */ -#define ATMEL_BASE_PIO ATMEL_BASE_PIOA - -/* - * Cpu Name - */ -#define ATMEL_CPU_NAME "AT91SAM9RL" - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9rl_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9rl_matrix.h deleted file mode 100644 index 295f768b55..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9rl_matrix.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9rl_matrix.h] - * - * Copyright (C) 2007 Atmel Corporation - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9RL datasheet revision A. (Preliminary) - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#ifndef AT91SAM9RL_MATRIX_H -#define AT91SAM9RL_MATRIX_H - -#ifndef __ASSEMBLY__ - -struct at91_matrix { - u32 mcfg[16]; /* Master Configuration Registers */ - u32 scfg[16]; /* Slave Configuration Registers */ - u32 pras[16][2]; /* Priority Assignment Slave Registers */ - u32 mrcr; /* Master Remap Control Register */ - u32 filler[7]; - u32 ebicsa; /* EBI Chip Select Assignment Register */ -}; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 -#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) -#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) - -#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) -#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) -#define AT91_MATRIX_DBPUC (1 << 8) -#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9x5.h b/arch/arm/include/asm/arch-at91/at91sam9x5.h deleted file mode 100644 index 36a5cdf476..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9x5.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Chip-specific header file for the AT91SAM9x5 family - * - * Copyright (C) 2012-2013 Atmel Corporation. - * - * Definitions for the SoC: - * AT91SAM9x5 & AT91SAM9N12 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __AT91SAM9X5_H__ -#define __AT91SAM9X5_H__ - -#define CONFIG_AT91FAMILY /* it's a member of AT91 family */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ -#define ATMEL_ID_PIOAB 2 /* Parallel I/O Controller A and B */ -#define ATMEL_ID_PIOCD 3 /* Parallel I/O Controller C and D */ -#define ATMEL_ID_SMD 4 /* SMD Soft Modem (SMD), only for AT91SAM9X5 */ -#define ATMEL_ID_FUSE 4 /* FUSE Controller, only for AT91SAM9N12 */ -#define ATMEL_ID_USART0 5 /* USART 0 */ -#define ATMEL_ID_USART1 6 /* USART 1 */ -#define ATMEL_ID_USART2 7 /* USART 2 */ -#define ATMEL_ID_USART3 8 /* USART 3 */ -#define ATMEL_ID_TWI0 9 /* Two-Wire Interface 0 */ -#define ATMEL_ID_TWI1 10 /* Two-Wire Interface 1 */ -#define ATMEL_ID_TWI2 11 /* Two-Wire Interface 2 */ -#define ATMEL_ID_HSMCI0 12 /* High Speed Multimedia Card Interface 0 */ -#define ATMEL_ID_SPI0 13 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 14 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_UART0 15 /* UART 0 */ -#define ATMEL_ID_UART1 16 /* UART 1 */ -#define ATMEL_ID_TC01 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ -#define ATMEL_ID_PWM 18 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_ADC 19 /* ADC Controller */ -#define ATMEL_ID_DMAC0 20 /* DMA Controller 0 */ -#define ATMEL_ID_DMAC1 21 /* DMA Controller 1 */ -#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */ -#define ATMEL_ID_UDPHS 23 /* USB Device High Speed */ -#define ATMEL_ID_EMAC0 24 /* Ethernet MAC0 */ -#define ATMEL_ID_LCDC 25 /* LCD Controller */ -#define ATMEL_ID_HSMCI1 26 /* High Speed Multimedia Card Interface 1 */ -#define ATMEL_ID_EMAC1 27 /* Ethernet MAC1 */ -#define ATMEL_ID_SSC 28 /* Synchronous Serial Controller */ -#define ATMEL_ID_TRNG 30 /* True Random Number Generator */ -#define ATMEL_ID_IRQ 31 /* Advanced Interrupt Controller */ - -/* - * User Peripheral physical base addresses. - */ -#define ATMEL_BASE_SPI0 0xf0000000 -#define ATMEL_BASE_SPI1 0xf0004000 -#define ATMEL_BASE_HSMCI0 0xf0008000 -#define ATMEL_BASE_HSMCI1 0xf000c000 -#define ATMEL_BASE_SSC 0xf0010000 -#define ATMEL_BASE_CAN0 0xf8000000 -#define ATMEL_BASE_CAN1 0xf8004000 -#define ATMEL_BASE_TC0 0xf8008000 -#define ATMEL_BASE_TC1 0xf8008040 -#define ATMEL_BASE_TC2 0xf8008080 -#define ATMEL_BASE_TC3 0xf800c000 -#define ATMEL_BASE_TC4 0xf800c040 -#define ATMEL_BASE_TC5 0xf800c080 -#define ATMEL_BASE_TWI0 0xf8010000 -#define ATMEL_BASE_TWI1 0xf8014000 -#define ATMEL_BASE_TWI2 0xf8018000 -#define ATMEL_BASE_USART0 0xf801c000 -#define ATMEL_BASE_USART1 0xf8020000 -#define ATMEL_BASE_USART2 0xf8024000 -#define ATMEL_BASE_USART3 0xf8028000 -#define ATMEL_BASE_EMAC0 0xf802c000 -#define ATMEL_BASE_EMAC1 0xf8030000 -#define ATMEL_BASE_PWM 0xf8034000 -#define ATMEL_BASE_LCDC 0xf8038000 -#define ATMEL_BASE_UDPHS 0xf803c000 -#define ATMEL_BASE_UART0 0xf8040000 -#define ATMEL_BASE_UART1 0xf8044000 -#define ATMEL_BASE_ISI 0xf8048000 -#define ATMEL_BASE_ADC 0xf804c000 -#define ATMEL_BASE_SYS 0xffffc000 - -/* - * System Peripherals - */ -#define ATMEL_BASE_FUSE 0xffffdc00 -#define ATMEL_BASE_MATRIX 0xffffde00 -#define ATMEL_BASE_PMECC 0xffffe000 -#define ATMEL_BASE_PMERRLOC 0xffffe600 -#define ATMEL_BASE_DDRSDRC 0xffffe800 -#define ATMEL_BASE_SMC 0xffffea00 -#define ATMEL_BASE_DMAC0 0xffffec00 -#define ATMEL_BASE_DMAC1 0xffffee00 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_DBGU 0xfffff200 -#define ATMEL_BASE_PIOA 0xfffff400 -#define ATMEL_BASE_PIOB 0xfffff600 -#define ATMEL_BASE_PIOC 0xfffff800 -#define ATMEL_BASE_PIOD 0xfffffa00 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffe00 -#define ATMEL_BASE_SHDWC 0xfffffe10 -#define ATMEL_BASE_PIT 0xfffffe30 -#define ATMEL_BASE_WDT 0xfffffe40 -#define ATMEL_BASE_GPBR 0xfffffe60 -#define ATMEL_BASE_RTC 0xfffffeb0 - -/* - * Internal Memory. - */ -#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ -#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ - -#ifdef CONFIG_AT91SAM9N12 -#define ATMEL_BASE_OHCI 0x00500000 /* USB Host controller */ -#else /* AT91SAM9X5 */ -#define ATMEL_BASE_SMD 0x00400000 /* SMD Controller */ -#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ -#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ -#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ -#endif - -/* 9x5 series chip id definitions */ -#define ARCH_ID_AT91SAM9X5 0x819a05a0 -#define ARCH_ID_VERSION_MASK 0x1f -#define ARCH_EXID_AT91SAM9G15 0x00000000 -#define ARCH_EXID_AT91SAM9G35 0x00000001 -#define ARCH_EXID_AT91SAM9X35 0x00000002 -#define ARCH_EXID_AT91SAM9G25 0x00000003 -#define ARCH_EXID_AT91SAM9X25 0x00000004 - -#define cpu_is_at91sam9x5() (get_chip_id() == ARCH_ID_AT91SAM9X5) -#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ - (get_extension_chip_id() == ARCH_EXID_AT91SAM9G15)) -#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ - (get_extension_chip_id() == ARCH_EXID_AT91SAM9G25)) -#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ - (get_extension_chip_id() == ARCH_EXID_AT91SAM9G35)) -#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ - (get_extension_chip_id() == ARCH_EXID_AT91SAM9X25)) -#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ - (get_extension_chip_id() == ARCH_EXID_AT91SAM9X35)) - -/* - * Cpu Name - */ -#ifdef CONFIG_AT91SAM9N12 -#define ATMEL_CPU_NAME "AT91SAM9N12" -#else /* AT91SAM9X5 */ -#define ATMEL_CPU_NAME get_cpu_name() -#endif - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 4 -#define CPU_HAS_PIO3 -#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ -#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP -#define ATMEL_ID_UHP ATMEL_ID_UHPHS - -/* - * PMECC table in ROM - */ -#define ATMEL_PMECC_INDEX_OFFSET_512 0x8000 -#define ATMEL_PMECC_INDEX_OFFSET_1024 0x10000 - -/* - * at91sam9x5 specific prototypes - */ -#ifndef __ASSEMBLY__ -unsigned int get_chip_id(void); -unsigned int get_extension_chip_id(void); -unsigned int has_emac1(void); -unsigned int has_emac0(void); -unsigned int has_lcdc(void); -char *get_cpu_name(void); -#endif - -#endif diff --git a/arch/arm/include/asm/arch-at91/at91sam9x5_matrix.h b/arch/arm/include/asm/arch-at91/at91sam9x5_matrix.h deleted file mode 100644 index bd0b25adc9..0000000000 --- a/arch/arm/include/asm/arch-at91/at91sam9x5_matrix.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Matrix-centric header file for the AT91SAM9X5 family - * - * Copyright (C) 2012-2013 Atmel Corporation. - * - * Memory Controllers (MATRIX, EBI) - System peripherals registers. - * Based on AT91SAM9X5 & AT91SAM9N12 preliminary datasheet. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __AT91SAM9X5_MATRIX_H__ -#define __AT91SAM9X5_MATRIX_H__ - -#ifndef __ASSEMBLY__ - -/* AT91SAM9N12 Matrix definition is a subset of AT91SAM9X5. */ -struct at91_matrix { - u32 mcfg[16]; - u32 scfg[16]; - u32 pras[16][2]; - u32 mrcr; /* 0x100 Master Remap Control */ - u32 filler[5]; -#ifdef CONFIG_AT91SAM9X5 - u32 filler1[2]; -#endif - /* EBI Chip Select Assignment Register - * 0x118: AT91SAM9N12 - * 0x120: AT91SAM9X5 - */ - u32 ebicsa; - u32 filler4[47]; -#ifdef CONFIG_AT91SAM9N12 - u32 filler5[2]; -#endif - u32 wpmr; - u32 wpsr; -}; - -#endif /* __ASSEMBLY__ */ - -#define AT91_MATRIX_ULBT_INFINITE (0 << 0) -#define AT91_MATRIX_ULBT_SINGLE (1 << 0) -#define AT91_MATRIX_ULBT_FOUR (2 << 0) -#define AT91_MATRIX_ULBT_EIGHT (3 << 0) -#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) -#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) -#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) -#define AT91_MATRIX_ULBT_128 (7 << 0) - -#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) -#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) -#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 - -#define AT91_MATRIX_M0PR_SHIFT 0 -#define AT91_MATRIX_M1PR_SHIFT 4 -#define AT91_MATRIX_M2PR_SHIFT 8 -#define AT91_MATRIX_M3PR_SHIFT 12 -#define AT91_MATRIX_M4PR_SHIFT 16 -#define AT91_MATRIX_M5PR_SHIFT 20 -#define AT91_MATRIX_M6PR_SHIFT 24 -#define AT91_MATRIX_M7PR_SHIFT 28 - -#define AT91_MATRIX_M8PR_SHIFT 0 /* register B */ -#define AT91_MATRIX_M9PR_SHIFT 4 /* register B */ -#define AT91_MATRIX_M10PR_SHIFT 8 /* register B */ -#define AT91_MATRIX_M11PR_SHIFT 12 /* register B */ - -#define AT91_MATRIX_RCB0 (1 << 0) -#define AT91_MATRIX_RCB1 (1 << 1) -#define AT91_MATRIX_RCB2 (1 << 2) -#define AT91_MATRIX_RCB3 (1 << 3) -#define AT91_MATRIX_RCB4 (1 << 4) -#define AT91_MATRIX_RCB5 (1 << 5) -#define AT91_MATRIX_RCB6 (1 << 6) -#define AT91_MATRIX_RCB7 (1 << 7) -#define AT91_MATRIX_RCB8 (1 << 8) -#define AT91_MATRIX_RCB9 (1 << 9) -#define AT91_MATRIX_RCB10 (1 << 10) - -#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) -#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) -#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) -#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) -#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) -#define AT91_MATRIX_EBI_DBPD_ON (0 << 9) -#define AT91_MATRIX_EBI_DBPD_OFF (1 << 9) -#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) -#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) -#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) -#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) -#define AT91_MATRIX_NFD0_ON_D0 (0 << 24) -#define AT91_MATRIX_NFD0_ON_D16 (1 << 24) -#define AT91_MATRIX_MP_OFF (0 << 25) -#define AT91_MATRIX_MP_ON (1 << 25) - -#endif diff --git a/arch/arm/include/asm/arch-at91/atmel_mpddrc.h b/arch/arm/include/asm/arch-at91/atmel_mpddrc.h deleted file mode 100644 index 130a85abee..0000000000 --- a/arch/arm/include/asm/arch-at91/atmel_mpddrc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ATMEL_MPDDRC_H__ -#define __ATMEL_MPDDRC_H__ - -/* - * Only define the needed register in mpddr - * If other register needed, will add them later - */ -struct atmel_mpddr { - u32 mr; - u32 rtr; - u32 cr; - u32 tpr0; - u32 tpr1; - u32 tpr2; - u32 reserved[2]; - u32 md; -}; - -int ddr2_init(const unsigned int ram_address, - const struct atmel_mpddr *mpddr); - -/* Bit field in mode register */ -#define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD 0x0 -#define ATMEL_MPDDRC_MR_MODE_NOP_CMD 0x1 -#define ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD 0x2 -#define ATMEL_MPDDRC_MR_MODE_LMR_CMD 0x3 -#define ATMEL_MPDDRC_MR_MODE_RFSH_CMD 0x4 -#define ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD 0x5 -#define ATMEL_MPDDRC_MR_MODE_DEEP_CMD 0x6 -#define ATMEL_MPDDRC_MR_MODE_LPDDR2_CMD 0x7 - -/* Bit field in configuration register */ -#define ATMEL_MPDDRC_CR_NC_MASK 0x3 -#define ATMEL_MPDDRC_CR_NC_COL_9 0x0 -#define ATMEL_MPDDRC_CR_NC_COL_10 0x1 -#define ATMEL_MPDDRC_CR_NC_COL_11 0x2 -#define ATMEL_MPDDRC_CR_NC_COL_12 0x3 -#define ATMEL_MPDDRC_CR_NR_MASK (0x3 << 2) -#define ATMEL_MPDDRC_CR_NR_ROW_11 (0x0 << 2) -#define ATMEL_MPDDRC_CR_NR_ROW_12 (0x1 << 2) -#define ATMEL_MPDDRC_CR_NR_ROW_13 (0x2 << 2) -#define ATMEL_MPDDRC_CR_NR_ROW_14 (0x3 << 2) -#define ATMEL_MPDDRC_CR_CAS_MASK (0x7 << 4) -#define ATMEL_MPDDRC_CR_CAS_DDR_CAS2 (0x2 << 4) -#define ATMEL_MPDDRC_CR_CAS_DDR_CAS3 (0x3 << 4) -#define ATMEL_MPDDRC_CR_CAS_DDR_CAS4 (0x4 << 4) -#define ATMEL_MPDDRC_CR_CAS_DDR_CAS5 (0x5 << 4) -#define ATMEL_MPDDRC_CR_CAS_DDR_CAS6 (0x6 << 4) -#define ATMEL_MPDDRC_CR_DLL_RESET_ENABLED (0x1 << 7) -#define ATMEL_MPDDRC_CR_DIC_DS (0x1 << 8) -#define ATMEL_MPDDRC_CR_DIS_DLL (0x1 << 9) -#define ATMEL_MPDDRC_CR_OCD_DEFAULT (0x7 << 12) -#define ATMEL_MPDDRC_CR_DQMS_SHARED (0x1 << 16) -#define ATMEL_MPDDRC_CR_ENRDM_ON (0x1 << 17) -#define ATMEL_MPDDRC_CR_NB_8BANKS (0x1 << 20) -#define ATMEL_MPDDRC_CR_NDQS_DISABLED (0x1 << 21) -#define ATMEL_MPDDRC_CR_DECOD_INTERLEAVED (0x1 << 22) -#define ATMEL_MPDDRC_CR_UNAL_SUPPORTED (0x1 << 23) - -/* Bit field in timing parameter 0 register */ -#define ATMEL_MPDDRC_TPR0_TRAS_OFFSET 0 -#define ATMEL_MPDDRC_TPR0_TRAS_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TRCD_OFFSET 4 -#define ATMEL_MPDDRC_TPR0_TRCD_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TWR_OFFSET 8 -#define ATMEL_MPDDRC_TPR0_TWR_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TRC_OFFSET 12 -#define ATMEL_MPDDRC_TPR0_TRC_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TRP_OFFSET 16 -#define ATMEL_MPDDRC_TPR0_TRP_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TRRD_OFFSET 20 -#define ATMEL_MPDDRC_TPR0_TRRD_MASK 0xf -#define ATMEL_MPDDRC_TPR0_TWTR_OFFSET 24 -#define ATMEL_MPDDRC_TPR0_TWTR_MASK 0x7 -#define ATMEL_MPDDRC_TPR0_RDC_WRRD_OFFSET 27 -#define ATMEL_MPDDRC_TPR0_RDC_WRRD_MASK 0x1 -#define ATMEL_MPDDRC_TPR0_TMRD_OFFSET 28 -#define ATMEL_MPDDRC_TPR0_TMRD_MASK 0xf - -/* Bit field in timing parameter 1 register */ -#define ATMEL_MPDDRC_TPR1_TRFC_OFFSET 0 -#define ATMEL_MPDDRC_TPR1_TRFC_MASK 0x7f -#define ATMEL_MPDDRC_TPR1_TXSNR_OFFSET 8 -#define ATMEL_MPDDRC_TPR1_TXSNR_MASK 0xff -#define ATMEL_MPDDRC_TPR1_TXSRD_OFFSET 16 -#define ATMEL_MPDDRC_TPR1_TXSRD_MASK 0xff -#define ATMEL_MPDDRC_TPR1_TXP_OFFSET 24 -#define ATMEL_MPDDRC_TPR1_TXP_MASK 0xf - -/* Bit field in timing parameter 2 register */ -#define ATMEL_MPDDRC_TPR2_TXARD_OFFSET 0 -#define ATMEL_MPDDRC_TPR2_TXARD_MASK 0xf -#define ATMEL_MPDDRC_TPR2_TXARDS_OFFSET 4 -#define ATMEL_MPDDRC_TPR2_TXARDS_MASK 0xf -#define ATMEL_MPDDRC_TPR2_TRPA_OFFSET 8 -#define ATMEL_MPDDRC_TPR2_TRPA_MASK 0xf -#define ATMEL_MPDDRC_TPR2_TRTP_OFFSET 12 -#define ATMEL_MPDDRC_TPR2_TRTP_MASK 0x7 -#define ATMEL_MPDDRC_TPR2_TFAW_OFFSET 16 -#define ATMEL_MPDDRC_TPR2_TFAW_MASK 0xf - -/* Bit field in Memory Device Register */ -#define ATMEL_MPDDRC_MD_LPDDR_SDRAM 0x3 -#define ATMEL_MPDDRC_MD_DDR2_SDRAM 0x6 -#define ATMEL_MPDDRC_MD_DBW_MASK (0x1 << 4) -#define ATMEL_MPDDRC_MD_DBW_32_BITS (0x0 << 4) -#define ATMEL_MPDDRC_MD_DBW_16_BITS (0x1 << 4) - -#endif diff --git a/arch/arm/include/asm/arch-at91/atmel_serial.h b/arch/arm/include/asm/arch-at91/atmel_serial.h deleted file mode 100644 index 5bc094b355..0000000000 --- a/arch/arm/include/asm/arch-at91/atmel_serial.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ATMEL_SERIAL_H -#define _ATMEL_SERIAL_H - -/* Information about a serial port */ -struct atmel_serial_platdata { - uint32_t base_addr; -}; - -#endif diff --git a/arch/arm/include/asm/arch-at91/atmel_usba_udc.h b/arch/arm/include/asm/arch-at91/atmel_usba_udc.h deleted file mode 100644 index 38b5012fce..0000000000 --- a/arch/arm/include/asm/arch-at91/atmel_usba_udc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2005-2013 Atmel Corporation - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ATMEL_USBA_UDC_H__ -#define __ATMEL_USBA_UDC_H__ - -#include - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ - defined(CONFIG_AT91SAM9X5) -static struct usba_ep_data usba_udc_ep[] = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 2, 1, 1), - EP("ep2", 2, 1024, 2, 1, 1), - EP("ep3", 3, 1024, 3, 1, 0), - EP("ep4", 4, 1024, 3, 1, 0), - EP("ep5", 5, 1024, 3, 1, 1), - EP("ep6", 6, 1024, 3, 1, 1), -}; -#elif defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) -static struct usba_ep_data usba_udc_ep[] = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 1024, 3, 1, 0), - EP("ep2", 2, 1024, 3, 1, 0), - EP("ep3", 3, 1024, 2, 1, 0), - EP("ep4", 4, 1024, 2, 1, 0), - EP("ep5", 5, 1024, 2, 1, 0), - EP("ep6", 6, 1024, 2, 1, 0), - EP("ep7", 7, 1024, 2, 1, 0), - EP("ep8", 8, 1024, 2, 0, 0), - EP("ep9", 9, 1024, 2, 0, 0), - EP("ep10", 10, 1024, 2, 0, 0), - EP("ep11", 11, 1024, 2, 0, 0), - EP("ep12", 12, 1024, 2, 0, 0), - EP("ep13", 13, 1024, 2, 0, 0), - EP("ep14", 14, 1024, 2, 0, 0), - EP("ep15", 15, 1024, 2, 0, 0), -}; -#else -# error "NO usba_udc_ep defined" -#endif - -#undef EP - -struct usba_platform_data pdata = { - .num_ep = ARRAY_SIZE(usba_udc_ep), - .ep = usba_udc_ep, -}; - -#endif diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h deleted file mode 100644 index 1d45e2dc11..0000000000 --- a/arch/arm/include/asm/arch-at91/clk.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * (C) Copyright 2007 - * Stelian Pop - * Lead Tech Design - * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __ASM_ARM_ARCH_CLK_H__ -#define __ASM_ARM_ARCH_CLK_H__ - -#include -#include -#include - -static inline unsigned long get_cpu_clk_rate(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.cpu_clk_rate_hz; -} - -static inline unsigned long get_main_clk_rate(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.main_clk_rate_hz; -} - -static inline unsigned long get_mck_clk_rate(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.mck_rate_hz; -} - -static inline unsigned long get_plla_clk_rate(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.plla_rate_hz; -} - -static inline unsigned long get_pllb_clk_rate(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.pllb_rate_hz; -} - -static inline u32 get_pllb_init(void) -{ - DECLARE_GLOBAL_DATA_PTR; - return gd->arch.at91_pllb_usb_init; -} - -#ifdef CPU_HAS_H32MXDIV -static inline unsigned int get_h32mxdiv(void) -{ - struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; - - return readl(&pmc->mckr) & AT91_PMC_MCKR_H32MXDIV; -} -#else -static inline unsigned int get_h32mxdiv(void) -{ - return 0; -} -#endif - -static inline unsigned long get_macb_pclk_rate(unsigned int dev_id) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -static inline unsigned long get_usart_clk_rate(unsigned int dev_id) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -static inline unsigned long get_lcdc_clk_rate(unsigned int dev_id) -{ - return get_mck_clk_rate(); -} - -static inline unsigned long get_spi_clk_rate(unsigned int dev_id) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -static inline unsigned long get_twi_clk_rate(unsigned int dev_id) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -static inline unsigned long get_mci_clk_rate(void) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -static inline unsigned long get_pit_clk_rate(void) -{ - if (get_h32mxdiv()) - return get_mck_clk_rate() / 2; - else - return get_mck_clk_rate(); -} - -int at91_clock_init(unsigned long main_clock); -void at91_periph_clk_enable(int id); -void at91_periph_clk_disable(int id); -#endif /* __ASM_ARM_ARCH_CLK_H__ */ diff --git a/arch/arm/include/asm/arch-at91/gpio.h b/arch/arm/include/asm/arch-at91/gpio.h deleted file mode 100644 index 6d2a7b72ff..0000000000 --- a/arch/arm/include/asm/arch-at91/gpio.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * [origin: Linux kernel include/asm-arm/arch-at91/gpio.h] - * - * Copyright (C) 2005 HP Labs - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_AT91_GPIO_H -#define __ASM_ARCH_AT91_GPIO_H - -#include -#include -#include -#include - -#ifdef CONFIG_ATMEL_LEGACY - -#define PIN_BASE 0 - -#define MAX_GPIO_BANKS 5 - -/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ - -#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) -#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) -#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) -#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) -#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) -#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) -#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) -#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) -#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) -#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) -#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) -#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) -#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) -#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) -#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) -#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) -#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) -#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) -#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) -#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) -#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) -#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) -#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) -#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) -#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) -#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) -#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) -#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) -#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) -#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) -#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) -#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) - -#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) -#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) -#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) -#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) -#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) -#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) -#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) -#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) -#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) -#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) -#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) -#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) -#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) -#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) -#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) -#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) -#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) -#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) -#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) -#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) -#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) -#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) -#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) -#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) -#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) -#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) -#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) -#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) -#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) -#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) -#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) -#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) - -#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) -#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) -#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) -#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) -#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) -#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) -#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) -#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) -#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) -#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) -#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) -#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) -#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) -#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) -#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) -#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) -#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) -#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) -#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) -#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) -#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) -#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) -#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) -#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) -#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) -#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) -#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) -#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) -#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) -#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) -#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) -#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) - -#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) -#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) -#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) -#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) -#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) -#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) -#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) -#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) -#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) -#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) -#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) -#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) -#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) -#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) -#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) -#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) -#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) -#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) -#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) -#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) -#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) -#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) -#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) -#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) -#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) -#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) -#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) -#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) -#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) -#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) -#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) -#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) - -#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) -#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) -#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) -#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) -#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) -#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) -#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) -#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) -#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) -#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) -#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) -#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) -#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) -#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) -#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) -#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) -#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) -#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) -#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) -#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) -#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) -#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) -#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) -#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) -#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) -#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) -#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) -#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) -#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) -#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) -#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) -#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) - -static unsigned long at91_pios[] = { - ATMEL_BASE_PIOA, - ATMEL_BASE_PIOB, - ATMEL_BASE_PIOC, -#ifdef ATMEL_BASE_PIOD - ATMEL_BASE_PIOD, -#ifdef ATMEL_BASE_PIOE - ATMEL_BASE_PIOE -#endif -#endif -}; - -static inline void *pin_to_controller(unsigned pin) -{ - pin -= PIN_BASE; - pin /= 32; - return (void *)(at91_pios[pin]); -} - -static inline unsigned pin_to_mask(unsigned pin) -{ - pin -= PIN_BASE; - return 1 << (pin % 32); -} - -/* The following macros are need for backward compatibility */ -#define at91_set_GPIO_periph(x, y) \ - at91_set_pio_periph((x - PIN_BASE) / 32,(x % 32), y) -#define at91_set_A_periph(x, y) \ - at91_set_a_periph((x - PIN_BASE) / 32,(x % 32), y) -#define at91_set_B_periph(x, y) \ - at91_set_b_periph((x - PIN_BASE) / 32,(x % 32), y) -#define at91_set_gpio_output(x, y) \ - at91_set_pio_output((x - PIN_BASE) / 32,(x % 32), y) -#define at91_set_gpio_input(x, y) \ - at91_set_pio_input((x - PIN_BASE) / 32,(x % 32), y) -#define at91_set_gpio_value(x, y) \ - at91_set_pio_value((x - PIN_BASE) / 32,(x % 32), y) -#define at91_get_gpio_value(x) \ - at91_get_pio_value((x - PIN_BASE) / 32,(x % 32)) -#else -#define at91_set_gpio_value(x, y) at91_set_pio_value(x, y) -#define at91_get_gpio_value(x) at91_get_pio_value(x) -#endif - -#define GPIO_PIOA_BASE (0) -#define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32) -#define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32) -#define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32) -#define GPIO_PIOE_BASE (GPIO_PIOD_BASE + 32) -#define GPIO_PIN_PA(x) (GPIO_PIOA_BASE + (x)) -#define GPIO_PIN_PB(x) (GPIO_PIOB_BASE + (x)) -#define GPIO_PIN_PC(x) (GPIO_PIOC_BASE + (x)) -#define GPIO_PIN_PD(x) (GPIO_PIOD_BASE + (x)) -#define GPIO_PIN_PE(x) (GPIO_PIOE_BASE + (x)) - -static inline unsigned at91_gpio_to_port(unsigned gpio) -{ - return gpio / 32; -} - -static inline unsigned at91_gpio_to_pin(unsigned gpio) -{ - return gpio % 32; -} - -/* Platform data for each GPIO port */ -struct at91_port_platdata { - uint32_t base_addr; - const char *bank_name; -}; - -#endif /* __ASM_ARCH_AT91_GPIO_H */ diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h deleted file mode 100644 index ff6b71b135..0000000000 --- a/arch/arm/include/asm/arch-at91/hardware.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Stelian Pop - * Lead Tech Design - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __ASM_ARM_ARCH_HARDWARE_H__ -#define __ASM_ARM_ARCH_HARDWARE_H__ - -#if defined(CONFIG_AT91RM9200) -# include -#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) || \ - defined(CONFIG_AT91SAM9XE) -# include -#elif defined(CONFIG_AT91SAM9261) || defined(CONFIG_AT91SAM9G10) -# include -#elif defined(CONFIG_AT91SAM9263) -# include -#elif defined(CONFIG_AT91SAM9RL) -# include -#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) -# include -#elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) -# include -#elif defined(CONFIG_SAMA5D3) -# include -#elif defined(CONFIG_SAMA5D4) -# include -#else -# error "Unsupported AT91 processor" -#endif - -#endif /* __ASM_ARM_ARCH_HARDWARE_H__ */ diff --git a/arch/arm/include/asm/arch-at91/sama5_matrix.h b/arch/arm/include/asm/arch-at91/sama5_matrix.h deleted file mode 100644 index e324766733..0000000000 --- a/arch/arm/include/asm/arch-at91/sama5_matrix.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Bus Matrix header file for the SAMA5 family - * - * Copyright (C) 2014 Atmel - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __SAMA5_MATRIX_H -#define __SAMA5_MATRIX_H - -struct atmel_matrix { - u32 mcfg[16]; /* 0x00 ~ 0x3c: Master Configuration Register */ - u32 scfg[16]; /* 0x40 ~ 0x7c: Slave Configuration Register */ - u32 pras[16][2];/* 0x80 ~ 0xfc: Priority Register A/B */ - u32 res1[20]; /* 0x100 ~ 0x14c */ - u32 meier; /* 0x150: Master Error Interrupt Enable Register */ - u32 meidr; /* 0x154: Master Error Interrupt Disable Register */ - u32 meimr; /* 0x158: Master Error Interrupt Mask Register */ - u32 mesr; /* 0x15c: Master Error Status Register */ - u32 mear[16]; /* 0x160 ~ 0x19c: Master Error Address Register */ - u32 res2[17]; /* 0x1A0 ~ 0x1E0 */ - u32 wpmr; /* 0x1E4: Write Protection Mode Register */ - u32 wpsr; /* 0x1E8: Write Protection Status Register */ - u32 res3[5]; /* 0x1EC ~ 0x1FC */ - u32 ssr[16]; /* 0x200 ~ 0x23c: Security Slave Register */ - u32 sassr[16]; /* 0x240 ~ 0x27c: Security Areas Split Slave Register */ - u32 srtsr[16]; /* 0x280 ~ 0x2bc: Security Region Top Slave */ - u32 spselr[3]; /* 0x2c0 ~ 0x2c8: Security Peripheral Select Register */ -}; - -/* Bit field in WPMR */ -#define ATMEL_MATRIX_WPMR_WPKEY 0x4D415400 -#define ATMEL_MATRIX_WPMR_WPEN 0x00000001 - -#endif diff --git a/arch/arm/include/asm/arch-at91/sama5_sfr.h b/arch/arm/include/asm/arch-at91/sama5_sfr.h deleted file mode 100644 index 3081d37571..0000000000 --- a/arch/arm/include/asm/arch-at91/sama5_sfr.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Special Function Register (SFR) - * - * Copyright (C) 2014 Atmel - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __SAMA5_SFR_H -#define __SAMA5_SFR_H - -struct atmel_sfr { - u32 reserved1; /* 0x00 */ - u32 ddrcfg; /* 0x04: DDR Configuration Register */ - u32 reserved2; /* 0x08 */ - u32 reserved3; /* 0x0c */ - u32 ohciicr; /* 0x10: OHCI Interrupt Configuration Register */ - u32 ohciisr; /* 0x14: OHCI Interrupt Status Register */ - u32 reserved4[4]; /* 0x18 ~ 0x24 */ - u32 secure; /* 0x28: Security Configuration Register */ - u32 reserved5[5]; /* 0x2c ~ 0x3c */ - u32 ebicfg; /* 0x40: EBI Configuration Register */ - u32 reserved6[2]; /* 0x44 ~ 0x48 */ - u32 sn0; /* 0x4c */ - u32 sn1; /* 0x50 */ - u32 aicredir; /* 0x54 */ -}; - -/* Bit field in DDRCFG */ -#define ATMEL_SFR_DDRCFG_FDQIEN 0x00010000 -#define ATMEL_SFR_DDRCFG_FDQSIEN 0x00020000 - -/* Bit field in AICREDIR */ -#define ATMEL_SFR_AICREDIR_KEY 0x5F67B102 -#define ATMEL_SFR_AICREDIR_NSAIC 0x00000001 - -#endif diff --git a/arch/arm/include/asm/arch-at91/sama5d3.h b/arch/arm/include/asm/arch-at91/sama5d3.h deleted file mode 100644 index 227ba80825..0000000000 --- a/arch/arm/include/asm/arch-at91/sama5d3.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Chip-specific header file for the SAMA5D3 family - * - * (C) 2012 - 2013 Atmel Corporation. - * Bo Shen - * - * Definitions for the SoC: - * SAMA5D3 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef SAMA5D3_H -#define SAMA5D3_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* it's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ -#define ATMEL_ID_DBGU 2 /* Debug Unit Interrupt */ -#define ATMEL_ID_PIT 3 /* Periodic Interval Timer Interrupt */ -#define ATMEL_ID_WDT 4 /* Watchdog timer Interrupt */ -#define ATMEL_ID_SMC 5 /* Multi-bit ECC Interrupt */ -#define ATMEL_ID_PIOA 6 /* Parallel I/O Controller A */ -#define ATMEL_ID_PIOB 7 /* Parallel I/O Controller B */ -#define ATMEL_ID_PIOC 8 /* Parallel I/O Controller C */ -#define ATMEL_ID_PIOD 9 /* Parallel I/O Controller D */ -#define ATMEL_ID_PIOE 10 /* Parallel I/O Controller E */ -#define ATMEL_ID_SMD 11 /* SMD Soft Modem */ -#define ATMEL_ID_USART0 12 /* USART 0 */ -#define ATMEL_ID_USART1 13 /* USART 1 */ -#define ATMEL_ID_USART2 14 /* USART 2 */ -#define ATMEL_ID_USART3 15 /* USART 3 */ -#define ATMEL_ID_UART0 16 -#define ATMEL_ID_UART1 17 -#define ATMEL_ID_TWI0 18 /* Two-Wire Interface 0 */ -#define ATMEL_ID_TWI1 19 /* Two-Wire Interface 1 */ -#define ATMEL_ID_TWI2 20 /* Two-Wire Interface 2 */ -#define ATMEL_ID_MCI0 21 /* High Speed Multimedia Card Interface 0 */ -#define ATMEL_ID_MCI1 22 /* */ -#define ATMEL_ID_MCI2 23 /* */ -#define ATMEL_ID_SPI0 24 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 25 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_TC0 26 /* */ -#define ATMEL_ID_TC1 27 /* */ -#define ATMEL_ID_PWMC 28 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_TSC 29 /* Touch Screen ADC Controller */ -#define ATMEL_ID_DMA0 30 /* DMA Controller */ -#define ATMEL_ID_DMA1 31 /* DMA Controller */ -#define ATMEL_ID_UHPHS 32 /* USB Host High Speed */ -#define ATMEL_ID_UDPHS 33 /* USB Device High Speed */ -#define ATMEL_ID_GMAC 34 -#define ATMEL_ID_EMAC 35 /* Ethernet MAC */ -#define ATMEL_ID_LCDC 36 /* LCD Controller */ -#define ATMEL_ID_ISI 37 /* Image Sensor Interface */ -#define ATMEL_ID_SSC0 38 /* Synchronous Serial Controller 0 */ -#define ATMEL_ID_SSC1 39 /* Synchronous Serial Controller 1 */ -#define ATMEL_ID_CAN0 40 -#define ATMEL_ID_CAN1 41 -#define ATMEL_ID_SHA 42 -#define ATMEL_ID_AES 43 -#define ATMEL_ID_TDES 44 -#define ATMEL_ID_TRNG 45 -#define ATMEL_ID_ARM 46 -#define ATMEL_ID_IRQ0 47 /* Advanced Interrupt Controller */ -#define ATMEL_ID_FUSE 48 -#define ATMEL_ID_MPDDRC 49 - -/* sama5d3 series chip id definitions */ -#define ARCH_ID_SAMA5D3 0x8a5c07c0 -#define ARCH_EXID_SAMA5D31 0x00444300 -#define ARCH_EXID_SAMA5D33 0x00414300 -#define ARCH_EXID_SAMA5D34 0x00414301 -#define ARCH_EXID_SAMA5D35 0x00584300 -#define ARCH_EXID_SAMA5D36 0x00004301 - -#define cpu_is_sama5d3() (get_chip_id() == ARCH_ID_SAMA5D3) -#define cpu_is_sama5d31() (cpu_is_sama5d3() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D31)) -#define cpu_is_sama5d33() (cpu_is_sama5d3() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D33)) -#define cpu_is_sama5d34() (cpu_is_sama5d3() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D34)) -#define cpu_is_sama5d35() (cpu_is_sama5d3() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D35)) -#define cpu_is_sama5d36() (cpu_is_sama5d3() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D36)) - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_MCI0 0xf0000000 -#define ATMEL_BASE_SPI0 0xf0004000 -#define ATMEL_BASE_SSC0 0xf000C000 -#define ATMEL_BASE_TC2 0xf0010000 -#define ATMEL_BASE_TWI0 0xf0014000 -#define ATMEL_BASE_TWI1 0xf0018000 -#define ATMEL_BASE_USART0 0xf001c000 -#define ATMEL_BASE_USART1 0xf0020000 -#define ATMEL_BASE_UART0 0xf0024000 -#define ATMEL_BASE_GMAC 0xf0028000 -#define ATMEL_BASE_PWMC 0xf002c000 -#define ATMEL_BASE_LCDC 0xf0030000 -#define ATMEL_BASE_ISI 0xf0034000 -#define ATMEL_BASE_SFR 0xf0038000 -/* Reserved: 0xf003c000 - 0xf8000000 */ -#define ATMEL_BASE_MCI1 0xf8000000 -#define ATMEL_BASE_MCI2 0xf8004000 -#define ATMEL_BASE_SPI1 0xf8008000 -#define ATMEL_BASE_SSC1 0xf800c000 -#define ATMEL_BASE_CAN1 0xf8010000 -#define ATMEL_BASE_TC3 0xf8014000 -#define ATMEL_BASE_TSADC 0xf8018000 -#define ATMEL_BASE_TWI2 0xf801c000 -#define ATMEL_BASE_USART2 0xf8020000 -#define ATMEL_BASE_USART3 0xf8024000 -#define ATMEL_BASE_UART1 0xf8028000 -#define ATMEL_BASE_EMAC 0xf802c000 -#define ATMEL_BASE_UDPHS 0xf8030000 -#define ATMEL_BASE_SHA 0xf8034000 -#define ATMEL_BASE_AES 0xf8038000 -#define ATMEL_BASE_TDES 0xf803c000 -#define ATMEL_BASE_TRNG 0xf8040000 -/* Reserved: 0xf804400 - 0xffffc00 */ - -/* - * System Peripherals physical base addresses. - */ -#define ATMEL_BASE_SYS 0xffffc000 -#define ATMEL_BASE_SMC 0xffffc000 -#define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) -#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) -#define ATMEL_BASE_FUSE 0xffffe400 -#define ATMEL_BASE_DMAC0 0xffffe600 -#define ATMEL_BASE_DMAC1 0xffffe800 -#define ATMEL_BASE_MPDDRC 0xffffea00 -#define ATMEL_BASE_MATRIX 0xffffec00 -#define ATMEL_BASE_DBGU 0xffffee00 -#define ATMEL_BASE_AIC 0xfffff000 -#define ATMEL_BASE_PIOA 0xfffff200 -#define ATMEL_BASE_PIOB 0xfffff400 -#define ATMEL_BASE_PIOC 0xfffff600 -#define ATMEL_BASE_PIOD 0xfffff800 -#define ATMEL_BASE_PIOE 0xfffffa00 -#define ATMEL_BASE_PMC 0xfffffc00 -#define ATMEL_BASE_RSTC 0xfffffe00 -#define ATMEL_BASE_SHDWN 0xfffffe10 -#define ATMEL_BASE_PIT 0xfffffe30 -#define ATMEL_BASE_WDT 0xfffffe40 -#define ATMEL_BASE_SCKCR 0xfffffe50 -#define ATMEL_BASE_GPBR 0xfffffe60 -#define ATMEL_BASE_RTC 0xfffffeb0 -/* Reserved: 0xfffffee0 - 0xffffffff */ - -/* - * Internal Memory. - */ -#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ -#define ATMEL_BASE_SRAM 0x00200000 /* Internal ROM base address */ -#define ATMEL_BASE_SRAM0 0x00300000 /* Internal SRAM base address */ -#define ATMEL_BASE_SRAM1 0x00310000 /* Internal SRAM base address */ -#define ATMEL_BASE_SMD 0x00400000 /* Internal ROM base address */ -#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ -#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ -#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ -#define ATMEL_BASE_AXI 0x00800000 /* Video Decoder Controller */ -#define ATMEL_BASE_DAP 0x00900000 /* Video Decoder Controller */ - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 -#define ATMEL_BASE_DDRCS 0x20000000 -#define ATMEL_BASE_CS1 0x40000000 -#define ATMEL_BASE_CS2 0x50000000 -#define ATMEL_BASE_CS3 0x60000000 - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 5 -#define CPU_HAS_PIO3 -#define PIO_SCDR_DIV 0x3fff -#define CPU_HAS_PCR - -/* - * PMECC table in ROM - */ -#define ATMEL_PMECC_INDEX_OFFSET_512 0x10000 -#define ATMEL_PMECC_INDEX_OFFSET_1024 0x18000 - -/* - * SAMA5D3 specific prototypes - */ -#ifndef __ASSEMBLY__ -unsigned int get_chip_id(void); -unsigned int get_extension_chip_id(void); -unsigned int has_emac(void); -unsigned int has_gmac(void); -unsigned int has_lcdc(void); -char *get_cpu_name(void); -#endif - -#endif diff --git a/arch/arm/include/asm/arch-at91/sama5d3_smc.h b/arch/arm/include/asm/arch-at91/sama5d3_smc.h deleted file mode 100644 index a859b6db9b..0000000000 --- a/arch/arm/include/asm/arch-at91/sama5d3_smc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2012 Atmel Corporation. - * - * Static Memory Controllers (SMC) - System peripherals registers. - * Based on SAMA5D3 datasheet. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef SAMA5D3_SMC_H -#define SAMA5D3_SMC_H - -#ifdef __ASSEMBLY__ -#define AT91_ASM_SMC_SETUP0 (ATMEL_BASE_SMC + 0x600) -#define AT91_ASM_SMC_PULSE0 (ATMEL_BASE_SMC + 0x604) -#define AT91_ASM_SMC_CYCLE0 (ATMEL_BASE_SMC + 0x608) -#define AT91_ASM_SMC_TIMINGS0 (ATMEL_BASE_SMC + 0x60c) -#define AT91_ASM_SMC_MODE0 (ATMEL_BASE_SMC + 0x610) -#else -struct at91_cs { - u32 setup; /* 0x600 SMC Setup Register */ - u32 pulse; /* 0x604 SMC Pulse Register */ - u32 cycle; /* 0x608 SMC Cycle Register */ - u32 timings; /* 0x60C SMC Cycle Register */ - u32 mode; /* 0x610 SMC Mode Register */ -}; - -struct at91_smc { - u32 reserved[384]; - struct at91_cs cs[4]; -}; -#endif /* __ASSEMBLY__ */ - -#define AT91_SMC_SETUP_NWE(x) (x & 0x3f) -#define AT91_SMC_SETUP_NCS_WR(x) ((x & 0x3f) << 8) -#define AT91_SMC_SETUP_NRD(x) ((x & 0x3f) << 16) -#define AT91_SMC_SETUP_NCS_RD(x) ((x & 0x3f) << 24) - -#define AT91_SMC_PULSE_NWE(x) (x & 0x3f) -#define AT91_SMC_PULSE_NCS_WR(x) ((x & 0x3f) << 8) -#define AT91_SMC_PULSE_NRD(x) ((x & 0x3f) << 16) -#define AT91_SMC_PULSE_NCS_RD(x) ((x & 0x3f) << 24) - -#define AT91_SMC_CYCLE_NWE(x) (x & 0x1ff) -#define AT91_SMC_CYCLE_NRD(x) ((x & 0x1ff) << 16) - -#define AT91_SMC_TIMINGS_TCLR(x) (x & 0xf) -#define AT91_SMC_TIMINGS_TADL(x) ((x & 0xf) << 4) -#define AT91_SMC_TIMINGS_TAR(x) ((x & 0xf) << 8) -#define AT91_SMC_TIMINGS_OCMS(x) ((x & 0x1) << 12) -#define AT91_SMC_TIMINGS_TRR(x) ((x & 0xf) << 16) -#define AT91_SMC_TIMINGS_TWB(x) ((x & 0xf) << 24) -#define AT91_SMC_TIMINGS_RBNSEL(x) ((x & 0xf) << 28) -#define AT91_SMC_TIMINGS_NFSEL(x) ((x & 0x1) << 31) - -#define AT91_SMC_MODE_RM_NCS 0x00000000 -#define AT91_SMC_MODE_RM_NRD 0x00000001 -#define AT91_SMC_MODE_WM_NCS 0x00000000 -#define AT91_SMC_MODE_WM_NWE 0x00000002 - -#define AT91_SMC_MODE_EXNW_DISABLE 0x00000000 -#define AT91_SMC_MODE_EXNW_FROZEN 0x00000020 -#define AT91_SMC_MODE_EXNW_READY 0x00000030 - -#define AT91_SMC_MODE_BAT 0x00000100 -#define AT91_SMC_MODE_DBW_8 0x00000000 -#define AT91_SMC_MODE_DBW_16 0x00001000 -#define AT91_SMC_MODE_DBW_32 0x00002000 -#define AT91_SMC_MODE_TDF_CYCLE(x) ((x & 0xf) << 16) -#define AT91_SMC_MODE_TDF 0x00100000 -#define AT91_SMC_MODE_PMEN 0x01000000 -#define AT91_SMC_MODE_PS_4 0x00000000 -#define AT91_SMC_MODE_PS_8 0x10000000 -#define AT91_SMC_MODE_PS_16 0x20000000 -#define AT91_SMC_MODE_PS_32 0x30000000 - -#endif diff --git a/arch/arm/include/asm/arch-at91/sama5d4.h b/arch/arm/include/asm/arch-at91/sama5d4.h deleted file mode 100644 index f30cb5fed1..0000000000 --- a/arch/arm/include/asm/arch-at91/sama5d4.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Chip-specific header file for the SAMA5D4 SoC - * - * Copyright (C) 2014 Atmel - * Bo Shen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __SAMA5D4_H -#define __SAMA5D4_H - -/* - * defines to be used in other places - */ -#define CONFIG_AT91FAMILY /* It's a member of AT91 */ - -/* - * Peripheral identifiers/interrupts. - */ -#define ATMEL_ID_FIQ 0 /* FIQ Interrupt */ -#define ATMEL_ID_SYS 1 /* System Controller */ -#define ATMEL_ID_ARM 2 /* Performance Monitor Unit */ -#define ATMEL_ID_PIT 3 /* Periodic Interval Timer */ -#define ATMEL_ID_WDT 4 /* Watchdog timer */ -#define ATMEL_ID_PIOD 5 /* Parallel I/O Controller D */ -#define ATMEL_ID_USART0 6 /* USART 0 */ -#define ATMEL_ID_USART1 7 /* USART 1 */ -#define ATMEL_ID_DMA0 8 /* DMA Controller 0 */ -#define ATMEL_ID_ICM 9 /* Integrity Check Monitor */ -#define ATMEL_ID_PKCC 10 /* Public Key Crypto Controller */ -#define ATMEL_ID_AES 12 /* Advanced Encryption Standard */ -#define ATMEL_ID_AESB 13 /* AES Bridge*/ -#define ATMEL_ID_TDES 14 /* Triple Data Encryption Standard */ -#define ATMEL_ID_SHA 15 /* SHA Signature */ -#define ATMEL_ID_MPDDRC 16 /* MPDDR controller */ -#define ATMEL_ID_MATRIX1 17 /* H32MX, 32-bit AHB Matrix */ -#define ATMEL_ID_MATRIX0 18 /* H64MX, 64-bit AHB Matrix */ -#define ATMEL_ID_VDEC 19 /* Video Decoder */ -#define ATMEL_ID_SBM 20 /* Secure Box Module */ -#define ATMEL_ID_SMC 22 /* Multi-bit ECC interrupt */ -#define ATMEL_ID_PIOA 23 /* Parallel I/O Controller A */ -#define ATMEL_ID_PIOB 24 /* Parallel I/O Controller B */ -#define ATMEL_ID_PIOC 25 /* Parallel I/O Controller C */ -#define ATMEL_ID_PIOE 26 /* Parallel I/O Controller E */ -#define ATMEL_ID_UART0 27 /* UART 0 */ -#define ATMEL_ID_UART1 28 /* UART 1 */ -#define ATMEL_ID_USART2 29 /* USART 2 */ -#define ATMEL_ID_USART3 30 /* USART 3 */ -#define ATMEL_ID_USART4 31 /* USART 4 */ -#define ATMEL_ID_TWI0 32 /* Two-Wire Interface 0 */ -#define ATMEL_ID_TWI1 33 /* Two-Wire Interface 1 */ -#define ATMEL_ID_TWI2 34 /* Two-Wire Interface 2 */ -#define ATMEL_ID_MCI0 35 /* High Speed Multimedia Card Interface 0 */ -#define ATMEL_ID_MCI1 36 /* High Speed Multimedia Card Interface 1 */ -#define ATMEL_ID_SPI0 37 /* Serial Peripheral Interface 0 */ -#define ATMEL_ID_SPI1 38 /* Serial Peripheral Interface 1 */ -#define ATMEL_ID_SPI2 39 /* Serial Peripheral Interface 2 */ -#define ATMEL_ID_TC0 40 /* Timer Counter 0 (ch. 0, 1, 2) */ -#define ATMEL_ID_TC1 41 /* Timer Counter 1 (ch. 3, 4, 5) */ -#define ATMEL_ID_TC2 42 /* Timer Counter 2 (ch. 6, 7, 8) */ -#define ATMEL_ID_PWMC 43 /* Pulse Width Modulation Controller */ -#define ATMEL_ID_ADC 44 /* Touch Screen ADC Controller */ -#define ATMEL_ID_DBGU 45 /* Debug Unit Interrupt */ -#define ATMEL_ID_UHPHS 46 /* USB Host High Speed */ -#define ATMEL_ID_UDPHS 47 /* USB Device High Speed */ -#define ATMEL_ID_SSC0 48 /* Synchronous Serial Controller 0 */ -#define ATMEL_ID_SSC1 49 /* Synchronous Serial Controller 1 */ -#define ATMEL_ID_XDMAC1 50 /* DMA Controller 1 */ -#define ATMEL_ID_LCDC 51 /* LCD Controller */ -#define ATMEL_ID_ISI 52 /* Image Sensor Interface */ -#define ATMEL_ID_TRNG 53 /* True Random Number Generator */ -#define ATMEL_ID_GMAC0 54 /* Ethernet MAC 0 */ -#define ATMEL_ID_GMAC1 55 /* Ethernet MAC 1 */ -#define ATMEL_ID_IRQ 56 /* IRQ Interrupt ID */ -#define ATMEL_ID_SFC 57 /* Fuse Controller */ -#define ATMEL_ID_SECURAM 59 /* Secured RAM */ -#define ATMEL_ID_SMD 61 /* SMD Soft Modem */ -#define ATMEL_ID_TWI3 62 /* Two-Wire Interface 3 */ -#define ATMEL_ID_CATB 63 /* Capacitive Touch Controller */ -#define ATMEL_ID_SFR 64 /* Special Funcion Register */ -#define ATMEL_ID_AIC 65 /* Advanced Interrupt Controller */ -#define ATMEL_ID_SAIC 66 /* Secured Advanced Interrupt Controller */ -#define ATMEL_ID_L2CC 67 /* L2 Cache Controller */ - -/* - * User Peripherals physical base addresses. - */ -#define ATMEL_BASE_LCDC 0xf0000000 -#define ATMEL_BASE_DMAC1 0xf0004000 -#define ATMEL_BASE_ISI 0xf0008000 -#define ATMEL_BASE_PKCC 0xf000C000 -#define ATMEL_BASE_MPDDRC 0xf0010000 -#define ATMEL_BASE_DMAC0 0xf0014000 -#define ATMEL_BASE_PMC 0xf0018000 -#define ATMEL_BASE_MATRIX0 0xf001c000 -#define ATMEL_BASE_AESB 0xf0020000 -/* Reserved: 0xf0024000 - 0xf8000000 */ -#define ATMEL_BASE_MCI0 0xf8000000 -#define ATMEL_BASE_UART0 0xf8004000 -#define ATMEL_BASE_SSC0 0xf8008000 -#define ATMEL_BASE_PWMC 0xf800c000 -#define ATMEL_BASE_SPI0 0xf8010000 -#define ATMEL_BASE_TWI0 0xf8014000 -#define ATMEL_BASE_TWI1 0xf8018000 -#define ATMEL_BASE_TC0 0xf801c000 -#define ATMEL_BASE_GMAC0 0xf8020000 -#define ATMEL_BASE_TWI2 0xf8024000 -#define ATMEL_BASE_SFR 0xf8028000 -#define ATMEL_BASE_USART0 0xf802c000 -#define ATMEL_BASE_USART1 0xf8030000 -/* Reserved: 0xf8034000 - 0xfc000000 */ -#define ATMEL_BASE_MCI1 0xfc000000 -#define ATMEL_BASE_UART1 0xfc004000 -#define ATMEL_BASE_USART2 0xfc008000 -#define ATMEL_BASE_USART3 0xfc00c000 -#define ATMEL_BASE_USART4 0xfc010000 -#define ATMEL_BASE_SSC1 0xfc014000 -#define ATMEL_BASE_SPI1 0xfc018000 -#define ATMEL_BASE_SPI2 0xfc01c000 -#define ATMEL_BASE_TC1 0xfc020000 -#define ATMEL_BASE_TC2 0xfc024000 -#define ATMEL_BASE_GMAC1 0xfc028000 -#define ATMEL_BASE_UDPHS 0xfc02c000 -#define ATMEL_BASE_TRNG 0xfc030000 -#define ATMEL_BASE_ADC 0xfc034000 -#define ATMEL_BASE_TWI3 0xfc038000 - -#define ATMEL_BASE_MATRIX1 0xfc054000 - -#define ATMEL_BASE_SMC 0xfc05c000 -#define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) -#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) - -#define ATMEL_BASE_PIOD 0xfc068000 -#define ATMEL_BASE_RSTC 0xfc068600 -#define ATMEL_BASE_PIT 0xfc068630 -#define ATMEL_BASE_WDT 0xfc068640 - -#define ATMEL_BASE_DBGU 0xfc069000 -#define ATMEL_BASE_PIOA 0xfc06a000 -#define ATMEL_BASE_PIOB 0xfc06b000 -#define ATMEL_BASE_PIOC 0xfc06c000 -#define ATMEL_BASE_PIOE 0xfc06d000 -#define ATMEL_BASE_AIC 0xfc06e000 - -/* - * Internal Memory. - */ -#define ATMEL_BASE_ROM 0x00000000 /* Internal ROM base address */ -#define ATMEL_BASE_NFC 0x00100000 /* NFC SRAM */ -#define ATMEL_BASE_SRAM 0x00200000 /* Internal ROM base address */ -#define ATMEL_BASE_VDEC 0x00300000 /* Video Decoder Controller */ -#define ATMEL_BASE_UDPHS_FIFO 0x00400000 /* USB Device HS controller */ -#define ATMEL_BASE_OHCI 0x00500000 /* USB Host controller (OHCI) */ -#define ATMEL_BASE_EHCI 0x00600000 /* USB Host controller (EHCI) */ -#define ATMEL_BASE_AXI 0x00700000 -#define ATMEL_BASE_DAP 0x00800000 -#define ATMEL_BASE_SMD 0x00900000 - -/* - * External memory - */ -#define ATMEL_BASE_CS0 0x10000000 -#define ATMEL_BASE_DDRCS 0x20000000 -#define ATMEL_BASE_CS1 0x60000000 -#define ATMEL_BASE_CS2 0x70000000 -#define ATMEL_BASE_CS3 0x80000000 - -/* - * Other misc defines - */ -#define ATMEL_PIO_PORTS 5 -#define CPU_HAS_PIO3 -#define PIO_SCDR_DIV 0x3fff -#define CPU_HAS_PCR -#define CPU_HAS_H32MXDIV - -/* sama5d4 series chip id definitions */ -#define ARCH_ID_SAMA5D4 0x8a5c07c0 -#define ARCH_EXID_SAMA5D41 0x00000001 -#define ARCH_EXID_SAMA5D42 0x00000002 -#define ARCH_EXID_SAMA5D43 0x00000003 -#define ARCH_EXID_SAMA5D44 0x00000004 - -#define cpu_is_sama5d4() (get_chip_id() == ARCH_ID_SAMA5D4) -#define cpu_is_sama5d41() (cpu_is_sama5d4() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D41)) -#define cpu_is_sama5d42() (cpu_is_sama5d4() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D42)) -#define cpu_is_sama5d43() (cpu_is_sama5d4() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D43)) -#define cpu_is_sama5d44() (cpu_is_sama5d4() && \ - (get_extension_chip_id() == ARCH_EXID_SAMA5D44)) - -/* - * No PMECC Galois table in ROM - */ -#define NO_GALOIS_TABLE_IN_ROM - -#ifndef __ASSEMBLY__ -unsigned int get_chip_id(void); -unsigned int get_extension_chip_id(void); -unsigned int has_lcdc(void); -char *get_cpu_name(void); -#endif - -#endif diff --git a/arch/arm/mach-at91/include/mach/at91_common.h b/arch/arm/mach-at91/include/mach/at91_common.h new file mode 100644 index 0000000000..efcd74ed90 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_common.h @@ -0,0 +1,38 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_COMMON_H +#define AT91_COMMON_H + +void at91_can_hw_init(void); +void at91_gmac_hw_init(void); +void at91_macb_hw_init(void); +void at91_mci_hw_init(void); +void at91_serial0_hw_init(void); +void at91_serial1_hw_init(void); +void at91_serial2_hw_init(void); +void at91_seriald_hw_init(void); +void at91_spi0_hw_init(unsigned long cs_mask); +void at91_spi1_hw_init(unsigned long cs_mask); +void at91_udp_hw_init(void); +void at91_uhp_hw_init(void); +void at91_lcd_hw_init(void); +void at91_plla_init(u32 pllar); +void at91_pllb_init(u32 pllar); +void at91_mck_init(u32 mckr); +void at91_pmc_init(void); +void mem_init(void); +void at91_phy_reset(void); +void at91_sdram_hw_init(void); +void at91_mck_init(u32 mckr); +void at91_spl_board_init(void); +void at91_disable_wdt(void); +void matrix_init(void); +void redirect_int_from_saic_to_aic(void); + +#endif /* AT91_COMMON_H */ diff --git a/arch/arm/mach-at91/include/mach/at91_dbu.h b/arch/arm/mach-at91/include/mach/at91_dbu.h new file mode 100644 index 0000000000..7346fc0569 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_dbu.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Debug Unit + * Based on AT91SAM9XE datasheet + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_DBU_H +#define AT91_DBU_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_dbu { + u32 cr; /* Control Register WO */ + u32 mr; /* Mode Register RW */ + u32 ier; /* Interrupt Enable Register WO */ + u32 idr; /* Interrupt Disable Register WO */ + u32 imr; /* Interrupt Mask Register RO */ + u32 sr; /* Status Register RO */ + u32 rhr; /* Receive Holding Register RO */ + u32 thr; /* Transmit Holding Register WO */ + u32 brgr; /* Baud Rate Generator Register RW */ + u32 res1[7];/* 0x0024 - 0x003C Reserved */ + u32 cidr; /* Chip ID Register RO */ + u32 exid; /* Chip ID Extension Register RO */ + u32 fnr; /* Force NTRST Register RW */ +} at91_dbu_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_DBU_CID_ARCH_MASK 0x0ff00000 +#define AT91_DBU_CID_ARCH_9xx 0x01900000 +#define AT91_DBU_CID_ARCH_9XExx 0x02900000 + +#define AT91_DBU_CIDR_MASK 0x1f +#define AT91_DBU_CIDR 0x40 +#define AT91_DBU_EXID 0x44 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_eefc.h b/arch/arm/mach-at91/include/mach/at91_eefc.h new file mode 100644 index 0000000000..7ffbaee27d --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_eefc.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Enhanced Embedded Flash Controller + * Based on AT91SAM9XE datasheet + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_EEFC_H +#define AT91_EEFC_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_eefc { + u32 fmr; /* Flash Mode Register RW */ + u32 fcr; /* Flash Command Register WO */ + u32 fsr; /* Flash Status Register RO */ + u32 frr; /* Flash Result Register RO */ +} at91_eefc_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_EEFC_FMR_FWS_MASK 0x00000f00 +#define AT91_EEFC_FMR_FRDY_BIT 0x00000001 + +#define AT91_EEFC_FCR_KEY 0x5a000000 +#define AT91_EEFC_FCR_FARG_MASK 0x00ffff00 +#define AT91_EEFC_FCR_FARG_SHIFT 8 +#define AT91_EEFC_FCR_FCMD_GETD 0x0 +#define AT91_EEFC_FCR_FCMD_WP 0x1 +#define AT91_EEFC_FCR_FCMD_WPL 0x2 +#define AT91_EEFC_FCR_FCMD_EWP 0x3 +#define AT91_EEFC_FCR_FCMD_EWPL 0x4 +#define AT91_EEFC_FCR_FCMD_EA 0x5 +#define AT91_EEFC_FCR_FCMD_SLB 0x8 +#define AT91_EEFC_FCR_FCMD_CLB 0x9 +#define AT91_EEFC_FCR_FCMD_GLB 0xA +#define AT91_EEFC_FCR_FCMD_SGPB 0xB +#define AT91_EEFC_FCR_FCMD_CGPB 0xC +#define AT91_EEFC_FCR_FCMD_GGPB 0xD + +#define AT91_EEFC_FSR_FRDY 1 +#define AT91_EEFC_FSR_FCMDE 2 +#define AT91_EEFC_FSR_FLOCKE 4 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_emac.h b/arch/arm/mach-at91/include/mach/at91_emac.h new file mode 100644 index 0000000000..a0d74ab660 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_emac.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * based on AT91RM9200 datasheet revision I (36. Ethernet MAC (EMAC)) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_H +#define AT91_H + +typedef struct at91_emac { + u32 ctl; + u32 cfg; + u32 sr; + u32 tar; + u32 tcr; + u32 tsr; + u32 rbqp; + u32 reserved0; + u32 rsr; + u32 isr; + u32 ier; + u32 idr; + u32 imr; + u32 man; + u32 reserved1[2]; + u32 fra; + u32 scol; + u32 mocl; + u32 ok; + u32 seqe; + u32 ale; + u32 dte; + u32 lcol; + u32 ecol; + u32 cse; + u32 tue; + u32 cde; + u32 elr; + u32 rjb; + u32 usf; + u32 sqee; + u32 drfc; + u32 reserved2[3]; + u32 hsh; + u32 hsl; + u32 sa1l; + u32 sa1h; + u32 sa2l; + u32 sa2h; + u32 sa3l; + u32 sa3h; + u32 sa4l; + u32 sa4h; +} at91_emac_t; + +#define AT91_EMAC_CTL_LB 0x0001 +#define AT91_EMAC_CTL_LBL 0x0002 +#define AT91_EMAC_CTL_RE 0x0004 +#define AT91_EMAC_CTL_TE 0x0008 +#define AT91_EMAC_CTL_MPE 0x0010 +#define AT91_EMAC_CTL_CSR 0x0020 +#define AT91_EMAC_CTL_ISR 0x0040 +#define AT91_EMAC_CTL_WES 0x0080 +#define AT91_EMAC_CTL_BP 0x1000 + +#define AT91_EMAC_CFG_SPD 0x0001 +#define AT91_EMAC_CFG_FD 0x0002 +#define AT91_EMAC_CFG_BR 0x0004 +#define AT91_EMAC_CFG_CAF 0x0010 +#define AT91_EMAC_CFG_NBC 0x0020 +#define AT91_EMAC_CFG_MTI 0x0040 +#define AT91_EMAC_CFG_UNI 0x0080 +#define AT91_EMAC_CFG_BIG 0x0100 +#define AT91_EMAC_CFG_EAE 0x0200 +#define AT91_EMAC_CFG_CLK_MASK 0xFFFFF3FF +#define AT91_EMAC_CFG_MCLK_8 0x0000 +#define AT91_EMAC_CFG_MCLK_16 0x0400 +#define AT91_EMAC_CFG_MCLK_32 0x0800 +#define AT91_EMAC_CFG_MCLK_64 0x0C00 +#define AT91_EMAC_CFG_RTY 0x1000 +#define AT91_EMAC_CFG_RMII 0x2000 + +#define AT91_EMAC_SR_LINK 0x0001 +#define AT91_EMAC_SR_MDIO 0x0002 +#define AT91_EMAC_SR_IDLE 0x0004 + +#define AT91_EMAC_TCR_LEN(x) (x & 0x7FF) +#define AT91_EMAC_TCR_NCRC 0x8000 + +#define AT91_EMAC_TSR_OVR 0x0001 +#define AT91_EMAC_TSR_COL 0x0002 +#define AT91_EMAC_TSR_RLE 0x0004 +#define AT91_EMAC_TSR_TXIDLE 0x0008 +#define AT91_EMAC_TSR_BNQ 0x0010 +#define AT91_EMAC_TSR_COMP 0x0020 +#define AT91_EMAC_TSR_UND 0x0040 + +#define AT91_EMAC_RSR_BNA 0x0001 +#define AT91_EMAC_RSR_REC 0x0002 +#define AT91_EMAC_RSR_OVR 0x0004 + +/* ISR, IER, IDR, IMR use the same bits */ +#define AT91_EMAC_IxR_DONE 0x0001 +#define AT91_EMAC_IxR_RCOM 0x0002 +#define AT91_EMAC_IxR_RBNA 0x0004 +#define AT91_EMAC_IxR_TOVR 0x0008 +#define AT91_EMAC_IxR_TUND 0x0010 +#define AT91_EMAC_IxR_RTRY 0x0020 +#define AT91_EMAC_IxR_TBRE 0x0040 +#define AT91_EMAC_IxR_TCOM 0x0080 +#define AT91_EMAC_IxR_TIDLE 0x0100 +#define AT91_EMAC_IxR_LINK 0x0200 +#define AT91_EMAC_IxR_ROVR 0x0400 +#define AT91_EMAC_IxR_HRESP 0x0800 + +#define AT91_EMAC_MAN_DATA_MASK 0xFFFF +#define AT91_EMAC_MAN_CODE_802_3 0x00020000 +#define AT91_EMAC_MAN_REGA(reg) ((reg & 0x1F) << 18) +#define AT91_EMAC_MAN_PHYA(phy) ((phy & 0x1F) << 23) +#define AT91_EMAC_MAN_RW_R 0x20000000 +#define AT91_EMAC_MAN_RW_W 0x10000000 +#define AT91_EMAC_MAN_HIGH 0x40000000 +#define AT91_EMAC_MAN_LOW 0x80000000 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_gpbr.h b/arch/arm/mach-at91/include/mach/at91_gpbr.h new file mode 100644 index 0000000000..e781481e88 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_gpbr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * General Purpose Backup Registers + * Based on AT91SAM9XE datasheet + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_GPBR_H +#define AT91_GPBR_H + +/* + * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile + * 32 Bit registers (buffered by the Vbu power). + * + * Please consider carefully before using this resource for tasks + * that do not really need nonvolatile registers. Maybe you can + * store information in EEPROM or FLASH instead. + * + * However, if you use a GPBR please document its use here and + * reference the define in your code! + * + * known typical uses of the GPBRs: + * GPBR[0]: offset for RTT timekeeping (u-boot, kernel) + * GPBR[1]: unused + * GPBR[2]: unused + * GPBR[3]: bootcount (u-boot) + */ +#define AT91_GPBR_INDEX_TIMEOFF 0 +#define AT91_GPBR_INDEX_BOOTCOUNT 3 + +#ifndef __ASSEMBLY__ + +typedef struct at91_gpbr { + u32 reg[4]; +} at91_gpbr_t; + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_matrix.h b/arch/arm/mach-at91/include/mach/at91_matrix.h new file mode 100644 index 0000000000..2379dd40f8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_matrix.h @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_MATRIX_H +#define AT91_MATRIX_H + +#ifdef __ASSEMBLY__ + +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) +#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x11C) +#elif defined(CONFIG_AT91SAM9261) +#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x30) +#elif defined(CONFIG_AT91SAM9263) +#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x120) +#elif defined(CONFIG_AT91SAM9G45) +#define AT91_ASM_MATRIX_CSA0 (ATMEL_BASE_MATRIX + 0x128) +#else +#error AT91_ASM_MATRIX_CSA0 is not definied for current CPU +#endif + +#define AT91_ASM_MATRIX_MCFG ATMEL_BASE_MATRIX + +#else +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) +#define AT91_MATRIX_MASTERS 6 +#define AT91_MATRIX_SLAVES 5 +#elif defined(CONFIG_AT91SAM9261) +#define AT91_MATRIX_MASTERS 1 +#define AT91_MATRIX_SLAVES 5 +#elif defined(CONFIG_AT91SAM9263) +#define AT91_MATRIX_MASTERS 9 +#define AT91_MATRIX_SLAVES 7 +#elif defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_MASTERS 11 +#define AT91_MATRIX_SLAVES 8 +#else +#error CPU not supported. Please update at91_matrix.h +#endif + +typedef struct at91_priority { + u32 a; + u32 b; +} at91_priority_t; + +typedef struct at91_matrix { + u32 mcfg[AT91_MATRIX_MASTERS]; +#if defined(CONFIG_AT91SAM9261) + u32 scfg[AT91_MATRIX_SLAVES]; + u32 res61_1[3]; + u32 tcr; + u32 res61_2[2]; + u32 csa; + u32 pucr; + u32 res61_3[114]; +#else + u32 reserve1[16 - AT91_MATRIX_MASTERS]; + u32 scfg[AT91_MATRIX_SLAVES]; + u32 reserve2[16 - AT91_MATRIX_SLAVES]; + at91_priority_t pr[AT91_MATRIX_SLAVES]; + u32 reserve3[32 - (2 * AT91_MATRIX_SLAVES)]; + u32 mrcr; /* 0x100 Master Remap Control */ + u32 reserve4[3]; +#if defined(CONFIG_AT91SAM9G45) + u32 ccr[52]; /* 0x110 - 0x1E0 Chip Configuration */ + u32 womr; /* 0x1E4 Write Protect Mode */ + u32 wpsr; /* 0x1E8 Write Protect Status */ + u32 resg45_1[10]; +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) + u32 res60_1[3]; + u32 csa; + u32 res60_2[56]; +#elif defined(CONFIG_AT91SAM9263) + u32 res63_1; + u32 tcmr; + u32 res63_2[2]; + u32 csa[2]; + u32 res63_3[54]; +#else + u32 reserve5[60]; +#endif +#endif +} at91_matrix_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_CSA_DBPUC 0x00000100 +#define AT91_MATRIX_CSA_VDDIOMSEL_1_8V 0x00000000 +#define AT91_MATRIX_CSA_VDDIOMSEL_3_3V 0x00010000 + +#define AT91_MATRIX_CSA_EBI_CS1A 0x00000002 +#define AT91_MATRIX_CSA_EBI_CS3A 0x00000008 +#define AT91_MATRIX_CSA_EBI_CS4A 0x00000010 +#define AT91_MATRIX_CSA_EBI_CS5A 0x00000020 + +#define AT91_MATRIX_CSA_EBI1_CS2A 0x00000008 + +#if defined CONFIG_AT91SAM9261 +/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_MCFG_RCB0 (1 << 0) +/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_MCFG_RCB1 (1 << 1) +#endif + +/* Undefined Length Burst Type */ +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) || \ + defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_MCFG_ULBT_INFINITE 0x00000000 +#define AT91_MATRIX_MCFG_ULBT_SINGLE 0x00000001 +#define AT91_MATRIX_MCFG_ULBT_FOUR 0x00000002 +#define AT91_MATRIX_MCFG_ULBT_EIGHT 0x00000003 +#define AT91_MATRIX_MCFG_ULBT_SIXTEEN 0x00000004 +#endif +#if defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_MCFG_ULBT_THIRTYTWO 0x00000005 +#define AT91_MATRIX_MCFG_ULBT_SIXTYFOUR 0x00000006 +#define AT91_MATRIX_MCFG_ULBT_128 0x00000007 +#endif + +/* Default Master Type */ +#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_NONE 0x00000000 +#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_LAST 0x00010000 +#define AT91_MATRIX_SCFG_DEFMSTR_TYPE_FIXED 0x00020000 + +/* Fixed Index of Default Master */ +#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9263) +#define AT91_MATRIX_SCFG_FIXED_DEFMSTR(x) ((x & 0xf) << 18) +#elif defined(CONFIG_AT91SAM9261) || defined(CONFIG_AT91SAM9260) +#define AT91_MATRIX_SCFG_FIXED_DEFMSTR(x) ((x & 7) << 18) +#endif + +/* Maximum Number of Allowed Cycles for a Burst */ +#if defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_SCFG_SLOT_CYCLE(x) ((x & 0x1ff) << 0) +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ + defined(CONFIG_AT91SAM9263) +#define AT91_MATRIX_SCFG_SLOT_CYCLE(x) ((x & 0xff) << 0) +#endif + +/* Arbitration Type */ +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) +#define AT91_MATRIX_SCFG_ARBT_ROUND_ROBIN 0x00000000 +#define AT91_MATRIX_SCFG_ARBT_FIXED_PRIORITY 0x01000000 +#endif + +/* Master Remap Control Register */ +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9263) || \ + defined(CONFIG_AT91SAM9G45) +/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ +#define AT91_MATRIX_MRCR_RCB0 (1 << 0) +/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ +#define AT91_MATRIX_MRCR_RCB1 (1 << 1) +#endif +#if defined(CONFIG_AT91SAM9263) || defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_MRCR_RCB2 0x00000004 +#define AT91_MATRIX_MRCR_RCB3 0x00000008 +#define AT91_MATRIX_MRCR_RCB4 0x00000010 +#define AT91_MATRIX_MRCR_RCB5 0x00000020 +#define AT91_MATRIX_MRCR_RCB6 0x00000040 +#define AT91_MATRIX_MRCR_RCB7 0x00000080 +#define AT91_MATRIX_MRCR_RCB8 0x00000100 +#endif +#if defined(CONFIG_AT91SAM9G45) +#define AT91_MATRIX_MRCR_RCB9 0x00000200 +#define AT91_MATRIX_MRCR_RCB10 0x00000400 +#define AT91_MATRIX_MRCR_RCB11 0x00000800 +#endif + +/* TCM Configuration Register */ +#if defined(CONFIG_AT91SAM9G45) +/* Size of ITCM enabled memory block */ +#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 +#define AT91_MATRIX_TCMR_ITCM_32 0x00000040 +/* Size of DTCM enabled memory block */ +#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 +#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 +#define AT91_MATRIX_TCMR_DTCM_64 0x00000070 +/* Wait state TCM register */ +#define AT91_MATRIX_TCMR_TCM_NO_WS 0x00000000 +#define AT91_MATRIX_TCMR_TCM_ONE_WS 0x00000800 +#endif +#if defined(CONFIG_AT91SAM9263) +/* Size of ITCM enabled memory block */ +#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 +#define AT91_MATRIX_TCMR_ITCM_16 0x00000005 +#define AT91_MATRIX_TCMR_ITCM_32 0x00000006 +/* Size of DTCM enabled memory block */ +#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 +#define AT91_MATRIX_TCMR_DTCM_16 0x00000050 +#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 +#endif +#if defined(CONFIG_AT91SAM9261) +/* Size of ITCM enabled memory block */ +#define AT91_MATRIX_TCMR_ITCM_0 0x00000000 +#define AT91_MATRIX_TCMR_ITCM_16 0x00000005 +#define AT91_MATRIX_TCMR_ITCM_32 0x00000006 +#define AT91_MATRIX_TCMR_ITCM_64 0x00000007 +/* Size of DTCM enabled memory block */ +#define AT91_MATRIX_TCMR_DTCM_0 0x00000000 +#define AT91_MATRIX_TCMR_DTCM_16 0x00000050 +#define AT91_MATRIX_TCMR_DTCM_32 0x00000060 +#define AT91_MATRIX_TCMR_DTCM_64 0x00000070 +#endif + +#if defined(CONFIG_AT91SAM9G45) +/* Video Mode Configuration Register */ +#define AT91C_MATRIX_VDEC_SEL_OFF 0x00000000 +#define AT91C_MATRIX_VDEC_SEL_ON 0x00000001 +/* Write Protect Mode Register */ +#define AT91_MATRIX_WPMR_WP_WPDIS 0x00000000 +#define AT91_MATRIX_WPMR_WP_WPEN 0x00000001 +#define AT91_MATRIX_WPMR_WPKEY 0xFFFFFF00 /* Write Protect KEY */ +/* Write Protect Status Register */ +#define AT91_MATRIX_WPSR_NO_WPV 0x00000000 +#define AT91_MATRIX_WPSR_WPV 0x00000001 +#define AT91_MATRIX_WPSR_WPVSRC 0x00FFFF00 /* Write Protect Violation Source */ +#endif + +/* USB Pad Pull-Up Control Register */ +#if defined(CONFIG_AT91SAM9261) +#define AT91_MATRIX_USBPUCR_PUON 0x40000000 +#endif + +#define AT91_MATRIX_PRA_M0(x) ((x & 3) << 0) /* Master 0 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M1(x) ((x & 3) << 4) /* Master 1 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M2(x) ((x & 3) << 8) /* Master 2 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M3(x) ((x & 3) << 12) /* Master 3 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M4(x) ((x & 3) << 16) /* Master 4 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M5(x) ((x & 3) << 20) /* Master 5 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M6(x) ((x & 3) << 24) /* Master 6 Priority Reg. A*/ +#define AT91_MATRIX_PRA_M7(x) ((x & 3) << 28) /* Master 7 Priority Reg. A*/ +#define AT91_MATRIX_PRB_M8(x) ((x & 3) << 0) /* Master 8 Priority Reg. B) */ +#define AT91_MATRIX_PRB_M9(x) ((x & 3) << 4) /* Master 9 Priority Reg. B) */ +#define AT91_MATRIX_PRB_M10(x) ((x & 3) << 8) /* Master 10 Priority Reg. B) */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_mc.h b/arch/arm/mach-at91/include/mach/at91_mc.h new file mode 100644 index 0000000000..2ace77931d --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_mc.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_MC_H +#define AT91_MC_H + +#define AT91_ASM_MC_EBI_CSA (ATMEL_BASE_MC + 0x60) +#define AT91_ASM_MC_EBI_CFG (ATMEL_BASE_MC + 0x64) +#define AT91_ASM_MC_SMC_CSR0 (ATMEL_BASE_MC + 0x70) +#define AT91_ASM_MC_SDRAMC_MR (ATMEL_BASE_MC + 0x90) +#define AT91_ASM_MC_SDRAMC_TR (ATMEL_BASE_MC + 0x94) +#define AT91_ASM_MC_SDRAMC_CR (ATMEL_BASE_MC + 0x98) + +#ifndef __ASSEMBLY__ + +typedef struct at91_ebi { + u32 csa; /* 0x00 Chip Select Assignment Register */ + u32 cfgr; /* 0x04 Configuration Register */ + u32 reserved[2]; +} at91_ebi_t; + +#define AT91_EBI_CSA_CS0A 0x0001 +#define AT91_EBI_CSA_CS1A 0x0002 + +#define AT91_EBI_CSA_CS3A 0x0008 +#define AT91_EBI_CSA_CS4A 0x0010 + +typedef struct at91_sdramc { + u32 mr; /* 0x00 SDRAMC Mode Register */ + u32 tr; /* 0x04 SDRAMC Refresh Timer Register */ + u32 cr; /* 0x08 SDRAMC Configuration Register */ + u32 ssr; /* 0x0C SDRAMC Self Refresh Register */ + u32 lpr; /* 0x10 SDRAMC Low Power Register */ + u32 ier; /* 0x14 SDRAMC Interrupt Enable Register */ + u32 idr; /* 0x18 SDRAMC Interrupt Disable Register */ + u32 imr; /* 0x1C SDRAMC Interrupt Mask Register */ + u32 icr; /* 0x20 SDRAMC Interrupt Status Register */ + u32 reserved[3]; +} at91_sdramc_t; + +typedef struct at91_smc { + u32 csr[8]; /* 0x00 SDRAMC Mode Register */ +} at91_smc_t; + +#define AT91_SMC_CSR_RWHOLD(x) ((x & 0x7) << 28) +#define AT91_SMC_CSR_RWSETUP(x) ((x & 0x7) << 24) +#define AT91_SMC_CSR_ACSS_STANDARD 0x00000000 +#define AT91_SMC_CSR_ACSS_1CYCLE 0x00010000 +#define AT91_SMC_CSR_ACSS_2CYCLE 0x00020000 +#define AT91_SMC_CSR_ACSS_3CYCLE 0x00030000 +#define AT91_SMC_CSR_DRP 0x00008000 +#define AT91_SMC_CSR_DBW_8 0x00004000 +#define AT91_SMC_CSR_DBW_16 0x00002000 +#define AT91_SMC_CSR_BAT_8 0x00000000 +#define AT91_SMC_CSR_BAT_16 0x00001000 +#define AT91_SMC_CSR_TDF(x) ((x & 0xF) << 8) +#define AT91_SMC_CSR_WSEN 0x00000080 +#define AT91_SMC_CSR_NWS(x) (x & 0x7F) + +typedef struct at91_bfc { + u32 mr; /* 0x00 SDRAMC Mode Register */ +} at91_bfc_t; + +typedef struct at91_mc { + u32 rcr; /* 0x00 MC Remap Control Register */ + u32 asr; /* 0x04 MC Abort Status Register */ + u32 aasr; /* 0x08 MC Abort Address Status Reg */ + u32 mpr; /* 0x0C MC Master Priority Register */ + u32 reserved1[20]; /* 0x10-0x5C */ + at91_ebi_t ebi; /* 0x60 - 0x6C EBI */ + at91_smc_t smc; /* 0x70 - 0x8C SMC User Interface */ + at91_sdramc_t sdramc; /* 0x90 - 0xBC SDRAMC User Interface */ + at91_bfc_t bfc; /* 0xC0 BFC User Interface */ + u32 reserved2[15]; +} at91_mc_t; + +#endif +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pdc.h b/arch/arm/mach-at91/include/mach/at91_pdc.h new file mode 100644 index 0000000000..832ebb51c1 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pdc.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_PDC_H +#define AT91_PDC_H + +typedef struct at91_pdc { + u32 rpr; /* 0x100 Receive Pointer Register */ + u32 rcr; /* 0x104 Receive Counter Register */ + u32 tpr; /* 0x108 Transmit Pointer Register */ + u32 tcr; /* 0x10C Transmit Counter Register */ + u32 pnpr; /* 0x110 Receive Next Pointer Register */ + u32 pncr; /* 0x114 Receive Next Counter Register */ + u32 tnpr; /* 0x118 Transmit Next Pointer Register */ + u32 tncr; /* 0x11C Transmit Next Counter Register */ + u32 ptcr; /* 0x120 Transfer Control Register */ + u32 ptsr; /* 0x124 Transfer Status Register */ +} at91_pdc_t; + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h new file mode 100644 index 0000000000..301227880a --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pio.h @@ -0,0 +1,150 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91_pio.h] + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * Parallel I/O Controller (PIO) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_PIO_H +#define AT91_PIO_H + + +#define AT91_ASM_PIO_RANGE 0x200 +#define AT91_ASM_PIOC_ASR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x70) +#define AT91_ASM_PIOC_BSR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x74) +#define AT91_ASM_PIOC_PDR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x04) +#define AT91_ASM_PIOC_PUDR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTC * AT91_ASM_PIO_RANGE + 0x60) + +#define AT91_ASM_PIOD_PDR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x04) +#define AT91_ASM_PIOD_PUDR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x60) +#define AT91_ASM_PIOD_ASR \ + (ATMEL_BASE_PIO + AT91_PIO_PORTD * AT91_ASM_PIO_RANGE + 0x70) + +#ifndef __ASSEMBLY__ + +typedef struct at91_port { + u32 per; /* 0x00 PIO Enable Register */ + u32 pdr; /* 0x04 PIO Disable Register */ + u32 psr; /* 0x08 PIO Status Register */ + u32 reserved0; + u32 oer; /* 0x10 Output Enable Register */ + u32 odr; /* 0x14 Output Disable Registerr */ + u32 osr; /* 0x18 Output Status Register */ + u32 reserved1; + u32 ifer; /* 0x20 Input Filter Enable Register */ + u32 ifdr; /* 0x24 Input Filter Disable Register */ + u32 ifsr; /* 0x28 Input Filter Status Register */ + u32 reserved2; + u32 sodr; /* 0x30 Set Output Data Register */ + u32 codr; /* 0x34 Clear Output Data Register */ + u32 odsr; /* 0x38 Output Data Status Register */ + u32 pdsr; /* 0x3C Pin Data Status Register */ + u32 ier; /* 0x40 Interrupt Enable Register */ + u32 idr; /* 0x44 Interrupt Disable Register */ + u32 imr; /* 0x48 Interrupt Mask Register */ + u32 isr; /* 0x4C Interrupt Status Register */ + u32 mder; /* 0x50 Multi-driver Enable Register */ + u32 mddr; /* 0x54 Multi-driver Disable Register */ + u32 mdsr; /* 0x58 Multi-driver Status Register */ + u32 reserved3; + u32 pudr; /* 0x60 Pull-up Disable Register */ + u32 puer; /* 0x64 Pull-up Enable Register */ + u32 pusr; /* 0x68 Pad Pull-up Status Register */ + u32 reserved4; +#if defined(CPU_HAS_PIO3) + u32 abcdsr1; /* 0x70 Peripheral ABCD Select Register 1 */ + u32 abcdsr2; /* 0x74 Peripheral ABCD Select Register 2 */ + u32 reserved5[2]; + u32 ifscdr; /* 0x80 Input Filter SCLK Disable Register */ + u32 ifscer; /* 0x84 Input Filter SCLK Enable Register */ + u32 ifscsr; /* 0x88 Input Filter SCLK Status Register */ + u32 scdr; /* 0x8C SCLK Divider Debouncing Register */ + u32 ppddr; /* 0x90 Pad Pull-down Disable Register */ + u32 ppder; /* 0x94 Pad Pull-down Enable Register */ + u32 ppdsr; /* 0x98 Pad Pull-down Status Register */ + u32 reserved6; /* */ +#else + u32 asr; /* 0x70 Select A Register */ + u32 bsr; /* 0x74 Select B Register */ + u32 absr; /* 0x78 AB Select Status Register */ + u32 reserved5[9]; /* */ +#endif + u32 ower; /* 0xA0 Output Write Enable Register */ + u32 owdr; /* 0xA4 Output Write Disable Register */ + u32 owsr; /* OxA8 Output Write Status Register */ +#if defined(CPU_HAS_PIO3) + u32 reserved7; /* */ + u32 aimer; /* 0xB0 Additional INT Modes Enable Register */ + u32 aimdr; /* 0xB4 Additional INT Modes Disable Register */ + u32 aimmr; /* 0xB8 Additional INT Modes Mask Register */ + u32 reserved8; /* */ + u32 esr; /* 0xC0 Edge Select Register */ + u32 lsr; /* 0xC4 Level Select Register */ + u32 elsr; /* 0xC8 Edge/Level Status Register */ + u32 reserved9; /* 0xCC */ + u32 fellsr; /* 0xD0 Falling /Low Level Select Register */ + u32 rehlsr; /* 0xD4 Rising /High Level Select Register */ + u32 frlhsr; /* 0xD8 Fall/Rise - Low/High Status Register */ + u32 reserved10; /* */ + u32 locksr; /* 0xE0 Lock Status */ + u32 wpmr; /* 0xE4 Write Protect Mode Register */ + u32 wpsr; /* 0xE8 Write Protect Status Register */ + u32 reserved11[5]; /* */ + u32 schmitt; /* 0x100 Schmitt Trigger Register */ + u32 reserved12[63]; +#else + u32 reserved6[85]; +#endif +} at91_port_t; + +typedef union at91_pio { + struct { + at91_port_t pioa; + at91_port_t piob; + at91_port_t pioc; + at91_port_t piod; /* not present in all hardware */ + at91_port_t pioe;/* not present in all hardware */ + }; + at91_port_t port[5]; +} at91_pio_t; + +#ifdef CONFIG_AT91_GPIO +int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup); +#if defined(CPU_HAS_PIO3) +int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div); +int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on); +int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin); +#endif +int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup); +int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on); +int at91_set_pio_output(unsigned port, unsigned pin, int value); +int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup); +int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup); +int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on); +int at91_set_pio_value(unsigned port, unsigned pin, int value); +int at91_get_pio_value(unsigned port, unsigned pin); +#endif +#endif + +#define AT91_PIO_PORTA 0x0 +#define AT91_PIO_PORTB 0x1 +#define AT91_PIO_PORTC 0x2 +#define AT91_PIO_PORTD 0x3 +#define AT91_PIO_PORTE 0x4 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h new file mode 100644 index 0000000000..56724f15e7 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pit.h @@ -0,0 +1,28 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91_pit.h] + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Periodic Interval Timer (PIT) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_PIT_H +#define AT91_PIT_H + +typedef struct at91_pit { + u32 mr; /* 0x00 Mode Register */ + u32 sr; /* 0x04 Status Register */ + u32 pivr; /* 0x08 Periodic Interval Value Register */ + u32 piir; /* 0x0C Periodic Interval Image Register */ +} at91_pit_t; + +#define AT91_PIT_MR_IEN 0x02000000 +#define AT91_PIT_MR_EN 0x01000000 +#define AT91_PIT_MR_PIV_MASK(x) (x & 0x000fffff) +#define AT91_PIT_MR_PIV(x) (x & AT91_PIT_MR_PIV_MASK) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h new file mode 100644 index 0000000000..65691aba01 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -0,0 +1,238 @@ +/* + * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_pmc.h] + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * Power Management Controller (PMC) - System peripherals registers. + * Based on AT91RM9200 datasheet revision E. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_PMC_H +#define AT91_PMC_H + +#ifdef __ASSEMBLY__ + +#define AT91_ASM_PMC_MOR (ATMEL_BASE_PMC + 0x20) +#define AT91_ASM_PMC_PLLAR (ATMEL_BASE_PMC + 0x28) +#define AT91_ASM_PMC_PLLBR (ATMEL_BASE_PMC + 0x2c) +#define AT91_ASM_PMC_MCKR (ATMEL_BASE_PMC + 0x30) +#define AT91_ASM_PMC_SR (ATMEL_BASE_PMC + 0x68) + +#else + +#include + +typedef struct at91_pmc { + u32 scer; /* 0x00 System Clock Enable Register */ + u32 scdr; /* 0x04 System Clock Disable Register */ + u32 scsr; /* 0x08 System Clock Status Register */ + u32 reserved0; + u32 pcer; /* 0x10 Peripheral Clock Enable Register */ + u32 pcdr; /* 0x14 Peripheral Clock Disable Register */ + u32 pcsr; /* 0x18 Peripheral Clock Status Register */ + u32 uckr; /* 0x1C UTMI Clock Register */ + u32 mor; /* 0x20 Main Oscilator Register */ + u32 mcfr; /* 0x24 Main Clock Frequency Register */ + u32 pllar; /* 0x28 PLL A Register */ + u32 pllbr; /* 0x2C PLL B Register */ + u32 mckr; /* 0x30 Master Clock Register */ + u32 reserved1; + u32 usb; /* 0x38 USB Clock Register */ + u32 reserved2; + u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */ + u32 reserved3[4]; + u32 ier; /* 0x60 Interrupt Enable Register */ + u32 idr; /* 0x64 Interrupt Disable Register */ + u32 sr; /* 0x68 Status Register */ + u32 imr; /* 0x6C Interrupt Mask Register */ + u32 reserved4[4]; + u32 pllicpr; /* 0x80 Change Pump Current Register (SAM9) */ + u32 reserved5[21]; + u32 wpmr; /* 0xE4 Write Protect Mode Register (CAP0) */ + u32 wpsr; /* 0xE8 Write Protect Status Register (CAP0) */ +#ifdef CPU_HAS_PCR + u32 reserved6[8]; + u32 pcer1; /* 0x100 Periperial Clock Enable Register 1 */ + u32 pcdr1; /* 0x104 Periperial Clock Disable Register 1 */ + u32 pcsr1; /* 0x108 Periperial Clock Status Register 1 */ + u32 pcr; /* 0x10c Periperial Control Register */ + u32 ocr; /* 0x110 Oscillator Calibration Register */ +#else + u32 reserved8[5]; +#endif +} at91_pmc_t; + +#endif /* end not assembly */ + +#define AT91_PMC_MOR_MOSCEN 0x01 +#define AT91_PMC_MOR_OSCBYPASS 0x02 +#define AT91_PMC_MOR_MOSCRCEN 0x08 +#define AT91_PMC_MOR_OSCOUNT(x) ((x & 0xff) << 8) +#define AT91_PMC_MOR_KEY(x) ((x & 0xff) << 16) +#define AT91_PMC_MOR_MOSCSEL (1 << 24) + +#define AT91_PMC_PLLXR_DIV(x) (x & 0xFF) +#define AT91_PMC_PLLXR_PLLCOUNT(x) ((x & 0x3F) << 8) +#define AT91_PMC_PLLXR_OUT(x) ((x & 0x03) << 14) +#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) +#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7F) << 18) +#else +#define AT91_PMC_PLLXR_MUL(x) ((x & 0x7FF) << 16) +#endif +#define AT91_PMC_PLLAR_29 0x20000000 +#define AT91_PMC_PLLBR_USBDIV_1 0x00000000 +#define AT91_PMC_PLLBR_USBDIV_2 0x10000000 +#define AT91_PMC_PLLBR_USBDIV_4 0x20000000 + +#define AT91_PMC_MCFR_MAINRDY 0x00010000 +#define AT91_PMC_MCFR_MAINF_MASK 0x0000FFFF + +#define AT91_PMC_MCKR_CSS_SLOW 0x00000000 +#define AT91_PMC_MCKR_CSS_MAIN 0x00000001 +#define AT91_PMC_MCKR_CSS_PLLA 0x00000002 +#define AT91_PMC_MCKR_CSS_PLLB 0x00000003 +#define AT91_PMC_MCKR_CSS_MASK 0x00000003 + +#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) +#define AT91_PMC_MCKR_PRES_1 0x00000000 +#define AT91_PMC_MCKR_PRES_2 0x00000010 +#define AT91_PMC_MCKR_PRES_4 0x00000020 +#define AT91_PMC_MCKR_PRES_8 0x00000030 +#define AT91_PMC_MCKR_PRES_16 0x00000040 +#define AT91_PMC_MCKR_PRES_32 0x00000050 +#define AT91_PMC_MCKR_PRES_64 0x00000060 +#define AT91_PMC_MCKR_PRES_MASK 0x00000070 +#else +#define AT91_PMC_MCKR_PRES_1 0x00000000 +#define AT91_PMC_MCKR_PRES_2 0x00000004 +#define AT91_PMC_MCKR_PRES_4 0x00000008 +#define AT91_PMC_MCKR_PRES_8 0x0000000C +#define AT91_PMC_MCKR_PRES_16 0x00000010 +#define AT91_PMC_MCKR_PRES_32 0x00000014 +#define AT91_PMC_MCKR_PRES_64 0x00000018 +#define AT91_PMC_MCKR_PRES_MASK 0x0000001C +#endif + +#ifdef CONFIG_AT91RM9200 +#define AT91_PMC_MCKR_MDIV_1 0x00000000 +#define AT91_PMC_MCKR_MDIV_2 0x00000100 +#define AT91_PMC_MCKR_MDIV_3 0x00000200 +#define AT91_PMC_MCKR_MDIV_4 0x00000300 +#define AT91_PMC_MCKR_MDIV_MASK 0x00000300 +#else +#define AT91_PMC_MCKR_MDIV_1 0x00000000 +#define AT91_PMC_MCKR_MDIV_2 0x00000100 +#if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) +#define AT91_PMC_MCKR_MDIV_3 0x00000300 +#endif +#define AT91_PMC_MCKR_MDIV_4 0x00000200 +#define AT91_PMC_MCKR_MDIV_MASK 0x00000300 +#endif + +#define AT91_PMC_MCKR_PLLADIV_MASK 0x00003000 +#define AT91_PMC_MCKR_PLLADIV_1 0x00000000 +#define AT91_PMC_MCKR_PLLADIV_2 0x00001000 + +#define AT91_PMC_MCKR_H32MXDIV 0x01000000 + +#define AT91_PMC_IXR_MOSCS 0x00000001 +#define AT91_PMC_IXR_LOCKA 0x00000002 +#define AT91_PMC_IXR_LOCKB 0x00000004 +#define AT91_PMC_IXR_MCKRDY 0x00000008 +#define AT91_PMC_IXR_LOCKU 0x00000040 +#define AT91_PMC_IXR_PCKRDY0 0x00000100 +#define AT91_PMC_IXR_PCKRDY1 0x00000200 +#define AT91_PMC_IXR_PCKRDY2 0x00000400 +#define AT91_PMC_IXR_PCKRDY3 0x00000800 +#define AT91_PMC_IXR_MOSCSELS 0x00010000 + +#define AT91_PMC_PCR_PID_MASK (0x3f) +#define AT91_PMC_PCR_CMD_WRITE (0x1 << 12) +#define AT91_PMC_PCR_EN (0x1 << 28) + +#define AT91_PMC_PCK (1 << 0) /* Processor Clock */ +#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ +#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ +#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ +#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ +#define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */ +#define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */ +#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */ +#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */ +#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */ +#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */ +#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */ + +#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ +#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ +#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ +#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */ + +#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */ +#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ + +#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ +#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ + +#define AT91_PMC_DIV (0xff << 0) /* Divider */ +#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */ +#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */ +#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */ +#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */ +#define AT91_PMC_USBDIV_1 (0 << 28) +#define AT91_PMC_USBDIV_2 (1 << 28) +#define AT91_PMC_USBDIV_4 (2 << 28) +#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ +#define AT91_PMC_PLLA_WR_ERRATA (1 << 29) /* Bit 29 must always be set to 1 when programming the CKGR_PLLAR register */ + +#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ +#define AT91_PMC_CSS_SLOW (0 << 0) +#define AT91_PMC_CSS_MAIN (1 << 0) +#define AT91_PMC_CSS_PLLA (2 << 0) +#define AT91_PMC_CSS_PLLB (3 << 0) +#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ +#define AT91_PMC_PRES_1 (0 << 2) +#define AT91_PMC_PRES_2 (1 << 2) +#define AT91_PMC_PRES_4 (2 << 2) +#define AT91_PMC_PRES_8 (3 << 2) +#define AT91_PMC_PRES_16 (4 << 2) +#define AT91_PMC_PRES_32 (5 << 2) +#define AT91_PMC_PRES_64 (6 << 2) +#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ +#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ +#define AT91RM9200_PMC_MDIV_2 (1 << 8) +#define AT91RM9200_PMC_MDIV_3 (2 << 8) +#define AT91RM9200_PMC_MDIV_4 (3 << 8) +#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */ +#define AT91SAM9_PMC_MDIV_2 (1 << 8) +#define AT91SAM9_PMC_MDIV_4 (2 << 8) +#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */ +#define AT91SAM9_PMC_MDIV_6 (3 << 8) +#define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */ +#define AT91_PMC_PDIV_1 (0 << 12) +#define AT91_PMC_PDIV_2 (1 << 12) + +#define AT91_PMC_USBS_USB_PLLA (0x0) /* USB Clock Input is PLLA */ +#define AT91_PMC_USBS_USB_UPLL (0x1) /* USB Clock Input is UPLL */ +#define AT91_PMC_USBS_USB_PLLB (0x1) /* USB Clock Input is PLLB, AT91SAM9N12 only */ +#define AT91_PMC_USB_DIV_2 (0x1 << 8) /* USB Clock divided by 2 */ +#define AT91_PMC_USBDIV_8 (0x7 << 8) /* USB Clock divided by 8 */ +#define AT91_PMC_USBDIV_10 (0x9 << 8) /* USB Clock divided by 10 */ + +#define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ +#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ +#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ +#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock */ +#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ +#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ +#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ +#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ + +#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_rstc.h b/arch/arm/mach-at91/include/mach/at91_rstc.h new file mode 100644 index 0000000000..e4eb3da03f --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_rstc.h @@ -0,0 +1,50 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91_rstc.h] + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Reset Controller (RSTC) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_RSTC_H +#define AT91_RSTC_H + +/* Reset Controller Status Register */ +#define AT91_ASM_RSTC_SR (ATMEL_BASE_RSTC + 0x04) +#define AT91_ASM_RSTC_MR (ATMEL_BASE_RSTC + 0x08) + +#ifndef __ASSEMBLY__ + +typedef struct at91_rstc { + u32 cr; /* Reset Controller Control Register */ + u32 sr; /* Reset Controller Status Register */ + u32 mr; /* Reset Controller Mode Register */ +} at91_rstc_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_RSTC_KEY 0xA5000000 + +#define AT91_RSTC_CR_PROCRST 0x00000001 +#define AT91_RSTC_CR_PERRST 0x00000004 +#define AT91_RSTC_CR_EXTRST 0x00000008 + +#define AT91_RSTC_MR_URSTEN 0x00000001 +#define AT91_RSTC_MR_URSTIEN 0x00000010 +#define AT91_RSTC_MR_ERSTL(x) ((x & 0xf) << 8) +#define AT91_RSTC_MR_ERSTL_MASK 0x0000FF00 + +#define AT91_RSTC_SR_NRSTL 0x00010000 + +#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ +#define AT91_RSTC_RSTTYP_GENERAL (0 << 8) +#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8) +#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8) +#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8) +#define AT91_RSTC_RSTTYP_USER (4 << 8) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h new file mode 100644 index 0000000000..fe7619a932 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_rtt.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 + * Reinhard Meyer, reinhard.meyer@emk-elektronik.de + * + * Real-time Timer + * Based on AT91SAM9XE datasheet + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_RTT_H +#define AT91_RTT_H + +#ifndef __ASSEMBLY__ + +typedef struct at91_rtt { + u32 mr; /* Mode Register RW 0x00008000 */ + u32 ar; /* Alarm Register RW 0xFFFFFFFF */ + u32 vr; /* Value Register RO 0x00000000 */ + u32 sr; /* Status Register RO 0x00000000 */ +} at91_rtt_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_RTT_MR_RTPRES 0x0000ffff +#define AT91_RTT_MR_ALMIEN 0x00010000 +#define AT91_RTT_RTTINCIEN 0x00020000 +#define AT91_RTT_RTTRST 0x00040000 + +#define AT91_RTT_SR_ALMS 0x00000001 +#define AT91_RTT_SR_RTTINC 0x00000002 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_spi.h b/arch/arm/mach-at91/include/mach/at91_spi.h new file mode 100644 index 0000000000..b18665b62c --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_spi.h @@ -0,0 +1,123 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91_spi.h] + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Serial Peripheral Interface (SPI) registers. + * Based on AT91RM9200 datasheet revision E. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_SPI_H +#define AT91_SPI_H + +#include + +typedef struct at91_spi { + u32 cr; /* 0x00 Control Register */ + u32 mr; /* 0x04 Mode Register */ + u32 rdr; /* 0x08 Receive Data Register */ + u32 tdr; /* 0x0C Transmit Data Register */ + u32 sr; /* 0x10 Status Register */ + u32 ier; /* 0x14 Interrupt Enable Register */ + u32 idr; /* 0x18 Interrupt Disable Register */ + u32 imr; /* 0x1C Interrupt Mask Register */ + u32 reserve1[4]; + u32 csr[4]; /* 0x30 Chip Select Register 0-3 */ + u32 reserve2[48]; + at91_pdc_t pdc; +} at91_spi_t; + +#ifdef CONFIG_ATMEL_LEGACY + +#define AT91_SPI_CR 0x00 /* Control Register */ +#define AT91_SPI_SPIEN (1 << 0) /* SPI Enable */ +#define AT91_SPI_SPIDIS (1 << 1) /* SPI Disable */ +#define AT91_SPI_SWRST (1 << 7) /* SPI Software Reset */ +#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ + +#define AT91_SPI_MR 0x04 /* Mode Register */ +#define AT91_SPI_MSTR (1 << 0) /* Master/Slave Mode */ +#define AT91_SPI_PS (1 << 1) /* Peripheral Select */ +#define AT91_SPI_PS_FIXED (0 << 1) +#define AT91_SPI_PS_VARIABLE (1 << 1) +#define AT91_SPI_PCSDEC (1 << 2) /* Chip Select Decode */ +#define AT91_SPI_DIV32 (1 << 3) /* Clock Selection [AT91RM9200 only] */ +#define AT91_SPI_MODFDIS (1 << 4) /* Mode Fault Detection */ +#define AT91_SPI_LLB (1 << 7) /* Local Loopback Enable */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ +#define AT91_SPI_DLYBCS (0xff << 24) /* Delay Between Chip Selects */ + +#define AT91_SPI_RDR 0x08 /* Receive Data Register */ +#define AT91_SPI_RD (0xffff << 0) /* Receive Data */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ + +#define AT91_SPI_TDR 0x0c /* Transmit Data Register */ +#define AT91_SPI_TD (0xffff << 0) /* Transmit Data */ +#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */ +#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */ + +#define AT91_SPI_SR 0x10 /* Status Register */ +#define AT91_SPI_RDRF (1 << 0) /* Receive Data Register Full */ +#define AT91_SPI_TDRE (1 << 1) /* Transmit Data Register Full */ +#define AT91_SPI_MODF (1 << 2) /* Mode Fault Error */ +#define AT91_SPI_OVRES (1 << 3) /* Overrun Error Status */ +#define AT91_SPI_ENDRX (1 << 4) /* End of RX buffer */ +#define AT91_SPI_ENDTX (1 << 5) /* End of TX buffer */ +#define AT91_SPI_RXBUFF (1 << 6) /* RX Buffer Full */ +#define AT91_SPI_TXBUFE (1 << 7) /* TX Buffer Empty */ +#define AT91_SPI_NSSR (1 << 8) /* NSS Rising [SAM9261 only] */ +#define AT91_SPI_TXEMPTY (1 << 9) /* Transmission Register Empty [SAM9261 only] */ +#define AT91_SPI_SPIENS (1 << 16) /* SPI Enable Status */ + +#define AT91_SPI_IER 0x14 /* Interrupt Enable Register */ +#define AT91_SPI_IDR 0x18 /* Interrupt Disable Register */ +#define AT91_SPI_IMR 0x1c /* Interrupt Mask Register */ + +#define AT91_SPI_CSR(n) (0x30 + ((n) * 4)) /* Chip Select Registers 0-3 */ +#define AT91_SPI_CPOL (1 << 0) /* Clock Polarity */ +#define AT91_SPI_NCPHA (1 << 1) /* Clock Phase */ +#define AT91_SPI_CSAAT (1 << 3) /* Chip Select Active After Transfer [SAM9261 only] */ +#define AT91_SPI_BITS (0xf << 4) /* Bits Per Transfer */ +#define AT91_SPI_BITS_8 (0 << 4) +#define AT91_SPI_BITS_9 (1 << 4) +#define AT91_SPI_BITS_10 (2 << 4) +#define AT91_SPI_BITS_11 (3 << 4) +#define AT91_SPI_BITS_12 (4 << 4) +#define AT91_SPI_BITS_13 (5 << 4) +#define AT91_SPI_BITS_14 (6 << 4) +#define AT91_SPI_BITS_15 (7 << 4) +#define AT91_SPI_BITS_16 (8 << 4) +#define AT91_SPI_SCBR (0xff << 8) /* Serial Clock Baud Rate */ +#define AT91_SPI_DLYBS (0xff << 16) /* Delay before SPCK */ +#define AT91_SPI_DLYBCT (0xff << 24) /* Delay between Consecutive Transfers */ + +#define AT91_SPI_RPR 0x0100 /* Receive Pointer Register */ + +#define AT91_SPI_RCR 0x0104 /* Receive Counter Register */ + +#define AT91_SPI_TPR 0x0108 /* Transmit Pointer Register */ + +#define AT91_SPI_TCR 0x010c /* Transmit Counter Register */ + +#define AT91_SPI_RNPR 0x0110 /* Receive Next Pointer Register */ + +#define AT91_SPI_RNCR 0x0114 /* Receive Next Counter Register */ + +#define AT91_SPI_TNPR 0x0118 /* Transmit Next Pointer Register */ + +#define AT91_SPI_TNCR 0x011c /* Transmit Next Counter Register */ + +#define AT91_SPI_PTCR 0x0120 /* PDC Transfer Control Register */ +#define AT91_SPI_RXTEN (0x1 << 0) /* Receiver Transfer Enable */ +#define AT91_SPI_RXTDIS (0x1 << 1) /* Receiver Transfer Disable */ +#define AT91_SPI_TXTEN (0x1 << 8) /* Transmitter Transfer Enable */ +#define AT91_SPI_TXTDIS (0x1 << 9) /* Transmitter Transfer Disable */ + +#define AT91_SPI_PTSR 0x0124 /* PDC Transfer Status Register */ + +#endif /* CONFIG_ATMEL_LEGACY */ + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h new file mode 100644 index 0000000000..b1ee1472e5 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_st.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_ST_H +#define AT91_ST_H + +typedef struct at91_st { + + u32 cr; + u32 pimr; + u32 wdmr; + u32 rtmr; + u32 sr; + u32 ier; + u32 idr; + u32 imr; + u32 rtar; + u32 crtr; +} at91_st_t ; + +#define AT91_ST_CR_WDRST 1 + +#define AT91_ST_WDMR_WDV(x) (x & 0xFFFF) +#define AT91_ST_WDMR_RSTEN 0x00010000 +#define AT91_ST_WDMR_EXTEN 0x00020000 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_tc.h b/arch/arm/mach-at91/include/mach/at91_tc.h new file mode 100644 index 0000000000..de0e266565 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_tc.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_TC_H +#define AT91_TC_H + +typedef struct at91_tcc { + u32 ccr; /* 0x00 Channel Control Register */ + u32 cmr; /* 0x04 Channel Mode Register */ + u32 reserved1[2]; + u32 cv; /* 0x10 Counter Value */ + u32 ra; /* 0x14 Register A */ + u32 rb; /* 0x18 Register B */ + u32 rc; /* 0x1C Register C */ + u32 sr; /* 0x20 Status Register */ + u32 ier; /* 0x24 Interrupt Enable Register */ + u32 idr; /* 0x28 Interrupt Disable Register */ + u32 imr; /* 0x2C Interrupt Mask Register */ + u32 reserved3[4]; +} at91_tcc_t; + +#define AT91_TC_CCR_CLKEN 0x00000001 +#define AT91_TC_CCR_CLKDIS 0x00000002 +#define AT91_TC_CCR_SWTRG 0x00000004 + +#define AT91_TC_CMR_CPCTRG 0x00004000 + +#define AT91_TC_CMR_TCCLKS_CLOCK1 0x00000000 +#define AT91_TC_CMR_TCCLKS_CLOCK2 0x00000001 +#define AT91_TC_CMR_TCCLKS_CLOCK3 0x00000002 +#define AT91_TC_CMR_TCCLKS_CLOCK4 0x00000003 +#define AT91_TC_CMR_TCCLKS_CLOCK5 0x00000004 +#define AT91_TC_CMR_TCCLKS_XC0 0x00000005 +#define AT91_TC_CMR_TCCLKS_XC1 0x00000006 +#define AT91_TC_CMR_TCCLKS_XC2 0x00000007 + +typedef struct at91_tc { + at91_tcc_t tc[3]; /* 0x00 TC Channel 0-2 */ + u32 bcr; /* 0xC0 TC Block Control Register */ + u32 bmr; /* 0xC4 TC Block Mode Register */ +} at91_tc_t; + +#define AT91_TC_BMR_TC0XC0S_TCLK0 0x00000000 +#define AT91_TC_BMR_TC0XC0S_NONE 0x00000001 +#define AT91_TC_BMR_TC0XC0S_TIOA1 0x00000002 +#define AT91_TC_BMR_TC0XC0S_TIOA2 0x00000003 + +#define AT91_TC_BMR_TC1XC1S_TCLK1 0x00000000 +#define AT91_TC_BMR_TC1XC1S_NONE 0x00000004 +#define AT91_TC_BMR_TC1XC1S_TIOA0 0x00000008 +#define AT91_TC_BMR_TC1XC1S_TIOA2 0x0000000C + +#define AT91_TC_BMR_TC2XC2S_TCLK2 0x00000000 +#define AT91_TC_BMR_TC2XC2S_NONE 0x00000010 +#define AT91_TC_BMR_TC2XC2S_TIOA0 0x00000020 +#define AT91_TC_BMR_TC2XC2S_TIOA1 0x00000030 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h new file mode 100644 index 0000000000..0644bbf3c6 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -0,0 +1,43 @@ +/* + * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_wdt.h] + * + * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Watchdog Timer (WDT) - System peripherals regsters. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91_WDT_H +#define AT91_WDT_H + +#ifdef __ASSEMBLY__ + +#define AT91_ASM_WDT_MR (ATMEL_BASE_WDT + 0x04) + +#else + +typedef struct at91_wdt { + u32 cr; + u32 mr; + u32 sr; +} at91_wdt_t; + +#endif + +#define AT91_WDT_CR_WDRSTT 1 +#define AT91_WDT_CR_KEY 0xa5000000 /* KEY Password */ + +#define AT91_WDT_MR_WDV(x) (x & 0xfff) +#define AT91_WDT_MR_WDFIEN 0x00001000 +#define AT91_WDT_MR_WDRSTEN 0x00002000 +#define AT91_WDT_MR_WDRPROC 0x00004000 +#define AT91_WDT_MR_WDDIS 0x00008000 +#define AT91_WDT_MR_WDD(x) ((x & 0xfff) << 16) +#define AT91_WDT_MR_WDDBGHLT 0x10000000 +#define AT91_WDT_MR_WDIDLEHLT 0x20000000 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h new file mode 100644 index 0000000000..d177bdcae5 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -0,0 +1,136 @@ +/* + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __AT91RM9200_H__ +#define __AT91RM9200_H__ + +#define CONFIG_AT91FAMILY /* it's a member of AT91 family */ +#define CONFIG_ARCH_CPU_INIT /* we need arch_cpu_init() for hw timers */ +#define CONFIG_AT91_GPIO /* and require always gpio features */ + +/* Periperial Identifiers */ + +#define ATMEL_ID_SYS 1 /* System Peripheral */ +#define ATMEL_ID_PIOA 2 /* PIO port A */ +#define ATMEL_ID_PIOB 3 /* PIO port B */ +#define ATMEL_ID_PIOC 4 /* PIO port C */ +#define ATMEL_ID_PIOD 5 /* PIO port D BGA only */ +#define ATMEL_ID_USART0 6 /* USART 0 */ +#define ATMEL_ID_USART1 7 /* USART 1 */ +#define ATMEL_ID_USART2 8 /* USART 2 */ +#define ATMEL_ID_USART3 9 /* USART 3 */ +#define ATMEL_ID_MCI 10 /* Multimedia Card Interface */ +#define ATMEL_ID_UDP 11 /* USB Device Port */ +#define ATMEL_ID_TWI 12 /* Two Wire Interface */ +#define ATMEL_ID_SPI 13 /* Serial Peripheral Interface */ +#define ATMEL_ID_SSC0 14 /* Synch. Serial Controller 0 */ +#define ATMEL_ID_SSC1 15 /* Synch. Serial Controller 1 */ +#define ATMEL_ID_SSC2 16 /* Synch. Serial Controller 2 */ +#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ +#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ +#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ +#define ATMEL_ID_TC3 20 /* Timer Counter 3 */ +#define ATMEL_ID_TC4 21 /* Timer Counter 4 */ +#define ATMEL_ID_TC5 22 /* Timer Counter 5 */ +#define ATMEL_ID_UHP 23 /* OHCI USB Host Port */ +#define ATMEL_ID_EMAC 24 /* Ethernet MAC */ +#define ATMEL_ID_IRQ0 25 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ1 26 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ2 27 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ3 28 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ4 29 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ5 30 /* Advanced Interrupt Controller */ +#define ATMEL_ID_IRQ6 31 /* Advanced Interrupt Controller */ + +#define ATMEL_USB_HOST_BASE 0x00300000 + +#define ATMEL_BASE_TC 0xFFFA0000 +#define ATMEL_BASE_UDP 0xFFFB0000 +#define ATMEL_BASE_MCI 0xFFFB4000 +#define ATMEL_BASE_TWI 0xFFFB8000 +#define ATMEL_BASE_EMAC 0xFFFBC000 +#define ATMEL_BASE_USART 0xFFFC0000 /* 4x 0x4000 Offset */ +#define ATMEL_BASE_USART0 ATMEL_BASE_USART +#define ATMEL_BASE_USART1 (ATMEL_BASE_USART + 0x4000) +#define ATMEL_BASE_USART2 (ATMEL_BASE_USART + 0x8000) +#define ATMEL_BASE_USART3 (ATMEL_BASE_USART + 0xC000) + +#define ATMEL_BASE_SCC 0xFFFD0000 /* 4x 0x4000 Offset */ +#define ATMEL_BASE_SPI 0xFFFE0000 + +#define ATMEL_BASE_AIC 0xFFFFF000 +#define ATMEL_BASE_DBGU 0xFFFFF200 +#define ATMEL_BASE_PIO 0xFFFFF400 /* 4x 0x200 Offset */ +#define ATMEL_BASE_PIOA 0xFFFFF400 +#define ATMEL_BASE_PIOB 0xFFFFF600 +#define ATMEL_BASE_PIOC 0xFFFFF800 +#define ATMEL_BASE_PIOD 0xFFFFFA00 +#define ATMEL_BASE_PMC 0xFFFFFC00 +#define ATMEL_BASE_ST 0xFFFFFD00 +#define ATMEL_BASE_RTC 0xFFFFFE00 +#define ATMEL_BASE_MC 0xFFFFFF00 + +#define AT91_PIO_BASE ATMEL_BASE_PIO + +/* AT91RM9200 Periperial Multiplexing A */ +/* Port A */ +#define ATMEL_PMX_AA_EREFCK 0x00000080 +#define ATMEL_PMX_AA_ETXCK 0x00000080 +#define ATMEL_PMX_AA_ETXEN 0x00000100 +#define ATMEL_PMX_AA_ETX0 0x00000200 +#define ATMEL_PMX_AA_ETX1 0x00000400 +#define ATMEL_PMX_AA_ECRS 0x00000800 +#define ATMEL_PMX_AA_ECRSDV 0x00000800 +#define ATMEL_PMX_AA_ERX0 0x00001000 +#define ATMEL_PMX_AA_ERX1 0x00002000 +#define ATMEL_PMX_AA_ERXER 0x00004000 +#define ATMEL_PMX_AA_EMDC 0x00008000 +#define ATMEL_PMX_AA_EMDIO 0x00010000 + +#define ATMEL_PMX_AA_TXD2 0x00800000 + +#define ATMEL_PMX_AA_TWD 0x02000000 +#define ATMEL_PMX_AA_TWCK 0x04000000 + +/* Port B */ +#define ATMEL_PMX_BA_ERXCK 0x00080000 +#define ATMEL_PMX_BA_ECOL 0x00040000 +#define ATMEL_PMX_BA_ERXDV 0x00020000 +#define ATMEL_PMX_BA_ERX3 0x00010000 +#define ATMEL_PMX_BA_ERX2 0x00008000 +#define ATMEL_PMX_BA_ETXER 0x00004000 +#define ATMEL_PMX_BA_ETX3 0x00002000 +#define ATMEL_PMX_BA_ETX2 0x00001000 + +/* Port B */ + +#define ATMEL_PMX_CA_BFCK 0x00000001 +#define ATMEL_PMX_CA_BFRDY 0x00000002 +#define ATMEL_PMX_CA_SMOE 0x00000002 +#define ATMEL_PMX_CA_BFAVD 0x00000004 +#define ATMEL_PMX_CA_BFBAA 0x00000008 +#define ATMEL_PMX_CA_SMWE 0x00000008 +#define ATMEL_PMX_CA_BFOE 0x00000010 +#define ATMEL_PMX_CA_BFWE 0x00000020 +#define ATMEL_PMX_CA_NWAIT 0x00000040 +#define ATMEL_PMX_CA_A23 0x00000080 +#define ATMEL_PMX_CA_A24 0x00000100 +#define ATMEL_PMX_CA_A25 0x00000200 +#define ATMEL_PMX_CA_CFRNW 0x00000200 +#define ATMEL_PMX_CA_NCS4 0x00000400 +#define ATMEL_PMX_CA_CFCS 0x00000400 +#define ATMEL_PMX_CA_NCS5 0x00000800 +#define ATMEL_PMX_CA_CFCE1 0x00001000 +#define ATMEL_PMX_CA_NCS6 0x00001000 +#define ATMEL_PMX_CA_CFCE2 0x00002000 +#define ATMEL_PMX_CA_NCS7 0x00002000 +#define ATMEL_PMX_CA_D16_31 0xFFFF0000 + +#define ATMEL_PIO_PORTS 4 /* theese SoCs have 4 PIO */ +#define ATMEL_PMC_UHP AT91RM9200_PMC_UHP + +#define CONFIG_SYS_ATMEL_CPU_NAME "AT91RM9200" + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h new file mode 100644 index 0000000000..8950d67409 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -0,0 +1,172 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9260.h] + * + * (C) 2006 Andrew Victor + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de + * + * Definitions for the SoCs: + * AT91SAM9260, AT91SAM9G20, AT91SAM9XE + * + * Note that those SoCs are mostly software and pin compatible, + * therefore this file applies to all of them. Differences between + * those SoCs are concentrated at the end of this file. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9260_H +#define AT91SAM9260_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Peripherals */ +#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ +#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ +#define ATMEL_ID_ADC 5 /* Analog-to-Digital Converter */ +#define ATMEL_ID_USART0 6 /* USART 0 */ +#define ATMEL_ID_USART1 7 /* USART 1 */ +#define ATMEL_ID_USART2 8 /* USART 2 */ +#define ATMEL_ID_MCI 9 /* Multimedia Card Interface */ +#define ATMEL_ID_UDP 10 /* USB Device Port */ +#define ATMEL_ID_TWI0 11 /* Two-Wire Interface 0 */ +#define ATMEL_ID_SPI0 12 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 13 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +/* Reserved: 15 */ +/* Reserved: 16 */ +#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ +#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ +#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ +#define ATMEL_ID_UHP 20 /* USB Host port */ +#define ATMEL_ID_EMAC0 21 /* Ethernet 0 */ +#define ATMEL_ID_ISI 22 /* Image Sensor Interface */ +#define ATMEL_ID_USART3 23 /* USART 3 */ +#define ATMEL_ID_USART4 24 /* USART 4 */ +/* USART5 or TWI1: 25 */ +#define ATMEL_ID_TC3 26 /* Timer Counter 3 */ +#define ATMEL_ID_TC4 27 /* Timer Counter 4 */ +#define ATMEL_ID_TC5 28 /* Timer Counter 5 */ +#define ATMEL_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ +#define ATMEL_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ +#define ATMEL_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_TCB0 0xfffa0000 +#define ATMEL_BASE_TC0 0xfffa0000 +#define ATMEL_BASE_TC1 0xfffa0040 +#define ATMEL_BASE_TC2 0xfffa0080 +#define ATMEL_BASE_UDP0 0xfffa4000 +#define ATMEL_BASE_MCI 0xfffa8000 +#define ATMEL_BASE_TWI0 0xfffac000 +#define ATMEL_BASE_USART0 0xfffb0000 +#define ATMEL_BASE_USART1 0xfffb4000 +#define ATMEL_BASE_USART2 0xfffb8000 +#define ATMEL_BASE_SSC0 0xfffbc000 +#define ATMEL_BASE_ISI0 0xfffc0000 +#define ATMEL_BASE_EMAC0 0xfffc4000 +#define ATMEL_BASE_SPI0 0xfffc8000 +#define ATMEL_BASE_SPI1 0xfffcc000 +#define ATMEL_BASE_USART3 0xfffd0000 +#define ATMEL_BASE_USART4 0xfffd4000 +/* USART5 or TWI1: 0xfffd8000 */ +#define ATMEL_BASE_TCB1 0xfffdc000 +#define ATMEL_BASE_TC3 0xfffdc000 +#define ATMEL_BASE_TC4 0xfffdc040 +#define ATMEL_BASE_TC5 0xfffdc080 +#define ATMEL_BASE_ADC 0xfffe0000 +/* Reserved: 0xfffe4000 - 0xffffe7ff */ + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_SYS 0xffffe800 +#define ATMEL_BASE_SDRAMC 0xffffea00 +#define ATMEL_BASE_SMC 0xffffec00 +#define ATMEL_BASE_MATRIX 0xffffee00 +#define ATMEL_BASE_CCFG 0xffffef14 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_DBGU 0xfffff200 +#define ATMEL_BASE_PIOA 0xfffff400 +#define ATMEL_BASE_PIOB 0xfffff600 +#define ATMEL_BASE_PIOC 0xfffff800 +/* EEFC: 0xfffffa00 */ +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffd00 +#define ATMEL_BASE_SHDWN 0xfffffd10 +#define ATMEL_BASE_RTT 0xfffffd20 +#define ATMEL_BASE_PIT 0xfffffd30 +#define ATMEL_BASE_WDT 0xfffffd40 +/* GPBR(non-XE SoCs): 0xfffffd50 */ +/* GPBR(XE SoCs): 0xfffffd60 */ +/* Reserved: 0xfffffd70 - 0xffffffff */ + +/* + * Internal Memory common on all these SoCs + */ +#define ATMEL_BASE_BOOT 0x00000000 /* Boot mapped area */ +#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ +/* SRAM or FLASH: 0x00200000 */ +/* SRAM: 0x00300000 */ +/* Reserved: 0x00400000 */ +#define ATMEL_UHP_BASE 0x00500000 /* USB Host controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ +#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ +#define ATMEL_BASE_CS4 0x50000000 +#define ATMEL_BASE_CS5 0x60000000 +#define ATMEL_BASE_CS6 0x70000000 +#define ATMEL_BASE_CS7 0x80000000 + +/* + * Other misc defines + */ +#ifndef CONFIG_DM_GPIO +#define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */ +#define ATMEL_BASE_PIO ATMEL_BASE_PIOA +#endif +#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP + +/* + * SoC specific defines + */ +#if defined(CONFIG_AT91SAM9XE) +# define ATMEL_CPU_NAME "AT91SAM9XE" +# define ATMEL_ID_TWI1 25 /* TWI 1 */ +# define ATMEL_BASE_FLASH 0x00200000 /* Internal FLASH */ +# define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM */ +# define ATMEL_BASE_TWI1 0xfffd8000 +# define ATMEL_BASE_EEFC 0xfffffa00 +# define ATMEL_BASE_GPBR 0xfffffd60 +#elif defined(CONFIG_AT91SAM9260) +# define ATMEL_CPU_NAME "AT91SAM9260" +# define ATMEL_ID_USART5 25 /* USART 5 */ +# define ATMEL_BASE_SRAM0 0x00200000 /* Internal SRAM 0 */ +# define ATMEL_BASE_SRAM1 0x00300000 /* Internal SRAM 1 */ +# define ATMEL_BASE_USART5 0xfffd8000 +# define ATMEL_BASE_GPBR 0xfffffd50 +#elif defined(CONFIG_AT91SAM9G20) +# define ATMEL_CPU_NAME "AT91SAM9G20" +# define ATMEL_ID_USART5 25 /* USART 5 */ +# define ATMEL_BASE_SRAM0 0x00200000 /* Internal SRAM 0 */ +# define ATMEL_BASE_SRAM1 0x00300000 /* Internal SRAM 1 */ +# define ATMEL_BASE_USART5 0xfffd8000 +# define ATMEL_BASE_GPBR 0xfffffd50 +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h new file mode 100644 index 0000000000..dc61f48f52 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h @@ -0,0 +1,70 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9260_matrix.h] + * + * Copyright (C) 2007 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9260 datasheet revision B. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9260_MATRIX_H +#define AT91SAM9260_MATRIX_H + +#ifndef __ASSEMBLY__ + +/* + * This struct defines access to the matrix' maximum of + * 16 masters and 16 slaves. + * However, on the AT91SAM9260/9G20/9XE there exist only + * 6 Masters and 5 Slaves! + */ +struct at91_matrix { + u32 mcfg[16]; /* Master Configuration Registers */ + u32 scfg[16]; /* Slave Configuration Registers */ + u32 pras[16][2]; /* Priority Assignment Slave Registers */ + u32 mrcr; /* Master Remap Control Register */ + u32 filler[0x06]; + u32 ebicsa; /* EBI Chip Select Assignment Register */ +}; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) + +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_IOSR_SEL (1 << 17) + +/* Maximum Number of Allowed Cycles for a Burst */ +#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) +#define AT91_MATRIX_SLOT_CYCLE_(x) (x << 0) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h new file mode 100644 index 0000000000..6dfcf4c0c8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -0,0 +1,136 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261.h] + * + * Copyright (C) SAN People + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de + * + * Definitions for the SoCs: + * AT91SAM9261, AT91SAM9G10 + * + * Note that those SoCs are mostly software and pin compatible, + * therefore this file applies to all of them. Differences between + * those SoCs are concentrated at the end of this file. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9261_H +#define AT91SAM9261_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Peripherals */ +#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ +#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ +/* Reserved: 5 */ +#define ATMEL_ID_USART0 6 /* USART 0 */ +#define ATMEL_ID_USART1 7 /* USART 1 */ +#define ATMEL_ID_USART2 8 /* USART 2 */ +#define ATMEL_ID_MCI 9 /* Multimedia Card Interface */ +#define ATMEL_ID_UDP 10 /* USB Device Port */ +#define ATMEL_ID_TWI0 11 /* Two-Wire Interface 0 */ +#define ATMEL_ID_SPI0 12 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 13 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define ATMEL_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define ATMEL_ID_SSC2 16 /* Serial Synchronous Controller 2 */ +#define ATMEL_ID_TC0 17 /* Timer Counter 0 */ +#define ATMEL_ID_TC1 18 /* Timer Counter 1 */ +#define ATMEL_ID_TC2 19 /* Timer Counter 2 */ +#define ATMEL_ID_UHP 20 /* USB Host port */ +#define ATMEL_ID_LCDC 21 /* LDC Controller */ +/* Reserved: 22-28 */ +#define ATMEL_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */ +#define ATMEL_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */ +#define ATMEL_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */ + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_TCB0 0xfffa0000 +#define ATMEL_BASE_TC0 0xfffa0000 +#define ATMEL_BASE_TC1 0xfffa0040 +#define ATMEL_BASE_TC2 0xfffa0080 +#define ATMEL_BASE_UDP0 0xfffa4000 +#define ATMEL_BASE_MCI 0xfffa8000 +#define ATMEL_BASE_TWI0 0xfffac000 +#define ATMEL_BASE_USART0 0xfffb0000 +#define ATMEL_BASE_USART1 0xfffb4000 +#define ATMEL_BASE_USART2 0xfffb8000 +#define ATMEL_BASE_SSC0 0xfffbc000 +#define ATMEL_BASE_SSC1 0xfffc0000 +#define ATMEL_BASE_SSC2 0xfffc4000 +#define ATMEL_BASE_SPI0 0xfffc8000 +#define ATMEL_BASE_SPI1 0xfffcc000 +/* Reserved: 0xfffc4000 - 0xffffe9ff */ + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_SYS 0xffffea00 +#define ATMEL_BASE_SDRAMC 0xffffea00 +#define ATMEL_BASE_SMC 0xffffec00 +#define ATMEL_BASE_MATRIX 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_DBGU 0xfffff200 +#define ATMEL_BASE_PIOA 0xfffff400 +#define ATMEL_BASE_PIOB 0xfffff600 +#define ATMEL_BASE_PIOC 0xfffff800 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffd00 +#define ATMEL_BASE_SHDWN 0xfffffd10 +#define ATMEL_BASE_RTT 0xfffffd20 +#define ATMEL_BASE_PIT 0xfffffd30 +#define ATMEL_BASE_WDT 0xfffffd40 +#define ATMEL_BASE_GPBR 0xfffffd50 + +/* + * Internal Memory common on all these SoCs + */ +#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ +#define ATMEL_SIZE_SRAM 0x00028000 /* Internal SRAM size (160Kb) */ + +#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ +#define ATMEL_SIZE_ROM 0x00008000 /* Internal ROM size (32Kb) */ + +#define ATMEL_BASE_UHP 0x00500000 /* USB Host controller */ +#define ATMEL_BASE_LCDC 0x00600000 /* LDC controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ +#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ +#define ATMEL_BASE_CS4 0x50000000 +#define ATMEL_BASE_CS5 0x60000000 +#define ATMEL_BASE_CS6 0x70000000 +#define ATMEL_BASE_CS7 0x80000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 3 /* theese SoCs have 3 PIO */ +#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP +#define ATMEL_BASE_PIO ATMEL_BASE_PIOA + +/* + * SoC specific defines + */ +#if defined(CONFIG_AT91SAM9261) +# define ATMEL_CPU_NAME "AT91SAM9261" +#elif defined(CONFIG_AT91SAM9G10) +# define ATMEL_CPU_NAME "AT91SAM9G10" +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h new file mode 100644 index 0000000000..fc5f0831b8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h @@ -0,0 +1,56 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9261_matrix.h] + * + * Copyright (C) 2007 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9261_MATRIX_H +#define AT91SAM9261_MATRIX_H + +#ifndef __ASSEMBLY__ + +struct at91_matrix { + u32 mcfg; /* Master Configuration Registers */ + u32 scfg[5]; /* Slave Configuration Registers */ + u32 filler[6]; + u32 ebicsa; /* EBI Chip Select Assignment Register */ +}; +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) + +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h new file mode 100644 index 0000000000..64a3888e22 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -0,0 +1,147 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9263.h] + * + * (C) 2007 Atmel Corporation. + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de + * + * Definitions for the SoC: + * AT91SAM9263 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9263_H +#define AT91SAM9263_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Peripherals */ +#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ +#define ATMEL_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */ +/* Reserved: 5 */ +/* Reserved: 6 */ +#define ATMEL_ID_USART0 7 /* USART 0 */ +#define ATMEL_ID_USART1 8 /* USART 1 */ +#define ATMEL_ID_USART2 9 /* USART 2 */ +#define ATMEL_ID_MCI0 10 /* Multimedia Card Interface 0 */ +#define ATMEL_ID_MCI1 11 /* Multimedia Card Interface 1 */ +#define ATMEL_ID_CAN 12 /* CAN */ +#define ATMEL_ID_TWI 13 /* Two-Wire Interface */ +#define ATMEL_ID_SPI0 14 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 15 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_SSC0 16 /* Serial Synchronous Controller 0 */ +#define ATMEL_ID_SSC1 17 /* Serial Synchronous Controller 1 */ +#define ATMEL_ID_AC97C 18 /* AC97 Controller */ +#define ATMEL_ID_TCB 19 /* Timer Counter 0, 1 and 2 */ +#define ATMEL_ID_PWMC 20 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_EMAC 21 /* Ethernet */ +/* Reserved: 22 */ +#define ATMEL_ID_2DGE 23 /* 2D Graphic Engine */ +#define ATMEL_ID_UDP 24 /* USB Device Port */ +#define ATMEL_ID_ISI 25 /* Image Sensor Interface */ +#define ATMEL_ID_LCDC 26 /* LCD Controller */ +#define ATMEL_ID_DMA 27 /* DMA Controller */ +/* Reserved: 28 */ +#define ATMEL_ID_UHP 29 /* USB Host port */ +#define ATMEL_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */ +#define ATMEL_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */ + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_UDP 0xfff78000 +#define ATMEL_BASE_TCB0 0xfff7c000 +#define ATMEL_BASE_TC0 0xfff7c000 +#define ATMEL_BASE_TC1 0xfff7c040 +#define ATMEL_BASE_TC2 0xfff7c080 +#define ATMEL_BASE_MCI0 0xfff80000 +#define ATMEL_BASE_MCI1 0xfff84000 +#define ATMEL_BASE_TWI 0xfff88000 +#define ATMEL_BASE_USART0 0xfff8c000 +#define ATMEL_BASE_USART1 0xfff90000 +#define ATMEL_BASE_USART2 0xfff94000 +#define ATMEL_BASE_SSC0 0xfff98000 +#define ATMEL_BASE_SSC1 0xfff9c000 +#define ATMEL_BASE_AC97C 0xfffa0000 +#define ATMEL_BASE_SPI0 0xfffa4000 +#define ATMEL_BASE_SPI1 0xfffa8000 +#define ATMEL_BASE_CAN 0xfffac000 +#define ATMEL_BASE_PWMC 0xfffb8000 +#define ATMEL_BASE_EMAC 0xfffbc000 +#define ATMEL_BASE_ISI 0xfffc4000 +#define ATMEL_BASE_2DGE 0xfffc8000 + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_ECC0 0xffffe000 +#define ATMEL_BASE_SDRAMC0 0xffffe200 +#define ATMEL_BASE_SMC0 0xffffe400 +#define ATMEL_BASE_ECC1 0xffffe600 +#define ATMEL_BASE_SDRAMC1 0xffffe800 +#define ATMEL_BASE_SMC1 0xffffea00 +#define ATMEL_BASE_MATRIX 0xffffec00 +#define ATMEL_BASE_CCFG 0xffffed10 +#define ATMEL_BASE_DBGU 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_PIOA 0xfffff200 +#define ATMEL_BASE_PIOB 0xfffff400 +#define ATMEL_BASE_PIOC 0xfffff600 +#define ATMEL_BASE_PIOD 0xfffff800 +#define ATMEL_BASE_PIOE 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffd00 +#define ATMEL_BASE_SHDWC 0xfffffd10 +#define ATMEL_BASE_RTT0 0xfffffd20 +#define ATMEL_BASE_PIT 0xfffffd30 +#define ATMEL_BASE_WDT 0xfffffd40 +#define ATMEL_BASE_RTT1 0xfffffd50 +#define ATMEL_BASE_GPBR 0xfffffd60 + +/* + * Internal Memory. + */ +#define ATMEL_BASE_SRAM0 0x00300000 /* Internal SRAM 0 */ + +#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM */ + +#define ATMEL_BASE_SRAM1 0x00500000 /* Internal SRAM 1 */ + +#define ATMEL_BASE_LCDC 0x00700000 /* LCD Controller */ +#define ATMEL_BASE_DMAC 0x00800000 /* DMA Controller */ +#define ATMEL_BASE_UHP 0x00a00000 /* USB Host controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 /* typically NOR */ +#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 /* typically NAND */ +#define ATMEL_BASE_CS4 0x50000000 +#define ATMEL_BASE_CS5 0x60000000 +#define ATMEL_BASE_CS6 0x70000000 +#define ATMEL_BASE_CS7 0x80000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 5 /* this SoCs has 5 PIO */ +#define ATMEL_BASE_PIO ATMEL_BASE_PIOA +#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP + +/* + * Cpu Name + */ +#define ATMEL_CPU_NAME "AT91SAM9263" + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h new file mode 100644 index 0000000000..54d862287b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h @@ -0,0 +1,64 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9263_matrix.h] + * + * Copyright (C) 2006 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9263 datasheet revision B (Preliminary). + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9263_MATRIX_H +#define AT91SAM9263_MATRIX_H + +#ifndef __ASSEMBLY__ + +/* + * This struct defines access to the matrix' maximum of + * 16 masters and 16 slaves. + * Note: not all masters/slaves are available + */ +struct at91_matrix { + u32 mcfg[16]; /* Master Configuration Registers */ + u32 scfg[16]; /* Slave Configuration Registers */ + u32 pras[16][2]; /* Priority Assignment Slave Registers */ + u32 mrcr; /* Master Remap Control Register */ + u32 filler[0x06]; + u32 ebicsa; /* EBI Chip Select Assignment Register */ +}; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) + +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9_matrix.h new file mode 100644 index 0000000000..d0bf0c2e2b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_matrix.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_AT91SAM9_MATRIX_H +#define __ASM_ARCH_AT91SAM9_MATRIX_H + +#if defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) +#include +#elif defined(CONFIG_AT91SAM9261) +#include +#elif defined(CONFIG_AT91SAM9263) +#include +#elif defined(CONFIG_AT91SAM9RL) +#include +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) +#include +#elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) +#include +#else +#error "Unsupported AT91SAM9/CAP9 processor" +#endif + +#endif /* __ASM_ARCH_AT91SAM9_MATRIX_H */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h new file mode 100644 index 0000000000..3a076c6b80 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h @@ -0,0 +1,117 @@ +/* + * [origin: Linux kernel arch/arm/mach-at91/include/mach/at91_wdt.h] + * + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * SDRAM Controllers (SDRAMC) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9_SDRAMC_H +#define AT91SAM9_SDRAMC_H + +#ifdef __ASSEMBLY__ + +#ifndef ATMEL_BASE_SDRAMC +#define ATMEL_BASE_SDRAMC ATMEL_BASE_SDRAMC0 +#endif + +#define AT91_ASM_SDRAMC_MR ATMEL_BASE_SDRAMC +#define AT91_ASM_SDRAMC_TR (ATMEL_BASE_SDRAMC + 0x04) +#define AT91_ASM_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08) +#define AT91_ASM_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24) + +#else +struct sdramc_reg { + u32 mr; + u32 tr; + u32 cr; + u32 lpr; + u32 ier; + u32 idr; + u32 imr; + u32 isr; + u32 mdr; +}; + +int sdramc_initialize(unsigned int sdram_address, + const struct sdramc_reg *p); +#endif + +/* SDRAM Controller (SDRAMC) registers */ +#define AT91_SDRAMC_MR (ATMEL_BASE_SDRAMC + 0x00) /* SDRAM Controller Mode Register */ +#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */ +#define AT91_SDRAMC_MODE_NORMAL 0 +#define AT91_SDRAMC_MODE_NOP 1 +#define AT91_SDRAMC_MODE_PRECHARGE 2 +#define AT91_SDRAMC_MODE_LMR 3 +#define AT91_SDRAMC_MODE_REFRESH 4 +#define AT91_SDRAMC_MODE_EXT_LMR 5 +#define AT91_SDRAMC_MODE_DEEP 6 + +#define AT91_SDRAMC_TR (ATMEL_BASE_SDRAMC + 0x04) /* SDRAM Controller Refresh Timer Register */ +#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_SDRAMC_CR (ATMEL_BASE_SDRAMC + 0x08) /* SDRAM Controller Configuration Register */ +#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_SDRAMC_NC_8 (0 << 0) +#define AT91_SDRAMC_NC_9 (1 << 0) +#define AT91_SDRAMC_NC_10 (2 << 0) +#define AT91_SDRAMC_NC_11 (3 << 0) +#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_SDRAMC_NR_11 (0 << 2) +#define AT91_SDRAMC_NR_12 (1 << 2) +#define AT91_SDRAMC_NR_13 (2 << 2) +#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */ +#define AT91_SDRAMC_NB_2 (0 << 4) +#define AT91_SDRAMC_NB_4 (1 << 4) +#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */ +#define AT91_SDRAMC_CAS_1 (1 << 5) +#define AT91_SDRAMC_CAS_2 (2 << 5) +#define AT91_SDRAMC_CAS_3 (3 << 5) +#define AT91_SDRAMC_DBW (1 << 7) /* Data Bus Width */ +#define AT91_SDRAMC_DBW_32 (0 << 7) +#define AT91_SDRAMC_DBW_16 (1 << 7) +#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */ +#define AT91_SDRAMC_TWR_VAL(x) (x << 8) +#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */ +#define AT91_SDRAMC_TRC_VAL(x) (x << 12) +#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */ +#define AT91_SDRAMC_TRP_VAL(x) (x << 16) +#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */ +#define AT91_SDRAMC_TRCD_VAL(x) (x << 20) +#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */ +#define AT91_SDRAMC_TRAS_VAL(x) (x << 24) +#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */ +#define AT91_SDRAMC_TXSR_VAL(x) (x << 28) + +#define AT91_SDRAMC_LPR (ATMEL_BASE_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */ +#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_SDRAMC_LPCB_DISABLE 0 +#define AT91_SDRAMC_LPCB_SELF_REFRESH 1 +#define AT91_SDRAMC_LPCB_POWER_DOWN 2 +#define AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_SDRAMC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_SDRAMC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_SDRAMC_DS (3 << 10) /* Drive Strength */ +#define AT91_SDRAMC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12) + +#define AT91_SDRAMC_IER (ATMEL_BASE_SDRAMC + 0x14) /* SDRAM Controller Interrupt Enable Register */ +#define AT91_SDRAMC_IDR (ATMEL_BASE_SDRAMC + 0x18) /* SDRAM Controller Interrupt Disable Register */ +#define AT91_SDRAMC_IMR (ATMEL_BASE_SDRAMC + 0x1C) /* SDRAM Controller Interrupt Mask Register */ +#define AT91_SDRAMC_ISR (ATMEL_BASE_SDRAMC + 0x20) /* SDRAM Controller Interrupt Status Register */ +#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */ + +#define AT91_SDRAMC_MDR (ATMEL_BASE_SDRAMC + 0x24) /* SDRAM Memory Device Register */ +#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */ +#define AT91_SDRAMC_MD_SDRAM 0 +#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h new file mode 100644 index 0000000000..d29e98e711 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h @@ -0,0 +1,76 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9_smc.h] + * + * Copyright (C) 2007 Andrew Victor + * Copyright (C) 2007 Atmel Corporation. + * + * Static Memory Controllers (SMC) - System peripherals registers. + * Based on AT91SAM9261 datasheet revision D. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9_SMC_H +#define AT91SAM9_SMC_H + +#ifdef __ASSEMBLY__ + +#ifndef ATMEL_BASE_SMC +#define ATMEL_BASE_SMC ATMEL_BASE_SMC0 +#endif + +#define AT91_ASM_SMC_SETUP0 ATMEL_BASE_SMC +#define AT91_ASM_SMC_PULSE0 (ATMEL_BASE_SMC + 0x04) +#define AT91_ASM_SMC_CYCLE0 (ATMEL_BASE_SMC + 0x08) +#define AT91_ASM_SMC_MODE0 (ATMEL_BASE_SMC + 0x0C) + +#else + +typedef struct at91_cs { + u32 setup; /* 0x00 SMC Setup Register */ + u32 pulse; /* 0x04 SMC Pulse Register */ + u32 cycle; /* 0x08 SMC Cycle Register */ + u32 mode; /* 0x0C SMC Mode Register */ +} at91_cs_t; + +typedef struct at91_smc { + at91_cs_t cs[8]; +} at91_smc_t; + +#endif /* __ASSEMBLY__ */ + +#define AT91_SMC_SETUP_NWE(x) (x & 0x3f) +#define AT91_SMC_SETUP_NCS_WR(x) ((x & 0x3f) << 8) +#define AT91_SMC_SETUP_NRD(x) ((x & 0x3f) << 16) +#define AT91_SMC_SETUP_NCS_RD(x) ((x & 0x3f) << 24) + +#define AT91_SMC_PULSE_NWE(x) (x & 0x7f) +#define AT91_SMC_PULSE_NCS_WR(x) ((x & 0x7f) << 8) +#define AT91_SMC_PULSE_NRD(x) ((x & 0x7f) << 16) +#define AT91_SMC_PULSE_NCS_RD(x) ((x & 0x7f) << 24) + +#define AT91_SMC_CYCLE_NWE(x) (x & 0x1ff) +#define AT91_SMC_CYCLE_NRD(x) ((x & 0x1ff) << 16) + +#define AT91_SMC_MODE_RM_NCS 0x00000000 +#define AT91_SMC_MODE_RM_NRD 0x00000001 +#define AT91_SMC_MODE_WM_NCS 0x00000000 +#define AT91_SMC_MODE_WM_NWE 0x00000002 + +#define AT91_SMC_MODE_EXNW_DISABLE 0x00000000 +#define AT91_SMC_MODE_EXNW_FROZEN 0x00000020 +#define AT91_SMC_MODE_EXNW_READY 0x00000030 + +#define AT91_SMC_MODE_BAT 0x00000100 +#define AT91_SMC_MODE_DBW_8 0x00000000 +#define AT91_SMC_MODE_DBW_16 0x00001000 +#define AT91_SMC_MODE_DBW_32 0x00002000 +#define AT91_SMC_MODE_TDF_CYCLE(x) ((x & 0xf) << 16) +#define AT91_SMC_MODE_TDF 0x00100000 +#define AT91_SMC_MODE_PMEN 0x01000000 +#define AT91_SMC_MODE_PS_4 0x00000000 +#define AT91_SMC_MODE_PS_8 0x10000000 +#define AT91_SMC_MODE_PS_16 0x20000000 +#define AT91_SMC_MODE_PS_32 0x30000000 + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h new file mode 100644 index 0000000000..6df8cdb56d --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -0,0 +1,151 @@ +/* + * Chip-specific header file for the AT91SAM9M1x family + * + * (C) 2008 Atmel Corporation. + * + * Definitions for the SoC: + * AT91SAM9G45 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9G45_H +#define AT91SAM9G45_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ +#define ATMEL_ID_PIOA 2 /* Parallel I/O Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel I/O Controller B */ +#define ATMEL_ID_PIOC 4 /* Parallel I/O Controller C */ +#define ATMEL_ID_PIODE 5 /* Parallel I/O Controller D and E */ +#define ATMEL_ID_TRNG 6 /* True Random Number Generator */ +#define ATMEL_ID_USART0 7 /* USART 0 */ +#define ATMEL_ID_USART1 8 /* USART 1 */ +#define ATMEL_ID_USART2 9 /* USART 2 */ +#define ATMEL_ID_USART3 10 /* USART 3 */ +#define ATMEL_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */ +#define ATMEL_ID_TWI0 12 /* Two-Wire Interface 0 */ +#define ATMEL_ID_TWI1 13 /* Two-Wire Interface 1 */ +#define ATMEL_ID_SPI0 14 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 15 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_SSC0 16 /* Synchronous Serial Controller 0 */ +#define ATMEL_ID_SSC1 17 /* Synchronous Serial Controller 1 */ +#define ATMEL_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define ATMEL_ID_PWMC 19 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_TSC 20 /* Touch Screen ADC Controller */ +#define ATMEL_ID_DMA 21 /* DMA Controller */ +#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */ +#define ATMEL_ID_LCDC 23 /* LCD Controller */ +#define ATMEL_ID_AC97C 24 /* AC97 Controller */ +#define ATMEL_ID_EMAC 25 /* Ethernet MAC */ +#define ATMEL_ID_ISI 26 /* Image Sensor Interface */ +#define ATMEL_ID_UDPHS 27 /* USB Device High Speed */ +#define ATMEL_ID_AESTDESSHA 28 /* AES + T-DES + SHA */ +#define ATMEL_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */ +#define ATMEL_ID_VDEC 30 /* Video Decoder */ +#define ATMEL_ID_IRQ0 31 /* Advanced Interrupt Controller */ + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_UDPHS 0xfff78000 +#define ATMEL_BASE_TC0 0xfff7c000 +#define ATMEL_BASE_TC1 0xfff7c040 +#define ATMEL_BASE_TC2 0xfff7c080 +#define ATMEL_BASE_MCI0 0xfff80000 +#define ATMEL_BASE_TWI0 0xfff84000 +#define ATMEL_BASE_TWI1 0xfff88000 +#define ATMEL_BASE_USART0 0xfff8c000 +#define ATMEL_BASE_USART1 0xfff90000 +#define ATMEL_BASE_USART2 0xfff94000 +#define ATMEL_BASE_USART3 0xfff98000 +#define ATMEL_BASE_SSC0 0xfff9c000 +#define ATMEL_BASE_SSC1 0xfffa0000 +#define ATMEL_BASE_SPI0 0xfffa4000 +#define ATMEL_BASE_SPI1 0xfffa8000 +#define ATMEL_BASE_AC97C 0xfffac000 +#define ATMEL_BASE_TSC 0xfffb0000 +#define ATMEL_BASE_ISI 0xfffb4000 +#define ATMEL_BASE_PWMC 0xfffb8000 +#define ATMEL_BASE_EMAC 0xfffbc000 +#define ATMEL_BASE_AES 0xfffc0000 +#define ATMEL_BASE_TDES 0xfffc4000 +#define ATMEL_BASE_SHA 0xfffc8000 +#define ATMEL_BASE_TRNG 0xfffcc000 +#define ATMEL_BASE_MCI1 0xfffd0000 +#define ATMEL_BASE_TC3 0xfffd4000 +#define ATMEL_BASE_TC4 0xfffd4040 +#define ATMEL_BASE_TC5 0xfffd4080 +/* Reserved: 0xfffd8000 - 0xffffe1ff */ + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_SYS 0xffffe200 +#define ATMEL_BASE_ECC 0xffffe200 +#define ATMEL_BASE_DDRSDRC1 0xffffe400 +#define ATMEL_BASE_DDRSDRC0 0xffffe600 +#define ATMEL_BASE_SMC 0xffffe800 +#define ATMEL_BASE_MATRIX 0xffffea00 +#define ATMEL_BASE_DMA 0xffffec00 +#define ATMEL_BASE_DBGU 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_PIOA 0xfffff200 +#define ATMEL_BASE_PIOB 0xfffff400 +#define ATMEL_BASE_PIOC 0xfffff600 +#define ATMEL_BASE_PIOD 0xfffff800 +#define ATMEL_BASE_PIOE 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffd00 +#define ATMEL_BASE_SHDWN 0xfffffd10 +#define ATMEL_BASE_RTT 0xfffffd20 +#define ATMEL_BASE_PIT 0xfffffd30 +#define ATMEL_BASE_WDT 0xfffffd40 +#define ATMEL_BASE_GPBR 0xfffffd60 +#define ATMEL_BASE_RTC 0xfffffdb0 +/* Reserved: 0xfffffdc0 - 0xffffffff */ + +/* + * Internal Memory. + */ +#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ +#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ +#define ATMEL_BASE_LCDC 0x00500000 /* LCD Controller */ +#define ATMEL_BASE_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ +#define ATMEL_BASE_HCI 0x00700000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00800000 /* USB Host controller (EHCI) */ +#define ATMEL_BASE_VDEC 0x00900000 /* Video Decoder Controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_CS1 0x20000000 +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 +#define ATMEL_BASE_CS4 0x50000000 +#define ATMEL_BASE_CS5 0x60000000 +#define ATMEL_BASE_CS6 0x70000000 +#define ATMEL_BASE_CS7 0x80000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 5 /* this SoCs has 5 PIO */ +#define ATMEL_BASE_PIO ATMEL_BASE_PIOA +#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP +#define ATMEL_ID_UHP ATMEL_ID_UHPHS +/* + * Cpu Name + */ +#define ATMEL_CPU_NAME "AT91SAM9G45" + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h new file mode 100644 index 0000000000..80e49e3430 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h @@ -0,0 +1,92 @@ +/* + * Matrix-centric header file for the AT91SAM9M1x family + * + * Copyright (C) 2008 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9G45 preliminary datasheet. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef AT91SAM9G45_MATRIX_H +#define AT91SAM9G45_MATRIX_H + +#ifndef __ASSEMBLY__ + +struct at91_matrix { + u32 mcfg[16]; + u32 scfg[16]; + u32 pras[16][2]; + u32 mrcr; /* 0x100 Master Remap Control */ + u32 filler[3]; + u32 tcmr; + u32 filler2; + u32 ddrmpr; + u32 filler3[3]; + u32 ebicsa; + u32 filler4[47]; + u32 wpmr; + u32 wpsr; +}; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) +#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) +#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) +#define AT91_MATRIX_ULBT_128 (7 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 +#define AT91_MATRIX_M6PR_SHIFT 24 +#define AT91_MATRIX_M7PR_SHIFT 28 + +#define AT91_MATRIX_M8PR_SHIFT 0 /* register B */ +#define AT91_MATRIX_M9PR_SHIFT 4 /* register B */ +#define AT91_MATRIX_M10PR_SHIFT 8 /* register B */ +#define AT91_MATRIX_M11PR_SHIFT 12 /* register B */ + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) +#define AT91_MATRIX_RCB6 (1 << 6) +#define AT91_MATRIX_RCB7 (1 << 7) +#define AT91_MATRIX_RCB8 (1 << 8) +#define AT91_MATRIX_RCB9 (1 << 9) +#define AT91_MATRIX_RCB10 (1 << 10) + +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) +#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4) +#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) +#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5) +#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) +#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) +#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) +#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) +#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h new file mode 100644 index 0000000000..3a8e6d62ce --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -0,0 +1,130 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9rl.h] + * + * Copyright (C) 2007 Atmel Corporation + * + * Common definitions. + * Based on AT91SAM9RL datasheet revision A. (Preliminary) + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef AT91SAM9RL_H +#define AT91SAM9RL_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Peripherals */ +#define ATMEL_ID_PIOA 2 /* Parallel IO Controller A */ +#define ATMEL_ID_PIOB 3 /* Parallel IO Controller B */ +#define ATMEL_ID_PIOC 4 /* Parallel IO Controller C */ +#define ATMEL_ID_PIOD 5 /* Parallel IO Controller D */ +#define ATMEL_ID_USART0 6 /* USART 0 */ +#define ATMEL_ID_USART1 7 /* USART 1 */ +#define ATMEL_ID_USART2 8 /* USART 2 */ +#define ATMEL_ID_USART3 9 /* USART 3 */ +#define ATMEL_ID_MCI 10 /* Multimedia Card Interface */ +#define ATMEL_ID_TWI0 11 /* TWI 0 */ +#define ATMEL_ID_TWI1 12 /* TWI 1 */ +#define ATMEL_ID_SPI 13 /* Serial Peripheral Interface */ +#define ATMEL_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define ATMEL_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define ATMEL_ID_TC0 16 /* Timer Counter 0 */ +#define ATMEL_ID_TC1 17 /* Timer Counter 1 */ +#define ATMEL_ID_TC2 18 /* Timer Counter 2 */ +#define ATMEL_ID_PWMC 19 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_TSC 20 /* Touch Screen Controller */ +#define ATMEL_ID_DMA 21 /* DMA Controller */ +#define ATMEL_ID_UDPHS 22 /* USB Device HS */ +#define ATMEL_ID_LCDC 23 /* LCD Controller */ +#define ATMEL_ID_AC97C 24 /* AC97 Controller */ +#define ATMEL_ID_IRQ0 31 /* Advanced Interrupt Controller (IRQ0) */ + +/* + * User Peripheral physical base addresses. + */ +#define ATMEL_BASE_TCB0 0xfffa0000 +#define ATMEL_BASE_TC0 0xfffa0000 +#define ATMEL_BASE_TC1 0xfffa0040 +#define ATMEL_BASE_TC2 0xfffa0080 +#define ATMEL_BASE_MCI 0xfffa4000 +#define ATMEL_BASE_TWI0 0xfffa8000 +#define ATMEL_BASE_TWI1 0xfffac000 +#define ATMEL_BASE_USART0 0xfffb0000 +#define ATMEL_BASE_USART1 0xfffb4000 +#define ATMEL_BASE_USART2 0xfffb8000 +#define ATMEL_BASE_USART3 0xfffbc000 +#define ATMEL_BASE_SSC0 0xfffc0000 +#define ATMEL_BASE_SSC1 0xfffc4000 +#define ATMEL_BASE_PWMC 0xfffc8000 +#define ATMEL_BASE_SPI0 0xfffcc000 +#define ATMEL_BASE_TSC 0xfffd0000 +#define ATMEL_BASE_UDPHS 0xfffd4000 +#define ATMEL_BASE_AC97C 0xfffd8000 +#define ATMEL_BASE_SYS 0xffffc000 + +/* + * System Peripherals + */ +#define ATMEL_BASE_DMA 0xffffe600 +#define ATMEL_BASE_ECC 0xffffe800 +#define ATMEL_BASE_SDRAMC 0xffffea00 +#define ATMEL_BASE_SMC 0xffffec00 +#define ATMEL_BASE_MATRIX 0xffffee00 +#define ATMEL_BASE_CCFG 0xffffef10 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_DBGU 0xfffff200 +#define ATMEL_BASE_PIOA 0xfffff400 +#define ATMEL_BASE_PIOB 0xfffff600 +#define ATMEL_BASE_PIOC 0xfffff800 +#define ATMEL_BASE_PIOD 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffd00 +#define ATMEL_BASE_SHDWC 0xfffffd10 +#define ATMEL_BASE_RTT 0xfffffd20 +#define ATMEL_BASE_PIT 0xfffffd30 +#define ATMEL_BASE_WDT 0xfffffd40 +#define ATMEL_BASE_SCKCR 0xfffffd50 +#define ATMEL_BASE_GPBR 0xfffffd60 +#define ATMEL_BASE_RTC 0xfffffe00 + +/* + * Internal Memory. + */ +#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ +#define ATMEL_BASE_ROM 0x00400000 /* Internal ROM base address */ + +#define ATMEL_BASE_LCDC 0x00500000 /* LCD Controller */ +#define ATMEL_UHP_BASE 0x00600000 /* USB Device HS controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_CS1 0x20000000 /* SDRAM */ +#define ATMEL_BASE_CS2 0x30000000 +#define ATMEL_BASE_CS3 0x40000000 /* NAND */ +#define ATMEL_BASE_CS4 0x50000000 /* Compact Flash Slot 0 */ +#define ATMEL_BASE_CS5 0x60000000 /* Compact Flash Slot 1 */ + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 4 /* this SoC has 4 PIO */ +#define ATMEL_BASE_PIO ATMEL_BASE_PIOA + +/* + * Cpu Name + */ +#define ATMEL_CPU_NAME "AT91SAM9RL" + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h new file mode 100644 index 0000000000..295f768b55 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h @@ -0,0 +1,61 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/at91sam9rl_matrix.h] + * + * Copyright (C) 2007 Atmel Corporation + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9RL datasheet revision A. (Preliminary) + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef AT91SAM9RL_MATRIX_H +#define AT91SAM9RL_MATRIX_H + +#ifndef __ASSEMBLY__ + +struct at91_matrix { + u32 mcfg[16]; /* Master Configuration Registers */ + u32 scfg[16]; /* Slave Configuration Registers */ + u32 pras[16][2]; /* Priority Assignment Slave Registers */ + u32 mrcr; /* Master Remap Control Register */ + u32 filler[7]; + u32 ebicsa; /* EBI Chip Select Assignment Register */ +}; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 +#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24) +#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24) + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) + +#define AT91_MATRIX_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4) +#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5) +#define AT91_MATRIX_DBPUC (1 << 8) +#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16) + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h new file mode 100644 index 0000000000..36a5cdf476 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h @@ -0,0 +1,184 @@ +/* + * Chip-specific header file for the AT91SAM9x5 family + * + * Copyright (C) 2012-2013 Atmel Corporation. + * + * Definitions for the SoC: + * AT91SAM9x5 & AT91SAM9N12 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __AT91SAM9X5_H__ +#define __AT91SAM9X5_H__ + +#define CONFIG_AT91FAMILY /* it's a member of AT91 family */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ +#define ATMEL_ID_PIOAB 2 /* Parallel I/O Controller A and B */ +#define ATMEL_ID_PIOCD 3 /* Parallel I/O Controller C and D */ +#define ATMEL_ID_SMD 4 /* SMD Soft Modem (SMD), only for AT91SAM9X5 */ +#define ATMEL_ID_FUSE 4 /* FUSE Controller, only for AT91SAM9N12 */ +#define ATMEL_ID_USART0 5 /* USART 0 */ +#define ATMEL_ID_USART1 6 /* USART 1 */ +#define ATMEL_ID_USART2 7 /* USART 2 */ +#define ATMEL_ID_USART3 8 /* USART 3 */ +#define ATMEL_ID_TWI0 9 /* Two-Wire Interface 0 */ +#define ATMEL_ID_TWI1 10 /* Two-Wire Interface 1 */ +#define ATMEL_ID_TWI2 11 /* Two-Wire Interface 2 */ +#define ATMEL_ID_HSMCI0 12 /* High Speed Multimedia Card Interface 0 */ +#define ATMEL_ID_SPI0 13 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 14 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_UART0 15 /* UART 0 */ +#define ATMEL_ID_UART1 16 /* UART 1 */ +#define ATMEL_ID_TC01 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ +#define ATMEL_ID_PWM 18 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_ADC 19 /* ADC Controller */ +#define ATMEL_ID_DMAC0 20 /* DMA Controller 0 */ +#define ATMEL_ID_DMAC1 21 /* DMA Controller 1 */ +#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */ +#define ATMEL_ID_UDPHS 23 /* USB Device High Speed */ +#define ATMEL_ID_EMAC0 24 /* Ethernet MAC0 */ +#define ATMEL_ID_LCDC 25 /* LCD Controller */ +#define ATMEL_ID_HSMCI1 26 /* High Speed Multimedia Card Interface 1 */ +#define ATMEL_ID_EMAC1 27 /* Ethernet MAC1 */ +#define ATMEL_ID_SSC 28 /* Synchronous Serial Controller */ +#define ATMEL_ID_TRNG 30 /* True Random Number Generator */ +#define ATMEL_ID_IRQ 31 /* Advanced Interrupt Controller */ + +/* + * User Peripheral physical base addresses. + */ +#define ATMEL_BASE_SPI0 0xf0000000 +#define ATMEL_BASE_SPI1 0xf0004000 +#define ATMEL_BASE_HSMCI0 0xf0008000 +#define ATMEL_BASE_HSMCI1 0xf000c000 +#define ATMEL_BASE_SSC 0xf0010000 +#define ATMEL_BASE_CAN0 0xf8000000 +#define ATMEL_BASE_CAN1 0xf8004000 +#define ATMEL_BASE_TC0 0xf8008000 +#define ATMEL_BASE_TC1 0xf8008040 +#define ATMEL_BASE_TC2 0xf8008080 +#define ATMEL_BASE_TC3 0xf800c000 +#define ATMEL_BASE_TC4 0xf800c040 +#define ATMEL_BASE_TC5 0xf800c080 +#define ATMEL_BASE_TWI0 0xf8010000 +#define ATMEL_BASE_TWI1 0xf8014000 +#define ATMEL_BASE_TWI2 0xf8018000 +#define ATMEL_BASE_USART0 0xf801c000 +#define ATMEL_BASE_USART1 0xf8020000 +#define ATMEL_BASE_USART2 0xf8024000 +#define ATMEL_BASE_USART3 0xf8028000 +#define ATMEL_BASE_EMAC0 0xf802c000 +#define ATMEL_BASE_EMAC1 0xf8030000 +#define ATMEL_BASE_PWM 0xf8034000 +#define ATMEL_BASE_LCDC 0xf8038000 +#define ATMEL_BASE_UDPHS 0xf803c000 +#define ATMEL_BASE_UART0 0xf8040000 +#define ATMEL_BASE_UART1 0xf8044000 +#define ATMEL_BASE_ISI 0xf8048000 +#define ATMEL_BASE_ADC 0xf804c000 +#define ATMEL_BASE_SYS 0xffffc000 + +/* + * System Peripherals + */ +#define ATMEL_BASE_FUSE 0xffffdc00 +#define ATMEL_BASE_MATRIX 0xffffde00 +#define ATMEL_BASE_PMECC 0xffffe000 +#define ATMEL_BASE_PMERRLOC 0xffffe600 +#define ATMEL_BASE_DDRSDRC 0xffffe800 +#define ATMEL_BASE_SMC 0xffffea00 +#define ATMEL_BASE_DMAC0 0xffffec00 +#define ATMEL_BASE_DMAC1 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_DBGU 0xfffff200 +#define ATMEL_BASE_PIOA 0xfffff400 +#define ATMEL_BASE_PIOB 0xfffff600 +#define ATMEL_BASE_PIOC 0xfffff800 +#define ATMEL_BASE_PIOD 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffe00 +#define ATMEL_BASE_SHDWC 0xfffffe10 +#define ATMEL_BASE_PIT 0xfffffe30 +#define ATMEL_BASE_WDT 0xfffffe40 +#define ATMEL_BASE_GPBR 0xfffffe60 +#define ATMEL_BASE_RTC 0xfffffeb0 + +/* + * Internal Memory. + */ +#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */ + +#ifdef CONFIG_AT91SAM9N12 +#define ATMEL_BASE_OHCI 0x00500000 /* USB Host controller */ +#else /* AT91SAM9X5 */ +#define ATMEL_BASE_SMD 0x00400000 /* SMD Controller */ +#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ +#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ +#endif + +/* 9x5 series chip id definitions */ +#define ARCH_ID_AT91SAM9X5 0x819a05a0 +#define ARCH_ID_VERSION_MASK 0x1f +#define ARCH_EXID_AT91SAM9G15 0x00000000 +#define ARCH_EXID_AT91SAM9G35 0x00000001 +#define ARCH_EXID_AT91SAM9X35 0x00000002 +#define ARCH_EXID_AT91SAM9G25 0x00000003 +#define ARCH_EXID_AT91SAM9X25 0x00000004 + +#define cpu_is_at91sam9x5() (get_chip_id() == ARCH_ID_AT91SAM9X5) +#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAM9G15)) +#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAM9G25)) +#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAM9G35)) +#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAM9X25)) +#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ + (get_extension_chip_id() == ARCH_EXID_AT91SAM9X35)) + +/* + * Cpu Name + */ +#ifdef CONFIG_AT91SAM9N12 +#define ATMEL_CPU_NAME "AT91SAM9N12" +#else /* AT91SAM9X5 */ +#define ATMEL_CPU_NAME get_cpu_name() +#endif + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 4 +#define CPU_HAS_PIO3 +#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */ +#define ATMEL_PMC_UHP AT91SAM926x_PMC_UHP +#define ATMEL_ID_UHP ATMEL_ID_UHPHS + +/* + * PMECC table in ROM + */ +#define ATMEL_PMECC_INDEX_OFFSET_512 0x8000 +#define ATMEL_PMECC_INDEX_OFFSET_1024 0x10000 + +/* + * at91sam9x5 specific prototypes + */ +#ifndef __ASSEMBLY__ +unsigned int get_chip_id(void); +unsigned int get_extension_chip_id(void); +unsigned int has_emac1(void); +unsigned int has_emac0(void); +unsigned int has_lcdc(void); +char *get_cpu_name(void); +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h new file mode 100644 index 0000000000..bd0b25adc9 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h @@ -0,0 +1,99 @@ +/* + * Matrix-centric header file for the AT91SAM9X5 family + * + * Copyright (C) 2012-2013 Atmel Corporation. + * + * Memory Controllers (MATRIX, EBI) - System peripherals registers. + * Based on AT91SAM9X5 & AT91SAM9N12 preliminary datasheet. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __AT91SAM9X5_MATRIX_H__ +#define __AT91SAM9X5_MATRIX_H__ + +#ifndef __ASSEMBLY__ + +/* AT91SAM9N12 Matrix definition is a subset of AT91SAM9X5. */ +struct at91_matrix { + u32 mcfg[16]; + u32 scfg[16]; + u32 pras[16][2]; + u32 mrcr; /* 0x100 Master Remap Control */ + u32 filler[5]; +#ifdef CONFIG_AT91SAM9X5 + u32 filler1[2]; +#endif + /* EBI Chip Select Assignment Register + * 0x118: AT91SAM9N12 + * 0x120: AT91SAM9X5 + */ + u32 ebicsa; + u32 filler4[47]; +#ifdef CONFIG_AT91SAM9N12 + u32 filler5[2]; +#endif + u32 wpmr; + u32 wpsr; +}; + +#endif /* __ASSEMBLY__ */ + +#define AT91_MATRIX_ULBT_INFINITE (0 << 0) +#define AT91_MATRIX_ULBT_SINGLE (1 << 0) +#define AT91_MATRIX_ULBT_FOUR (2 << 0) +#define AT91_MATRIX_ULBT_EIGHT (3 << 0) +#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) +#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) +#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) +#define AT91_MATRIX_ULBT_128 (7 << 0) + +#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) +#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) +#define AT91_MATRIX_FIXED_DEFMSTR_SHIFT 18 + +#define AT91_MATRIX_M0PR_SHIFT 0 +#define AT91_MATRIX_M1PR_SHIFT 4 +#define AT91_MATRIX_M2PR_SHIFT 8 +#define AT91_MATRIX_M3PR_SHIFT 12 +#define AT91_MATRIX_M4PR_SHIFT 16 +#define AT91_MATRIX_M5PR_SHIFT 20 +#define AT91_MATRIX_M6PR_SHIFT 24 +#define AT91_MATRIX_M7PR_SHIFT 28 + +#define AT91_MATRIX_M8PR_SHIFT 0 /* register B */ +#define AT91_MATRIX_M9PR_SHIFT 4 /* register B */ +#define AT91_MATRIX_M10PR_SHIFT 8 /* register B */ +#define AT91_MATRIX_M11PR_SHIFT 12 /* register B */ + +#define AT91_MATRIX_RCB0 (1 << 0) +#define AT91_MATRIX_RCB1 (1 << 1) +#define AT91_MATRIX_RCB2 (1 << 2) +#define AT91_MATRIX_RCB3 (1 << 3) +#define AT91_MATRIX_RCB4 (1 << 4) +#define AT91_MATRIX_RCB5 (1 << 5) +#define AT91_MATRIX_RCB6 (1 << 6) +#define AT91_MATRIX_RCB7 (1 << 7) +#define AT91_MATRIX_RCB8 (1 << 8) +#define AT91_MATRIX_RCB9 (1 << 9) +#define AT91_MATRIX_RCB10 (1 << 10) + +#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) +#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) +#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) +#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) +#define AT91_MATRIX_EBI_DBPU_ON (0 << 8) +#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) +#define AT91_MATRIX_EBI_DBPD_ON (0 << 9) +#define AT91_MATRIX_EBI_DBPD_OFF (1 << 9) +#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) +#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) +#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) +#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) +#define AT91_MATRIX_NFD0_ON_D0 (0 << 24) +#define AT91_MATRIX_NFD0_ON_D16 (1 << 24) +#define AT91_MATRIX_MP_OFF (0 << 25) +#define AT91_MATRIX_MP_ON (1 << 25) + +#endif diff --git a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h new file mode 100644 index 0000000000..130a85abee --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ATMEL_MPDDRC_H__ +#define __ATMEL_MPDDRC_H__ + +/* + * Only define the needed register in mpddr + * If other register needed, will add them later + */ +struct atmel_mpddr { + u32 mr; + u32 rtr; + u32 cr; + u32 tpr0; + u32 tpr1; + u32 tpr2; + u32 reserved[2]; + u32 md; +}; + +int ddr2_init(const unsigned int ram_address, + const struct atmel_mpddr *mpddr); + +/* Bit field in mode register */ +#define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD 0x0 +#define ATMEL_MPDDRC_MR_MODE_NOP_CMD 0x1 +#define ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD 0x2 +#define ATMEL_MPDDRC_MR_MODE_LMR_CMD 0x3 +#define ATMEL_MPDDRC_MR_MODE_RFSH_CMD 0x4 +#define ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD 0x5 +#define ATMEL_MPDDRC_MR_MODE_DEEP_CMD 0x6 +#define ATMEL_MPDDRC_MR_MODE_LPDDR2_CMD 0x7 + +/* Bit field in configuration register */ +#define ATMEL_MPDDRC_CR_NC_MASK 0x3 +#define ATMEL_MPDDRC_CR_NC_COL_9 0x0 +#define ATMEL_MPDDRC_CR_NC_COL_10 0x1 +#define ATMEL_MPDDRC_CR_NC_COL_11 0x2 +#define ATMEL_MPDDRC_CR_NC_COL_12 0x3 +#define ATMEL_MPDDRC_CR_NR_MASK (0x3 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_11 (0x0 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_12 (0x1 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_13 (0x2 << 2) +#define ATMEL_MPDDRC_CR_NR_ROW_14 (0x3 << 2) +#define ATMEL_MPDDRC_CR_CAS_MASK (0x7 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS2 (0x2 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS3 (0x3 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS4 (0x4 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS5 (0x5 << 4) +#define ATMEL_MPDDRC_CR_CAS_DDR_CAS6 (0x6 << 4) +#define ATMEL_MPDDRC_CR_DLL_RESET_ENABLED (0x1 << 7) +#define ATMEL_MPDDRC_CR_DIC_DS (0x1 << 8) +#define ATMEL_MPDDRC_CR_DIS_DLL (0x1 << 9) +#define ATMEL_MPDDRC_CR_OCD_DEFAULT (0x7 << 12) +#define ATMEL_MPDDRC_CR_DQMS_SHARED (0x1 << 16) +#define ATMEL_MPDDRC_CR_ENRDM_ON (0x1 << 17) +#define ATMEL_MPDDRC_CR_NB_8BANKS (0x1 << 20) +#define ATMEL_MPDDRC_CR_NDQS_DISABLED (0x1 << 21) +#define ATMEL_MPDDRC_CR_DECOD_INTERLEAVED (0x1 << 22) +#define ATMEL_MPDDRC_CR_UNAL_SUPPORTED (0x1 << 23) + +/* Bit field in timing parameter 0 register */ +#define ATMEL_MPDDRC_TPR0_TRAS_OFFSET 0 +#define ATMEL_MPDDRC_TPR0_TRAS_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRCD_OFFSET 4 +#define ATMEL_MPDDRC_TPR0_TRCD_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TWR_OFFSET 8 +#define ATMEL_MPDDRC_TPR0_TWR_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRC_OFFSET 12 +#define ATMEL_MPDDRC_TPR0_TRC_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRP_OFFSET 16 +#define ATMEL_MPDDRC_TPR0_TRP_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TRRD_OFFSET 20 +#define ATMEL_MPDDRC_TPR0_TRRD_MASK 0xf +#define ATMEL_MPDDRC_TPR0_TWTR_OFFSET 24 +#define ATMEL_MPDDRC_TPR0_TWTR_MASK 0x7 +#define ATMEL_MPDDRC_TPR0_RDC_WRRD_OFFSET 27 +#define ATMEL_MPDDRC_TPR0_RDC_WRRD_MASK 0x1 +#define ATMEL_MPDDRC_TPR0_TMRD_OFFSET 28 +#define ATMEL_MPDDRC_TPR0_TMRD_MASK 0xf + +/* Bit field in timing parameter 1 register */ +#define ATMEL_MPDDRC_TPR1_TRFC_OFFSET 0 +#define ATMEL_MPDDRC_TPR1_TRFC_MASK 0x7f +#define ATMEL_MPDDRC_TPR1_TXSNR_OFFSET 8 +#define ATMEL_MPDDRC_TPR1_TXSNR_MASK 0xff +#define ATMEL_MPDDRC_TPR1_TXSRD_OFFSET 16 +#define ATMEL_MPDDRC_TPR1_TXSRD_MASK 0xff +#define ATMEL_MPDDRC_TPR1_TXP_OFFSET 24 +#define ATMEL_MPDDRC_TPR1_TXP_MASK 0xf + +/* Bit field in timing parameter 2 register */ +#define ATMEL_MPDDRC_TPR2_TXARD_OFFSET 0 +#define ATMEL_MPDDRC_TPR2_TXARD_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TXARDS_OFFSET 4 +#define ATMEL_MPDDRC_TPR2_TXARDS_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TRPA_OFFSET 8 +#define ATMEL_MPDDRC_TPR2_TRPA_MASK 0xf +#define ATMEL_MPDDRC_TPR2_TRTP_OFFSET 12 +#define ATMEL_MPDDRC_TPR2_TRTP_MASK 0x7 +#define ATMEL_MPDDRC_TPR2_TFAW_OFFSET 16 +#define ATMEL_MPDDRC_TPR2_TFAW_MASK 0xf + +/* Bit field in Memory Device Register */ +#define ATMEL_MPDDRC_MD_LPDDR_SDRAM 0x3 +#define ATMEL_MPDDRC_MD_DDR2_SDRAM 0x6 +#define ATMEL_MPDDRC_MD_DBW_MASK (0x1 << 4) +#define ATMEL_MPDDRC_MD_DBW_32_BITS (0x0 << 4) +#define ATMEL_MPDDRC_MD_DBW_16_BITS (0x1 << 4) + +#endif diff --git a/arch/arm/mach-at91/include/mach/atmel_serial.h b/arch/arm/mach-at91/include/mach/atmel_serial.h new file mode 100644 index 0000000000..5bc094b355 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel_serial.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ATMEL_SERIAL_H +#define _ATMEL_SERIAL_H + +/* Information about a serial port */ +struct atmel_serial_platdata { + uint32_t base_addr; +}; + +#endif diff --git a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h new file mode 100644 index 0000000000..38b5012fce --- /dev/null +++ b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005-2013 Atmel Corporation + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ATMEL_USBA_UDC_H__ +#define __ATMEL_USBA_UDC_H__ + +#include + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ + defined(CONFIG_AT91SAM9X5) +static struct usba_ep_data usba_udc_ep[] = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 2, 1, 1), + EP("ep2", 2, 1024, 2, 1, 1), + EP("ep3", 3, 1024, 3, 1, 0), + EP("ep4", 4, 1024, 3, 1, 0), + EP("ep5", 5, 1024, 3, 1, 1), + EP("ep6", 6, 1024, 3, 1, 1), +}; +#elif defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) +static struct usba_ep_data usba_udc_ep[] = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 3, 1, 0), + EP("ep2", 2, 1024, 3, 1, 0), + EP("ep3", 3, 1024, 2, 1, 0), + EP("ep4", 4, 1024, 2, 1, 0), + EP("ep5", 5, 1024, 2, 1, 0), + EP("ep6", 6, 1024, 2, 1, 0), + EP("ep7", 7, 1024, 2, 1, 0), + EP("ep8", 8, 1024, 2, 0, 0), + EP("ep9", 9, 1024, 2, 0, 0), + EP("ep10", 10, 1024, 2, 0, 0), + EP("ep11", 11, 1024, 2, 0, 0), + EP("ep12", 12, 1024, 2, 0, 0), + EP("ep13", 13, 1024, 2, 0, 0), + EP("ep14", 14, 1024, 2, 0, 0), + EP("ep15", 15, 1024, 2, 0, 0), +}; +#else +# error "NO usba_udc_ep defined" +#endif + +#undef EP + +struct usba_platform_data pdata = { + .num_ep = ARRAY_SIZE(usba_udc_ep), + .ep = usba_udc_ep, +}; + +#endif diff --git a/arch/arm/mach-at91/include/mach/clk.h b/arch/arm/mach-at91/include/mach/clk.h new file mode 100644 index 0000000000..1d45e2dc11 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/clk.h @@ -0,0 +1,122 @@ +/* + * (C) Copyright 2007 + * Stelian Pop + * Lead Tech Design + * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARM_ARCH_CLK_H__ +#define __ASM_ARM_ARCH_CLK_H__ + +#include +#include +#include + +static inline unsigned long get_cpu_clk_rate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.cpu_clk_rate_hz; +} + +static inline unsigned long get_main_clk_rate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.main_clk_rate_hz; +} + +static inline unsigned long get_mck_clk_rate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.mck_rate_hz; +} + +static inline unsigned long get_plla_clk_rate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.plla_rate_hz; +} + +static inline unsigned long get_pllb_clk_rate(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.pllb_rate_hz; +} + +static inline u32 get_pllb_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + return gd->arch.at91_pllb_usb_init; +} + +#ifdef CPU_HAS_H32MXDIV +static inline unsigned int get_h32mxdiv(void) +{ + struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; + + return readl(&pmc->mckr) & AT91_PMC_MCKR_H32MXDIV; +} +#else +static inline unsigned int get_h32mxdiv(void) +{ + return 0; +} +#endif + +static inline unsigned long get_macb_pclk_rate(unsigned int dev_id) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +static inline unsigned long get_usart_clk_rate(unsigned int dev_id) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +static inline unsigned long get_lcdc_clk_rate(unsigned int dev_id) +{ + return get_mck_clk_rate(); +} + +static inline unsigned long get_spi_clk_rate(unsigned int dev_id) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +static inline unsigned long get_twi_clk_rate(unsigned int dev_id) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +static inline unsigned long get_mci_clk_rate(void) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +static inline unsigned long get_pit_clk_rate(void) +{ + if (get_h32mxdiv()) + return get_mck_clk_rate() / 2; + else + return get_mck_clk_rate(); +} + +int at91_clock_init(unsigned long main_clock); +void at91_periph_clk_enable(int id); +void at91_periph_clk_disable(int id); +#endif /* __ASM_ARM_ARCH_CLK_H__ */ diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h new file mode 100644 index 0000000000..6d2a7b72ff --- /dev/null +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -0,0 +1,262 @@ +/* + * [origin: Linux kernel include/asm-arm/arch-at91/gpio.h] + * + * Copyright (C) 2005 HP Labs + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_AT91_GPIO_H +#define __ASM_ARCH_AT91_GPIO_H + +#include +#include +#include +#include + +#ifdef CONFIG_ATMEL_LEGACY + +#define PIN_BASE 0 + +#define MAX_GPIO_BANKS 5 + +/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ + +#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) +#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) +#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) +#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) +#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) +#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) +#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) +#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) +#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) +#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) +#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) +#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) +#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) +#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) +#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) +#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) +#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) +#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) +#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) +#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) +#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) +#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) +#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) +#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) +#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) +#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) +#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) +#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) +#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) +#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) +#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) +#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) + +#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) +#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) +#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) +#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) +#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) +#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) +#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) +#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) +#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) +#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) +#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) +#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) +#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) +#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) +#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) +#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) +#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) +#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) +#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) +#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) +#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) +#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) +#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) +#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) +#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) +#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) +#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) +#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) +#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) +#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) +#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) +#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) + +#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) +#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) +#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) +#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) +#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) +#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) +#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) +#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) +#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) +#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) +#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) +#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) +#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) +#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) +#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) +#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) +#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) +#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) +#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) +#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) +#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) +#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) +#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) +#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) +#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) +#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) +#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) +#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) +#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) +#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) +#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) +#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) + +#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) +#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) +#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) +#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) +#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) +#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) +#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) +#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) +#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) +#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) +#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) +#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) +#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) +#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) +#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) +#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) +#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) +#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) +#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) +#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) +#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) +#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) +#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) +#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) +#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) +#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) +#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) +#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) +#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) +#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) +#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) +#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) + +#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) +#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) +#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) +#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) +#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) +#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) +#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) +#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) +#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) +#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) +#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) +#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) +#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) +#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) +#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) +#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) +#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) +#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) +#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) +#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) +#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) +#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) +#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) +#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) +#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) +#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) +#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) +#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) +#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) +#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) +#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) +#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) + +static unsigned long at91_pios[] = { + ATMEL_BASE_PIOA, + ATMEL_BASE_PIOB, + ATMEL_BASE_PIOC, +#ifdef ATMEL_BASE_PIOD + ATMEL_BASE_PIOD, +#ifdef ATMEL_BASE_PIOE + ATMEL_BASE_PIOE +#endif +#endif +}; + +static inline void *pin_to_controller(unsigned pin) +{ + pin -= PIN_BASE; + pin /= 32; + return (void *)(at91_pios[pin]); +} + +static inline unsigned pin_to_mask(unsigned pin) +{ + pin -= PIN_BASE; + return 1 << (pin % 32); +} + +/* The following macros are need for backward compatibility */ +#define at91_set_GPIO_periph(x, y) \ + at91_set_pio_periph((x - PIN_BASE) / 32,(x % 32), y) +#define at91_set_A_periph(x, y) \ + at91_set_a_periph((x - PIN_BASE) / 32,(x % 32), y) +#define at91_set_B_periph(x, y) \ + at91_set_b_periph((x - PIN_BASE) / 32,(x % 32), y) +#define at91_set_gpio_output(x, y) \ + at91_set_pio_output((x - PIN_BASE) / 32,(x % 32), y) +#define at91_set_gpio_input(x, y) \ + at91_set_pio_input((x - PIN_BASE) / 32,(x % 32), y) +#define at91_set_gpio_value(x, y) \ + at91_set_pio_value((x - PIN_BASE) / 32,(x % 32), y) +#define at91_get_gpio_value(x) \ + at91_get_pio_value((x - PIN_BASE) / 32,(x % 32)) +#else +#define at91_set_gpio_value(x, y) at91_set_pio_value(x, y) +#define at91_get_gpio_value(x) at91_get_pio_value(x) +#endif + +#define GPIO_PIOA_BASE (0) +#define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32) +#define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32) +#define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32) +#define GPIO_PIOE_BASE (GPIO_PIOD_BASE + 32) +#define GPIO_PIN_PA(x) (GPIO_PIOA_BASE + (x)) +#define GPIO_PIN_PB(x) (GPIO_PIOB_BASE + (x)) +#define GPIO_PIN_PC(x) (GPIO_PIOC_BASE + (x)) +#define GPIO_PIN_PD(x) (GPIO_PIOD_BASE + (x)) +#define GPIO_PIN_PE(x) (GPIO_PIOE_BASE + (x)) + +static inline unsigned at91_gpio_to_port(unsigned gpio) +{ + return gpio / 32; +} + +static inline unsigned at91_gpio_to_pin(unsigned gpio) +{ + return gpio % 32; +} + +/* Platform data for each GPIO port */ +struct at91_port_platdata { + uint32_t base_addr; + const char *bank_name; +}; + +#endif /* __ASM_ARCH_AT91_GPIO_H */ diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h new file mode 100644 index 0000000000..ff6b71b135 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2007-2008 + * Stelian Pop + * Lead Tech Design + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARM_ARCH_HARDWARE_H__ +#define __ASM_ARM_ARCH_HARDWARE_H__ + +#if defined(CONFIG_AT91RM9200) +# include +#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20) || \ + defined(CONFIG_AT91SAM9XE) +# include +#elif defined(CONFIG_AT91SAM9261) || defined(CONFIG_AT91SAM9G10) +# include +#elif defined(CONFIG_AT91SAM9263) +# include +#elif defined(CONFIG_AT91SAM9RL) +# include +#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) +# include +#elif defined(CONFIG_AT91SAM9N12) || defined(CONFIG_AT91SAM9X5) +# include +#elif defined(CONFIG_SAMA5D3) +# include +#elif defined(CONFIG_SAMA5D4) +# include +#else +# error "Unsupported AT91 processor" +#endif + +#endif /* __ASM_ARM_ARCH_HARDWARE_H__ */ diff --git a/arch/arm/mach-at91/include/mach/sama5_matrix.h b/arch/arm/mach-at91/include/mach/sama5_matrix.h new file mode 100644 index 0000000000..e324766733 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5_matrix.h @@ -0,0 +1,37 @@ +/* + * Bus Matrix header file for the SAMA5 family + * + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SAMA5_MATRIX_H +#define __SAMA5_MATRIX_H + +struct atmel_matrix { + u32 mcfg[16]; /* 0x00 ~ 0x3c: Master Configuration Register */ + u32 scfg[16]; /* 0x40 ~ 0x7c: Slave Configuration Register */ + u32 pras[16][2];/* 0x80 ~ 0xfc: Priority Register A/B */ + u32 res1[20]; /* 0x100 ~ 0x14c */ + u32 meier; /* 0x150: Master Error Interrupt Enable Register */ + u32 meidr; /* 0x154: Master Error Interrupt Disable Register */ + u32 meimr; /* 0x158: Master Error Interrupt Mask Register */ + u32 mesr; /* 0x15c: Master Error Status Register */ + u32 mear[16]; /* 0x160 ~ 0x19c: Master Error Address Register */ + u32 res2[17]; /* 0x1A0 ~ 0x1E0 */ + u32 wpmr; /* 0x1E4: Write Protection Mode Register */ + u32 wpsr; /* 0x1E8: Write Protection Status Register */ + u32 res3[5]; /* 0x1EC ~ 0x1FC */ + u32 ssr[16]; /* 0x200 ~ 0x23c: Security Slave Register */ + u32 sassr[16]; /* 0x240 ~ 0x27c: Security Areas Split Slave Register */ + u32 srtsr[16]; /* 0x280 ~ 0x2bc: Security Region Top Slave */ + u32 spselr[3]; /* 0x2c0 ~ 0x2c8: Security Peripheral Select Register */ +}; + +/* Bit field in WPMR */ +#define ATMEL_MATRIX_WPMR_WPKEY 0x4D415400 +#define ATMEL_MATRIX_WPMR_WPEN 0x00000001 + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5_sfr.h b/arch/arm/mach-at91/include/mach/sama5_sfr.h new file mode 100644 index 0000000000..3081d37571 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5_sfr.h @@ -0,0 +1,38 @@ +/* + * Special Function Register (SFR) + * + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SAMA5_SFR_H +#define __SAMA5_SFR_H + +struct atmel_sfr { + u32 reserved1; /* 0x00 */ + u32 ddrcfg; /* 0x04: DDR Configuration Register */ + u32 reserved2; /* 0x08 */ + u32 reserved3; /* 0x0c */ + u32 ohciicr; /* 0x10: OHCI Interrupt Configuration Register */ + u32 ohciisr; /* 0x14: OHCI Interrupt Status Register */ + u32 reserved4[4]; /* 0x18 ~ 0x24 */ + u32 secure; /* 0x28: Security Configuration Register */ + u32 reserved5[5]; /* 0x2c ~ 0x3c */ + u32 ebicfg; /* 0x40: EBI Configuration Register */ + u32 reserved6[2]; /* 0x44 ~ 0x48 */ + u32 sn0; /* 0x4c */ + u32 sn1; /* 0x50 */ + u32 aicredir; /* 0x54 */ +}; + +/* Bit field in DDRCFG */ +#define ATMEL_SFR_DDRCFG_FDQIEN 0x00010000 +#define ATMEL_SFR_DDRCFG_FDQSIEN 0x00020000 + +/* Bit field in AICREDIR */ +#define ATMEL_SFR_AICREDIR_KEY 0x5F67B102 +#define ATMEL_SFR_AICREDIR_NSAIC 0x00000001 + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h new file mode 100644 index 0000000000..227ba80825 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -0,0 +1,210 @@ +/* + * Chip-specific header file for the SAMA5D3 family + * + * (C) 2012 - 2013 Atmel Corporation. + * Bo Shen + * + * Definitions for the SoC: + * SAMA5D3 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef SAMA5D3_H +#define SAMA5D3_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* it's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define ATMEL_ID_SYS 1 /* System Controller Interrupt */ +#define ATMEL_ID_DBGU 2 /* Debug Unit Interrupt */ +#define ATMEL_ID_PIT 3 /* Periodic Interval Timer Interrupt */ +#define ATMEL_ID_WDT 4 /* Watchdog timer Interrupt */ +#define ATMEL_ID_SMC 5 /* Multi-bit ECC Interrupt */ +#define ATMEL_ID_PIOA 6 /* Parallel I/O Controller A */ +#define ATMEL_ID_PIOB 7 /* Parallel I/O Controller B */ +#define ATMEL_ID_PIOC 8 /* Parallel I/O Controller C */ +#define ATMEL_ID_PIOD 9 /* Parallel I/O Controller D */ +#define ATMEL_ID_PIOE 10 /* Parallel I/O Controller E */ +#define ATMEL_ID_SMD 11 /* SMD Soft Modem */ +#define ATMEL_ID_USART0 12 /* USART 0 */ +#define ATMEL_ID_USART1 13 /* USART 1 */ +#define ATMEL_ID_USART2 14 /* USART 2 */ +#define ATMEL_ID_USART3 15 /* USART 3 */ +#define ATMEL_ID_UART0 16 +#define ATMEL_ID_UART1 17 +#define ATMEL_ID_TWI0 18 /* Two-Wire Interface 0 */ +#define ATMEL_ID_TWI1 19 /* Two-Wire Interface 1 */ +#define ATMEL_ID_TWI2 20 /* Two-Wire Interface 2 */ +#define ATMEL_ID_MCI0 21 /* High Speed Multimedia Card Interface 0 */ +#define ATMEL_ID_MCI1 22 /* */ +#define ATMEL_ID_MCI2 23 /* */ +#define ATMEL_ID_SPI0 24 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 25 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_TC0 26 /* */ +#define ATMEL_ID_TC1 27 /* */ +#define ATMEL_ID_PWMC 28 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_TSC 29 /* Touch Screen ADC Controller */ +#define ATMEL_ID_DMA0 30 /* DMA Controller */ +#define ATMEL_ID_DMA1 31 /* DMA Controller */ +#define ATMEL_ID_UHPHS 32 /* USB Host High Speed */ +#define ATMEL_ID_UDPHS 33 /* USB Device High Speed */ +#define ATMEL_ID_GMAC 34 +#define ATMEL_ID_EMAC 35 /* Ethernet MAC */ +#define ATMEL_ID_LCDC 36 /* LCD Controller */ +#define ATMEL_ID_ISI 37 /* Image Sensor Interface */ +#define ATMEL_ID_SSC0 38 /* Synchronous Serial Controller 0 */ +#define ATMEL_ID_SSC1 39 /* Synchronous Serial Controller 1 */ +#define ATMEL_ID_CAN0 40 +#define ATMEL_ID_CAN1 41 +#define ATMEL_ID_SHA 42 +#define ATMEL_ID_AES 43 +#define ATMEL_ID_TDES 44 +#define ATMEL_ID_TRNG 45 +#define ATMEL_ID_ARM 46 +#define ATMEL_ID_IRQ0 47 /* Advanced Interrupt Controller */ +#define ATMEL_ID_FUSE 48 +#define ATMEL_ID_MPDDRC 49 + +/* sama5d3 series chip id definitions */ +#define ARCH_ID_SAMA5D3 0x8a5c07c0 +#define ARCH_EXID_SAMA5D31 0x00444300 +#define ARCH_EXID_SAMA5D33 0x00414300 +#define ARCH_EXID_SAMA5D34 0x00414301 +#define ARCH_EXID_SAMA5D35 0x00584300 +#define ARCH_EXID_SAMA5D36 0x00004301 + +#define cpu_is_sama5d3() (get_chip_id() == ARCH_ID_SAMA5D3) +#define cpu_is_sama5d31() (cpu_is_sama5d3() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D31)) +#define cpu_is_sama5d33() (cpu_is_sama5d3() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D33)) +#define cpu_is_sama5d34() (cpu_is_sama5d3() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D34)) +#define cpu_is_sama5d35() (cpu_is_sama5d3() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D35)) +#define cpu_is_sama5d36() (cpu_is_sama5d3() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D36)) + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_MCI0 0xf0000000 +#define ATMEL_BASE_SPI0 0xf0004000 +#define ATMEL_BASE_SSC0 0xf000C000 +#define ATMEL_BASE_TC2 0xf0010000 +#define ATMEL_BASE_TWI0 0xf0014000 +#define ATMEL_BASE_TWI1 0xf0018000 +#define ATMEL_BASE_USART0 0xf001c000 +#define ATMEL_BASE_USART1 0xf0020000 +#define ATMEL_BASE_UART0 0xf0024000 +#define ATMEL_BASE_GMAC 0xf0028000 +#define ATMEL_BASE_PWMC 0xf002c000 +#define ATMEL_BASE_LCDC 0xf0030000 +#define ATMEL_BASE_ISI 0xf0034000 +#define ATMEL_BASE_SFR 0xf0038000 +/* Reserved: 0xf003c000 - 0xf8000000 */ +#define ATMEL_BASE_MCI1 0xf8000000 +#define ATMEL_BASE_MCI2 0xf8004000 +#define ATMEL_BASE_SPI1 0xf8008000 +#define ATMEL_BASE_SSC1 0xf800c000 +#define ATMEL_BASE_CAN1 0xf8010000 +#define ATMEL_BASE_TC3 0xf8014000 +#define ATMEL_BASE_TSADC 0xf8018000 +#define ATMEL_BASE_TWI2 0xf801c000 +#define ATMEL_BASE_USART2 0xf8020000 +#define ATMEL_BASE_USART3 0xf8024000 +#define ATMEL_BASE_UART1 0xf8028000 +#define ATMEL_BASE_EMAC 0xf802c000 +#define ATMEL_BASE_UDPHS 0xf8030000 +#define ATMEL_BASE_SHA 0xf8034000 +#define ATMEL_BASE_AES 0xf8038000 +#define ATMEL_BASE_TDES 0xf803c000 +#define ATMEL_BASE_TRNG 0xf8040000 +/* Reserved: 0xf804400 - 0xffffc00 */ + +/* + * System Peripherals physical base addresses. + */ +#define ATMEL_BASE_SYS 0xffffc000 +#define ATMEL_BASE_SMC 0xffffc000 +#define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) +#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) +#define ATMEL_BASE_FUSE 0xffffe400 +#define ATMEL_BASE_DMAC0 0xffffe600 +#define ATMEL_BASE_DMAC1 0xffffe800 +#define ATMEL_BASE_MPDDRC 0xffffea00 +#define ATMEL_BASE_MATRIX 0xffffec00 +#define ATMEL_BASE_DBGU 0xffffee00 +#define ATMEL_BASE_AIC 0xfffff000 +#define ATMEL_BASE_PIOA 0xfffff200 +#define ATMEL_BASE_PIOB 0xfffff400 +#define ATMEL_BASE_PIOC 0xfffff600 +#define ATMEL_BASE_PIOD 0xfffff800 +#define ATMEL_BASE_PIOE 0xfffffa00 +#define ATMEL_BASE_PMC 0xfffffc00 +#define ATMEL_BASE_RSTC 0xfffffe00 +#define ATMEL_BASE_SHDWN 0xfffffe10 +#define ATMEL_BASE_PIT 0xfffffe30 +#define ATMEL_BASE_WDT 0xfffffe40 +#define ATMEL_BASE_SCKCR 0xfffffe50 +#define ATMEL_BASE_GPBR 0xfffffe60 +#define ATMEL_BASE_RTC 0xfffffeb0 +/* Reserved: 0xfffffee0 - 0xffffffff */ + +/* + * Internal Memory. + */ +#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM 0x00200000 /* Internal ROM base address */ +#define ATMEL_BASE_SRAM0 0x00300000 /* Internal SRAM base address */ +#define ATMEL_BASE_SRAM1 0x00310000 /* Internal SRAM base address */ +#define ATMEL_BASE_SMD 0x00400000 /* Internal ROM base address */ +#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */ +#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */ +#define ATMEL_BASE_AXI 0x00800000 /* Video Decoder Controller */ +#define ATMEL_BASE_DAP 0x00900000 /* Video Decoder Controller */ + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_DDRCS 0x20000000 +#define ATMEL_BASE_CS1 0x40000000 +#define ATMEL_BASE_CS2 0x50000000 +#define ATMEL_BASE_CS3 0x60000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 5 +#define CPU_HAS_PIO3 +#define PIO_SCDR_DIV 0x3fff +#define CPU_HAS_PCR + +/* + * PMECC table in ROM + */ +#define ATMEL_PMECC_INDEX_OFFSET_512 0x10000 +#define ATMEL_PMECC_INDEX_OFFSET_1024 0x18000 + +/* + * SAMA5D3 specific prototypes + */ +#ifndef __ASSEMBLY__ +unsigned int get_chip_id(void); +unsigned int get_extension_chip_id(void); +unsigned int has_emac(void); +unsigned int has_gmac(void); +unsigned int has_lcdc(void); +char *get_cpu_name(void); +#endif + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5d3_smc.h b/arch/arm/mach-at91/include/mach/sama5d3_smc.h new file mode 100644 index 0000000000..a859b6db9b --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d3_smc.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 Atmel Corporation. + * + * Static Memory Controllers (SMC) - System peripherals registers. + * Based on SAMA5D3 datasheet. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef SAMA5D3_SMC_H +#define SAMA5D3_SMC_H + +#ifdef __ASSEMBLY__ +#define AT91_ASM_SMC_SETUP0 (ATMEL_BASE_SMC + 0x600) +#define AT91_ASM_SMC_PULSE0 (ATMEL_BASE_SMC + 0x604) +#define AT91_ASM_SMC_CYCLE0 (ATMEL_BASE_SMC + 0x608) +#define AT91_ASM_SMC_TIMINGS0 (ATMEL_BASE_SMC + 0x60c) +#define AT91_ASM_SMC_MODE0 (ATMEL_BASE_SMC + 0x610) +#else +struct at91_cs { + u32 setup; /* 0x600 SMC Setup Register */ + u32 pulse; /* 0x604 SMC Pulse Register */ + u32 cycle; /* 0x608 SMC Cycle Register */ + u32 timings; /* 0x60C SMC Cycle Register */ + u32 mode; /* 0x610 SMC Mode Register */ +}; + +struct at91_smc { + u32 reserved[384]; + struct at91_cs cs[4]; +}; +#endif /* __ASSEMBLY__ */ + +#define AT91_SMC_SETUP_NWE(x) (x & 0x3f) +#define AT91_SMC_SETUP_NCS_WR(x) ((x & 0x3f) << 8) +#define AT91_SMC_SETUP_NRD(x) ((x & 0x3f) << 16) +#define AT91_SMC_SETUP_NCS_RD(x) ((x & 0x3f) << 24) + +#define AT91_SMC_PULSE_NWE(x) (x & 0x3f) +#define AT91_SMC_PULSE_NCS_WR(x) ((x & 0x3f) << 8) +#define AT91_SMC_PULSE_NRD(x) ((x & 0x3f) << 16) +#define AT91_SMC_PULSE_NCS_RD(x) ((x & 0x3f) << 24) + +#define AT91_SMC_CYCLE_NWE(x) (x & 0x1ff) +#define AT91_SMC_CYCLE_NRD(x) ((x & 0x1ff) << 16) + +#define AT91_SMC_TIMINGS_TCLR(x) (x & 0xf) +#define AT91_SMC_TIMINGS_TADL(x) ((x & 0xf) << 4) +#define AT91_SMC_TIMINGS_TAR(x) ((x & 0xf) << 8) +#define AT91_SMC_TIMINGS_OCMS(x) ((x & 0x1) << 12) +#define AT91_SMC_TIMINGS_TRR(x) ((x & 0xf) << 16) +#define AT91_SMC_TIMINGS_TWB(x) ((x & 0xf) << 24) +#define AT91_SMC_TIMINGS_RBNSEL(x) ((x & 0xf) << 28) +#define AT91_SMC_TIMINGS_NFSEL(x) ((x & 0x1) << 31) + +#define AT91_SMC_MODE_RM_NCS 0x00000000 +#define AT91_SMC_MODE_RM_NRD 0x00000001 +#define AT91_SMC_MODE_WM_NCS 0x00000000 +#define AT91_SMC_MODE_WM_NWE 0x00000002 + +#define AT91_SMC_MODE_EXNW_DISABLE 0x00000000 +#define AT91_SMC_MODE_EXNW_FROZEN 0x00000020 +#define AT91_SMC_MODE_EXNW_READY 0x00000030 + +#define AT91_SMC_MODE_BAT 0x00000100 +#define AT91_SMC_MODE_DBW_8 0x00000000 +#define AT91_SMC_MODE_DBW_16 0x00001000 +#define AT91_SMC_MODE_DBW_32 0x00002000 +#define AT91_SMC_MODE_TDF_CYCLE(x) ((x & 0xf) << 16) +#define AT91_SMC_MODE_TDF 0x00100000 +#define AT91_SMC_MODE_PMEN 0x01000000 +#define AT91_SMC_MODE_PS_4 0x00000000 +#define AT91_SMC_MODE_PS_8 0x10000000 +#define AT91_SMC_MODE_PS_16 0x20000000 +#define AT91_SMC_MODE_PS_32 0x30000000 + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5d4.h b/arch/arm/mach-at91/include/mach/sama5d4.h new file mode 100644 index 0000000000..f30cb5fed1 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d4.h @@ -0,0 +1,208 @@ +/* + * Chip-specific header file for the SAMA5D4 SoC + * + * Copyright (C) 2014 Atmel + * Bo Shen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __SAMA5D4_H +#define __SAMA5D4_H + +/* + * defines to be used in other places + */ +#define CONFIG_AT91FAMILY /* It's a member of AT91 */ + +/* + * Peripheral identifiers/interrupts. + */ +#define ATMEL_ID_FIQ 0 /* FIQ Interrupt */ +#define ATMEL_ID_SYS 1 /* System Controller */ +#define ATMEL_ID_ARM 2 /* Performance Monitor Unit */ +#define ATMEL_ID_PIT 3 /* Periodic Interval Timer */ +#define ATMEL_ID_WDT 4 /* Watchdog timer */ +#define ATMEL_ID_PIOD 5 /* Parallel I/O Controller D */ +#define ATMEL_ID_USART0 6 /* USART 0 */ +#define ATMEL_ID_USART1 7 /* USART 1 */ +#define ATMEL_ID_DMA0 8 /* DMA Controller 0 */ +#define ATMEL_ID_ICM 9 /* Integrity Check Monitor */ +#define ATMEL_ID_PKCC 10 /* Public Key Crypto Controller */ +#define ATMEL_ID_AES 12 /* Advanced Encryption Standard */ +#define ATMEL_ID_AESB 13 /* AES Bridge*/ +#define ATMEL_ID_TDES 14 /* Triple Data Encryption Standard */ +#define ATMEL_ID_SHA 15 /* SHA Signature */ +#define ATMEL_ID_MPDDRC 16 /* MPDDR controller */ +#define ATMEL_ID_MATRIX1 17 /* H32MX, 32-bit AHB Matrix */ +#define ATMEL_ID_MATRIX0 18 /* H64MX, 64-bit AHB Matrix */ +#define ATMEL_ID_VDEC 19 /* Video Decoder */ +#define ATMEL_ID_SBM 20 /* Secure Box Module */ +#define ATMEL_ID_SMC 22 /* Multi-bit ECC interrupt */ +#define ATMEL_ID_PIOA 23 /* Parallel I/O Controller A */ +#define ATMEL_ID_PIOB 24 /* Parallel I/O Controller B */ +#define ATMEL_ID_PIOC 25 /* Parallel I/O Controller C */ +#define ATMEL_ID_PIOE 26 /* Parallel I/O Controller E */ +#define ATMEL_ID_UART0 27 /* UART 0 */ +#define ATMEL_ID_UART1 28 /* UART 1 */ +#define ATMEL_ID_USART2 29 /* USART 2 */ +#define ATMEL_ID_USART3 30 /* USART 3 */ +#define ATMEL_ID_USART4 31 /* USART 4 */ +#define ATMEL_ID_TWI0 32 /* Two-Wire Interface 0 */ +#define ATMEL_ID_TWI1 33 /* Two-Wire Interface 1 */ +#define ATMEL_ID_TWI2 34 /* Two-Wire Interface 2 */ +#define ATMEL_ID_MCI0 35 /* High Speed Multimedia Card Interface 0 */ +#define ATMEL_ID_MCI1 36 /* High Speed Multimedia Card Interface 1 */ +#define ATMEL_ID_SPI0 37 /* Serial Peripheral Interface 0 */ +#define ATMEL_ID_SPI1 38 /* Serial Peripheral Interface 1 */ +#define ATMEL_ID_SPI2 39 /* Serial Peripheral Interface 2 */ +#define ATMEL_ID_TC0 40 /* Timer Counter 0 (ch. 0, 1, 2) */ +#define ATMEL_ID_TC1 41 /* Timer Counter 1 (ch. 3, 4, 5) */ +#define ATMEL_ID_TC2 42 /* Timer Counter 2 (ch. 6, 7, 8) */ +#define ATMEL_ID_PWMC 43 /* Pulse Width Modulation Controller */ +#define ATMEL_ID_ADC 44 /* Touch Screen ADC Controller */ +#define ATMEL_ID_DBGU 45 /* Debug Unit Interrupt */ +#define ATMEL_ID_UHPHS 46 /* USB Host High Speed */ +#define ATMEL_ID_UDPHS 47 /* USB Device High Speed */ +#define ATMEL_ID_SSC0 48 /* Synchronous Serial Controller 0 */ +#define ATMEL_ID_SSC1 49 /* Synchronous Serial Controller 1 */ +#define ATMEL_ID_XDMAC1 50 /* DMA Controller 1 */ +#define ATMEL_ID_LCDC 51 /* LCD Controller */ +#define ATMEL_ID_ISI 52 /* Image Sensor Interface */ +#define ATMEL_ID_TRNG 53 /* True Random Number Generator */ +#define ATMEL_ID_GMAC0 54 /* Ethernet MAC 0 */ +#define ATMEL_ID_GMAC1 55 /* Ethernet MAC 1 */ +#define ATMEL_ID_IRQ 56 /* IRQ Interrupt ID */ +#define ATMEL_ID_SFC 57 /* Fuse Controller */ +#define ATMEL_ID_SECURAM 59 /* Secured RAM */ +#define ATMEL_ID_SMD 61 /* SMD Soft Modem */ +#define ATMEL_ID_TWI3 62 /* Two-Wire Interface 3 */ +#define ATMEL_ID_CATB 63 /* Capacitive Touch Controller */ +#define ATMEL_ID_SFR 64 /* Special Funcion Register */ +#define ATMEL_ID_AIC 65 /* Advanced Interrupt Controller */ +#define ATMEL_ID_SAIC 66 /* Secured Advanced Interrupt Controller */ +#define ATMEL_ID_L2CC 67 /* L2 Cache Controller */ + +/* + * User Peripherals physical base addresses. + */ +#define ATMEL_BASE_LCDC 0xf0000000 +#define ATMEL_BASE_DMAC1 0xf0004000 +#define ATMEL_BASE_ISI 0xf0008000 +#define ATMEL_BASE_PKCC 0xf000C000 +#define ATMEL_BASE_MPDDRC 0xf0010000 +#define ATMEL_BASE_DMAC0 0xf0014000 +#define ATMEL_BASE_PMC 0xf0018000 +#define ATMEL_BASE_MATRIX0 0xf001c000 +#define ATMEL_BASE_AESB 0xf0020000 +/* Reserved: 0xf0024000 - 0xf8000000 */ +#define ATMEL_BASE_MCI0 0xf8000000 +#define ATMEL_BASE_UART0 0xf8004000 +#define ATMEL_BASE_SSC0 0xf8008000 +#define ATMEL_BASE_PWMC 0xf800c000 +#define ATMEL_BASE_SPI0 0xf8010000 +#define ATMEL_BASE_TWI0 0xf8014000 +#define ATMEL_BASE_TWI1 0xf8018000 +#define ATMEL_BASE_TC0 0xf801c000 +#define ATMEL_BASE_GMAC0 0xf8020000 +#define ATMEL_BASE_TWI2 0xf8024000 +#define ATMEL_BASE_SFR 0xf8028000 +#define ATMEL_BASE_USART0 0xf802c000 +#define ATMEL_BASE_USART1 0xf8030000 +/* Reserved: 0xf8034000 - 0xfc000000 */ +#define ATMEL_BASE_MCI1 0xfc000000 +#define ATMEL_BASE_UART1 0xfc004000 +#define ATMEL_BASE_USART2 0xfc008000 +#define ATMEL_BASE_USART3 0xfc00c000 +#define ATMEL_BASE_USART4 0xfc010000 +#define ATMEL_BASE_SSC1 0xfc014000 +#define ATMEL_BASE_SPI1 0xfc018000 +#define ATMEL_BASE_SPI2 0xfc01c000 +#define ATMEL_BASE_TC1 0xfc020000 +#define ATMEL_BASE_TC2 0xfc024000 +#define ATMEL_BASE_GMAC1 0xfc028000 +#define ATMEL_BASE_UDPHS 0xfc02c000 +#define ATMEL_BASE_TRNG 0xfc030000 +#define ATMEL_BASE_ADC 0xfc034000 +#define ATMEL_BASE_TWI3 0xfc038000 + +#define ATMEL_BASE_MATRIX1 0xfc054000 + +#define ATMEL_BASE_SMC 0xfc05c000 +#define ATMEL_BASE_PMECC (ATMEL_BASE_SMC + 0x070) +#define ATMEL_BASE_PMERRLOC (ATMEL_BASE_SMC + 0x500) + +#define ATMEL_BASE_PIOD 0xfc068000 +#define ATMEL_BASE_RSTC 0xfc068600 +#define ATMEL_BASE_PIT 0xfc068630 +#define ATMEL_BASE_WDT 0xfc068640 + +#define ATMEL_BASE_DBGU 0xfc069000 +#define ATMEL_BASE_PIOA 0xfc06a000 +#define ATMEL_BASE_PIOB 0xfc06b000 +#define ATMEL_BASE_PIOC 0xfc06c000 +#define ATMEL_BASE_PIOE 0xfc06d000 +#define ATMEL_BASE_AIC 0xfc06e000 + +/* + * Internal Memory. + */ +#define ATMEL_BASE_ROM 0x00000000 /* Internal ROM base address */ +#define ATMEL_BASE_NFC 0x00100000 /* NFC SRAM */ +#define ATMEL_BASE_SRAM 0x00200000 /* Internal ROM base address */ +#define ATMEL_BASE_VDEC 0x00300000 /* Video Decoder Controller */ +#define ATMEL_BASE_UDPHS_FIFO 0x00400000 /* USB Device HS controller */ +#define ATMEL_BASE_OHCI 0x00500000 /* USB Host controller (OHCI) */ +#define ATMEL_BASE_EHCI 0x00600000 /* USB Host controller (EHCI) */ +#define ATMEL_BASE_AXI 0x00700000 +#define ATMEL_BASE_DAP 0x00800000 +#define ATMEL_BASE_SMD 0x00900000 + +/* + * External memory + */ +#define ATMEL_BASE_CS0 0x10000000 +#define ATMEL_BASE_DDRCS 0x20000000 +#define ATMEL_BASE_CS1 0x60000000 +#define ATMEL_BASE_CS2 0x70000000 +#define ATMEL_BASE_CS3 0x80000000 + +/* + * Other misc defines + */ +#define ATMEL_PIO_PORTS 5 +#define CPU_HAS_PIO3 +#define PIO_SCDR_DIV 0x3fff +#define CPU_HAS_PCR +#define CPU_HAS_H32MXDIV + +/* sama5d4 series chip id definitions */ +#define ARCH_ID_SAMA5D4 0x8a5c07c0 +#define ARCH_EXID_SAMA5D41 0x00000001 +#define ARCH_EXID_SAMA5D42 0x00000002 +#define ARCH_EXID_SAMA5D43 0x00000003 +#define ARCH_EXID_SAMA5D44 0x00000004 + +#define cpu_is_sama5d4() (get_chip_id() == ARCH_ID_SAMA5D4) +#define cpu_is_sama5d41() (cpu_is_sama5d4() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D41)) +#define cpu_is_sama5d42() (cpu_is_sama5d4() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D42)) +#define cpu_is_sama5d43() (cpu_is_sama5d4() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D43)) +#define cpu_is_sama5d44() (cpu_is_sama5d4() && \ + (get_extension_chip_id() == ARCH_EXID_SAMA5D44)) + +/* + * No PMECC Galois table in ROM + */ +#define NO_GALOIS_TABLE_IN_ROM + +#ifndef __ASSEMBLY__ +unsigned int get_chip_id(void); +unsigned int get_extension_chip_id(void); +unsigned int has_lcdc(void); +char *get_cpu_name(void); +#endif + +#endif -- cgit From 3d357619a509eb2b39dc5056731ca08bc2b23e62 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:14 +0900 Subject: ARM: davinci: move SoC headers to mach-davinci/include/mach Move arch/arm/include/asm/arch-davinci/* -> arch/arm/mach-davinci/include/mach/* Signed-off-by: Masahiro Yamada Cc: Tom Rini --- arch/arm/include/asm/arch-davinci/aintc_defs.h | 36 -- arch/arm/include/asm/arch-davinci/da850_lowlevel.h | 35 -- arch/arm/include/asm/arch-davinci/da8xx-usb.h | 93 ---- arch/arm/include/asm/arch-davinci/davinci_misc.h | 51 -- arch/arm/include/asm/arch-davinci/ddr2_defs.h | 84 --- arch/arm/include/asm/arch-davinci/dm365_lowlevel.h | 25 - arch/arm/include/asm/arch-davinci/emac_defs.h | 94 ---- arch/arm/include/asm/arch-davinci/gpio.h | 67 --- arch/arm/include/asm/arch-davinci/hardware.h | 616 --------------------- arch/arm/include/asm/arch-davinci/i2c_defs.h | 18 - arch/arm/include/asm/arch-davinci/pinmux_defs.h | 57 -- arch/arm/include/asm/arch-davinci/pll_defs.h | 83 --- arch/arm/include/asm/arch-davinci/psc_defs.h | 70 --- arch/arm/include/asm/arch-davinci/sdmmc_defs.h | 164 ------ arch/arm/include/asm/arch-davinci/syscfg_defs.h | 50 -- arch/arm/include/asm/arch-davinci/timer_defs.h | 44 -- arch/arm/mach-davinci/include/mach/aintc_defs.h | 36 ++ .../arm/mach-davinci/include/mach/da850_lowlevel.h | 35 ++ arch/arm/mach-davinci/include/mach/da8xx-usb.h | 93 ++++ arch/arm/mach-davinci/include/mach/davinci_misc.h | 51 ++ arch/arm/mach-davinci/include/mach/ddr2_defs.h | 84 +++ .../arm/mach-davinci/include/mach/dm365_lowlevel.h | 25 + arch/arm/mach-davinci/include/mach/emac_defs.h | 94 ++++ arch/arm/mach-davinci/include/mach/gpio.h | 67 +++ arch/arm/mach-davinci/include/mach/hardware.h | 616 +++++++++++++++++++++ arch/arm/mach-davinci/include/mach/i2c_defs.h | 18 + arch/arm/mach-davinci/include/mach/pinmux_defs.h | 57 ++ arch/arm/mach-davinci/include/mach/pll_defs.h | 83 +++ arch/arm/mach-davinci/include/mach/psc_defs.h | 70 +++ arch/arm/mach-davinci/include/mach/sdmmc_defs.h | 164 ++++++ arch/arm/mach-davinci/include/mach/syscfg_defs.h | 50 ++ arch/arm/mach-davinci/include/mach/timer_defs.h | 44 ++ 32 files changed, 1587 insertions(+), 1587 deletions(-) delete mode 100644 arch/arm/include/asm/arch-davinci/aintc_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/da850_lowlevel.h delete mode 100644 arch/arm/include/asm/arch-davinci/da8xx-usb.h delete mode 100644 arch/arm/include/asm/arch-davinci/davinci_misc.h delete mode 100644 arch/arm/include/asm/arch-davinci/ddr2_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/dm365_lowlevel.h delete mode 100644 arch/arm/include/asm/arch-davinci/emac_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/gpio.h delete mode 100644 arch/arm/include/asm/arch-davinci/hardware.h delete mode 100644 arch/arm/include/asm/arch-davinci/i2c_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/pinmux_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/pll_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/psc_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/sdmmc_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/syscfg_defs.h delete mode 100644 arch/arm/include/asm/arch-davinci/timer_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/aintc_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/da850_lowlevel.h create mode 100644 arch/arm/mach-davinci/include/mach/da8xx-usb.h create mode 100644 arch/arm/mach-davinci/include/mach/davinci_misc.h create mode 100644 arch/arm/mach-davinci/include/mach/ddr2_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/dm365_lowlevel.h create mode 100644 arch/arm/mach-davinci/include/mach/emac_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/gpio.h create mode 100644 arch/arm/mach-davinci/include/mach/hardware.h create mode 100644 arch/arm/mach-davinci/include/mach/i2c_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/pinmux_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/pll_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/psc_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/sdmmc_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/syscfg_defs.h create mode 100644 arch/arm/mach-davinci/include/mach/timer_defs.h diff --git a/arch/arm/include/asm/arch-davinci/aintc_defs.h b/arch/arm/include/asm/arch-davinci/aintc_defs.h deleted file mode 100644 index 5063e3964c..0000000000 --- a/arch/arm/include/asm/arch-davinci/aintc_defs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _DV_AINTC_DEFS_H_ -#define _DV_AINTC_DEFS_H_ - -struct dv_aintc_regs { - unsigned int fiq0; /* 0x00 */ - unsigned int fiq1; /* 0x04 */ - unsigned int irq0; /* 0x08 */ - unsigned int irq1; /* 0x0c */ - unsigned int fiqentry; /* 0x10 */ - unsigned int irqentry; /* 0x14 */ - unsigned int eint0; /* 0x18 */ - unsigned int eint1; /* 0x1c */ - unsigned int intctl; /* 0x20 */ - unsigned int eabase; /* 0x24 */ - unsigned char rsvd0[8]; /* 0x28 */ - unsigned int intpri0; /* 0x30 */ - unsigned int intpri1; /* 0x34 */ - unsigned int intpri2; /* 0x38 */ - unsigned int intpri3; /* 0x3c */ - unsigned int intpri4; /* 0x40 */ - unsigned int intpri5; /* 0x44 */ - unsigned int intpri6; /* 0x48 */ - unsigned int intpri7; /* 0x4c */ -}; - -#define dv_aintc_regs ((struct dv_aintc_regs *)DAVINCI_ARM_INTC_BASE) - -#define DV_AINTC_INTCTL_IDMODE (1 << 2) - -#endif /* _DV_AINTC_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/da850_lowlevel.h b/arch/arm/include/asm/arch-davinci/da850_lowlevel.h deleted file mode 100644 index 45a325c123..0000000000 --- a/arch/arm/include/asm/arch-davinci/da850_lowlevel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SoC-specific lowlevel code for DA850 - * - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __DA850_LOWLEVEL_H -#define __DA850_LOWLEVEL_H - -#include - -/* pinmux_resource[] vector is defined in the board specific file */ -extern const struct pinmux_resource pinmuxes[]; -extern const int pinmuxes_size; - -extern const struct lpsc_resource lpsc[]; -extern const int lpsc_size; - -/* NOR Boot Configuration Word Field Descriptions */ -#define DA850_NORBOOT_COPY_XK(X) ((X - 1) << 8) -#define DA850_NORBOOT_METHOD_DIRECT (1 << 4) -#define DA850_NORBOOT_16BIT (1 << 0) - -#define dv_maskbits(addr, val) \ - writel((readl(addr) & val), addr) - -void da850_lpc_transition(unsigned char pscnum, unsigned char module, - unsigned char domain, unsigned char state); -void da850_psc_init(void); -void da850_pinmux_ctl(unsigned long offset, unsigned long mask, - unsigned long value); - -#endif /* #ifndef __DA850_LOWLEVEL_H */ diff --git a/arch/arm/include/asm/arch-davinci/da8xx-usb.h b/arch/arm/include/asm/arch-davinci/da8xx-usb.h deleted file mode 100644 index f091e49899..0000000000 --- a/arch/arm/include/asm/arch-davinci/da8xx-usb.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * da8xx-usb.h -- TI's DA8xx platform specific usb wrapper definitions. - * - * Author: Ajay Kumar Gupta - * - * Based on drivers/usb/musb/davinci.h - * - * Copyright (C) 2009 Texas Instruments Incorporated - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __DA8XX_MUSB_H__ -#define __DA8XX_MUSB_H__ - -#include -#include - -/* Base address of da8xx usb0 wrapper */ -#define DA8XX_USB_OTG_BASE 0x01E00000 - -/* Base address of da8xx musb core */ -#define DA8XX_USB_OTG_CORE_BASE (DA8XX_USB_OTG_BASE + 0x400) - -/* Timeout for DA8xx usb module */ -#define DA8XX_USB_OTG_TIMEOUT 0x3FFFFFF - -/* - * DA8xx platform USB wrapper register overlay. - */ -struct da8xx_usb_regs { - dv_reg revision; - dv_reg control; - dv_reg status; - dv_reg emulation; - dv_reg mode; - dv_reg autoreq; - dv_reg srpfixtime; - dv_reg teardown; - dv_reg intsrc; - dv_reg intsrc_set; - dv_reg intsrc_clr; - dv_reg intmsk; - dv_reg intmsk_set; - dv_reg intmsk_clr; - dv_reg intsrcmsk; - dv_reg eoi; - dv_reg intvector; - dv_reg grndis_size[4]; -}; - -#define da8xx_usb_regs ((struct da8xx_usb_regs *)DA8XX_USB_OTG_BASE) - -/* DA8XX interrupt bits definitions */ -#define DA8XX_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */ -#define DA8XX_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */ -#define DA8XX_USB_TXINT_SHIFT 0 -#define DA8XX_USB_RXINT_SHIFT 8 - -#define DA8XX_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */ -#define DA8XX_USB_TXINT_MASK \ - (DA8XX_USB_TX_ENDPTS_MASK << DA8XX_USB_TXINT_SHIFT) -#define DA8XX_USB_RXINT_MASK \ - (DA8XX_USB_RX_ENDPTS_MASK << DA8XX_USB_RXINT_SHIFT) - -/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */ -#define CFGCHIP2_PHYCLKGD (1 << 17) -#define CFGCHIP2_VBUSSENSE (1 << 16) -#define CFGCHIP2_RESET (1 << 15) -#define CFGCHIP2_OTGMODE (3 << 13) -#define CFGCHIP2_NO_OVERRIDE (0 << 13) -#define CFGCHIP2_FORCE_HOST (1 << 13) -#define CFGCHIP2_FORCE_DEVICE (2 << 13) -#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13) -#define CFGCHIP2_USB1PHYCLKMUX (1 << 12) -#define CFGCHIP2_USB2PHYCLKMUX (1 << 11) -#define CFGCHIP2_PHYPWRDN (1 << 10) -#define CFGCHIP2_OTGPWRDN (1 << 9) -#define CFGCHIP2_DATPOL (1 << 8) -#define CFGCHIP2_USB1SUSPENDM (1 << 7) -#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */ -#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */ -#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */ -#define CFGCHIP2_REFFREQ (0xf << 0) -#define CFGCHIP2_REFFREQ_12MHZ (1 << 0) -#define CFGCHIP2_REFFREQ_24MHZ (2 << 0) -#define CFGCHIP2_REFFREQ_48MHZ (3 << 0) - -#define DA8XX_USB_VBUS_GPIO (1 << 15) - -int usb_phy_on(void); -void usb_phy_off(void); - -#endif /* __DA8XX_MUSB_H__ */ diff --git a/arch/arm/include/asm/arch-davinci/davinci_misc.h b/arch/arm/include/asm/arch-davinci/davinci_misc.h deleted file mode 100644 index 03be3882f8..0000000000 --- a/arch/arm/include/asm/arch-davinci/davinci_misc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2008 Lyrtech - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __MISC_H -#define __MISC_H - -/* pin muxer definitions */ -#define PIN_MUX_NUM_FIELDS 8 /* Per register */ -#define PIN_MUX_FIELD_SIZE 4 /* n in bits */ -#define PIN_MUX_FIELD_MASK ((1 << PIN_MUX_FIELD_SIZE) - 1) - -/* pin definition */ -struct pinmux_config { - dv_reg *mux; /* Address of mux register */ - unsigned char value; /* Value to set in field */ - unsigned char field; /* field number */ -}; - -/* pin table definition */ -struct pinmux_resource { - const struct pinmux_config *pins; - const int n_pins; -}; - -#define PINMUX_ITEM(item) { \ - .pins = item, \ - .n_pins = ARRAY_SIZE(item) \ - } - -struct lpsc_resource { - const int lpsc_no; -}; - -int dvevm_read_mac_address(uint8_t *buf); -void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr); -int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins); -int davinci_configure_pin_mux_items(const struct pinmux_resource *item, - int n_items); -#if defined(CONFIG_DRIVER_TI_EMAC) && defined(CONFIG_SOC_DA8XX) -void davinci_emac_mii_mode_sel(int mode_sel); -#endif -#if defined(CONFIG_SOC_DA8XX) -void irq_init(void); -int da8xx_configure_lpsc_items(const struct lpsc_resource *item, - const int n_items); -#endif - -#endif /* __MISC_H */ diff --git a/arch/arm/include/asm/arch-davinci/ddr2_defs.h b/arch/arm/include/asm/arch-davinci/ddr2_defs.h deleted file mode 100644 index 24afd9d526..0000000000 --- a/arch/arm/include/asm/arch-davinci/ddr2_defs.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _DV_DDR2_DEFS_H_ -#define _DV_DDR2_DEFS_H_ - -/* - * DDR2 Memory Ctrl Register structure - * See sprueh7d.pdf for more details. - */ -struct dv_ddr2_regs_ctrl { - unsigned char rsvd0[4]; /* 0x00 */ - unsigned int sdrstat; /* 0x04 */ - unsigned int sdbcr; /* 0x08 */ - unsigned int sdrcr; /* 0x0C */ - unsigned int sdtimr; /* 0x10 */ - unsigned int sdtimr2; /* 0x14 */ - unsigned char rsvd1[4]; /* 0x18 */ - unsigned int sdbcr2; /* 0x1C */ - unsigned int pbbpr; /* 0x20 */ - unsigned char rsvd2[156]; /* 0x24 */ - unsigned int irr; /* 0xC0 */ - unsigned int imr; /* 0xC4 */ - unsigned int imsr; /* 0xC8 */ - unsigned int imcr; /* 0xCC */ - unsigned char rsvd3[20]; /* 0xD0 */ - unsigned int ddrphycr; /* 0xE4 */ - unsigned int ddrphycr2; /* 0xE8 */ - unsigned char rsvd4[4]; /* 0xEC */ -}; - -#define DV_DDR_PHY_PWRDNEN 0x40 -#define DV_DDR_PHY_EXT_STRBEN 0x80 -#define DV_DDR_PHY_RD_LATENCY_SHIFT 0 - -#define DV_DDR_SDTMR1_RFC_SHIFT 25 -#define DV_DDR_SDTMR1_RP_SHIFT 22 -#define DV_DDR_SDTMR1_RCD_SHIFT 19 -#define DV_DDR_SDTMR1_WR_SHIFT 16 -#define DV_DDR_SDTMR1_RAS_SHIFT 11 -#define DV_DDR_SDTMR1_RC_SHIFT 6 -#define DV_DDR_SDTMR1_RRD_SHIFT 3 -#define DV_DDR_SDTMR1_WTR_SHIFT 0 - -#define DV_DDR_SDTMR2_RASMAX_SHIFT 27 -#define DV_DDR_SDTMR2_XP_SHIFT 25 -#define DV_DDR_SDTMR2_ODT_SHIFT 23 -#define DV_DDR_SDTMR2_XSNR_SHIFT 16 -#define DV_DDR_SDTMR2_XSRD_SHIFT 8 -#define DV_DDR_SDTMR2_RTP_SHIFT 5 -#define DV_DDR_SDTMR2_CKE_SHIFT 0 - -#define DV_DDR_SDCR_DDR2TERM1_SHIFT 27 -#define DV_DDR_SDCR_IBANK_POS_SHIFT 26 -#define DV_DDR_SDCR_MSDRAMEN_SHIFT 25 -#define DV_DDR_SDCR_DDRDRIVE1_SHIFT 24 -#define DV_DDR_SDCR_BOOTUNLOCK_SHIFT 23 -#define DV_DDR_SDCR_DDR_DDQS_SHIFT 22 -#define DV_DDR_SDCR_DDR2EN_SHIFT 20 -#define DV_DDR_SDCR_DDRDRIVE0_SHIFT 18 -#define DV_DDR_SDCR_DDREN_SHIFT 17 -#define DV_DDR_SDCR_SDRAMEN_SHIFT 16 -#define DV_DDR_SDCR_TIMUNLOCK_SHIFT 15 -#define DV_DDR_SDCR_BUS_WIDTH_SHIFT 14 -#define DV_DDR_SDCR_CL_SHIFT 9 -#define DV_DDR_SDCR_IBANK_SHIFT 4 -#define DV_DDR_SDCR_PAGESIZE_SHIFT 0 - -#define DV_DDR_SDRCR_LPMODEN (1 << 31) -#define DV_DDR_SDRCR_MCLKSTOPEN (1 << 30) - -#define DV_DDR_SRCR_LPMODEN_SHIFT 31 -#define DV_DDR_SRCR_MCLKSTOPEN_SHIFT 30 - -#define DV_DDR_BOOTUNLOCK (1 << DV_DDR_SDCR_BOOTUNLOCK_SHIFT) -#define DV_DDR_TIMUNLOCK (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT) - -#define dv_ddr2_regs_ctrl \ - ((struct dv_ddr2_regs_ctrl *)DAVINCI_DDR_EMIF_CTRL_BASE) - -#endif /* _DV_DDR2_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/dm365_lowlevel.h b/arch/arm/include/asm/arch-davinci/dm365_lowlevel.h deleted file mode 100644 index 6c0275efa7..0000000000 --- a/arch/arm/include/asm/arch-davinci/dm365_lowlevel.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SoC-specific lowlevel code for tms320dm365 and similar chips - * - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __DM365_LOWLEVEL_H -#define __DM365_LOWLEVEL_H - -#include -#include -#include - -void dm365_waitloop(unsigned long loopcnt); -int dm365_pll1_init(unsigned long pllmult, unsigned long prediv); -int dm365_pll2_init(unsigned long pllm, unsigned long prediv); -int dm365_ddr_setup(void); -void dm365_psc_init(void); -void dm365_pinmux_ctl(unsigned long offset, unsigned long mask, - unsigned long value); -void dm36x_lowlevel_init(ulong bootflag); - -#endif /* #ifndef __DM365_LOWLEVEL_H */ diff --git a/arch/arm/include/asm/arch-davinci/emac_defs.h b/arch/arm/include/asm/arch-davinci/emac_defs.h deleted file mode 100644 index c3f046efa8..0000000000 --- a/arch/arm/include/asm/arch-davinci/emac_defs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2007 Sergey Kubushyn - * - * Based on: - * - * ---------------------------------------------------------------------------- - * - * dm644x_emac.h - * - * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM - * - * Copyright (C) 2005 Texas Instruments. - * - * ---------------------------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Modifications: - * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot. - */ - -#ifndef _DM644X_EMAC_H_ -#define _DM644X_EMAC_H_ - -#include - -#ifdef CONFIG_SOC_DM365 -#define EMAC_BASE_ADDR (0x01d07000) -#define EMAC_WRAPPER_BASE_ADDR (0x01d0a000) -#define EMAC_WRAPPER_RAM_ADDR (0x01d08000) -#define EMAC_MDIO_BASE_ADDR (0x01d0b000) -#define DAVINCI_EMAC_VERSION2 -#elif defined(CONFIG_SOC_DA8XX) -#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE -#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE -#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE -#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE -#define DAVINCI_EMAC_VERSION2 -#else -#define EMAC_BASE_ADDR (0x01c80000) -#define EMAC_WRAPPER_BASE_ADDR (0x01c81000) -#define EMAC_WRAPPER_RAM_ADDR (0x01c82000) -#define EMAC_MDIO_BASE_ADDR (0x01c84000) -#endif - -#ifdef CONFIG_SOC_DM646X -#define DAVINCI_EMAC_VERSION2 -#define DAVINCI_EMAC_GIG_ENABLE -#endif - -#ifdef CONFIG_SOC_DM646X -/* MDIO module input frequency */ -#define EMAC_MDIO_BUS_FREQ 76500000 -/* MDIO clock output frequency */ -#define EMAC_MDIO_CLOCK_FREQ 2500000 /* 2.5 MHz */ -#elif defined(CONFIG_SOC_DM365) -/* MDIO module input frequency */ -#define EMAC_MDIO_BUS_FREQ 121500000 -/* MDIO clock output frequency */ -#define EMAC_MDIO_CLOCK_FREQ 2200000 /* 2.2 MHz */ -#elif defined(CONFIG_SOC_DA8XX) -/* MDIO module input frequency */ -#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID) -/* MDIO clock output frequency */ -#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ -#else -/* MDIO module input frequency */ -#define EMAC_MDIO_BUS_FREQ 99000000 /* PLL/6 - 99 MHz */ -/* MDIO clock output frequency */ -#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ -#endif - -#define PHY_KSZ8873 (0x00221450) -int ksz8873_is_phy_connected(int phy_addr); -int ksz8873_get_link_speed(int phy_addr); -int ksz8873_init_phy(int phy_addr); -int ksz8873_auto_negotiate(int phy_addr); - -#define PHY_LXT972 (0x001378e2) -int lxt972_is_phy_connected(int phy_addr); -int lxt972_get_link_speed(int phy_addr); -int lxt972_init_phy(int phy_addr); -int lxt972_auto_negotiate(int phy_addr); - -#define PHY_DP83848 (0x20005c90) -int dp83848_is_phy_connected(int phy_addr); -int dp83848_get_link_speed(int phy_addr); -int dp83848_init_phy(int phy_addr); -int dp83848_auto_negotiate(int phy_addr); - -#define PHY_ET1011C (0x282f013) -int et1011c_get_link_speed(int phy_addr); - -#endif /* _DM644X_EMAC_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/gpio.h b/arch/arm/include/asm/arch-davinci/gpio.h deleted file mode 100644 index 7da0060cd4..0000000000 --- a/arch/arm/include/asm/arch-davinci/gpio.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 Texas Instruments Incorporated - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _GPIO_DEFS_H_ -#define _GPIO_DEFS_H_ - -#ifndef CONFIG_SOC_DA8XX -#define DAVINCI_GPIO_BINTEN 0x01C67008 -#define DAVINCI_GPIO_BANK01 0x01C67010 -#define DAVINCI_GPIO_BANK23 0x01C67038 -#define DAVINCI_GPIO_BANK45 0x01C67060 -#define DAVINCI_GPIO_BANK67 0x01C67088 - -#else /* CONFIG_SOC_DA8XX */ -#define DAVINCI_GPIO_BINTEN 0x01E26008 -#define DAVINCI_GPIO_BANK01 0x01E26010 -#define DAVINCI_GPIO_BANK23 0x01E26038 -#define DAVINCI_GPIO_BANK45 0x01E26060 -#define DAVINCI_GPIO_BANK67 0x01E26088 -#define DAVINCI_GPIO_BANK8 0x01E260B0 -#endif /* CONFIG_SOC_DA8XX */ - -struct davinci_gpio { - unsigned int dir; - unsigned int out_data; - unsigned int set_data; - unsigned int clr_data; - unsigned int in_data; - unsigned int set_rising; - unsigned int clr_rising; - unsigned int set_falling; - unsigned int clr_falling; - unsigned int intstat; -}; - -struct davinci_gpio_bank { - int num_gpio; - unsigned int irq_num; - unsigned int irq_mask; - unsigned long *in_use; - unsigned long base; -}; - -#define davinci_gpio_bank01 ((struct davinci_gpio *)DAVINCI_GPIO_BANK01) -#define davinci_gpio_bank23 ((struct davinci_gpio *)DAVINCI_GPIO_BANK23) -#define davinci_gpio_bank45 ((struct davinci_gpio *)DAVINCI_GPIO_BANK45) -#define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) -#define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8) - -#define gpio_status() gpio_info() -#define GPIO_NAME_SIZE 20 -#if defined(CONFIG_SOC_DM644X) -/* GPIO0 to GPIO53, omit the V3.3 volts one */ -#define MAX_NUM_GPIOS 70 -#elif defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850) -#define MAX_NUM_GPIOS 128 -#else -#define MAX_NUM_GPIOS 144 -#endif -#define GPIO_BANK(gp) (davinci_gpio_bank01 + ((gp) >> 5)) -#define GPIO_BIT(gp) ((gp) & 0x1F) - -void gpio_info(void); - -#endif diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h deleted file mode 100644 index a4eb0bd89b..0000000000 --- a/arch/arm/include/asm/arch-davinci/hardware.h +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright (C) 2007 Sergey Kubushyn - * - * Based on: - * - * ------------------------------------------------------------------------- - * - * linux/include/asm-arm/arch-davinci/hardware.h - * - * Copyright (C) 2006 Texas Instruments. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include -#include - -#define REG(addr) (*(volatile unsigned int *)(addr)) -#define REG_P(addr) ((volatile unsigned int *)(addr)) - -typedef volatile unsigned int dv_reg; -typedef volatile unsigned int * dv_reg_p; - -/* - * Base register addresses - * - * NOTE: some of these DM6446-specific addresses DO NOT WORK - * on other DaVinci chips. Double check them before you try - * using the addresses ... or PSC module identifiers, etc. - */ -#ifndef CONFIG_SOC_DA8XX - -#define DAVINCI_DMA_3PCC_BASE (0x01c00000) -#define DAVINCI_DMA_3PTC0_BASE (0x01c10000) -#define DAVINCI_DMA_3PTC1_BASE (0x01c10400) -#define DAVINCI_UART0_BASE (0x01c20000) -#define DAVINCI_UART1_BASE (0x01c20400) -#define DAVINCI_TIMER3_BASE (0x01c20800) -#define DAVINCI_I2C_BASE (0x01c21000) -#define DAVINCI_TIMER0_BASE (0x01c21400) -#define DAVINCI_TIMER1_BASE (0x01c21800) -#define DAVINCI_WDOG_BASE (0x01c21c00) -#define DAVINCI_PWM0_BASE (0x01c22000) -#define DAVINCI_PWM1_BASE (0x01c22400) -#define DAVINCI_PWM2_BASE (0x01c22800) -#define DAVINCI_TIMER4_BASE (0x01c23800) -#define DAVINCI_SYSTEM_MODULE_BASE (0x01c40000) -#define DAVINCI_PLL_CNTRL0_BASE (0x01c40800) -#define DAVINCI_PLL_CNTRL1_BASE (0x01c40c00) -#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01c41000) -#define DAVINCI_ARM_INTC_BASE (0x01c48000) -#define DAVINCI_USB_OTG_BASE (0x01c64000) -#define DAVINCI_CFC_ATA_BASE (0x01c66000) -#define DAVINCI_SPI_BASE (0x01c66800) -#define DAVINCI_GPIO_BASE (0x01c67000) -#define DAVINCI_VPSS_REGS_BASE (0x01c70000) -#if !defined(CONFIG_SOC_DM646X) -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000) -#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000) -#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000) -#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000) -#endif -#define DAVINCI_DDR_BASE (0x80000000) - -#ifdef CONFIG_SOC_DM644X -#define DAVINCI_UART2_BASE 0x01c20800 -#define DAVINCI_UHPI_BASE 0x01c67800 -#define DAVINCI_EMAC_CNTRL_REGS_BASE 0x01c80000 -#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x01c81000 -#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x01c82000 -#define DAVINCI_MDIO_CNTRL_REGS_BASE 0x01c84000 -#define DAVINCI_IMCOP_BASE 0x01cc0000 -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01e00000 -#define DAVINCI_VLYNQ_BASE 0x01e01000 -#define DAVINCI_ASP_BASE 0x01e02000 -#define DAVINCI_MMC_SD_BASE 0x01e10000 -#define DAVINCI_MS_BASE 0x01e20000 -#define DAVINCI_VLYNQ_REMOTE_BASE 0x0c000000 - -#elif defined(CONFIG_SOC_DM355) -#define DAVINCI_MMC_SD1_BASE 0x01e00000 -#define DAVINCI_ASP0_BASE 0x01e02000 -#define DAVINCI_ASP1_BASE 0x01e04000 -#define DAVINCI_UART2_BASE 0x01e06000 -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01e10000 -#define DAVINCI_MMC_SD0_BASE 0x01e11000 - -#elif defined(CONFIG_SOC_DM365) -#define DAVINCI_MMC_SD1_BASE 0x01d00000 -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01d10000 -#define DAVINCI_MMC_SD0_BASE 0x01d11000 -#define DAVINCI_DDR_EMIF_CTRL_BASE 0x20000000 -#define DAVINCI_SPI0_BASE 0x01c66000 -#define DAVINCI_SPI1_BASE 0x01c66800 - -#elif defined(CONFIG_SOC_DM646X) -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x20008000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x44000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x46000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x48000000 - -#endif - -#else /* CONFIG_SOC_DA8XX */ - -#define DAVINCI_UART0_BASE 0x01c42000 -#define DAVINCI_UART1_BASE 0x01d0c000 -#define DAVINCI_UART2_BASE 0x01d0d000 -#define DAVINCI_I2C0_BASE 0x01c22000 -#define DAVINCI_I2C1_BASE 0x01e28000 -#define DAVINCI_TIMER0_BASE 0x01c20000 -#define DAVINCI_TIMER1_BASE 0x01c21000 -#define DAVINCI_WDOG_BASE 0x01c21000 -#define DAVINCI_RTC_BASE 0x01c23000 -#define DAVINCI_PLL_CNTRL0_BASE 0x01c11000 -#define DAVINCI_PLL_CNTRL1_BASE 0x01e1a000 -#define DAVINCI_PSC0_BASE 0x01c10000 -#define DAVINCI_PSC1_BASE 0x01e27000 -#define DAVINCI_SPI0_BASE 0x01c41000 -#define DAVINCI_USB_OTG_BASE 0x01e00000 -#define DAVINCI_SPI1_BASE (cpu_is_da830() ? \ - 0x01e12000 : 0x01f0e000) -#define DAVINCI_GPIO_BASE 0x01e26000 -#define DAVINCI_EMAC_CNTRL_REGS_BASE 0x01e23000 -#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x01e22000 -#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x01e20000 -#define DAVINCI_MDIO_CNTRL_REGS_BASE 0x01e24000 -#define DAVINCI_SYSCFG1_BASE 0x01e2c000 -#define DAVINCI_MMC_SD0_BASE 0x01c40000 -#define DAVINCI_MMC_SD1_BASE 0x01e1b000 -#define DAVINCI_TIMER2_BASE 0x01f0c000 -#define DAVINCI_TIMER3_BASE 0x01f0d000 -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x68000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x40000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x60000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x62000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE 0x64000000 -#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE 0x66000000 -#define DAVINCI_DDR_EMIF_CTRL_BASE 0xb0000000 -#define DAVINCI_DDR_EMIF_DATA_BASE 0xc0000000 -#define DAVINCI_INTC_BASE 0xfffee000 -#define DAVINCI_BOOTCFG_BASE 0x01c14000 -#define DAVINCI_LCD_CNTL_BASE 0x01e13000 -#define DAVINCI_L3CBARAM_BASE 0x80000000 -#define JTAG_ID_REG (DAVINCI_BOOTCFG_BASE + 0x18) -#define CHIP_REV_ID_REG (DAVINCI_BOOTCFG_BASE + 0x24) -#define HOST1CFG (DAVINCI_BOOTCFG_BASE + 0x44) -#define PSC0_MDCTL (DAVINCI_PSC0_BASE + 0xa00) - -#define GPIO_BANK0_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x10) -#define GPIO_BANK0_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x14) -#define GPIO_BANK0_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x18) -#define GPIO_BANK0_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x1c) -#define GPIO_BANK2_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x38) -#define GPIO_BANK2_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x3c) -#define GPIO_BANK2_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x40) -#define GPIO_BANK2_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x44) -#define GPIO_BANK6_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x88) -#define GPIO_BANK6_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x8c) -#define GPIO_BANK6_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x90) -#define GPIO_BANK6_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x94) -#endif /* CONFIG_SOC_DA8XX */ - -/* Power and Sleep Controller (PSC) Domains */ -#define DAVINCI_GPSC_ARMDOMAIN 0 -#define DAVINCI_GPSC_DSPDOMAIN 1 - -#ifndef CONFIG_SOC_DA8XX - -#define DAVINCI_LPSC_VPSSMSTR 0 -#define DAVINCI_LPSC_VPSSSLV 1 -#define DAVINCI_LPSC_TPCC 2 -#define DAVINCI_LPSC_TPTC0 3 -#define DAVINCI_LPSC_TPTC1 4 -#define DAVINCI_LPSC_EMAC 5 -#define DAVINCI_LPSC_EMAC_WRAPPER 6 -#define DAVINCI_LPSC_MDIO 7 -#define DAVINCI_LPSC_IEEE1394 8 -#define DAVINCI_LPSC_USB 9 -#define DAVINCI_LPSC_ATA 10 -#define DAVINCI_LPSC_VLYNQ 11 -#define DAVINCI_LPSC_UHPI 12 -#define DAVINCI_LPSC_DDR_EMIF 13 -#define DAVINCI_LPSC_AEMIF 14 -#define DAVINCI_LPSC_MMC_SD 15 -#define DAVINCI_LPSC_MEMSTICK 16 -#define DAVINCI_LPSC_McBSP 17 -#define DAVINCI_LPSC_I2C 18 -#define DAVINCI_LPSC_UART0 19 -#define DAVINCI_LPSC_UART1 20 -#define DAVINCI_LPSC_UART2 21 -#define DAVINCI_LPSC_SPI 22 -#define DAVINCI_LPSC_PWM0 23 -#define DAVINCI_LPSC_PWM1 24 -#define DAVINCI_LPSC_PWM2 25 -#define DAVINCI_LPSC_GPIO 26 -#define DAVINCI_LPSC_TIMER0 27 -#define DAVINCI_LPSC_TIMER1 28 -#define DAVINCI_LPSC_TIMER2 29 -#define DAVINCI_LPSC_SYSTEM_SUBSYS 30 -#define DAVINCI_LPSC_ARM 31 -#define DAVINCI_LPSC_SCR2 32 -#define DAVINCI_LPSC_SCR3 33 -#define DAVINCI_LPSC_SCR4 34 -#define DAVINCI_LPSC_CROSSBAR 35 -#define DAVINCI_LPSC_CFG27 36 -#define DAVINCI_LPSC_CFG3 37 -#define DAVINCI_LPSC_CFG5 38 -#define DAVINCI_LPSC_GEM 39 -#define DAVINCI_LPSC_IMCOP 40 -#define DAVINCI_LPSC_VPSSMASTER 47 -#define DAVINCI_LPSC_MJCP 50 -#define DAVINCI_LPSC_HDVICP 51 - -#define DAVINCI_DM646X_LPSC_EMAC 14 -#define DAVINCI_DM646X_LPSC_UART0 26 -#define DAVINCI_DM646X_LPSC_I2C 31 -#define DAVINCI_DM646X_LPSC_TIMER0 34 - -#else /* CONFIG_SOC_DA8XX */ - -#define DAVINCI_LPSC_TPCC 0 -#define DAVINCI_LPSC_TPTC0 1 -#define DAVINCI_LPSC_TPTC1 2 -#define DAVINCI_LPSC_AEMIF 3 -#define DAVINCI_LPSC_SPI0 4 -#define DAVINCI_LPSC_MMC_SD 5 -#define DAVINCI_LPSC_AINTC 6 -#define DAVINCI_LPSC_ARM_RAM_ROM 7 -#define DAVINCI_LPSC_SECCTL_KEYMGR 8 -#define DAVINCI_LPSC_UART0 9 -#define DAVINCI_LPSC_SCR0 10 -#define DAVINCI_LPSC_SCR1 11 -#define DAVINCI_LPSC_SCR2 12 -#define DAVINCI_LPSC_DMAX 13 -#define DAVINCI_LPSC_ARM 14 -#define DAVINCI_LPSC_GEM 15 - -/* for LPSCs in PSC1, offset from 32 for differentiation */ -#define DAVINCI_LPSC_PSC1_BASE 32 -#define DAVINCI_LPSC_USB20 (DAVINCI_LPSC_PSC1_BASE + 1) -#define DAVINCI_LPSC_USB11 (DAVINCI_LPSC_PSC1_BASE + 2) -#define DAVINCI_LPSC_GPIO (DAVINCI_LPSC_PSC1_BASE + 3) -#define DAVINCI_LPSC_UHPI (DAVINCI_LPSC_PSC1_BASE + 4) -#define DAVINCI_LPSC_EMAC (DAVINCI_LPSC_PSC1_BASE + 5) -#define DAVINCI_LPSC_DDR_EMIF (DAVINCI_LPSC_PSC1_BASE + 6) -#define DAVINCI_LPSC_McASP0 (DAVINCI_LPSC_PSC1_BASE + 7) -#define DAVINCI_LPSC_SPI1 (DAVINCI_LPSC_PSC1_BASE + 10) -#define DAVINCI_LPSC_I2C1 (DAVINCI_LPSC_PSC1_BASE + 11) -#define DAVINCI_LPSC_UART1 (DAVINCI_LPSC_PSC1_BASE + 12) -#define DAVINCI_LPSC_UART2 (DAVINCI_LPSC_PSC1_BASE + 13) -#define DAVINCI_LPSC_LCDC (DAVINCI_LPSC_PSC1_BASE + 16) -#define DAVINCI_LPSC_ePWM (DAVINCI_LPSC_PSC1_BASE + 17) -#define DAVINCI_LPSC_MMCSD1 (DAVINCI_LPSC_PSC1_BASE + 18) -#define DAVINCI_LPSC_eCAP (DAVINCI_LPSC_PSC1_BASE + 20) -#define DAVINCI_LPSC_L3_CBA_RAM (DAVINCI_LPSC_PSC1_BASE + 31) - -/* DA830-specific peripherals */ -#define DAVINCI_LPSC_McASP1 (DAVINCI_LPSC_PSC1_BASE + 8) -#define DAVINCI_LPSC_McASP2 (DAVINCI_LPSC_PSC1_BASE + 9) -#define DAVINCI_LPSC_eQEP (DAVINCI_LPSC_PSC1_BASE + 21) -#define DAVINCI_LPSC_SCR8 (DAVINCI_LPSC_PSC1_BASE + 24) -#define DAVINCI_LPSC_SCR7 (DAVINCI_LPSC_PSC1_BASE + 25) -#define DAVINCI_LPSC_SCR12 (DAVINCI_LPSC_PSC1_BASE + 26) - -/* DA850-specific peripherals */ -#define DAVINCI_LPSC_TPCC1 (DAVINCI_LPSC_PSC1_BASE + 0) -#define DAVINCI_LPSC_SATA (DAVINCI_LPSC_PSC1_BASE + 8) -#define DAVINCI_LPSC_VPIF (DAVINCI_LPSC_PSC1_BASE + 9) -#define DAVINCI_LPSC_McBSP0 (DAVINCI_LPSC_PSC1_BASE + 14) -#define DAVINCI_LPSC_McBSP1 (DAVINCI_LPSC_PSC1_BASE + 15) -#define DAVINCI_LPSC_MMC_SD1 (DAVINCI_LPSC_PSC1_BASE + 18) -#define DAVINCI_LPSC_uPP (DAVINCI_LPSC_PSC1_BASE + 19) -#define DAVINCI_LPSC_TPTC2 (DAVINCI_LPSC_PSC1_BASE + 21) -#define DAVINCI_LPSC_SCR_F0 (DAVINCI_LPSC_PSC1_BASE + 24) -#define DAVINCI_LPSC_SCR_F1 (DAVINCI_LPSC_PSC1_BASE + 25) -#define DAVINCI_LPSC_SCR_F2 (DAVINCI_LPSC_PSC1_BASE + 26) -#define DAVINCI_LPSC_SCR_F6 (DAVINCI_LPSC_PSC1_BASE + 27) -#define DAVINCI_LPSC_SCR_F7 (DAVINCI_LPSC_PSC1_BASE + 28) -#define DAVINCI_LPSC_SCR_F8 (DAVINCI_LPSC_PSC1_BASE + 29) -#define DAVINCI_LPSC_BR_F7 (DAVINCI_LPSC_PSC1_BASE + 30) - -#endif /* CONFIG_SOC_DA8XX */ - -void lpsc_on(unsigned int id); -void lpsc_syncreset(unsigned int id); -void lpsc_disable(unsigned int id); -void dsp_on(void); - -void davinci_enable_uart0(void); -void davinci_enable_emac(void); -void davinci_enable_i2c(void); -void davinci_errata_workarounds(void); - -#ifndef CONFIG_SOC_DA8XX - -/* Some PSC defines */ -#define PSC_CHP_SHRTSW (0x01c40038) -#define PSC_GBLCTL (0x01c41010) -#define PSC_EPCPR (0x01c41070) -#define PSC_EPCCR (0x01c41078) -#define PSC_PTCMD (0x01c41120) -#define PSC_PTSTAT (0x01c41128) -#define PSC_PDSTAT (0x01c41200) -#define PSC_PDSTAT1 (0x01c41204) -#define PSC_PDCTL (0x01c41300) -#define PSC_PDCTL1 (0x01c41304) - -#define PSC_MDCTL_BASE (0x01c41a00) -#define PSC_MDSTAT_BASE (0x01c41800) - -#define VDD3P3V_PWDN (0x01c40048) -#define UART0_PWREMU_MGMT (0x01c20030) - -#define PSC_SILVER_BULLET (0x01c41a20) - -#else /* CONFIG_SOC_DA8XX */ - -#define PSC_ENABLE 0x3 -#define PSC_DISABLE 0x2 -#define PSC_SYNCRESET 0x1 -#define PSC_SWRSTDISABLE 0x0 - -#define PSC_PSC0_MODULE_ID_CNT 16 -#define PSC_PSC1_MODULE_ID_CNT 32 - -#define UART0_PWREMU_MGMT (0x01c42030) - -struct davinci_psc_regs { - dv_reg revid; - dv_reg rsvd0[71]; - dv_reg ptcmd; - dv_reg rsvd1; - dv_reg ptstat; - dv_reg rsvd2[437]; - union { - struct { - dv_reg mdstat[PSC_PSC0_MODULE_ID_CNT]; - dv_reg rsvd3[112]; - dv_reg mdctl[PSC_PSC0_MODULE_ID_CNT]; - } psc0; - struct { - dv_reg mdstat[PSC_PSC1_MODULE_ID_CNT]; - dv_reg rsvd3[96]; - dv_reg mdctl[PSC_PSC1_MODULE_ID_CNT]; - } psc1; - }; -}; - -#define davinci_psc0_regs ((struct davinci_psc_regs *)DAVINCI_PSC0_BASE) -#define davinci_psc1_regs ((struct davinci_psc_regs *)DAVINCI_PSC1_BASE) - -#endif /* CONFIG_SOC_DA8XX */ - -#define PSC_MDSTAT_STATE 0x3f -#define PSC_MDCTL_NEXT 0x07 - -#ifndef CONFIG_SOC_DA8XX - -/* Miscellania... */ -#define VBPR (0x20000020) - -/* NOTE: system control modules are *highly* chip-specific, both - * as to register content (e.g. for muxing) and which registers exist. - */ -#define PINMUX0 0x01c40000 -#define PINMUX1 0x01c40004 -#define PINMUX2 0x01c40008 -#define PINMUX3 0x01c4000c -#define PINMUX4 0x01c40010 - -struct davinci_uart_ctrl_regs { - dv_reg revid1; - dv_reg res; - dv_reg pwremu_mgmt; - dv_reg mdr; -}; - -#define DAVINCI_UART_CTRL_BASE 0x28 - -/* UART PWREMU_MGMT definitions */ -#define DAVINCI_UART_PWREMU_MGMT_FREE (1 << 0) -#define DAVINCI_UART_PWREMU_MGMT_URRST (1 << 13) -#define DAVINCI_UART_PWREMU_MGMT_UTRST (1 << 14) - -#else /* CONFIG_SOC_DA8XX */ - -struct davinci_pllc_regs { - dv_reg revid; - dv_reg rsvd1[56]; - dv_reg rstype; - dv_reg rsvd2[6]; - dv_reg pllctl; - dv_reg ocsel; - dv_reg rsvd3[2]; - dv_reg pllm; - dv_reg prediv; - dv_reg plldiv1; - dv_reg plldiv2; - dv_reg plldiv3; - dv_reg oscdiv; - dv_reg postdiv; - dv_reg rsvd4[3]; - dv_reg pllcmd; - dv_reg pllstat; - dv_reg alnctl; - dv_reg dchange; - dv_reg cken; - dv_reg ckstat; - dv_reg systat; - dv_reg rsvd5[3]; - dv_reg plldiv4; - dv_reg plldiv5; - dv_reg plldiv6; - dv_reg plldiv7; - dv_reg rsvd6[32]; - dv_reg emucnt0; - dv_reg emucnt1; -}; - -#define davinci_pllc0_regs ((struct davinci_pllc_regs *)DAVINCI_PLL_CNTRL0_BASE) -#define davinci_pllc1_regs ((struct davinci_pllc_regs *)DAVINCI_PLL_CNTRL1_BASE) -#define DAVINCI_PLLC_DIV_MASK 0x1f - -/* - * A clock ID is a 32-bit number where bit 16 represents the PLL controller - * (clear is PLLC0, set is PLLC1) and the low 16 bits represent the divisor, - * counting from 1. Clock IDs may be passed to clk_get(). - */ - -/* flags to select PLL controller */ -#define DAVINCI_PLLC0_FLAG (0) -#define DAVINCI_PLLC1_FLAG (1 << 16) - -enum davinci_clk_ids { - /* - * Clock IDs for PLL outputs. Each may be switched on/off - * independently, and each may map to one or more peripherals. - */ - DAVINCI_PLL0_SYSCLK2 = DAVINCI_PLLC0_FLAG | 2, - DAVINCI_PLL0_SYSCLK4 = DAVINCI_PLLC0_FLAG | 4, - DAVINCI_PLL0_SYSCLK6 = DAVINCI_PLLC0_FLAG | 6, - DAVINCI_PLL1_SYSCLK1 = DAVINCI_PLLC1_FLAG | 1, - DAVINCI_PLL1_SYSCLK2 = DAVINCI_PLLC1_FLAG | 2, - - /* map peripherals to clock IDs */ - DAVINCI_ARM_CLKID = DAVINCI_PLL0_SYSCLK6, - DAVINCI_DDR_CLKID = DAVINCI_PLL1_SYSCLK1, - DAVINCI_MDIO_CLKID = DAVINCI_PLL0_SYSCLK4, - DAVINCI_MMC_CLKID = DAVINCI_PLL0_SYSCLK2, - DAVINCI_SPI0_CLKID = DAVINCI_PLL0_SYSCLK2, - DAVINCI_MMCSD_CLKID = DAVINCI_PLL0_SYSCLK2, - - /* special clock ID - output of PLL multiplier */ - DAVINCI_PLLM_CLKID = 0x0FF, - - /* special clock ID - output of PLL post divisor */ - DAVINCI_PLLC_CLKID = 0x100, - - /* special clock ID - PLL bypass */ - DAVINCI_AUXCLK_CLKID = 0x101, -}; - -#define DAVINCI_UART2_CLKID (cpu_is_da830() ? DAVINCI_PLL0_SYSCLK2 \ - : get_async3_src()) - -#define DAVINCI_SPI1_CLKID (cpu_is_da830() ? DAVINCI_PLL0_SYSCLK2 \ - : get_async3_src()) - -int clk_get(enum davinci_clk_ids id); - -/* Boot config */ -struct davinci_syscfg_regs { - dv_reg revid; - dv_reg rsvd[13]; - dv_reg kick0; - dv_reg kick1; - dv_reg rsvd1[52]; - dv_reg mstpri[3]; - dv_reg rsvd2; - dv_reg pinmux[20]; - dv_reg suspsrc; - dv_reg chipsig; - dv_reg chipsig_clr; - dv_reg cfgchip0; - dv_reg cfgchip1; - dv_reg cfgchip2; - dv_reg cfgchip3; - dv_reg cfgchip4; -}; - -#define davinci_syscfg_regs \ - ((struct davinci_syscfg_regs *)DAVINCI_BOOTCFG_BASE) - -#define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) - -/* Emulation suspend bits */ -#define DAVINCI_SYSCFG_SUSPSRC_EMAC (1 << 5) -#define DAVINCI_SYSCFG_SUSPSRC_I2C (1 << 16) -#define DAVINCI_SYSCFG_SUSPSRC_SPI0 (1 << 21) -#define DAVINCI_SYSCFG_SUSPSRC_SPI1 (1 << 22) -#define DAVINCI_SYSCFG_SUSPSRC_UART0 (1 << 18) -#define DAVINCI_SYSCFG_SUSPSRC_UART2 (1 << 20) -#define DAVINCI_SYSCFG_SUSPSRC_TIMER0 (1 << 27) - -struct davinci_syscfg1_regs { - dv_reg vtpio_ctl; - dv_reg ddr_slew; - dv_reg deepsleep; - dv_reg pupd_ena; - dv_reg pupd_sel; - dv_reg rxactive; - dv_reg pwrdwn; -}; - -#define davinci_syscfg1_regs \ - ((struct davinci_syscfg1_regs *)DAVINCI_SYSCFG1_BASE) - -#define DDR_SLEW_CMOSEN_BIT 4 -#define DDR_SLEW_DDR_PDENA_BIT 5 - -#define VTP_POWERDWN (1 << 6) -#define VTP_LOCK (1 << 7) -#define VTP_CLKRZ (1 << 13) -#define VTP_READY (1 << 15) -#define VTP_IOPWRDWN (1 << 14) - -#define DV_SYSCFG_KICK0_UNLOCK 0x83e70b13 -#define DV_SYSCFG_KICK1_UNLOCK 0x95a4f1e0 - -/* Interrupt controller */ -struct davinci_aintc_regs { - dv_reg revid; - dv_reg cr; - dv_reg dummy0[2]; - dv_reg ger; - dv_reg dummy1[219]; - dv_reg ecr1; - dv_reg ecr2; - dv_reg ecr3; - dv_reg dummy2[1117]; - dv_reg hier; -}; - -#define davinci_aintc_regs ((struct davinci_aintc_regs *)DAVINCI_INTC_BASE) - -struct davinci_uart_ctrl_regs { - dv_reg revid1; - dv_reg revid2; - dv_reg pwremu_mgmt; - dv_reg mdr; -}; - -#define DAVINCI_UART_CTRL_BASE 0x28 -#define DAVINCI_UART0_CTRL_ADDR (DAVINCI_UART0_BASE + DAVINCI_UART_CTRL_BASE) -#define DAVINCI_UART1_CTRL_ADDR (DAVINCI_UART1_BASE + DAVINCI_UART_CTRL_BASE) -#define DAVINCI_UART2_CTRL_ADDR (DAVINCI_UART2_BASE + DAVINCI_UART_CTRL_BASE) - -#define davinci_uart0_ctrl_regs \ - ((struct davinci_uart_ctrl_regs *)DAVINCI_UART0_CTRL_ADDR) -#define davinci_uart1_ctrl_regs \ - ((struct davinci_uart_ctrl_regs *)DAVINCI_UART1_CTRL_ADDR) -#define davinci_uart2_ctrl_regs \ - ((struct davinci_uart_ctrl_regs *)DAVINCI_UART2_CTRL_ADDR) - -/* UART PWREMU_MGMT definitions */ -#define DAVINCI_UART_PWREMU_MGMT_FREE (1 << 0) -#define DAVINCI_UART_PWREMU_MGMT_URRST (1 << 13) -#define DAVINCI_UART_PWREMU_MGMT_UTRST (1 << 14) - -static inline int cpu_is_da830(void) -{ - unsigned int jtag_id = REG(JTAG_ID_REG); - unsigned short part_no = (jtag_id >> 12) & 0xffff; - - return ((part_no == 0xb7df) ? 1 : 0); -} -static inline int cpu_is_da850(void) -{ - unsigned int jtag_id = REG(JTAG_ID_REG); - unsigned short part_no = (jtag_id >> 12) & 0xffff; - - return ((part_no == 0xb7d1) ? 1 : 0); -} - -static inline enum davinci_clk_ids get_async3_src(void) -{ - return (REG(&davinci_syscfg_regs->cfgchip3) & 0x10) ? - DAVINCI_PLL1_SYSCLK2 : DAVINCI_PLL0_SYSCLK2; -} - -#endif /* CONFIG_SOC_DA8XX */ - -#if defined(CONFIG_SOC_DM365) -#include -#include -#include -#include -#include -#include -#include - -#define TMPBUF 0x00017ff8 -#define TMPSTATUS 0x00017ff0 -#define DV_TMPBUF_VAL 0x591b3ed7 -#define FLAG_PORRST 0x00000001 -#define FLAG_WDTRST 0x00000002 -#define FLAG_FLGON 0x00000004 -#define FLAG_FLGOFF 0x00000010 - -#endif - -#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-davinci/i2c_defs.h b/arch/arm/include/asm/arch-davinci/i2c_defs.h deleted file mode 100644 index 06da8947b4..0000000000 --- a/arch/arm/include/asm/arch-davinci/i2c_defs.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * (C) Copyright 2004-2014 - * Texas Instruments, - * - * Some changes copyright (C) 2007 Sergey Kubushyn - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _I2C_DEFS_H_ -#define _I2C_DEFS_H_ - -#ifndef CONFIG_SOC_DA8XX -#define I2C_BASE 0x01c21000 -#else -#define I2C_BASE 0x01c22000 -#endif - -#endif diff --git a/arch/arm/include/asm/arch-davinci/pinmux_defs.h b/arch/arm/include/asm/arch-davinci/pinmux_defs.h deleted file mode 100644 index 2d82af554b..0000000000 --- a/arch/arm/include/asm/arch-davinci/pinmux_defs.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Pinmux configurations for the DAxxx SoCs - * - * Copyright (C) 2011 OMICRON electronics GmbH - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_PINMUX_DEFS_H -#define __ASM_ARCH_PINMUX_DEFS_H - -#include -#include - -/* SPI0 pin muxer settings */ -extern const struct pinmux_config spi0_pins_base[3]; -extern const struct pinmux_config spi0_pins_scs0[1]; -extern const struct pinmux_config spi0_pins_ena[1]; - -/* SPI1 pin muxer settings */ -extern const struct pinmux_config spi1_pins_base[3]; -extern const struct pinmux_config spi1_pins_scs0[1]; - -/* UART pin muxer settings */ -extern const struct pinmux_config uart0_pins_txrx[2]; -extern const struct pinmux_config uart0_pins_rtscts[2]; -extern const struct pinmux_config uart1_pins_txrx[2]; -extern const struct pinmux_config uart2_pins_txrx[2]; -extern const struct pinmux_config uart2_pins_rtscts[2]; - -/* EMAC pin muxer settings*/ -extern const struct pinmux_config emac_pins_rmii[8]; -extern const struct pinmux_config emac_pins_rmii_clk_source[1]; -extern const struct pinmux_config emac_pins_mii[15]; -extern const struct pinmux_config emac_pins_mdio[2]; - -/* I2C pin muxer settings */ -extern const struct pinmux_config i2c0_pins[2]; -extern const struct pinmux_config i2c1_pins[2]; - -/* EMIFA pin muxer settings */ -extern const struct pinmux_config emifa_pins[40]; -extern const struct pinmux_config emifa_pins_cs0[1]; -extern const struct pinmux_config emifa_pins_cs2[1]; -extern const struct pinmux_config emifa_pins_cs3[1]; -extern const struct pinmux_config emifa_pins_cs4[1]; -extern const struct pinmux_config emifa_pins_nand[12]; -extern const struct pinmux_config emifa_pins_nor[43]; - -/* USB pin mux setting */ -extern const struct pinmux_config usb_pins[1]; - -/* MMC pin muxer settings */ -extern const struct pinmux_config mmc0_pins_8bit[10]; -extern const struct pinmux_config mmc0_pins[6]; - -#endif diff --git a/arch/arm/include/asm/arch-davinci/pll_defs.h b/arch/arm/include/asm/arch-davinci/pll_defs.h deleted file mode 100644 index d083cccadb..0000000000 --- a/arch/arm/include/asm/arch-davinci/pll_defs.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _DV_PLL_DEFS_H_ -#define _DV_PLL_DEFS_H_ - -struct dv_pll_regs { - unsigned int pid; /* 0x00 */ - unsigned char rsvd0[224]; /* 0x04 */ - unsigned int rstype; /* 0xe4 */ - unsigned char rsvd1[24]; /* 0xe8 */ - unsigned int pllctl; /* 0x100 */ - unsigned char rsvd2[4]; /* 0x104 */ - unsigned int secctl; /* 0x108 */ - unsigned int rv; /* 0x10c */ - unsigned int pllm; /* 0x110 */ - unsigned int prediv; /* 0x114 */ - unsigned int plldiv1; /* 0x118 */ - unsigned int plldiv2; /* 0x11c */ - unsigned int plldiv3; /* 0x120 */ - unsigned int oscdiv1; /* 0x124 */ - unsigned int postdiv; /* 0x128 */ - unsigned int bpdiv; /* 0x12c */ - unsigned char rsvd5[8]; /* 0x130 */ - unsigned int pllcmd; /* 0x138 */ - unsigned int pllstat; /* 0x13c */ - unsigned int alnctl; /* 0x140 */ - unsigned int dchange; /* 0x144 */ - unsigned int cken; /* 0x148 */ - unsigned int ckstat; /* 0x14c */ - unsigned int systat; /* 0x150 */ - unsigned char rsvd6[12]; /* 0x154 */ - unsigned int plldiv4; /* 0x160 */ - unsigned int plldiv5; /* 0x164 */ - unsigned int plldiv6; /* 0x168 */ - unsigned int plldiv7; /* 0x16C */ - unsigned int plldiv8; /* 0x170 */ - unsigned int plldiv9; /* 0x174 */ -}; - -#define PLL_MASTER_LOCK (1 << 4) - -#define PLLCTL_CLOCK_MODE_SHIFT 8 -#define PLLCTL_PLLEN (1 << 0) -#define PLLCTL_PLLPWRDN (1 << 1) -#define PLLCTL_PLLRST (1 << 3) -#define PLLCTL_PLLDIS (1 << 4) -#define PLLCTL_PLLENSRC (1 << 5) -#define PLLCTL_RES_9 (1 << 8) -#define PLLCTL_EXTCLKSRC (1 << 9) - -#define PLL_DIVEN (1 << 15) -#define PLL_POSTDEN PLL_DIVEN - -#define PLL_SCSCFG3_DIV45PENA (1 << 2) -#define PLL_SCSCFG3_EMA_CLKSRC (1 << 1) - -#define PLL_RSTYPE_POR (1 << 0) -#define PLL_RSTYPE_XWRST (1 << 1) - -#define PLLSECCTL_TINITZ (1 << 16) -#define PLLSECCTL_TENABLE (1 << 17) -#define PLLSECCTL_TENABLEDIV (1 << 18) -#define PLLSECCTL_STOPMODE (1 << 22) - -#define PLLCMD_GOSET (1 << 0) -#define PLLCMD_GOSTAT (1 << 0) - -#define PLL0_LOCK 0x07000000 -#define PLL1_LOCK 0x07000000 - -#define dv_pll0_regs ((struct dv_pll_regs *)DAVINCI_PLL_CNTRL0_BASE) -#define dv_pll1_regs ((struct dv_pll_regs *)DAVINCI_PLL_CNTRL1_BASE) - -#define ARM_PLLDIV (offsetof(struct dv_pll_regs, plldiv2)) -#define DDR_PLLDIV (offsetof(struct dv_pll_regs, plldiv7)) -#define SPI_PLLDIV (offsetof(struct dv_pll_regs, plldiv4)) - -unsigned int davinci_clk_get(unsigned int div); -#endif /* _DV_PLL_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/psc_defs.h b/arch/arm/include/asm/arch-davinci/psc_defs.h deleted file mode 100644 index bcb5580499..0000000000 --- a/arch/arm/include/asm/arch-davinci/psc_defs.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _DV_PSC_DEFS_H_ -#define _DV_PSC_DEFS_H_ - -/* - * Power/Sleep Ctrl Register structure - * See sprufb3.pdf, Chapter 7 - */ -struct dv_psc_regs { - unsigned int pid; /* 0x000 */ - unsigned char rsvd0[16]; /* 0x004 */ - unsigned char rsvd1[4]; /* 0x014 */ - unsigned int inteval; /* 0x018 */ - unsigned char rsvd2[36]; /* 0x01C */ - unsigned int merrpr0; /* 0x040 */ - unsigned int merrpr1; /* 0x044 */ - unsigned char rsvd3[8]; /* 0x048 */ - unsigned int merrcr0; /* 0x050 */ - unsigned int merrcr1; /* 0x054 */ - unsigned char rsvd4[8]; /* 0x058 */ - unsigned int perrpr; /* 0x060 */ - unsigned char rsvd5[4]; /* 0x064 */ - unsigned int perrcr; /* 0x068 */ - unsigned char rsvd6[4]; /* 0x06C */ - unsigned int epcpr; /* 0x070 */ - unsigned char rsvd7[4]; /* 0x074 */ - unsigned int epccr; /* 0x078 */ - unsigned char rsvd8[144]; /* 0x07C */ - unsigned char rsvd9[20]; /* 0x10C */ - unsigned int ptcmd; /* 0x120 */ - unsigned char rsvd10[4]; /* 0x124 */ - unsigned int ptstat; /* 0x128 */ - unsigned char rsvd11[212]; /* 0x12C */ - unsigned int pdstat0; /* 0x200 */ - unsigned int pdstat1; /* 0x204 */ - unsigned char rsvd12[248]; /* 0x208 */ - unsigned int pdctl0; /* 0x300 */ - unsigned int pdctl1; /* 0x304 */ - unsigned char rsvd13[536]; /* 0x308 */ - unsigned int mckout0; /* 0x520 */ - unsigned int mckout1; /* 0x524 */ - unsigned char rsvd14[728]; /* 0x528 */ - unsigned int mdstat[52]; /* 0x800 */ - unsigned char rsvd15[304]; /* 0x8D0 */ - unsigned int mdctl[52]; /* 0xA00 */ -}; - -/* PSC constants */ -#define EMURSTIE_MASK (0x00000200) - -#define PD0 (0) - -#define PSC_ENABLE (0x3) -#define PSC_DISABLE (0x2) -#define PSC_SYNCRESET (0x1) -#define PSC_SWRSTDISABLE (0x0) - -#define PSC_GOSTAT (1 << 0) -#define PSC_MD_STATE_MSK (0x1f) - -#define PSC_CMD_GO (1 << 0) - -#define dv_psc_regs ((struct dv_psc_regs *)DAVINCI_PWR_SLEEP_CNTRL_BASE) - -#endif /* _DV_PSC_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/sdmmc_defs.h b/arch/arm/include/asm/arch-davinci/sdmmc_defs.h deleted file mode 100644 index 9aa3f4ab27..0000000000 --- a/arch/arm/include/asm/arch-davinci/sdmmc_defs.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Davinci MMC Controller Defines - Based on Linux davinci_mmc.c - * - * Copyright (C) 2010 Texas Instruments Incorporated - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _SDMMC_DEFS_H_ -#define _SDMMC_DEFS_H_ - -#include - -/* MMC Control Reg fields */ -#define MMCCTL_DATRST (1 << 0) -#define MMCCTL_CMDRST (1 << 1) -#define MMCCTL_WIDTH_4_BIT (1 << 2) -#define MMCCTL_DATEG_DISABLED (0 << 6) -#define MMCCTL_DATEG_RISING (1 << 6) -#define MMCCTL_DATEG_FALLING (2 << 6) -#define MMCCTL_DATEG_BOTH (3 << 6) -#define MMCCTL_PERMDR_LE (0 << 9) -#define MMCCTL_PERMDR_BE (1 << 9) -#define MMCCTL_PERMDX_LE (0 << 10) -#define MMCCTL_PERMDX_BE (1 << 10) - -/* MMC Clock Control Reg fields */ -#define MMCCLK_CLKEN (1 << 8) -#define MMCCLK_CLKRT_MASK (0xFF << 0) - -/* MMC Status Reg0 fields */ -#define MMCST0_DATDNE (1 << 0) -#define MMCST0_BSYDNE (1 << 1) -#define MMCST0_RSPDNE (1 << 2) -#define MMCST0_TOUTRD (1 << 3) -#define MMCST0_TOUTRS (1 << 4) -#define MMCST0_CRCWR (1 << 5) -#define MMCST0_CRCRD (1 << 6) -#define MMCST0_CRCRS (1 << 7) -#define MMCST0_DXRDY (1 << 9) -#define MMCST0_DRRDY (1 << 10) -#define MMCST0_DATED (1 << 11) -#define MMCST0_TRNDNE (1 << 12) - -#define MMCST0_ERR_MASK (0x00F8) - -/* MMC Status Reg1 fields */ -#define MMCST1_BUSY (1 << 0) -#define MMCST1_CLKSTP (1 << 1) -#define MMCST1_DXEMP (1 << 2) -#define MMCST1_DRFUL (1 << 3) -#define MMCST1_DAT3ST (1 << 4) -#define MMCST1_FIFOEMP (1 << 5) -#define MMCST1_FIFOFUL (1 << 6) - -/* MMC INT Mask Reg fields */ -#define MMCIM_EDATDNE (1 << 0) -#define MMCIM_EBSYDNE (1 << 1) -#define MMCIM_ERSPDNE (1 << 2) -#define MMCIM_ETOUTRD (1 << 3) -#define MMCIM_ETOUTRS (1 << 4) -#define MMCIM_ECRCWR (1 << 5) -#define MMCIM_ECRCRD (1 << 6) -#define MMCIM_ECRCRS (1 << 7) -#define MMCIM_EDXRDY (1 << 9) -#define MMCIM_EDRRDY (1 << 10) -#define MMCIM_EDATED (1 << 11) -#define MMCIM_ETRNDNE (1 << 12) - -#define MMCIM_MASKALL (0xFFFFFFFF) - -/* MMC Resp Tout Reg fields */ -#define MMCTOR_TOR_MASK (0xFF) /* dont write to reg, | it */ -#define MMCTOR_TOD_20_16_SHIFT (8) - -/* MMC Data Read Tout Reg fields */ -#define MMCTOD_TOD_0_15_MASK (0xFFFF) - -/* MMC Block len Reg fields */ -#define MMCBLEN_BLEN_MASK (0xFFF) - -/* MMC Num Blocks Reg fields */ -#define MMCNBLK_NBLK_MASK (0xFFFF) -#define MMCNBLK_NBLK_MAX (0xFFFF) - -/* MMC Num Blocks Counter Reg fields */ -#define MMCNBLC_NBLC_MASK (0xFFFF) - -/* MMC Cmd Reg fields */ -#define MMCCMD_CMD_MASK (0x3F) -#define MMCCMD_PPLEN (1 << 7) -#define MMCCMD_BSYEXP (1 << 8) -#define MMCCMD_RSPFMT_NONE (0 << 9) -#define MMCCMD_RSPFMT_R1567 (1 << 9) -#define MMCCMD_RSPFMT_R2 (2 << 9) -#define MMCCMD_RSPFMT_R3 (3 << 9) -#define MMCCMD_DTRW (1 << 11) -#define MMCCMD_STRMTP (1 << 12) -#define MMCCMD_WDATX (1 << 13) -#define MMCCMD_INITCK (1 << 14) -#define MMCCMD_DCLR (1 << 15) -#define MMCCMD_DMATRIG (1 << 16) - -/* FIFO control Reg fields */ -#define MMCFIFOCTL_FIFORST (1 << 0) -#define MMCFIFOCTL_FIFODIR (1 << 1) -#define MMCFIFOCTL_FIFOLEV (1 << 2) -#define MMCFIFOCTL_ACCWD_4 (0 << 3) /* access width of 4 bytes */ -#define MMCFIFOCTL_ACCWD_3 (1 << 3) /* access width of 3 bytes */ -#define MMCFIFOCTL_ACCWD_2 (2 << 3) /* access width of 2 bytes */ -#define MMCFIFOCTL_ACCWD_1 (3 << 3) /* access width of 1 byte */ - -/* Davinci MMC Register definitions */ -struct davinci_mmc_regs { - dv_reg mmcctl; - dv_reg mmcclk; - dv_reg mmcst0; - dv_reg mmcst1; - dv_reg mmcim; - dv_reg mmctor; - dv_reg mmctod; - dv_reg mmcblen; - dv_reg mmcnblk; - dv_reg mmcnblc; - dv_reg mmcdrr; - dv_reg mmcdxr; - dv_reg mmccmd; - dv_reg mmcarghl; - dv_reg mmcrsp01; - dv_reg mmcrsp23; - dv_reg mmcrsp45; - dv_reg mmcrsp67; - dv_reg mmcdrsp; - dv_reg mmcetok; - dv_reg mmccidx; - dv_reg mmcckc; - dv_reg mmctorc; - dv_reg mmctodc; - dv_reg mmcblnc; - dv_reg sdioctl; - dv_reg sdiost0; - dv_reg sdioien; - dv_reg sdioist; - dv_reg mmcfifoctl; -}; - -/* Davinci MMC board definitions */ -struct davinci_mmc { - struct davinci_mmc_regs *reg_base; /* Register base address */ - uint input_clk; /* Input clock to MMC controller */ - uint host_caps; /* Host capabilities */ - uint voltages; /* Host supported voltages */ - uint version; /* MMC Controller version */ - struct mmc_config cfg; -}; - -enum { - MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */ - MMC_CTLR_VERSION_2, /* DA830 */ -}; - -int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host); - -#endif /* _SDMMC_DEFS_H */ diff --git a/arch/arm/include/asm/arch-davinci/syscfg_defs.h b/arch/arm/include/asm/arch-davinci/syscfg_defs.h deleted file mode 100644 index 812088f379..0000000000 --- a/arch/arm/include/asm/arch-davinci/syscfg_defs.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2011 - * Heiko Schocher, DENX Software Engineering, hs@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _DV_SYSCFG_DEFS_H_ -#define _DV_SYSCFG_DEFS_H_ - -#ifndef CONFIG_SOC_DA8XX -/* System Control Module register structure for DM365 */ -struct dv_sys_module_regs { - unsigned int pinmux[5]; /* 0x00 */ - unsigned int bootcfg; /* 0x14 */ - unsigned int arm_intmux; /* 0x18 */ - unsigned int edma_evtmux; /* 0x1C */ - unsigned int ddr_slew; /* 0x20 */ - unsigned int clkout; /* 0x24 */ - unsigned int device_id; /* 0x28 */ - unsigned int vdac_config; /* 0x2C */ - unsigned int timer64_ctl; /* 0x30 */ - unsigned int usbbphy_ctl; /* 0x34 */ - unsigned int misc; /* 0x38 */ - unsigned int mstpri[2]; /* 0x3C */ - unsigned int vpss_clkctl; /* 0x44 */ - unsigned int peri_clkctl; /* 0x48 */ - unsigned int deepsleep; /* 0x4C */ - unsigned int dft_enable; /* 0x50 */ - unsigned int debounce[8]; /* 0x54 */ - unsigned int vtpiocr; /* 0x74 */ - unsigned int pupdctl0; /* 0x78 */ - unsigned int pupdctl1; /* 0x7C */ - unsigned int hdimcopbt; /* 0x80 */ - unsigned int pll0_config; /* 0x84 */ - unsigned int pll1_config; /* 0x88 */ -}; - -#define VPTIO_RDY (1 << 15) -#define VPTIO_IOPWRDN (1 << 14) -#define VPTIO_CLRZ (1 << 13) -#define VPTIO_LOCK (1 << 7) -#define VPTIO_PWRDN (1 << 6) - -#define VPSS_CLK_CTL_VPSS_CLKMD (1 << 7) - -#define dv_sys_module_regs \ - ((struct dv_sys_module_regs *)DAVINCI_SYSTEM_MODULE_BASE) - -#endif /* !CONFIG_SOC_DA8XX */ -#endif /* _DV_SYSCFG_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-davinci/timer_defs.h b/arch/arm/include/asm/arch-davinci/timer_defs.h deleted file mode 100644 index 94d18320d9..0000000000 --- a/arch/arm/include/asm/arch-davinci/timer_defs.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2011 DENX Software Engineering GmbH - * Heiko Schocher - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _TIMER_DEFS_H_ -#define _TIMER_DEFS_H_ - -struct davinci_timer { - u_int32_t pid12; - u_int32_t emumgt; - u_int32_t na1; - u_int32_t na2; - u_int32_t tim12; - u_int32_t tim34; - u_int32_t prd12; - u_int32_t prd34; - u_int32_t tcr; - u_int32_t tgcr; - u_int32_t wdtcr; -}; - -#define DV_TIMER_TCR_ENAMODE_MASK 3 - -#define DV_TIMER_TCR_ENAMODE12_SHIFT 6 -#define DV_TIMER_TCR_CLKSRC12_SHIFT 8 -#define DV_TIMER_TCR_READRSTMODE12_SHIFT 10 -#define DV_TIMER_TCR_CAPMODE12_SHIFT 11 -#define DV_TIMER_TCR_CAPVTMODE12_SHIFT 12 -#define DV_TIMER_TCR_ENAMODE34_SHIFT 22 -#define DV_TIMER_TCR_CLKSRC34_SHIFT 24 -#define DV_TIMER_TCR_READRSTMODE34_SHIFT 26 -#define DV_TIMER_TCR_CAPMODE34_SHIFT 27 -#define DV_TIMER_TCR_CAPEVTMODE12_SHIFT 28 - -#define DV_WDT_ENABLE_SYS_RESET 0x00020000 -#define DV_WDT_TRIGGER_SYS_RESET 0x00020002 - -#ifdef CONFIG_HW_WATCHDOG -void davinci_hw_watchdog_enable(void); -void davinci_hw_watchdog_reset(void); -#endif -#endif /* _TIMER_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/aintc_defs.h b/arch/arm/mach-davinci/include/mach/aintc_defs.h new file mode 100644 index 0000000000..5063e3964c --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/aintc_defs.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DV_AINTC_DEFS_H_ +#define _DV_AINTC_DEFS_H_ + +struct dv_aintc_regs { + unsigned int fiq0; /* 0x00 */ + unsigned int fiq1; /* 0x04 */ + unsigned int irq0; /* 0x08 */ + unsigned int irq1; /* 0x0c */ + unsigned int fiqentry; /* 0x10 */ + unsigned int irqentry; /* 0x14 */ + unsigned int eint0; /* 0x18 */ + unsigned int eint1; /* 0x1c */ + unsigned int intctl; /* 0x20 */ + unsigned int eabase; /* 0x24 */ + unsigned char rsvd0[8]; /* 0x28 */ + unsigned int intpri0; /* 0x30 */ + unsigned int intpri1; /* 0x34 */ + unsigned int intpri2; /* 0x38 */ + unsigned int intpri3; /* 0x3c */ + unsigned int intpri4; /* 0x40 */ + unsigned int intpri5; /* 0x44 */ + unsigned int intpri6; /* 0x48 */ + unsigned int intpri7; /* 0x4c */ +}; + +#define dv_aintc_regs ((struct dv_aintc_regs *)DAVINCI_ARM_INTC_BASE) + +#define DV_AINTC_INTCTL_IDMODE (1 << 2) + +#endif /* _DV_AINTC_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/da850_lowlevel.h b/arch/arm/mach-davinci/include/mach/da850_lowlevel.h new file mode 100644 index 0000000000..45a325c123 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/da850_lowlevel.h @@ -0,0 +1,35 @@ +/* + * SoC-specific lowlevel code for DA850 + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __DA850_LOWLEVEL_H +#define __DA850_LOWLEVEL_H + +#include + +/* pinmux_resource[] vector is defined in the board specific file */ +extern const struct pinmux_resource pinmuxes[]; +extern const int pinmuxes_size; + +extern const struct lpsc_resource lpsc[]; +extern const int lpsc_size; + +/* NOR Boot Configuration Word Field Descriptions */ +#define DA850_NORBOOT_COPY_XK(X) ((X - 1) << 8) +#define DA850_NORBOOT_METHOD_DIRECT (1 << 4) +#define DA850_NORBOOT_16BIT (1 << 0) + +#define dv_maskbits(addr, val) \ + writel((readl(addr) & val), addr) + +void da850_lpc_transition(unsigned char pscnum, unsigned char module, + unsigned char domain, unsigned char state); +void da850_psc_init(void); +void da850_pinmux_ctl(unsigned long offset, unsigned long mask, + unsigned long value); + +#endif /* #ifndef __DA850_LOWLEVEL_H */ diff --git a/arch/arm/mach-davinci/include/mach/da8xx-usb.h b/arch/arm/mach-davinci/include/mach/da8xx-usb.h new file mode 100644 index 0000000000..f091e49899 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/da8xx-usb.h @@ -0,0 +1,93 @@ +/* + * da8xx-usb.h -- TI's DA8xx platform specific usb wrapper definitions. + * + * Author: Ajay Kumar Gupta + * + * Based on drivers/usb/musb/davinci.h + * + * Copyright (C) 2009 Texas Instruments Incorporated + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __DA8XX_MUSB_H__ +#define __DA8XX_MUSB_H__ + +#include +#include + +/* Base address of da8xx usb0 wrapper */ +#define DA8XX_USB_OTG_BASE 0x01E00000 + +/* Base address of da8xx musb core */ +#define DA8XX_USB_OTG_CORE_BASE (DA8XX_USB_OTG_BASE + 0x400) + +/* Timeout for DA8xx usb module */ +#define DA8XX_USB_OTG_TIMEOUT 0x3FFFFFF + +/* + * DA8xx platform USB wrapper register overlay. + */ +struct da8xx_usb_regs { + dv_reg revision; + dv_reg control; + dv_reg status; + dv_reg emulation; + dv_reg mode; + dv_reg autoreq; + dv_reg srpfixtime; + dv_reg teardown; + dv_reg intsrc; + dv_reg intsrc_set; + dv_reg intsrc_clr; + dv_reg intmsk; + dv_reg intmsk_set; + dv_reg intmsk_clr; + dv_reg intsrcmsk; + dv_reg eoi; + dv_reg intvector; + dv_reg grndis_size[4]; +}; + +#define da8xx_usb_regs ((struct da8xx_usb_regs *)DA8XX_USB_OTG_BASE) + +/* DA8XX interrupt bits definitions */ +#define DA8XX_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */ +#define DA8XX_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */ +#define DA8XX_USB_TXINT_SHIFT 0 +#define DA8XX_USB_RXINT_SHIFT 8 + +#define DA8XX_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */ +#define DA8XX_USB_TXINT_MASK \ + (DA8XX_USB_TX_ENDPTS_MASK << DA8XX_USB_TXINT_SHIFT) +#define DA8XX_USB_RXINT_MASK \ + (DA8XX_USB_RX_ENDPTS_MASK << DA8XX_USB_RXINT_SHIFT) + +/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */ +#define CFGCHIP2_PHYCLKGD (1 << 17) +#define CFGCHIP2_VBUSSENSE (1 << 16) +#define CFGCHIP2_RESET (1 << 15) +#define CFGCHIP2_OTGMODE (3 << 13) +#define CFGCHIP2_NO_OVERRIDE (0 << 13) +#define CFGCHIP2_FORCE_HOST (1 << 13) +#define CFGCHIP2_FORCE_DEVICE (2 << 13) +#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13) +#define CFGCHIP2_USB1PHYCLKMUX (1 << 12) +#define CFGCHIP2_USB2PHYCLKMUX (1 << 11) +#define CFGCHIP2_PHYPWRDN (1 << 10) +#define CFGCHIP2_OTGPWRDN (1 << 9) +#define CFGCHIP2_DATPOL (1 << 8) +#define CFGCHIP2_USB1SUSPENDM (1 << 7) +#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */ +#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */ +#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */ +#define CFGCHIP2_REFFREQ (0xf << 0) +#define CFGCHIP2_REFFREQ_12MHZ (1 << 0) +#define CFGCHIP2_REFFREQ_24MHZ (2 << 0) +#define CFGCHIP2_REFFREQ_48MHZ (3 << 0) + +#define DA8XX_USB_VBUS_GPIO (1 << 15) + +int usb_phy_on(void); +void usb_phy_off(void); + +#endif /* __DA8XX_MUSB_H__ */ diff --git a/arch/arm/mach-davinci/include/mach/davinci_misc.h b/arch/arm/mach-davinci/include/mach/davinci_misc.h new file mode 100644 index 0000000000..03be3882f8 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/davinci_misc.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 Lyrtech + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MISC_H +#define __MISC_H + +/* pin muxer definitions */ +#define PIN_MUX_NUM_FIELDS 8 /* Per register */ +#define PIN_MUX_FIELD_SIZE 4 /* n in bits */ +#define PIN_MUX_FIELD_MASK ((1 << PIN_MUX_FIELD_SIZE) - 1) + +/* pin definition */ +struct pinmux_config { + dv_reg *mux; /* Address of mux register */ + unsigned char value; /* Value to set in field */ + unsigned char field; /* field number */ +}; + +/* pin table definition */ +struct pinmux_resource { + const struct pinmux_config *pins; + const int n_pins; +}; + +#define PINMUX_ITEM(item) { \ + .pins = item, \ + .n_pins = ARRAY_SIZE(item) \ + } + +struct lpsc_resource { + const int lpsc_no; +}; + +int dvevm_read_mac_address(uint8_t *buf); +void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr); +int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins); +int davinci_configure_pin_mux_items(const struct pinmux_resource *item, + int n_items); +#if defined(CONFIG_DRIVER_TI_EMAC) && defined(CONFIG_SOC_DA8XX) +void davinci_emac_mii_mode_sel(int mode_sel); +#endif +#if defined(CONFIG_SOC_DA8XX) +void irq_init(void); +int da8xx_configure_lpsc_items(const struct lpsc_resource *item, + const int n_items); +#endif + +#endif /* __MISC_H */ diff --git a/arch/arm/mach-davinci/include/mach/ddr2_defs.h b/arch/arm/mach-davinci/include/mach/ddr2_defs.h new file mode 100644 index 0000000000..24afd9d526 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ddr2_defs.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DV_DDR2_DEFS_H_ +#define _DV_DDR2_DEFS_H_ + +/* + * DDR2 Memory Ctrl Register structure + * See sprueh7d.pdf for more details. + */ +struct dv_ddr2_regs_ctrl { + unsigned char rsvd0[4]; /* 0x00 */ + unsigned int sdrstat; /* 0x04 */ + unsigned int sdbcr; /* 0x08 */ + unsigned int sdrcr; /* 0x0C */ + unsigned int sdtimr; /* 0x10 */ + unsigned int sdtimr2; /* 0x14 */ + unsigned char rsvd1[4]; /* 0x18 */ + unsigned int sdbcr2; /* 0x1C */ + unsigned int pbbpr; /* 0x20 */ + unsigned char rsvd2[156]; /* 0x24 */ + unsigned int irr; /* 0xC0 */ + unsigned int imr; /* 0xC4 */ + unsigned int imsr; /* 0xC8 */ + unsigned int imcr; /* 0xCC */ + unsigned char rsvd3[20]; /* 0xD0 */ + unsigned int ddrphycr; /* 0xE4 */ + unsigned int ddrphycr2; /* 0xE8 */ + unsigned char rsvd4[4]; /* 0xEC */ +}; + +#define DV_DDR_PHY_PWRDNEN 0x40 +#define DV_DDR_PHY_EXT_STRBEN 0x80 +#define DV_DDR_PHY_RD_LATENCY_SHIFT 0 + +#define DV_DDR_SDTMR1_RFC_SHIFT 25 +#define DV_DDR_SDTMR1_RP_SHIFT 22 +#define DV_DDR_SDTMR1_RCD_SHIFT 19 +#define DV_DDR_SDTMR1_WR_SHIFT 16 +#define DV_DDR_SDTMR1_RAS_SHIFT 11 +#define DV_DDR_SDTMR1_RC_SHIFT 6 +#define DV_DDR_SDTMR1_RRD_SHIFT 3 +#define DV_DDR_SDTMR1_WTR_SHIFT 0 + +#define DV_DDR_SDTMR2_RASMAX_SHIFT 27 +#define DV_DDR_SDTMR2_XP_SHIFT 25 +#define DV_DDR_SDTMR2_ODT_SHIFT 23 +#define DV_DDR_SDTMR2_XSNR_SHIFT 16 +#define DV_DDR_SDTMR2_XSRD_SHIFT 8 +#define DV_DDR_SDTMR2_RTP_SHIFT 5 +#define DV_DDR_SDTMR2_CKE_SHIFT 0 + +#define DV_DDR_SDCR_DDR2TERM1_SHIFT 27 +#define DV_DDR_SDCR_IBANK_POS_SHIFT 26 +#define DV_DDR_SDCR_MSDRAMEN_SHIFT 25 +#define DV_DDR_SDCR_DDRDRIVE1_SHIFT 24 +#define DV_DDR_SDCR_BOOTUNLOCK_SHIFT 23 +#define DV_DDR_SDCR_DDR_DDQS_SHIFT 22 +#define DV_DDR_SDCR_DDR2EN_SHIFT 20 +#define DV_DDR_SDCR_DDRDRIVE0_SHIFT 18 +#define DV_DDR_SDCR_DDREN_SHIFT 17 +#define DV_DDR_SDCR_SDRAMEN_SHIFT 16 +#define DV_DDR_SDCR_TIMUNLOCK_SHIFT 15 +#define DV_DDR_SDCR_BUS_WIDTH_SHIFT 14 +#define DV_DDR_SDCR_CL_SHIFT 9 +#define DV_DDR_SDCR_IBANK_SHIFT 4 +#define DV_DDR_SDCR_PAGESIZE_SHIFT 0 + +#define DV_DDR_SDRCR_LPMODEN (1 << 31) +#define DV_DDR_SDRCR_MCLKSTOPEN (1 << 30) + +#define DV_DDR_SRCR_LPMODEN_SHIFT 31 +#define DV_DDR_SRCR_MCLKSTOPEN_SHIFT 30 + +#define DV_DDR_BOOTUNLOCK (1 << DV_DDR_SDCR_BOOTUNLOCK_SHIFT) +#define DV_DDR_TIMUNLOCK (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT) + +#define dv_ddr2_regs_ctrl \ + ((struct dv_ddr2_regs_ctrl *)DAVINCI_DDR_EMIF_CTRL_BASE) + +#endif /* _DV_DDR2_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/dm365_lowlevel.h b/arch/arm/mach-davinci/include/mach/dm365_lowlevel.h new file mode 100644 index 0000000000..6c0275efa7 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/dm365_lowlevel.h @@ -0,0 +1,25 @@ +/* + * SoC-specific lowlevel code for tms320dm365 and similar chips + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __DM365_LOWLEVEL_H +#define __DM365_LOWLEVEL_H + +#include +#include +#include + +void dm365_waitloop(unsigned long loopcnt); +int dm365_pll1_init(unsigned long pllmult, unsigned long prediv); +int dm365_pll2_init(unsigned long pllm, unsigned long prediv); +int dm365_ddr_setup(void); +void dm365_psc_init(void); +void dm365_pinmux_ctl(unsigned long offset, unsigned long mask, + unsigned long value); +void dm36x_lowlevel_init(ulong bootflag); + +#endif /* #ifndef __DM365_LOWLEVEL_H */ diff --git a/arch/arm/mach-davinci/include/mach/emac_defs.h b/arch/arm/mach-davinci/include/mach/emac_defs.h new file mode 100644 index 0000000000..c3f046efa8 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/emac_defs.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2007 Sergey Kubushyn + * + * Based on: + * + * ---------------------------------------------------------------------------- + * + * dm644x_emac.h + * + * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM + * + * Copyright (C) 2005 Texas Instruments. + * + * ---------------------------------------------------------------------------- + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Modifications: + * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot. + */ + +#ifndef _DM644X_EMAC_H_ +#define _DM644X_EMAC_H_ + +#include + +#ifdef CONFIG_SOC_DM365 +#define EMAC_BASE_ADDR (0x01d07000) +#define EMAC_WRAPPER_BASE_ADDR (0x01d0a000) +#define EMAC_WRAPPER_RAM_ADDR (0x01d08000) +#define EMAC_MDIO_BASE_ADDR (0x01d0b000) +#define DAVINCI_EMAC_VERSION2 +#elif defined(CONFIG_SOC_DA8XX) +#define EMAC_BASE_ADDR DAVINCI_EMAC_CNTRL_REGS_BASE +#define EMAC_WRAPPER_BASE_ADDR DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE +#define EMAC_WRAPPER_RAM_ADDR DAVINCI_EMAC_WRAPPER_RAM_BASE +#define EMAC_MDIO_BASE_ADDR DAVINCI_MDIO_CNTRL_REGS_BASE +#define DAVINCI_EMAC_VERSION2 +#else +#define EMAC_BASE_ADDR (0x01c80000) +#define EMAC_WRAPPER_BASE_ADDR (0x01c81000) +#define EMAC_WRAPPER_RAM_ADDR (0x01c82000) +#define EMAC_MDIO_BASE_ADDR (0x01c84000) +#endif + +#ifdef CONFIG_SOC_DM646X +#define DAVINCI_EMAC_VERSION2 +#define DAVINCI_EMAC_GIG_ENABLE +#endif + +#ifdef CONFIG_SOC_DM646X +/* MDIO module input frequency */ +#define EMAC_MDIO_BUS_FREQ 76500000 +/* MDIO clock output frequency */ +#define EMAC_MDIO_CLOCK_FREQ 2500000 /* 2.5 MHz */ +#elif defined(CONFIG_SOC_DM365) +/* MDIO module input frequency */ +#define EMAC_MDIO_BUS_FREQ 121500000 +/* MDIO clock output frequency */ +#define EMAC_MDIO_CLOCK_FREQ 2200000 /* 2.2 MHz */ +#elif defined(CONFIG_SOC_DA8XX) +/* MDIO module input frequency */ +#define EMAC_MDIO_BUS_FREQ clk_get(DAVINCI_MDIO_CLKID) +/* MDIO clock output frequency */ +#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ +#else +/* MDIO module input frequency */ +#define EMAC_MDIO_BUS_FREQ 99000000 /* PLL/6 - 99 MHz */ +/* MDIO clock output frequency */ +#define EMAC_MDIO_CLOCK_FREQ 2000000 /* 2.0 MHz */ +#endif + +#define PHY_KSZ8873 (0x00221450) +int ksz8873_is_phy_connected(int phy_addr); +int ksz8873_get_link_speed(int phy_addr); +int ksz8873_init_phy(int phy_addr); +int ksz8873_auto_negotiate(int phy_addr); + +#define PHY_LXT972 (0x001378e2) +int lxt972_is_phy_connected(int phy_addr); +int lxt972_get_link_speed(int phy_addr); +int lxt972_init_phy(int phy_addr); +int lxt972_auto_negotiate(int phy_addr); + +#define PHY_DP83848 (0x20005c90) +int dp83848_is_phy_connected(int phy_addr); +int dp83848_get_link_speed(int phy_addr); +int dp83848_init_phy(int phy_addr); +int dp83848_auto_negotiate(int phy_addr); + +#define PHY_ET1011C (0x282f013) +int et1011c_get_link_speed(int phy_addr); + +#endif /* _DM644X_EMAC_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h new file mode 100644 index 0000000000..7da0060cd4 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Texas Instruments Incorporated + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _GPIO_DEFS_H_ +#define _GPIO_DEFS_H_ + +#ifndef CONFIG_SOC_DA8XX +#define DAVINCI_GPIO_BINTEN 0x01C67008 +#define DAVINCI_GPIO_BANK01 0x01C67010 +#define DAVINCI_GPIO_BANK23 0x01C67038 +#define DAVINCI_GPIO_BANK45 0x01C67060 +#define DAVINCI_GPIO_BANK67 0x01C67088 + +#else /* CONFIG_SOC_DA8XX */ +#define DAVINCI_GPIO_BINTEN 0x01E26008 +#define DAVINCI_GPIO_BANK01 0x01E26010 +#define DAVINCI_GPIO_BANK23 0x01E26038 +#define DAVINCI_GPIO_BANK45 0x01E26060 +#define DAVINCI_GPIO_BANK67 0x01E26088 +#define DAVINCI_GPIO_BANK8 0x01E260B0 +#endif /* CONFIG_SOC_DA8XX */ + +struct davinci_gpio { + unsigned int dir; + unsigned int out_data; + unsigned int set_data; + unsigned int clr_data; + unsigned int in_data; + unsigned int set_rising; + unsigned int clr_rising; + unsigned int set_falling; + unsigned int clr_falling; + unsigned int intstat; +}; + +struct davinci_gpio_bank { + int num_gpio; + unsigned int irq_num; + unsigned int irq_mask; + unsigned long *in_use; + unsigned long base; +}; + +#define davinci_gpio_bank01 ((struct davinci_gpio *)DAVINCI_GPIO_BANK01) +#define davinci_gpio_bank23 ((struct davinci_gpio *)DAVINCI_GPIO_BANK23) +#define davinci_gpio_bank45 ((struct davinci_gpio *)DAVINCI_GPIO_BANK45) +#define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) +#define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8) + +#define gpio_status() gpio_info() +#define GPIO_NAME_SIZE 20 +#if defined(CONFIG_SOC_DM644X) +/* GPIO0 to GPIO53, omit the V3.3 volts one */ +#define MAX_NUM_GPIOS 70 +#elif defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850) +#define MAX_NUM_GPIOS 128 +#else +#define MAX_NUM_GPIOS 144 +#endif +#define GPIO_BANK(gp) (davinci_gpio_bank01 + ((gp) >> 5)) +#define GPIO_BIT(gp) ((gp) & 0x1F) + +void gpio_info(void); + +#endif diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h new file mode 100644 index 0000000000..a4eb0bd89b --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/hardware.h @@ -0,0 +1,616 @@ +/* + * Copyright (C) 2007 Sergey Kubushyn + * + * Based on: + * + * ------------------------------------------------------------------------- + * + * linux/include/asm-arm/arch-davinci/hardware.h + * + * Copyright (C) 2006 Texas Instruments. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include +#include + +#define REG(addr) (*(volatile unsigned int *)(addr)) +#define REG_P(addr) ((volatile unsigned int *)(addr)) + +typedef volatile unsigned int dv_reg; +typedef volatile unsigned int * dv_reg_p; + +/* + * Base register addresses + * + * NOTE: some of these DM6446-specific addresses DO NOT WORK + * on other DaVinci chips. Double check them before you try + * using the addresses ... or PSC module identifiers, etc. + */ +#ifndef CONFIG_SOC_DA8XX + +#define DAVINCI_DMA_3PCC_BASE (0x01c00000) +#define DAVINCI_DMA_3PTC0_BASE (0x01c10000) +#define DAVINCI_DMA_3PTC1_BASE (0x01c10400) +#define DAVINCI_UART0_BASE (0x01c20000) +#define DAVINCI_UART1_BASE (0x01c20400) +#define DAVINCI_TIMER3_BASE (0x01c20800) +#define DAVINCI_I2C_BASE (0x01c21000) +#define DAVINCI_TIMER0_BASE (0x01c21400) +#define DAVINCI_TIMER1_BASE (0x01c21800) +#define DAVINCI_WDOG_BASE (0x01c21c00) +#define DAVINCI_PWM0_BASE (0x01c22000) +#define DAVINCI_PWM1_BASE (0x01c22400) +#define DAVINCI_PWM2_BASE (0x01c22800) +#define DAVINCI_TIMER4_BASE (0x01c23800) +#define DAVINCI_SYSTEM_MODULE_BASE (0x01c40000) +#define DAVINCI_PLL_CNTRL0_BASE (0x01c40800) +#define DAVINCI_PLL_CNTRL1_BASE (0x01c40c00) +#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01c41000) +#define DAVINCI_ARM_INTC_BASE (0x01c48000) +#define DAVINCI_USB_OTG_BASE (0x01c64000) +#define DAVINCI_CFC_ATA_BASE (0x01c66000) +#define DAVINCI_SPI_BASE (0x01c66800) +#define DAVINCI_GPIO_BASE (0x01c67000) +#define DAVINCI_VPSS_REGS_BASE (0x01c70000) +#if !defined(CONFIG_SOC_DM646X) +#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000) +#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000) +#endif +#define DAVINCI_DDR_BASE (0x80000000) + +#ifdef CONFIG_SOC_DM644X +#define DAVINCI_UART2_BASE 0x01c20800 +#define DAVINCI_UHPI_BASE 0x01c67800 +#define DAVINCI_EMAC_CNTRL_REGS_BASE 0x01c80000 +#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x01c81000 +#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x01c82000 +#define DAVINCI_MDIO_CNTRL_REGS_BASE 0x01c84000 +#define DAVINCI_IMCOP_BASE 0x01cc0000 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01e00000 +#define DAVINCI_VLYNQ_BASE 0x01e01000 +#define DAVINCI_ASP_BASE 0x01e02000 +#define DAVINCI_MMC_SD_BASE 0x01e10000 +#define DAVINCI_MS_BASE 0x01e20000 +#define DAVINCI_VLYNQ_REMOTE_BASE 0x0c000000 + +#elif defined(CONFIG_SOC_DM355) +#define DAVINCI_MMC_SD1_BASE 0x01e00000 +#define DAVINCI_ASP0_BASE 0x01e02000 +#define DAVINCI_ASP1_BASE 0x01e04000 +#define DAVINCI_UART2_BASE 0x01e06000 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01e10000 +#define DAVINCI_MMC_SD0_BASE 0x01e11000 + +#elif defined(CONFIG_SOC_DM365) +#define DAVINCI_MMC_SD1_BASE 0x01d00000 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x01d10000 +#define DAVINCI_MMC_SD0_BASE 0x01d11000 +#define DAVINCI_DDR_EMIF_CTRL_BASE 0x20000000 +#define DAVINCI_SPI0_BASE 0x01c66000 +#define DAVINCI_SPI1_BASE 0x01c66800 + +#elif defined(CONFIG_SOC_DM646X) +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x20008000 +#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x42000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x44000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x46000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x48000000 + +#endif + +#else /* CONFIG_SOC_DA8XX */ + +#define DAVINCI_UART0_BASE 0x01c42000 +#define DAVINCI_UART1_BASE 0x01d0c000 +#define DAVINCI_UART2_BASE 0x01d0d000 +#define DAVINCI_I2C0_BASE 0x01c22000 +#define DAVINCI_I2C1_BASE 0x01e28000 +#define DAVINCI_TIMER0_BASE 0x01c20000 +#define DAVINCI_TIMER1_BASE 0x01c21000 +#define DAVINCI_WDOG_BASE 0x01c21000 +#define DAVINCI_RTC_BASE 0x01c23000 +#define DAVINCI_PLL_CNTRL0_BASE 0x01c11000 +#define DAVINCI_PLL_CNTRL1_BASE 0x01e1a000 +#define DAVINCI_PSC0_BASE 0x01c10000 +#define DAVINCI_PSC1_BASE 0x01e27000 +#define DAVINCI_SPI0_BASE 0x01c41000 +#define DAVINCI_USB_OTG_BASE 0x01e00000 +#define DAVINCI_SPI1_BASE (cpu_is_da830() ? \ + 0x01e12000 : 0x01f0e000) +#define DAVINCI_GPIO_BASE 0x01e26000 +#define DAVINCI_EMAC_CNTRL_REGS_BASE 0x01e23000 +#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE 0x01e22000 +#define DAVINCI_EMAC_WRAPPER_RAM_BASE 0x01e20000 +#define DAVINCI_MDIO_CNTRL_REGS_BASE 0x01e24000 +#define DAVINCI_SYSCFG1_BASE 0x01e2c000 +#define DAVINCI_MMC_SD0_BASE 0x01c40000 +#define DAVINCI_MMC_SD1_BASE 0x01e1b000 +#define DAVINCI_TIMER2_BASE 0x01f0c000 +#define DAVINCI_TIMER3_BASE 0x01f0d000 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE 0x68000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x40000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x60000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x62000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE4_BASE 0x64000000 +#define DAVINCI_ASYNC_EMIF_DATA_CE5_BASE 0x66000000 +#define DAVINCI_DDR_EMIF_CTRL_BASE 0xb0000000 +#define DAVINCI_DDR_EMIF_DATA_BASE 0xc0000000 +#define DAVINCI_INTC_BASE 0xfffee000 +#define DAVINCI_BOOTCFG_BASE 0x01c14000 +#define DAVINCI_LCD_CNTL_BASE 0x01e13000 +#define DAVINCI_L3CBARAM_BASE 0x80000000 +#define JTAG_ID_REG (DAVINCI_BOOTCFG_BASE + 0x18) +#define CHIP_REV_ID_REG (DAVINCI_BOOTCFG_BASE + 0x24) +#define HOST1CFG (DAVINCI_BOOTCFG_BASE + 0x44) +#define PSC0_MDCTL (DAVINCI_PSC0_BASE + 0xa00) + +#define GPIO_BANK0_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x10) +#define GPIO_BANK0_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x14) +#define GPIO_BANK0_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x18) +#define GPIO_BANK0_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x1c) +#define GPIO_BANK2_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x38) +#define GPIO_BANK2_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x3c) +#define GPIO_BANK2_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x40) +#define GPIO_BANK2_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x44) +#define GPIO_BANK6_REG_DIR_ADDR (DAVINCI_GPIO_BASE + 0x88) +#define GPIO_BANK6_REG_OPDATA_ADDR (DAVINCI_GPIO_BASE + 0x8c) +#define GPIO_BANK6_REG_SET_ADDR (DAVINCI_GPIO_BASE + 0x90) +#define GPIO_BANK6_REG_CLR_ADDR (DAVINCI_GPIO_BASE + 0x94) +#endif /* CONFIG_SOC_DA8XX */ + +/* Power and Sleep Controller (PSC) Domains */ +#define DAVINCI_GPSC_ARMDOMAIN 0 +#define DAVINCI_GPSC_DSPDOMAIN 1 + +#ifndef CONFIG_SOC_DA8XX + +#define DAVINCI_LPSC_VPSSMSTR 0 +#define DAVINCI_LPSC_VPSSSLV 1 +#define DAVINCI_LPSC_TPCC 2 +#define DAVINCI_LPSC_TPTC0 3 +#define DAVINCI_LPSC_TPTC1 4 +#define DAVINCI_LPSC_EMAC 5 +#define DAVINCI_LPSC_EMAC_WRAPPER 6 +#define DAVINCI_LPSC_MDIO 7 +#define DAVINCI_LPSC_IEEE1394 8 +#define DAVINCI_LPSC_USB 9 +#define DAVINCI_LPSC_ATA 10 +#define DAVINCI_LPSC_VLYNQ 11 +#define DAVINCI_LPSC_UHPI 12 +#define DAVINCI_LPSC_DDR_EMIF 13 +#define DAVINCI_LPSC_AEMIF 14 +#define DAVINCI_LPSC_MMC_SD 15 +#define DAVINCI_LPSC_MEMSTICK 16 +#define DAVINCI_LPSC_McBSP 17 +#define DAVINCI_LPSC_I2C 18 +#define DAVINCI_LPSC_UART0 19 +#define DAVINCI_LPSC_UART1 20 +#define DAVINCI_LPSC_UART2 21 +#define DAVINCI_LPSC_SPI 22 +#define DAVINCI_LPSC_PWM0 23 +#define DAVINCI_LPSC_PWM1 24 +#define DAVINCI_LPSC_PWM2 25 +#define DAVINCI_LPSC_GPIO 26 +#define DAVINCI_LPSC_TIMER0 27 +#define DAVINCI_LPSC_TIMER1 28 +#define DAVINCI_LPSC_TIMER2 29 +#define DAVINCI_LPSC_SYSTEM_SUBSYS 30 +#define DAVINCI_LPSC_ARM 31 +#define DAVINCI_LPSC_SCR2 32 +#define DAVINCI_LPSC_SCR3 33 +#define DAVINCI_LPSC_SCR4 34 +#define DAVINCI_LPSC_CROSSBAR 35 +#define DAVINCI_LPSC_CFG27 36 +#define DAVINCI_LPSC_CFG3 37 +#define DAVINCI_LPSC_CFG5 38 +#define DAVINCI_LPSC_GEM 39 +#define DAVINCI_LPSC_IMCOP 40 +#define DAVINCI_LPSC_VPSSMASTER 47 +#define DAVINCI_LPSC_MJCP 50 +#define DAVINCI_LPSC_HDVICP 51 + +#define DAVINCI_DM646X_LPSC_EMAC 14 +#define DAVINCI_DM646X_LPSC_UART0 26 +#define DAVINCI_DM646X_LPSC_I2C 31 +#define DAVINCI_DM646X_LPSC_TIMER0 34 + +#else /* CONFIG_SOC_DA8XX */ + +#define DAVINCI_LPSC_TPCC 0 +#define DAVINCI_LPSC_TPTC0 1 +#define DAVINCI_LPSC_TPTC1 2 +#define DAVINCI_LPSC_AEMIF 3 +#define DAVINCI_LPSC_SPI0 4 +#define DAVINCI_LPSC_MMC_SD 5 +#define DAVINCI_LPSC_AINTC 6 +#define DAVINCI_LPSC_ARM_RAM_ROM 7 +#define DAVINCI_LPSC_SECCTL_KEYMGR 8 +#define DAVINCI_LPSC_UART0 9 +#define DAVINCI_LPSC_SCR0 10 +#define DAVINCI_LPSC_SCR1 11 +#define DAVINCI_LPSC_SCR2 12 +#define DAVINCI_LPSC_DMAX 13 +#define DAVINCI_LPSC_ARM 14 +#define DAVINCI_LPSC_GEM 15 + +/* for LPSCs in PSC1, offset from 32 for differentiation */ +#define DAVINCI_LPSC_PSC1_BASE 32 +#define DAVINCI_LPSC_USB20 (DAVINCI_LPSC_PSC1_BASE + 1) +#define DAVINCI_LPSC_USB11 (DAVINCI_LPSC_PSC1_BASE + 2) +#define DAVINCI_LPSC_GPIO (DAVINCI_LPSC_PSC1_BASE + 3) +#define DAVINCI_LPSC_UHPI (DAVINCI_LPSC_PSC1_BASE + 4) +#define DAVINCI_LPSC_EMAC (DAVINCI_LPSC_PSC1_BASE + 5) +#define DAVINCI_LPSC_DDR_EMIF (DAVINCI_LPSC_PSC1_BASE + 6) +#define DAVINCI_LPSC_McASP0 (DAVINCI_LPSC_PSC1_BASE + 7) +#define DAVINCI_LPSC_SPI1 (DAVINCI_LPSC_PSC1_BASE + 10) +#define DAVINCI_LPSC_I2C1 (DAVINCI_LPSC_PSC1_BASE + 11) +#define DAVINCI_LPSC_UART1 (DAVINCI_LPSC_PSC1_BASE + 12) +#define DAVINCI_LPSC_UART2 (DAVINCI_LPSC_PSC1_BASE + 13) +#define DAVINCI_LPSC_LCDC (DAVINCI_LPSC_PSC1_BASE + 16) +#define DAVINCI_LPSC_ePWM (DAVINCI_LPSC_PSC1_BASE + 17) +#define DAVINCI_LPSC_MMCSD1 (DAVINCI_LPSC_PSC1_BASE + 18) +#define DAVINCI_LPSC_eCAP (DAVINCI_LPSC_PSC1_BASE + 20) +#define DAVINCI_LPSC_L3_CBA_RAM (DAVINCI_LPSC_PSC1_BASE + 31) + +/* DA830-specific peripherals */ +#define DAVINCI_LPSC_McASP1 (DAVINCI_LPSC_PSC1_BASE + 8) +#define DAVINCI_LPSC_McASP2 (DAVINCI_LPSC_PSC1_BASE + 9) +#define DAVINCI_LPSC_eQEP (DAVINCI_LPSC_PSC1_BASE + 21) +#define DAVINCI_LPSC_SCR8 (DAVINCI_LPSC_PSC1_BASE + 24) +#define DAVINCI_LPSC_SCR7 (DAVINCI_LPSC_PSC1_BASE + 25) +#define DAVINCI_LPSC_SCR12 (DAVINCI_LPSC_PSC1_BASE + 26) + +/* DA850-specific peripherals */ +#define DAVINCI_LPSC_TPCC1 (DAVINCI_LPSC_PSC1_BASE + 0) +#define DAVINCI_LPSC_SATA (DAVINCI_LPSC_PSC1_BASE + 8) +#define DAVINCI_LPSC_VPIF (DAVINCI_LPSC_PSC1_BASE + 9) +#define DAVINCI_LPSC_McBSP0 (DAVINCI_LPSC_PSC1_BASE + 14) +#define DAVINCI_LPSC_McBSP1 (DAVINCI_LPSC_PSC1_BASE + 15) +#define DAVINCI_LPSC_MMC_SD1 (DAVINCI_LPSC_PSC1_BASE + 18) +#define DAVINCI_LPSC_uPP (DAVINCI_LPSC_PSC1_BASE + 19) +#define DAVINCI_LPSC_TPTC2 (DAVINCI_LPSC_PSC1_BASE + 21) +#define DAVINCI_LPSC_SCR_F0 (DAVINCI_LPSC_PSC1_BASE + 24) +#define DAVINCI_LPSC_SCR_F1 (DAVINCI_LPSC_PSC1_BASE + 25) +#define DAVINCI_LPSC_SCR_F2 (DAVINCI_LPSC_PSC1_BASE + 26) +#define DAVINCI_LPSC_SCR_F6 (DAVINCI_LPSC_PSC1_BASE + 27) +#define DAVINCI_LPSC_SCR_F7 (DAVINCI_LPSC_PSC1_BASE + 28) +#define DAVINCI_LPSC_SCR_F8 (DAVINCI_LPSC_PSC1_BASE + 29) +#define DAVINCI_LPSC_BR_F7 (DAVINCI_LPSC_PSC1_BASE + 30) + +#endif /* CONFIG_SOC_DA8XX */ + +void lpsc_on(unsigned int id); +void lpsc_syncreset(unsigned int id); +void lpsc_disable(unsigned int id); +void dsp_on(void); + +void davinci_enable_uart0(void); +void davinci_enable_emac(void); +void davinci_enable_i2c(void); +void davinci_errata_workarounds(void); + +#ifndef CONFIG_SOC_DA8XX + +/* Some PSC defines */ +#define PSC_CHP_SHRTSW (0x01c40038) +#define PSC_GBLCTL (0x01c41010) +#define PSC_EPCPR (0x01c41070) +#define PSC_EPCCR (0x01c41078) +#define PSC_PTCMD (0x01c41120) +#define PSC_PTSTAT (0x01c41128) +#define PSC_PDSTAT (0x01c41200) +#define PSC_PDSTAT1 (0x01c41204) +#define PSC_PDCTL (0x01c41300) +#define PSC_PDCTL1 (0x01c41304) + +#define PSC_MDCTL_BASE (0x01c41a00) +#define PSC_MDSTAT_BASE (0x01c41800) + +#define VDD3P3V_PWDN (0x01c40048) +#define UART0_PWREMU_MGMT (0x01c20030) + +#define PSC_SILVER_BULLET (0x01c41a20) + +#else /* CONFIG_SOC_DA8XX */ + +#define PSC_ENABLE 0x3 +#define PSC_DISABLE 0x2 +#define PSC_SYNCRESET 0x1 +#define PSC_SWRSTDISABLE 0x0 + +#define PSC_PSC0_MODULE_ID_CNT 16 +#define PSC_PSC1_MODULE_ID_CNT 32 + +#define UART0_PWREMU_MGMT (0x01c42030) + +struct davinci_psc_regs { + dv_reg revid; + dv_reg rsvd0[71]; + dv_reg ptcmd; + dv_reg rsvd1; + dv_reg ptstat; + dv_reg rsvd2[437]; + union { + struct { + dv_reg mdstat[PSC_PSC0_MODULE_ID_CNT]; + dv_reg rsvd3[112]; + dv_reg mdctl[PSC_PSC0_MODULE_ID_CNT]; + } psc0; + struct { + dv_reg mdstat[PSC_PSC1_MODULE_ID_CNT]; + dv_reg rsvd3[96]; + dv_reg mdctl[PSC_PSC1_MODULE_ID_CNT]; + } psc1; + }; +}; + +#define davinci_psc0_regs ((struct davinci_psc_regs *)DAVINCI_PSC0_BASE) +#define davinci_psc1_regs ((struct davinci_psc_regs *)DAVINCI_PSC1_BASE) + +#endif /* CONFIG_SOC_DA8XX */ + +#define PSC_MDSTAT_STATE 0x3f +#define PSC_MDCTL_NEXT 0x07 + +#ifndef CONFIG_SOC_DA8XX + +/* Miscellania... */ +#define VBPR (0x20000020) + +/* NOTE: system control modules are *highly* chip-specific, both + * as to register content (e.g. for muxing) and which registers exist. + */ +#define PINMUX0 0x01c40000 +#define PINMUX1 0x01c40004 +#define PINMUX2 0x01c40008 +#define PINMUX3 0x01c4000c +#define PINMUX4 0x01c40010 + +struct davinci_uart_ctrl_regs { + dv_reg revid1; + dv_reg res; + dv_reg pwremu_mgmt; + dv_reg mdr; +}; + +#define DAVINCI_UART_CTRL_BASE 0x28 + +/* UART PWREMU_MGMT definitions */ +#define DAVINCI_UART_PWREMU_MGMT_FREE (1 << 0) +#define DAVINCI_UART_PWREMU_MGMT_URRST (1 << 13) +#define DAVINCI_UART_PWREMU_MGMT_UTRST (1 << 14) + +#else /* CONFIG_SOC_DA8XX */ + +struct davinci_pllc_regs { + dv_reg revid; + dv_reg rsvd1[56]; + dv_reg rstype; + dv_reg rsvd2[6]; + dv_reg pllctl; + dv_reg ocsel; + dv_reg rsvd3[2]; + dv_reg pllm; + dv_reg prediv; + dv_reg plldiv1; + dv_reg plldiv2; + dv_reg plldiv3; + dv_reg oscdiv; + dv_reg postdiv; + dv_reg rsvd4[3]; + dv_reg pllcmd; + dv_reg pllstat; + dv_reg alnctl; + dv_reg dchange; + dv_reg cken; + dv_reg ckstat; + dv_reg systat; + dv_reg rsvd5[3]; + dv_reg plldiv4; + dv_reg plldiv5; + dv_reg plldiv6; + dv_reg plldiv7; + dv_reg rsvd6[32]; + dv_reg emucnt0; + dv_reg emucnt1; +}; + +#define davinci_pllc0_regs ((struct davinci_pllc_regs *)DAVINCI_PLL_CNTRL0_BASE) +#define davinci_pllc1_regs ((struct davinci_pllc_regs *)DAVINCI_PLL_CNTRL1_BASE) +#define DAVINCI_PLLC_DIV_MASK 0x1f + +/* + * A clock ID is a 32-bit number where bit 16 represents the PLL controller + * (clear is PLLC0, set is PLLC1) and the low 16 bits represent the divisor, + * counting from 1. Clock IDs may be passed to clk_get(). + */ + +/* flags to select PLL controller */ +#define DAVINCI_PLLC0_FLAG (0) +#define DAVINCI_PLLC1_FLAG (1 << 16) + +enum davinci_clk_ids { + /* + * Clock IDs for PLL outputs. Each may be switched on/off + * independently, and each may map to one or more peripherals. + */ + DAVINCI_PLL0_SYSCLK2 = DAVINCI_PLLC0_FLAG | 2, + DAVINCI_PLL0_SYSCLK4 = DAVINCI_PLLC0_FLAG | 4, + DAVINCI_PLL0_SYSCLK6 = DAVINCI_PLLC0_FLAG | 6, + DAVINCI_PLL1_SYSCLK1 = DAVINCI_PLLC1_FLAG | 1, + DAVINCI_PLL1_SYSCLK2 = DAVINCI_PLLC1_FLAG | 2, + + /* map peripherals to clock IDs */ + DAVINCI_ARM_CLKID = DAVINCI_PLL0_SYSCLK6, + DAVINCI_DDR_CLKID = DAVINCI_PLL1_SYSCLK1, + DAVINCI_MDIO_CLKID = DAVINCI_PLL0_SYSCLK4, + DAVINCI_MMC_CLKID = DAVINCI_PLL0_SYSCLK2, + DAVINCI_SPI0_CLKID = DAVINCI_PLL0_SYSCLK2, + DAVINCI_MMCSD_CLKID = DAVINCI_PLL0_SYSCLK2, + + /* special clock ID - output of PLL multiplier */ + DAVINCI_PLLM_CLKID = 0x0FF, + + /* special clock ID - output of PLL post divisor */ + DAVINCI_PLLC_CLKID = 0x100, + + /* special clock ID - PLL bypass */ + DAVINCI_AUXCLK_CLKID = 0x101, +}; + +#define DAVINCI_UART2_CLKID (cpu_is_da830() ? DAVINCI_PLL0_SYSCLK2 \ + : get_async3_src()) + +#define DAVINCI_SPI1_CLKID (cpu_is_da830() ? DAVINCI_PLL0_SYSCLK2 \ + : get_async3_src()) + +int clk_get(enum davinci_clk_ids id); + +/* Boot config */ +struct davinci_syscfg_regs { + dv_reg revid; + dv_reg rsvd[13]; + dv_reg kick0; + dv_reg kick1; + dv_reg rsvd1[52]; + dv_reg mstpri[3]; + dv_reg rsvd2; + dv_reg pinmux[20]; + dv_reg suspsrc; + dv_reg chipsig; + dv_reg chipsig_clr; + dv_reg cfgchip0; + dv_reg cfgchip1; + dv_reg cfgchip2; + dv_reg cfgchip3; + dv_reg cfgchip4; +}; + +#define davinci_syscfg_regs \ + ((struct davinci_syscfg_regs *)DAVINCI_BOOTCFG_BASE) + +#define pinmux(x) (&davinci_syscfg_regs->pinmux[x]) + +/* Emulation suspend bits */ +#define DAVINCI_SYSCFG_SUSPSRC_EMAC (1 << 5) +#define DAVINCI_SYSCFG_SUSPSRC_I2C (1 << 16) +#define DAVINCI_SYSCFG_SUSPSRC_SPI0 (1 << 21) +#define DAVINCI_SYSCFG_SUSPSRC_SPI1 (1 << 22) +#define DAVINCI_SYSCFG_SUSPSRC_UART0 (1 << 18) +#define DAVINCI_SYSCFG_SUSPSRC_UART2 (1 << 20) +#define DAVINCI_SYSCFG_SUSPSRC_TIMER0 (1 << 27) + +struct davinci_syscfg1_regs { + dv_reg vtpio_ctl; + dv_reg ddr_slew; + dv_reg deepsleep; + dv_reg pupd_ena; + dv_reg pupd_sel; + dv_reg rxactive; + dv_reg pwrdwn; +}; + +#define davinci_syscfg1_regs \ + ((struct davinci_syscfg1_regs *)DAVINCI_SYSCFG1_BASE) + +#define DDR_SLEW_CMOSEN_BIT 4 +#define DDR_SLEW_DDR_PDENA_BIT 5 + +#define VTP_POWERDWN (1 << 6) +#define VTP_LOCK (1 << 7) +#define VTP_CLKRZ (1 << 13) +#define VTP_READY (1 << 15) +#define VTP_IOPWRDWN (1 << 14) + +#define DV_SYSCFG_KICK0_UNLOCK 0x83e70b13 +#define DV_SYSCFG_KICK1_UNLOCK 0x95a4f1e0 + +/* Interrupt controller */ +struct davinci_aintc_regs { + dv_reg revid; + dv_reg cr; + dv_reg dummy0[2]; + dv_reg ger; + dv_reg dummy1[219]; + dv_reg ecr1; + dv_reg ecr2; + dv_reg ecr3; + dv_reg dummy2[1117]; + dv_reg hier; +}; + +#define davinci_aintc_regs ((struct davinci_aintc_regs *)DAVINCI_INTC_BASE) + +struct davinci_uart_ctrl_regs { + dv_reg revid1; + dv_reg revid2; + dv_reg pwremu_mgmt; + dv_reg mdr; +}; + +#define DAVINCI_UART_CTRL_BASE 0x28 +#define DAVINCI_UART0_CTRL_ADDR (DAVINCI_UART0_BASE + DAVINCI_UART_CTRL_BASE) +#define DAVINCI_UART1_CTRL_ADDR (DAVINCI_UART1_BASE + DAVINCI_UART_CTRL_BASE) +#define DAVINCI_UART2_CTRL_ADDR (DAVINCI_UART2_BASE + DAVINCI_UART_CTRL_BASE) + +#define davinci_uart0_ctrl_regs \ + ((struct davinci_uart_ctrl_regs *)DAVINCI_UART0_CTRL_ADDR) +#define davinci_uart1_ctrl_regs \ + ((struct davinci_uart_ctrl_regs *)DAVINCI_UART1_CTRL_ADDR) +#define davinci_uart2_ctrl_regs \ + ((struct davinci_uart_ctrl_regs *)DAVINCI_UART2_CTRL_ADDR) + +/* UART PWREMU_MGMT definitions */ +#define DAVINCI_UART_PWREMU_MGMT_FREE (1 << 0) +#define DAVINCI_UART_PWREMU_MGMT_URRST (1 << 13) +#define DAVINCI_UART_PWREMU_MGMT_UTRST (1 << 14) + +static inline int cpu_is_da830(void) +{ + unsigned int jtag_id = REG(JTAG_ID_REG); + unsigned short part_no = (jtag_id >> 12) & 0xffff; + + return ((part_no == 0xb7df) ? 1 : 0); +} +static inline int cpu_is_da850(void) +{ + unsigned int jtag_id = REG(JTAG_ID_REG); + unsigned short part_no = (jtag_id >> 12) & 0xffff; + + return ((part_no == 0xb7d1) ? 1 : 0); +} + +static inline enum davinci_clk_ids get_async3_src(void) +{ + return (REG(&davinci_syscfg_regs->cfgchip3) & 0x10) ? + DAVINCI_PLL1_SYSCLK2 : DAVINCI_PLL0_SYSCLK2; +} + +#endif /* CONFIG_SOC_DA8XX */ + +#if defined(CONFIG_SOC_DM365) +#include +#include +#include +#include +#include +#include +#include + +#define TMPBUF 0x00017ff8 +#define TMPSTATUS 0x00017ff0 +#define DV_TMPBUF_VAL 0x591b3ed7 +#define FLAG_PORRST 0x00000001 +#define FLAG_WDTRST 0x00000002 +#define FLAG_FLGON 0x00000004 +#define FLAG_FLGOFF 0x00000010 + +#endif + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-davinci/include/mach/i2c_defs.h b/arch/arm/mach-davinci/include/mach/i2c_defs.h new file mode 100644 index 0000000000..06da8947b4 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/i2c_defs.h @@ -0,0 +1,18 @@ +/* + * (C) Copyright 2004-2014 + * Texas Instruments, + * + * Some changes copyright (C) 2007 Sergey Kubushyn + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _I2C_DEFS_H_ +#define _I2C_DEFS_H_ + +#ifndef CONFIG_SOC_DA8XX +#define I2C_BASE 0x01c21000 +#else +#define I2C_BASE 0x01c22000 +#endif + +#endif diff --git a/arch/arm/mach-davinci/include/mach/pinmux_defs.h b/arch/arm/mach-davinci/include/mach/pinmux_defs.h new file mode 100644 index 0000000000..2d82af554b --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pinmux_defs.h @@ -0,0 +1,57 @@ +/* + * Pinmux configurations for the DAxxx SoCs + * + * Copyright (C) 2011 OMICRON electronics GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_PINMUX_DEFS_H +#define __ASM_ARCH_PINMUX_DEFS_H + +#include +#include + +/* SPI0 pin muxer settings */ +extern const struct pinmux_config spi0_pins_base[3]; +extern const struct pinmux_config spi0_pins_scs0[1]; +extern const struct pinmux_config spi0_pins_ena[1]; + +/* SPI1 pin muxer settings */ +extern const struct pinmux_config spi1_pins_base[3]; +extern const struct pinmux_config spi1_pins_scs0[1]; + +/* UART pin muxer settings */ +extern const struct pinmux_config uart0_pins_txrx[2]; +extern const struct pinmux_config uart0_pins_rtscts[2]; +extern const struct pinmux_config uart1_pins_txrx[2]; +extern const struct pinmux_config uart2_pins_txrx[2]; +extern const struct pinmux_config uart2_pins_rtscts[2]; + +/* EMAC pin muxer settings*/ +extern const struct pinmux_config emac_pins_rmii[8]; +extern const struct pinmux_config emac_pins_rmii_clk_source[1]; +extern const struct pinmux_config emac_pins_mii[15]; +extern const struct pinmux_config emac_pins_mdio[2]; + +/* I2C pin muxer settings */ +extern const struct pinmux_config i2c0_pins[2]; +extern const struct pinmux_config i2c1_pins[2]; + +/* EMIFA pin muxer settings */ +extern const struct pinmux_config emifa_pins[40]; +extern const struct pinmux_config emifa_pins_cs0[1]; +extern const struct pinmux_config emifa_pins_cs2[1]; +extern const struct pinmux_config emifa_pins_cs3[1]; +extern const struct pinmux_config emifa_pins_cs4[1]; +extern const struct pinmux_config emifa_pins_nand[12]; +extern const struct pinmux_config emifa_pins_nor[43]; + +/* USB pin mux setting */ +extern const struct pinmux_config usb_pins[1]; + +/* MMC pin muxer settings */ +extern const struct pinmux_config mmc0_pins_8bit[10]; +extern const struct pinmux_config mmc0_pins[6]; + +#endif diff --git a/arch/arm/mach-davinci/include/mach/pll_defs.h b/arch/arm/mach-davinci/include/mach/pll_defs.h new file mode 100644 index 0000000000..d083cccadb --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/pll_defs.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DV_PLL_DEFS_H_ +#define _DV_PLL_DEFS_H_ + +struct dv_pll_regs { + unsigned int pid; /* 0x00 */ + unsigned char rsvd0[224]; /* 0x04 */ + unsigned int rstype; /* 0xe4 */ + unsigned char rsvd1[24]; /* 0xe8 */ + unsigned int pllctl; /* 0x100 */ + unsigned char rsvd2[4]; /* 0x104 */ + unsigned int secctl; /* 0x108 */ + unsigned int rv; /* 0x10c */ + unsigned int pllm; /* 0x110 */ + unsigned int prediv; /* 0x114 */ + unsigned int plldiv1; /* 0x118 */ + unsigned int plldiv2; /* 0x11c */ + unsigned int plldiv3; /* 0x120 */ + unsigned int oscdiv1; /* 0x124 */ + unsigned int postdiv; /* 0x128 */ + unsigned int bpdiv; /* 0x12c */ + unsigned char rsvd5[8]; /* 0x130 */ + unsigned int pllcmd; /* 0x138 */ + unsigned int pllstat; /* 0x13c */ + unsigned int alnctl; /* 0x140 */ + unsigned int dchange; /* 0x144 */ + unsigned int cken; /* 0x148 */ + unsigned int ckstat; /* 0x14c */ + unsigned int systat; /* 0x150 */ + unsigned char rsvd6[12]; /* 0x154 */ + unsigned int plldiv4; /* 0x160 */ + unsigned int plldiv5; /* 0x164 */ + unsigned int plldiv6; /* 0x168 */ + unsigned int plldiv7; /* 0x16C */ + unsigned int plldiv8; /* 0x170 */ + unsigned int plldiv9; /* 0x174 */ +}; + +#define PLL_MASTER_LOCK (1 << 4) + +#define PLLCTL_CLOCK_MODE_SHIFT 8 +#define PLLCTL_PLLEN (1 << 0) +#define PLLCTL_PLLPWRDN (1 << 1) +#define PLLCTL_PLLRST (1 << 3) +#define PLLCTL_PLLDIS (1 << 4) +#define PLLCTL_PLLENSRC (1 << 5) +#define PLLCTL_RES_9 (1 << 8) +#define PLLCTL_EXTCLKSRC (1 << 9) + +#define PLL_DIVEN (1 << 15) +#define PLL_POSTDEN PLL_DIVEN + +#define PLL_SCSCFG3_DIV45PENA (1 << 2) +#define PLL_SCSCFG3_EMA_CLKSRC (1 << 1) + +#define PLL_RSTYPE_POR (1 << 0) +#define PLL_RSTYPE_XWRST (1 << 1) + +#define PLLSECCTL_TINITZ (1 << 16) +#define PLLSECCTL_TENABLE (1 << 17) +#define PLLSECCTL_TENABLEDIV (1 << 18) +#define PLLSECCTL_STOPMODE (1 << 22) + +#define PLLCMD_GOSET (1 << 0) +#define PLLCMD_GOSTAT (1 << 0) + +#define PLL0_LOCK 0x07000000 +#define PLL1_LOCK 0x07000000 + +#define dv_pll0_regs ((struct dv_pll_regs *)DAVINCI_PLL_CNTRL0_BASE) +#define dv_pll1_regs ((struct dv_pll_regs *)DAVINCI_PLL_CNTRL1_BASE) + +#define ARM_PLLDIV (offsetof(struct dv_pll_regs, plldiv2)) +#define DDR_PLLDIV (offsetof(struct dv_pll_regs, plldiv7)) +#define SPI_PLLDIV (offsetof(struct dv_pll_regs, plldiv4)) + +unsigned int davinci_clk_get(unsigned int div); +#endif /* _DV_PLL_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/psc_defs.h b/arch/arm/mach-davinci/include/mach/psc_defs.h new file mode 100644 index 0000000000..bcb5580499 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/psc_defs.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DV_PSC_DEFS_H_ +#define _DV_PSC_DEFS_H_ + +/* + * Power/Sleep Ctrl Register structure + * See sprufb3.pdf, Chapter 7 + */ +struct dv_psc_regs { + unsigned int pid; /* 0x000 */ + unsigned char rsvd0[16]; /* 0x004 */ + unsigned char rsvd1[4]; /* 0x014 */ + unsigned int inteval; /* 0x018 */ + unsigned char rsvd2[36]; /* 0x01C */ + unsigned int merrpr0; /* 0x040 */ + unsigned int merrpr1; /* 0x044 */ + unsigned char rsvd3[8]; /* 0x048 */ + unsigned int merrcr0; /* 0x050 */ + unsigned int merrcr1; /* 0x054 */ + unsigned char rsvd4[8]; /* 0x058 */ + unsigned int perrpr; /* 0x060 */ + unsigned char rsvd5[4]; /* 0x064 */ + unsigned int perrcr; /* 0x068 */ + unsigned char rsvd6[4]; /* 0x06C */ + unsigned int epcpr; /* 0x070 */ + unsigned char rsvd7[4]; /* 0x074 */ + unsigned int epccr; /* 0x078 */ + unsigned char rsvd8[144]; /* 0x07C */ + unsigned char rsvd9[20]; /* 0x10C */ + unsigned int ptcmd; /* 0x120 */ + unsigned char rsvd10[4]; /* 0x124 */ + unsigned int ptstat; /* 0x128 */ + unsigned char rsvd11[212]; /* 0x12C */ + unsigned int pdstat0; /* 0x200 */ + unsigned int pdstat1; /* 0x204 */ + unsigned char rsvd12[248]; /* 0x208 */ + unsigned int pdctl0; /* 0x300 */ + unsigned int pdctl1; /* 0x304 */ + unsigned char rsvd13[536]; /* 0x308 */ + unsigned int mckout0; /* 0x520 */ + unsigned int mckout1; /* 0x524 */ + unsigned char rsvd14[728]; /* 0x528 */ + unsigned int mdstat[52]; /* 0x800 */ + unsigned char rsvd15[304]; /* 0x8D0 */ + unsigned int mdctl[52]; /* 0xA00 */ +}; + +/* PSC constants */ +#define EMURSTIE_MASK (0x00000200) + +#define PD0 (0) + +#define PSC_ENABLE (0x3) +#define PSC_DISABLE (0x2) +#define PSC_SYNCRESET (0x1) +#define PSC_SWRSTDISABLE (0x0) + +#define PSC_GOSTAT (1 << 0) +#define PSC_MD_STATE_MSK (0x1f) + +#define PSC_CMD_GO (1 << 0) + +#define dv_psc_regs ((struct dv_psc_regs *)DAVINCI_PWR_SLEEP_CNTRL_BASE) + +#endif /* _DV_PSC_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/sdmmc_defs.h b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h new file mode 100644 index 0000000000..9aa3f4ab27 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h @@ -0,0 +1,164 @@ +/* + * Davinci MMC Controller Defines - Based on Linux davinci_mmc.c + * + * Copyright (C) 2010 Texas Instruments Incorporated + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SDMMC_DEFS_H_ +#define _SDMMC_DEFS_H_ + +#include + +/* MMC Control Reg fields */ +#define MMCCTL_DATRST (1 << 0) +#define MMCCTL_CMDRST (1 << 1) +#define MMCCTL_WIDTH_4_BIT (1 << 2) +#define MMCCTL_DATEG_DISABLED (0 << 6) +#define MMCCTL_DATEG_RISING (1 << 6) +#define MMCCTL_DATEG_FALLING (2 << 6) +#define MMCCTL_DATEG_BOTH (3 << 6) +#define MMCCTL_PERMDR_LE (0 << 9) +#define MMCCTL_PERMDR_BE (1 << 9) +#define MMCCTL_PERMDX_LE (0 << 10) +#define MMCCTL_PERMDX_BE (1 << 10) + +/* MMC Clock Control Reg fields */ +#define MMCCLK_CLKEN (1 << 8) +#define MMCCLK_CLKRT_MASK (0xFF << 0) + +/* MMC Status Reg0 fields */ +#define MMCST0_DATDNE (1 << 0) +#define MMCST0_BSYDNE (1 << 1) +#define MMCST0_RSPDNE (1 << 2) +#define MMCST0_TOUTRD (1 << 3) +#define MMCST0_TOUTRS (1 << 4) +#define MMCST0_CRCWR (1 << 5) +#define MMCST0_CRCRD (1 << 6) +#define MMCST0_CRCRS (1 << 7) +#define MMCST0_DXRDY (1 << 9) +#define MMCST0_DRRDY (1 << 10) +#define MMCST0_DATED (1 << 11) +#define MMCST0_TRNDNE (1 << 12) + +#define MMCST0_ERR_MASK (0x00F8) + +/* MMC Status Reg1 fields */ +#define MMCST1_BUSY (1 << 0) +#define MMCST1_CLKSTP (1 << 1) +#define MMCST1_DXEMP (1 << 2) +#define MMCST1_DRFUL (1 << 3) +#define MMCST1_DAT3ST (1 << 4) +#define MMCST1_FIFOEMP (1 << 5) +#define MMCST1_FIFOFUL (1 << 6) + +/* MMC INT Mask Reg fields */ +#define MMCIM_EDATDNE (1 << 0) +#define MMCIM_EBSYDNE (1 << 1) +#define MMCIM_ERSPDNE (1 << 2) +#define MMCIM_ETOUTRD (1 << 3) +#define MMCIM_ETOUTRS (1 << 4) +#define MMCIM_ECRCWR (1 << 5) +#define MMCIM_ECRCRD (1 << 6) +#define MMCIM_ECRCRS (1 << 7) +#define MMCIM_EDXRDY (1 << 9) +#define MMCIM_EDRRDY (1 << 10) +#define MMCIM_EDATED (1 << 11) +#define MMCIM_ETRNDNE (1 << 12) + +#define MMCIM_MASKALL (0xFFFFFFFF) + +/* MMC Resp Tout Reg fields */ +#define MMCTOR_TOR_MASK (0xFF) /* dont write to reg, | it */ +#define MMCTOR_TOD_20_16_SHIFT (8) + +/* MMC Data Read Tout Reg fields */ +#define MMCTOD_TOD_0_15_MASK (0xFFFF) + +/* MMC Block len Reg fields */ +#define MMCBLEN_BLEN_MASK (0xFFF) + +/* MMC Num Blocks Reg fields */ +#define MMCNBLK_NBLK_MASK (0xFFFF) +#define MMCNBLK_NBLK_MAX (0xFFFF) + +/* MMC Num Blocks Counter Reg fields */ +#define MMCNBLC_NBLC_MASK (0xFFFF) + +/* MMC Cmd Reg fields */ +#define MMCCMD_CMD_MASK (0x3F) +#define MMCCMD_PPLEN (1 << 7) +#define MMCCMD_BSYEXP (1 << 8) +#define MMCCMD_RSPFMT_NONE (0 << 9) +#define MMCCMD_RSPFMT_R1567 (1 << 9) +#define MMCCMD_RSPFMT_R2 (2 << 9) +#define MMCCMD_RSPFMT_R3 (3 << 9) +#define MMCCMD_DTRW (1 << 11) +#define MMCCMD_STRMTP (1 << 12) +#define MMCCMD_WDATX (1 << 13) +#define MMCCMD_INITCK (1 << 14) +#define MMCCMD_DCLR (1 << 15) +#define MMCCMD_DMATRIG (1 << 16) + +/* FIFO control Reg fields */ +#define MMCFIFOCTL_FIFORST (1 << 0) +#define MMCFIFOCTL_FIFODIR (1 << 1) +#define MMCFIFOCTL_FIFOLEV (1 << 2) +#define MMCFIFOCTL_ACCWD_4 (0 << 3) /* access width of 4 bytes */ +#define MMCFIFOCTL_ACCWD_3 (1 << 3) /* access width of 3 bytes */ +#define MMCFIFOCTL_ACCWD_2 (2 << 3) /* access width of 2 bytes */ +#define MMCFIFOCTL_ACCWD_1 (3 << 3) /* access width of 1 byte */ + +/* Davinci MMC Register definitions */ +struct davinci_mmc_regs { + dv_reg mmcctl; + dv_reg mmcclk; + dv_reg mmcst0; + dv_reg mmcst1; + dv_reg mmcim; + dv_reg mmctor; + dv_reg mmctod; + dv_reg mmcblen; + dv_reg mmcnblk; + dv_reg mmcnblc; + dv_reg mmcdrr; + dv_reg mmcdxr; + dv_reg mmccmd; + dv_reg mmcarghl; + dv_reg mmcrsp01; + dv_reg mmcrsp23; + dv_reg mmcrsp45; + dv_reg mmcrsp67; + dv_reg mmcdrsp; + dv_reg mmcetok; + dv_reg mmccidx; + dv_reg mmcckc; + dv_reg mmctorc; + dv_reg mmctodc; + dv_reg mmcblnc; + dv_reg sdioctl; + dv_reg sdiost0; + dv_reg sdioien; + dv_reg sdioist; + dv_reg mmcfifoctl; +}; + +/* Davinci MMC board definitions */ +struct davinci_mmc { + struct davinci_mmc_regs *reg_base; /* Register base address */ + uint input_clk; /* Input clock to MMC controller */ + uint host_caps; /* Host capabilities */ + uint voltages; /* Host supported voltages */ + uint version; /* MMC Controller version */ + struct mmc_config cfg; +}; + +enum { + MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */ + MMC_CTLR_VERSION_2, /* DA830 */ +}; + +int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host); + +#endif /* _SDMMC_DEFS_H */ diff --git a/arch/arm/mach-davinci/include/mach/syscfg_defs.h b/arch/arm/mach-davinci/include/mach/syscfg_defs.h new file mode 100644 index 0000000000..812088f379 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/syscfg_defs.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DV_SYSCFG_DEFS_H_ +#define _DV_SYSCFG_DEFS_H_ + +#ifndef CONFIG_SOC_DA8XX +/* System Control Module register structure for DM365 */ +struct dv_sys_module_regs { + unsigned int pinmux[5]; /* 0x00 */ + unsigned int bootcfg; /* 0x14 */ + unsigned int arm_intmux; /* 0x18 */ + unsigned int edma_evtmux; /* 0x1C */ + unsigned int ddr_slew; /* 0x20 */ + unsigned int clkout; /* 0x24 */ + unsigned int device_id; /* 0x28 */ + unsigned int vdac_config; /* 0x2C */ + unsigned int timer64_ctl; /* 0x30 */ + unsigned int usbbphy_ctl; /* 0x34 */ + unsigned int misc; /* 0x38 */ + unsigned int mstpri[2]; /* 0x3C */ + unsigned int vpss_clkctl; /* 0x44 */ + unsigned int peri_clkctl; /* 0x48 */ + unsigned int deepsleep; /* 0x4C */ + unsigned int dft_enable; /* 0x50 */ + unsigned int debounce[8]; /* 0x54 */ + unsigned int vtpiocr; /* 0x74 */ + unsigned int pupdctl0; /* 0x78 */ + unsigned int pupdctl1; /* 0x7C */ + unsigned int hdimcopbt; /* 0x80 */ + unsigned int pll0_config; /* 0x84 */ + unsigned int pll1_config; /* 0x88 */ +}; + +#define VPTIO_RDY (1 << 15) +#define VPTIO_IOPWRDN (1 << 14) +#define VPTIO_CLRZ (1 << 13) +#define VPTIO_LOCK (1 << 7) +#define VPTIO_PWRDN (1 << 6) + +#define VPSS_CLK_CTL_VPSS_CLKMD (1 << 7) + +#define dv_sys_module_regs \ + ((struct dv_sys_module_regs *)DAVINCI_SYSTEM_MODULE_BASE) + +#endif /* !CONFIG_SOC_DA8XX */ +#endif /* _DV_SYSCFG_DEFS_H_ */ diff --git a/arch/arm/mach-davinci/include/mach/timer_defs.h b/arch/arm/mach-davinci/include/mach/timer_defs.h new file mode 100644 index 0000000000..94d18320d9 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/timer_defs.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 DENX Software Engineering GmbH + * Heiko Schocher + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _TIMER_DEFS_H_ +#define _TIMER_DEFS_H_ + +struct davinci_timer { + u_int32_t pid12; + u_int32_t emumgt; + u_int32_t na1; + u_int32_t na2; + u_int32_t tim12; + u_int32_t tim34; + u_int32_t prd12; + u_int32_t prd34; + u_int32_t tcr; + u_int32_t tgcr; + u_int32_t wdtcr; +}; + +#define DV_TIMER_TCR_ENAMODE_MASK 3 + +#define DV_TIMER_TCR_ENAMODE12_SHIFT 6 +#define DV_TIMER_TCR_CLKSRC12_SHIFT 8 +#define DV_TIMER_TCR_READRSTMODE12_SHIFT 10 +#define DV_TIMER_TCR_CAPMODE12_SHIFT 11 +#define DV_TIMER_TCR_CAPVTMODE12_SHIFT 12 +#define DV_TIMER_TCR_ENAMODE34_SHIFT 22 +#define DV_TIMER_TCR_CLKSRC34_SHIFT 24 +#define DV_TIMER_TCR_READRSTMODE34_SHIFT 26 +#define DV_TIMER_TCR_CAPMODE34_SHIFT 27 +#define DV_TIMER_TCR_CAPEVTMODE12_SHIFT 28 + +#define DV_WDT_ENABLE_SYS_RESET 0x00020000 +#define DV_WDT_TRIGGER_SYS_RESET 0x00020002 + +#ifdef CONFIG_HW_WATCHDOG +void davinci_hw_watchdog_enable(void); +void davinci_hw_watchdog_reset(void); +#endif +#endif /* _TIMER_DEFS_H_ */ -- cgit From ea3857230c2d7428e8c22a9d063b4a5b86b34a0c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:15 +0900 Subject: ARM: kirkwood: move SoC headers to mach-kirkwood/include/mach Move arch/arm/include/asm/arch-kirkwood/* -> arch/arm/mach-kirkwood/include/mach/* Signed-off-by: Masahiro Yamada Acked-by: Stefan Roese Cc: Prafulla Wadaskar Cc: Luka Perkov --- MAINTAINERS | 1 - arch/arm/include/asm/arch-kirkwood/config.h | 138 ----------- arch/arm/include/asm/arch-kirkwood/cpu.h | 155 ------------ arch/arm/include/asm/arch-kirkwood/gpio.h | 49 ---- arch/arm/include/asm/arch-kirkwood/kw88f6192.h | 21 -- arch/arm/include/asm/arch-kirkwood/kw88f6281.h | 23 -- arch/arm/include/asm/arch-kirkwood/mpp.h | 301 ------------------------ arch/arm/include/asm/arch-kirkwood/soc.h | 74 ------ arch/arm/mach-kirkwood/include/mach/config.h | 138 +++++++++++ arch/arm/mach-kirkwood/include/mach/cpu.h | 155 ++++++++++++ arch/arm/mach-kirkwood/include/mach/gpio.h | 49 ++++ arch/arm/mach-kirkwood/include/mach/kw88f6192.h | 21 ++ arch/arm/mach-kirkwood/include/mach/kw88f6281.h | 23 ++ arch/arm/mach-kirkwood/include/mach/mpp.h | 301 ++++++++++++++++++++++++ arch/arm/mach-kirkwood/include/mach/soc.h | 74 ++++++ include/configs/km/km_arm.h | 2 +- 16 files changed, 762 insertions(+), 763 deletions(-) delete mode 100644 arch/arm/include/asm/arch-kirkwood/config.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/cpu.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/gpio.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/kw88f6192.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/kw88f6281.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/mpp.h delete mode 100644 arch/arm/include/asm/arch-kirkwood/soc.h create mode 100644 arch/arm/mach-kirkwood/include/mach/config.h create mode 100644 arch/arm/mach-kirkwood/include/mach/cpu.h create mode 100644 arch/arm/mach-kirkwood/include/mach/gpio.h create mode 100644 arch/arm/mach-kirkwood/include/mach/kw88f6192.h create mode 100644 arch/arm/mach-kirkwood/include/mach/kw88f6281.h create mode 100644 arch/arm/mach-kirkwood/include/mach/mpp.h create mode 100644 arch/arm/mach-kirkwood/include/mach/soc.h diff --git a/MAINTAINERS b/MAINTAINERS index 7a3e963100..eef70d0f68 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -99,7 +99,6 @@ M: Luka Perkov S: Maintained T: git git://git.denx.de/u-boot-marvell.git F: arch/arm/mach-kirkwood/ -F: arch/arm/include/asm/arch-kirkwood/ ARM MARVELL PXA M: Marek Vasut diff --git a/arch/arm/include/asm/arch-kirkwood/config.h b/arch/arm/include/asm/arch-kirkwood/config.h deleted file mode 100644 index e77ac400d8..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/config.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * (C) Copyright 2011 - * Marvell Semiconductor - * Written-by: Lei Wen - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * This file should be included in board config header file. - * - * It supports common definitions for Kirkwood platform - */ - -#ifndef _KW_CONFIG_H -#define _KW_CONFIG_H - -#if defined (CONFIG_KW88F6281) -#include -#elif defined (CONFIG_KW88F6192) -#include -#else -#error "SOC Name not defined" -#endif /* CONFIG_KW88F6281 */ - -#include -#define CONFIG_SYS_CACHELINE_SIZE 32 - /* default Dcache Line length for kirkwood */ -#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */ -#define CONFIG_KIRKWOOD_EGIGA_INIT /* Enable GbePort0/1 for kernel */ -#define CONFIG_KIRKWOOD_RGMII_PAD_1V8 /* Set RGMII Pad voltage to 1.8V */ -#define CONFIG_KIRKWOOD_PCIE_INIT /* Enable PCIE Port0 for kernel */ - -/* - * By default kwbimage.cfg from board specific folder is used - * If for some board, different configuration file need to be used, - * CONFIG_SYS_KWD_CONFIG should be defined in board specific header file - */ -#ifndef CONFIG_SYS_KWD_CONFIG -#define CONFIG_SYS_KWD_CONFIG $(CONFIG_BOARDDIR)/kwbimage.cfg -#endif /* CONFIG_SYS_KWD_CONFIG */ - -/* Kirkwood has 2k of Security SRAM, use it for SP */ -#define CONFIG_SYS_INIT_SP_ADDR 0xC8012000 -#define CONFIG_NR_DRAM_BANKS_MAX 2 - -#define CONFIG_I2C_MVTWSI_BASE KW_TWSI_BASE -#define MV_UART_CONSOLE_BASE KW_UART0_BASE -#define MV_SATA_BASE KW_SATA_BASE -#define MV_SATA_PORT0_OFFSET KW_SATA_PORT0_OFFSET -#define MV_SATA_PORT1_OFFSET KW_SATA_PORT1_OFFSET - -/* - * NAND configuration - */ -#ifdef CONFIG_CMD_NAND -#define CONFIG_NAND_KIRKWOOD -#define CONFIG_SYS_NAND_BASE 0xD8000000 /* MV_DEFADR_NANDF */ -#define NAND_ALLOW_ERASE_ALL 1 -#endif - -/* - * SPI Flash configuration - */ -#ifdef CONFIG_CMD_SF -#define CONFIG_HARD_SPI 1 -#define CONFIG_KIRKWOOD_SPI 1 -#ifndef CONFIG_ENV_SPI_BUS -# define CONFIG_ENV_SPI_BUS 0 -#endif -#ifndef CONFIG_ENV_SPI_CS -# define CONFIG_ENV_SPI_CS 0 -#endif -#ifndef CONFIG_ENV_SPI_MAX_HZ -# define CONFIG_ENV_SPI_MAX_HZ 50000000 -#endif -#endif - -/* - * Ethernet Driver configuration - */ -#ifdef CONFIG_CMD_NET -#define CONFIG_CMD_MII -#define CONFIG_NETCONSOLE /* include NetConsole support */ -#define CONFIG_MII /* expose smi ove miiphy interface */ -#define CONFIG_MVGBE /* Enable Marvell Gbe Controller Driver */ -#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN /* detect link using phy */ -#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ -#define CONFIG_RESET_PHY_R /* use reset_phy() to init mv8831116 PHY */ -#endif /* CONFIG_CMD_NET */ - -/* - * USB/EHCI - */ -#ifdef CONFIG_CMD_USB -#define CONFIG_USB_EHCI_MARVELL -#define CONFIG_EHCI_IS_TDI -#endif /* CONFIG_CMD_USB */ - -/* - * IDE Support on SATA ports - */ -#ifdef CONFIG_CMD_IDE -#define __io -#define CONFIG_CMD_EXT2 -#define CONFIG_MVSATA_IDE -#define CONFIG_IDE_PREINIT -#define CONFIG_MVSATA_IDE_USE_PORT1 -/* Needs byte-swapping for ATA data register */ -#define CONFIG_IDE_SWAP_IO -/* Data, registers and alternate blocks are at the same offset */ -#define CONFIG_SYS_ATA_DATA_OFFSET (0x0100) -#define CONFIG_SYS_ATA_REG_OFFSET (0x0100) -#define CONFIG_SYS_ATA_ALT_OFFSET (0x0100) -/* Each 8-bit ATA register is aligned to a 4-bytes address */ -#define CONFIG_SYS_ATA_STRIDE 4 -/* Controller supports 48-bits LBA addressing */ -#define CONFIG_LBA48 -/* CONFIG_CMD_IDE requires some #defines for ATA registers */ -#define CONFIG_SYS_IDE_MAXBUS 2 -#define CONFIG_SYS_IDE_MAXDEVICE 2 -/* ATA registers base is at SATA controller base */ -#define CONFIG_SYS_ATA_BASE_ADDR MV_SATA_BASE -#endif /* CONFIG_CMD_IDE */ - -/* - * I2C related stuff - */ -#ifdef CONFIG_CMD_I2C -#ifndef CONFIG_SYS_I2C_SOFT -#define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_MVTWSI -#endif -#define CONFIG_SYS_I2C_SLAVE 0x0 -#define CONFIG_SYS_I2C_SPEED 100000 -#endif - -#endif /* _KW_CONFIG_H */ diff --git a/arch/arm/include/asm/arch-kirkwood/cpu.h b/arch/arm/include/asm/arch-kirkwood/cpu.h deleted file mode 100644 index 926d347110..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/cpu.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _KWCPU_H -#define _KWCPU_H - -#include - -#ifndef __ASSEMBLY__ - -#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ - | (attr << 8) | (kw_winctrl_calcsize(size) << 16)) - -#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x) \ - ((_x ? KW_EGIGA1_BASE : KW_EGIGA0_BASE) + 0x44c) - -#define KW_REG_PCIE_DEVID (KW_REG_PCIE_BASE + 0x00) -#define KW_REG_PCIE_REVID (KW_REG_PCIE_BASE + 0x08) -#define KW_REG_DEVICE_ID (KW_MPP_BASE + 0x34) -#define KW_REG_SYSRST_CNT (KW_MPP_BASE + 0x50) -#define SYSRST_CNT_1SEC_VAL (25*1000000) -#define KW_REG_MPP_OUT_DRV_REG (KW_MPP_BASE + 0xE0) - -enum memory_bank { - BANK0, - BANK1, - BANK2, - BANK3 -}; - -enum kwcpu_winen { - KWCPU_WIN_DISABLE, - KWCPU_WIN_ENABLE -}; - -enum kwcpu_target { - KWCPU_TARGET_RESERVED, - KWCPU_TARGET_MEMORY, - KWCPU_TARGET_1RESERVED, - KWCPU_TARGET_SASRAM, - KWCPU_TARGET_PCIE -}; - -enum kwcpu_attrib { - KWCPU_ATTR_SASRAM = 0x01, - KWCPU_ATTR_DRAM_CS0 = 0x0e, - KWCPU_ATTR_DRAM_CS1 = 0x0d, - KWCPU_ATTR_DRAM_CS2 = 0x0b, - KWCPU_ATTR_DRAM_CS3 = 0x07, - KWCPU_ATTR_NANDFLASH = 0x2f, - KWCPU_ATTR_SPIFLASH = 0x1e, - KWCPU_ATTR_BOOTROM = 0x1d, - KWCPU_ATTR_PCIE_IO = 0xe0, - KWCPU_ATTR_PCIE_MEM = 0xe8 -}; - -/* - * Default Device Address MAP BAR values - */ -#define KW_DEFADR_PCI_MEM 0x90000000 -#define KW_DEFADR_PCI_IO 0xC0000000 -#define KW_DEFADR_PCI_IO_REMAP 0xC0000000 -#define KW_DEFADR_SASRAM 0xC8010000 -#define KW_DEFADR_NANDF 0xD8000000 -#define KW_DEFADR_SPIF 0xE8000000 -#define KW_DEFADR_BOOTROM 0xF8000000 - -/* - * read feroceon/sheeva core extra feature register - * using co-proc instruction - */ -static inline unsigned int readfr_extra_feature_reg(void) -{ - unsigned int val; - asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r" - (val)::"cc"); - return val; -} - -/* - * write feroceon/sheeva core extra feature register - * using co-proc instruction - */ -static inline void writefr_extra_feature_reg(unsigned int val) -{ - asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" - (val):"cc"); - isb(); -} - -/* - * MBus-L to Mbus Bridge Registers - * Ref: Datasheet sec:A.3 - */ -struct kwwin_registers { - u32 ctrl; - u32 base; - u32 remap_lo; - u32 remap_hi; -}; - -/* - * CPU control and status Registers - * Ref: Datasheet sec:A.3.2 - */ -struct kwcpu_registers { - u32 config; /*0x20100 */ - u32 ctrl_stat; /*0x20104 */ - u32 rstoutn_mask; /* 0x20108 */ - u32 sys_soft_rst; /* 0x2010C */ - u32 ahb_mbus_cause_irq; /* 0x20110 */ - u32 ahb_mbus_mask_irq; /* 0x20114 */ - u32 pad1[2]; - u32 ftdll_config; /* 0x20120 */ - u32 pad2; - u32 l2_cfg; /* 0x20128 */ -}; - -/* - * GPIO Registers - * Ref: Datasheet sec:A.19 - */ -struct kwgpio_registers { - u32 dout; - u32 oe; - u32 blink_en; - u32 din_pol; - u32 din; - u32 irq_cause; - u32 irq_mask; - u32 irq_level; -}; - -/* - * functions - */ -unsigned char get_random_hex(void); -unsigned int mvebu_sdram_bar(enum memory_bank bank); -unsigned int mvebu_sdram_bs(enum memory_bank bank); -void mvebu_sdram_size_adjust(enum memory_bank bank); -int kw_config_adr_windows(void); -void mvebu_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, - unsigned int gpp0_oe, unsigned int gpp1_oe); -int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, - unsigned int mpp16_23, unsigned int mpp24_31, - unsigned int mpp32_39, unsigned int mpp40_47, - unsigned int mpp48_55); -unsigned int kw_winctrl_calcsize(unsigned int sizeval); -#endif /* __ASSEMBLY__ */ -#endif /* _KWCPU_H */ diff --git a/arch/arm/include/asm/arch-kirkwood/gpio.h b/arch/arm/include/asm/arch-kirkwood/gpio.h deleted file mode 100644 index aa8c5da36d..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/gpio.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * arch/asm-arm/mach-kirkwood/include/mach/gpio.h - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Based on (mostly copied from) plat-orion based Linux 2.6 kernel driver. - * Removed kernel level irq handling. Took some macros from kernel to - * allow build. - * - * Dieter Kiermaier dk-arm-linux@gmx.de - */ - -#ifndef __KIRKWOOD_GPIO_H -#define __KIRKWOOD_GPIO_H - -/* got from kernel include/linux/bitops.h */ -#define BITS_PER_BYTE 8 -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) - -#define GPIO_MAX 50 -#define GPIO_OFF(pin) (((pin) >> 5) ? 0x0040 : 0x0000) -#define GPIO_OUT(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x00) -#define GPIO_IO_CONF(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x04) -#define GPIO_BLINK_EN(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x08) -#define GPIO_IN_POL(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x0c) -#define GPIO_DATA_IN(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x10) -#define GPIO_EDGE_CAUSE(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x14) -#define GPIO_EDGE_MASK(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x18) -#define GPIO_LEVEL_MASK(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x1c) - -/* - * Kirkwood-specific GPIO API - */ - -void kw_gpio_set_valid(unsigned pin, int mode); -int kw_gpio_is_valid(unsigned pin, int mode); -int kw_gpio_direction_input(unsigned pin); -int kw_gpio_direction_output(unsigned pin, int value); -int kw_gpio_get_value(unsigned pin); -void kw_gpio_set_value(unsigned pin, int value); -void kw_gpio_set_blink(unsigned pin, int blink); -void kw_gpio_set_unused(unsigned pin); - -#define GPIO_INPUT_OK (1 << 0) -#define GPIO_OUTPUT_OK (1 << 1) - -#endif diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6192.h b/arch/arm/include/asm/arch-kirkwood/kw88f6192.h deleted file mode 100644 index de220d57d4..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/kw88f6192.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * Header file for Feroceon CPU core 88FR131 Based KW88F6192 SOC. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _CONFIG_KW88F6192_H -#define _CONFIG_KW88F6192_H - -/* SOC specific definations */ -#define KW88F6192_REGS_PHYS_BASE 0xf1000000 -#define KW_REGS_PHY_BASE KW88F6192_REGS_PHYS_BASE - -/* TCLK Core Clock defination */ -#define CONFIG_SYS_TCLK 166000000 /* 166MHz */ - -#endif /* _CONFIG_KW88F6192_H */ diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h deleted file mode 100644 index ca88a300e0..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * Header file for Feroceon CPU core 88FR131 Based KW88F6281 SOC. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ASM_ARCH_KW88F6281_H -#define _ASM_ARCH_KW88F6281_H - -/* SOC specific definitions */ -#define KW88F6281_REGS_PHYS_BASE 0xf1000000 -#define KW_REGS_PHY_BASE KW88F6281_REGS_PHYS_BASE - -/* TCLK Core Clock definition */ -#ifndef CONFIG_SYS_TCLK -#define CONFIG_SYS_TCLK 200000000 /* 200MHz */ -#endif - -#endif /* _ASM_ARCH_KW88F6281_H */ diff --git a/arch/arm/include/asm/arch-kirkwood/mpp.h b/arch/arm/include/asm/arch-kirkwood/mpp.h deleted file mode 100644 index 7c8f6eba97..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/mpp.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins - * - * Copyright 2009: Marvell Technology Group Ltd. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __KIRKWOOD_MPP_H -#define __KIRKWOOD_MPP_H - -#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \ - /* MPP number */ ((_num) & 0xff) | \ - /* MPP select value */ (((_sel) & 0xf) << 8) | \ - /* may be input signal */ ((!!(_in)) << 12) | \ - /* may be output signal */ ((!!(_out)) << 13) | \ - /* available on F6180 */ ((!!(_F6180)) << 14) | \ - /* available on F6190 */ ((!!(_F6190)) << 15) | \ - /* available on F6192 */ ((!!(_F6192)) << 16) | \ - /* available on F6281 */ ((!!(_F6281)) << 17)) - -#define MPP_NUM(x) ((x) & 0xff) -#define MPP_SEL(x) (((x) >> 8) & 0xf) - - /* num sel i o 6180 6190 6192 6281 */ - -#define MPP_INPUT_MASK MPP( 0, 0x0, 1, 0, 0, 0, 0, 0 ) -#define MPP_OUTPUT_MASK MPP( 0, 0x0, 0, 1, 0, 0, 0, 0 ) - -#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0 ) -#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0 ) -#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0 ) -#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1 ) - -#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP0_NF_IO2 MPP( 0, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 1, 1, 1, 1, 1 ) - -#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP1_NF_IO3 MPP( 1, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 1, 1, 1, 1, 1 ) - -#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP2_NF_IO4 MPP( 2, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 1, 1, 1, 1, 1 ) - -#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP3_NF_IO5 MPP( 3, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP3_SPI_MISO MPP( 3, 0x2, 1, 0, 1, 1, 1, 1 ) - -#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP4_NF_IO6 MPP( 4, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP4_UART0_RXD MPP( 4, 0x2, 1, 0, 1, 1, 1, 1 ) -#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 1, 0, 0, 1, 1 ) -#define MPP4_PTP_CLK MPP( 4, 0xd, 1, 0, 1, 1, 1, 1 ) - -#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP5_NF_IO7 MPP( 5, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 1, 1, 1, 1, 1 ) -#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 1, 0, 1, 1, 1 ) - -#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 1, 1, 1, 1, 1 ) -#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 1, 1, 1, 1, 1 ) - -#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 1, 1, 1, 1, 1 ) -#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 1, 1, 1, 1, 1 ) - -#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP8_TW_SDA MPP( 8, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 1, 1, 1, 1, 1 ) -#define MPP8_MII0_RXERR MPP( 8, 0x4, 1, 0, 0, 1, 1, 1 ) -#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 1, 0, 0, 1, 1 ) -#define MPP8_PTP_CLK MPP( 8, 0xc, 1, 0, 1, 1, 1, 1 ) -#define MPP8_MII0_COL MPP( 8, 0xd, 1, 0, 1, 1, 1, 1 ) - -#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP9_TW_SCK MPP( 9, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP9_UART0_CTS MPP( 9, 0x2, 1, 0, 1, 1, 1, 1 ) -#define MPP9_UART1_CTS MPP( 9, 0x3, 1, 0, 1, 1, 1, 1 ) -#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 1, 0, 1, 1, 1 ) -#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 1, 0, 1, 1, 1, 1 ) -#define MPP9_MII0_CRS MPP( 9, 0xd, 1, 0, 1, 1, 1, 1 ) - -#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 1, 1, 1, 1, 1 ) -#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 1, 0, 0, 1, 1 ) -#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 1, 1, 1, 1, 1 ) - -#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP11_SPI_MISO MPP( 11, 0x2, 1, 0, 1, 1, 1, 1 ) -#define MPP11_UART0_RXD MPP( 11, 0x3, 1, 0, 1, 1, 1, 1 ) -#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 1, 0, 1, 1, 1, 1 ) -#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 1, 1, 1, 1, 1 ) -#define MPP11_PTP_CLK MPP( 11, 0xd, 1, 0, 1, 1, 1, 1 ) -#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1 ) - -#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1 ) - -#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP13_SD_CMD MPP( 13, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 1, 1, 1, 1, 1 ) - -#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP14_SD_D0 MPP( 14, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP14_UART1_RXD MPP( 14, 0x3, 1, 0, 1, 1, 1, 1 ) -#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 1, 0, 0, 1, 1 ) -#define MPP14_MII0_COL MPP( 14, 0xd, 1, 0, 1, 1, 1, 1 ) - -#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP15_SD_D1 MPP( 15, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 1, 1, 1, 1, 1 ) -#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 1, 1, 1, 1, 1 ) -#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 1, 0, 1, 1, 1 ) - -#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP16_SD_D2 MPP( 16, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP16_UART0_CTS MPP( 16, 0x2, 1, 0, 1, 1, 1, 1 ) -#define MPP16_UART1_RXD MPP( 16, 0x3, 1, 0, 1, 1, 1, 1 ) -#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 1, 0, 0, 1, 1 ) -#define MPP16_MII0_CRS MPP( 16, 0xd, 1, 0, 1, 1, 1, 1 ) - -#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP17_SD_D3 MPP( 17, 0x1, 1, 1, 1, 1, 1, 1 ) -#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 1, 0, 1, 1, 1 ) - -#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP18_NF_IO0 MPP( 18, 0x1, 1, 1, 1, 1, 1, 1 ) - -#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1 ) -#define MPP19_NF_IO1 MPP( 19, 0x1, 1, 1, 1, 1, 1, 1 ) - -#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP20_TSMP0 MPP( 20, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP20_GE1_0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP20_AUDIO_SPDIFI MPP( 20, 0x4, 1, 0, 0, 0, 1, 1 ) -#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 1, 0, 0, 1, 1 ) - -#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP21_TSMP1 MPP( 21, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP21_GE1_1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP21_AUDIO_SPDIFO MPP( 21, 0x4, 0, 1, 0, 0, 1, 1 ) -#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 1, 0, 1, 1, 1 ) - -#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP22_TSMP2 MPP( 22, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP22_GE1_2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP22_AUDIO_SPDIFRMKCLK MPP( 22, 0x4, 0, 1, 0, 0, 1, 1 ) -#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 1, 0, 0, 1, 1 ) - -#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP23_TSMP3 MPP( 23, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 1, 0, 0, 0, 1, 1 ) -#define MPP23_GE1_3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP23_AUDIO_I2SBCLK MPP( 23, 0x4, 0, 1, 0, 0, 1, 1 ) -#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 1, 0, 1, 1, 1 ) - -#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP24_TSMP4 MPP( 24, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP24_TDM_SPI_CS0 DEV( 24, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP24_GE1_4 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP24_AUDIO_I2SDO MPP( 24, 0x4, 0, 1, 0, 0, 1, 1 ) - -#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP25_TSMP5 MPP( 25, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP25_GE1_5 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP25_AUDIO_I2SLRCLK MPP( 25, 0x4, 0, 1, 0, 0, 1, 1 ) - -#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP26_TSMP6 MPP( 26, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 1, 0, 0, 0, 1, 1 ) -#define MPP26_GE1_6 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP26_AUDIO_I2SMCLK MPP( 26, 0x4, 0, 1, 0, 0, 1, 1 ) - -#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP27_TSMP7 MPP( 27, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP27_GE1_7 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP27_AUDIO_I2SDI MPP( 27, 0x4, 1, 0, 0, 0, 1, 1 ) - -#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP28_TSMP8 MPP( 28, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1 ) -#define MPP28_GE1_8 MPP( 28, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP28_AUDIO_EXTCLK MPP( 28, 0x4, 1, 0, 0, 0, 1, 1 ) - -#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP29_TSMP9 MPP( 29, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1 ) -#define MPP29_GE1_9 MPP( 29, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP30_TSMP10 MPP( 30, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP30_TDM_PCLK MPP( 30, 0x2, 1, 1, 0, 0, 1, 1 ) -#define MPP30_GE1_10 MPP( 30, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP31_TSMP11 MPP( 31, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP31_TDM_FS MPP( 31, 0x2, 1, 1, 0, 0, 1, 1 ) -#define MPP31_GE1_11 MPP( 31, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP32_TSMP12 MPP( 32, 0x1, 1, 1, 0, 0, 1, 1 ) -#define MPP32_TDM_DRX MPP( 32, 0x2, 1, 0, 0, 0, 1, 1 ) -#define MPP32_GE1_12 MPP( 32, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP33_GPIO MPP( 33, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP33_GE1_13 MPP( 33, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1 ) -#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP34_GE1_14 MPP( 34, 0x3, 0, 0, 0, 1, 1, 1 ) - -#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1 ) -#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 1, 0, 0, 1, 1 ) -#define MPP35_GE1_15 MPP( 35, 0x3, 0, 0, 0, 1, 1, 1 ) -#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 1, 0, 1, 1, 1 ) -#define MPP35_MII0_RXERR MPP( 35, 0xc, 1, 0, 1, 1, 1, 1 ) - -#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP36_TSMP0 MPP( 36, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP36_AUDIO_SPDIFI MPP( 36, 0x4, 1, 0, 1, 0, 0, 1 ) - -#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP37_TSMP1 MPP( 37, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP37_AUDIO_SPDIFO MPP( 37, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP38_TSMP2 MPP( 38, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP38_AUDIO_SPDIFRMLCLK MPP( 38, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP39_TSMP3 MPP( 39, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP39_AUDIO_I2SBCLK MPP( 39, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP40_TSMP4 MPP( 40, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP40_AUDIO_I2SDO MPP( 40, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP41_TSMP5 MPP( 41, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 1, 0, 0, 0, 0, 1 ) -#define MPP41_AUDIO_I2SLRC MPP( 41, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP42_TSMP6 MPP( 42, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP42_AUDIO_I2SMCLK MPP( 42, 0x4, 0, 1, 1, 0, 0, 1 ) - -#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP43_TSMP7 MPP( 43, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1 ) -#define MPP43_AUDIO_I2SDI MPP( 43, 0x4, 1, 0, 1, 0, 0, 1 ) - -#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1 ) -#define MPP44_TSMP8 MPP( 44, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1 ) -#define MPP44_AUDIO_EXTCLK MPP( 44, 0x4, 1, 0, 1, 0, 0, 1 ) - -#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1 ) -#define MPP45_TSMP9 MPP( 45, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP45_TDM_PCLK MPP( 45, 0x2, 1, 1, 0, 0, 0, 1 ) - -#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1 ) -#define MPP46_TSMP10 MPP( 46, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP46_TDM_FS MPP( 46, 0x2, 1, 1, 0, 0, 0, 1 ) - -#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1 ) -#define MPP47_TSMP11 MPP( 47, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP47_TDM_DRX MPP( 47, 0x2, 1, 0, 0, 0, 0, 1 ) - -#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 ) -#define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 1, 0, 0, 0, 1 ) - -#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 ) -#define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 ) -#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 1, 0, 0, 0, 1 ) -#define MPP49_PTP_CLK MPP( 49, 0x5, 1, 0, 0, 0, 0, 1 ) - -#define MPP_MAX 49 - -void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save); - -#endif diff --git a/arch/arm/include/asm/arch-kirkwood/soc.h b/arch/arm/include/asm/arch-kirkwood/soc.h deleted file mode 100644 index 58ed71b186..0000000000 --- a/arch/arm/include/asm/arch-kirkwood/soc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * Header file for the Marvell's Feroceon CPU core. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ASM_ARCH_KIRKWOOD_H -#define _ASM_ARCH_KIRKWOOD_H - -#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) - -/* SOC specific definations */ -#define INTREG_BASE 0xd0000000 -#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) -#define KW_OFFSET_REG (INTREG_BASE + 0x20080) - -/* undocumented registers */ -#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) -#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) - -#define MVEBU_SDRAM_BASE (KW_REGISTER(0x1500)) -#define KW_TWSI_BASE (KW_REGISTER(0x11000)) -#define KW_UART0_BASE (KW_REGISTER(0x12000)) -#define KW_UART1_BASE (KW_REGISTER(0x12100)) -#define KW_MPP_BASE (KW_REGISTER(0x10000)) -#define MVEBU_GPIO0_BASE (KW_REGISTER(0x10100)) -#define MVEBU_GPIO1_BASE (KW_REGISTER(0x10140)) -#define KW_RTC_BASE (KW_REGISTER(0x10300)) -#define KW_NANDF_BASE (KW_REGISTER(0x10418)) -#define MVEBU_SPI_BASE (KW_REGISTER(0x10600)) -#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) -#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) -#define MVEBU_TIMER_BASE (KW_REGISTER(0x20300)) -#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) -#define KW_USB20_BASE (KW_REGISTER(0x50000)) -#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) -#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) -#define KW_SATA_BASE (KW_REGISTER(0x80000)) -#define KW_SDIO_BASE (KW_REGISTER(0x90000)) - -/* Kirkwood Sata controller has two ports */ -#define KW_SATA_PORT0_OFFSET 0x2000 -#define KW_SATA_PORT1_OFFSET 0x4000 - -/* Kirkwood GbE controller has two ports */ -#define MAX_MVGBE_DEVS 2 -#define MVGBE0_BASE KW_EGIGA0_BASE -#define MVGBE1_BASE KW_EGIGA1_BASE - -/* Kirkwood USB Host controller */ -#define MVUSB0_BASE KW_USB20_BASE -#define MVUSB0_CPU_ATTR_DRAM_CS0 KWCPU_ATTR_DRAM_CS0 -#define MVUSB0_CPU_ATTR_DRAM_CS1 KWCPU_ATTR_DRAM_CS1 -#define MVUSB0_CPU_ATTR_DRAM_CS2 KWCPU_ATTR_DRAM_CS2 -#define MVUSB0_CPU_ATTR_DRAM_CS3 KWCPU_ATTR_DRAM_CS3 - -/* Kirkwood CPU memory windows */ -#define MVCPU_WIN_CTRL_DATA KWCPU_WIN_CTRL_DATA -#define MVCPU_WIN_ENABLE KWCPU_WIN_ENABLE -#define MVCPU_WIN_DISABLE KWCPU_WIN_DISABLE - -#if defined (CONFIG_KW88F6281) -#include -#elif defined (CONFIG_KW88F6192) -#include -#else -#error "SOC Name not defined" -#endif /* CONFIG_KW88F6281 */ -#endif /* CONFIG_FEROCEON_88FR131 */ -#endif /* _ASM_ARCH_KIRKWOOD_H */ diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h new file mode 100644 index 0000000000..e77ac400d8 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/config.h @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2011 + * Marvell Semiconductor + * Written-by: Lei Wen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This file should be included in board config header file. + * + * It supports common definitions for Kirkwood platform + */ + +#ifndef _KW_CONFIG_H +#define _KW_CONFIG_H + +#if defined (CONFIG_KW88F6281) +#include +#elif defined (CONFIG_KW88F6192) +#include +#else +#error "SOC Name not defined" +#endif /* CONFIG_KW88F6281 */ + +#include +#define CONFIG_SYS_CACHELINE_SIZE 32 + /* default Dcache Line length for kirkwood */ +#define CONFIG_MD5 /* get_random_hex on krikwood needs MD5 support */ +#define CONFIG_KIRKWOOD_EGIGA_INIT /* Enable GbePort0/1 for kernel */ +#define CONFIG_KIRKWOOD_RGMII_PAD_1V8 /* Set RGMII Pad voltage to 1.8V */ +#define CONFIG_KIRKWOOD_PCIE_INIT /* Enable PCIE Port0 for kernel */ + +/* + * By default kwbimage.cfg from board specific folder is used + * If for some board, different configuration file need to be used, + * CONFIG_SYS_KWD_CONFIG should be defined in board specific header file + */ +#ifndef CONFIG_SYS_KWD_CONFIG +#define CONFIG_SYS_KWD_CONFIG $(CONFIG_BOARDDIR)/kwbimage.cfg +#endif /* CONFIG_SYS_KWD_CONFIG */ + +/* Kirkwood has 2k of Security SRAM, use it for SP */ +#define CONFIG_SYS_INIT_SP_ADDR 0xC8012000 +#define CONFIG_NR_DRAM_BANKS_MAX 2 + +#define CONFIG_I2C_MVTWSI_BASE KW_TWSI_BASE +#define MV_UART_CONSOLE_BASE KW_UART0_BASE +#define MV_SATA_BASE KW_SATA_BASE +#define MV_SATA_PORT0_OFFSET KW_SATA_PORT0_OFFSET +#define MV_SATA_PORT1_OFFSET KW_SATA_PORT1_OFFSET + +/* + * NAND configuration + */ +#ifdef CONFIG_CMD_NAND +#define CONFIG_NAND_KIRKWOOD +#define CONFIG_SYS_NAND_BASE 0xD8000000 /* MV_DEFADR_NANDF */ +#define NAND_ALLOW_ERASE_ALL 1 +#endif + +/* + * SPI Flash configuration + */ +#ifdef CONFIG_CMD_SF +#define CONFIG_HARD_SPI 1 +#define CONFIG_KIRKWOOD_SPI 1 +#ifndef CONFIG_ENV_SPI_BUS +# define CONFIG_ENV_SPI_BUS 0 +#endif +#ifndef CONFIG_ENV_SPI_CS +# define CONFIG_ENV_SPI_CS 0 +#endif +#ifndef CONFIG_ENV_SPI_MAX_HZ +# define CONFIG_ENV_SPI_MAX_HZ 50000000 +#endif +#endif + +/* + * Ethernet Driver configuration + */ +#ifdef CONFIG_CMD_NET +#define CONFIG_CMD_MII +#define CONFIG_NETCONSOLE /* include NetConsole support */ +#define CONFIG_MII /* expose smi ove miiphy interface */ +#define CONFIG_MVGBE /* Enable Marvell Gbe Controller Driver */ +#define CONFIG_SYS_FAULT_ECHO_LINK_DOWN /* detect link using phy */ +#define CONFIG_ENV_OVERWRITE /* ethaddr can be reprogrammed */ +#define CONFIG_RESET_PHY_R /* use reset_phy() to init mv8831116 PHY */ +#endif /* CONFIG_CMD_NET */ + +/* + * USB/EHCI + */ +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_EHCI_MARVELL +#define CONFIG_EHCI_IS_TDI +#endif /* CONFIG_CMD_USB */ + +/* + * IDE Support on SATA ports + */ +#ifdef CONFIG_CMD_IDE +#define __io +#define CONFIG_CMD_EXT2 +#define CONFIG_MVSATA_IDE +#define CONFIG_IDE_PREINIT +#define CONFIG_MVSATA_IDE_USE_PORT1 +/* Needs byte-swapping for ATA data register */ +#define CONFIG_IDE_SWAP_IO +/* Data, registers and alternate blocks are at the same offset */ +#define CONFIG_SYS_ATA_DATA_OFFSET (0x0100) +#define CONFIG_SYS_ATA_REG_OFFSET (0x0100) +#define CONFIG_SYS_ATA_ALT_OFFSET (0x0100) +/* Each 8-bit ATA register is aligned to a 4-bytes address */ +#define CONFIG_SYS_ATA_STRIDE 4 +/* Controller supports 48-bits LBA addressing */ +#define CONFIG_LBA48 +/* CONFIG_CMD_IDE requires some #defines for ATA registers */ +#define CONFIG_SYS_IDE_MAXBUS 2 +#define CONFIG_SYS_IDE_MAXDEVICE 2 +/* ATA registers base is at SATA controller base */ +#define CONFIG_SYS_ATA_BASE_ADDR MV_SATA_BASE +#endif /* CONFIG_CMD_IDE */ + +/* + * I2C related stuff + */ +#ifdef CONFIG_CMD_I2C +#ifndef CONFIG_SYS_I2C_SOFT +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MVTWSI +#endif +#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C_SPEED 100000 +#endif + +#endif /* _KW_CONFIG_H */ diff --git a/arch/arm/mach-kirkwood/include/mach/cpu.h b/arch/arm/mach-kirkwood/include/mach/cpu.h new file mode 100644 index 0000000000..926d347110 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/cpu.h @@ -0,0 +1,155 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _KWCPU_H +#define _KWCPU_H + +#include + +#ifndef __ASSEMBLY__ + +#define KWCPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ + | (attr << 8) | (kw_winctrl_calcsize(size) << 16)) + +#define KWGBE_PORT_SERIAL_CONTROL1_REG(_x) \ + ((_x ? KW_EGIGA1_BASE : KW_EGIGA0_BASE) + 0x44c) + +#define KW_REG_PCIE_DEVID (KW_REG_PCIE_BASE + 0x00) +#define KW_REG_PCIE_REVID (KW_REG_PCIE_BASE + 0x08) +#define KW_REG_DEVICE_ID (KW_MPP_BASE + 0x34) +#define KW_REG_SYSRST_CNT (KW_MPP_BASE + 0x50) +#define SYSRST_CNT_1SEC_VAL (25*1000000) +#define KW_REG_MPP_OUT_DRV_REG (KW_MPP_BASE + 0xE0) + +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum kwcpu_winen { + KWCPU_WIN_DISABLE, + KWCPU_WIN_ENABLE +}; + +enum kwcpu_target { + KWCPU_TARGET_RESERVED, + KWCPU_TARGET_MEMORY, + KWCPU_TARGET_1RESERVED, + KWCPU_TARGET_SASRAM, + KWCPU_TARGET_PCIE +}; + +enum kwcpu_attrib { + KWCPU_ATTR_SASRAM = 0x01, + KWCPU_ATTR_DRAM_CS0 = 0x0e, + KWCPU_ATTR_DRAM_CS1 = 0x0d, + KWCPU_ATTR_DRAM_CS2 = 0x0b, + KWCPU_ATTR_DRAM_CS3 = 0x07, + KWCPU_ATTR_NANDFLASH = 0x2f, + KWCPU_ATTR_SPIFLASH = 0x1e, + KWCPU_ATTR_BOOTROM = 0x1d, + KWCPU_ATTR_PCIE_IO = 0xe0, + KWCPU_ATTR_PCIE_MEM = 0xe8 +}; + +/* + * Default Device Address MAP BAR values + */ +#define KW_DEFADR_PCI_MEM 0x90000000 +#define KW_DEFADR_PCI_IO 0xC0000000 +#define KW_DEFADR_PCI_IO_REMAP 0xC0000000 +#define KW_DEFADR_SASRAM 0xC8010000 +#define KW_DEFADR_NANDF 0xD8000000 +#define KW_DEFADR_SPIF 0xE8000000 +#define KW_DEFADR_BOOTROM 0xF8000000 + +/* + * read feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline unsigned int readfr_extra_feature_reg(void) +{ + unsigned int val; + asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr":"=r" + (val)::"cc"); + return val; +} + +/* + * write feroceon/sheeva core extra feature register + * using co-proc instruction + */ +static inline void writefr_extra_feature_reg(unsigned int val) +{ + asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr"::"r" + (val):"cc"); + isb(); +} + +/* + * MBus-L to Mbus Bridge Registers + * Ref: Datasheet sec:A.3 + */ +struct kwwin_registers { + u32 ctrl; + u32 base; + u32 remap_lo; + u32 remap_hi; +}; + +/* + * CPU control and status Registers + * Ref: Datasheet sec:A.3.2 + */ +struct kwcpu_registers { + u32 config; /*0x20100 */ + u32 ctrl_stat; /*0x20104 */ + u32 rstoutn_mask; /* 0x20108 */ + u32 sys_soft_rst; /* 0x2010C */ + u32 ahb_mbus_cause_irq; /* 0x20110 */ + u32 ahb_mbus_mask_irq; /* 0x20114 */ + u32 pad1[2]; + u32 ftdll_config; /* 0x20120 */ + u32 pad2; + u32 l2_cfg; /* 0x20128 */ +}; + +/* + * GPIO Registers + * Ref: Datasheet sec:A.19 + */ +struct kwgpio_registers { + u32 dout; + u32 oe; + u32 blink_en; + u32 din_pol; + u32 din; + u32 irq_cause; + u32 irq_mask; + u32 irq_level; +}; + +/* + * functions + */ +unsigned char get_random_hex(void); +unsigned int mvebu_sdram_bar(enum memory_bank bank); +unsigned int mvebu_sdram_bs(enum memory_bank bank); +void mvebu_sdram_size_adjust(enum memory_bank bank); +int kw_config_adr_windows(void); +void mvebu_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, + unsigned int gpp0_oe, unsigned int gpp1_oe); +int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, + unsigned int mpp16_23, unsigned int mpp24_31, + unsigned int mpp32_39, unsigned int mpp40_47, + unsigned int mpp48_55); +unsigned int kw_winctrl_calcsize(unsigned int sizeval); +#endif /* __ASSEMBLY__ */ +#endif /* _KWCPU_H */ diff --git a/arch/arm/mach-kirkwood/include/mach/gpio.h b/arch/arm/mach-kirkwood/include/mach/gpio.h new file mode 100644 index 0000000000..aa8c5da36d --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/gpio.h @@ -0,0 +1,49 @@ +/* + * arch/asm-arm/mach-kirkwood/include/mach/gpio.h + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Based on (mostly copied from) plat-orion based Linux 2.6 kernel driver. + * Removed kernel level irq handling. Took some macros from kernel to + * allow build. + * + * Dieter Kiermaier dk-arm-linux@gmx.de + */ + +#ifndef __KIRKWOOD_GPIO_H +#define __KIRKWOOD_GPIO_H + +/* got from kernel include/linux/bitops.h */ +#define BITS_PER_BYTE 8 +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) + +#define GPIO_MAX 50 +#define GPIO_OFF(pin) (((pin) >> 5) ? 0x0040 : 0x0000) +#define GPIO_OUT(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x00) +#define GPIO_IO_CONF(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x04) +#define GPIO_BLINK_EN(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x08) +#define GPIO_IN_POL(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x0c) +#define GPIO_DATA_IN(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x10) +#define GPIO_EDGE_CAUSE(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x14) +#define GPIO_EDGE_MASK(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x18) +#define GPIO_LEVEL_MASK(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x1c) + +/* + * Kirkwood-specific GPIO API + */ + +void kw_gpio_set_valid(unsigned pin, int mode); +int kw_gpio_is_valid(unsigned pin, int mode); +int kw_gpio_direction_input(unsigned pin); +int kw_gpio_direction_output(unsigned pin, int value); +int kw_gpio_get_value(unsigned pin); +void kw_gpio_set_value(unsigned pin, int value); +void kw_gpio_set_blink(unsigned pin, int blink); +void kw_gpio_set_unused(unsigned pin); + +#define GPIO_INPUT_OK (1 << 0) +#define GPIO_OUTPUT_OK (1 << 1) + +#endif diff --git a/arch/arm/mach-kirkwood/include/mach/kw88f6192.h b/arch/arm/mach-kirkwood/include/mach/kw88f6192.h new file mode 100644 index 0000000000..de220d57d4 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/kw88f6192.h @@ -0,0 +1,21 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for Feroceon CPU core 88FR131 Based KW88F6192 SOC. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_KW88F6192_H +#define _CONFIG_KW88F6192_H + +/* SOC specific definations */ +#define KW88F6192_REGS_PHYS_BASE 0xf1000000 +#define KW_REGS_PHY_BASE KW88F6192_REGS_PHYS_BASE + +/* TCLK Core Clock defination */ +#define CONFIG_SYS_TCLK 166000000 /* 166MHz */ + +#endif /* _CONFIG_KW88F6192_H */ diff --git a/arch/arm/mach-kirkwood/include/mach/kw88f6281.h b/arch/arm/mach-kirkwood/include/mach/kw88f6281.h new file mode 100644 index 0000000000..ca88a300e0 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/kw88f6281.h @@ -0,0 +1,23 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for Feroceon CPU core 88FR131 Based KW88F6281 SOC. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_KW88F6281_H +#define _ASM_ARCH_KW88F6281_H + +/* SOC specific definitions */ +#define KW88F6281_REGS_PHYS_BASE 0xf1000000 +#define KW_REGS_PHY_BASE KW88F6281_REGS_PHYS_BASE + +/* TCLK Core Clock definition */ +#ifndef CONFIG_SYS_TCLK +#define CONFIG_SYS_TCLK 200000000 /* 200MHz */ +#endif + +#endif /* _ASM_ARCH_KW88F6281_H */ diff --git a/arch/arm/mach-kirkwood/include/mach/mpp.h b/arch/arm/mach-kirkwood/include/mach/mpp.h new file mode 100644 index 0000000000..7c8f6eba97 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/mpp.h @@ -0,0 +1,301 @@ +/* + * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins + * + * Copyright 2009: Marvell Technology Group Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __KIRKWOOD_MPP_H +#define __KIRKWOOD_MPP_H + +#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \ + /* MPP number */ ((_num) & 0xff) | \ + /* MPP select value */ (((_sel) & 0xf) << 8) | \ + /* may be input signal */ ((!!(_in)) << 12) | \ + /* may be output signal */ ((!!(_out)) << 13) | \ + /* available on F6180 */ ((!!(_F6180)) << 14) | \ + /* available on F6190 */ ((!!(_F6190)) << 15) | \ + /* available on F6192 */ ((!!(_F6192)) << 16) | \ + /* available on F6281 */ ((!!(_F6281)) << 17)) + +#define MPP_NUM(x) ((x) & 0xff) +#define MPP_SEL(x) (((x) >> 8) & 0xf) + + /* num sel i o 6180 6190 6192 6281 */ + +#define MPP_INPUT_MASK MPP( 0, 0x0, 1, 0, 0, 0, 0, 0 ) +#define MPP_OUTPUT_MASK MPP( 0, 0x0, 0, 1, 0, 0, 0, 0 ) + +#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0 ) +#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0 ) +#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0 ) +#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1 ) + +#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP0_NF_IO2 MPP( 0, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 1, 1, 1, 1, 1 ) + +#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP1_NF_IO3 MPP( 1, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 1, 1, 1, 1, 1 ) + +#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP2_NF_IO4 MPP( 2, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 1, 1, 1, 1, 1 ) + +#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP3_NF_IO5 MPP( 3, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP3_SPI_MISO MPP( 3, 0x2, 1, 0, 1, 1, 1, 1 ) + +#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP4_NF_IO6 MPP( 4, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP4_UART0_RXD MPP( 4, 0x2, 1, 0, 1, 1, 1, 1 ) +#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 1, 0, 0, 1, 1 ) +#define MPP4_PTP_CLK MPP( 4, 0xd, 1, 0, 1, 1, 1, 1 ) + +#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP5_NF_IO7 MPP( 5, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 1, 1, 1, 1, 1 ) +#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 1, 0, 1, 1, 1 ) + +#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 1, 1, 1, 1, 1 ) +#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 1, 1, 1, 1, 1 ) + +#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 1, 1, 1, 1, 1 ) +#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 1, 1, 1, 1, 1 ) + +#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP8_TW_SDA MPP( 8, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 1, 1, 1, 1, 1 ) +#define MPP8_MII0_RXERR MPP( 8, 0x4, 1, 0, 0, 1, 1, 1 ) +#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 1, 0, 0, 1, 1 ) +#define MPP8_PTP_CLK MPP( 8, 0xc, 1, 0, 1, 1, 1, 1 ) +#define MPP8_MII0_COL MPP( 8, 0xd, 1, 0, 1, 1, 1, 1 ) + +#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP9_TW_SCK MPP( 9, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP9_UART0_CTS MPP( 9, 0x2, 1, 0, 1, 1, 1, 1 ) +#define MPP9_UART1_CTS MPP( 9, 0x3, 1, 0, 1, 1, 1, 1 ) +#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 1, 0, 1, 1, 1 ) +#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 1, 0, 1, 1, 1, 1 ) +#define MPP9_MII0_CRS MPP( 9, 0xd, 1, 0, 1, 1, 1, 1 ) + +#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 1, 1, 1, 1, 1 ) +#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 1, 0, 0, 1, 1 ) +#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 1, 1, 1, 1, 1 ) + +#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP11_SPI_MISO MPP( 11, 0x2, 1, 0, 1, 1, 1, 1 ) +#define MPP11_UART0_RXD MPP( 11, 0x3, 1, 0, 1, 1, 1, 1 ) +#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 1, 0, 1, 1, 1, 1 ) +#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 1, 1, 1, 1, 1 ) +#define MPP11_PTP_CLK MPP( 11, 0xd, 1, 0, 1, 1, 1, 1 ) +#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1 ) + +#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1 ) + +#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP13_SD_CMD MPP( 13, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 1, 1, 1, 1, 1 ) + +#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP14_SD_D0 MPP( 14, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP14_UART1_RXD MPP( 14, 0x3, 1, 0, 1, 1, 1, 1 ) +#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 1, 0, 0, 1, 1 ) +#define MPP14_MII0_COL MPP( 14, 0xd, 1, 0, 1, 1, 1, 1 ) + +#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP15_SD_D1 MPP( 15, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 1, 1, 1, 1, 1 ) +#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 1, 1, 1, 1, 1 ) +#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 1, 0, 1, 1, 1 ) + +#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP16_SD_D2 MPP( 16, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP16_UART0_CTS MPP( 16, 0x2, 1, 0, 1, 1, 1, 1 ) +#define MPP16_UART1_RXD MPP( 16, 0x3, 1, 0, 1, 1, 1, 1 ) +#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 1, 0, 0, 1, 1 ) +#define MPP16_MII0_CRS MPP( 16, 0xd, 1, 0, 1, 1, 1, 1 ) + +#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP17_SD_D3 MPP( 17, 0x1, 1, 1, 1, 1, 1, 1 ) +#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 1, 0, 1, 1, 1 ) + +#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP18_NF_IO0 MPP( 18, 0x1, 1, 1, 1, 1, 1, 1 ) + +#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1 ) +#define MPP19_NF_IO1 MPP( 19, 0x1, 1, 1, 1, 1, 1, 1 ) + +#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP20_TSMP0 MPP( 20, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP20_GE1_0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP20_AUDIO_SPDIFI MPP( 20, 0x4, 1, 0, 0, 0, 1, 1 ) +#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 1, 0, 0, 1, 1 ) + +#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP21_TSMP1 MPP( 21, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP21_GE1_1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP21_AUDIO_SPDIFO MPP( 21, 0x4, 0, 1, 0, 0, 1, 1 ) +#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 1, 0, 1, 1, 1 ) + +#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP22_TSMP2 MPP( 22, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP22_GE1_2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP22_AUDIO_SPDIFRMKCLK MPP( 22, 0x4, 0, 1, 0, 0, 1, 1 ) +#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 1, 0, 0, 1, 1 ) + +#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP23_TSMP3 MPP( 23, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 1, 0, 0, 0, 1, 1 ) +#define MPP23_GE1_3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP23_AUDIO_I2SBCLK MPP( 23, 0x4, 0, 1, 0, 0, 1, 1 ) +#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 1, 0, 1, 1, 1 ) + +#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP24_TSMP4 MPP( 24, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP24_TDM_SPI_CS0 DEV( 24, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP24_GE1_4 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP24_AUDIO_I2SDO MPP( 24, 0x4, 0, 1, 0, 0, 1, 1 ) + +#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP25_TSMP5 MPP( 25, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP25_GE1_5 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP25_AUDIO_I2SLRCLK MPP( 25, 0x4, 0, 1, 0, 0, 1, 1 ) + +#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP26_TSMP6 MPP( 26, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 1, 0, 0, 0, 1, 1 ) +#define MPP26_GE1_6 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP26_AUDIO_I2SMCLK MPP( 26, 0x4, 0, 1, 0, 0, 1, 1 ) + +#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP27_TSMP7 MPP( 27, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP27_GE1_7 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP27_AUDIO_I2SDI MPP( 27, 0x4, 1, 0, 0, 0, 1, 1 ) + +#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP28_TSMP8 MPP( 28, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1 ) +#define MPP28_GE1_8 MPP( 28, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP28_AUDIO_EXTCLK MPP( 28, 0x4, 1, 0, 0, 0, 1, 1 ) + +#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP29_TSMP9 MPP( 29, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1 ) +#define MPP29_GE1_9 MPP( 29, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP30_TSMP10 MPP( 30, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP30_TDM_PCLK MPP( 30, 0x2, 1, 1, 0, 0, 1, 1 ) +#define MPP30_GE1_10 MPP( 30, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP31_TSMP11 MPP( 31, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP31_TDM_FS MPP( 31, 0x2, 1, 1, 0, 0, 1, 1 ) +#define MPP31_GE1_11 MPP( 31, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP32_TSMP12 MPP( 32, 0x1, 1, 1, 0, 0, 1, 1 ) +#define MPP32_TDM_DRX MPP( 32, 0x2, 1, 0, 0, 0, 1, 1 ) +#define MPP32_GE1_12 MPP( 32, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP33_GPIO MPP( 33, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP33_GE1_13 MPP( 33, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1 ) +#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP34_GE1_14 MPP( 34, 0x3, 0, 0, 0, 1, 1, 1 ) + +#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1 ) +#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 1, 0, 0, 1, 1 ) +#define MPP35_GE1_15 MPP( 35, 0x3, 0, 0, 0, 1, 1, 1 ) +#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 1, 0, 1, 1, 1 ) +#define MPP35_MII0_RXERR MPP( 35, 0xc, 1, 0, 1, 1, 1, 1 ) + +#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP36_TSMP0 MPP( 36, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP36_AUDIO_SPDIFI MPP( 36, 0x4, 1, 0, 1, 0, 0, 1 ) + +#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP37_TSMP1 MPP( 37, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP37_AUDIO_SPDIFO MPP( 37, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP38_TSMP2 MPP( 38, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP38_AUDIO_SPDIFRMLCLK MPP( 38, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP39_TSMP3 MPP( 39, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP39_AUDIO_I2SBCLK MPP( 39, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP40_TSMP4 MPP( 40, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP40_AUDIO_I2SDO MPP( 40, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP41_TSMP5 MPP( 41, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 1, 0, 0, 0, 0, 1 ) +#define MPP41_AUDIO_I2SLRC MPP( 41, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP42_TSMP6 MPP( 42, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP42_AUDIO_I2SMCLK MPP( 42, 0x4, 0, 1, 1, 0, 0, 1 ) + +#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP43_TSMP7 MPP( 43, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1 ) +#define MPP43_AUDIO_I2SDI MPP( 43, 0x4, 1, 0, 1, 0, 0, 1 ) + +#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1 ) +#define MPP44_TSMP8 MPP( 44, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1 ) +#define MPP44_AUDIO_EXTCLK MPP( 44, 0x4, 1, 0, 1, 0, 0, 1 ) + +#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1 ) +#define MPP45_TSMP9 MPP( 45, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP45_TDM_PCLK MPP( 45, 0x2, 1, 1, 0, 0, 0, 1 ) + +#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1 ) +#define MPP46_TSMP10 MPP( 46, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP46_TDM_FS MPP( 46, 0x2, 1, 1, 0, 0, 0, 1 ) + +#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1 ) +#define MPP47_TSMP11 MPP( 47, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP47_TDM_DRX MPP( 47, 0x2, 1, 0, 0, 0, 0, 1 ) + +#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 ) +#define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 1, 0, 0, 0, 1 ) + +#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 ) +#define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 ) +#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 1, 0, 0, 0, 1 ) +#define MPP49_PTP_CLK MPP( 49, 0x5, 1, 0, 0, 0, 0, 1 ) + +#define MPP_MAX 49 + +void kirkwood_mpp_conf(const u32 *mpp_list, u32 *mpp_save); + +#endif diff --git a/arch/arm/mach-kirkwood/include/mach/soc.h b/arch/arm/mach-kirkwood/include/mach/soc.h new file mode 100644 index 0000000000..58ed71b186 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/soc.h @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for the Marvell's Feroceon CPU core. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_KIRKWOOD_H +#define _ASM_ARCH_KIRKWOOD_H + +#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131) + +/* SOC specific definations */ +#define INTREG_BASE 0xd0000000 +#define KW_REGISTER(x) (KW_REGS_PHY_BASE + x) +#define KW_OFFSET_REG (INTREG_BASE + 0x20080) + +/* undocumented registers */ +#define KW_REG_UNDOC_0x1470 (KW_REGISTER(0x1470)) +#define KW_REG_UNDOC_0x1478 (KW_REGISTER(0x1478)) + +#define MVEBU_SDRAM_BASE (KW_REGISTER(0x1500)) +#define KW_TWSI_BASE (KW_REGISTER(0x11000)) +#define KW_UART0_BASE (KW_REGISTER(0x12000)) +#define KW_UART1_BASE (KW_REGISTER(0x12100)) +#define KW_MPP_BASE (KW_REGISTER(0x10000)) +#define MVEBU_GPIO0_BASE (KW_REGISTER(0x10100)) +#define MVEBU_GPIO1_BASE (KW_REGISTER(0x10140)) +#define KW_RTC_BASE (KW_REGISTER(0x10300)) +#define KW_NANDF_BASE (KW_REGISTER(0x10418)) +#define MVEBU_SPI_BASE (KW_REGISTER(0x10600)) +#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) +#define MVEBU_TIMER_BASE (KW_REGISTER(0x20300)) +#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) +#define KW_USB20_BASE (KW_REGISTER(0x50000)) +#define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) +#define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) +#define KW_SATA_BASE (KW_REGISTER(0x80000)) +#define KW_SDIO_BASE (KW_REGISTER(0x90000)) + +/* Kirkwood Sata controller has two ports */ +#define KW_SATA_PORT0_OFFSET 0x2000 +#define KW_SATA_PORT1_OFFSET 0x4000 + +/* Kirkwood GbE controller has two ports */ +#define MAX_MVGBE_DEVS 2 +#define MVGBE0_BASE KW_EGIGA0_BASE +#define MVGBE1_BASE KW_EGIGA1_BASE + +/* Kirkwood USB Host controller */ +#define MVUSB0_BASE KW_USB20_BASE +#define MVUSB0_CPU_ATTR_DRAM_CS0 KWCPU_ATTR_DRAM_CS0 +#define MVUSB0_CPU_ATTR_DRAM_CS1 KWCPU_ATTR_DRAM_CS1 +#define MVUSB0_CPU_ATTR_DRAM_CS2 KWCPU_ATTR_DRAM_CS2 +#define MVUSB0_CPU_ATTR_DRAM_CS3 KWCPU_ATTR_DRAM_CS3 + +/* Kirkwood CPU memory windows */ +#define MVCPU_WIN_CTRL_DATA KWCPU_WIN_CTRL_DATA +#define MVCPU_WIN_ENABLE KWCPU_WIN_ENABLE +#define MVCPU_WIN_DISABLE KWCPU_WIN_DISABLE + +#if defined (CONFIG_KW88F6281) +#include +#elif defined (CONFIG_KW88F6192) +#include +#else +#error "SOC Name not defined" +#endif /* CONFIG_KW88F6281 */ +#endif /* CONFIG_FEROCEON_88FR131 */ +#endif /* _ASM_ARCH_KIRKWOOD_H */ diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h index f780f8b5bb..2ed0855fdd 100644 --- a/include/configs/km/km_arm.h +++ b/include/configs/km/km_arm.h @@ -195,7 +195,7 @@ } #ifndef __ASSEMBLY__ -#include +#include extern void __set_direction(unsigned pin, int high); void set_sda(int state); void set_scl(int state); -- cgit From 5d0e6b28f3b35234211ac23c3687ef06c8c14fba Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:16 +0900 Subject: ARM: nomadik: move SoC headers to mach-nomadik/include/mach Move arch/arm/include/asm/arch-nomadik/* -> arch/arm/mach-nomadik/include/mach/* Signed-off-by: Masahiro Yamada Cc: Nomadik Linux Team Cc: Alessandro Rubini --- arch/arm/include/asm/arch-nomadik/gpio.h | 26 ---------------- arch/arm/include/asm/arch-nomadik/mtu.h | 50 ------------------------------- arch/arm/mach-nomadik/include/mach/gpio.h | 26 ++++++++++++++++ arch/arm/mach-nomadik/include/mach/mtu.h | 50 +++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 76 deletions(-) delete mode 100644 arch/arm/include/asm/arch-nomadik/gpio.h delete mode 100644 arch/arm/include/asm/arch-nomadik/mtu.h create mode 100644 arch/arm/mach-nomadik/include/mach/gpio.h create mode 100644 arch/arm/mach-nomadik/include/mach/mtu.h diff --git a/arch/arm/include/asm/arch-nomadik/gpio.h b/arch/arm/include/asm/arch-nomadik/gpio.h deleted file mode 100644 index 311758ae1a..0000000000 --- a/arch/arm/include/asm/arch-nomadik/gpio.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __NMK_GPIO_H__ -#define __NMK_GPIO_H__ - -/* - * These functions are called from the soft-i2c driver, but - * are also used by board files to set output bits. - */ - -enum nmk_af { /* alternate function settings */ - GPIO_GPIO = 0, - GPIO_ALT_A, - GPIO_ALT_B, - GPIO_ALT_C -}; - -extern void nmk_gpio_af(int gpio, int alternate_function); -extern void nmk_gpio_dir(int gpio, int dir); -extern void nmk_gpio_set(int gpio, int val); -extern int nmk_gpio_get(int gpio); - -#endif /* __NMK_GPIO_H__ */ diff --git a/arch/arm/include/asm/arch-nomadik/mtu.h b/arch/arm/include/asm/arch-nomadik/mtu.h deleted file mode 100644 index f89f242247..0000000000 --- a/arch/arm/include/asm/arch-nomadik/mtu.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * (C) Copyright 2009 Alessandro Rubini - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_MTU_H -#define __ASM_ARCH_MTU_H - -/* - * The MTU device hosts four different counters, with 4 set of - * registers. These are register names. - */ - -#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ -#define MTU_RIS 0x04 /* Raw interrupt status */ -#define MTU_MIS 0x08 /* Masked interrupt status */ -#define MTU_ICR 0x0C /* Interrupt clear register */ - -/* per-timer registers take 0..3 as argument */ -#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ -#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ -#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ -#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ - -/* bits for the control register */ -#define MTU_CRn_ENA 0x80 -#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ -#define MTU_CRn_PRESCALE_MASK 0x0c -#define MTU_CRn_PRESCALE_1 0x00 -#define MTU_CRn_PRESCALE_16 0x04 -#define MTU_CRn_PRESCALE_256 0x08 -#define MTU_CRn_32BITS 0x02 -#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ - -/* Other registers are usual amba/primecell registers, currently not used */ -#define MTU_ITCR 0xff0 -#define MTU_ITOP 0xff4 - -#define MTU_PERIPH_ID0 0xfe0 -#define MTU_PERIPH_ID1 0xfe4 -#define MTU_PERIPH_ID2 0xfe8 -#define MTU_PERIPH_ID3 0xfeC - -#define MTU_PCELL0 0xff0 -#define MTU_PCELL1 0xff4 -#define MTU_PCELL2 0xff8 -#define MTU_PCELL3 0xffC - -#endif /* __ASM_ARCH_MTU_H */ diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h new file mode 100644 index 0000000000..311758ae1a --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/gpio.h @@ -0,0 +1,26 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __NMK_GPIO_H__ +#define __NMK_GPIO_H__ + +/* + * These functions are called from the soft-i2c driver, but + * are also used by board files to set output bits. + */ + +enum nmk_af { /* alternate function settings */ + GPIO_GPIO = 0, + GPIO_ALT_A, + GPIO_ALT_B, + GPIO_ALT_C +}; + +extern void nmk_gpio_af(int gpio, int alternate_function); +extern void nmk_gpio_dir(int gpio, int dir); +extern void nmk_gpio_set(int gpio, int val); +extern int nmk_gpio_get(int gpio); + +#endif /* __NMK_GPIO_H__ */ diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h new file mode 100644 index 0000000000..f89f242247 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/mtu.h @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_MTU_H +#define __ASM_ARCH_MTU_H + +/* + * The MTU device hosts four different counters, with 4 set of + * registers. These are register names. + */ + +#define MTU_IMSC 0x00 /* Interrupt mask set/clear */ +#define MTU_RIS 0x04 /* Raw interrupt status */ +#define MTU_MIS 0x08 /* Masked interrupt status */ +#define MTU_ICR 0x0C /* Interrupt clear register */ + +/* per-timer registers take 0..3 as argument */ +#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ +#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ +#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ +#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ + +/* bits for the control register */ +#define MTU_CRn_ENA 0x80 +#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ +#define MTU_CRn_PRESCALE_MASK 0x0c +#define MTU_CRn_PRESCALE_1 0x00 +#define MTU_CRn_PRESCALE_16 0x04 +#define MTU_CRn_PRESCALE_256 0x08 +#define MTU_CRn_32BITS 0x02 +#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ + +/* Other registers are usual amba/primecell registers, currently not used */ +#define MTU_ITCR 0xff0 +#define MTU_ITOP 0xff4 + +#define MTU_PERIPH_ID0 0xfe0 +#define MTU_PERIPH_ID1 0xfe4 +#define MTU_PERIPH_ID2 0xfe8 +#define MTU_PERIPH_ID3 0xfeC + +#define MTU_PCELL0 0xff0 +#define MTU_PCELL1 0xff4 +#define MTU_PCELL2 0xff8 +#define MTU_PCELL3 0xffC + +#endif /* __ASM_ARCH_MTU_H */ -- cgit From fd697ecf5d1797180c29328b013d48ee3a788e03 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:17 +0900 Subject: ARM: orion5x: move SoC headers to mach-orion5x/include/mach Move arch/arm/include/asm/arch-orion5x/* -> arch/arm/mach-orion5x/include/mach/* Signed-off-by: Masahiro Yamada Cc: Albert ARIBAUD --- arch/arm/include/asm/arch-orion5x/cpu.h | 243 ------------------------- arch/arm/include/asm/arch-orion5x/mv88f5182.h | 24 --- arch/arm/include/asm/arch-orion5x/orion5x.h | 67 ------- arch/arm/mach-orion5x/include/mach/cpu.h | 243 +++++++++++++++++++++++++ arch/arm/mach-orion5x/include/mach/mv88f5182.h | 24 +++ arch/arm/mach-orion5x/include/mach/orion5x.h | 67 +++++++ 6 files changed, 334 insertions(+), 334 deletions(-) delete mode 100644 arch/arm/include/asm/arch-orion5x/cpu.h delete mode 100644 arch/arm/include/asm/arch-orion5x/mv88f5182.h delete mode 100644 arch/arm/include/asm/arch-orion5x/orion5x.h create mode 100644 arch/arm/mach-orion5x/include/mach/cpu.h create mode 100644 arch/arm/mach-orion5x/include/mach/mv88f5182.h create mode 100644 arch/arm/mach-orion5x/include/mach/orion5x.h diff --git a/arch/arm/include/asm/arch-orion5x/cpu.h b/arch/arm/include/asm/arch-orion5x/cpu.h deleted file mode 100644 index 08a450f1f3..0000000000 --- a/arch/arm/include/asm/arch-orion5x/cpu.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirorion5x_ood support which is - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ORION5X_CPU_H -#define _ORION5X_CPU_H - -#include - -#ifndef __ASSEMBLY__ - -#define ORION5X_CPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ - | (attr << 8) | (orion5x_winctrl_calcsize(size) << 16)) - -#define ORION5XGBE_PORT_SERIAL_CONTROL1_REG(_x) \ - ((_x ? ORION5X_EGIGA0_BASE : ORION5X_EGIGA1_BASE) + 0x44c) - -enum memory_bank { - BANK0, - BANK1, - BANK2, - BANK3 -}; - -enum orion5x_cpu_winen { - ORION5X_WIN_DISABLE, - ORION5X_WIN_ENABLE -}; - -enum orion5x_cpu_target { - ORION5X_TARGET_DRAM = 0, - ORION5X_TARGET_DEVICE = 1, - ORION5X_TARGET_PCI = 3, - ORION5X_TARGET_PCIE = 4, - ORION5X_TARGET_SASRAM = 9 -}; - -enum orion5x_cpu_attrib { - ORION5X_ATTR_DRAM_CS0 = 0x0e, - ORION5X_ATTR_DRAM_CS1 = 0x0d, - ORION5X_ATTR_DRAM_CS2 = 0x0b, - ORION5X_ATTR_DRAM_CS3 = 0x07, - ORION5X_ATTR_PCI_MEM = 0x59, - ORION5X_ATTR_PCI_IO = 0x51, - ORION5X_ATTR_PCIE_MEM = 0x59, - ORION5X_ATTR_PCIE_IO = 0x51, - ORION5X_ATTR_SASRAM = 0x00, - ORION5X_ATTR_DEV_CS0 = 0x1e, - ORION5X_ATTR_DEV_CS1 = 0x1d, - ORION5X_ATTR_DEV_CS2 = 0x1b, - ORION5X_ATTR_BOOTROM = 0x0f -}; - -/* - * Device Address MAP BAR values - * - * All addresses and sizes not defined by board code - * will be given default values here. - */ - -#if !defined (ORION5X_ADR_PCIE_MEM) -#define ORION5X_ADR_PCIE_MEM 0x90000000 -#endif - -#if !defined (ORION5X_ADR_PCIE_MEM_REMAP_LO) -#define ORION5X_ADR_PCIE_MEM_REMAP_LO 0x90000000 -#endif - -#if !defined (ORION5X_ADR_PCIE_MEM_REMAP_HI) -#define ORION5X_ADR_PCIE_MEM_REMAP_HI 0 -#endif - -#if !defined (ORION5X_SZ_PCIE_MEM) -#define ORION5X_SZ_PCIE_MEM (128*1024*1024) -#endif - -#if !defined (ORION5X_ADR_PCIE_IO) -#define ORION5X_ADR_PCIE_IO 0xf0000000 -#endif - -#if !defined (ORION5X_ADR_PCIE_IO_REMAP_LO) -#define ORION5X_ADR_PCIE_IO_REMAP_LO 0x90000000 -#endif - -#if !defined (ORION5X_ADR_PCIE_IO_REMAP_HI) -#define ORION5X_ADR_PCIE_IO_REMAP_HI 0 -#endif - -#if !defined (ORION5X_SZ_PCIE_IO) -#define ORION5X_SZ_PCIE_IO (64*1024) -#endif - -#if !defined (ORION5X_ADR_PCI_MEM) -#define ORION5X_ADR_PCI_MEM 0x98000000 -#endif - -#if !defined (ORION5X_SZ_PCI_MEM) -#define ORION5X_SZ_PCI_MEM (128*1024*1024) -#endif - -#if !defined (ORION5X_ADR_PCI_IO) -#define ORION5X_ADR_PCI_IO 0xf0100000 -#endif - -#if !defined (ORION5X_SZ_PCI_IO) -#define ORION5X_SZ_PCI_IO (64*1024) -#endif - -#if !defined (ORION5X_ADR_DEV_CS0) -#define ORION5X_ADR_DEV_CS0 0xfa000000 -#endif - -#if !defined (ORION5X_SZ_DEV_CS0) -#define ORION5X_SZ_DEV_CS0 (2*1024*1024) -#endif - -#if !defined (ORION5X_ADR_DEV_CS1) -#define ORION5X_ADR_DEV_CS1 0xf8000000 -#endif - -#if !defined (ORION5X_SZ_DEV_CS1) -#define ORION5X_SZ_DEV_CS1 (32*1024*1024) -#endif - -#if !defined (ORION5X_ADR_DEV_CS2) -#define ORION5X_ADR_DEV_CS2 0xfa800000 -#endif - -#if !defined (ORION5X_SZ_DEV_CS2) -#define ORION5X_SZ_DEV_CS2 (1*1024*1024) -#endif - -#if !defined (ORION5X_ADR_BOOTROM) -#define ORION5X_ADR_BOOTROM 0xFFF80000 -#endif - -#if !defined (ORION5X_SZ_BOOTROM) -#define ORION5X_SZ_BOOTROM (512*1024) -#endif - -/* - * PCIE registers are used for SoC device ID and revision - */ -#define PCIE_DEV_ID_OFF (ORION5X_REG_PCIE_BASE + 0x0000) -#define PCIE_DEV_REV_OFF (ORION5X_REG_PCIE_BASE + 0x0008) - -/* - * The following definitions are intended for identifying - * the real device and revision on which u-boot is running - * even if it was compiled only for a specific one. Thus, - * these constants must not be considered chip-specific. - */ - -/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */ -#define MV88F5181_DEV_ID 0x5181 -#define MV88F5181_REV_B1 3 -#define MV88F5181L_REV_A0 8 -#define MV88F5181L_REV_A1 9 -/* Orion-NAS (88F5182) */ -#define MV88F5182_DEV_ID 0x5182 -#define MV88F5182_REV_A2 2 -/* Orion-2 (88F5281) */ -#define MV88F5281_DEV_ID 0x5281 -#define MV88F5281_REV_D0 4 -#define MV88F5281_REV_D1 5 -#define MV88F5281_REV_D2 6 -/* Orion-1-90 (88F6183) */ -#define MV88F6183_DEV_ID 0x6183 -#define MV88F6183_REV_B0 3 - -/* - * read feroceon core extra feature register - * using co-proc instruction - */ -static inline unsigned int readfr_extra_feature_reg(void) -{ - unsigned int val; - asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr" : "=r" - (val) : : "cc"); - return val; -} - -/* - * write feroceon core extra feature register - * using co-proc instruction - */ -static inline void writefr_extra_feature_reg(unsigned int val) -{ - asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr" : : "r" - (val) : "cc"); - isb(); -} - -/* - * AHB to Mbus Bridge Registers - * Source: 88F5182 User Manual, Appendix A, section A.4 - * Note: only windows 0 and 1 have remap capability. - */ -struct orion5x_win_registers { - u32 ctrl; - u32 base; - u32 remap_lo; - u32 remap_hi; -}; - -/* - * CPU control and status Registers - * Source: 88F5182 User Manual, Appendix A, section A.4 - */ -struct orion5x_cpu_registers { - u32 config; /*0x20100 */ - u32 ctrl_stat; /*0x20104 */ - u32 rstoutn_mask; /* 0x20108 */ - u32 sys_soft_rst; /* 0x2010C */ - u32 ahb_mbus_cause_irq; /* 0x20110 */ - u32 ahb_mbus_mask_irq; /* 0x20114 */ -}; - -/* - * DDR SDRAM Controller Address Decode Registers - * Source: 88F5182 User Manual, Appendix A, section A.5.1 - */ -struct orion5x_ddr_addr_decode_registers { - u32 base; - u32 size; -}; - -/* - * functions - */ -u32 orion5x_device_id(void); -u32 orion5x_device_rev(void); -unsigned int orion5x_winctrl_calcsize(unsigned int sizeval); -void timer_init_r(void); -#endif /* __ASSEMBLY__ */ -#endif /* _ORION5X_CPU_H */ diff --git a/arch/arm/include/asm/arch-orion5x/mv88f5182.h b/arch/arm/include/asm/arch-orion5x/mv88f5182.h deleted file mode 100644 index e6c71ae1b3..0000000000 --- a/arch/arm/include/asm/arch-orion5x/mv88f5182.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirkwood 88F6182 support which is - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * Header file for Feroceon CPU core 88F5182 SOC. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _CONFIG_88F5182_H -#define _CONFIG_88F5182_H - -/* SOC specific definitions */ -#define F88F5182_REGS_PHYS_BASE 0xf1000000 -#define ORION5X_REGS_PHY_BASE F88F5182_REGS_PHYS_BASE - -/* TCLK Core Clock defination */ -#define CONFIG_SYS_TCLK 166000000 /* 166MHz */ - -#endif /* _CONFIG_88F5182_H */ diff --git a/arch/arm/include/asm/arch-orion5x/orion5x.h b/arch/arm/include/asm/arch-orion5x/orion5x.h deleted file mode 100644 index fbb1de8c0d..0000000000 --- a/arch/arm/include/asm/arch-orion5x/orion5x.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2010 Albert ARIBAUD - * - * Based on original Kirkwood support which is - * (C) Copyright 2009 - * Marvell Semiconductor - * Written-by: Prafulla Wadaskar - * - * Header file for Marvell's Orion SoC with Feroceon CPU core. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ASM_ARCH_ORION5X_H -#define _ASM_ARCH_ORION5X_H - -#if defined(CONFIG_FEROCEON) - -/* SOC specific definations */ -#define ORION5X_REGISTER(x) (ORION5X_REGS_PHY_BASE + x) - -/* Documented registers */ -#define ORION5X_DRAM_BASE (ORION5X_REGISTER(0x01500)) -#define ORION5X_TWSI_BASE (ORION5X_REGISTER(0x11000)) -#define ORION5X_UART0_BASE (ORION5X_REGISTER(0x12000)) -#define ORION5X_UART1_BASE (ORION5X_REGISTER(0x12100)) -#define ORION5X_MPP_BASE (ORION5X_REGISTER(0x10000)) -#define ORION5X_GPIO_BASE (ORION5X_REGISTER(0x10100)) -#define ORION5X_CPU_WIN_BASE (ORION5X_REGISTER(0x20000)) -#define ORION5X_CPU_REG_BASE (ORION5X_REGISTER(0x20100)) -#define ORION5X_TIMER_BASE (ORION5X_REGISTER(0x20300)) -#define ORION5X_REG_PCI_BASE (ORION5X_REGISTER(0x30000)) -#define ORION5X_REG_PCIE_BASE (ORION5X_REGISTER(0x40000)) -#define ORION5X_USB20_PORT0_BASE (ORION5X_REGISTER(0x50000)) -#define ORION5X_USB20_PORT1_BASE (ORION5X_REGISTER(0xA0000)) -#define ORION5X_EGIGA_BASE (ORION5X_REGISTER(0x72000)) -#define ORION5X_SATA_BASE (ORION5X_REGISTER(0x80000)) -#define ORION5X_SATA_PORT0_OFFSET 0x2000 -#define ORION5X_SATA_PORT1_OFFSET 0x4000 - -/* Orion5x GbE controller has a single port */ -#define MAX_MVGBE_DEVS 1 -#define MVGBE0_BASE ORION5X_EGIGA_BASE - -/* Orion5x USB Host controller is port 1 */ -#define MVUSB0_BASE ORION5X_USB20_HOST_PORT_BASE -#define MVUSB0_CPU_ATTR_DRAM_CS0 ORION5X_ATTR_DRAM_CS0 -#define MVUSB0_CPU_ATTR_DRAM_CS1 ORION5X_ATTR_DRAM_CS1 -#define MVUSB0_CPU_ATTR_DRAM_CS2 ORION5X_ATTR_DRAM_CS2 -#define MVUSB0_CPU_ATTR_DRAM_CS3 ORION5X_ATTR_DRAM_CS3 - -/* Kirkwood CPU memory windows */ -#define MVCPU_WIN_CTRL_DATA ORION5X_CPU_WIN_CTRL_DATA -#define MVCPU_WIN_ENABLE ORION5X_WIN_ENABLE -#define MVCPU_WIN_DISABLE ORION5X_WIN_DISABLE - -#define CONFIG_MAX_RAM_BANK_SIZE (64*1024*1024) - -/* include here SoC variants. 5181, 5281, 6183 should go here when - adding support for them, and this comment should then be updated. */ -#if defined(CONFIG_88F5182) -#include -#else -#error "SOC Name not defined" -#endif -#endif /* CONFIG_FEROCEON */ -#endif /* _ASM_ARCH_ORION5X_H */ diff --git a/arch/arm/mach-orion5x/include/mach/cpu.h b/arch/arm/mach-orion5x/include/mach/cpu.h new file mode 100644 index 0000000000..08a450f1f3 --- /dev/null +++ b/arch/arm/mach-orion5x/include/mach/cpu.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirorion5x_ood support which is + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ORION5X_CPU_H +#define _ORION5X_CPU_H + +#include + +#ifndef __ASSEMBLY__ + +#define ORION5X_CPU_WIN_CTRL_DATA(size, target, attr, en) (en | (target << 4) \ + | (attr << 8) | (orion5x_winctrl_calcsize(size) << 16)) + +#define ORION5XGBE_PORT_SERIAL_CONTROL1_REG(_x) \ + ((_x ? ORION5X_EGIGA0_BASE : ORION5X_EGIGA1_BASE) + 0x44c) + +enum memory_bank { + BANK0, + BANK1, + BANK2, + BANK3 +}; + +enum orion5x_cpu_winen { + ORION5X_WIN_DISABLE, + ORION5X_WIN_ENABLE +}; + +enum orion5x_cpu_target { + ORION5X_TARGET_DRAM = 0, + ORION5X_TARGET_DEVICE = 1, + ORION5X_TARGET_PCI = 3, + ORION5X_TARGET_PCIE = 4, + ORION5X_TARGET_SASRAM = 9 +}; + +enum orion5x_cpu_attrib { + ORION5X_ATTR_DRAM_CS0 = 0x0e, + ORION5X_ATTR_DRAM_CS1 = 0x0d, + ORION5X_ATTR_DRAM_CS2 = 0x0b, + ORION5X_ATTR_DRAM_CS3 = 0x07, + ORION5X_ATTR_PCI_MEM = 0x59, + ORION5X_ATTR_PCI_IO = 0x51, + ORION5X_ATTR_PCIE_MEM = 0x59, + ORION5X_ATTR_PCIE_IO = 0x51, + ORION5X_ATTR_SASRAM = 0x00, + ORION5X_ATTR_DEV_CS0 = 0x1e, + ORION5X_ATTR_DEV_CS1 = 0x1d, + ORION5X_ATTR_DEV_CS2 = 0x1b, + ORION5X_ATTR_BOOTROM = 0x0f +}; + +/* + * Device Address MAP BAR values + * + * All addresses and sizes not defined by board code + * will be given default values here. + */ + +#if !defined (ORION5X_ADR_PCIE_MEM) +#define ORION5X_ADR_PCIE_MEM 0x90000000 +#endif + +#if !defined (ORION5X_ADR_PCIE_MEM_REMAP_LO) +#define ORION5X_ADR_PCIE_MEM_REMAP_LO 0x90000000 +#endif + +#if !defined (ORION5X_ADR_PCIE_MEM_REMAP_HI) +#define ORION5X_ADR_PCIE_MEM_REMAP_HI 0 +#endif + +#if !defined (ORION5X_SZ_PCIE_MEM) +#define ORION5X_SZ_PCIE_MEM (128*1024*1024) +#endif + +#if !defined (ORION5X_ADR_PCIE_IO) +#define ORION5X_ADR_PCIE_IO 0xf0000000 +#endif + +#if !defined (ORION5X_ADR_PCIE_IO_REMAP_LO) +#define ORION5X_ADR_PCIE_IO_REMAP_LO 0x90000000 +#endif + +#if !defined (ORION5X_ADR_PCIE_IO_REMAP_HI) +#define ORION5X_ADR_PCIE_IO_REMAP_HI 0 +#endif + +#if !defined (ORION5X_SZ_PCIE_IO) +#define ORION5X_SZ_PCIE_IO (64*1024) +#endif + +#if !defined (ORION5X_ADR_PCI_MEM) +#define ORION5X_ADR_PCI_MEM 0x98000000 +#endif + +#if !defined (ORION5X_SZ_PCI_MEM) +#define ORION5X_SZ_PCI_MEM (128*1024*1024) +#endif + +#if !defined (ORION5X_ADR_PCI_IO) +#define ORION5X_ADR_PCI_IO 0xf0100000 +#endif + +#if !defined (ORION5X_SZ_PCI_IO) +#define ORION5X_SZ_PCI_IO (64*1024) +#endif + +#if !defined (ORION5X_ADR_DEV_CS0) +#define ORION5X_ADR_DEV_CS0 0xfa000000 +#endif + +#if !defined (ORION5X_SZ_DEV_CS0) +#define ORION5X_SZ_DEV_CS0 (2*1024*1024) +#endif + +#if !defined (ORION5X_ADR_DEV_CS1) +#define ORION5X_ADR_DEV_CS1 0xf8000000 +#endif + +#if !defined (ORION5X_SZ_DEV_CS1) +#define ORION5X_SZ_DEV_CS1 (32*1024*1024) +#endif + +#if !defined (ORION5X_ADR_DEV_CS2) +#define ORION5X_ADR_DEV_CS2 0xfa800000 +#endif + +#if !defined (ORION5X_SZ_DEV_CS2) +#define ORION5X_SZ_DEV_CS2 (1*1024*1024) +#endif + +#if !defined (ORION5X_ADR_BOOTROM) +#define ORION5X_ADR_BOOTROM 0xFFF80000 +#endif + +#if !defined (ORION5X_SZ_BOOTROM) +#define ORION5X_SZ_BOOTROM (512*1024) +#endif + +/* + * PCIE registers are used for SoC device ID and revision + */ +#define PCIE_DEV_ID_OFF (ORION5X_REG_PCIE_BASE + 0x0000) +#define PCIE_DEV_REV_OFF (ORION5X_REG_PCIE_BASE + 0x0008) + +/* + * The following definitions are intended for identifying + * the real device and revision on which u-boot is running + * even if it was compiled only for a specific one. Thus, + * these constants must not be considered chip-specific. + */ + +/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */ +#define MV88F5181_DEV_ID 0x5181 +#define MV88F5181_REV_B1 3 +#define MV88F5181L_REV_A0 8 +#define MV88F5181L_REV_A1 9 +/* Orion-NAS (88F5182) */ +#define MV88F5182_DEV_ID 0x5182 +#define MV88F5182_REV_A2 2 +/* Orion-2 (88F5281) */ +#define MV88F5281_DEV_ID 0x5281 +#define MV88F5281_REV_D0 4 +#define MV88F5281_REV_D1 5 +#define MV88F5281_REV_D2 6 +/* Orion-1-90 (88F6183) */ +#define MV88F6183_DEV_ID 0x6183 +#define MV88F6183_REV_B0 3 + +/* + * read feroceon core extra feature register + * using co-proc instruction + */ +static inline unsigned int readfr_extra_feature_reg(void) +{ + unsigned int val; + asm volatile ("mrc p15, 1, %0, c15, c1, 0 @ readfr exfr" : "=r" + (val) : : "cc"); + return val; +} + +/* + * write feroceon core extra feature register + * using co-proc instruction + */ +static inline void writefr_extra_feature_reg(unsigned int val) +{ + asm volatile ("mcr p15, 1, %0, c15, c1, 0 @ writefr exfr" : : "r" + (val) : "cc"); + isb(); +} + +/* + * AHB to Mbus Bridge Registers + * Source: 88F5182 User Manual, Appendix A, section A.4 + * Note: only windows 0 and 1 have remap capability. + */ +struct orion5x_win_registers { + u32 ctrl; + u32 base; + u32 remap_lo; + u32 remap_hi; +}; + +/* + * CPU control and status Registers + * Source: 88F5182 User Manual, Appendix A, section A.4 + */ +struct orion5x_cpu_registers { + u32 config; /*0x20100 */ + u32 ctrl_stat; /*0x20104 */ + u32 rstoutn_mask; /* 0x20108 */ + u32 sys_soft_rst; /* 0x2010C */ + u32 ahb_mbus_cause_irq; /* 0x20110 */ + u32 ahb_mbus_mask_irq; /* 0x20114 */ +}; + +/* + * DDR SDRAM Controller Address Decode Registers + * Source: 88F5182 User Manual, Appendix A, section A.5.1 + */ +struct orion5x_ddr_addr_decode_registers { + u32 base; + u32 size; +}; + +/* + * functions + */ +u32 orion5x_device_id(void); +u32 orion5x_device_rev(void); +unsigned int orion5x_winctrl_calcsize(unsigned int sizeval); +void timer_init_r(void); +#endif /* __ASSEMBLY__ */ +#endif /* _ORION5X_CPU_H */ diff --git a/arch/arm/mach-orion5x/include/mach/mv88f5182.h b/arch/arm/mach-orion5x/include/mach/mv88f5182.h new file mode 100644 index 0000000000..e6c71ae1b3 --- /dev/null +++ b/arch/arm/mach-orion5x/include/mach/mv88f5182.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirkwood 88F6182 support which is + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for Feroceon CPU core 88F5182 SOC. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_88F5182_H +#define _CONFIG_88F5182_H + +/* SOC specific definitions */ +#define F88F5182_REGS_PHYS_BASE 0xf1000000 +#define ORION5X_REGS_PHY_BASE F88F5182_REGS_PHYS_BASE + +/* TCLK Core Clock defination */ +#define CONFIG_SYS_TCLK 166000000 /* 166MHz */ + +#endif /* _CONFIG_88F5182_H */ diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h new file mode 100644 index 0000000000..fbb1de8c0d --- /dev/null +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Albert ARIBAUD + * + * Based on original Kirkwood support which is + * (C) Copyright 2009 + * Marvell Semiconductor + * Written-by: Prafulla Wadaskar + * + * Header file for Marvell's Orion SoC with Feroceon CPU core. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_ORION5X_H +#define _ASM_ARCH_ORION5X_H + +#if defined(CONFIG_FEROCEON) + +/* SOC specific definations */ +#define ORION5X_REGISTER(x) (ORION5X_REGS_PHY_BASE + x) + +/* Documented registers */ +#define ORION5X_DRAM_BASE (ORION5X_REGISTER(0x01500)) +#define ORION5X_TWSI_BASE (ORION5X_REGISTER(0x11000)) +#define ORION5X_UART0_BASE (ORION5X_REGISTER(0x12000)) +#define ORION5X_UART1_BASE (ORION5X_REGISTER(0x12100)) +#define ORION5X_MPP_BASE (ORION5X_REGISTER(0x10000)) +#define ORION5X_GPIO_BASE (ORION5X_REGISTER(0x10100)) +#define ORION5X_CPU_WIN_BASE (ORION5X_REGISTER(0x20000)) +#define ORION5X_CPU_REG_BASE (ORION5X_REGISTER(0x20100)) +#define ORION5X_TIMER_BASE (ORION5X_REGISTER(0x20300)) +#define ORION5X_REG_PCI_BASE (ORION5X_REGISTER(0x30000)) +#define ORION5X_REG_PCIE_BASE (ORION5X_REGISTER(0x40000)) +#define ORION5X_USB20_PORT0_BASE (ORION5X_REGISTER(0x50000)) +#define ORION5X_USB20_PORT1_BASE (ORION5X_REGISTER(0xA0000)) +#define ORION5X_EGIGA_BASE (ORION5X_REGISTER(0x72000)) +#define ORION5X_SATA_BASE (ORION5X_REGISTER(0x80000)) +#define ORION5X_SATA_PORT0_OFFSET 0x2000 +#define ORION5X_SATA_PORT1_OFFSET 0x4000 + +/* Orion5x GbE controller has a single port */ +#define MAX_MVGBE_DEVS 1 +#define MVGBE0_BASE ORION5X_EGIGA_BASE + +/* Orion5x USB Host controller is port 1 */ +#define MVUSB0_BASE ORION5X_USB20_HOST_PORT_BASE +#define MVUSB0_CPU_ATTR_DRAM_CS0 ORION5X_ATTR_DRAM_CS0 +#define MVUSB0_CPU_ATTR_DRAM_CS1 ORION5X_ATTR_DRAM_CS1 +#define MVUSB0_CPU_ATTR_DRAM_CS2 ORION5X_ATTR_DRAM_CS2 +#define MVUSB0_CPU_ATTR_DRAM_CS3 ORION5X_ATTR_DRAM_CS3 + +/* Kirkwood CPU memory windows */ +#define MVCPU_WIN_CTRL_DATA ORION5X_CPU_WIN_CTRL_DATA +#define MVCPU_WIN_ENABLE ORION5X_WIN_ENABLE +#define MVCPU_WIN_DISABLE ORION5X_WIN_DISABLE + +#define CONFIG_MAX_RAM_BANK_SIZE (64*1024*1024) + +/* include here SoC variants. 5181, 5281, 6183 should go here when + adding support for them, and this comment should then be updated. */ +#if defined(CONFIG_88F5182) +#include +#else +#error "SOC Name not defined" +#endif +#endif /* CONFIG_FEROCEON */ +#endif /* _ASM_ARCH_ORION5X_H */ -- cgit From dc7de222aa82cc962f15b5d04e1e4c6b0ab62398 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:18 +0900 Subject: ARM: keystone: move SoC headers to mach-keystone/include/mach Move arch/arm/include/asm/arch-keystone/* -> arch/arm/mach-keystone/include/mach/* Signed-off-by: Masahiro Yamada Cc: Tom Rini --- arch/arm/include/asm/arch-keystone/clock-k2e.h | 85 ------ arch/arm/include/asm/arch-keystone/clock-k2hk.h | 103 -------- arch/arm/include/asm/arch-keystone/clock-k2l.h | 95 ------- arch/arm/include/asm/arch-keystone/clock.h | 66 ----- arch/arm/include/asm/arch-keystone/clock_defs.h | 111 -------- arch/arm/include/asm/arch-keystone/ddr3.h | 62 ----- arch/arm/include/asm/arch-keystone/hardware-k2e.h | 65 ----- arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 106 -------- arch/arm/include/asm/arch-keystone/hardware-k2l.h | 108 -------- arch/arm/include/asm/arch-keystone/hardware.h | 290 --------------------- arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 -- arch/arm/include/asm/arch-keystone/mon.h | 15 -- arch/arm/include/asm/arch-keystone/msmc.h | 45 ---- arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ------- arch/arm/include/asm/arch-keystone/xhci-keystone.h | 21 -- arch/arm/mach-keystone/include/mach/clock-k2e.h | 85 ++++++ arch/arm/mach-keystone/include/mach/clock-k2hk.h | 103 ++++++++ arch/arm/mach-keystone/include/mach/clock-k2l.h | 95 +++++++ arch/arm/mach-keystone/include/mach/clock.h | 66 +++++ arch/arm/mach-keystone/include/mach/clock_defs.h | 111 ++++++++ arch/arm/mach-keystone/include/mach/ddr3.h | 62 +++++ arch/arm/mach-keystone/include/mach/hardware-k2e.h | 65 +++++ .../arm/mach-keystone/include/mach/hardware-k2hk.h | 106 ++++++++ arch/arm/mach-keystone/include/mach/hardware-k2l.h | 108 ++++++++ arch/arm/mach-keystone/include/mach/hardware.h | 290 +++++++++++++++++++++ arch/arm/mach-keystone/include/mach/i2c_defs.h | 17 ++ arch/arm/mach-keystone/include/mach/mon.h | 15 ++ arch/arm/mach-keystone/include/mach/msmc.h | 45 ++++ arch/arm/mach-keystone/include/mach/psc_defs.h | 90 +++++++ .../arm/mach-keystone/include/mach/xhci-keystone.h | 21 ++ 30 files changed, 1279 insertions(+), 1279 deletions(-) delete mode 100644 arch/arm/include/asm/arch-keystone/clock-k2e.h delete mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h delete mode 100644 arch/arm/include/asm/arch-keystone/clock-k2l.h delete mode 100644 arch/arm/include/asm/arch-keystone/clock.h delete mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h delete mode 100644 arch/arm/include/asm/arch-keystone/ddr3.h delete mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2e.h delete mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h delete mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2l.h delete mode 100644 arch/arm/include/asm/arch-keystone/hardware.h delete mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h delete mode 100644 arch/arm/include/asm/arch-keystone/mon.h delete mode 100644 arch/arm/include/asm/arch-keystone/msmc.h delete mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h delete mode 100644 arch/arm/include/asm/arch-keystone/xhci-keystone.h create mode 100644 arch/arm/mach-keystone/include/mach/clock-k2e.h create mode 100644 arch/arm/mach-keystone/include/mach/clock-k2hk.h create mode 100644 arch/arm/mach-keystone/include/mach/clock-k2l.h create mode 100644 arch/arm/mach-keystone/include/mach/clock.h create mode 100644 arch/arm/mach-keystone/include/mach/clock_defs.h create mode 100644 arch/arm/mach-keystone/include/mach/ddr3.h create mode 100644 arch/arm/mach-keystone/include/mach/hardware-k2e.h create mode 100644 arch/arm/mach-keystone/include/mach/hardware-k2hk.h create mode 100644 arch/arm/mach-keystone/include/mach/hardware-k2l.h create mode 100644 arch/arm/mach-keystone/include/mach/hardware.h create mode 100644 arch/arm/mach-keystone/include/mach/i2c_defs.h create mode 100644 arch/arm/mach-keystone/include/mach/mon.h create mode 100644 arch/arm/mach-keystone/include/mach/msmc.h create mode 100644 arch/arm/mach-keystone/include/mach/psc_defs.h create mode 100644 arch/arm/mach-keystone/include/mach/xhci-keystone.h diff --git a/arch/arm/include/asm/arch-keystone/clock-k2e.h b/arch/arm/include/asm/arch-keystone/clock-k2e.h deleted file mode 100644 index d013b830ed..0000000000 --- a/arch/arm/include/asm/arch-keystone/clock-k2e.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * K2E: Clock management APIs - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_CLOCK_K2E_H -#define __ASM_ARCH_CLOCK_K2E_H - -enum ext_clk_e { - sys_clk, - alt_core_clk, - pa_clk, - ddr3_clk, - mcm_clk, - pcie_clk, - sgmii_clk, - xgmii_clk, - usb_clk, - ext_clk_count /* number of external clocks */ -}; - -extern unsigned int external_clk[ext_clk_count]; - -#define CLK_LIST(CLK)\ - CLK(0, core_pll_clk)\ - CLK(1, pass_pll_clk)\ - CLK(2, ddr3_pll_clk)\ - CLK(3, sys_clk0_clk)\ - CLK(4, sys_clk0_1_clk)\ - CLK(5, sys_clk0_2_clk)\ - CLK(6, sys_clk0_3_clk)\ - CLK(7, sys_clk0_4_clk)\ - CLK(8, sys_clk0_6_clk)\ - CLK(9, sys_clk0_8_clk)\ - CLK(10, sys_clk0_12_clk)\ - CLK(11, sys_clk0_24_clk)\ - CLK(12, sys_clk1_clk)\ - CLK(13, sys_clk1_3_clk)\ - CLK(14, sys_clk1_4_clk)\ - CLK(15, sys_clk1_6_clk)\ - CLK(16, sys_clk1_12_clk)\ - CLK(17, sys_clk2_clk)\ - CLK(18, sys_clk3_clk) - -#define PLLSET_CMD_LIST "" - -#define KS2_CLK1_6 sys_clk0_6_clk - -/* PLL identifiers */ -enum pll_type_e { - CORE_PLL, - PASS_PLL, - DDR3_PLL, -}; - -enum { - SPD800, - SPD850, - SPD1000, - SPD1250, - SPD1350, - SPD1400, - SPD1500, - SPD_RSV -}; - -#define CORE_PLL_800 {CORE_PLL, 16, 1, 2} -#define CORE_PLL_850 {CORE_PLL, 17, 1, 2} -#define CORE_PLL_1000 {CORE_PLL, 20, 1, 2} -#define CORE_PLL_1200 {CORE_PLL, 24, 1, 2} -#define PASS_PLL_1000 {PASS_PLL, 20, 1, 2} -#define CORE_PLL_1250 {CORE_PLL, 25, 1, 2} -#define CORE_PLL_1350 {CORE_PLL, 27, 1, 2} -#define CORE_PLL_1400 {CORE_PLL, 28, 1, 2} -#define CORE_PLL_1500 {CORE_PLL, 30, 1, 2} -#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2} -#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4} -#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2} -#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6} - -#endif diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h deleted file mode 100644 index f28d5f0c4e..0000000000 --- a/arch/arm/include/asm/arch-keystone/clock-k2hk.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * K2HK: Clock management APIs - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_CLOCK_K2HK_H -#define __ASM_ARCH_CLOCK_K2HK_H - -enum ext_clk_e { - sys_clk, - alt_core_clk, - pa_clk, - tetris_clk, - ddr3a_clk, - ddr3b_clk, - mcm_clk, - pcie_clk, - sgmii_srio_clk, - xgmii_clk, - usb_clk, - rp1_clk, - ext_clk_count /* number of external clocks */ -}; - -extern unsigned int external_clk[ext_clk_count]; - -#define CLK_LIST(CLK)\ - CLK(0, core_pll_clk)\ - CLK(1, pass_pll_clk)\ - CLK(2, tetris_pll_clk)\ - CLK(3, ddr3a_pll_clk)\ - CLK(4, ddr3b_pll_clk)\ - CLK(5, sys_clk0_clk)\ - CLK(6, sys_clk0_1_clk)\ - CLK(7, sys_clk0_2_clk)\ - CLK(8, sys_clk0_3_clk)\ - CLK(9, sys_clk0_4_clk)\ - CLK(10, sys_clk0_6_clk)\ - CLK(11, sys_clk0_8_clk)\ - CLK(12, sys_clk0_12_clk)\ - CLK(13, sys_clk0_24_clk)\ - CLK(14, sys_clk1_clk)\ - CLK(15, sys_clk1_3_clk)\ - CLK(16, sys_clk1_4_clk)\ - CLK(17, sys_clk1_6_clk)\ - CLK(18, sys_clk1_12_clk)\ - CLK(19, sys_clk2_clk)\ - CLK(20, sys_clk3_clk) - -#define PLLSET_CMD_LIST "" - -#define KS2_CLK1_6 sys_clk0_6_clk - -/* PLL identifiers */ -enum pll_type_e { - CORE_PLL, - PASS_PLL, - TETRIS_PLL, - DDR3A_PLL, - DDR3B_PLL, -}; - -enum { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD_RSV -}; - -#define CORE_PLL_799 {CORE_PLL, 13, 1, 2} -#define CORE_PLL_983 {CORE_PLL, 16, 1, 2} -#define CORE_PLL_999 {CORE_PLL, 122, 15, 1} -#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2} -#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2} -#define CORE_PLL_1200 {CORE_PLL, 625, 32, 2} -#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2} -#define PASS_PLL_983 {PASS_PLL, 16, 1, 2} -#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2} -#define TETRIS_PLL_500 {TETRIS_PLL, 8, 1, 2} -#define TETRIS_PLL_750 {TETRIS_PLL, 12, 1, 2} -#define TETRIS_PLL_800 {TETRIS_PLL, 32, 5, 1} -#define TETRIS_PLL_687 {TETRIS_PLL, 11, 1, 2} -#define TETRIS_PLL_625 {TETRIS_PLL, 10, 1, 2} -#define TETRIS_PLL_812 {TETRIS_PLL, 13, 1, 2} -#define TETRIS_PLL_875 {TETRIS_PLL, 14, 1, 2} -#define TETRIS_PLL_1000 {TETRIS_PLL, 40, 5, 1} -#define TETRIS_PLL_1188 {TETRIS_PLL, 19, 2, 1} -#define TETRIS_PLL_1200 {TETRIS_PLL, 48, 5, 1} -#define TETRIS_PLL_1350 {TETRIS_PLL, 54, 5, 1} -#define TETRIS_PLL_1375 {TETRIS_PLL, 22, 2, 1} -#define TETRIS_PLL_1400 {TETRIS_PLL, 56, 5, 1} -#define DDR3_PLL_200(x) {DDR3##x##_PLL, 4, 1, 2} -#define DDR3_PLL_400(x) {DDR3##x##_PLL, 16, 1, 4} -#define DDR3_PLL_800(x) {DDR3##x##_PLL, 16, 1, 2} -#define DDR3_PLL_333(x) {DDR3##x##_PLL, 20, 1, 6} - -#endif diff --git a/arch/arm/include/asm/arch-keystone/clock-k2l.h b/arch/arm/include/asm/arch-keystone/clock-k2l.h deleted file mode 100644 index bb9a5c4dcf..0000000000 --- a/arch/arm/include/asm/arch-keystone/clock-k2l.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * K2L: Clock management APIs - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_CLOCK_K2L_H -#define __ASM_ARCH_CLOCK_K2L_H - -enum ext_clk_e { - sys_clk, - alt_core_clk, - pa_clk, - tetris_clk, - ddr3_clk, - pcie_clk, - sgmii_clk, - usb_clk, - rp1_clk, - ext_clk_count /* number of external clocks */ -}; - -extern unsigned int external_clk[ext_clk_count]; - -#define CLK_LIST(CLK)\ - CLK(0, core_pll_clk)\ - CLK(1, pass_pll_clk)\ - CLK(2, tetris_pll_clk)\ - CLK(3, ddr3_pll_clk)\ - CLK(4, sys_clk0_clk)\ - CLK(5, sys_clk0_1_clk)\ - CLK(6, sys_clk0_2_clk)\ - CLK(7, sys_clk0_3_clk)\ - CLK(8, sys_clk0_4_clk)\ - CLK(9, sys_clk0_6_clk)\ - CLK(10, sys_clk0_8_clk)\ - CLK(11, sys_clk0_12_clk)\ - CLK(12, sys_clk0_24_clk)\ - CLK(13, sys_clk1_clk)\ - CLK(14, sys_clk1_3_clk)\ - CLK(15, sys_clk1_4_clk)\ - CLK(16, sys_clk1_6_clk)\ - CLK(17, sys_clk1_12_clk)\ - CLK(18, sys_clk2_clk)\ - CLK(19, sys_clk3_clk)\ - -#define PLLSET_CMD_LIST "" - -#define KS2_CLK1_6 sys_clk0_6_clk - -/* PLL identifiers */ -enum pll_type_e { - CORE_PLL, - PASS_PLL, - TETRIS_PLL, - DDR3_PLL, -}; - -enum { - SPD800, - SPD1000, - SPD1200, - SPD1350, - SPD1400, - SPD_RSV -}; - -#define CORE_PLL_799 {CORE_PLL, 13, 1, 2} -#define CORE_PLL_983 {CORE_PLL, 16, 1, 2} -#define CORE_PLL_1000 {CORE_PLL, 114, 7, 2} -#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2} -#define CORE_PLL_1198 {CORE_PLL, 39, 2, 2} -#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2} -#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2} -#define PASS_PLL_983 {PASS_PLL, 16, 1, 2} -#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2} -#define TETRIS_PLL_491 {TETRIS_PLL, 8, 1, 2} -#define TETRIS_PLL_737 {TETRIS_PLL, 12, 1, 2} -#define TETRIS_PLL_799 {TETRIS_PLL, 13, 1, 2} -#define TETRIS_PLL_983 {TETRIS_PLL, 16, 1, 2} -#define TETRIS_PLL_1000 {TETRIS_PLL, 114, 7, 2} -#define TETRIS_PLL_1167 {TETRIS_PLL, 19, 1, 2} -#define TETRIS_PLL_1198 {TETRIS_PLL, 39, 2, 2} -#define TETRIS_PLL_1228 {TETRIS_PLL, 20, 1, 2} -#define TETRIS_PLL_1352 {TETRIS_PLL, 22, 1, 2} -#define TETRIS_PLL_1401 {TETRIS_PLL, 114, 5, 2} -#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2} -#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4} -#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2} -#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6} - -#endif diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h deleted file mode 100644 index 9f6cfb265f..0000000000 --- a/arch/arm/include/asm/arch-keystone/clock.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * keystone2: common clock header file - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_CLOCK_H -#define __ASM_ARCH_CLOCK_H - -#ifndef __ASSEMBLY__ - -#ifdef CONFIG_SOC_K2HK -#include -#endif - -#ifdef CONFIG_SOC_K2E -#include -#endif - -#ifdef CONFIG_SOC_K2L -#include -#endif - -#define MAIN_PLL CORE_PLL - -#include - -#define GENERATE_ENUM(NUM, ENUM) ENUM = NUM, -#define GENERATE_INDX_STR(NUM, STRING) #NUM"\t- "#STRING"\n" -#define CLOCK_INDEXES_LIST CLK_LIST(GENERATE_INDX_STR) - -enum clk_e { - CLK_LIST(GENERATE_ENUM) -}; - -struct keystone_pll_regs { - u32 reg0; - u32 reg1; -}; - -/* PLL configuration data */ -struct pll_init_data { - int pll; - int pll_m; /* PLL Multiplier */ - int pll_d; /* PLL divider */ - int pll_od; /* PLL output divider */ -}; - -extern const struct keystone_pll_regs keystone_pll_regs[]; -extern int dev_speeds[]; -extern int arm_speeds[]; - -void init_plls(int num_pll, struct pll_init_data *config); -void init_pll(const struct pll_init_data *data); -unsigned long clk_get_rate(unsigned int clk); -unsigned long clk_round_rate(unsigned int clk, unsigned long hz); -int clk_set_rate(unsigned int clk, unsigned long hz); -void pass_pll_pa_clk_enable(void); -int get_max_dev_speed(void); -int get_max_arm_speed(void); - -#endif -#endif diff --git a/arch/arm/include/asm/arch-keystone/clock_defs.h b/arch/arm/include/asm/arch-keystone/clock_defs.h deleted file mode 100644 index 85a046b89a..0000000000 --- a/arch/arm/include/asm/arch-keystone/clock_defs.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * keystone2: common pll clock definitions - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _CLOCK_DEFS_H_ -#define _CLOCK_DEFS_H_ - -#include - -#define BIT(x) (1 << (x)) - -/* PLL Control Registers */ -struct pllctl_regs { - u32 ctl; /* 00 */ - u32 ocsel; /* 04 */ - u32 secctl; /* 08 */ - u32 resv0; - u32 mult; /* 10 */ - u32 prediv; /* 14 */ - u32 div1; /* 18 */ - u32 div2; /* 1c */ - u32 div3; /* 20 */ - u32 oscdiv1; /* 24 */ - u32 resv1; /* 28 */ - u32 bpdiv; /* 2c */ - u32 wakeup; /* 30 */ - u32 resv2; - u32 cmd; /* 38 */ - u32 stat; /* 3c */ - u32 alnctl; /* 40 */ - u32 dchange; /* 44 */ - u32 cken; /* 48 */ - u32 ckstat; /* 4c */ - u32 systat; /* 50 */ - u32 ckctl; /* 54 */ - u32 resv3[2]; - u32 div4; /* 60 */ - u32 div5; /* 64 */ - u32 div6; /* 68 */ - u32 div7; /* 6c */ - u32 div8; /* 70 */ - u32 div9; /* 74 */ - u32 div10; /* 78 */ - u32 div11; /* 7c */ - u32 div12; /* 80 */ -}; - -static struct pllctl_regs *pllctl_regs[] = { - (struct pllctl_regs *)(KS2_CLOCK_BASE + 0x100) -}; - -#define pllctl_reg(pll, reg) (&(pllctl_regs[pll]->reg)) -#define pllctl_reg_read(pll, reg) __raw_readl(pllctl_reg(pll, reg)) -#define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg)) - -#define pllctl_reg_rmw(pll, reg, mask, val) \ - pllctl_reg_write(pll, reg, \ - (pllctl_reg_read(pll, reg) & ~(mask)) | val) - -#define pllctl_reg_setbits(pll, reg, mask) \ - pllctl_reg_rmw(pll, reg, 0, mask) - -#define pllctl_reg_clrbits(pll, reg, mask) \ - pllctl_reg_rmw(pll, reg, mask, 0) - -#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1) - -/* PLLCTL Bits */ -#define PLLCTL_BYPASS BIT(23) -#define PLL_PLLRST BIT(14) -#define PLLCTL_PAPLL BIT(13) -#define PLLCTL_CLKMODE BIT(8) -#define PLLCTL_PLLSELB BIT(7) -#define PLLCTL_ENSAT BIT(6) -#define PLLCTL_PLLENSRC BIT(5) -#define PLLCTL_PLLDIS BIT(4) -#define PLLCTL_PLLRST BIT(3) -#define PLLCTL_PLLPWRDN BIT(1) -#define PLLCTL_PLLEN BIT(0) -#define PLLSTAT_GO BIT(0) - -#define MAIN_ENSAT_OFFSET 6 - -#define PLLDIV_ENABLE BIT(15) - -#define PLL_DIV_MASK 0x3f -#define PLL_MULT_MASK 0x1fff -#define PLL_MULT_SHIFT 6 -#define PLLM_MULT_HI_MASK 0x7f -#define PLLM_MULT_HI_SHIFT 12 -#define PLLM_MULT_HI_SMASK (PLLM_MULT_HI_MASK << PLLM_MULT_HI_SHIFT) -#define PLLM_MULT_LO_MASK 0x3f -#define PLL_CLKOD_MASK 0xf -#define PLL_CLKOD_SHIFT 19 -#define PLL_CLKOD_SMASK (PLL_CLKOD_MASK << PLL_CLKOD_SHIFT) -#define PLL_BWADJ_LO_MASK 0xff -#define PLL_BWADJ_LO_SHIFT 24 -#define PLL_BWADJ_LO_SMASK (PLL_BWADJ_LO_MASK << PLL_BWADJ_LO_SHIFT) -#define PLL_BWADJ_HI_MASK 0xf - -#define PLLM_RATIO_DIV1 (PLLDIV_ENABLE | 0x0) -#define PLLM_RATIO_DIV2 (PLLDIV_ENABLE | 0x0) -#define PLLM_RATIO_DIV3 (PLLDIV_ENABLE | 0x1) -#define PLLM_RATIO_DIV4 (PLLDIV_ENABLE | 0x4) -#define PLLM_RATIO_DIV5 (PLLDIV_ENABLE | 0x17) - -#endif /* _CLOCK_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-keystone/ddr3.h b/arch/arm/include/asm/arch-keystone/ddr3.h deleted file mode 100644 index a22c237c80..0000000000 --- a/arch/arm/include/asm/arch-keystone/ddr3.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * DDR3 - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _DDR3_H_ -#define _DDR3_H_ - -#include - -struct ddr3_phy_config { - unsigned int pllcr; - unsigned int pgcr1_mask; - unsigned int pgcr1_val; - unsigned int ptr0; - unsigned int ptr1; - unsigned int ptr2; - unsigned int ptr3; - unsigned int ptr4; - unsigned int dcr_mask; - unsigned int dcr_val; - unsigned int dtpr0; - unsigned int dtpr1; - unsigned int dtpr2; - unsigned int mr0; - unsigned int mr1; - unsigned int mr2; - unsigned int dtcr; - unsigned int pgcr2; - unsigned int zq0cr1; - unsigned int zq1cr1; - unsigned int zq2cr1; - unsigned int pir_v1; - unsigned int pir_v2; -}; - -struct ddr3_emif_config { - unsigned int sdcfg; - unsigned int sdtim1; - unsigned int sdtim2; - unsigned int sdtim3; - unsigned int sdtim4; - unsigned int zqcfg; - unsigned int sdrfc; -}; - -u32 ddr3_init(void); -void ddr3_reset_ddrphy(void); -void ddr3_init_ecc(u32 base, u32 ddr3_size); -void ddr3_disable_ecc(u32 base); -void ddr3_check_ecc_int(u32 base); -int ddr3_ecc_support_rmw(u32 base); -void ddr3_err_reset_workaround(void); -void ddr3_enable_ecc(u32 base, int test); -void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg); -void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg); - -#endif diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2e.h b/arch/arm/include/asm/arch-keystone/hardware-k2e.h deleted file mode 100644 index df499957e5..0000000000 --- a/arch/arm/include/asm/arch-keystone/hardware-k2e.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * K2E: SoC definitions - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_HARDWARE_K2E_H -#define __ASM_ARCH_HARDWARE_K2E_H - -/* PA SS Registers */ -#define KS2_PASS_BASE 0x24000000 - -/* Power and Sleep Controller (PSC) Domains */ -#define KS2_LPSC_MOD_RST 0 -#define KS2_LPSC_USB_1 1 -#define KS2_LPSC_USB 2 -#define KS2_LPSC_EMIF25_SPI 3 -#define KS2_LPSC_TSIP 4 -#define KS2_LPSC_DEBUGSS_TRC 5 -#define KS2_LPSC_TETB_TRC 6 -#define KS2_LPSC_PKTPROC 7 -#define KS2_LPSC_PA KS2_LPSC_PKTPROC -#define KS2_LPSC_SGMII 8 -#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII -#define KS2_LPSC_CRYPTO 9 -#define KS2_LPSC_PCIE 10 -#define KS2_LPSC_VUSR0 12 -#define KS2_LPSC_CHIP_SRSS 13 -#define KS2_LPSC_MSMC 14 -#define KS2_LPSC_EMIF4F_DDR3 23 -#define KS2_LPSC_PCIE_1 27 -#define KS2_LPSC_XGE 50 - -/* MSMC */ -#define KS2_MSMC_SEGMENT_PCIE1 13 - -/* Chip Interrupt Controller */ -#define KS2_CIC2_DDR3_ECC_IRQ_NUM -1 /* not defined in K2E */ -#define KS2_CIC2_DDR3_ECC_CHAN_NUM -1 /* not defined in K2E */ - -/* SGMII SerDes */ -#define KS2_SGMII_SERDES2_BASE 0x02324000 -#define KS2_LANES_PER_SGMII_SERDES 4 - -/* Number of DSP cores */ -#define KS2_NUM_DSPS 1 - -/* NETCP pktdma */ -#define KS2_NETCP_PDMA_CTRL_BASE 0x24186000 -#define KS2_NETCP_PDMA_TX_BASE 0x24187000 -#define KS2_NETCP_PDMA_TX_CH_NUM 21 -#define KS2_NETCP_PDMA_RX_BASE 0x24188000 -#define KS2_NETCP_PDMA_RX_CH_NUM 91 -#define KS2_NETCP_PDMA_SCHED_BASE 0x24186100 -#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x24189000 -#define KS2_NETCP_PDMA_RX_FLOW_NUM 96 -#define KS2_NETCP_PDMA_TX_SND_QUEUE 896 - -/* NETCP */ -#define KS2_NETCP_BASE 0x24000000 - -#endif diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h deleted file mode 100644 index 195c0d3003..0000000000 --- a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * K2HK: SoC definitions - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_HARDWARE_K2HK_H -#define __ASM_ARCH_HARDWARE_K2HK_H - -#define KS2_ARM_PLL_EN BIT(13) - -/* PA SS Registers */ -#define KS2_PASS_BASE 0x02000000 - -/* PLL control registers */ -#define KS2_DDR3BPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x368) -#define KS2_DDR3BPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x36C) - -/* Power and Sleep Controller (PSC) Domains */ -#define KS2_LPSC_MOD 0 -#define KS2_LPSC_DUMMY1 1 -#define KS2_LPSC_USB 2 -#define KS2_LPSC_EMIF25_SPI 3 -#define KS2_LPSC_TSIP 4 -#define KS2_LPSC_DEBUGSS_TRC 5 -#define KS2_LPSC_TETB_TRC 6 -#define KS2_LPSC_PKTPROC 7 -#define KS2_LPSC_PA KS2_LPSC_PKTPROC -#define KS2_LPSC_SGMII 8 -#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII -#define KS2_LPSC_CRYPTO 9 -#define KS2_LPSC_PCIE 10 -#define KS2_LPSC_SRIO 11 -#define KS2_LPSC_VUSR0 12 -#define KS2_LPSC_CHIP_SRSS 13 -#define KS2_LPSC_MSMC 14 -#define KS2_LPSC_GEM_1 16 -#define KS2_LPSC_GEM_2 17 -#define KS2_LPSC_GEM_3 18 -#define KS2_LPSC_GEM_4 19 -#define KS2_LPSC_GEM_5 20 -#define KS2_LPSC_GEM_6 21 -#define KS2_LPSC_GEM_7 22 -#define KS2_LPSC_EMIF4F_DDR3A 23 -#define KS2_LPSC_EMIF4F_DDR3B 24 -#define KS2_LPSC_TAC 25 -#define KS2_LPSC_RAC 26 -#define KS2_LPSC_RAC_1 27 -#define KS2_LPSC_FFTC_A 28 -#define KS2_LPSC_FFTC_B 29 -#define KS2_LPSC_FFTC_C 30 -#define KS2_LPSC_FFTC_D 31 -#define KS2_LPSC_FFTC_E 32 -#define KS2_LPSC_FFTC_F 33 -#define KS2_LPSC_AI2 34 -#define KS2_LPSC_TCP3D_0 35 -#define KS2_LPSC_TCP3D_1 36 -#define KS2_LPSC_TCP3D_2 37 -#define KS2_LPSC_TCP3D_3 38 -#define KS2_LPSC_VCP2X4_A 39 -#define KS2_LPSC_CP2X4_B 40 -#define KS2_LPSC_VCP2X4_C 41 -#define KS2_LPSC_VCP2X4_D 42 -#define KS2_LPSC_VCP2X4_E 43 -#define KS2_LPSC_VCP2X4_F 44 -#define KS2_LPSC_VCP2X4_G 45 -#define KS2_LPSC_VCP2X4_H 46 -#define KS2_LPSC_BCP 47 -#define KS2_LPSC_DXB 48 -#define KS2_LPSC_VUSR1 49 -#define KS2_LPSC_XGE 50 -#define KS2_LPSC_ARM_SREFLEX 51 - -/* DDR3B definitions */ -#define KS2_DDR3B_EMIF_CTRL_BASE 0x21020000 -#define KS2_DDR3B_EMIF_DATA_BASE 0x60000000 -#define KS2_DDR3B_DDRPHYC 0x02328000 - -#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3 /* DDR3 ECC system irq number */ -#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D /* DDR3 ECC int mapped to CIC2 - channel 29 */ - -/* SGMII SerDes */ -#define KS2_LANES_PER_SGMII_SERDES 4 - -/* Number of DSP cores */ -#define KS2_NUM_DSPS 8 - -/* NETCP pktdma */ -#define KS2_NETCP_PDMA_CTRL_BASE 0x02004000 -#define KS2_NETCP_PDMA_TX_BASE 0x02004400 -#define KS2_NETCP_PDMA_TX_CH_NUM 9 -#define KS2_NETCP_PDMA_RX_BASE 0x02004800 -#define KS2_NETCP_PDMA_RX_CH_NUM 26 -#define KS2_NETCP_PDMA_SCHED_BASE 0x02004c00 -#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x02005000 -#define KS2_NETCP_PDMA_RX_FLOW_NUM 32 -#define KS2_NETCP_PDMA_TX_SND_QUEUE 648 - -/* NETCP */ -#define KS2_NETCP_BASE 0x02000000 - -#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2l.h b/arch/arm/include/asm/arch-keystone/hardware-k2l.h deleted file mode 100644 index 4f1197ea92..0000000000 --- a/arch/arm/include/asm/arch-keystone/hardware-k2l.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * K2L: SoC definitions - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_ARCH_HARDWARE_K2L_H -#define __ASM_ARCH_HARDWARE_K2L_H - -#define KS2_ARM_PLL_EN BIT(13) - -/* PA SS Registers */ -#define KS2_PASS_BASE 0x26000000 - -/* Power and Sleep Controller (PSC) Domains */ -#define KS2_LPSC_MOD 0 -#define KS2_LPSC_DFE_IQN_SYS 1 -#define KS2_LPSC_USB 2 -#define KS2_LPSC_EMIF25_SPI 3 -#define KS2_LPSC_TSIP 4 -#define KS2_LPSC_DEBUGSS_TRC 5 -#define KS2_LPSC_TETB_TRC 6 -#define KS2_LPSC_PKTPROC 7 -#define KS2_LPSC_PA KS2_LPSC_PKTPROC -#define KS2_LPSC_SGMII 8 -#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII -#define KS2_LPSC_CRYPTO 9 -#define KS2_LPSC_PCIE0 10 -#define KS2_LPSC_PCIE1 11 -#define KS2_LPSC_JESD_MISC 12 -#define KS2_LPSC_CHIP_SRSS 13 -#define KS2_LPSC_MSMC 14 -#define KS2_LPSC_GEM_1 16 -#define KS2_LPSC_GEM_2 17 -#define KS2_LPSC_GEM_3 18 -#define KS2_LPSC_EMIF4F_DDR3 23 -#define KS2_LPSC_TAC 25 -#define KS2_LPSC_RAC 26 -#define KS2_LPSC_DDUC4X_CFR2X_BB 27 -#define KS2_LPSC_FFTC_A 28 -#define KS2_LPSC_OSR 34 -#define KS2_LPSC_TCP3D_0 35 -#define KS2_LPSC_TCP3D_1 37 -#define KS2_LPSC_VCP2X4_A 39 -#define KS2_LPSC_VCP2X4_B 40 -#define KS2_LPSC_VCP2X4_C 41 -#define KS2_LPSC_VCP2X4_D 42 -#define KS2_LPSC_BCP 47 -#define KS2_LPSC_DPD4X 48 -#define KS2_LPSC_FFTC_B 49 -#define KS2_LPSC_IQN_AIL 50 - -/* MSMC */ -#define KS2_MSMC_SEGMENT_PCIE1 14 - -/* Chip Interrupt Controller */ -#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3 -#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D - -/* OSR */ -#define KS2_OSR_DATA_BASE 0x70000000 /* OSR data base */ -#define KS2_OSR_CFG_BASE 0x02348c00 /* OSR config base */ -#define KS2_OSR_ECC_VEC 0x08 /* ECC Vector reg */ -#define KS2_OSR_ECC_CTRL 0x14 /* ECC control reg */ - -/* OSR ECC Vector register */ -#define KS2_OSR_ECC_VEC_TRIG_RD BIT(15) /* trigger a read op */ -#define KS2_OSR_ECC_VEC_RD_DONE BIT(24) /* read complete */ - -#define KS2_OSR_ECC_VEC_RAM_ID_SH 0 /* RAM ID shift */ -#define KS2_OSR_ECC_VEC_RD_ADDR_SH 16 /* read address shift */ - -/* OSR ECC control register */ -#define KS2_OSR_ECC_CTRL_EN BIT(0) /* ECC enable bit */ -#define KS2_OSR_ECC_CTRL_CHK BIT(1) /* ECC check bit */ -#define KS2_OSR_ECC_CTRL_RMW BIT(2) /* ECC check bit */ - -/* Number of OSR RAM banks */ -#define KS2_OSR_NUM_RAM_BANKS 4 - -/* OSR memory size */ -#define KS2_OSR_SIZE 0x100000 - -/* SGMII SerDes */ -#define KS2_SGMII_SERDES2_BASE 0x02320000 -#define KS2_LANES_PER_SGMII_SERDES 2 - -/* Number of DSP cores */ -#define KS2_NUM_DSPS 4 - -/* NETCP pktdma */ -#define KS2_NETCP_PDMA_CTRL_BASE 0x26186000 -#define KS2_NETCP_PDMA_TX_BASE 0x26187000 -#define KS2_NETCP_PDMA_TX_CH_NUM 21 -#define KS2_NETCP_PDMA_RX_BASE 0x26188000 -#define KS2_NETCP_PDMA_RX_CH_NUM 91 -#define KS2_NETCP_PDMA_SCHED_BASE 0x26186100 -#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x26189000 -#define KS2_NETCP_PDMA_RX_FLOW_NUM 96 -#define KS2_NETCP_PDMA_TX_SND_QUEUE 896 - -/* NETCP */ -#define KS2_NETCP_BASE 0x26000000 - -#endif /* __ASM_ARCH_HARDWARE_K2L_H */ diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h deleted file mode 100644 index 16cbcee12b..0000000000 --- a/arch/arm/include/asm/arch-keystone/hardware.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Keystone2: Common SoC definitions, structures etc. - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include - -#ifndef __ASSEMBLY__ - -#include -#include - -#define REG(addr) (*(volatile unsigned int *)(addr)) -#define REG_P(addr) ((volatile unsigned int *)(addr)) - -typedef volatile unsigned int dv_reg; -typedef volatile unsigned int *dv_reg_p; - -#endif - -#define BIT(x) (1 << (x)) - -#define KS2_DDRPHY_PIR_OFFSET 0x04 -#define KS2_DDRPHY_PGCR0_OFFSET 0x08 -#define KS2_DDRPHY_PGCR1_OFFSET 0x0C -#define KS2_DDRPHY_PGSR0_OFFSET 0x10 -#define KS2_DDRPHY_PGSR1_OFFSET 0x14 -#define KS2_DDRPHY_PLLCR_OFFSET 0x18 -#define KS2_DDRPHY_PTR0_OFFSET 0x1C -#define KS2_DDRPHY_PTR1_OFFSET 0x20 -#define KS2_DDRPHY_PTR2_OFFSET 0x24 -#define KS2_DDRPHY_PTR3_OFFSET 0x28 -#define KS2_DDRPHY_PTR4_OFFSET 0x2C -#define KS2_DDRPHY_DCR_OFFSET 0x44 - -#define KS2_DDRPHY_DTPR0_OFFSET 0x48 -#define KS2_DDRPHY_DTPR1_OFFSET 0x4C -#define KS2_DDRPHY_DTPR2_OFFSET 0x50 - -#define KS2_DDRPHY_MR0_OFFSET 0x54 -#define KS2_DDRPHY_MR1_OFFSET 0x58 -#define KS2_DDRPHY_MR2_OFFSET 0x5C -#define KS2_DDRPHY_DTCR_OFFSET 0x68 -#define KS2_DDRPHY_PGCR2_OFFSET 0x8C - -#define KS2_DDRPHY_ZQ0CR1_OFFSET 0x184 -#define KS2_DDRPHY_ZQ1CR1_OFFSET 0x194 -#define KS2_DDRPHY_ZQ2CR1_OFFSET 0x1A4 -#define KS2_DDRPHY_ZQ3CR1_OFFSET 0x1B4 - -#define KS2_DDRPHY_DATX8_8_OFFSET 0x3C0 - -#define IODDRM_MASK 0x00000180 -#define ZCKSEL_MASK 0x01800000 -#define CL_MASK 0x00000072 -#define WR_MASK 0x00000E00 -#define BL_MASK 0x00000003 -#define RRMODE_MASK 0x00040000 -#define UDIMM_MASK 0x20000000 -#define BYTEMASK_MASK 0x0003FC00 -#define MPRDQ_MASK 0x00000080 -#define PDQ_MASK 0x00000070 -#define NOSRA_MASK 0x08000000 -#define ECC_MASK 0x00000001 - -/* DDR3 definitions */ -#define KS2_DDR3A_EMIF_CTRL_BASE 0x21010000 -#define KS2_DDR3A_EMIF_DATA_BASE 0x80000000 -#define KS2_DDR3A_DDRPHYC 0x02329000 - -#define KS2_DDR3_MIDR_OFFSET 0x00 -#define KS2_DDR3_STATUS_OFFSET 0x04 -#define KS2_DDR3_SDCFG_OFFSET 0x08 -#define KS2_DDR3_SDRFC_OFFSET 0x10 -#define KS2_DDR3_SDTIM1_OFFSET 0x18 -#define KS2_DDR3_SDTIM2_OFFSET 0x1C -#define KS2_DDR3_SDTIM3_OFFSET 0x20 -#define KS2_DDR3_SDTIM4_OFFSET 0x28 -#define KS2_DDR3_PMCTL_OFFSET 0x38 -#define KS2_DDR3_ZQCFG_OFFSET 0xC8 - -#define KS2_DDR3_PLLCTRL_PHY_RESET 0x80000000 - -/* DDR3 ECC */ -#define KS2_DDR3_ECC_INT_STATUS_OFFSET 0x0AC -#define KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET 0x0B4 -#define KS2_DDR3_ECC_CTRL_OFFSET 0x110 -#define KS2_DDR3_ECC_ADDR_RANGE1_OFFSET 0x114 -#define KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET 0x130 -#define KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET 0x13C - -/* DDR3 ECC Interrupt Status register */ -#define KS2_DDR3_1B_ECC_ERR_SYS BIT(5) -#define KS2_DDR3_2B_ECC_ERR_SYS BIT(4) -#define KS2_DDR3_WR_ECC_ERR_SYS BIT(3) - -/* DDR3 ECC Control register */ -#define KS2_DDR3_ECC_EN BIT(31) -#define KS2_DDR3_ECC_ADDR_RNG_PROT BIT(30) -#define KS2_DDR3_ECC_VERIFY_EN BIT(29) -#define KS2_DDR3_ECC_RMW_EN BIT(28) -#define KS2_DDR3_ECC_ADDR_RNG_1_EN BIT(0) - -#define KS2_DDR3_ECC_ENABLE (KS2_DDR3_ECC_EN | \ - KS2_DDR3_ECC_ADDR_RNG_PROT | \ - KS2_DDR3_ECC_VERIFY_EN) - -/* EDMA */ -#define KS2_EDMA0_BASE 0x02700000 - -/* EDMA3 register offsets */ -#define KS2_EDMA_QCHMAP0 0x0200 -#define KS2_EDMA_IPR 0x1068 -#define KS2_EDMA_ICR 0x1070 -#define KS2_EDMA_QEECR 0x1088 -#define KS2_EDMA_QEESR 0x108c -#define KS2_EDMA_PARAM_1(x) (0x4020 + (4 * x)) - -/* NETCP pktdma */ -#define KS2_NETCP_PDMA_RX_FREE_QUEUE 4001 -#define KS2_NETCP_PDMA_RX_RCV_QUEUE 4002 - -/* Chip Interrupt Controller */ -#define KS2_CIC2_BASE 0x02608000 - -/* Chip Interrupt Controller register offsets */ -#define KS2_CIC_CTRL 0x04 -#define KS2_CIC_HOST_CTRL 0x0C -#define KS2_CIC_GLOBAL_ENABLE 0x10 -#define KS2_CIC_SYS_ENABLE_IDX_SET 0x28 -#define KS2_CIC_HOST_ENABLE_IDX_SET 0x34 -#define KS2_CIC_CHAN_MAP(n) (0x0400 + (n << 2)) - -#define KS2_UART0_BASE 0x02530c00 -#define KS2_UART1_BASE 0x02531000 - -/* Boot Config */ -#define KS2_DEVICE_STATE_CTRL_BASE 0x02620000 -#define KS2_JTAG_ID_REG (KS2_DEVICE_STATE_CTRL_BASE + 0x18) -#define KS2_DEVSTAT (KS2_DEVICE_STATE_CTRL_BASE + 0x20) -#define KS2_DEVCFG (KS2_DEVICE_STATE_CTRL_BASE + 0x14c) - -/* PSC */ -#define KS2_PSC_BASE 0x02350000 -#define KS2_LPSC_GEM_0 15 -#define KS2_LPSC_TETRIS 52 -#define KS2_TETRIS_PWR_DOMAIN 31 - -/* Chip configuration unlock codes and registers */ -#define KS2_KICK0 (KS2_DEVICE_STATE_CTRL_BASE + 0x38) -#define KS2_KICK1 (KS2_DEVICE_STATE_CTRL_BASE + 0x3c) -#define KS2_KICK0_MAGIC 0x83e70b13 -#define KS2_KICK1_MAGIC 0x95a4f1e0 - -/* PLL control registers */ -#define KS2_MAINPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x350) -#define KS2_MAINPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x354) -#define KS2_PASSPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x358) -#define KS2_PASSPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x35C) -#define KS2_DDR3APLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x360) -#define KS2_DDR3APLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x364) -#define KS2_ARMPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x370) -#define KS2_ARMPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x374) - -#define KS2_PLL_CNTRL_BASE 0x02310000 -#define KS2_CLOCK_BASE KS2_PLL_CNTRL_BASE -#define KS2_RSTCTRL_RSTYPE (KS2_PLL_CNTRL_BASE + 0xe4) -#define KS2_RSTCTRL (KS2_PLL_CNTRL_BASE + 0xe8) -#define KS2_RSTCTRL_RSCFG (KS2_PLL_CNTRL_BASE + 0xec) -#define KS2_RSTCTRL_KEY 0x5a69 -#define KS2_RSTCTRL_MASK 0xffff0000 -#define KS2_RSTCTRL_SWRST 0xfffe0000 -#define KS2_RSTYPE_PLL_SOFT BIT(13) - -/* SPI */ -#define KS2_SPI0_BASE 0x21000400 -#define KS2_SPI1_BASE 0x21000600 -#define KS2_SPI2_BASE 0x21000800 -#define KS2_SPI_BASE KS2_SPI0_BASE - -/* AEMIF */ -#define KS2_AEMIF_CNTRL_BASE 0x21000a00 -#define DAVINCI_ASYNC_EMIF_CNTRL_BASE KS2_AEMIF_CNTRL_BASE - -/* Flag from ks2_debug options to check if DSPs need to stay ON */ -#define DBG_LEAVE_DSPS_ON 0x1 - -/* MSMC control */ -#define KS2_MSMC_CTRL_BASE 0x0bc00000 -#define KS2_MSMC_DATA_BASE 0x0c000000 -#define KS2_MSMC_SEGMENT_TETRIS 8 -#define KS2_MSMC_SEGMENT_NETCP 9 -#define KS2_MSMC_SEGMENT_QM_PDSP 10 -#define KS2_MSMC_SEGMENT_PCIE0 11 - -/* MSMC segment size shift bits */ -#define KS2_MSMC_SEG_SIZE_SHIFT 12 -#define KS2_MSMC_MAP_SEG_NUM (2 << (30 - KS2_MSMC_SEG_SIZE_SHIFT)) -#define KS2_MSMC_DST_SEG_BASE (CONFIG_SYS_LPAE_SDRAM_BASE >> \ - KS2_MSMC_SEG_SIZE_SHIFT) - -/* Device speed */ -#define KS2_REV1_DEVSPEED (KS2_DEVICE_STATE_CTRL_BASE + 0xc98) -#define KS2_EFUSE_BOOTROM (KS2_DEVICE_STATE_CTRL_BASE + 0xc90) -#define KS2_MISC_CTRL (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c) - -/* Queue manager */ -#define KS2_QM_BASE_ADDRESS 0x23a80000 -#define KS2_QM_CONF_BASE 0x02a02000 -#define KS2_QM_DESC_SETUP_BASE 0x02a03000 -#define KS2_QM_STATUS_RAM_BASE 0x02a06000 -#define KS2_QM_INTD_CONF_BASE 0x02a0c000 -#define KS2_QM_PDSP1_CMD_BASE 0x02a20000 -#define KS2_QM_PDSP1_CTRL_BASE 0x02a0f000 -#define KS2_QM_PDSP1_IRAM_BASE 0x02a10000 -#define KS2_QM_MANAGER_QUEUES_BASE 0x02a80000 -#define KS2_QM_MANAGER_Q_PROXY_BASE 0x02ac0000 -#define KS2_QM_QUEUE_STATUS_BASE 0x02a40000 -#define KS2_QM_LINK_RAM_BASE 0x00100000 -#define KS2_QM_REGION_NUM 64 -#define KS2_QM_QPOOL_NUM 4000 - -/* USB */ -#define KS2_USB_SS_BASE 0x02680000 -#define KS2_USB_HOST_XHCI_BASE (KS2_USB_SS_BASE + 0x10000) -#define KS2_DEV_USB_PHY_BASE 0x02620738 -#define KS2_USB_PHY_CFG_BASE 0x02630000 - -#define KS2_MAC_ID_BASE_ADDR (KS2_DEVICE_STATE_CTRL_BASE + 0x110) - -/* SGMII SerDes */ -#define KS2_SGMII_SERDES_BASE 0x0232a000 - -#ifdef CONFIG_SOC_K2HK -#include -#endif - -#ifdef CONFIG_SOC_K2E -#include -#endif - -#ifdef CONFIG_SOC_K2L -#include -#endif - -#ifndef __ASSEMBLY__ -static inline int cpu_is_k2hk(void) -{ - unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); - unsigned int part_no = (jtag_id >> 12) & 0xffff; - - return (part_no == 0xb981) ? 1 : 0; -} - -static inline int cpu_is_k2e(void) -{ - unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); - unsigned int part_no = (jtag_id >> 12) & 0xffff; - - return (part_no == 0xb9a6) ? 1 : 0; -} - -static inline int cpu_is_k2l(void) -{ - unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); - unsigned int part_no = (jtag_id >> 12) & 0xffff; - - return (part_no == 0xb9a7) ? 1 : 0; -} - -static inline int cpu_revision(void) -{ - unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); - unsigned int rev = (jtag_id >> 28) & 0xf; - - return rev; -} - -int cpu_to_bus(u32 *ptr, u32 length); -void sdelay(unsigned long); - -#endif - -#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-keystone/i2c_defs.h b/arch/arm/include/asm/arch-keystone/i2c_defs.h deleted file mode 100644 index d4256526cc..0000000000 --- a/arch/arm/include/asm/arch-keystone/i2c_defs.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * keystone: i2c driver definitions - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _I2C_DEFS_H_ -#define _I2C_DEFS_H_ - -#define I2C0_BASE 0x02530000 -#define I2C1_BASE 0x02530400 -#define I2C2_BASE 0x02530800 -#define I2C_BASE I2C0_BASE - -#endif diff --git a/arch/arm/include/asm/arch-keystone/mon.h b/arch/arm/include/asm/arch-keystone/mon.h deleted file mode 100644 index 33a28764bc..0000000000 --- a/arch/arm/include/asm/arch-keystone/mon.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * K2HK: secure kernel command header file - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MON_H_ -#define _MON_H_ - -int mon_power_off(int core_id); - -#endif diff --git a/arch/arm/include/asm/arch-keystone/msmc.h b/arch/arm/include/asm/arch-keystone/msmc.h deleted file mode 100644 index 083f5ba052..0000000000 --- a/arch/arm/include/asm/arch-keystone/msmc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * MSMC controller - * - * (C) Copyright 2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MSMC_H_ -#define _MSMC_H_ - -#include - -enum mpax_seg_size { - MPAX_SEG_4K = 0x0b, - MPAX_SEG_8K, - MPAX_SEG_16K, - MPAX_SEG_32K, - MPAX_SEG_64K, - MPAX_SEG_128K, - MPAX_SEG_256K, - MPAX_SEG_512K, - MPAX_SEG_1M, - MPAX_SEG_2M, - MPAX_SEG_4M, - MPAX_SEG_8M, - MPAX_SEG_16M, - MPAX_SEG_32M, - MPAX_SEG_64M, - MPAX_SEG_128M, - MPAX_SEG_256M, - MPAX_SEG_512M, - MPAX_SEG_1G, - MPAX_SEG_2G, - MPAX_SEG_4G -}; - -void msmc_share_all_segments(int priv_id); -void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax); -void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax); -void msmc_map_ses_segment(int priv_id, int ses_pair, - u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size); - -#endif diff --git a/arch/arm/include/asm/arch-keystone/psc_defs.h b/arch/arm/include/asm/arch-keystone/psc_defs.h deleted file mode 100644 index 70d22cf217..0000000000 --- a/arch/arm/include/asm/arch-keystone/psc_defs.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef _PSC_DEFS_H_ -#define _PSC_DEFS_H_ - -#include - -/* - * FILE PURPOSE: Local Power Sleep Controller definitions - * - * FILE NAME: psc_defs.h - * - * DESCRIPTION: Provides local definitions for the power saver controller - * - */ - -/* Register offsets */ -#define PSC_REG_PTCMD 0x120 -#define PSC_REG_PSTAT 0x128 -#define PSC_REG_PDSTAT(x) (0x200 + (4 * (x))) -#define PSC_REG_PDCTL(x) (0x300 + (4 * (x))) -#define PSC_REG_MDCFG(x) (0x600 + (4 * (x))) -#define PSC_REG_MDSTAT(x) (0x800 + (4 * (x))) -#define PSC_REG_MDCTL(x) (0xa00 + (4 * (x))) - -#define BOOTBITMASK(x, y) ((((((u32)1 << (((u32)x) - ((u32)y) + (u32)1)) - \ - (u32)1)) << ((u32)y))) - -#define BOOT_READ_BITFIELD(z, x, y) (((u32)z) & BOOTBITMASK(x, y)) >> (y) -#define BOOT_SET_BITFIELD(z, f, x, y) (((u32)z) & ~BOOTBITMASK(x, y)) | \ - ((((u32)f) << (y)) & BOOTBITMASK(x, y)) - -/* PDCTL */ -#define PSC_REG_PDCTL_SET_NEXT(x, y) BOOT_SET_BITFIELD((x), (y), 0, 0) -#define PSC_REG_PDCTL_SET_PDMODE(x, y) BOOT_SET_BITFIELD((x), (y), 15, 12) - -/* PDSTAT */ -#define PSC_REG_PDSTAT_GET_STATE(x) BOOT_READ_BITFIELD((x), 4, 0) - -/* MDCFG */ -#define PSC_REG_MDCFG_GET_PD(x) BOOT_READ_BITFIELD((x), 20, 16) -#define PSC_REG_MDCFG_GET_RESET_ISO(x) BOOT_READ_BITFIELD((x), 14, 14) - -/* MDCTL */ -#define PSC_REG_MDCTL_SET_NEXT(x, y) BOOT_SET_BITFIELD((x), (y), 4, 0) -#define PSC_REG_MDCTL_SET_LRSTZ(x, y) BOOT_SET_BITFIELD((x), (y), 8, 8) -#define PSC_REG_MDCTL_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) -#define PSC_REG_MDCTL_SET_RESET_ISO(x, y) BOOT_SET_BITFIELD((x), (y), \ - 12, 12) - -/* MDSTAT */ -#define PSC_REG_MDSTAT_GET_STATUS(x) BOOT_READ_BITFIELD((x), 5, 0) -#define PSC_REG_MDSTAT_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) -#define PSC_REG_MDSTAT_GET_LRSTDONE(x) BOOT_READ_BITFIELD((x), 9, 9) - -/* PDCTL states */ -#define PSC_REG_VAL_PDCTL_NEXT_ON 1 -#define PSC_REG_VAL_PDCTL_NEXT_OFF 0 - -#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP 0 - -/* MDCTL states */ -#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE 0 -#define PSC_REG_VAL_MDCTL_NEXT_OFF 2 -#define PSC_REG_VAL_MDCTL_NEXT_ON 3 - -/* MDSTAT states */ -#define PSC_REG_VAL_MDSTAT_STATE_ON 3 -#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG 0x24 -#define PSC_REG_VAL_MDSTAT_STATE_OFF 2 -#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1 0x20 -#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2 0x21 -#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3 0x22 - -/* - * Timeout limit on checking PTSTAT. This is the number of times the - * wait function will be called before giving up. - */ -#define PSC_PTSTAT_TIMEOUT_LIMIT 100 - -u32 psc_get_domain_num(u32 mod_num); -int psc_enable_module(u32 mod_num); -int psc_disable_module(u32 mod_num); -int psc_disable_domain(u32 domain_num); - -#endif /* _PSC_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-keystone/xhci-keystone.h b/arch/arm/include/asm/arch-keystone/xhci-keystone.h deleted file mode 100644 index 3aab4e045f..0000000000 --- a/arch/arm/include/asm/arch-keystone/xhci-keystone.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * USB 3.0 DRD Controller - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#define USB3_PHY_REF_SSP_EN BIT(29) -#define USB3_PHY_OTG_VBUSVLDECTSEL BIT(16) - -/* KEYSTONE2 XHCI PHY register structure */ -struct keystone_xhci_phy { - unsigned int phy_utmi; /* ctl0 */ - unsigned int phy_pipe; /* ctl1 */ - unsigned int phy_param_ctrl_1; /* ctl2 */ - unsigned int phy_param_ctrl_2; /* ctl3 */ - unsigned int phy_clock; /* ctl4 */ - unsigned int phy_pll; /* ctl5 */ -}; diff --git a/arch/arm/mach-keystone/include/mach/clock-k2e.h b/arch/arm/mach-keystone/include/mach/clock-k2e.h new file mode 100644 index 0000000000..d013b830ed --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/clock-k2e.h @@ -0,0 +1,85 @@ +/* + * K2E: Clock management APIs + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_K2E_H +#define __ASM_ARCH_CLOCK_K2E_H + +enum ext_clk_e { + sys_clk, + alt_core_clk, + pa_clk, + ddr3_clk, + mcm_clk, + pcie_clk, + sgmii_clk, + xgmii_clk, + usb_clk, + ext_clk_count /* number of external clocks */ +}; + +extern unsigned int external_clk[ext_clk_count]; + +#define CLK_LIST(CLK)\ + CLK(0, core_pll_clk)\ + CLK(1, pass_pll_clk)\ + CLK(2, ddr3_pll_clk)\ + CLK(3, sys_clk0_clk)\ + CLK(4, sys_clk0_1_clk)\ + CLK(5, sys_clk0_2_clk)\ + CLK(6, sys_clk0_3_clk)\ + CLK(7, sys_clk0_4_clk)\ + CLK(8, sys_clk0_6_clk)\ + CLK(9, sys_clk0_8_clk)\ + CLK(10, sys_clk0_12_clk)\ + CLK(11, sys_clk0_24_clk)\ + CLK(12, sys_clk1_clk)\ + CLK(13, sys_clk1_3_clk)\ + CLK(14, sys_clk1_4_clk)\ + CLK(15, sys_clk1_6_clk)\ + CLK(16, sys_clk1_12_clk)\ + CLK(17, sys_clk2_clk)\ + CLK(18, sys_clk3_clk) + +#define PLLSET_CMD_LIST "" + +#define KS2_CLK1_6 sys_clk0_6_clk + +/* PLL identifiers */ +enum pll_type_e { + CORE_PLL, + PASS_PLL, + DDR3_PLL, +}; + +enum { + SPD800, + SPD850, + SPD1000, + SPD1250, + SPD1350, + SPD1400, + SPD1500, + SPD_RSV +}; + +#define CORE_PLL_800 {CORE_PLL, 16, 1, 2} +#define CORE_PLL_850 {CORE_PLL, 17, 1, 2} +#define CORE_PLL_1000 {CORE_PLL, 20, 1, 2} +#define CORE_PLL_1200 {CORE_PLL, 24, 1, 2} +#define PASS_PLL_1000 {PASS_PLL, 20, 1, 2} +#define CORE_PLL_1250 {CORE_PLL, 25, 1, 2} +#define CORE_PLL_1350 {CORE_PLL, 27, 1, 2} +#define CORE_PLL_1400 {CORE_PLL, 28, 1, 2} +#define CORE_PLL_1500 {CORE_PLL, 30, 1, 2} +#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2} +#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4} +#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2} +#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6} + +#endif diff --git a/arch/arm/mach-keystone/include/mach/clock-k2hk.h b/arch/arm/mach-keystone/include/mach/clock-k2hk.h new file mode 100644 index 0000000000..f28d5f0c4e --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/clock-k2hk.h @@ -0,0 +1,103 @@ +/* + * K2HK: Clock management APIs + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_K2HK_H +#define __ASM_ARCH_CLOCK_K2HK_H + +enum ext_clk_e { + sys_clk, + alt_core_clk, + pa_clk, + tetris_clk, + ddr3a_clk, + ddr3b_clk, + mcm_clk, + pcie_clk, + sgmii_srio_clk, + xgmii_clk, + usb_clk, + rp1_clk, + ext_clk_count /* number of external clocks */ +}; + +extern unsigned int external_clk[ext_clk_count]; + +#define CLK_LIST(CLK)\ + CLK(0, core_pll_clk)\ + CLK(1, pass_pll_clk)\ + CLK(2, tetris_pll_clk)\ + CLK(3, ddr3a_pll_clk)\ + CLK(4, ddr3b_pll_clk)\ + CLK(5, sys_clk0_clk)\ + CLK(6, sys_clk0_1_clk)\ + CLK(7, sys_clk0_2_clk)\ + CLK(8, sys_clk0_3_clk)\ + CLK(9, sys_clk0_4_clk)\ + CLK(10, sys_clk0_6_clk)\ + CLK(11, sys_clk0_8_clk)\ + CLK(12, sys_clk0_12_clk)\ + CLK(13, sys_clk0_24_clk)\ + CLK(14, sys_clk1_clk)\ + CLK(15, sys_clk1_3_clk)\ + CLK(16, sys_clk1_4_clk)\ + CLK(17, sys_clk1_6_clk)\ + CLK(18, sys_clk1_12_clk)\ + CLK(19, sys_clk2_clk)\ + CLK(20, sys_clk3_clk) + +#define PLLSET_CMD_LIST "" + +#define KS2_CLK1_6 sys_clk0_6_clk + +/* PLL identifiers */ +enum pll_type_e { + CORE_PLL, + PASS_PLL, + TETRIS_PLL, + DDR3A_PLL, + DDR3B_PLL, +}; + +enum { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD_RSV +}; + +#define CORE_PLL_799 {CORE_PLL, 13, 1, 2} +#define CORE_PLL_983 {CORE_PLL, 16, 1, 2} +#define CORE_PLL_999 {CORE_PLL, 122, 15, 1} +#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2} +#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2} +#define CORE_PLL_1200 {CORE_PLL, 625, 32, 2} +#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2} +#define PASS_PLL_983 {PASS_PLL, 16, 1, 2} +#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2} +#define TETRIS_PLL_500 {TETRIS_PLL, 8, 1, 2} +#define TETRIS_PLL_750 {TETRIS_PLL, 12, 1, 2} +#define TETRIS_PLL_800 {TETRIS_PLL, 32, 5, 1} +#define TETRIS_PLL_687 {TETRIS_PLL, 11, 1, 2} +#define TETRIS_PLL_625 {TETRIS_PLL, 10, 1, 2} +#define TETRIS_PLL_812 {TETRIS_PLL, 13, 1, 2} +#define TETRIS_PLL_875 {TETRIS_PLL, 14, 1, 2} +#define TETRIS_PLL_1000 {TETRIS_PLL, 40, 5, 1} +#define TETRIS_PLL_1188 {TETRIS_PLL, 19, 2, 1} +#define TETRIS_PLL_1200 {TETRIS_PLL, 48, 5, 1} +#define TETRIS_PLL_1350 {TETRIS_PLL, 54, 5, 1} +#define TETRIS_PLL_1375 {TETRIS_PLL, 22, 2, 1} +#define TETRIS_PLL_1400 {TETRIS_PLL, 56, 5, 1} +#define DDR3_PLL_200(x) {DDR3##x##_PLL, 4, 1, 2} +#define DDR3_PLL_400(x) {DDR3##x##_PLL, 16, 1, 4} +#define DDR3_PLL_800(x) {DDR3##x##_PLL, 16, 1, 2} +#define DDR3_PLL_333(x) {DDR3##x##_PLL, 20, 1, 6} + +#endif diff --git a/arch/arm/mach-keystone/include/mach/clock-k2l.h b/arch/arm/mach-keystone/include/mach/clock-k2l.h new file mode 100644 index 0000000000..bb9a5c4dcf --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/clock-k2l.h @@ -0,0 +1,95 @@ +/* + * K2L: Clock management APIs + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_K2L_H +#define __ASM_ARCH_CLOCK_K2L_H + +enum ext_clk_e { + sys_clk, + alt_core_clk, + pa_clk, + tetris_clk, + ddr3_clk, + pcie_clk, + sgmii_clk, + usb_clk, + rp1_clk, + ext_clk_count /* number of external clocks */ +}; + +extern unsigned int external_clk[ext_clk_count]; + +#define CLK_LIST(CLK)\ + CLK(0, core_pll_clk)\ + CLK(1, pass_pll_clk)\ + CLK(2, tetris_pll_clk)\ + CLK(3, ddr3_pll_clk)\ + CLK(4, sys_clk0_clk)\ + CLK(5, sys_clk0_1_clk)\ + CLK(6, sys_clk0_2_clk)\ + CLK(7, sys_clk0_3_clk)\ + CLK(8, sys_clk0_4_clk)\ + CLK(9, sys_clk0_6_clk)\ + CLK(10, sys_clk0_8_clk)\ + CLK(11, sys_clk0_12_clk)\ + CLK(12, sys_clk0_24_clk)\ + CLK(13, sys_clk1_clk)\ + CLK(14, sys_clk1_3_clk)\ + CLK(15, sys_clk1_4_clk)\ + CLK(16, sys_clk1_6_clk)\ + CLK(17, sys_clk1_12_clk)\ + CLK(18, sys_clk2_clk)\ + CLK(19, sys_clk3_clk)\ + +#define PLLSET_CMD_LIST "" + +#define KS2_CLK1_6 sys_clk0_6_clk + +/* PLL identifiers */ +enum pll_type_e { + CORE_PLL, + PASS_PLL, + TETRIS_PLL, + DDR3_PLL, +}; + +enum { + SPD800, + SPD1000, + SPD1200, + SPD1350, + SPD1400, + SPD_RSV +}; + +#define CORE_PLL_799 {CORE_PLL, 13, 1, 2} +#define CORE_PLL_983 {CORE_PLL, 16, 1, 2} +#define CORE_PLL_1000 {CORE_PLL, 114, 7, 2} +#define CORE_PLL_1167 {CORE_PLL, 19, 1, 2} +#define CORE_PLL_1198 {CORE_PLL, 39, 2, 2} +#define CORE_PLL_1228 {CORE_PLL, 20, 1, 2} +#define PASS_PLL_1228 {PASS_PLL, 20, 1, 2} +#define PASS_PLL_983 {PASS_PLL, 16, 1, 2} +#define PASS_PLL_1050 {PASS_PLL, 205, 12, 2} +#define TETRIS_PLL_491 {TETRIS_PLL, 8, 1, 2} +#define TETRIS_PLL_737 {TETRIS_PLL, 12, 1, 2} +#define TETRIS_PLL_799 {TETRIS_PLL, 13, 1, 2} +#define TETRIS_PLL_983 {TETRIS_PLL, 16, 1, 2} +#define TETRIS_PLL_1000 {TETRIS_PLL, 114, 7, 2} +#define TETRIS_PLL_1167 {TETRIS_PLL, 19, 1, 2} +#define TETRIS_PLL_1198 {TETRIS_PLL, 39, 2, 2} +#define TETRIS_PLL_1228 {TETRIS_PLL, 20, 1, 2} +#define TETRIS_PLL_1352 {TETRIS_PLL, 22, 1, 2} +#define TETRIS_PLL_1401 {TETRIS_PLL, 114, 5, 2} +#define DDR3_PLL_200 {DDR3_PLL, 4, 1, 2} +#define DDR3_PLL_400 {DDR3_PLL, 16, 1, 4} +#define DDR3_PLL_800 {DDR3_PLL, 16, 1, 2} +#define DDR3_PLL_333 {DDR3_PLL, 20, 1, 6} + +#endif diff --git a/arch/arm/mach-keystone/include/mach/clock.h b/arch/arm/mach-keystone/include/mach/clock.h new file mode 100644 index 0000000000..9f6cfb265f --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/clock.h @@ -0,0 +1,66 @@ +/* + * keystone2: common clock header file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_SOC_K2HK +#include +#endif + +#ifdef CONFIG_SOC_K2E +#include +#endif + +#ifdef CONFIG_SOC_K2L +#include +#endif + +#define MAIN_PLL CORE_PLL + +#include + +#define GENERATE_ENUM(NUM, ENUM) ENUM = NUM, +#define GENERATE_INDX_STR(NUM, STRING) #NUM"\t- "#STRING"\n" +#define CLOCK_INDEXES_LIST CLK_LIST(GENERATE_INDX_STR) + +enum clk_e { + CLK_LIST(GENERATE_ENUM) +}; + +struct keystone_pll_regs { + u32 reg0; + u32 reg1; +}; + +/* PLL configuration data */ +struct pll_init_data { + int pll; + int pll_m; /* PLL Multiplier */ + int pll_d; /* PLL divider */ + int pll_od; /* PLL output divider */ +}; + +extern const struct keystone_pll_regs keystone_pll_regs[]; +extern int dev_speeds[]; +extern int arm_speeds[]; + +void init_plls(int num_pll, struct pll_init_data *config); +void init_pll(const struct pll_init_data *data); +unsigned long clk_get_rate(unsigned int clk); +unsigned long clk_round_rate(unsigned int clk, unsigned long hz); +int clk_set_rate(unsigned int clk, unsigned long hz); +void pass_pll_pa_clk_enable(void); +int get_max_dev_speed(void); +int get_max_arm_speed(void); + +#endif +#endif diff --git a/arch/arm/mach-keystone/include/mach/clock_defs.h b/arch/arm/mach-keystone/include/mach/clock_defs.h new file mode 100644 index 0000000000..85a046b89a --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/clock_defs.h @@ -0,0 +1,111 @@ +/* + * keystone2: common pll clock definitions + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CLOCK_DEFS_H_ +#define _CLOCK_DEFS_H_ + +#include + +#define BIT(x) (1 << (x)) + +/* PLL Control Registers */ +struct pllctl_regs { + u32 ctl; /* 00 */ + u32 ocsel; /* 04 */ + u32 secctl; /* 08 */ + u32 resv0; + u32 mult; /* 10 */ + u32 prediv; /* 14 */ + u32 div1; /* 18 */ + u32 div2; /* 1c */ + u32 div3; /* 20 */ + u32 oscdiv1; /* 24 */ + u32 resv1; /* 28 */ + u32 bpdiv; /* 2c */ + u32 wakeup; /* 30 */ + u32 resv2; + u32 cmd; /* 38 */ + u32 stat; /* 3c */ + u32 alnctl; /* 40 */ + u32 dchange; /* 44 */ + u32 cken; /* 48 */ + u32 ckstat; /* 4c */ + u32 systat; /* 50 */ + u32 ckctl; /* 54 */ + u32 resv3[2]; + u32 div4; /* 60 */ + u32 div5; /* 64 */ + u32 div6; /* 68 */ + u32 div7; /* 6c */ + u32 div8; /* 70 */ + u32 div9; /* 74 */ + u32 div10; /* 78 */ + u32 div11; /* 7c */ + u32 div12; /* 80 */ +}; + +static struct pllctl_regs *pllctl_regs[] = { + (struct pllctl_regs *)(KS2_CLOCK_BASE + 0x100) +}; + +#define pllctl_reg(pll, reg) (&(pllctl_regs[pll]->reg)) +#define pllctl_reg_read(pll, reg) __raw_readl(pllctl_reg(pll, reg)) +#define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg)) + +#define pllctl_reg_rmw(pll, reg, mask, val) \ + pllctl_reg_write(pll, reg, \ + (pllctl_reg_read(pll, reg) & ~(mask)) | val) + +#define pllctl_reg_setbits(pll, reg, mask) \ + pllctl_reg_rmw(pll, reg, 0, mask) + +#define pllctl_reg_clrbits(pll, reg, mask) \ + pllctl_reg_rmw(pll, reg, mask, 0) + +#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1) + +/* PLLCTL Bits */ +#define PLLCTL_BYPASS BIT(23) +#define PLL_PLLRST BIT(14) +#define PLLCTL_PAPLL BIT(13) +#define PLLCTL_CLKMODE BIT(8) +#define PLLCTL_PLLSELB BIT(7) +#define PLLCTL_ENSAT BIT(6) +#define PLLCTL_PLLENSRC BIT(5) +#define PLLCTL_PLLDIS BIT(4) +#define PLLCTL_PLLRST BIT(3) +#define PLLCTL_PLLPWRDN BIT(1) +#define PLLCTL_PLLEN BIT(0) +#define PLLSTAT_GO BIT(0) + +#define MAIN_ENSAT_OFFSET 6 + +#define PLLDIV_ENABLE BIT(15) + +#define PLL_DIV_MASK 0x3f +#define PLL_MULT_MASK 0x1fff +#define PLL_MULT_SHIFT 6 +#define PLLM_MULT_HI_MASK 0x7f +#define PLLM_MULT_HI_SHIFT 12 +#define PLLM_MULT_HI_SMASK (PLLM_MULT_HI_MASK << PLLM_MULT_HI_SHIFT) +#define PLLM_MULT_LO_MASK 0x3f +#define PLL_CLKOD_MASK 0xf +#define PLL_CLKOD_SHIFT 19 +#define PLL_CLKOD_SMASK (PLL_CLKOD_MASK << PLL_CLKOD_SHIFT) +#define PLL_BWADJ_LO_MASK 0xff +#define PLL_BWADJ_LO_SHIFT 24 +#define PLL_BWADJ_LO_SMASK (PLL_BWADJ_LO_MASK << PLL_BWADJ_LO_SHIFT) +#define PLL_BWADJ_HI_MASK 0xf + +#define PLLM_RATIO_DIV1 (PLLDIV_ENABLE | 0x0) +#define PLLM_RATIO_DIV2 (PLLDIV_ENABLE | 0x0) +#define PLLM_RATIO_DIV3 (PLLDIV_ENABLE | 0x1) +#define PLLM_RATIO_DIV4 (PLLDIV_ENABLE | 0x4) +#define PLLM_RATIO_DIV5 (PLLDIV_ENABLE | 0x17) + +#endif /* _CLOCK_DEFS_H_ */ diff --git a/arch/arm/mach-keystone/include/mach/ddr3.h b/arch/arm/mach-keystone/include/mach/ddr3.h new file mode 100644 index 0000000000..a22c237c80 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/ddr3.h @@ -0,0 +1,62 @@ +/* + * DDR3 + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _DDR3_H_ +#define _DDR3_H_ + +#include + +struct ddr3_phy_config { + unsigned int pllcr; + unsigned int pgcr1_mask; + unsigned int pgcr1_val; + unsigned int ptr0; + unsigned int ptr1; + unsigned int ptr2; + unsigned int ptr3; + unsigned int ptr4; + unsigned int dcr_mask; + unsigned int dcr_val; + unsigned int dtpr0; + unsigned int dtpr1; + unsigned int dtpr2; + unsigned int mr0; + unsigned int mr1; + unsigned int mr2; + unsigned int dtcr; + unsigned int pgcr2; + unsigned int zq0cr1; + unsigned int zq1cr1; + unsigned int zq2cr1; + unsigned int pir_v1; + unsigned int pir_v2; +}; + +struct ddr3_emif_config { + unsigned int sdcfg; + unsigned int sdtim1; + unsigned int sdtim2; + unsigned int sdtim3; + unsigned int sdtim4; + unsigned int zqcfg; + unsigned int sdrfc; +}; + +u32 ddr3_init(void); +void ddr3_reset_ddrphy(void); +void ddr3_init_ecc(u32 base, u32 ddr3_size); +void ddr3_disable_ecc(u32 base); +void ddr3_check_ecc_int(u32 base); +int ddr3_ecc_support_rmw(u32 base); +void ddr3_err_reset_workaround(void); +void ddr3_enable_ecc(u32 base, int test); +void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg); +void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg); + +#endif diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2e.h b/arch/arm/mach-keystone/include/mach/hardware-k2e.h new file mode 100644 index 0000000000..df499957e5 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/hardware-k2e.h @@ -0,0 +1,65 @@ +/* + * K2E: SoC definitions + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_HARDWARE_K2E_H +#define __ASM_ARCH_HARDWARE_K2E_H + +/* PA SS Registers */ +#define KS2_PASS_BASE 0x24000000 + +/* Power and Sleep Controller (PSC) Domains */ +#define KS2_LPSC_MOD_RST 0 +#define KS2_LPSC_USB_1 1 +#define KS2_LPSC_USB 2 +#define KS2_LPSC_EMIF25_SPI 3 +#define KS2_LPSC_TSIP 4 +#define KS2_LPSC_DEBUGSS_TRC 5 +#define KS2_LPSC_TETB_TRC 6 +#define KS2_LPSC_PKTPROC 7 +#define KS2_LPSC_PA KS2_LPSC_PKTPROC +#define KS2_LPSC_SGMII 8 +#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII +#define KS2_LPSC_CRYPTO 9 +#define KS2_LPSC_PCIE 10 +#define KS2_LPSC_VUSR0 12 +#define KS2_LPSC_CHIP_SRSS 13 +#define KS2_LPSC_MSMC 14 +#define KS2_LPSC_EMIF4F_DDR3 23 +#define KS2_LPSC_PCIE_1 27 +#define KS2_LPSC_XGE 50 + +/* MSMC */ +#define KS2_MSMC_SEGMENT_PCIE1 13 + +/* Chip Interrupt Controller */ +#define KS2_CIC2_DDR3_ECC_IRQ_NUM -1 /* not defined in K2E */ +#define KS2_CIC2_DDR3_ECC_CHAN_NUM -1 /* not defined in K2E */ + +/* SGMII SerDes */ +#define KS2_SGMII_SERDES2_BASE 0x02324000 +#define KS2_LANES_PER_SGMII_SERDES 4 + +/* Number of DSP cores */ +#define KS2_NUM_DSPS 1 + +/* NETCP pktdma */ +#define KS2_NETCP_PDMA_CTRL_BASE 0x24186000 +#define KS2_NETCP_PDMA_TX_BASE 0x24187000 +#define KS2_NETCP_PDMA_TX_CH_NUM 21 +#define KS2_NETCP_PDMA_RX_BASE 0x24188000 +#define KS2_NETCP_PDMA_RX_CH_NUM 91 +#define KS2_NETCP_PDMA_SCHED_BASE 0x24186100 +#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x24189000 +#define KS2_NETCP_PDMA_RX_FLOW_NUM 96 +#define KS2_NETCP_PDMA_TX_SND_QUEUE 896 + +/* NETCP */ +#define KS2_NETCP_BASE 0x24000000 + +#endif diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2hk.h b/arch/arm/mach-keystone/include/mach/hardware-k2hk.h new file mode 100644 index 0000000000..195c0d3003 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/hardware-k2hk.h @@ -0,0 +1,106 @@ +/* + * K2HK: SoC definitions + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_HARDWARE_K2HK_H +#define __ASM_ARCH_HARDWARE_K2HK_H + +#define KS2_ARM_PLL_EN BIT(13) + +/* PA SS Registers */ +#define KS2_PASS_BASE 0x02000000 + +/* PLL control registers */ +#define KS2_DDR3BPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x368) +#define KS2_DDR3BPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x36C) + +/* Power and Sleep Controller (PSC) Domains */ +#define KS2_LPSC_MOD 0 +#define KS2_LPSC_DUMMY1 1 +#define KS2_LPSC_USB 2 +#define KS2_LPSC_EMIF25_SPI 3 +#define KS2_LPSC_TSIP 4 +#define KS2_LPSC_DEBUGSS_TRC 5 +#define KS2_LPSC_TETB_TRC 6 +#define KS2_LPSC_PKTPROC 7 +#define KS2_LPSC_PA KS2_LPSC_PKTPROC +#define KS2_LPSC_SGMII 8 +#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII +#define KS2_LPSC_CRYPTO 9 +#define KS2_LPSC_PCIE 10 +#define KS2_LPSC_SRIO 11 +#define KS2_LPSC_VUSR0 12 +#define KS2_LPSC_CHIP_SRSS 13 +#define KS2_LPSC_MSMC 14 +#define KS2_LPSC_GEM_1 16 +#define KS2_LPSC_GEM_2 17 +#define KS2_LPSC_GEM_3 18 +#define KS2_LPSC_GEM_4 19 +#define KS2_LPSC_GEM_5 20 +#define KS2_LPSC_GEM_6 21 +#define KS2_LPSC_GEM_7 22 +#define KS2_LPSC_EMIF4F_DDR3A 23 +#define KS2_LPSC_EMIF4F_DDR3B 24 +#define KS2_LPSC_TAC 25 +#define KS2_LPSC_RAC 26 +#define KS2_LPSC_RAC_1 27 +#define KS2_LPSC_FFTC_A 28 +#define KS2_LPSC_FFTC_B 29 +#define KS2_LPSC_FFTC_C 30 +#define KS2_LPSC_FFTC_D 31 +#define KS2_LPSC_FFTC_E 32 +#define KS2_LPSC_FFTC_F 33 +#define KS2_LPSC_AI2 34 +#define KS2_LPSC_TCP3D_0 35 +#define KS2_LPSC_TCP3D_1 36 +#define KS2_LPSC_TCP3D_2 37 +#define KS2_LPSC_TCP3D_3 38 +#define KS2_LPSC_VCP2X4_A 39 +#define KS2_LPSC_CP2X4_B 40 +#define KS2_LPSC_VCP2X4_C 41 +#define KS2_LPSC_VCP2X4_D 42 +#define KS2_LPSC_VCP2X4_E 43 +#define KS2_LPSC_VCP2X4_F 44 +#define KS2_LPSC_VCP2X4_G 45 +#define KS2_LPSC_VCP2X4_H 46 +#define KS2_LPSC_BCP 47 +#define KS2_LPSC_DXB 48 +#define KS2_LPSC_VUSR1 49 +#define KS2_LPSC_XGE 50 +#define KS2_LPSC_ARM_SREFLEX 51 + +/* DDR3B definitions */ +#define KS2_DDR3B_EMIF_CTRL_BASE 0x21020000 +#define KS2_DDR3B_EMIF_DATA_BASE 0x60000000 +#define KS2_DDR3B_DDRPHYC 0x02328000 + +#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3 /* DDR3 ECC system irq number */ +#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D /* DDR3 ECC int mapped to CIC2 + channel 29 */ + +/* SGMII SerDes */ +#define KS2_LANES_PER_SGMII_SERDES 4 + +/* Number of DSP cores */ +#define KS2_NUM_DSPS 8 + +/* NETCP pktdma */ +#define KS2_NETCP_PDMA_CTRL_BASE 0x02004000 +#define KS2_NETCP_PDMA_TX_BASE 0x02004400 +#define KS2_NETCP_PDMA_TX_CH_NUM 9 +#define KS2_NETCP_PDMA_RX_BASE 0x02004800 +#define KS2_NETCP_PDMA_RX_CH_NUM 26 +#define KS2_NETCP_PDMA_SCHED_BASE 0x02004c00 +#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x02005000 +#define KS2_NETCP_PDMA_RX_FLOW_NUM 32 +#define KS2_NETCP_PDMA_TX_SND_QUEUE 648 + +/* NETCP */ +#define KS2_NETCP_BASE 0x02000000 + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2l.h b/arch/arm/mach-keystone/include/mach/hardware-k2l.h new file mode 100644 index 0000000000..4f1197ea92 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/hardware-k2l.h @@ -0,0 +1,108 @@ +/* + * K2L: SoC definitions + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_HARDWARE_K2L_H +#define __ASM_ARCH_HARDWARE_K2L_H + +#define KS2_ARM_PLL_EN BIT(13) + +/* PA SS Registers */ +#define KS2_PASS_BASE 0x26000000 + +/* Power and Sleep Controller (PSC) Domains */ +#define KS2_LPSC_MOD 0 +#define KS2_LPSC_DFE_IQN_SYS 1 +#define KS2_LPSC_USB 2 +#define KS2_LPSC_EMIF25_SPI 3 +#define KS2_LPSC_TSIP 4 +#define KS2_LPSC_DEBUGSS_TRC 5 +#define KS2_LPSC_TETB_TRC 6 +#define KS2_LPSC_PKTPROC 7 +#define KS2_LPSC_PA KS2_LPSC_PKTPROC +#define KS2_LPSC_SGMII 8 +#define KS2_LPSC_CPGMAC KS2_LPSC_SGMII +#define KS2_LPSC_CRYPTO 9 +#define KS2_LPSC_PCIE0 10 +#define KS2_LPSC_PCIE1 11 +#define KS2_LPSC_JESD_MISC 12 +#define KS2_LPSC_CHIP_SRSS 13 +#define KS2_LPSC_MSMC 14 +#define KS2_LPSC_GEM_1 16 +#define KS2_LPSC_GEM_2 17 +#define KS2_LPSC_GEM_3 18 +#define KS2_LPSC_EMIF4F_DDR3 23 +#define KS2_LPSC_TAC 25 +#define KS2_LPSC_RAC 26 +#define KS2_LPSC_DDUC4X_CFR2X_BB 27 +#define KS2_LPSC_FFTC_A 28 +#define KS2_LPSC_OSR 34 +#define KS2_LPSC_TCP3D_0 35 +#define KS2_LPSC_TCP3D_1 37 +#define KS2_LPSC_VCP2X4_A 39 +#define KS2_LPSC_VCP2X4_B 40 +#define KS2_LPSC_VCP2X4_C 41 +#define KS2_LPSC_VCP2X4_D 42 +#define KS2_LPSC_BCP 47 +#define KS2_LPSC_DPD4X 48 +#define KS2_LPSC_FFTC_B 49 +#define KS2_LPSC_IQN_AIL 50 + +/* MSMC */ +#define KS2_MSMC_SEGMENT_PCIE1 14 + +/* Chip Interrupt Controller */ +#define KS2_CIC2_DDR3_ECC_IRQ_NUM 0x0D3 +#define KS2_CIC2_DDR3_ECC_CHAN_NUM 0x01D + +/* OSR */ +#define KS2_OSR_DATA_BASE 0x70000000 /* OSR data base */ +#define KS2_OSR_CFG_BASE 0x02348c00 /* OSR config base */ +#define KS2_OSR_ECC_VEC 0x08 /* ECC Vector reg */ +#define KS2_OSR_ECC_CTRL 0x14 /* ECC control reg */ + +/* OSR ECC Vector register */ +#define KS2_OSR_ECC_VEC_TRIG_RD BIT(15) /* trigger a read op */ +#define KS2_OSR_ECC_VEC_RD_DONE BIT(24) /* read complete */ + +#define KS2_OSR_ECC_VEC_RAM_ID_SH 0 /* RAM ID shift */ +#define KS2_OSR_ECC_VEC_RD_ADDR_SH 16 /* read address shift */ + +/* OSR ECC control register */ +#define KS2_OSR_ECC_CTRL_EN BIT(0) /* ECC enable bit */ +#define KS2_OSR_ECC_CTRL_CHK BIT(1) /* ECC check bit */ +#define KS2_OSR_ECC_CTRL_RMW BIT(2) /* ECC check bit */ + +/* Number of OSR RAM banks */ +#define KS2_OSR_NUM_RAM_BANKS 4 + +/* OSR memory size */ +#define KS2_OSR_SIZE 0x100000 + +/* SGMII SerDes */ +#define KS2_SGMII_SERDES2_BASE 0x02320000 +#define KS2_LANES_PER_SGMII_SERDES 2 + +/* Number of DSP cores */ +#define KS2_NUM_DSPS 4 + +/* NETCP pktdma */ +#define KS2_NETCP_PDMA_CTRL_BASE 0x26186000 +#define KS2_NETCP_PDMA_TX_BASE 0x26187000 +#define KS2_NETCP_PDMA_TX_CH_NUM 21 +#define KS2_NETCP_PDMA_RX_BASE 0x26188000 +#define KS2_NETCP_PDMA_RX_CH_NUM 91 +#define KS2_NETCP_PDMA_SCHED_BASE 0x26186100 +#define KS2_NETCP_PDMA_RX_FLOW_BASE 0x26189000 +#define KS2_NETCP_PDMA_RX_FLOW_NUM 96 +#define KS2_NETCP_PDMA_TX_SND_QUEUE 896 + +/* NETCP */ +#define KS2_NETCP_BASE 0x26000000 + +#endif /* __ASM_ARCH_HARDWARE_K2L_H */ diff --git a/arch/arm/mach-keystone/include/mach/hardware.h b/arch/arm/mach-keystone/include/mach/hardware.h new file mode 100644 index 0000000000..16cbcee12b --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/hardware.h @@ -0,0 +1,290 @@ +/* + * Keystone2: Common SoC definitions, structures etc. + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include + +#ifndef __ASSEMBLY__ + +#include +#include + +#define REG(addr) (*(volatile unsigned int *)(addr)) +#define REG_P(addr) ((volatile unsigned int *)(addr)) + +typedef volatile unsigned int dv_reg; +typedef volatile unsigned int *dv_reg_p; + +#endif + +#define BIT(x) (1 << (x)) + +#define KS2_DDRPHY_PIR_OFFSET 0x04 +#define KS2_DDRPHY_PGCR0_OFFSET 0x08 +#define KS2_DDRPHY_PGCR1_OFFSET 0x0C +#define KS2_DDRPHY_PGSR0_OFFSET 0x10 +#define KS2_DDRPHY_PGSR1_OFFSET 0x14 +#define KS2_DDRPHY_PLLCR_OFFSET 0x18 +#define KS2_DDRPHY_PTR0_OFFSET 0x1C +#define KS2_DDRPHY_PTR1_OFFSET 0x20 +#define KS2_DDRPHY_PTR2_OFFSET 0x24 +#define KS2_DDRPHY_PTR3_OFFSET 0x28 +#define KS2_DDRPHY_PTR4_OFFSET 0x2C +#define KS2_DDRPHY_DCR_OFFSET 0x44 + +#define KS2_DDRPHY_DTPR0_OFFSET 0x48 +#define KS2_DDRPHY_DTPR1_OFFSET 0x4C +#define KS2_DDRPHY_DTPR2_OFFSET 0x50 + +#define KS2_DDRPHY_MR0_OFFSET 0x54 +#define KS2_DDRPHY_MR1_OFFSET 0x58 +#define KS2_DDRPHY_MR2_OFFSET 0x5C +#define KS2_DDRPHY_DTCR_OFFSET 0x68 +#define KS2_DDRPHY_PGCR2_OFFSET 0x8C + +#define KS2_DDRPHY_ZQ0CR1_OFFSET 0x184 +#define KS2_DDRPHY_ZQ1CR1_OFFSET 0x194 +#define KS2_DDRPHY_ZQ2CR1_OFFSET 0x1A4 +#define KS2_DDRPHY_ZQ3CR1_OFFSET 0x1B4 + +#define KS2_DDRPHY_DATX8_8_OFFSET 0x3C0 + +#define IODDRM_MASK 0x00000180 +#define ZCKSEL_MASK 0x01800000 +#define CL_MASK 0x00000072 +#define WR_MASK 0x00000E00 +#define BL_MASK 0x00000003 +#define RRMODE_MASK 0x00040000 +#define UDIMM_MASK 0x20000000 +#define BYTEMASK_MASK 0x0003FC00 +#define MPRDQ_MASK 0x00000080 +#define PDQ_MASK 0x00000070 +#define NOSRA_MASK 0x08000000 +#define ECC_MASK 0x00000001 + +/* DDR3 definitions */ +#define KS2_DDR3A_EMIF_CTRL_BASE 0x21010000 +#define KS2_DDR3A_EMIF_DATA_BASE 0x80000000 +#define KS2_DDR3A_DDRPHYC 0x02329000 + +#define KS2_DDR3_MIDR_OFFSET 0x00 +#define KS2_DDR3_STATUS_OFFSET 0x04 +#define KS2_DDR3_SDCFG_OFFSET 0x08 +#define KS2_DDR3_SDRFC_OFFSET 0x10 +#define KS2_DDR3_SDTIM1_OFFSET 0x18 +#define KS2_DDR3_SDTIM2_OFFSET 0x1C +#define KS2_DDR3_SDTIM3_OFFSET 0x20 +#define KS2_DDR3_SDTIM4_OFFSET 0x28 +#define KS2_DDR3_PMCTL_OFFSET 0x38 +#define KS2_DDR3_ZQCFG_OFFSET 0xC8 + +#define KS2_DDR3_PLLCTRL_PHY_RESET 0x80000000 + +/* DDR3 ECC */ +#define KS2_DDR3_ECC_INT_STATUS_OFFSET 0x0AC +#define KS2_DDR3_ECC_INT_ENABLE_SET_SYS_OFFSET 0x0B4 +#define KS2_DDR3_ECC_CTRL_OFFSET 0x110 +#define KS2_DDR3_ECC_ADDR_RANGE1_OFFSET 0x114 +#define KS2_DDR3_ONE_BIT_ECC_ERR_CNT_OFFSET 0x130 +#define KS2_DDR3_ONE_BIT_ECC_ERR_ADDR_LOG_OFFSET 0x13C + +/* DDR3 ECC Interrupt Status register */ +#define KS2_DDR3_1B_ECC_ERR_SYS BIT(5) +#define KS2_DDR3_2B_ECC_ERR_SYS BIT(4) +#define KS2_DDR3_WR_ECC_ERR_SYS BIT(3) + +/* DDR3 ECC Control register */ +#define KS2_DDR3_ECC_EN BIT(31) +#define KS2_DDR3_ECC_ADDR_RNG_PROT BIT(30) +#define KS2_DDR3_ECC_VERIFY_EN BIT(29) +#define KS2_DDR3_ECC_RMW_EN BIT(28) +#define KS2_DDR3_ECC_ADDR_RNG_1_EN BIT(0) + +#define KS2_DDR3_ECC_ENABLE (KS2_DDR3_ECC_EN | \ + KS2_DDR3_ECC_ADDR_RNG_PROT | \ + KS2_DDR3_ECC_VERIFY_EN) + +/* EDMA */ +#define KS2_EDMA0_BASE 0x02700000 + +/* EDMA3 register offsets */ +#define KS2_EDMA_QCHMAP0 0x0200 +#define KS2_EDMA_IPR 0x1068 +#define KS2_EDMA_ICR 0x1070 +#define KS2_EDMA_QEECR 0x1088 +#define KS2_EDMA_QEESR 0x108c +#define KS2_EDMA_PARAM_1(x) (0x4020 + (4 * x)) + +/* NETCP pktdma */ +#define KS2_NETCP_PDMA_RX_FREE_QUEUE 4001 +#define KS2_NETCP_PDMA_RX_RCV_QUEUE 4002 + +/* Chip Interrupt Controller */ +#define KS2_CIC2_BASE 0x02608000 + +/* Chip Interrupt Controller register offsets */ +#define KS2_CIC_CTRL 0x04 +#define KS2_CIC_HOST_CTRL 0x0C +#define KS2_CIC_GLOBAL_ENABLE 0x10 +#define KS2_CIC_SYS_ENABLE_IDX_SET 0x28 +#define KS2_CIC_HOST_ENABLE_IDX_SET 0x34 +#define KS2_CIC_CHAN_MAP(n) (0x0400 + (n << 2)) + +#define KS2_UART0_BASE 0x02530c00 +#define KS2_UART1_BASE 0x02531000 + +/* Boot Config */ +#define KS2_DEVICE_STATE_CTRL_BASE 0x02620000 +#define KS2_JTAG_ID_REG (KS2_DEVICE_STATE_CTRL_BASE + 0x18) +#define KS2_DEVSTAT (KS2_DEVICE_STATE_CTRL_BASE + 0x20) +#define KS2_DEVCFG (KS2_DEVICE_STATE_CTRL_BASE + 0x14c) + +/* PSC */ +#define KS2_PSC_BASE 0x02350000 +#define KS2_LPSC_GEM_0 15 +#define KS2_LPSC_TETRIS 52 +#define KS2_TETRIS_PWR_DOMAIN 31 + +/* Chip configuration unlock codes and registers */ +#define KS2_KICK0 (KS2_DEVICE_STATE_CTRL_BASE + 0x38) +#define KS2_KICK1 (KS2_DEVICE_STATE_CTRL_BASE + 0x3c) +#define KS2_KICK0_MAGIC 0x83e70b13 +#define KS2_KICK1_MAGIC 0x95a4f1e0 + +/* PLL control registers */ +#define KS2_MAINPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x350) +#define KS2_MAINPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x354) +#define KS2_PASSPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x358) +#define KS2_PASSPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x35C) +#define KS2_DDR3APLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x360) +#define KS2_DDR3APLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x364) +#define KS2_ARMPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE + 0x370) +#define KS2_ARMPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE + 0x374) + +#define KS2_PLL_CNTRL_BASE 0x02310000 +#define KS2_CLOCK_BASE KS2_PLL_CNTRL_BASE +#define KS2_RSTCTRL_RSTYPE (KS2_PLL_CNTRL_BASE + 0xe4) +#define KS2_RSTCTRL (KS2_PLL_CNTRL_BASE + 0xe8) +#define KS2_RSTCTRL_RSCFG (KS2_PLL_CNTRL_BASE + 0xec) +#define KS2_RSTCTRL_KEY 0x5a69 +#define KS2_RSTCTRL_MASK 0xffff0000 +#define KS2_RSTCTRL_SWRST 0xfffe0000 +#define KS2_RSTYPE_PLL_SOFT BIT(13) + +/* SPI */ +#define KS2_SPI0_BASE 0x21000400 +#define KS2_SPI1_BASE 0x21000600 +#define KS2_SPI2_BASE 0x21000800 +#define KS2_SPI_BASE KS2_SPI0_BASE + +/* AEMIF */ +#define KS2_AEMIF_CNTRL_BASE 0x21000a00 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE KS2_AEMIF_CNTRL_BASE + +/* Flag from ks2_debug options to check if DSPs need to stay ON */ +#define DBG_LEAVE_DSPS_ON 0x1 + +/* MSMC control */ +#define KS2_MSMC_CTRL_BASE 0x0bc00000 +#define KS2_MSMC_DATA_BASE 0x0c000000 +#define KS2_MSMC_SEGMENT_TETRIS 8 +#define KS2_MSMC_SEGMENT_NETCP 9 +#define KS2_MSMC_SEGMENT_QM_PDSP 10 +#define KS2_MSMC_SEGMENT_PCIE0 11 + +/* MSMC segment size shift bits */ +#define KS2_MSMC_SEG_SIZE_SHIFT 12 +#define KS2_MSMC_MAP_SEG_NUM (2 << (30 - KS2_MSMC_SEG_SIZE_SHIFT)) +#define KS2_MSMC_DST_SEG_BASE (CONFIG_SYS_LPAE_SDRAM_BASE >> \ + KS2_MSMC_SEG_SIZE_SHIFT) + +/* Device speed */ +#define KS2_REV1_DEVSPEED (KS2_DEVICE_STATE_CTRL_BASE + 0xc98) +#define KS2_EFUSE_BOOTROM (KS2_DEVICE_STATE_CTRL_BASE + 0xc90) +#define KS2_MISC_CTRL (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c) + +/* Queue manager */ +#define KS2_QM_BASE_ADDRESS 0x23a80000 +#define KS2_QM_CONF_BASE 0x02a02000 +#define KS2_QM_DESC_SETUP_BASE 0x02a03000 +#define KS2_QM_STATUS_RAM_BASE 0x02a06000 +#define KS2_QM_INTD_CONF_BASE 0x02a0c000 +#define KS2_QM_PDSP1_CMD_BASE 0x02a20000 +#define KS2_QM_PDSP1_CTRL_BASE 0x02a0f000 +#define KS2_QM_PDSP1_IRAM_BASE 0x02a10000 +#define KS2_QM_MANAGER_QUEUES_BASE 0x02a80000 +#define KS2_QM_MANAGER_Q_PROXY_BASE 0x02ac0000 +#define KS2_QM_QUEUE_STATUS_BASE 0x02a40000 +#define KS2_QM_LINK_RAM_BASE 0x00100000 +#define KS2_QM_REGION_NUM 64 +#define KS2_QM_QPOOL_NUM 4000 + +/* USB */ +#define KS2_USB_SS_BASE 0x02680000 +#define KS2_USB_HOST_XHCI_BASE (KS2_USB_SS_BASE + 0x10000) +#define KS2_DEV_USB_PHY_BASE 0x02620738 +#define KS2_USB_PHY_CFG_BASE 0x02630000 + +#define KS2_MAC_ID_BASE_ADDR (KS2_DEVICE_STATE_CTRL_BASE + 0x110) + +/* SGMII SerDes */ +#define KS2_SGMII_SERDES_BASE 0x0232a000 + +#ifdef CONFIG_SOC_K2HK +#include +#endif + +#ifdef CONFIG_SOC_K2E +#include +#endif + +#ifdef CONFIG_SOC_K2L +#include +#endif + +#ifndef __ASSEMBLY__ +static inline int cpu_is_k2hk(void) +{ + unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); + unsigned int part_no = (jtag_id >> 12) & 0xffff; + + return (part_no == 0xb981) ? 1 : 0; +} + +static inline int cpu_is_k2e(void) +{ + unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); + unsigned int part_no = (jtag_id >> 12) & 0xffff; + + return (part_no == 0xb9a6) ? 1 : 0; +} + +static inline int cpu_is_k2l(void) +{ + unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); + unsigned int part_no = (jtag_id >> 12) & 0xffff; + + return (part_no == 0xb9a7) ? 1 : 0; +} + +static inline int cpu_revision(void) +{ + unsigned int jtag_id = __raw_readl(KS2_JTAG_ID_REG); + unsigned int rev = (jtag_id >> 28) & 0xf; + + return rev; +} + +int cpu_to_bus(u32 *ptr, u32 length); +void sdelay(unsigned long); + +#endif + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-keystone/include/mach/i2c_defs.h b/arch/arm/mach-keystone/include/mach/i2c_defs.h new file mode 100644 index 0000000000..d4256526cc --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/i2c_defs.h @@ -0,0 +1,17 @@ +/* + * keystone: i2c driver definitions + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _I2C_DEFS_H_ +#define _I2C_DEFS_H_ + +#define I2C0_BASE 0x02530000 +#define I2C1_BASE 0x02530400 +#define I2C2_BASE 0x02530800 +#define I2C_BASE I2C0_BASE + +#endif diff --git a/arch/arm/mach-keystone/include/mach/mon.h b/arch/arm/mach-keystone/include/mach/mon.h new file mode 100644 index 0000000000..33a28764bc --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/mon.h @@ -0,0 +1,15 @@ +/* + * K2HK: secure kernel command header file + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MON_H_ +#define _MON_H_ + +int mon_power_off(int core_id); + +#endif diff --git a/arch/arm/mach-keystone/include/mach/msmc.h b/arch/arm/mach-keystone/include/mach/msmc.h new file mode 100644 index 0000000000..083f5ba052 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/msmc.h @@ -0,0 +1,45 @@ +/* + * MSMC controller + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MSMC_H_ +#define _MSMC_H_ + +#include + +enum mpax_seg_size { + MPAX_SEG_4K = 0x0b, + MPAX_SEG_8K, + MPAX_SEG_16K, + MPAX_SEG_32K, + MPAX_SEG_64K, + MPAX_SEG_128K, + MPAX_SEG_256K, + MPAX_SEG_512K, + MPAX_SEG_1M, + MPAX_SEG_2M, + MPAX_SEG_4M, + MPAX_SEG_8M, + MPAX_SEG_16M, + MPAX_SEG_32M, + MPAX_SEG_64M, + MPAX_SEG_128M, + MPAX_SEG_256M, + MPAX_SEG_512M, + MPAX_SEG_1G, + MPAX_SEG_2G, + MPAX_SEG_4G +}; + +void msmc_share_all_segments(int priv_id); +void msmc_get_ses_mpax(int priv_id, int ses_pair, u32 *mpax); +void msmc_set_ses_mpax(int priv_id, int ses_pair, u32 *mpax); +void msmc_map_ses_segment(int priv_id, int ses_pair, + u32 src_pfn, u32 dst_pfn, enum mpax_seg_size size); + +#endif diff --git a/arch/arm/mach-keystone/include/mach/psc_defs.h b/arch/arm/mach-keystone/include/mach/psc_defs.h new file mode 100644 index 0000000000..70d22cf217 --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/psc_defs.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _PSC_DEFS_H_ +#define _PSC_DEFS_H_ + +#include + +/* + * FILE PURPOSE: Local Power Sleep Controller definitions + * + * FILE NAME: psc_defs.h + * + * DESCRIPTION: Provides local definitions for the power saver controller + * + */ + +/* Register offsets */ +#define PSC_REG_PTCMD 0x120 +#define PSC_REG_PSTAT 0x128 +#define PSC_REG_PDSTAT(x) (0x200 + (4 * (x))) +#define PSC_REG_PDCTL(x) (0x300 + (4 * (x))) +#define PSC_REG_MDCFG(x) (0x600 + (4 * (x))) +#define PSC_REG_MDSTAT(x) (0x800 + (4 * (x))) +#define PSC_REG_MDCTL(x) (0xa00 + (4 * (x))) + +#define BOOTBITMASK(x, y) ((((((u32)1 << (((u32)x) - ((u32)y) + (u32)1)) - \ + (u32)1)) << ((u32)y))) + +#define BOOT_READ_BITFIELD(z, x, y) (((u32)z) & BOOTBITMASK(x, y)) >> (y) +#define BOOT_SET_BITFIELD(z, f, x, y) (((u32)z) & ~BOOTBITMASK(x, y)) | \ + ((((u32)f) << (y)) & BOOTBITMASK(x, y)) + +/* PDCTL */ +#define PSC_REG_PDCTL_SET_NEXT(x, y) BOOT_SET_BITFIELD((x), (y), 0, 0) +#define PSC_REG_PDCTL_SET_PDMODE(x, y) BOOT_SET_BITFIELD((x), (y), 15, 12) + +/* PDSTAT */ +#define PSC_REG_PDSTAT_GET_STATE(x) BOOT_READ_BITFIELD((x), 4, 0) + +/* MDCFG */ +#define PSC_REG_MDCFG_GET_PD(x) BOOT_READ_BITFIELD((x), 20, 16) +#define PSC_REG_MDCFG_GET_RESET_ISO(x) BOOT_READ_BITFIELD((x), 14, 14) + +/* MDCTL */ +#define PSC_REG_MDCTL_SET_NEXT(x, y) BOOT_SET_BITFIELD((x), (y), 4, 0) +#define PSC_REG_MDCTL_SET_LRSTZ(x, y) BOOT_SET_BITFIELD((x), (y), 8, 8) +#define PSC_REG_MDCTL_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) +#define PSC_REG_MDCTL_SET_RESET_ISO(x, y) BOOT_SET_BITFIELD((x), (y), \ + 12, 12) + +/* MDSTAT */ +#define PSC_REG_MDSTAT_GET_STATUS(x) BOOT_READ_BITFIELD((x), 5, 0) +#define PSC_REG_MDSTAT_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) +#define PSC_REG_MDSTAT_GET_LRSTDONE(x) BOOT_READ_BITFIELD((x), 9, 9) + +/* PDCTL states */ +#define PSC_REG_VAL_PDCTL_NEXT_ON 1 +#define PSC_REG_VAL_PDCTL_NEXT_OFF 0 + +#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP 0 + +/* MDCTL states */ +#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE 0 +#define PSC_REG_VAL_MDCTL_NEXT_OFF 2 +#define PSC_REG_VAL_MDCTL_NEXT_ON 3 + +/* MDSTAT states */ +#define PSC_REG_VAL_MDSTAT_STATE_ON 3 +#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG 0x24 +#define PSC_REG_VAL_MDSTAT_STATE_OFF 2 +#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1 0x20 +#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2 0x21 +#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3 0x22 + +/* + * Timeout limit on checking PTSTAT. This is the number of times the + * wait function will be called before giving up. + */ +#define PSC_PTSTAT_TIMEOUT_LIMIT 100 + +u32 psc_get_domain_num(u32 mod_num); +int psc_enable_module(u32 mod_num); +int psc_disable_module(u32 mod_num); +int psc_disable_domain(u32 domain_num); + +#endif /* _PSC_DEFS_H_ */ diff --git a/arch/arm/mach-keystone/include/mach/xhci-keystone.h b/arch/arm/mach-keystone/include/mach/xhci-keystone.h new file mode 100644 index 0000000000..3aab4e045f --- /dev/null +++ b/arch/arm/mach-keystone/include/mach/xhci-keystone.h @@ -0,0 +1,21 @@ +/* + * USB 3.0 DRD Controller + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define USB3_PHY_REF_SSP_EN BIT(29) +#define USB3_PHY_OTG_VBUSVLDECTSEL BIT(16) + +/* KEYSTONE2 XHCI PHY register structure */ +struct keystone_xhci_phy { + unsigned int phy_utmi; /* ctl0 */ + unsigned int phy_pipe; /* ctl1 */ + unsigned int phy_param_ctrl_1; /* ctl2 */ + unsigned int phy_param_ctrl_2; /* ctl3 */ + unsigned int phy_clock; /* ctl4 */ + unsigned int phy_pll; /* ctl5 */ +}; -- cgit From 30ebf88f44917abf070ab899111cd2684000e204 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 20 Feb 2015 17:04:19 +0900 Subject: ARM: prepare for including This commit adds $(srctree)/arch/arm/$(machdirs)/include/mach to the headers search path. It allows us to replace "#include " with "#include ". As "#include " is still supported, we can modify each file one by one. Signed-off-by: Masahiro Yamada --- arch/arm/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 678ac132aa..878ae26ce4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -19,6 +19,8 @@ machine-$(CONFIG_ARCH_VERSATILE) += versatile machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) +PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) + libs-y += $(machdirs) head-y := arch/arm/cpu/$(CPU)/start.o -- cgit From a033171b2ece1f3575ab7277e7b862e7f611b3f6 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 16 Feb 2015 12:16:13 -0700 Subject: bcm2835/rpi: add SPDX license tags for some files Signed-off-by: Stephen Warren --- arch/arm/cpu/arm1176/bcm2835/Makefile | 12 ++---------- arch/arm/include/asm/arch-bcm2835/sdhci.h | 12 +----------- arch/arm/include/asm/arch-bcm2835/timer.h | 12 +----------- arch/arm/include/asm/arch-bcm2835/wdog.h | 12 +----------- board/raspberrypi/rpi/Makefile | 12 ++---------- board/raspberrypi/rpi/rpi.c | 12 +----------- include/configs/rpi.h | 12 +----------- 7 files changed, 9 insertions(+), 75 deletions(-) diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile index 0ad36906df..7e5dbe1fde 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Makefile +++ b/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -1,15 +1,7 @@ # -# See file CREDITS for list of people who contributed to this -# project. +# (C) Copyright 2012 Stephen Warren # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 2 as published by the Free Software Foundation. -# -# This program 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. +# SPDX-License-Identifier: GPL-2.0 # obj-y := lowlevel_init.o diff --git a/arch/arm/include/asm/arch-bcm2835/sdhci.h b/arch/arm/include/asm/arch-bcm2835/sdhci.h index a4f867b2e9..da4d5cd5a8 100644 --- a/arch/arm/include/asm/arch-bcm2835/sdhci.h +++ b/arch/arm/include/asm/arch-bcm2835/sdhci.h @@ -1,17 +1,7 @@ /* * (C) Copyright 2012 Stephen Warren * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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. + * SPDX-License-Identifier: GPL-2.0 */ #ifndef _BCM2835_SDHCI_H_ diff --git a/arch/arm/include/asm/arch-bcm2835/timer.h b/arch/arm/include/asm/arch-bcm2835/timer.h index c2001b6f93..2d7cfe5c56 100644 --- a/arch/arm/include/asm/arch-bcm2835/timer.h +++ b/arch/arm/include/asm/arch-bcm2835/timer.h @@ -1,17 +1,7 @@ /* * (C) Copyright 2012 Stephen Warren * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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. + * SPDX-License-Identifier: GPL-2.0 */ #ifndef _BCM2835_TIMER_H diff --git a/arch/arm/include/asm/arch-bcm2835/wdog.h b/arch/arm/include/asm/arch-bcm2835/wdog.h index 303a65f32e..f369ab589c 100644 --- a/arch/arm/include/asm/arch-bcm2835/wdog.h +++ b/arch/arm/include/asm/arch-bcm2835/wdog.h @@ -1,17 +1,7 @@ /* * (C) Copyright 2012 Stephen Warren * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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. + * SPDX-License-Identifier: GPL-2.0 */ #ifndef _BCM2835_TIMER_H diff --git a/board/raspberrypi/rpi/Makefile b/board/raspberrypi/rpi/Makefile index c53c92b1dd..4ce2c983b3 100644 --- a/board/raspberrypi/rpi/Makefile +++ b/board/raspberrypi/rpi/Makefile @@ -1,15 +1,7 @@ # -# See file CREDITS for list of people who contributed to this -# project. +# (C) Copyright 2012 Stephen Warren # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 2 as published by the Free Software Foundation. -# -# This program 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. +# SPDX-License-Identifier: GPL-2.0 # obj-y := rpi.o diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 948078b958..fdbf87d6fa 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -1,17 +1,7 @@ /* * (C) Copyright 2012-2013 Stephen Warren * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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. + * SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/include/configs/rpi.h b/include/configs/rpi.h index 7ad8d08021..9b32149b0e 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -1,17 +1,7 @@ /* * (C) Copyright 2012 Stephen Warren * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program 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. + * SPDX-License-Identifier: GPL-2.0 */ #ifndef __CONFIG_H -- cgit From db75356f14646a4bca7b712f2128435e97f55c17 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 16 Feb 2015 12:16:14 -0700 Subject: bcm2836 SoC support (used in Raspberry Pi 2 model B) The bcm2835 and bcm2836 are essentially identical, except: - The CPU is an ARM1176 v.s. a quad-core Cortex-A7. - The physical address of many IO controllers has moved. Rather than introducing a whole new bcm2836 value for $(SOC) or $(ARCH), update the existing bcm2835 code to handle the minor differences, and plumb it into the ARMv7 CPU architecture. Signed-off-by: Stephen Warren --- arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/bcm2835/Makefile | 13 +++++++++++++ arch/arm/include/asm/arch-bcm2835/gpio.h | 5 +++++ arch/arm/include/asm/arch-bcm2835/mbox.h | 6 +++++- arch/arm/include/asm/arch-bcm2835/sdhci.h | 6 +++++- arch/arm/include/asm/arch-bcm2835/timer.h | 6 +++++- arch/arm/include/asm/arch-bcm2835/wdog.h | 6 +++++- 7 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/bcm2835/Makefile diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 1a76982d6e..b228ed6a2e 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -39,6 +39,7 @@ endif obj-$(if $(filter am33xx,$(SOC)),y) += am33xx/ obj-$(if $(filter armada-xp,$(SOC)),y) += armada-xp/ +obj-$(CONFIG_BCM2835) += bcm2835/ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ diff --git a/arch/arm/cpu/armv7/bcm2835/Makefile b/arch/arm/cpu/armv7/bcm2835/Makefile new file mode 100644 index 0000000000..ed1ee4753d --- /dev/null +++ b/arch/arm/cpu/armv7/bcm2835/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2012 Stephen Warren +# +# SPDX-License-Identifier: GPL-2.0+ +# + +src_dir := ../../arm1176/bcm2835/ + +obj-y := +obj-y += $(src_dir)/init.o +obj-y += $(src_dir)/reset.o +obj-y += $(src_dir)/timer.o +obj-y += $(src_dir)/mbox.o diff --git a/arch/arm/include/asm/arch-bcm2835/gpio.h b/arch/arm/include/asm/arch-bcm2835/gpio.h index db42896201..c8ef8f528a 100644 --- a/arch/arm/include/asm/arch-bcm2835/gpio.h +++ b/arch/arm/include/asm/arch-bcm2835/gpio.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2012 Vikram Narayananan * + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,7 +9,11 @@ #ifndef _BCM2835_GPIO_H_ #define _BCM2835_GPIO_H_ +#ifdef CONFIG_BCM2836 +#define BCM2835_GPIO_BASE 0x3f200000 +#else #define BCM2835_GPIO_BASE 0x20200000 +#endif #define BCM2835_GPIO_COUNT 54 #define BCM2835_GPIO_FSEL_MASK 0x7 diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h index 88d2ec11a7..c4bbacaf3c 100644 --- a/arch/arm/include/asm/arch-bcm2835/mbox.h +++ b/arch/arm/include/asm/arch-bcm2835/mbox.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0+ */ @@ -38,7 +38,11 @@ /* Raw mailbox HW */ +#ifdef CONFIG_BCM2836 +#define BCM2835_MBOX_PHYSADDR 0x3f00b880 +#else #define BCM2835_MBOX_PHYSADDR 0x2000b880 +#endif struct bcm2835_mbox_regs { u32 read; diff --git a/arch/arm/include/asm/arch-bcm2835/sdhci.h b/arch/arm/include/asm/arch-bcm2835/sdhci.h index da4d5cd5a8..2a21ccbf66 100644 --- a/arch/arm/include/asm/arch-bcm2835/sdhci.h +++ b/arch/arm/include/asm/arch-bcm2835/sdhci.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0 */ @@ -7,7 +7,11 @@ #ifndef _BCM2835_SDHCI_H_ #define _BCM2835_SDHCI_H_ +#ifdef CONFIG_BCM2836 +#define BCM2835_SDHCI_BASE 0x3f300000 +#else #define BCM2835_SDHCI_BASE 0x20300000 +#endif int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq); diff --git a/arch/arm/include/asm/arch-bcm2835/timer.h b/arch/arm/include/asm/arch-bcm2835/timer.h index 2d7cfe5c56..fc7aec7b7c 100644 --- a/arch/arm/include/asm/arch-bcm2835/timer.h +++ b/arch/arm/include/asm/arch-bcm2835/timer.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0 */ @@ -7,7 +7,11 @@ #ifndef _BCM2835_TIMER_H #define _BCM2835_TIMER_H +#ifdef CONFIG_BCM2836 +#define BCM2835_TIMER_PHYSADDR 0x3f003000 +#else #define BCM2835_TIMER_PHYSADDR 0x20003000 +#endif struct bcm2835_timer_regs { u32 cs; diff --git a/arch/arm/include/asm/arch-bcm2835/wdog.h b/arch/arm/include/asm/arch-bcm2835/wdog.h index f369ab589c..beb6a08206 100644 --- a/arch/arm/include/asm/arch-bcm2835/wdog.h +++ b/arch/arm/include/asm/arch-bcm2835/wdog.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0 */ @@ -7,7 +7,11 @@ #ifndef _BCM2835_TIMER_H #define _BCM2835_TIMER_H +#ifdef CONFIG_BCM2836 +#define BCM2835_WDOG_PHYSADDR 0x3f100000 +#else #define BCM2835_WDOG_PHYSADDR 0x20100000 +#endif struct bcm2835_wdog_regs { u32 unknown0[7]; -- cgit From 46414296953410706e917cef9238926084e83a4b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 16 Feb 2015 12:16:15 -0700 Subject: rpi: add support for Raspberry Pi 2 model B USB doesn't seem to work yet; the controller detects the on-board Hub/ Ethernet device but can't read the descriptors from it. I haven't investigated yet. Signed-off-by: Stephen Warren --- arch/arm/Kconfig | 5 + arch/arm/cpu/arm1176/bcm2835/Kconfig | 2 +- arch/arm/include/asm/arch-bcm2835/mbox.h | 4 + board/raspberrypi/rpi/rpi.c | 28 ++++- board/raspberrypi/rpi_2/Kconfig | 15 +++ board/raspberrypi/rpi_2/MAINTAINERS | 6 + board/raspberrypi/rpi_2/Makefile | 7 ++ configs/rpi_2_defconfig | 4 + include/configs/rpi-common.h | 186 +++++++++++++++++++++++++++++++ include/configs/rpi.h | 168 +--------------------------- include/configs/rpi_2.h | 15 +++ 11 files changed, 271 insertions(+), 169 deletions(-) create mode 100644 board/raspberrypi/rpi_2/Kconfig create mode 100644 board/raspberrypi/rpi_2/MAINTAINERS create mode 100644 board/raspberrypi/rpi_2/Makefile create mode 100644 configs/rpi_2_defconfig create mode 100644 include/configs/rpi-common.h create mode 100644 include/configs/rpi_2.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 083823e8c4..820ba1ccab 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -310,6 +310,10 @@ config TARGET_RPI bool "Support rpi" select CPU_ARM1176 +config TARGET_RPI_2 + bool "Support rpi_2" + select CPU_V7 + config TARGET_TNETV107X_EVM bool "Support tnetv107x_evm" select CPU_ARM1176 @@ -830,6 +834,7 @@ source "board/phytec/pcm051/Kconfig" source "board/ppcag/bg0900/Kconfig" source "board/pxa255_idp/Kconfig" source "board/raspberrypi/rpi/Kconfig" +source "board/raspberrypi/rpi_2/Kconfig" source "board/samsung/smdk2410/Kconfig" source "board/sandisk/sansa_fuze_plus/Kconfig" source "board/scb9328/Kconfig" diff --git a/arch/arm/cpu/arm1176/bcm2835/Kconfig b/arch/arm/cpu/arm1176/bcm2835/Kconfig index 94f57d732f..162f973f6c 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Kconfig +++ b/arch/arm/cpu/arm1176/bcm2835/Kconfig @@ -1,4 +1,4 @@ -if TARGET_RPI +if TARGET_RPI || TARGET_RPI_2 config DM default y if !SPL_BUILD diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h index c4bbacaf3c..04bf480a54 100644 --- a/arch/arm/include/asm/arch-bcm2835/mbox.h +++ b/arch/arm/include/asm/arch-bcm2835/mbox.h @@ -125,6 +125,9 @@ struct bcm2835_mbox_tag_hdr { #define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002 +#ifdef CONFIG_BCM2836 +#define BCM2836_BOARD_REV_2_B 0x4 +#else /* * 0x2..0xf from: * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/ @@ -145,6 +148,7 @@ struct bcm2835_mbox_tag_hdr { #define BCM2835_BOARD_REV_B_PLUS 0x10 #define BCM2835_BOARD_REV_CM 0x11 #define BCM2835_BOARD_REV_A_PLUS 0x12 +#endif struct bcm2835_mbox_tag_get_board_rev { struct bcm2835_mbox_tag_hdr tag_hdr; diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index fdbf87d6fa..50a699bb9e 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012-2013 Stephen Warren + * (C) Copyright 2012-2013,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0 */ @@ -29,7 +29,11 @@ U_BOOT_DEVICE(bcm2835_gpios) = { }; static const struct pl01x_serial_platdata serial_platdata = { +#ifdef CONFIG_BCM2836 + .base = 0x3f201000, +#else .base = 0x20201000, +#endif .type = TYPE_PL011, .clock = 3000000, }; @@ -77,9 +81,20 @@ static const struct { } models[] = { [0] = { "Unknown model", +#ifdef CONFIG_BCM2836 + "bcm2836-rpi-other.dtb", +#else "bcm2835-rpi-other.dtb", +#endif false, }, +#ifdef CONFIG_BCM2836 + [BCM2836_BOARD_REV_2_B] = { + "2 Model B", + "bcm2836-rpi-2-b.dtb", + true, + }, +#else [BCM2835_BOARD_REV_B_I2C0_2] = { "Model B (no P5)", "bcm2835-rpi-b-i2c0.dtb", @@ -150,6 +165,7 @@ static const struct { "bcm2835-rpi-a-plus.dtb", false, }, +#endif }; u32 rpi_board_rev = 0; @@ -257,7 +273,15 @@ static void get_board_rev(void) return; } + /* + * For details of old-vs-new scheme, see: + * https://github.com/pimoroni/RPi.version/blob/master/RPi/version.py + * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=99293&p=690282 + * (a few posts down) + */ rpi_board_rev = msg->get_board_rev.body.resp.rev; + if (rpi_board_rev & 0x800000) + rpi_board_rev = (rpi_board_rev >> 4) & 0xff; if (rpi_board_rev >= ARRAY_SIZE(models)) { printf("RPI: Board rev %u outside known range\n", rpi_board_rev); @@ -269,7 +293,7 @@ static void get_board_rev(void) } name = models[rpi_board_rev].name; - printf("RPI model: %s\n", name); + printf("RPI %s\n", name); } int board_init(void) diff --git a/board/raspberrypi/rpi_2/Kconfig b/board/raspberrypi/rpi_2/Kconfig new file mode 100644 index 0000000000..032184d5ad --- /dev/null +++ b/board/raspberrypi/rpi_2/Kconfig @@ -0,0 +1,15 @@ +if TARGET_RPI_2 + +config SYS_BOARD + default "rpi_2" + +config SYS_VENDOR + default "raspberrypi" + +config SYS_SOC + default "bcm2835" + +config SYS_CONFIG_NAME + default "rpi_2" + +endif diff --git a/board/raspberrypi/rpi_2/MAINTAINERS b/board/raspberrypi/rpi_2/MAINTAINERS new file mode 100644 index 0000000000..85a480c9d1 --- /dev/null +++ b/board/raspberrypi/rpi_2/MAINTAINERS @@ -0,0 +1,6 @@ +RPI_2 BOARD +M: Stephen Warren +S: Maintained +F: board/raspberrypi/rpi_2/ +F: include/configs/rpi_2.h +F: configs/rpi_2_defconfig diff --git a/board/raspberrypi/rpi_2/Makefile b/board/raspberrypi/rpi_2/Makefile new file mode 100644 index 0000000000..d82cd21f4c --- /dev/null +++ b/board/raspberrypi/rpi_2/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2012,2015 Stephen Warren +# +# SPDX-License-Identifier: GPL-2.0 +# + +obj-y := ../rpi/rpi.o diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig new file mode 100644 index 0000000000..b539d4a689 --- /dev/null +++ b/configs/rpi_2_defconfig @@ -0,0 +1,4 @@ +CONFIG_ARM=y +CONFIG_TARGET_RPI_2=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x400 diff --git a/include/configs/rpi-common.h b/include/configs/rpi-common.h new file mode 100644 index 0000000000..3121ac9874 --- /dev/null +++ b/include/configs/rpi-common.h @@ -0,0 +1,186 @@ +/* + * (C) Copyright 2012,2015 Stephen Warren + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _RPI_COMMON_H_ +#define _RPI_COMMON_H_ + +#include + +/* Architecture, CPU, etc.*/ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_BCM2835 +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_SYS_DCACHE_OFF +/* + * 2835 is a SKU in a series for which the 2708 is the first or primary SoC, + * so 2708 has historically been used rather than a dedicated 2835 ID. + * + * We don't define a machine type for bcm2709/bcm2836 since the RPi Foundation + * chose to use someone else's previously registered machine ID (3139, MX51_GGC) + * rather than obtaining a valid ID:-/ + */ +#ifndef CONFIG_BCM2836 +#define CONFIG_MACH_TYPE MACH_TYPE_BCM2708 +#endif + +/* Memory layout */ +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x00000000 +#define CONFIG_SYS_TEXT_BASE 0x00008000 +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE +/* + * The board really has 256M. However, the VC (VideoCore co-processor) shares + * the RAM, and uses a configurable portion at the top. We tell U-Boot that a + * smaller amount of RAM is present in order to avoid stomping on the area + * the VC uses. + */ +#define CONFIG_SYS_SDRAM_SIZE SZ_128M +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_SDRAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_MALLOC_LEN SZ_4M +#define CONFIG_SYS_MEMTEST_START 0x00100000 +#define CONFIG_SYS_MEMTEST_END 0x00200000 +#define CONFIG_LOADADDR 0x00200000 + +/* Flash */ +#define CONFIG_SYS_NO_FLASH + +/* Devices */ +/* GPIO */ +#define CONFIG_BCM2835_GPIO +/* LCD */ +#define CONFIG_LCD +#define CONFIG_LCD_DT_SIMPLEFB +#define LCD_BPP LCD_COLOR16 +/* + * Prevent allocation of RAM for FB; the real FB address is queried + * dynamically from the VideoCore co-processor, and comes from RAM + * not owned by the ARM CPU. + */ +#define CONFIG_FB_ADDR 0 +#define CONFIG_VIDEO_BCM2835 +#define CONFIG_SYS_WHITE_ON_BLACK + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_MMC_SDHCI_IO_ACCESSORS +#define CONFIG_BCM2835_SDHCI + +#define CONFIG_CMD_USB +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_DWC2 +#ifdef CONFIG_BCM2836 +#define CONFIG_USB_DWC2_REG_ADDR 0x3f980000 +#else +#define CONFIG_USB_DWC2_REG_ADDR 0x20980000 +#endif +#define CONFIG_USB_STORAGE +#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_SMSC95XX +#define CONFIG_MISC_INIT_R +#endif + +/* Console UART */ +#define CONFIG_PL01X_SERIAL +#define CONFIG_CONS_INDEX 0 +#define CONFIG_BAUDRATE 115200 + +/* Console configuration */ +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +/* Environment */ +#define CONFIG_ENV_SIZE SZ_16K +#define CONFIG_ENV_IS_IN_FAT +#define FAT_ENV_INTERFACE "mmc" +#define FAT_ENV_DEVICE_AND_PART "0:1" +#define FAT_ENV_FILE "uboot.env" +#define CONFIG_FAT_WRITE +#define CONFIG_ENV_VARS_UBOOT_CONFIG +#define CONFIG_SYS_LOAD_ADDR 0x1000000 +#define CONFIG_CONSOLE_MUX +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +/* Shell */ +#define CONFIG_SYS_MAXARGS 8 +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_COMMAND_HISTORY + +/* Commands */ +#include +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_MMC +#define CONFIG_PARTITION_UUIDS +#define CONFIG_CMD_PART + +/* Device tree support */ +#define CONFIG_OF_BOARD_SETUP +/* ATAGs support for bootm/bootz */ +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG + +#include + +/* Some things don't make sense on this HW or yet */ +#undef CONFIG_CMD_FPGA + +/* Environment */ +#define ENV_DEVICE_SETTINGS \ + "stdin=serial,lcd\0" \ + "stdout=serial,lcd\0" \ + "stderr=serial,lcd\0" + +/* + * Memory layout for where various images get loaded by boot scripts: + * + * scriptaddr can be pretty much anywhere that doesn't conflict with something + * else. Put it low in memory to avoid conflicts. + * + * pxefile_addr_r can be pretty much anywhere that doesn't conflict with + * something else. Put it low in memory to avoid conflicts. + * + * kernel_addr_r must be within the first 128M of RAM in order for the + * kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will + * decompress itself to 0x8000 after the start of RAM, kernel_addr_r + * should not overlap that area, or the kernel will have to copy itself + * somewhere else before decompression. Similarly, the address of any other + * data passed to the kernel shouldn't overlap the start of RAM. Pushing + * this up to 16M allows for a sizable kernel to be decompressed below the + * compressed load address. + * + * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for + * the compressed kernel to be up to 16M too. + * + * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows + * for the FDT/DTB to be up to 1M, which is hopefully plenty. + */ +#define ENV_MEM_LAYOUT_SETTINGS \ + "scriptaddr=0x00000000\0" \ + "pxefile_addr_r=0x00100000\0" \ + "kernel_addr_r=0x01000000\0" \ + "fdt_addr_r=0x02000000\0" \ + "ramdisk_addr_r=0x02100000\0" \ + +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(USB, usb, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) +#include + +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_DEVICE_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV + +#define CONFIG_BOOTDELAY 2 + +#endif diff --git a/include/configs/rpi.h b/include/configs/rpi.h index 9b32149b0e..ab2f4db39f 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2012 Stephen Warren + * (C) Copyright 2012,2015 Stephen Warren * * SPDX-License-Identifier: GPL-2.0 */ @@ -7,170 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#include - -/* Architecture, CPU, etc.*/ -#define CONFIG_SYS_GENERIC_BOARD -#define CONFIG_BCM2835 -#define CONFIG_ARCH_CPU_INIT -#define CONFIG_SYS_DCACHE_OFF -/* - * 2835 is a SKU in a series for which the 2708 is the first or primary SoC, - * so 2708 has historically been used rather than a dedicated 2835 ID. - */ -#define CONFIG_MACH_TYPE MACH_TYPE_BCM2708 - -/* Memory layout */ -#define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_SYS_SDRAM_BASE 0x00000000 -#define CONFIG_SYS_TEXT_BASE 0x00008000 -#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE -/* - * The board really has 256M. However, the VC (VideoCore co-processor) shares - * the RAM, and uses a configurable portion at the top. We tell U-Boot that a - * smaller amount of RAM is present in order to avoid stomping on the area - * the VC uses. - */ -#define CONFIG_SYS_SDRAM_SIZE SZ_128M -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ - CONFIG_SYS_SDRAM_SIZE - \ - GENERATED_GBL_DATA_SIZE) -#define CONFIG_SYS_MALLOC_LEN SZ_4M -#define CONFIG_SYS_MEMTEST_START 0x00100000 -#define CONFIG_SYS_MEMTEST_END 0x00200000 -#define CONFIG_LOADADDR 0x00200000 - -/* Flash */ -#define CONFIG_SYS_NO_FLASH - -/* Devices */ -/* GPIO */ -#define CONFIG_BCM2835_GPIO -/* LCD */ -#define CONFIG_LCD -#define CONFIG_LCD_DT_SIMPLEFB -#define LCD_BPP LCD_COLOR16 -/* - * Prevent allocation of RAM for FB; the real FB address is queried - * dynamically from the VideoCore co-processor, and comes from RAM - * not owned by the ARM CPU. - */ -#define CONFIG_FB_ADDR 0 -#define CONFIG_VIDEO_BCM2835 -#define CONFIG_SYS_WHITE_ON_BLACK - -/* SD/MMC configuration */ -#define CONFIG_GENERIC_MMC -#define CONFIG_MMC -#define CONFIG_SDHCI -#define CONFIG_MMC_SDHCI_IO_ACCESSORS -#define CONFIG_BCM2835_SDHCI - -#define CONFIG_CMD_USB -#ifdef CONFIG_CMD_USB -#define CONFIG_USB_DWC2 -#define CONFIG_USB_DWC2_REG_ADDR 0x20980000 -#define CONFIG_USB_STORAGE -#define CONFIG_USB_HOST_ETHER -#define CONFIG_USB_ETHER_SMSC95XX -#define CONFIG_MISC_INIT_R -#endif - -/* Console UART */ -#define CONFIG_PL01X_SERIAL -#define CONFIG_CONS_INDEX 0 -#define CONFIG_BAUDRATE 115200 - -/* Console configuration */ -#define CONFIG_SYS_CBSIZE 1024 -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ - sizeof(CONFIG_SYS_PROMPT) + 16) - -/* Environment */ -#define CONFIG_ENV_SIZE SZ_16K -#define CONFIG_ENV_IS_IN_FAT -#define FAT_ENV_INTERFACE "mmc" -#define FAT_ENV_DEVICE_AND_PART "0:1" -#define FAT_ENV_FILE "uboot.env" -#define CONFIG_FAT_WRITE -#define CONFIG_ENV_VARS_UBOOT_CONFIG -#define CONFIG_SYS_LOAD_ADDR 0x1000000 -#define CONFIG_CONSOLE_MUX -#define CONFIG_SYS_CONSOLE_IS_IN_ENV - -/* Shell */ -#define CONFIG_SYS_MAXARGS 8 -#define CONFIG_SYS_PROMPT "U-Boot> " -#define CONFIG_COMMAND_HISTORY - -/* Commands */ -#include -#define CONFIG_CMD_GPIO -#define CONFIG_CMD_MMC -#define CONFIG_PARTITION_UUIDS -#define CONFIG_CMD_PART - -/* Device tree support */ -#define CONFIG_OF_BOARD_SETUP -/* ATAGs support for bootm/bootz */ -#define CONFIG_SETUP_MEMORY_TAGS -#define CONFIG_CMDLINE_TAG -#define CONFIG_INITRD_TAG - -#include - -/* Some things don't make sense on this HW or yet */ -#undef CONFIG_CMD_FPGA - -/* Environment */ -#define ENV_DEVICE_SETTINGS \ - "stdin=serial,lcd\0" \ - "stdout=serial,lcd\0" \ - "stderr=serial,lcd\0" - -/* - * Memory layout for where various images get loaded by boot scripts: - * - * scriptaddr can be pretty much anywhere that doesn't conflict with something - * else. Put it low in memory to avoid conflicts. - * - * pxefile_addr_r can be pretty much anywhere that doesn't conflict with - * something else. Put it low in memory to avoid conflicts. - * - * kernel_addr_r must be within the first 128M of RAM in order for the - * kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will - * decompress itself to 0x8000 after the start of RAM, kernel_addr_r - * should not overlap that area, or the kernel will have to copy itself - * somewhere else before decompression. Similarly, the address of any other - * data passed to the kernel shouldn't overlap the start of RAM. Pushing - * this up to 16M allows for a sizable kernel to be decompressed below the - * compressed load address. - * - * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for - * the compressed kernel to be up to 16M too. - * - * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows - * for the FDT/DTB to be up to 1M, which is hopefully plenty. - */ -#define ENV_MEM_LAYOUT_SETTINGS \ - "scriptaddr=0x00000000\0" \ - "pxefile_addr_r=0x00100000\0" \ - "kernel_addr_r=0x01000000\0" \ - "fdt_addr_r=0x02000000\0" \ - "ramdisk_addr_r=0x02100000\0" \ - -#define BOOT_TARGET_DEVICES(func) \ - func(MMC, mmc, 0) \ - func(USB, usb, 0) \ - func(PXE, pxe, na) \ - func(DHCP, dhcp, na) -#include - -#define CONFIG_EXTRA_ENV_SETTINGS \ - ENV_DEVICE_SETTINGS \ - ENV_MEM_LAYOUT_SETTINGS \ - BOOTENV - -#define CONFIG_BOOTDELAY 2 +#include "rpi-common.h" #endif diff --git a/include/configs/rpi_2.h b/include/configs/rpi_2.h new file mode 100644 index 0000000000..2e7e74fd56 --- /dev/null +++ b/include/configs/rpi_2.h @@ -0,0 +1,15 @@ +/* + * (C) Copyright 2012,2015 Stephen Warren + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_BCM2836 + +#include "rpi-common.h" + +#endif -- cgit From 1de32b8a69eebdd208914c2a90dfb6cdd8ea8352 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 19 Feb 2015 20:34:32 +0100 Subject: sunxi: mmc: Always declare High Capacity capability High Capacity (e)MMC cards work fine on sun4i / sun5i, and not having this capability set causes u-boot to not recognize the eMMC on an Utoo P66 A13 tablet, so always set it thereby fixing this. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index ebfec7cf07..22335452c5 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -449,11 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; - cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \ - defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN9I) - cfg->host_caps |= MMC_MODE_HC; -#endif + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_min = 400000; -- cgit From 636317c9eea8df0657fe702e1eddeedff605b0c7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Feb 2015 19:47:43 +0100 Subject: sunxi: Add support for the UTOO P66 tablet The UTOO P66 is a 6" A13 tablet / lcd ereader. It features a 6" 480x800 ips lcd screen, 512MB RAM & 4GB emmc. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- configs/UTOO_P66_defconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 configs/UTOO_P66_defconfig diff --git a/configs/UTOO_P66_defconfig b/configs/UTOO_P66_defconfig new file mode 100644 index 0000000000..919a4674d1 --- /dev/null +++ b/configs/UTOO_P66_defconfig @@ -0,0 +1,21 @@ +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +CONFIG_FDTFILE="sun5i-a13-utoo-p66.dtb" +CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB0_VBUS_PIN="PB04" +CONFIG_USB0_VBUS_DET="PG01" +CONFIG_VIDEO_LCD_MODE="x:480,y:800,depth:18,pclk_khz:25000,le:2,ri:93,up:2,lo:93,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_DCLK_PHASE=0 +CONFIG_VIDEO_LCD_POWER="PG4" +CONFIG_VIDEO_LCD_RESET="PG11" +CONFIG_VIDEO_LCD_BL_EN="AXP0-1" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_VIDEO_LCD_TL059WV5C0=y ++S:CONFIG_MMC_SUNXI_SLOT_EXTRA=2 ++S:CONFIG_MMC0_CD_PIN="PG0" ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN5I=y ++S:CONFIG_DRAM_CLK=432 ++S:CONFIG_DRAM_ZQ=123 ++S:CONFIG_DRAM_EMR1=0 -- cgit From 52defe8f65700ad625c3ca63f723564210b2dc82 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 16 Feb 2015 22:13:43 +0100 Subject: sunxi: musb: Check Vbus-det before enabling otg port power Sending out 5V when there is a charger connected to the otg port is not a good idea, so check for this and error out. Note this commit currently breaks otg support on the q8h tablets, as we need to do some magic with the pmic there to get vbus info, this is deliberate (better safe then sorry), fixing this is on my TODO list. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 8 ++++++++ configs/Ampe_A76_defconfig | 1 + configs/Chuwi_V7_CW0825_defconfig | 1 + configs/Hyundai_A7HD_defconfig | 1 + configs/Inet_86VS_defconfig | 1 + configs/TZX-Q8-713B7_defconfig | 1 + drivers/usb/musb-new/sunxi.c | 29 +++++++++++++++++++++++++++++ 7 files changed, 42 insertions(+) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index f5471a14c5..9cf54e51ac 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -223,6 +223,14 @@ config USB0_VBUS_PIN Set the Vbus enable pin for usb0 (otg). This takes a string in the format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. +config USB0_VBUS_DET + string "Vbus detect pin for usb0 (otg)" + depends on USB_MUSB_SUNXI + default "" + ---help--- + Set the Vbus detect pin for usb0 (otg). This takes a string in the + format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H. + config USB1_VBUS_PIN string "Vbus enable pin for usb1 (ehci0)" default "PH6" if MACH_SUN4I || MACH_SUN7I diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig index 2054fc3c96..f8ceb6cea6 100644 --- a/configs/Ampe_A76_defconfig +++ b/configs/Ampe_A76_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" CONFIG_FDTFILE="sun5i-a13-ampe-a76.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_USB0_VBUS_DET="PG01" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" diff --git a/configs/Chuwi_V7_CW0825_defconfig b/configs/Chuwi_V7_CW0825_defconfig index 680b6317df..1ef23e4f16 100644 --- a/configs/Chuwi_V7_CW0825_defconfig +++ b/configs/Chuwi_V7_CW0825_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" CONFIG_FDTFILE="sun4i-a10-chuwi-v7-cw0825.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="PH5" CONFIG_VIDEO_LCD_MODE="x:1024,y:768,depth:24,pclk_khz:51000,le:19,ri:300,up:6,lo:31,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="PH8" CONFIG_VIDEO_LCD_BL_EN="PH7" diff --git a/configs/Hyundai_A7HD_defconfig b/configs/Hyundai_A7HD_defconfig index 204640ee24..6b784e2408 100644 --- a/configs/Hyundai_A7HD_defconfig +++ b/configs/Hyundai_A7HD_defconfig @@ -6,6 +6,7 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" CONFIG_FDTFILE="sun4i-a10-hyundai-a7hd.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PB09" +CONFIG_USB0_VBUS_DET="PH5" CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="PH6" CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:45,ri:274,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" diff --git a/configs/Inet_86VS_defconfig b/configs/Inet_86VS_defconfig index ce9985affe..50c073a2e5 100644 --- a/configs/Inet_86VS_defconfig +++ b/configs/Inet_86VS_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" CONFIG_FDTFILE="sun5i-a13-inet-86vs.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_USB0_VBUS_DET="PG1" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig index 7b7b9ddf8e..c22286abe9 100644 --- a/configs/TZX-Q8-713B7_defconfig +++ b/configs/TZX-Q8-713B7_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" CONFIG_FDTFILE="sun5i-a13-tzx-q8-713b7.dtb" CONFIG_USB_MUSB_SUNXI=y CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_USB0_VBUS_DET="PG1" CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_EN="AXP0-1" diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 4646a3d9fe..fe45db1e06 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -22,7 +22,9 @@ */ #include #include +#include #include +#include #include "linux-compat.h" #include "musb_core.h" @@ -224,6 +226,33 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); + if (is_host_enabled(musb)) { + int vbus_det = sunxi_name_to_gpio(CONFIG_USB0_VBUS_DET); + if (vbus_det == -1) { + eprintf("Error invalid Vusb-det pin\n"); + return -EINVAL; + } + + err = gpio_request(vbus_det, "vbus0_det"); + if (err) + return err; + + err = gpio_direction_input(vbus_det); + if (err) { + gpio_free(vbus_det); + return err; + } + + err = gpio_get_value(vbus_det); + if (err) { + eprintf("Error: A charger is plugged into the OTG\n"); + gpio_free(vbus_det); + return -EIO; + } + + gpio_free(vbus_det); + } + err = sunxi_usbc_request_resources(0); if (err) return err; -- cgit From f388a26d1132dae7ffe123cd7bd9adf78d4f7b57 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 19 Feb 2015 14:46:44 +0100 Subject: sunxi: Fix sun5i mbus speed when booting old kernels Older linux-sunxi-3.4 kernels override our PLL6 setting with 300 MHz, halving the mbus frequency, so set it to 300 MHz ourselves and base the mbus divider on that. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h index d297ed0f73..c28ee0528f 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h @@ -144,7 +144,16 @@ struct sunxi_ccm_reg { #define PLL1_CFG_DEFAULT 0xa1005000 +#if defined CONFIG_OLD_SUNXI_KERNEL_COMPAT && defined CONFIG_MACH_SUN5I +/* + * Older linux-sunxi-3.4 kernels override our PLL6 setting with 300 MHz, + * halving the mbus frequency, so set it to 300 MHz ourselves and base the + * mbus divider on that. + */ +#define PLL6_CFG_DEFAULT 0xa1009900 +#else #define PLL6_CFG_DEFAULT 0xa1009911 +#endif /* nand clock */ #define NAND_CLK_SRC_OSC24 0 -- cgit From f3133962f469a8b6b9ba237ba670f0ca7c88a02e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 20 Feb 2015 16:55:12 +0100 Subject: sunxi: Set the /chosen/stdout-path fdt property for sunxi boards While discussing with some people how to get the Linux kernel to do the right thing wrt sending output to both the serial console and the hdmi out / lcd screen when booting on ARM devices, Grant Likely pointed out that there already is a solution for this. All we need to do is set the /chosen/stdout-path fdt property, and if no console= arguments were specified on the kernel commandline the kernel will honor this and add this device as a console (next to the primary video output on hdmi). And u-boot already has support for setting this, all we need to do is define OF_STDOUT_PATH and then everything will just work ootb, without people needing to meddle with adding console= arguments in extlinux.conf . Signed-off-by: Hans de Goede Acked-by: Ian Campbell Reviewed-by: Tom Rini --- include/configs/sunxi-common.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index f5efebbf28..0b4f0a07b7 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -210,6 +210,20 @@ extern int soft_i2c_gpio_scl; #define CONFIG_CONS_INDEX 1 /* UART0 */ #endif +#if CONFIG_CONS_INDEX == 1 +#ifdef CONFIG_MACH_SUN9I +#define OF_STDOUT_PATH "/soc/serial@07000000:115200" +#else +#define OF_STDOUT_PATH "/soc@01c00000/serial@01c28000:115200" +#endif +#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I) +#define OF_STDOUT_PATH "/soc@01c00000/serial@01c28400:115200" +#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I) +#define OF_STDOUT_PATH "/soc@01c00000/serial@01f02800:115200" +#else +#error Unsupported console port nr. Please fix stdout-path in sunxi-common.h. +#endif + /* GPIO */ #define CONFIG_SUNXI_GPIO #define CONFIG_SPL_GPIO_SUPPORT -- cgit From 77ef136950b4649ff4844c3b72dab107a9c565a0 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sat, 21 Feb 2015 07:34:09 +0200 Subject: sunxi: Machine id hack to prevent loading buggy sunxi-3.4 kernels Right now U-Boot supports the CONFIG_OLD_SUNXI_KERNEL_COMPAT option, which makes it go out of its way in limiting the selection of PLL clock frequencies and PMIC voltages in order not to upset outdated buggy sunxi-3.4 kernel releases. And if the CONFIG_OLD_SUNXI_KERNEL_COMPAT option is not set, then booting such old kernels exhibits various failures at runtime. This is very user unfriendly, and there were already several incidents when people wasted their time being hit by these runtime failures and trying to debug them. The right solution is not to add hacks and workarounds to the mainline U-Boot, but to fix these bugs in the sunxi-3.4 kernel. And in fact, the updated sunxi-3.4 kernels already exist. Still we need to follow the 'Principle of Least Surprise' and U-Boot needs to ensure that the old buggy kernels are not getting happily booted when the CONFIG_OLD_SUNXI_KERNEL_COMPAT option is not set. And this patch addresses this particular issue. This patch makes U-Boot store the 'compatibility revision' number in the top 4 bits of the machine id and pass it to the kernel. The old buggy kernels will fail to load with a very much googlable error message on the serial console (the "r1 = 0x100010bb" part of it): "Error: unrecognized/unsupported machine ID (r1 = 0x100010bb)" This error message can be documented in the linux-sunxi wiki with proper explanations about how to resolve this situation and where to get the necessary bugfixes for the sunxi-3.4 kernel. The fixed sunxi-3.4 kernels implement a revision compatibility check and clear the top 4 bits of the machine id if everything is alright. By accepting the machine id with the bits 31:28 set to 1, the sunxi-3.4 kernel effectively certifies that it has the PLL5 clock speed and AXP209 DCDC3 voltage fixes applied. It is still possible to set the CONFIG_OLD_SUNXI_KERNEL_COMPAT option in U-Boot if the user desires to use an outdated unpatched sunxi-3.4 kernel. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- include/configs/sun4i.h | 4 ++-- include/configs/sun5i.h | 4 ++-- include/configs/sun7i.h | 4 ++-- include/configs/sunxi-common.h | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h index 87d269b041..1537e536f9 100644 --- a/include/configs/sun4i.h +++ b/include/configs/sun4i.h @@ -13,8 +13,6 @@ */ #define CONFIG_CLK_FULL_SPEED 1008000000 -#define CONFIG_MACH_TYPE 4104 - #ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 @@ -25,4 +23,6 @@ */ #include +#define CONFIG_MACH_TYPE (4104 | ((CONFIG_MACH_TYPE_COMPAT_REV) << 28)) + #endif /* __CONFIG_H */ diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h index 52e3a6ff01..e7555313db 100644 --- a/include/configs/sun5i.h +++ b/include/configs/sun5i.h @@ -13,8 +13,6 @@ */ #define CONFIG_CLK_FULL_SPEED 1008000000 -#define CONFIG_MACH_TYPE 4138 - #ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 @@ -25,4 +23,6 @@ */ #include +#define CONFIG_MACH_TYPE (4138 | ((CONFIG_MACH_TYPE_COMPAT_REV) << 28)) + #endif /* __CONFIG_H */ diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index 7cd7890341..f817f73076 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -14,8 +14,6 @@ */ #define CONFIG_CLK_FULL_SPEED 912000000 -#define CONFIG_MACH_TYPE 4283 - #ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 @@ -31,4 +29,6 @@ */ #include +#define CONFIG_MACH_TYPE (4283 | ((CONFIG_MACH_TYPE_COMPAT_REV) << 28)) + #endif /* __CONFIG_H */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 0b4f0a07b7..bd7d049277 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -13,6 +13,22 @@ #ifndef _SUNXI_COMMON_CONFIG_H #define _SUNXI_COMMON_CONFIG_H +#ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT +/* + * The U-Boot workarounds bugs in the outdated buggy sunxi-3.4 kernels at the + * expense of restricting some features, so the regular machine id values can + * be used. + */ +# define CONFIG_MACH_TYPE_COMPAT_REV 0 +#else +/* + * A compatibility guard to prevent loading outdated buggy sunxi-3.4 kernels. + * Only sunxi-3.4 kernels with appropriate fixes applied are able to pass + * beyond the machine id check. + */ +# define CONFIG_MACH_TYPE_COMPAT_REV 1 +#endif + /* * High Level Configuration Options */ -- cgit From 4b7cee533630202095748ecb396bd9eacf47ff3f Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Fri, 23 Jan 2015 12:12:01 +0200 Subject: mmc: Implement SD/MMC versioning properly The SD/MMC version scheme was buggy when dealing with standard major.minor.change cases. Fix it by using something similar to the linux's kernel versioning method. Signed-off-by: Pantelis Antoniou Tested-by: Jaehoon Chung Reported-by: Stephen Warren Tested-by: Stephen Warren --- common/cmd_mmc.c | 8 ++++++-- include/mmc.h | 56 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 4e28c9d7a4..1335e3d344 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -85,8 +85,12 @@ static void print_mmcinfo(struct mmc *mmc) printf("Tran Speed: %d\n", mmc->tran_speed); printf("Rd Block Len: %d\n", mmc->read_bl_len); - printf("%s version %d.%d\n", IS_SD(mmc) ? "SD" : "MMC", - (mmc->version >> 8) & 0xf, mmc->version & 0xff); + printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC", + EXTRACT_SDMMC_MAJOR_VERSION(mmc->version), + EXTRACT_SDMMC_MINOR_VERSION(mmc->version)); + if (EXTRACT_SDMMC_CHANGE_VERSION(mmc->version) != 0) + printf(".%d", EXTRACT_SDMMC_CHANGE_VERSION(mmc->version)); + printf("\n"); printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No"); puts("Capacity: "); diff --git a/include/mmc.h b/include/mmc.h index 56d97bbdcf..7d6feca5b4 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -14,24 +14,41 @@ #include #include -#define SD_VERSION_SD 0x20000 -#define SD_VERSION_3 (SD_VERSION_SD | 0x300) -#define SD_VERSION_2 (SD_VERSION_SD | 0x200) -#define SD_VERSION_1_0 (SD_VERSION_SD | 0x100) -#define SD_VERSION_1_10 (SD_VERSION_SD | 0x10a) -#define MMC_VERSION_MMC 0x10000 -#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC) -#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x102) -#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x104) -#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x202) -#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x300) -#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x400) -#define MMC_VERSION_4_1 (MMC_VERSION_MMC | 0x401) -#define MMC_VERSION_4_2 (MMC_VERSION_MMC | 0x402) -#define MMC_VERSION_4_3 (MMC_VERSION_MMC | 0x403) -#define MMC_VERSION_4_41 (MMC_VERSION_MMC | 0x429) -#define MMC_VERSION_4_5 (MMC_VERSION_MMC | 0x405) -#define MMC_VERSION_5_0 (MMC_VERSION_MMC | 0x500) +/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */ +#define SD_VERSION_SD (1U << 31) +#define MMC_VERSION_MMC (1U << 30) + +#define MAKE_SDMMC_VERSION(a, b, c) \ + ((((u32)(a)) << 16) | ((u32)(b) << 8) | (u32)(c)) +#define MAKE_SD_VERSION(a, b, c) \ + (SD_VERSION_SD | MAKE_SDMMC_VERSION(a, b, c)) +#define MAKE_MMC_VERSION(a, b, c) \ + (MMC_VERSION_MMC | MAKE_SDMMC_VERSION(a, b, c)) + +#define EXTRACT_SDMMC_MAJOR_VERSION(x) \ + (((u32)(x) >> 16) & 0xff) +#define EXTRACT_SDMMC_MINOR_VERSION(x) \ + (((u32)(x) >> 8) & 0xff) +#define EXTRACT_SDMMC_CHANGE_VERSION(x) \ + ((u32)(x) & 0xff) + +#define SD_VERSION_3 MAKE_SD_VERSION(3, 0, 0) +#define SD_VERSION_2 MAKE_SD_VERSION(2, 0, 0) +#define SD_VERSION_1_0 MAKE_SD_VERSION(1, 0, 0) +#define SD_VERSION_1_10 MAKE_SD_VERSION(1, 10, 0) + +#define MMC_VERSION_UNKNOWN MAKE_MMC_VERSION(0, 0, 0) +#define MMC_VERSION_1_2 MAKE_MMC_VERSION(1, 2, 0) +#define MMC_VERSION_1_4 MAKE_MMC_VERSION(1, 4, 0) +#define MMC_VERSION_2_2 MAKE_MMC_VERSION(2, 2, 0) +#define MMC_VERSION_3 MAKE_MMC_VERSION(3, 0, 0) +#define MMC_VERSION_4 MAKE_MMC_VERSION(4, 0, 0) +#define MMC_VERSION_4_1 MAKE_MMC_VERSION(4, 1, 0) +#define MMC_VERSION_4_2 MAKE_MMC_VERSION(4, 2, 0) +#define MMC_VERSION_4_3 MAKE_MMC_VERSION(4, 3, 0) +#define MMC_VERSION_4_41 MAKE_MMC_VERSION(4, 4, 1) +#define MMC_VERSION_4_5 MAKE_MMC_VERSION(4, 5, 0) +#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0) #define MMC_MODE_HS (1 << 0) #define MMC_MODE_HS_52MHz (1 << 1) @@ -43,7 +60,8 @@ #define SD_DATA_4BIT 0x00040000 -#define IS_SD(x) (x->version & SD_VERSION_SD) +#define IS_SD(x) ((x)->version & SD_VERSION_SD) +#define IS_MMC(x) ((x)->version & SD_VERSION_MMC) #define MMC_DATA_READ 1 #define MMC_DATA_WRITE 2 -- cgit From afc9e2b509a6db3b716c81c97f9147491ebf76ba Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 14 Jan 2015 17:37:53 +0900 Subject: mmc: dw_mmc: fixed the wrong bit control If mode is not DDR-mode, then it needs to clear it. Signed-off-by: Jaehoon Chung --- drivers/mmc/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index b18c75dee2..76fa0b0534 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -321,7 +321,7 @@ static void dwmci_set_ios(struct mmc *mmc) if (mmc->ddr_mode) regs |= DWMCI_DDR_MODE; else - regs &= DWMCI_DDR_MODE; + regs &= ~DWMCI_DDR_MODE; dwmci_writel(host, DWMCI_UHS_REG, regs); -- cgit From 3a33bb1874a75abde8872915f808945b6d20f6f2 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 4 Feb 2015 15:48:39 +0900 Subject: mmc: exynos_dw_mmc: set to clksel_val into board-init function "clksel_val" is assigned to property of mmc or defined value. But it doesn't write at initial sequence. There is a reason that get the wrong source-clock value. This patch fixed it. Signed-off-by: Jaehoon Chung --- drivers/mmc/exynos_dw_mmc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index dfa209bded..3936660892 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -64,6 +64,10 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) MPSCTRL_NON_SECURE_READ_BIT | MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); } + + /* Set to clksel_val at initial time */ + if (host->clksel_val) + exynos_dwmci_clksel(host); } static int exynos_dwmci_core_init(struct dwmci_host *host, int index) -- cgit From 5dab81cea5500558b7bfc43a7364ae7ed706d2fc Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 4 Feb 2015 15:48:40 +0900 Subject: mmc: exynos_dw_mmc: use the exynos specific data structure Clksel value is exynos specific value. It removed "clksel_val" into dwmci_host and created the "dwmci_exynos_priv_data" structure for exynos specific data. Signed-off-by: Jaehoon Chung --- drivers/mmc/exynos_dw_mmc.c | 60 +++++++++++++++++++++++++++++++++++---------- include/dwmmc.h | 2 +- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 3936660892..c66c0b0bf8 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -19,8 +19,13 @@ #define DWMMC_MAX_CH_NUM 4 #define DWMMC_MAX_FREQ 52000000 #define DWMMC_MIN_FREQ 400000 -#define DWMMC_MMC0_CLKSEL_VAL 0x03030001 -#define DWMMC_MMC2_CLKSEL_VAL 0x03020001 +#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001 +#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001 + +/* Exynos implmentation specific drver private data */ +struct dwmci_exynos_priv_data { + u32 sdr_timing; +}; /* * Function used as callback function to initialise the @@ -28,7 +33,9 @@ */ static void exynos_dwmci_clksel(struct dwmci_host *host) { - dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val); + struct dwmci_exynos_priv_data *priv = host->priv; + + dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing); } unsigned int exynos_dwmci_get_clk(struct dwmci_host *host) @@ -55,6 +62,8 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host) static void exynos_dwmci_board_init(struct dwmci_host *host) { + struct dwmci_exynos_priv_data *priv = host->priv; + if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { dwmci_writel(host, EMMCP_MPSBEGIN0, 0); dwmci_writel(host, EMMCP_SEND0, 0); @@ -65,8 +74,8 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); } - /* Set to clksel_val at initial time */ - if (host->clksel_val) + /* Set to timing value at initial time */ + if (priv->sdr_timing) exynos_dwmci_clksel(host); } @@ -74,6 +83,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index) { unsigned int div; unsigned long freq, sclk; + struct dwmci_exynos_priv_data *priv = host->priv; if (host->bus_hz) freq = host->bus_hz; @@ -92,11 +102,11 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index) #endif host->board_init = exynos_dwmci_board_init; - if (!host->clksel_val) { + if (!priv->sdr_timing) { if (index == 0) - host->clksel_val = DWMMC_MMC0_CLKSEL_VAL; + priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL; else if (index == 2) - host->clksel_val = DWMMC_MMC2_CLKSEL_VAL; + priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL; } host->caps = MMC_MODE_DDR_52MHz; @@ -122,6 +132,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index) int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) { struct dwmci_host *host = NULL; + struct dwmci_exynos_priv_data *priv; host = malloc(sizeof(struct dwmci_host)); if (!host) { @@ -129,11 +140,19 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) return -ENOMEM; } + priv = malloc(sizeof(struct dwmci_exynos_priv_data)); + if (!priv) { + error("dwmci_exynos_priv_data malloc fail!\n"); + return -ENOMEM; + } + host->ioaddr = (void *)regbase; host->buswidth = bus_width; if (clksel) - host->clksel_val = clksel; + priv->sdr_timing = clksel; + + host->priv = priv; return exynos_dwmci_core_init(host, index); } @@ -161,7 +180,14 @@ static int exynos_dwmci_get_config(const void *blob, int node, struct dwmci_host *host) { int err = 0; - u32 base, clksel_val, timing[3]; + u32 base, timing[3]; + struct dwmci_exynos_priv_data *priv; + + priv = malloc(sizeof(struct dwmci_exynos_priv_data)); + if (!priv) { + error("dwmci_exynos_priv_data malloc fail!\n"); + return -ENOMEM; + } /* Extract device id for each mmc channel */ host->dev_id = pinmux_decode_periph_id(blob, node); @@ -194,16 +220,24 @@ static int exynos_dwmci_get_config(const void *blob, int node, return -EINVAL; } - clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) | + priv->sdr_timing = (DWMCI_SET_SAMPLE_CLK(timing[0]) | DWMCI_SET_DRV_CLK(timing[1]) | DWMCI_SET_DIV_RATIO(timing[2])); - if (clksel_val) - host->clksel_val = clksel_val; + + /* sdr_timing didn't assigned anything, use the default value */ + if (!priv->sdr_timing) { + if (host->dev_index == 0) + priv->sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL; + else if (host->dev_index == 2) + priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL; + } host->fifoth_val = fdtdec_get_int(blob, node, "fifoth_val", 0); host->bus_hz = fdtdec_get_int(blob, node, "bus_hz", 0); host->div = fdtdec_get_int(blob, node, "div", 0); + host->priv = priv; + return 0; } diff --git a/include/dwmmc.h b/include/dwmmc.h index 109f7c8ac7..86a54918f9 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -141,9 +141,9 @@ struct dwmci_host { int dev_index; int dev_id; int buswidth; - u32 clksel_val; u32 fifoth_val; struct mmc *mmc; + void *priv; void (*clksel)(struct dwmci_host *host); void (*board_init)(struct dwmci_host *host); -- cgit From 1f3e877defc5a073f8e93c04e03f9a75f34dd595 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 19 Feb 2015 21:03:21 +0100 Subject: sunxi: mmc: Always declare High Capacity capability High Capacity (e)MMC cards work fine on sun4i / sun5i, and not having this capability set causes u-boot to not recognize the eMMC on an Utoo P66 A13 tablet, so always set it thereby fixing this. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mmc/sunxi_mmc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index ebfec7cf07..22335452c5 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -449,11 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; - cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \ - defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN9I) - cfg->host_caps |= MMC_MODE_HC; -#endif + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_min = 400000; -- cgit From 64029f7aeec4e843ab99297c24e0ef4f40267a6e Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Fri, 20 Feb 2015 12:29:26 +0100 Subject: mmc: exynos dwmmc: check boot mode before init dwmmc Before this commit, the mmc devices were always registered in the same order. So dwmmc channel 0 was registered as mmc 0, channel 1 as mmc 1, etc. In case of possibility to boot from more then one device, the CONFIG_SYS_MMC_ENV_DEV should always point to right mmc device. This can be achieved by init boot device as first, so it will be always registered as mmc 0. Thanks to this, the 'saveenv' command will work fine for all mmc boot devices. Exynos based boards usually uses mmc host channels configuration: - 0, or 0+1 for 8 bit - as a default boot device (usually eMMC) - 2 for 4bit - as an optional boot device (usually SD card slot) And usually the boot order is defined by OM pin configuration, which can be changed in a few ways, eg. - Odroid U3 - eMMC card insertion -> first boot from eMMC - Odroid X2/XU3 - boot priority jumper By this commit, Exynos dwmmc driver will check the OM pin configuration, and then try to init the boot device and register it as mmc 0. Signed-off-by: Przemyslaw Marczak Cc: Minkyu Kang Cc: Jaehoon Chung Cc: Pantelis Antoniou Cc: Simon Glass Cc: Akshay Saraswat --- drivers/mmc/exynos_dw_mmc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index c66c0b0bf8..e083745235 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -196,7 +197,6 @@ static int exynos_dwmci_get_config(const void *blob, int node, if (host->dev_index == host->dev_id) host->dev_index = host->dev_id - PERIPH_ID_SDMMC0; - /* Get the bus width from the device node */ host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 0); if (host->buswidth <= 0) { @@ -267,12 +267,21 @@ int exynos_dwmmc_init(const void *blob) { int compat_id; int node_list[DWMMC_MAX_CH_NUM]; + int boot_dev_node; int err = 0, count; compat_id = COMPAT_SAMSUNG_EXYNOS_DWMMC; count = fdtdec_find_aliases_for_id(blob, "mmc", compat_id, node_list, DWMMC_MAX_CH_NUM); + + /* For DWMMC always set boot device as mmc 0 */ + if (count >= 3 && get_boot_mode() == BOOT_MODE_SD) { + boot_dev_node = node_list[2]; + node_list[2] = node_list[0]; + node_list[0] = boot_dev_node; + } + err = exynos_dwmci_process_node(blob, node_list, count); return err; -- cgit From 34dd928492fa020455d9b9f59fe4b643c0708306 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Fri, 20 Feb 2015 12:29:27 +0100 Subject: mmc: print SD/eMMC type for inited mmc devices Depending on the boot priority, the eMMC/SD cards, can be initialized with the same numbers for each boot. To be sure which mmc device is SD and which is eMMC, this info is printed by 'mmc list' command, when the init is done. Signed-off-by: Przemyslaw Marczak Cc: Pantelis Antoniou --- drivers/mmc/mmc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b8039cd092..a13769ea25 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1693,11 +1693,19 @@ void print_mmc_devices(char separator) { struct mmc *m; struct list_head *entry; + char *mmc_type; list_for_each(entry, &mmc_devices) { m = list_entry(entry, struct mmc, link); + if (m->has_init) + mmc_type = IS_SD(m) ? "SD" : "eMMC"; + else + mmc_type = NULL; + printf("%s: %d", m->cfg->name, m->block_dev.dev); + if (mmc_type) + printf(" (%s)", mmc_type); if (entry->next != &mmc_devices) { printf("%c", separator); -- cgit From f88a429f1179c9d9ab2883fba0ed0aa13c9bd72e Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Thu, 19 Feb 2015 11:22:53 -0700 Subject: mmc: sdhci: fix bus width switching on Samsung SoCs Fix bus width switching from 8-bit mode down to 4-bit or 1-bit modes on Samsung SoCs using SDHCI_QUIRK_USE_WIDE8. These SoCs report controller version 2.0 yet they support 8-bit bus widths. If 8-bit mode was previously enabled and then an operation like "mmc dev" caused a switch back down to 4-bit or 1-bit mode, WIDE8 was left set, causing failures. This problem was manifested by "mmc dev" timing out. Signed-off-by: Matt Reimer --- drivers/mmc/sdhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index de88e19609..82d7984a51 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -374,7 +374,8 @@ static void sdhci_set_ios(struct mmc *mmc) (host->quirks & SDHCI_QUIRK_USE_WIDE8)) ctrl |= SDHCI_CTRL_8BITBUS; } else { - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) + if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) || + (host->quirks & SDHCI_QUIRK_USE_WIDE8)) ctrl &= ~SDHCI_CTRL_8BITBUS; if (mmc->bus_width == 4) ctrl |= SDHCI_CTRL_4BITBUS; -- cgit